{- / \ / \ |\ / \ / \ chiral software | \ / \ \ \ |\ /| /| \| \ / |/ | |\ | /| / | \|/ |/ \ | / \|/ -} {- Note that these combinators assume that the fromDictForm transformation has _not_ taken place, the transformation is built into the 'raw' formatter. -} module DendraFormatters( Formatter, raw, ender, indent, formatList, formatDict ) where import Dict import Dendra -- exported type Formatter = Dendra -> String raw :: Formatter ender :: Formatter -> Formatter indent :: Int -> Formatter -> Formatter vertList :: Int -> Formatter -> [Dendra] -> String formatList :: Int -> -- open par indent Int -> -- number of leading items to put on first line Int -> -- indent of remaining lines Int -> -- close par indent Formatter -> -- formatter for remaining lines Bool -> -- put close par on own line ? Formatter formatDict :: Int -> -- open par indent Int -> -- key indent Int -> -- minimum value indent Formatter -> -- default formatter [(String,Formatter)] -> -- Explicit keys, will be printed -- one per line in this order. -- Use "break" for a black line. -- Keys not mentioned will be printed -- in random order at the end. Formatter -- internal spaces n = take n (repeat ' ') raw = printDendra . fromDictForm ender f d = f d ++ "\n" indent n f d = spaces n ++ f d formatList pi n vi li f b (DendraList l) = concat [ spaces pi, "(", foldr (\d s->raw d ++ " " ++ s) "" leading, vertList vi f rest, if b then "\n" ++ spaces li else "", ")" ] where (leading,rest) = splitAt n l vertList n f [] = [] vertList n f (d:ds) = "\n" ++ ((indent n) f) d ++ vertList n f ds formatDict si ki vi deff ekeys (DendraDict d) = concat [ spaces si, "(dict\n", elines, nlines, spaces si, ")\n" ] where (elines,notUsed) = makeLines ekeys d nlines = foldl f [] (listDict notUsed) where f s (k,v) = s ++ keyAndValue ki vi k v deff makeLines [] d =([],d) makeLines (("break",f):fks) d = ("\n"++re,rd) where (re,rd) = makeLines fks d makeLines ((k,f):fks) d = if d `has` k then (keyAndValue ki vi k (d `get` k) f ++ re,rd) else (re,rd) where (re,rd) = makeLines fks (d `del` k) keyAndValue ki vi k v f = spaces ki ++ kStr ++ filler ++ f v ++ "\n" where kStr = raw (DendraString k) kLen = length kStr filler = if kLen >= (vi - ki) then " " else spaces (vi - ki - kLen)