module Data.Text.ParagraphLayout.TextContainer (TextContainer ,getText ,setText ,splitTextAt8 ,splitTextsAt8 ) where import Data.Text (Text) import Data.Text.Foreign (I8, dropWord8, lengthWord8, takeWord8) class TextContainer a where getText :: a -> Text setText :: Text -> a -> a -- | Split a text container at the given number of `Word8` units -- from its beginning. splitTextAt8 :: TextContainer a => I8 -> a -> (a, a) splitTextAt8 n r = (setText text1 r, setText text2 r) where text1 = takeWord8 n $ getText r text2 = dropWord8 n $ getText r -- | Treat a list of text containers as a contiguous sequence, -- and make a split at the given number of `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 :: TextContainer a => I8 -> [a] -> ([a], [a]) splitTextsAt8 n rs = (pre, post) where pre = reverse rpre (rpre, post) = splitTextsAt8' n [] rs splitTextsAt8' :: TextContainer a => I8 -> [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 = fromIntegral $ lengthWord8 $ getText r