> module TextDisplay(textDisplay) > where > import Project3A(linePackets) > import Project3B(justify) > import Project3C(columns) > import Project3D(table) > import TeamProjBSupport(bracketedBlocks) > import SequenceUtilities(apply, packets, splitFromRight) > import IOutilities(integralFromString, trim, trimRight) > import Char(isDigit) convert markup text to display text > textDisplay :: String -> String > textDisplay markupText = > (unlines . concat . map concat) displayParagraphsInSegments > where > (lineWidthDirective : markupLines) = lines markupText > markupParagraphs = packets isBreak markupLines > markupParagraphsInSegments = > map (bracketedBlocks isTableBegin isTableEnd) markupParagraphs > displayParagraphsInSegments = > map (zipWith apply markupConverters) markupParagraphsInSegments > markupConverters = cycle[paragraphLines lineWidth, tableLines] > lineWidth = > (integralFromString . takeWhile isDigit . > dropWhile(not . isDigit)) lineWidthDirective > textDisplay "" = "" detect break directive:
> isBreak :: String -> Bool > isBreak markupLine = > maybeDirective && br == "br" && null parameters > where > (maybeDirective, br, parameters) = parseDirective markupLine detect table begin directive: > isTableBegin :: String -> Bool > isTableBegin markupLine = > maybeDirective && table == "table" && length shape == 2 && > all isDigit c && all isDigit g > where > (maybeDirective, table, shape) = parseDirective markupLine > [c, g] = shape detect table end directive:
> isTableEnd :: String -> Bool > isTableEnd markupLine = > maybeDirective && command == "/table" && null parameters > where > (maybeDirective, command, parameters) = > parseDirective markupLine break a markup line into into its component parts if it's a directive > parseDirective :: String -> (Bool, String, [String]) > parseDirective markupLine > = (maybeDirective, command, parameters) > where > (open, restOfLine) = (splitAt 1 . trim) markupLine > (commandAndParameters, close) = break (== '>') restOfLine > (cmdSeq, parameters) = (splitAt 1 . words) commandAndParameters > command = last([""] ++ cmdSeq) > maybeDirective = open == "<" && close == ">" build display lines from paragraph lines in markup > paragraphLines :: Int -> [String] -> [String] > paragraphLines lineWidth paragraphMarkupLines = > map (justify lineWidth) allButLastPacket ++ [unwords lastPacket] > where > (allButLastPacket, lastPacketSequence) = > (splitFromRight 1 . linePackets lineWidth . > words . unlines) paragraphMarkupLines > lastPacket = last([[ ]] ++ lastPacketSequence) build display lines from table lines in markup > tableLines :: [String] -> [String] > tableLines(tableDirective : tableMarkupLines) = > (table g . columns c . map trimRight) tableMarkupLines > where > (_, _, [cAsString, gAsString]) = parseDirective tableDirective > c = integralFromString cAsString > g = integralFromString gAsString >