word-wrap 0.1.2 → 0.2
raw patch · 4 files changed
+68/−15 lines, 4 files
Files
- CHANGELOG.md +13/−0
- src/Text/Wrap.hs +34/−9
- tests/Main.hs +20/−5
- word-wrap.cabal +1/−1
CHANGELOG.md view
@@ -1,4 +1,17 @@ +0.2+===++API changes:+ * Added a WrapSettings data type for controlling wrapping behavior.+ * All functions now require a WrapSettings.+ * Added defaultWrapSettings for prior behavior.+ * Wrap settings now include a setting to control how indentation is+ preserved in broken lines.++Bug fixes:+ * Lines with only whitespace are preserved as empty lines.+ 0.1.2 =====
src/Text/Wrap.hs view
@@ -1,5 +1,8 @@ module Text.Wrap- ( wrapTextToLines+ ( WrapSettings(..)+ , defaultWrapSettings++ , wrapTextToLines , wrapText ) where@@ -7,17 +10,32 @@ import Data.Char (isSpace) import qualified Data.Text as T +-- | Settings to control how wrapping is performed.+data WrapSettings =+ WrapSettings { preserveIndentation :: Bool+ -- ^ Whether to indent new lines created by wrapping+ -- when their original line was indented.+ }+ deriving (Eq, Show, Read)++defaultWrapSettings :: WrapSettings+defaultWrapSettings =+ WrapSettings { preserveIndentation = False+ }+ -- | Wrap text at the specified width. Newlines and whitespace in the -- input text are preserved. Returns the lines of text in wrapped form. -- New lines introduced due to wrapping will have leading whitespace -- stripped.-wrapTextToLines :: Int -> T.Text -> [T.Text]-wrapTextToLines amt s = concat $ fmap (wrapLine amt) $ T.lines s+wrapTextToLines :: WrapSettings -> Int -> T.Text -> [T.Text]+wrapTextToLines settings amt s =+ concat $ fmap (wrapLine settings amt) $ T.lines s -- | Like 'wrapTextToLines', but returns the wrapped text reconstructed -- with newlines inserted at wrap points.-wrapText :: Int -> T.Text -> T.Text-wrapText amt s = T.intercalate (T.pack "\n") $ wrapTextToLines amt s+wrapText :: WrapSettings -> Int -> T.Text -> T.Text+wrapText settings amt s =+ T.intercalate (T.pack "\n") $ wrapTextToLines settings amt s data Token = WS T.Text | NonWS T.Text deriving (Show)@@ -43,21 +61,28 @@ -- | Wrap a single line of text into a list of lines that all satisfy -- the wrapping width.-wrapLine :: Int+wrapLine :: WrapSettings+ -- ^ Settings.+ -> Int -- ^ The wrapping width. -> T.Text -- ^ A single line of text. -> [T.Text]-wrapLine limit t =+wrapLine settings limit t = let go [] = [T.empty]- go [WS _] = []+ go [WS _] = [T.empty] go [tok] = [tokenContent tok] go ts = let (firstLine, maybeRest) = breakTokens limit ts firstLineText = T.stripEnd $ T.concat $ fmap tokenContent firstLine in case maybeRest of Nothing -> [firstLineText]- Just rest -> firstLineText : go rest+ Just rest ->+ let maybeIndent = if preserveIndentation settings+ then ((WS indent) :)+ else id+ indent = T.takeWhile isSpace firstLineText+ in firstLineText : go (maybeIndent rest) in go (tokenize t) -- | Break a token sequence so that all tokens up to but not exceeding
tests/Main.hs view
@@ -8,16 +8,31 @@ main :: IO () main = hspec $ do it "leaves short lines untouched" $ do- wrapTextToLines 5 "foo" `shouldBe` ["foo"]+ wrapTextToLines defaultWrapSettings 5 "foo"+ `shouldBe` ["foo"] it "wraps long lines" $ do- wrapTextToLines 7 "Hello, World!" `shouldBe` ["Hello,", "World!"]+ wrapTextToLines defaultWrapSettings 7 "Hello, World!"+ `shouldBe` ["Hello,", "World!"] it "preserves leading whitespace" $ do- wrapTextToLines 10 " Hello, World!" `shouldBe` [" Hello,", "World!"]+ wrapTextToLines defaultWrapSettings 10 " Hello, World!"+ `shouldBe` [" Hello,", "World!"] it "honors preexisting newlines" $ do- wrapTextToLines 100 "Hello,\n\nWorld!" `shouldBe` ["Hello,", "", "World!"]+ wrapTextToLines defaultWrapSettings 100 "Hello,\n\n \nWorld!"+ `shouldBe` ["Hello,", "", "", "World!"] it "wraps long lines without truncation" $ do- wrapTextToLines 2 "Hello, World!" `shouldBe` ["Hello,", "World!"]+ wrapTextToLines defaultWrapSettings 2 "Hello, World!"+ `shouldBe` ["Hello,", "World!"]++ it "preserves indentation" $ do+ let s = WrapSettings { preserveIndentation = True }+ wrapTextToLines s 10 " Hello, World!"+ `shouldBe` [" Hello,", " World!"]++ it "preserves indentation (2)" $ do+ let s = WrapSettings { preserveIndentation = True }+ wrapTextToLines s 10 " Hello, World!\n Things And Stuff"+ `shouldBe` [" Hello,", " World!", " Things", " And", " Stuff"]
word-wrap.cabal view
@@ -1,5 +1,5 @@ name: word-wrap-version: 0.1.2+version: 0.2 synopsis: A library for word-wrapping description: A library for wrapping long lines of text. license: BSD3