doclayout 0.5.0.3 → 0.6
raw patch · 5 files changed
+244/−107 lines, 5 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- Text.DocLayout: unfoldD :: Doc a -> [Doc a]
Files
- changelog.md +36/−0
- doclayout.cabal +1/−1
- src/Text/DocLayout.hs +110/−101
- src/Text/unicodeWidth.inc +64/−4
- test/test.hs +33/−1
changelog.md view
@@ -1,5 +1,41 @@ # doclayout +## 0.6++ * Fix `nowrap` to descend into nested Doc structures.+ Previously nowrap only replaced top-level breaking spaces, so spaces+ inside Styled, Linked, Prefixed, and BeforeNonBlank remained+ breakable, e.g. nowrap (bold ("aa" <> space <> "bb")) still wrapped.++ * Remove deprecated `unfoldD` [API change].+ It has been deprecated since 0.5 and is no longer used internally.++ * Make `flatten` linear in the size of the Doc (formerly it was quadratic+ for left-nested Concats).++ * Fix `chop`: preserve attributes, keep combining marks with base, fill left.+ Previously `chop` (used for lines exceeding a block's width) lost ANSI+ styling in text, folded right-to-left (sometimes orphaning+ combining marks at the start of the next line), and under-filled the+ first chopped line instead of the last (e.g., `lblock 3 "abcdefg"`+ gave `"a/nbcd/nefg"` rather than `"abc/ndef/ng"`).++ * Fix `offset`/`minOffset`/`updateColumn` for mid-line Prefixed.+ `getOffset` restarted the column at 0 for Prefixed content and+ unconditionally added the prefix width, but the renderer only emits+ the prefix at the start of a line: mid-line, prefixed content simply+ continues at the current column.++ * Various small performance improvements and cleanups.++ * Update EastAsianWidth.txt to Unicode 17.0.++ * Make `update.hs` a cabal script and fix it for recent EastAsianWidths.++ * Update sources with latest EastAsianWidths.++ * Remove stack.yaml.+ ## 0.5.0.3 * Tests: Go back to using withMaxSuccess for compatibility with older
doclayout.cabal view
@@ -1,5 +1,5 @@ name: doclayout-version: 0.5.0.3+version: 0.6 synopsis: A prettyprinting library for laying out text documents. description: doclayout is a prettyprinting library for laying out text documents, with several features not present
src/Text/DocLayout.hs view
@@ -97,8 +97,6 @@ , isSkinToneModifier , isEmojiVariation , isZWJ- -- * Utility functions- , unfoldD -- * Types , Doc(..) , HasChars(..)@@ -107,7 +105,7 @@ where import Prelude-import Data.Maybe (fromMaybe, isJust, mapMaybe)+import Data.Maybe (isJust, mapMaybe) import Safe (lastMay, initSafe) import Control.Monad import Control.Monad.State.Strict@@ -174,14 +172,6 @@ instance HasChars a => IsString (Doc a) where fromString = text -{-# DEPRECATED unfoldD "unfoldD will be removed from the API." #-}--- | Unfold a 'Doc' into a flat list.-unfoldD :: Doc a -> [Doc a]-unfoldD Empty = []-unfoldD (Concat x@Concat{} y) = unfoldD x <> unfoldD y-unfoldD (Concat x y) = x : unfoldD y-unfoldD x = [x]- -- | True if the document is empty. isEmpty :: Doc a -> Bool isEmpty Empty = True@@ -291,31 +281,35 @@ -- * Other Docs with inner content are eliminated if the inner content is -- empty, otherwise the inner content is itself flattened and made into -- a NonEmpty.+-- The accumulator ("rest") style guarantees linear time even for+-- left-nested Concats; naive list appends would be quadratic. flatten :: HasChars a => Doc a -> [FlatDoc a]-flatten (Text n a) = [FText n a]-flatten (Block n a) = [FBlock n a]-flatten (VFill n a) = [FVFill n a]-flatten (CookedText n a) = [FCookedText n a]-flatten (Prefixed p d) | null f = []- | otherwise = [FPrefixed p (N.fromList f)]- where f = flatten d-flatten (BeforeNonBlank d) | null f = []- | otherwise = [FBeforeNonBlank (N.fromList f)]- where f = flatten d-flatten (Flush d) | null f = []- | otherwise = [FFlush (N.fromList f)]- where f = flatten d-flatten BreakingSpace = [FBreakingSpace]-flatten CarriageReturn = [FCarriageReturn]-flatten (AfterBreak t) | null f = []- | otherwise = [FAfterBreak (N.fromList f)]- where f = flatten $ fromString $ T.unpack t-flatten NewLine = [FNewLine]-flatten (BlankLines n) = [FBlankLines n]-flatten Empty = []-flatten (Concat x y) = flatten x <> flatten y-flatten (Linked l x) = FLinkOpen l : flatten x <> [FLinkClose]-flatten (Styled f x) = FStyleOpen f : flatten x <> [FStyleClose]+flatten d = go d []+ where+ go (Text n a) rest = FText n a : rest+ go (Block n a) rest = FBlock n a : rest+ go (VFill n a) rest = FVFill n a : rest+ go (CookedText n a) rest = FCookedText n a : rest+ go (Prefixed p x) rest = case go x [] of+ [] -> rest+ f -> FPrefixed p (N.fromList f) : rest+ go (BeforeNonBlank x) rest = case go x [] of+ [] -> rest+ f -> FBeforeNonBlank (N.fromList f) : rest+ go (Flush x) rest = case go x [] of+ [] -> rest+ f -> FFlush (N.fromList f) : rest+ go BreakingSpace rest = FBreakingSpace : rest+ go CarriageReturn rest = FCarriageReturn : rest+ go (AfterBreak t) rest = case go (fromString (T.unpack t)) [] of+ [] -> rest+ f -> FAfterBreak (N.fromList f) : rest+ go NewLine rest = FNewLine : rest+ go (BlankLines n) rest = FBlankLines n : rest+ go Empty rest = rest+ go (Concat x y) rest = go x (go y rest)+ go (Linked l x) rest = FLinkOpen l : go x (FLinkClose : rest)+ go (Styled f x) rest = FStyleOpen f : go x (FStyleClose : rest) type DocState a = State (RenderState a) () @@ -385,14 +379,14 @@ renderANSI :: HasChars a => Maybe Int -> Doc a -> TL.Text renderANSI n d = B.toLazyText $ go $ prerender n d where go s = (\(_,_,o) -> o) (go' s) <> B.fromText (renderFont baseFont) <> B.fromText (renderOSC8 Nothing)- go' (Attributed s) = foldl attrRender (Nothing, baseFont, B.fromText "") s+ go' (Attributed s) = foldl' attrRender (Nothing, baseFont, B.fromText "") s -- | Render a 'Doc' without using ANSI escapes. @renderPlain (Just n)@ will use -- a line length of @n@ to reflow text on breakable spaces. -- @renderPlain Nothing@ will not reflow text. renderPlain :: HasChars a => Maybe Int -> Doc a -> a renderPlain n d = go $ prerender n d where- go (Attributed s) = foldMap attrStrip s+ go (Attributed s) = mconcat $ map attrStrip $ toList s attrStrip :: HasChars a => Attr a -> a attrStrip (Attr _ _ y) | isNull y = ""@@ -504,9 +498,6 @@ -- Nested links are nonsensical, we only handle the outermost and -- silently ignore any attempts to have a link inside a link---- Nested links are nonsensical, we only handle the outermost and--- silently ignore any attempts to have a link inside a link renderList (FLinkOpen target : xs) = do st <- get case linkTarget st of@@ -600,10 +591,11 @@ heightOf _ = 1 let maxheight = maximum $ map heightOf (b:bs) let toBlockSpec (FBlock w ls) = (w, map (\l -> (realLength l, l)) ls)- toBlockSpec (FVFill w t) = (w, map (\l -> (realLength l, l)) $- map (singleton . (Attr (linkTarget st) font)) (take maxheight $ repeat t))+ toBlockSpec (FVFill w t) = (w, replicate maxheight+ (realLength t,+ singleton (Attr (linkTarget st) font t))) toBlockSpec _ = (0, [])- let (_, lns') = foldl (mergeBlocks maxheight) (toBlockSpec b)+ let (_, lns') = foldl' (mergeBlocks maxheight) (toBlockSpec b) (map toBlockSpec bs) let oldPref = prefix st oldPrefixA = prefixA st@@ -630,11 +622,10 @@ isBreakable (FBlankLines _) = True isBreakable _ = False +-- Whether the first character is a space. foldrChar is lazy in its+-- accumulator, so this inspects only the first character. startsBlank' :: HasChars a => a -> Bool-startsBlank' t = fromMaybe False $ foldlChar go Nothing t- where- go Nothing c = Just (isSpace c)- go (Just b) _ = Just b+startsBlank' = foldrChar (\c _ -> isSpace c) False startsBlank :: HasChars a => FlatDoc a -> Bool startsBlank (FText _ t) = startsBlank' t@@ -748,9 +739,15 @@ -- | Makes a 'Doc' non-reflowable. nowrap :: IsString a => Doc a -> Doc a-nowrap = mconcat . map replaceSpace . unfoldD- where replaceSpace BreakingSpace = Text 1 $ fromString " "- replaceSpace x = x+nowrap = go+ where go BreakingSpace = Text 1 $ fromString " "+ go (Concat x y) = Concat (go x) (go y)+ go (Styled s d) = Styled s (go d)+ go (Linked l d) = Linked l (go d)+ go (Prefixed p d) = Prefixed p (go d)+ go (BeforeNonBlank d) = BeforeNonBlank (go d)+ go (Flush d) = Flush (go d)+ go x = x -- | Content to print only if it comes at the beginning of a line, -- to be used e.g. for escaping line-initial `.` in roff man.@@ -759,47 +756,51 @@ -- | Returns the width of a 'Doc'. offset :: (IsString a, HasChars a) => Doc a -> Int-offset = uncurry max . getOffset (const False) (0, 0)+offset = uncurry max . getOffset (const False) 0 (0, 0) -- | Returns the minimal width of a 'Doc' when reflowed at breakable spaces. minOffset :: HasChars a => Doc a -> Int-minOffset = uncurry max . getOffset (> 0) (0,0)+minOffset = uncurry max . getOffset (> 0) 0 (0,0) --- l = longest, c = current+-- l = longest, c = current; pfx = width of the current line prefix,+-- to which the column returns after a line break. getOffset :: (IsString a, HasChars a)- => (Int -> Bool) -> (Int, Int) -> Doc a -> (Int, Int)-getOffset breakWhen (!l, !c) x =+ => (Int -> Bool) -> Int -> (Int, Int) -> Doc a -> (Int, Int)+getOffset breakWhen !pfx (!l, !c) x = case x of Text n _ -> (l, c + n) Block n _ -> (l, c + n) VFill n _ -> (l, c + n) CookedText n _ -> (l, c + n) Empty -> (l, c)- Styled _ d -> getOffset breakWhen (l, c) d- Linked _ d -> getOffset breakWhen (l, c) d- CarriageReturn -> (max l c, 0)- NewLine -> (max l c, 0)- BlankLines _ -> (max l c, 0)+ Styled _ d -> getOffset breakWhen pfx (l, c) d+ Linked _ d -> getOffset breakWhen pfx (l, c) d+ CarriageReturn -> (max l c, pfx)+ NewLine -> (max l c, pfx)+ BlankLines _ -> (max l c, pfx) Prefixed t d ->- let (l',c') = getOffset breakWhen (0, 0) d- in (max l (l' + realLength t), c' + realLength t)+ -- The renderer only emits prefixes at the start of a line;+ -- mid-line, the first line continues at the current column.+ let pfx' = pfx + realLength t+ c' = if c <= pfx then pfx' else c+ in getOffset breakWhen pfx' (l, c') d BeforeNonBlank _ -> (l, c)- Flush d -> getOffset breakWhen (l, c) d+ Flush d -> getOffset breakWhen 0 (l, c) d -- flush disables the prefix BreakingSpace- | breakWhen c -> (max l c, 0)+ | breakWhen c -> (max l c, pfx) | otherwise -> (l, c + 1)- AfterBreak t -> if c == 0+ AfterBreak t -> if c == pfx then (l, c + realLength t) else (l, c) Concat (Concat d y) z ->- getOffset breakWhen (l, c) (Concat d (Concat y z))+ getOffset breakWhen pfx (l, c) (Concat d (Concat y z)) Concat (BeforeNonBlank d) y -> if isNonBlank y- then getOffset breakWhen (l, c) (Concat d y)- else getOffset breakWhen (l, c) y+ then getOffset breakWhen pfx (l, c) (Concat d y)+ else getOffset breakWhen pfx (l, c) y Concat d y ->- let (l', c') = getOffset breakWhen (l, c) d- in getOffset breakWhen (l', c') y+ let (l', c') = getOffset breakWhen pfx (l, c) d+ in getOffset breakWhen pfx (l', c') y isNonBlank :: Doc a -> Bool isNonBlank (Text _ _) = True@@ -811,7 +812,7 @@ -- | Returns the column that would be occupied by the last -- laid out character (assuming no wrapping). updateColumn :: HasChars a => Doc a -> Int -> Int-updateColumn d k = snd . getOffset (const False) (0,k) $ d+updateColumn d k = snd . getOffset (const False) 0 (0,k) $ d -- | @lblock n d@ is a block of width @n@ characters, with -- text derived from @d@ and aligned to the left.@@ -845,7 +846,11 @@ vfill :: HasChars a => a -> Doc a vfill t = VFill (realLength t) t -chop :: HasChars a => Int -> a -> [a]+-- Split lines longer than n at width n, filling lines left to right.+-- Attributes are preserved: each Attr is split into as few pieces as+-- possible. Width-0 characters (combining marks) never start a new+-- line, so they stay with their base character.+chop :: HasChars a => Int -> Attributed a -> [Attributed a] chop n = concatMap chopLine . removeFinalEmpty . map addRealLength . splitLines where@@ -853,20 +858,26 @@ Just (0, _) -> initSafe xs _ -> xs addRealLength l = (realLength l, l)- chopLine (len, l)+ chopLine (len, l@(Attributed attrs)) | len <= n = [l]- | otherwise = map snd $- foldrChar- (\c ls ->- let clen = charWidth c- cs = replicateChar 1 c- in case ls of- (len', l'):rest- | len' + clen > n ->- (clen, cs):(len', l'):rest- | otherwise ->- (len' + clen, cs <> l'):rest- [] -> [(clen, cs)]) [] l+ | otherwise =+ let (_, cur, lns) = foldl' goAttr (0, [], []) (toList attrs)+ in reverse (fromList (reverse cur) : lns)+ -- State: (width of current line, reversed Attrs of current line,+ -- reversed list of completed lines). Within an Attr, characters+ -- are accumulated in reverse in pend and flushed into a single+ -- Attr on line breaks and at the end of the Attr.+ goAttr (w0, cur0, lns0) (Attr lk f x) =+ let (w, cur, lns, pend) = foldlChar (goChar lk f) (w0, cur0, lns0, []) x+ in (w, addPend lk f pend cur, lns)+ goChar lk f (w, cur, lns, pend) c =+ let cw = charWidth c+ in if w + cw > n && w > 0+ then (cw, [], fromList (reverse (addPend lk f pend cur)) : lns,+ [c])+ else (w + cw, cur, lns, c : pend)+ addPend _ _ [] cur = cur+ addPend lk f pend cur = Attr lk f (fromString (reverse pend)) : cur -- | Encloses a 'Doc' inside a start and end 'Doc'. inside :: Doc a -> Doc a -> Doc a -> Doc a@@ -1012,10 +1023,7 @@ -- Combining diacritical marks used in Latin and other scripts | c <= '\x036F' = combiningState -- Han ideographs- | c >= '\x3250' && c <= '\xA4CF' =- if | c <= '\x4DBF' -> wideState -- Han ideographs- | c <= '\x4DFF' -> narrowState -- Hexagrams- | otherwise -> wideState -- More Han ideographs+ | c >= '\x3250' && c <= '\xA4CF' = wideState -- Arabic | c >= '\x0600' && c <= '\x06FF' = if | c <= '\x0605' -> controlState -- Number marks@@ -1057,9 +1065,7 @@ | c <= '\x09C4' -> combiningState -- Combining signs | c == '\x09CD' -> combiningState -- Combining signs | c <= '\x09E1' -> narrowState -- Bengali- | c <= '\x09E3' -> combiningState -- Combining marks- | c == '\x09E2' -> combiningState -- Bengali vocalic vowel signs- | c == '\x09E3' -> combiningState -- Bengali vocalic vowel signs+ | c <= '\x09E3' -> combiningState -- Bengali vocalic vowel signs | c <= '\x09FD' -> narrowState -- Bengali digits and other symbols | otherwise -> combiningState -- Bengali sandhi mark, plus a few symbols from Gurmukhi -- Cyrillic (plus Greek and Armenian for free)@@ -1149,10 +1155,7 @@ -- ASCII | c <= '\x007E' = narrowState -- Han ideographs- | c >= '\x3250' && c <= '\xA4CF' =- if | c <= '\x4DBF' -> wideState -- Han ideographs- | c <= '\x4DFF' -> narrowState -- Hexagrams- | otherwise -> wideState -- More Han ideographs+ | c >= '\x3250' && c <= '\xA4CF' = wideState -- Japanese | c >= '\x2E80' && c <= '\x324F' = if | c <= '\x3029' -> wideState -- Punctuation and others@@ -1207,9 +1210,7 @@ | c <= '\x09C4' -> combiningState -- Combining signs | c == '\x09CD' -> combiningState -- Combining signs | c <= '\x09E1' -> narrowState -- Bengali- | c <= '\x09E3' -> combiningState -- Combining marks- | c == '\x09E2' -> combiningState -- Bengali vocalic vowel signs- | c == '\x09E3' -> combiningState -- Bengali vocalic vowel signs+ | c <= '\x09E3' -> combiningState -- Bengali vocalic vowel signs | c <= '\x09FD' -> narrowState -- Bengali digits and other symbols | otherwise -> combiningState -- Bengali sandhi mark, plus a few symbols from Gurmukhi -- Telugu (plus one character of Kannada)@@ -1275,13 +1276,21 @@ -- shortcuts. This should give the same answer as 'updateMatchStateNarrow', but will -- be slower. It is here to test that the shortcuts are implemented correctly. updateMatchStateNoShortcut :: MatchState -> Char -> MatchState-updateMatchStateNoShortcut match c = resolveWidth match c $ unicodeWidth (unicodeRangeMap Narrow) c+updateMatchStateNoShortcut match c = resolveWidth match c $ unicodeWidth narrowUnicodeMap c -- | Update a 'MatchState' by processing a character, without taking any -- shortcuts. This should give the same answer as 'updateMatchStateWide', but will -- be slower. It is here to test that the shortcuts are implemented correctly. updateMatchStateNoShortcutWide :: MatchState -> Char -> MatchState-updateMatchStateNoShortcutWide match c = resolveWidth match c $ unicodeWidth (unicodeRangeMap Wide) c+updateMatchStateNoShortcutWide match c = resolveWidth match c $ unicodeWidth wideUnicodeMap c++-- | Width table resolving ambiguous characters as narrow.+narrowUnicodeMap :: UnicodeMap+narrowUnicodeMap = unicodeRangeMap Narrow++-- | Width table resolving ambiguous characters as wide.+wideUnicodeMap :: UnicodeMap+wideUnicodeMap = unicodeRangeMap Wide -- | Update a match state given a character and its class resolveWidth :: MatchState -> Char -> UnicodeWidth -> MatchState
src/Text/unicodeWidth.inc view
@@ -178,7 +178,7 @@ , ( '\2137' , Combining ) , ( '\2142' , Narrow ) , ( '\2192' , Control )- , ( '\2200' , Combining )+ , ( '\2199' , Combining ) , ( '\2208' , Narrow ) , ( '\2250' , Combining ) , ( '\2274' , Control )@@ -621,6 +621,8 @@ , ( '\9757' , Narrow ) , ( '\9758' , Ambiguous ) , ( '\9759' , Narrow )+ , ( '\9776' , Wide )+ , ( '\9784' , Narrow ) , ( '\9792' , Ambiguous ) , ( '\9793' , Narrow ) , ( '\9794' , Ambiguous )@@ -639,6 +641,8 @@ , ( '\9840' , Narrow ) , ( '\9855' , Wide ) , ( '\9856' , Narrow )+ , ( '\9866' , Wide )+ , ( '\9872' , Narrow ) , ( '\9875' , Wide ) , ( '\9876' , Narrow ) , ( '\9886' , Ambiguous )@@ -717,8 +721,6 @@ , ( '\12443' , Wide ) , ( '\12872' , Ambiguous ) , ( '\12880' , Wide )- , ( '\19904' , Narrow )- , ( '\19968' , Wide ) , ( '\42192' , Narrow ) , ( '\42607' , Combining ) , ( '\42611' , Narrow )@@ -826,8 +828,12 @@ , ( '\68331' , Narrow ) , ( '\68900' , Combining ) , ( '\68912' , Narrow )+ , ( '\68969' , Combining )+ , ( '\68974' , Narrow ) , ( '\69291' , Combining ) , ( '\69293' , Narrow )+ , ( '\69370' , Combining )+ , ( '\69376' , Narrow ) , ( '\69446' , Combining ) , ( '\69457' , Narrow ) , ( '\69506' , Combining )@@ -874,6 +880,8 @@ , ( '\70198' , Combining ) , ( '\70200' , Narrow ) , ( '\70206' , Combining )+ , ( '\70207' , Narrow )+ , ( '\70209' , Combining ) , ( '\70272' , Narrow ) , ( '\70367' , Combining ) , ( '\70368' , Narrow )@@ -886,6 +894,16 @@ , ( '\70464' , Combining ) , ( '\70465' , Narrow ) , ( '\70502' , Combining )+ , ( '\70528' , Narrow )+ , ( '\70587' , Combining )+ , ( '\70594' , Narrow )+ , ( '\70606' , Combining )+ , ( '\70607' , Narrow )+ , ( '\70608' , Combining )+ , ( '\70609' , Narrow )+ , ( '\70610' , Combining )+ , ( '\70611' , Narrow )+ , ( '\70625' , Combining ) , ( '\70656' , Narrow ) , ( '\70712' , Combining ) , ( '\70720' , Narrow )@@ -926,6 +944,8 @@ , ( '\71351' , Combining ) , ( '\71352' , Narrow ) , ( '\71453' , Combining )+ , ( '\71454' , Narrow )+ , ( '\71455' , Combining ) , ( '\71456' , Narrow ) , ( '\71458' , Combining ) , ( '\71462' , Narrow )@@ -961,6 +981,12 @@ , ( '\72343' , Narrow ) , ( '\72344' , Combining ) , ( '\72346' , Narrow )+ , ( '\72544' , Combining )+ , ( '\72545' , Narrow )+ , ( '\72546' , Combining )+ , ( '\72549' , Narrow )+ , ( '\72550' , Combining )+ , ( '\72551' , Narrow ) , ( '\72752' , Combining ) , ( '\72766' , Narrow ) , ( '\72767' , Combining )@@ -985,8 +1011,25 @@ , ( '\73112' , Narrow ) , ( '\73459' , Combining ) , ( '\73461' , Narrow )+ , ( '\73472' , Combining )+ , ( '\73474' , Narrow )+ , ( '\73526' , Combining )+ , ( '\73534' , Narrow )+ , ( '\73536' , Combining )+ , ( '\73537' , Narrow )+ , ( '\73538' , Combining )+ , ( '\73539' , Narrow )+ , ( '\73562' , Combining )+ , ( '\73648' , Narrow ) , ( '\78896' , Control )- , ( '\82944' , Narrow )+ , ( '\78912' , Combining )+ , ( '\78913' , Narrow )+ , ( '\78919' , Combining )+ , ( '\78944' , Narrow )+ , ( '\90398' , Combining )+ , ( '\90410' , Narrow )+ , ( '\90413' , Combining )+ , ( '\90416' , Narrow ) , ( '\92912' , Combining ) , ( '\92917' , Narrow ) , ( '\92976' , Combining )@@ -1002,6 +1045,7 @@ , ( '\113821' , Combining ) , ( '\113823' , Narrow ) , ( '\113824' , Control )+ , ( '\117760' , Narrow ) , ( '\118528' , Combining ) , ( '\118608' , Narrow ) , ( '\119143' , Combining )@@ -1015,6 +1059,8 @@ , ( '\119214' , Narrow ) , ( '\119362' , Combining ) , ( '\119365' , Narrow )+ , ( '\119552' , Wide )+ , ( '\119671' , Narrow ) , ( '\121344' , Combining ) , ( '\121399' , Narrow ) , ( '\121403' , Combining )@@ -1026,6 +1072,8 @@ , ( '\121499' , Combining ) , ( '\122624' , Narrow ) , ( '\122880' , Combining )+ , ( '\122928' , Narrow )+ , ( '\123023' , Combining ) , ( '\123136' , Narrow ) , ( '\123184' , Combining ) , ( '\123191' , Narrow )@@ -1033,6 +1081,18 @@ , ( '\123584' , Narrow ) , ( '\123628' , Combining ) , ( '\123632' , Narrow )+ , ( '\124140' , Combining )+ , ( '\124144' , Narrow )+ , ( '\124398' , Combining )+ , ( '\124400' , Narrow )+ , ( '\124643' , Combining )+ , ( '\124644' , Narrow )+ , ( '\124646' , Combining )+ , ( '\124647' , Narrow )+ , ( '\124654' , Combining )+ , ( '\124656' , Narrow )+ , ( '\124661' , Combining )+ , ( '\124670' , Narrow ) , ( '\125136' , Combining ) , ( '\125184' , Narrow ) , ( '\125252' , Combining )
test/test.hs view
@@ -10,6 +10,7 @@ import Data.Functor ((<&>)) import Data.Text (Text) import qualified Data.Text as T+import qualified Data.Text.Lazy as TL #if MIN_VERSION_base(4,11,0) #else import Data.Semigroup@@ -32,11 +33,32 @@ (offset (nest 3 (text "**" <> text "thisIsGoingToBeTooLongAnyway" <> text "**") <> blankline :: Doc Text) @?= 35) + , testCase "offset with mid-line prefixed" $+ offset ("hello" <> nest 2 "world" :: Doc Text) @?= 10++ , testCase "offset with prefixed continuation lines" $+ offset ("aa" <> nest 2 ("bb" <> cr <> "cc") :: Doc Text) @?= 4+ , renderTest "lblock with chop" Nothing (lblock 4 (text "hi there" :: Doc Text)) "hi t\nhere" + , renderTest "chop fills lines from the left"+ Nothing+ (lblock 3 (text "abcdefg" :: Doc Text))+ "abc\ndef\ng"++ , renderTest "chop keeps combining chars with their base"+ Nothing+ (lblock 2 (text "ab\770cd" :: Doc Text))+ "ab\770\ncd"++ , testCase "chop preserves styling" $+ assertBool "bold escape code survives chopping" $+ "\ESC[1m" `TL.isInfixOf`+ renderANSI Nothing (lblock 4 (bold (text "hi there")) :: Doc Text)+ , renderTest "lblock with blank line" Nothing (Block 5 ["a", "", "b"] :: Doc Text)@@ -80,7 +102,7 @@ , renderTest "simple box wrapping" (Just 50) (lblock 3 "aa" <> lblock 3 "bb" <> lblock 3 ("aa" <+> "bbbb"))- "aa bb aa\n b\n bbb"+ "aa bb aa\n bbb\n b" , renderTest "prefixed with multi paragraphs" (Just 80)@@ -286,6 +308,16 @@ Nothing (literal "a" <> cr <> literal "\nb" <> cr <> literal "c") "a\n\nb\nc"++ , renderTest "nowrap inside styled text"+ (Just 4)+ (nowrap (bold ("aa" <> space <> "bb")))+ "aa bb"++ , renderTest "nowrap around prefixed"+ (Just 4)+ (nowrap (prefixed "> " ("aa" <> space <> "bb")))+ "> aa bb" , renderTest "breaking within styled text" (Just 5)