M => +10 -10
@@ 12,7 12,7 @@
-- (Preceding context may limit the space available on the given page, but it
-- is assumed that the space on every following page can be used in full.)
module Data.Text.ParagraphLayout.Internal.LinePagination
( Line
( LineHeight
, lineHeight
, PageContinuity (Break, Continue)
, bestSplit
@@ 30,13 30,13 @@ import qualified Data.List.NonEmpty as NonEmpty
-- Lines are assumed to be tightly packed without overlaps,
-- so that the vertical space taken up by multiple lines
-- is equal to the sum of the height of each line.
class Line a where
class LineHeight a where
lineHeight :: a -> Int32
-- | A trivial instance of `Line` that is just a height.
-- | A trivial instance of `LineHeight` that is just a height.
--
-- For testing purposes.
instance Line Int32 where
instance LineHeight Int32 where
lineHeight = id
-- | Represents the best place to place a chunk of paginated content.
@@ 72,7 72,7 @@ data PageContinuity
--
-- The third component of the output contains all remaining lines. If non-empty,
-- these can be passed to this function again to produce more pages.
paginateLines :: Line a
paginateLines :: LineHeight a
=> Word
-- ^ Minimum number of lines to keep before a page break ("orphans"),
-- if possible.
@@ 136,7 136,7 @@ split1 xs = (take 1 xs, drop 1 xs)
-- as possible while satisfying the given constraints.
--
-- This is a low-level function that makes no compromises.
bestSplit :: Line a
bestSplit :: LineHeight a
=> Word
-- ^ Number of lines at the beginning ("orphans") to keep together.
-> Word
@@ 156,7 156,7 @@ bestSplit o w h ls = NonEmpty.last $ constrainedSplits o w h ls
-- not exceed @h@, the first @o@ lines ("orphans") are kept together,
-- and the last @w@ lines ("widows") are kept together.
constrainedSplits
:: Line a => Word -> Word -> Int32 -> [a] -> NonEmpty ([a], [a])
:: LineHeight a => Word -> Word -> Int32 -> [a] -> NonEmpty ([a], [a])
constrainedSplits o w h ls = zeroSplit :| dropWhileEnd violating splits
where
zeroSplit :| splits = fittingSplits h ls
@@ 168,7 168,7 @@ constrainedSplits o w h ls = zeroSplit :| dropWhileEnd violating splits
-- | Split a list of lines in every possible way, from shortest prefix
-- to longest, as long as the total of line heights in the prefix does
-- not exceed @h@.
fittingSplits :: Line a => Int32 -> [a] -> NonEmpty ([a], [a])
fittingSplits :: LineHeight a => Int32 -> [a] -> NonEmpty ([a], [a])
fittingSplits h ls = fmap snd $ zeroSplit :| takeWhile fitting splits
where
zeroSplit :| splits = splitsWithTotal ls
@@ 176,7 176,7 @@ fittingSplits h ls = fmap snd $ zeroSplit :| takeWhile fitting splits
-- | Split a list of lines in every possible way, from shortest prefix
-- to longest, and keep a running total of line heights in the prefix.
splitsWithTotal :: Line a => [a] -> NonEmpty (Int32, ([a], [a]))
splitsWithTotal :: LineHeight a => [a] -> NonEmpty (Int32, ([a], [a]))
splitsWithTotal ls = zeroSplit :| splits
where
zeroSplit = (zeroTotal, (zeroClosed, ls))
@@ 184,7 184,7 @@ splitsWithTotal ls = zeroSplit :| splits
zeroClosed = []
zeroTotal = 0
splitsWithTotal' :: Line a => Int32 -> [a] -> [a] -> [(Int32, ([a], [a]))]
splitsWithTotal' :: LineHeight a => Int32 -> [a] -> [a] -> [(Int32, ([a], [a]))]
splitsWithTotal' _ _ [] = []
splitsWithTotal' total closed (x : xs) = split : splits
where
M src/Data/Text/ParagraphLayout/Internal/Paginable.hs => src/Data/Text/ParagraphLayout/Internal/Paginable.hs +2 -2
@@ 67,7 67,7 @@ class Paginable pl where
paginate :: PageOptions -> pl -> (PageContinuity, pl, Maybe pl)
-- | Internal implementation of paginating a simple list of generic lines.
-instance Line a => Paginable [a] where
+instance LineHeight a => Paginable [a] where
paginate opts ls = case paginateLines o w h1 h2 ls of
(c, p, []) -> (c, p, Nothing)
(c, p, rest) -> (c, p, Just rest)
@@ 87,7 87,7 @@ instance Paginable (Plain.ParagraphLayout d) where
instance Paginable (Rich.ParagraphLayout d) where
paginate = paginateLayout
-paginateLayout :: (Line a, LineNumbers a, GenericLayout a) =>
+paginateLayout :: (LineHeight a, LineNumbers a, GenericLayout a) =>
PageOptions -> a -> (PageContinuity, a, Maybe a)
paginateLayout opts pl =
case paginate opts (cutLines pl) of
M src/Data/Text/ParagraphLayout/Internal/Plain/ParagraphLayout.hs => src/Data/Text/ParagraphLayout/Internal/Plain/ParagraphLayout.hs +1 -1
@@ 30,7 30,7 @@ data ParagraphLayout d = ParagraphLayout
instance LineNumbers (ParagraphLayout d) where
lineNumbersWithDuplication pl = map fragmentLine $ paragraphFragments pl
-instance Line (ParagraphLayout d) where
+instance LineHeight (ParagraphLayout d) where
lineHeight pl = height $ paragraphRect pl
-- | Wrap the given `SpanLayout`s and compute their containing rectangle.
M src/Data/Text/ParagraphLayout/Internal/Rich/ParagraphLayout.hs => src/Data/Text/ParagraphLayout/Internal/Rich/ParagraphLayout.hs +1 -1
@@ 34,7 34,7 @@ data ParagraphLayout d = ParagraphLayout
instance LineNumbers (ParagraphLayout d) where
lineNumbersWithDuplication pl = map fragmentLine $ paragraphFragments pl
-instance Line (ParagraphLayout d) where
+instance LineHeight (ParagraphLayout d) where
lineHeight pl = height $ paragraphRect pl
-- | Wrap the given `Fragment`s and compute their containing rectangle.