diff --git a/src/Text/Blaze/Renderer/XmlHtml.hs b/src/Text/Blaze/Renderer/XmlHtml.hs index 6d4c906..0e18832 100644 --- a/src/Text/Blaze/Renderer/XmlHtml.hs +++ b/src/Text/Blaze/Renderer/XmlHtml.hs @@ -3,15 +3,14 @@ -- -- Warning: because this renderer doesn't directly create the output, but -- rather an XML tree representation, it is impossible to render pre-escaped --- text. This means that @preEscapedString@ will produce the same output as --- @string@. This also applies to the functions @preEscapedText@, --- @preEscapedTextValue@... +-- 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 import Text.XmlHtml @@ -52,14 +51,18 @@ fromChoiceString EmptyChoiceString = id renderNodes :: Html -> [Node] -> [Node] renderNodes = go [] where - go :: [(Text, Text)] -> HtmlM b -> [Node] -> [Node] + 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 attrs (AddCustomAttribute key value content) = go ((fromChoiceStringText key, fromChoiceStringText value) : attrs) content go _ (Content content) = fromChoiceString content diff --git a/src/Text/XmlHtml.hs b/src/Text/XmlHtml.hs index 9be2881..325bede 100644 --- a/src/Text/XmlHtml.hs +++ b/src/Text/XmlHtml.hs @@ -56,7 +56,9 @@ module Text.XmlHtml ( parseHTML, -- * Rendering - render + render, + XML.renderXmlFragment, + HTML.renderHtmlFragment ) where ------------------------------------------------------------------------------ diff --git a/src/Text/XmlHtml/HTML/Parse.hs b/src/Text/XmlHtml/HTML/Parse.hs index 571e170..93601f5 100644 --- a/src/Text/XmlHtml/HTML/Parse.hs +++ b/src/Text/XmlHtml/HTML/Parse.hs @@ -239,9 +239,10 @@ attrValue = quotedAttrValue <|> unquotedAttrValue attribute :: Parser (Text, Text) attribute = do n <- attrName - _ <- optional XML.whiteSpace v <- optional $ do - _ <- P.char '=' + _ <- P.try $ do + _ <- optional XML.whiteSpace + P.char '=' _ <- optional XML.whiteSpace attrValue return $ maybe (n,"") (n,) v diff --git a/src/Text/XmlHtml/HTML/Render.hs b/src/Text/XmlHtml/HTML/Render.hs index 0b49502..3e57ded 100644 --- a/src/Text/XmlHtml/HTML/Render.hs +++ b/src/Text/XmlHtml/HTML/Render.hs @@ -230,6 +230,17 @@ ambiguousAmpersand _ = False ------------------------------------------------------------------------------ +-- | Function for rendering HTML nodes without the overhead of creating a +-- Document structure. +renderHtmlFragment :: Encoding -> [Node] -> Builder +renderHtmlFragment _ [] = mempty +renderHtmlFragment e (n:ns) = + firstNode e n `mappend` (mconcat $ map (node e) ns) + + +------------------------------------------------------------------------------ +-- | HTML allows & so long as it is not "ambiguous" (i.e., looks like an +-- entity). So we have a special case for that. escaped :: [Char] -> Encoding -> Text -> Builder escaped _ _ "" = mempty escaped bad e t = diff --git a/src/Text/XmlHtml/TextParser.hs b/src/Text/XmlHtml/TextParser.hs index 676fb21..7dc0141 100644 --- a/src/Text/XmlHtml/TextParser.hs +++ b/src/Text/XmlHtml/TextParser.hs @@ -2,7 +2,19 @@ {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} -module Text.XmlHtml.TextParser where +module Text.XmlHtml.TextParser +( guessEncoding +, parse +, isValidChar +, parseText +, takeWhile0 +, takeWhile1 +, text +, scanText +, ScanState(..) + +, module Text.Parsec.Text +) where import Control.Applicative import Data.Char @@ -12,13 +24,12 @@ import Text.XmlHtml.Common import Data.Text (Text) import qualified Data.Text as T -import Text.Parsec (Parsec) import qualified Text.Parsec as P +import Text.Parsec.Text import Data.ByteString (ByteString) import qualified Data.ByteString as B - ------------------------------------------------------------------------------ -- | Get an initial guess at document encoding from the byte order mark. If -- the mark doesn't exist, guess UTF-8. Otherwise, guess according to the @@ -30,18 +41,6 @@ guessEncoding b | B.take 2 b == B.pack [ 0xFF, 0xFE ] = (UTF16LE, B.drop 2 b) | otherwise = (UTF8, b) - ------------------------------------------------------------------------------- --- | Specialized type for the parsers we use here. -type Parser = Parsec Text () - - ------------------------------------------------------------------------------- --- An (orphaned) instance for parsing Text with Parsec. -instance (Monad m) => P.Stream T.Text m Char where - uncons = return . T.uncons - - ------------------------------------------------------------------------------ parse :: (Encoding -> Parser a) -> String -> ByteString -> Either String a parse p src b = let (e, b') = guessEncoding b diff --git a/src/Text/XmlHtml/XML/Render.hs b/src/Text/XmlHtml/XML/Render.hs index 848fe85..35395d1 100644 --- a/src/Text/XmlHtml/XML/Render.hs +++ b/src/Text/XmlHtml/XML/Render.hs @@ -25,6 +25,15 @@ render e dt ns = byteOrder `mappend` (mconcat $ map (node e) (tail ns)) +------------------------------------------------------------------------------ +-- | Function for rendering XML nodes without the overhead of creating a +-- Document structure. +renderXmlFragment :: Encoding -> [Node] -> Builder +renderXmlFragment _ [] = mempty +renderXmlFragment e (n:ns) = + firstNode e n `mappend` (mconcat $ map (node e) ns) + + ------------------------------------------------------------------------------ xmlDecl :: Encoding -> Builder xmlDecl e = fromText e "" == Right (HtmlDocument UTF8 Nothing [Element "test" [("attr", "")] []]) +emptyAttr2 :: Bool +emptyAttr2 = parseHTML "" "
" + == Right (HtmlDocument UTF8 Nothing [Element "div" [("itemscope", ""), ("itemtype", "type")] []]) + unquotedAttr :: Bool unquotedAttr = parseHTML "" "