vty-ui-0.2: src/Text/Trans/Wrap.hs
-- |This module provides text-wrapping functionality.
module Text.Trans.Wrap
( wrap
, wrapLine
)
where
import Data.List ( intercalate )
-- |Given a position @p@ and string @s@, find the greatest string
-- index @i@ such that @i <= p@ and @s !! i@ is whitespace, or zero if
-- the string contains no whitespace.
findBreak :: Int -> String -> Int
findBreak 0 _ = 0
findBreak pos str = if str !! pos `elem` " \t"
then pos
else findBreak (pos - 1) str
-- |Given a column and string not containing newlines, break the
-- string into lines each having @length <= cols@.
wrapLine :: Int -> String -> [String]
wrapLine cols str
| length str <= cols = [str]
| otherwise = let breakpoint = findBreak cols str
first = take breakpoint str
rest = drop (breakpoint + 1) str
in if breakpoint /= 0
then first:(wrapLine cols rest)
else [str]
-- |Wraps the specified string (possibly containing newlines) at the
-- specified column and returns a new string with newlines inserted
-- where appropriate.
wrap :: Int -> String -> String
wrap cols s = intercalate "\n" $ concat $ map (wrapLine cols) $ lines s