Implement wordWrap and paginate
This commit is contained in:
parent
67b691d410
commit
b783faef1a
4 changed files with 62 additions and 5 deletions
|
|
@ -1,6 +1,9 @@
|
|||
-- | Internal module in order to facilitate testability.
|
||||
module HCat.Internal where
|
||||
|
||||
import Data.Text (Text)
|
||||
import Data.Text qualified as T
|
||||
|
||||
-- | @parseArgs@ takes a list of strings and returns a single FilePath if there was exactly one element.
|
||||
--
|
||||
-- >>> parseArgs ["foo"]
|
||||
|
|
@ -28,3 +31,39 @@ chunksOf n xs@(_ : _)
|
|||
| otherwise =
|
||||
let (chunk, rest) = splitAt n xs
|
||||
in chunk : chunksOf n rest
|
||||
|
||||
-- | @wordWrap@ splits the given Text if it is longer than the given margin.
|
||||
--
|
||||
-- >>> :set -XOverloadedStrings
|
||||
-- >>> wordWrap 3 "abcdef"
|
||||
-- ["abc","def"]
|
||||
--
|
||||
-- >>> wordWrap 3 "abc"
|
||||
-- ["abc"]
|
||||
--
|
||||
-- >>> wordWrap 3 "ab"
|
||||
-- ["ab"]
|
||||
wordWrap :: Int -> Text -> [Text]
|
||||
wordWrap n text
|
||||
| n > 0 && T.length text > n =
|
||||
let (line, rest) = T.splitAt n text
|
||||
in line : wordWrap n rest
|
||||
| otherwise = pure text
|
||||
|
||||
data ScreenDimensions = ScreenDimensions
|
||||
{ screenRows :: Int
|
||||
, screenColumns :: Int
|
||||
}
|
||||
deriving (Show)
|
||||
|
||||
-- | @paginate@ transforms a given piece of Text into pages of lines that fit
|
||||
-- onto the screen.
|
||||
--
|
||||
-- >>> paginate ScreenDimensions{screenRows = 2, screenColumns = 2} "foo bar baz"
|
||||
-- ["fo\no \n","ba\nr \n","ba\nz\n"]
|
||||
paginate :: ScreenDimensions -> Text -> Pages
|
||||
paginate (ScreenDimensions rows cols) =
|
||||
fmap T.unlines . chunksOf rows . concatMap (wordWrap cols) . T.lines
|
||||
|
||||
type Pages = [Page]
|
||||
type Page = Text
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue