module Data.Text.ParagraphLayout.PrettyShow ( PrettyShow , prettyShow , Pages (..) , ShapedRuns (..) ) where import Data.List (intersperse) import Data.Text.ParagraphLayout import Data.Text.ParagraphLayout.Internal.Fragment (ShapedRun) import qualified Data.Text.ParagraphLayout.Plain as Plain class PrettyShow a where prettyShow :: a -> String newtype ShapedRuns = ShapedRuns { getShapedRuns :: [ShapedRun] } deriving (Eq) instance PrettyShow ShapedRuns where prettyShow (ShapedRuns xs) = concat $ commaFirstList indent0 $ map (prettyShow . ShapedRun') xs newtype ShapedRun' = ShapedRun' ShapedRun instance PrettyShow ShapedRun' where prettyShow (ShapedRun' (x, y, glyphs)) = concat [ "(" , show x , ", " , show y , ", " , newline , concat $ commaFirstList indent1 $ map prettyShowPair glyphs , ")" ] type Page = (PageContinuity, Plain.ParagraphLayout) newtype Pages = Pages { getPages :: [Page] } deriving (Eq) instance PrettyShow Pages where prettyShow (Pages ps) = concat (commaFirstList indent0 $ map (prettyShow . Page') ps) ++ newline newtype Page' = Page' Page instance PrettyShow Page' where prettyShow (Page' (c, pl)) = concat [ "(" , show c , ", " , prettyShow pl , ")" ] instance PrettyShow Plain.ParagraphLayout where prettyShow (Plain.ParagraphLayout pr sls) = concat [ "ParagraphLayout" , newline , indent1 , "{ paragraphRect = " , show pr , newline , indent1 , ", spanLayouts = [" , newline , concat $ commaAloneList indent2 $ map prettyShow sls , newline , indent1 , "]}" , newline ] instance PrettyShow Plain.SpanLayout where prettyShow (Plain.SpanLayout frags) = concat [ "SpanLayout" , newline , concat $ commaFirstList indent2 $ map prettyShow frags ] instance PrettyShow Plain.Fragment where prettyShow (Plain.Fragment r pen glyphs) = concat [ "Fragment" , newline , indent3 , "{ fragmentRect = " , show r , newline , indent3 , ", fragmentPen = " , prettyShowPair pen , newline , indent3 , ", fragmentGlyphs =" , newline , concat $ commaFirstList indent4 $ map prettyShowPair glyphs , newline , indent3 , "}" ] prettyShowPair :: (Show a, Show b) => (a, b) -> String prettyShowPair (a, b) = "(" ++ show a ++ ", " ++ show b ++ ")" commaAloneList :: String -> [String] -> [String] commaAloneList indent items = map (indent ++) $ suffixInit newline $ intersperse "," $ items commaFirstList :: String -> [String] -> [String] commaFirstList indent [] = [indent ++ "[]"] commaFirstList indent items = prefixHead (indent ++ "[ ") $ prefixTail (indent ++ ", ") $ suffixInit newline $ suffixLast (newline ++ indent ++ "]") $ items suffixInit :: String -> [String] -> [String] suffixInit suffix = mapInit (++ suffix) mapInit :: (a -> a) -> [a] -> [a] mapInit _ [] = [] mapInit _ [x] = [x] mapInit f (x : y : ys) = f x : mapInit f (y : ys) prefixTail :: String -> [String] -> [String] prefixTail prefix = mapTail (prefix ++) mapTail :: (a -> a) -> [a] -> [a] mapTail _ [] = [] mapTail f (x : xs) = x : (map f xs) prefixHead :: String -> [String] -> [String] prefixHead prefix = mapHead (prefix ++) mapHead :: (a -> a) -> [a] -> [a] mapHead _ [] = [] mapHead f (x : xs) = f x : xs suffixLast :: String -> [String] -> [String] suffixLast suffix = mapLast (++ suffix) mapLast :: (a -> a) -> [a] -> [a] mapLast _ [] = [] mapLast f [x] = [f x] mapLast f (x : y : ys) = x : mapLast f (y : ys) indent0 :: String indent0 = "" indent1 :: String indent1 = " " indent2 :: String indent2 = indent1 ++ indent1 indent3 :: String indent3 = indent1 ++ indent2 indent4 :: String indent4 = indent1 ++ indent3 newline :: String newline = "\n"