{-# LANGUAGE CPP #-} -- | Renderer that supports rendering to xmlhtml forests. This is a port of -- the Hexpat renderer. -- -- Warning: because this renderer doesn't directly create the output, but -- rather an XML tree representation, it is impossible to render pre-escaped -- text. -- module Text.Blaze.Renderer.XmlHtml (renderHtml, renderHtmlNodes) where import Data.Text (Text) import qualified Data.Text as T import qualified Data.Text.Encoding as T import Text.Blaze.Html import Text.Blaze.Internal as TBI import Text.XmlHtml as X -- | Render a 'ChoiceString' to Text. This is only meant to be used for -- shorter strings, since it is inefficient for large strings. -- fromChoiceStringText :: ChoiceString -> Text fromChoiceStringText (Static s) = getText s fromChoiceStringText (String s) = T.pack s fromChoiceStringText (Text s) = s fromChoiceStringText (ByteString s) = T.decodeUtf8 s fromChoiceStringText (PreEscaped s) = fromChoiceStringText s fromChoiceStringText (External s) = fromChoiceStringText s fromChoiceStringText (AppendChoiceString x y) = fromChoiceStringText x `T.append` fromChoiceStringText y fromChoiceStringText EmptyChoiceString = T.empty {-# INLINE fromChoiceStringText #-} -- | Render a 'ChoiceString' to an appending list of nodes -- fromChoiceString :: ChoiceString -> [Node] -> [Node] fromChoiceString s@(Static _) = (TextNode (fromChoiceStringText s) :) fromChoiceString s@(String _) = (TextNode (fromChoiceStringText s) :) fromChoiceString s@(Text _) = (TextNode (fromChoiceStringText s) :) fromChoiceString s@(ByteString _) = (TextNode (fromChoiceStringText s) :) fromChoiceString (PreEscaped s) = fromChoiceString s fromChoiceString (External s) = fromChoiceString s fromChoiceString (AppendChoiceString x y) = fromChoiceString x . fromChoiceString y fromChoiceString EmptyChoiceString = id {-# INLINE fromChoiceString #-} -- | Render some 'Html' to an appending list of nodes -- renderNodes :: Html -> [Node] -> [Node] renderNodes = go [] where go :: [(Text, Text)] -> MarkupM a -> [Node] -> [Node] go attrs (Parent tag _ _ content) = (Element (getText tag) attrs (go [] content []) :) go attrs (CustomParent tag content) = (Element (fromChoiceStringText tag) attrs (go [] content []) :) go attrs (Leaf tag _ _ _) = (Element (getText tag) attrs [] :) go attrs (CustomLeaf tag _ _) = (Element (fromChoiceStringText tag) attrs [] :) go attrs (AddAttribute key _ value content) = go ((getText key, fromChoiceStringText value) : attrs) content go attrs (AddCustomAttribute key value content) = go ((fromChoiceStringText key, fromChoiceStringText value) : attrs) content go _ (Content content _) = fromChoiceString content #if MIN_VERSION_blaze_markup(0,6,3) go _ (TBI.Comment comment _) = (X.Comment (fromChoiceStringText comment) :) #endif go attrs (Append h1 h2) = go attrs h1 . go attrs h2 go _ (Empty _) = id {-# NOINLINE go #-} {-# INLINE renderNodes #-} -- | Render HTML to an xmlhtml 'Document' -- renderHtml :: Html -> Document renderHtml html = HtmlDocument UTF8 Nothing (renderNodes html []) {-# INLINE renderHtml #-} -- | Render HTML to a list of xmlhtml nodes -- renderHtmlNodes :: Html -> [Node] renderHtmlNodes = flip renderNodes []