{-# LANGUAGE FlexibleInstances, NoMonomorphismRestriction, GeneralizedNewtypeDeriving, FlexibleContexts, EmptyDataDecls, MultiParamTypeClasses, FunctionalDependencies, GADTs #-} --------------------------------------------------------------------------- -- | -- Module : HGene.HtmlWriterInternals -- License : http://www.gnu.org/copyleft/gpl.html -- -- Maintainer : mmirman@andrew.cmu.edu -- Stability : experimental -- Portability : probable -- -- The xml writer. -- TODO: Use the module redirect tequnique to exclude items we don't want. module Language.XmlHtml.XmlWriter where import Control.Monad.Trans import Control.Monad.Writer.Strict (WriterT, tell, execWriterT) import Control.Monad.Writer.Class (MonadWriter(..)) void a = a >> return () -- -------------------------------------------------------------------------- -- Type definition for the HtmlWriter newtype HtmlWriter a = HtmlWriter { getHtml :: WriterT String IO a} deriving (Monad, MonadWriter String) liftIO t = HtmlWriter $ lift t -- | @'writeString' s@ writes a string to the html writer monad writeString = tell -- | @'makeHtml' s@ currently just converts this into a string makeXml = execWriterT . getHtml . printThis data End data Par data Param a b where Param :: Printable a b => [HtmlAttr] -> a -> Param a b data Elem a b where Elem :: Printable a b => String -> a -> Elem a b data HtmlAttr = Attr String String instance Show HtmlAttr where show (Attr a b) = a++"="++b -- -------------------------------------------------------------------------- -- Printable allows us to use tag for either a monad or a string or whatever -- just makes syntax better, and ideally in the future, everything better. class Printable a b | a -> b where printThis :: a -> HtmlWriter () instance Printable [Char] End where printThis = writeString instance Printable (HtmlWriter a) End where printThis = void instance Printable a Par => Printable (Elem a Par) End where printThis (Elem tg msg) = do writeString $ "<"++tg printThis msg writeString $ "\n" instance Printable a End => Printable (Elem a End) End where printThis (Elem tg msg) = do writeString $ "<"++tg++">\n" printThis msg writeString $ "\n" instance Printable a Par => Printable (Param a Par) Par where printThis (Param params msg) = do printThis $ showMiddle params printThis msg instance Printable a End => Printable (Param a End) Par where printThis (Param params msg) = do printThis $ showMiddle params++">\n" printThis msg showMiddle = concatMap (\x -> " "++show x) tag tg = printThis . Elem tg