{-# LANGUAGE NoMonomorphismRestriction #-} module Text.HTML.Moe2.Renderer ( render , render' ) where import Text.HTML.Moe2.Element import Text.HTML.Moe2.Attribute import Text.HTML.Moe2.Utils import Text.HTML.Moe2.Type hiding (name, value) import qualified Text.HTML.Moe2.Type as T import Prelude hiding ((/), (-), head, (>), (.), concat, concatMap, (+)) import qualified Prelude as P import MPS.Env ((>), (.), times, belongs_to, reject) import Control.Monad.Writer (execWriter) import qualified Data.ByteString.Char8 as B import Data.DList (toList) import Data.List (intersperse) render :: MoeUnit -> String render = render' > B.unpack render' :: MoeUnit -> B.ByteString render' = execWriter > toList > map render_element > intercalate new_line > to_bs _indent_space :: Int _indent_space = 2 new_line :: Internal new_line = pack "\n" space :: Internal space = pack " " _indent :: Int -> Internal _indent n = (n * _indent_space).times space.concat render_element' :: Int -> Element -> Internal render_element' _ (Raw x) = x render_element' _ (Pre x) = x render_element' n (Prim x) = _indent n + x render_element' n (Data x) = _indent n + x render_element' n (Attributes xs e) = let xs' = e.attributes.reject (key > belongs_to (xs.map key)) ++ xs in render_element' n e {attributes = xs'} render_element' n x | x.self_close = [ _indent n , "<".pack , x.T.name , x.attributes.map render_attribute. join_attribute , " />".pack ] .concat | otherwise = [ self_indent , "<".pack , x.T.name , x.attributes.map render_attribute. join_attribute , ">".pack , inner_elements , "".pack ] .concat where self_indent = if x.indent then _indent n else "".pack join_attribute xs = xs.map (pack " " `append`) .concat inner_elements = if x.elements.null then "".pack else [ new_line , x.elements.map (render_element' (n P.+ 1)) .intersperse new_line .concat , new_line , self_indent ] .concat render_element :: Element -> Internal render_element = render_element' 0 render_attribute :: Attribute -> Internal render_attribute x = [x.key, pack "=", pack "\"", x.T.value, pack "\""].concat