module Data.Text.ParagraphLayout.Internal.Paginable (PageOptions(..) ,Paginable ,paginate ) where import Data.Int (Int32) import Data.Text.ParagraphLayout.Internal.LinePagination import Data.Text.ParagraphLayout.Internal.ParagraphLayout import Data.Text.ParagraphLayout.Internal.ParagraphLine data PageOptions = PageOptions { pageCurrentHeight :: Int32 -- ^ Amount of vertical space available for the paragraph -- on the current page. , pageNextHeight :: Int32 -- ^ Expected amount of vertical space available for the paragraph -- on the next page. -- -- If this is greater than `pageCurrentHeight`, the paragraph may be pushed -- onto the next page in order to better satisfy orphan/widow constraints. , pageOrphans :: Word -- ^ If a page break is required inside the paragraph, this will be the -- minimum number of lines to keep at the bottom of this page, if possible. , pageWidows :: Word -- ^ If a page break is required inside the paragraph, this will be the -- minimum number of lines to keep at the top of the next page, if possible. } -- | Typeclass for layouts that can be broken into pages. -- -- The first component of the output determines whether a page break should -- be inserted before the paragraph. -- -- The second component of the output contains the portion of the paragraph -- that fits on the page and satisfies the given constraints as much as -- possible. -- -- The third component of the output will be `Just` the remainder of the -- paragraph that can be passed to this function again, or `Nothing` if there -- is nothing left to put on further pages. class Paginable pl where paginate :: PageOptions -> pl -> (PageContinuity, pl, Maybe pl) instance Line 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) where o = pageOrphans opts w = pageWidows opts h1 = pageCurrentHeight opts h2 = pageNextHeight opts -- | Break a paragraph in order to fit the given pagination constraints. instance Paginable ParagraphLayout where paginate opts pl = case paginate opts (cutLines pl) of (c, p, Nothing) -> (c, mergeLines p, Nothing) (c, p, Just rest) -> (c, mergeLines p, Just (mergeLines rest))