{-# LANGUAGE Arrows, RecursiveDo, EmptyDataDecls, TemplateHaskell, PostfixOperators, FlexibleContexts #-} module Document.Grammars.Html where import Prelude hiding ((+), (*)) import Data.Char import Control.Applicative import Language.Grammars.Grammar import Language.Grammars.Murder import Language.Grammars.Murder.Derive import Language.Grammars.Murder.UUParsing import Language.Grammars.AspectAG import Document.Decl import Utils -- Generate the labels used as lookup keys in the exportlist $(csLabels ["cs_document", "cs_blockL", "cs_paragraph", "cs_header", "cs_inline", "cs_inlineL"]) {- -- | Recognizes a header at level x, i.e. " ... " headerLvl :: (int -> inlines -> a) -- ^ The semantic function -> Symbol inlines TNonT env -- ^ The non terminal to be recognized between the tags -> Int -- ^ The level -> PreProductions l env a -} headerLvl pHeader body x = let open = "" close = "" in iI (pHeader x) open body close Ii -- | The grammar for a simplified version of Html gHtml sem = proc () -> do rec document <-addNT-< iI (pDocument sem) blockL Ii blockL <-addNT-< pFoldr (pBlockL_Cons sem, pBlockL_Nil sem) $ (iI header Ii) <|> (iI paragraph Ii) paragraph <-addNT-< iI (pParagraph sem) "

" inlineL "

" Ii header <-addNT-< foldr1 (<|>) $ map (headerLvl (pHeader sem) inlineL) [1..6] -- this seperation is required for the inlines non-terminal inline <-addNT-< iI (pPlain sem) "" (someExcept "<") "" Ii <|> iI (pBold sem) "" inlineL "" Ii <|> iI (pItalics sem) "" inlineL "" Ii -- Multiple inlines inlineL <-addNT-< pFoldr (pInlineL_Cons sem, pInlineL_Nil sem) $ iI inline Ii exportNTs -< exportList document ( export cs_document document . export cs_blockL blockL . export cs_paragraph paragraph . export cs_header header . export cs_inline inline . export cs_inlineL inlineL)