M balkon.cabal => balkon.cabal +1 -0
@@ 137,6 137,7 @@ library balkon-internal
-- Modules used purely internally and not in any tests.
other-modules:
Data.Text.ParagraphLayout.Internal.Layout,
+ Data.Text.ParagraphLayout.Internal.LineNumbers,
Data.Text.ParagraphLayout.Internal.ParagraphExtents,
Data.Text.ParagraphLayout.Internal.ParagraphLine,
Data.Text.ParagraphLayout.Internal.ProtoFragment,
A src/Data/Text/ParagraphLayout/Internal/LineNumbers.hs => src/Data/Text/ParagraphLayout/Internal/LineNumbers.hs +23 -0
@@ 0,0 1,23 @@
+module Data.Text.ParagraphLayout.Internal.LineNumbers
+ ( LineNumbers
+ , lineNumbers
+ , lineNumbersWithDuplication
+ )
+where
+
+import qualified Data.List.NonEmpty as NonEmpty
+
+-- | Data types that contain numbered lines.
+class LineNumbers ml where
+
+ -- | A list of all line numbers in ascending order,
+ -- with possible duplicates.
+ lineNumbersWithDuplication :: ml -> [Int]
+
+-- | A list of all unique line numbers, in ascending order.
+lineNumbers :: (LineNumbers ml) => ml -> [Int]
+lineNumbers ml = dedupe $ lineNumbersWithDuplication ml
+
+-- | Remove duplicates from a sorted list.
+dedupe :: Eq a => [a] -> [a]
+dedupe xs = map NonEmpty.head $ NonEmpty.group xs
M src/Data/Text/ParagraphLayout/Internal/Paginable.hs => src/Data/Text/ParagraphLayout/Internal/Paginable.hs +2 -1
@@ 8,6 8,7 @@ where
import Data.Int (Int32)
+import Data.Text.ParagraphLayout.Internal.LineNumbers
import Data.Text.ParagraphLayout.Internal.LinePagination
import Data.Text.ParagraphLayout.Internal.ParagraphLine
import qualified Data.Text.ParagraphLayout.Internal.Plain.ParagraphLayout
@@ 86,7 87,7 @@ instance Paginable (Plain.ParagraphLayout d) where
instance Paginable (Rich.ParagraphLayout d) where
paginate = paginateLayout
-paginateLayout :: (Line a, GenericLayout a) =>
+paginateLayout :: (Line 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/ParagraphLine.hs => src/Data/Text/ParagraphLayout/Internal/ParagraphLine.hs +2 -14
@@ 7,9 7,9 @@ module Data.Text.ParagraphLayout.Internal.ParagraphLine
where
import Data.Int (Int32)
-import qualified Data.List.NonEmpty as NonEmpty
import Data.Text.ParagraphLayout.Internal.Fragment
+import Data.Text.ParagraphLayout.Internal.LineNumbers
import qualified Data.Text.ParagraphLayout.Internal.Plain.ParagraphLayout as P
import qualified Data.Text.ParagraphLayout.Internal.Rich.ParagraphLayout as R
import Data.Text.ParagraphLayout.Internal.Rect
@@ 25,9 25,6 @@ class GenericLayout pl where
-- | Actual distance between the paragraph origin and the nearest fragment.
topDistance :: pl -> Int32
- -- | A list of all unique line numbers that have laid out content.
- lineNumbers :: pl -> [Int]
-
-- | Keep only fragments with the given line number.
limitFragments :: Int -> pl -> pl
@@ 42,7 39,6 @@ instance GenericLayout (P.ParagraphLayout d) where
empty = P.emptyParagraphLayout
rect = P.paragraphRect
topDistance pl = topFragmentOrigin $ P.paragraphFragments pl
- lineNumbers pl = uniqueFragmentLines $ P.paragraphFragments pl
limitFragments n = P.filterFragments (fragmentIsOnLine n)
shiftFragments dy = P.mapFragments (shiftFragment dy)
appendFragments = P.appendFragments
@@ 51,13 47,12 @@ instance GenericLayout (R.ParagraphLayout d) where
empty = R.emptyParagraphLayout
rect = R.paragraphRect
topDistance pl = topFragmentOrigin $ R.paragraphFragments pl
- lineNumbers pl = uniqueFragmentLines $ R.paragraphFragments pl
limitFragments n = R.filterFragments (fragmentIsOnLine n)
shiftFragments dy = R.mapFragments (shiftFragment dy)
appendFragments = R.appendFragments
-- | Split the given paragraph layout into single-line layouts.
-cutLines :: GenericLayout pl => pl -> [pl]
+cutLines :: (GenericLayout pl, LineNumbers pl) => pl -> [pl]
cutLines pl = map (\ n -> cutLine n pl) (lineNumbers pl)
-- | Reduce the given paragraph layout to fragments with the given line number.
@@ 71,13 66,6 @@ trimTop pl = shiftFragments (-topDistance pl) pl
topFragmentOrigin :: [Fragment d] -> Int32
topFragmentOrigin frags = maximum $ map (y_origin . fragmentRect) frags
-uniqueFragmentLines :: [Fragment d] -> [Int]
-uniqueFragmentLines frags = dedupe $ map fragmentLine frags
-
--- | Remove duplicates from a sorted list.
-dedupe :: Eq a => [a] -> [a]
-dedupe xs = map NonEmpty.head $ NonEmpty.group xs
-
-- | Put the given paragraph layouts together as a vertically contiguous
-- sequence.
mergeLines :: GenericLayout pl => [pl] -> pl
M src/Data/Text/ParagraphLayout/Internal/Plain/ParagraphLayout.hs => src/Data/Text/ParagraphLayout/Internal/Plain/ParagraphLayout.hs +4 -0
@@ 13,6 13,7 @@ where
import Data.Int (Int32)
import Data.Text.ParagraphLayout.Internal.Fragment
+import Data.Text.ParagraphLayout.Internal.LineNumbers
import Data.Text.ParagraphLayout.Internal.LinePagination
import Data.Text.ParagraphLayout.Internal.ParagraphExtents
import Data.Text.ParagraphLayout.Internal.Rect
@@ 26,6 27,9 @@ data ParagraphLayout d = ParagraphLayout
}
deriving (Eq, Read, Show)
+instance LineNumbers (ParagraphLayout d) where
+ lineNumbersWithDuplication pl = map fragmentLine $ paragraphFragments pl
+
instance Line (ParagraphLayout d) where
lineHeight pl = height $ paragraphRect pl
M src/Data/Text/ParagraphLayout/Internal/Rich/ParagraphLayout.hs => src/Data/Text/ParagraphLayout/Internal/Rich/ParagraphLayout.hs +4 -0
@@ 14,6 14,7 @@ where
import Data.Int (Int32)
import Data.Text.ParagraphLayout.Internal.Fragment
+import Data.Text.ParagraphLayout.Internal.LineNumbers
import Data.Text.ParagraphLayout.Internal.LinePagination
import Data.Text.ParagraphLayout.Internal.ParagraphExtents
import Data.Text.ParagraphLayout.Internal.Rect
@@ 29,6 30,9 @@ data ParagraphLayout d = ParagraphLayout
}
deriving (Eq, Read, Show)
+instance LineNumbers (ParagraphLayout d) where
+ lineNumbersWithDuplication pl = map fragmentLine $ paragraphFragments pl
+
instance Line (ParagraphLayout d) where
lineHeight pl = height $ paragraphRect pl