module Data.Text.ParagraphLayout.Internal.TextContainer (SeparableTextContainer ,TextContainer ,getText ,splitTextAt8 ,splitTextsAt8 ) where import Data.Text (Text) import Data.Text.Foreign (lengthWord8) -- | Class of data types containing `Text` that can be accessed. class TextContainer a where -- | Extract a `Text` from its container. getText :: a -> Text -- | Class of data types containing `Text` that can be split at a given number -- of `Data.Word.Word8` units from the start of the text. class TextContainer a => SeparableTextContainer a where -- | Split the given `SeparableTextContainer` at the given number of -- `Data.Word.Word8` units from the start of the text, preserving whatever -- constraints the instance requires. splitTextAt8 :: Int -> a -> (a, a) -- | Treat a list of text containers as a contiguous sequence, -- and make a split at the given number of `Data.Word.Word8` from the beginning -- of this sequence. -- -- If @n@ falls on a container boundary, the total number of output containers -- will equal the number of input containers; otherwise, it will be one larger. splitTextsAt8 :: SeparableTextContainer a => Int -> [a] -> ([a], [a]) splitTextsAt8 n rs = (pre, post) where pre = reverse rpre (rpre, post) = splitTextsAt8' n [] rs splitTextsAt8' :: SeparableTextContainer a => Int -> [a] -> [a] -> ([a], [a]) splitTextsAt8' _ rpre [] = (rpre, []) splitTextsAt8' n rpre (r:rs) | n <= 0 = (rpre, r:rs) | n >= l = splitTextsAt8' (n - l) (r:rpre) (rs) | otherwise = let (r1, r2) = splitTextAt8 n r in (r1:rpre, r2:rs) where l = lengthWord8 $ getText r