-- | A module for rendering lines as an HTML5 file containing an SVG image. -- This can be used to visualize the denotational semantics of a MiniLogo -- program. -- -- NOTE: You should not change the definitions in this file! -- module Render (Point,Line,toHTML,toGridHTML) where import Data.List (intercalate) -- | A point is a cartesian pair (x,y). type Point = (Int,Int) -- | A line is defined by its endpoints. type Line = (Point,Point) -- | Output a list of lines as an HTML5 file containing an SVG image. toHTML :: [Line] -> IO () toHTML ls = writeFile "MiniMiniLogo.html" (header ++ content ls ++ footer) -- | Alternate version of 'toHTML' that adds a grid to the background. toGridHTML :: [Line] -> IO () toGridHTML ls = writeFile "MiniMiniLogo.html" (header ++ grid ++ content ls ++ footer) -- -- Private definitions. All definitions below this point will not be visible -- from within a module that imports this module. -- scale, margin, width, height :: Int scale = 10 margin = 10 width = 800 height = 400 gridStep = 5 maxX = width `div` scale maxY = height `div` scale gridStyle = "fill:none;stroke:lightgrey;stroke-width:1" drawStyle = "fill:none;stroke:red;stroke-width:2" title = "MiniLogo Semantics Viewer" view = "" border = "" header = unlines ["", "", title, "", view, border] footer = unlines ["","",""] grid = unlines (map (poly gridStyle) lines) where lines = [ [(x,0), (x,maxY)] | x <- [0,gridStep..maxX] ] ++ [ [(0,y), (maxX,y)] | y <- [0,gridStep..maxY] ] content :: [Line] -> String content = unlines . map (poly drawStyle) . chunk -- | A canvas-adjusted point as a string. point :: Point -> String point (x,y) = show xp ++ "," ++ show yp where xp = x*scale + margin yp = height - y*scale + margin -- | Chunk a bunch of lines into sequences of connected points. chunk :: [Line] -> [[Point]] chunk [] = [] chunk [(p,q)] = [[p,q]] chunk ((p,q):ls) | q == head ps = (p:ps) : pss | otherwise = [p,q] : ps : pss where (ps:pss) = chunk ls -- | Draw a sequence of connected points. poly :: String -> [Point] -> String poly style ps = ""