diff --git a/haddock.sh b/haddock.sh
--- a/haddock.sh
+++ b/haddock.sh
@@ -8,6 +8,5 @@
 
 cabal haddock $HADDOCK_OPTS --hyperlink-source $@
 
-cp -r extra/fonts dist/doc/html/xmlhtml/
 cp extra/logo.gif dist/doc/html/xmlhtml/haskell_icon.gif
 cp extra/hscolour.css dist/doc/html/xmlhtml/src/
diff --git a/src/Text/XmlHtml.hs b/src/Text/XmlHtml.hs
--- a/src/Text/XmlHtml.hs
+++ b/src/Text/XmlHtml.hs
@@ -56,7 +56,9 @@
     parseHTML,
 
     -- * Rendering
-    render
+    render,
+    XML.renderXmlFragment,
+    HTML.renderHtmlFragment
     ) where
 
 ------------------------------------------------------------------------------
diff --git a/src/Text/XmlHtml/HTML/Meta.hs b/src/Text/XmlHtml/HTML/Meta.hs
--- a/src/Text/XmlHtml/HTML/Meta.hs
+++ b/src/Text/XmlHtml/HTML/Meta.hs
@@ -1,27 +1,29 @@
 {-# OPTIONS_GHC -O0 -fno-case-merge -fno-strictness -fno-cse #-}
-{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE OverloadedStrings           #-}
 
 module Text.XmlHtml.HTML.Meta where
 
 import           Data.Monoid
-import           Data.Map (Map)
-import qualified Data.Map as M
-import           Data.Set (Set)
-import qualified Data.Set as S
+import           Data.HashMap.Strict (HashMap)
+import qualified Data.HashMap.Strict as M
+import           Data.HashSet (HashSet)
+import qualified Data.HashSet as S
 import           Data.Text (Text)
 
 ------------------------------------------------------------------------------
 -- Metadata used for HTML5 quirks mode.                                     --
 ------------------------------------------------------------------------------
 
-voidTags :: Set Text
-voidTags = S.fromAscList [
+{-# NOINLINE voidTags #-}
+voidTags :: HashSet Text
+voidTags = S.fromList [
     "area", "base", "br", "col", "command", "embed", "hr", "img", "input",
     "keygen", "link", "meta", "param", "source", "track", "wbr"
     ]
 
-rawTextTags :: Set Text
-rawTextTags = S.fromAscList [ "script", "style" ]
+{-# NOINLINE rawTextTags #-}
+rawTextTags :: HashSet Text
+rawTextTags = S.fromList [ "script", "style" ]
 
 ------------------------------------------------------------------------------
 -- | Tags which can be implicitly ended in case they are the last element in
@@ -31,8 +33,9 @@
 -- because in a complete document it isn't expected to ever be the last thing
 -- in its parent.  We aren't interested in enforcing element structure rules,
 -- so we'll allow it anyway.
-endOmittableLast :: Set Text
-endOmittableLast = S.fromAscList [
+{-# NOINLINE endOmittableLast #-}
+endOmittableLast :: HashSet Text
+endOmittableLast = S.fromList [
     "body", "colgroup", "dd", "dt", "head", "html", "li", "optgroup",
     "option", "p", "rp", "rt", "tbody", "td", "tfoot", "th", "thead", "tr"
     ]
@@ -40,33 +43,35 @@
 ------------------------------------------------------------------------------
 -- | Tags which should be considered automatically ended in case one of a
 -- certain set of tags pops up.
-endOmittableNext :: Map Text (Set Text)
-endOmittableNext = M.fromAscList [
-    ("colgroup", S.fromAscList ["caption", "colgroup", "tbody",
-                                "thead", "tfoot", "tr"]),
-    ("dd",       S.fromAscList ["dd", "dt"]),
-    ("dt",       S.fromAscList ["dd", "dt"]),
-    ("head",     S.fromAscList ["body"]),
-    ("li",       S.fromAscList ["li"]),
-    ("optgroup", S.fromAscList ["optgroup"]),
-    ("option",   S.fromAscList ["optgroup", "option"]),
-    ("p",        S.fromAscList ["address", "article", "aside", "blockquote",
-                                "dir", "div", "dl", "fieldset", "footer",
-                                "form", "h1", "h2", "h3", "h4", "h5", "h6",
-                                "header", "hgroup", "hr", "menu", "nav", "ol",
-                                "p", "pre", "section", "table", "ul"]),
-    ("rp",       S.fromAscList ["rp", "rt"]),
-    ("rt",       S.fromAscList ["rp", "rt"]),
-    ("tbody",    S.fromAscList ["tbody", "tfoot", "thead"]),
-    ("td",       S.fromAscList ["td", "th"]),
-    ("tfoot",    S.fromAscList ["tbody", "tfoot", "thead"]),
-    ("th",       S.fromAscList ["td", "th"]),
-    ("thead",    S.fromAscList ["tbody", "tfoot", "thead"]),
-    ("tr",       S.fromAscList ["tr"])
+{-# NOINLINE endOmittableNext #-}
+endOmittableNext :: HashMap Text (HashSet Text)
+endOmittableNext = M.fromList [
+    ("colgroup", S.fromList ["caption", "colgroup", "tbody",
+                             "thead", "tfoot", "tr"]),
+    ("dd",       S.fromList ["dd", "dt"]),
+    ("dt",       S.fromList ["dd", "dt"]),
+    ("head",     S.fromList ["body"]),
+    ("li",       S.fromList ["li"]),
+    ("optgroup", S.fromList ["optgroup"]),
+    ("option",   S.fromList ["optgroup", "option"]),
+    ("p",        S.fromList ["address", "article", "aside", "blockquote",
+                             "dir", "div", "dl", "fieldset", "footer",
+                             "form", "h1", "h2", "h3", "h4", "h5", "h6",
+                             "header", "hgroup", "hr", "menu", "nav", "ol",
+                             "p", "pre", "section", "table", "ul"]),
+    ("rp",       S.fromList ["rp", "rt"]),
+    ("rt",       S.fromList ["rp", "rt"]),
+    ("tbody",    S.fromList ["tbody", "tfoot", "thead"]),
+    ("td",       S.fromList ["td", "th"]),
+    ("tfoot",    S.fromList ["tbody", "tfoot", "thead"]),
+    ("th",       S.fromList ["td", "th"]),
+    ("thead",    S.fromList ["tbody", "tfoot", "thead"]),
+    ("tr",       S.fromList ["tr"])
     ]
 
-predefinedRefs :: Map Text Text
-predefinedRefs = mconcat $ map M.fromAscList [
+{-# NOINLINE predefinedRefs #-}
+predefinedRefs :: HashMap Text Text
+predefinedRefs = mconcat $ map M.fromList [
       reftab1
     , reftab2
     , reftab3
@@ -127,6 +132,7 @@
     , reftab58 ]
 
 
+{-# NOINLINE reftab1 #-}
 reftab1 :: [(Text,Text)]
 reftab1 =
   [ ("AElig", "\x000C6"),
@@ -167,6 +173,7 @@
     ("CapitalDifferentialD", "\x02145"),
     ("Cayleys", "\x0212D") ]
 
+{-# NOINLINE reftab2 #-}
 reftab2 :: [(Text,Text)]
 reftab2 =
   [ ("Ccaron", "\x0010C"),
@@ -207,6 +214,7 @@
     ("Dashv", "\x02AE4"),
     ("Dcaron", "\x0010E") ]
 
+{-# NOINLINE reftab3 #-}
 reftab3 :: [(Text,Text)]
 reftab3 =
   [ ("Dcy", "\x00414"),
@@ -247,6 +255,7 @@
     ("DownLeftVector", "\x021BD"),
     ("DownLeftVectorBar", "\x02956") ]
 
+{-# NOINLINE reftab4 #-}
 reftab4 :: [(Text,Text)]
 reftab4 =
   [ ("DownRightTeeVector", "\x0295F"),
@@ -287,6 +296,7 @@
     ("FilledSmallSquare", "\x025FC"),
     ("FilledVerySmallSquare", "\x025AA") ]
 
+{-# NOINLINE reftab5 #-}
 reftab5 :: [(Text,Text)]
 reftab5 =
   [ ("Fopf", "\x1D53D"),
@@ -327,6 +337,7 @@
     ("HumpDownHump", "\x0224E"),
     ("HumpEqual", "\x0224F") ]
 
+{-# NOINLINE reftab6 #-}
 reftab6 :: [(Text,Text)]
 reftab6 =
   [ ("IEcy", "\x00415"),
@@ -367,6 +378,7 @@
     ("Kcedil", "\x00136"),
     ("Kcy", "\x0041A") ]
 
+{-# NOINLINE reftab7 #-}
 reftab7 :: [(Text,Text)]
 reftab7 =
   [ ("Kfr", "\x1D50E"),
@@ -407,6 +419,7 @@
     ("LeftVector", "\x021BC"),
     ("LeftVectorBar", "\x02952") ]
 
+{-# NOINLINE reftab8 #-}
 reftab8 :: [(Text,Text)]
 reftab8 =
   [ ("Leftarrow", "\x021D0"),
@@ -447,6 +460,7 @@
     ("Nacute", "\x00143"),
     ("Ncaron", "\x00147") ]
 
+{-# NOINLINE reftab9 #-}
 reftab9 :: [(Text,Text)]
 reftab9 =
   [ ("Ncedil", "\x00145"),
@@ -487,6 +501,7 @@
     ("NotLessGreater", "\x02278"),
     ("NotLessLess", "\x0226A\x00338") ]
 
+{-# NOINLINE reftab10 #-}
 reftab10 :: [(Text,Text)]
 reftab10 =
   [ ("NotLessSlantEqual", "\x02A7D\x00338"),
@@ -527,6 +542,7 @@
     ("Odblac", "\x00150"),
     ("Ofr", "\x1D512") ]
 
+{-# NOINLINE reftab11 #-}
 reftab11 :: [(Text,Text)]
 reftab11 =
   [ ("Ograve", "\x000D2"),
@@ -567,6 +583,7 @@
     ("Psi", "\x003A8"),
     ("QUOT", "\x00022") ]
 
+{-# NOINLINE reftab12 #-}
 reftab12 :: [(Text,Text)]
 reftab12 =
   [ ("Qfr", "\x1D514"),
@@ -607,6 +624,7 @@
     ("RightUpTeeVector", "\x0295C"),
     ("RightUpVector", "\x021BE") ]
 
+{-# NOINLINE reftab13 #-}
 reftab13 :: [(Text,Text)]
 reftab13 =
   [ ("RightUpVectorBar", "\x02954"),
@@ -647,6 +665,7 @@
     ("Sscr", "\x1D4AE"),
     ("Star", "\x022C6") ]
 
+{-# NOINLINE reftab14 #-}
 reftab14 :: [(Text,Text)]
 reftab14 =
   [ ("Sub", "\x022D0"),
@@ -687,6 +706,7 @@
     ("Uacute", "\x000DA"),
     ("Uarr", "\x0219F") ]
 
+{-# NOINLINE reftab15 #-}
 reftab15 :: [(Text,Text)]
 reftab15 =
   [ ("Uarrocir", "\x02949"),
@@ -727,6 +747,7 @@
     ("Vbar", "\x02AEB"),
     ("Vcy", "\x00412") ]
 
+{-# NOINLINE reftab16 #-}
 reftab16 :: [(Text,Text)]
 reftab16 =
   [ ("Vdash", "\x022A9"),
@@ -767,6 +788,7 @@
     ("Zcaron", "\x0017D"),
     ("Zcy", "\x00417") ]
 
+{-# NOINLINE reftab17 #-}
 reftab17 :: [(Text,Text)]
 reftab17 =
   [ ("Zdot", "\x0017B"),
@@ -807,6 +829,7 @@
     ("angmsdac", "\x029AA"),
     ("angmsdad", "\x029AB") ]
 
+{-# NOINLINE reftab18 #-}
 reftab18 :: [(Text,Text)]
 reftab18 =
   [ ("angmsdae", "\x029AC"),
@@ -847,6 +870,7 @@
     ("barvee", "\x022BD"),
     ("barwed", "\x02305") ]
 
+{-# NOINLINE reftab19 #-}
 reftab19 :: [(Text,Text)]
 reftab19 =
   [ ("barwedge", "\x02305"),
@@ -887,6 +911,7 @@
     ("blank", "\x02423"),
     ("blk12", "\x02592") ]
 
+{-# NOINLINE reftab20 #-}
 reftab20 :: [(Text,Text)]
 reftab20 =
   [ ("blk14", "\x02591"),
@@ -927,6 +952,7 @@
     ("boxh", "\x02500"),
     ("boxhD", "\x02565") ]
 
+{-# NOINLINE reftab21 #-}
 reftab21 :: [(Text,Text)]
 reftab21 =
   [ ("boxhU", "\x02568"),
@@ -967,6 +993,7 @@
     ("capand", "\x02A44"),
     ("capbrcup", "\x02A49") ]
 
+{-# NOINLINE reftab22 #-}
 reftab22 :: [(Text,Text)]
 reftab22 =
   [ ("capcap", "\x02A4B"),
@@ -1007,6 +1034,7 @@
     ("cirmid", "\x02AEF"),
     ("cirscir", "\x029C2") ]
 
+{-# NOINLINE reftab23 #-}
 reftab23 :: [(Text,Text)]
 reftab23 =
   [ ("clubs", "\x02663"),
@@ -1047,6 +1075,7 @@
     ("cupcup", "\x02A4A"),
     ("cupdot", "\x0228D") ]
 
+{-# NOINLINE reftab24 #-}
 reftab24 :: [(Text,Text)]
 reftab24 =
   [ ("cupor", "\x02A45"),
@@ -1087,6 +1116,7 @@
     ("dfr", "\x1D521"),
     ("dharl", "\x021C3") ]
 
+{-# NOINLINE reftab25 #-}
 reftab25 :: [(Text,Text)]
 reftab25 =
   [ ("dharr", "\x021C2"),
@@ -1127,6 +1157,7 @@
     ("dtdot", "\x022F1"),
     ("dtri", "\x025BF") ]
 
+{-# NOINLINE reftab26 #-}
 reftab26 :: [(Text,Text)]
 reftab26 =
   [ ("dtrif", "\x025BE"),
@@ -1167,6 +1198,7 @@
     ("eng", "\x0014B"),
     ("ensp", "\x02002") ]
 
+{-# NOINLINE reftab27 #-}
 reftab27 :: [(Text,Text)]
 reftab27 =
   [ ("eogon", "\x00119"),
@@ -1207,6 +1239,7 @@
     ("fflig", "\x0FB00"),
     ("ffllig", "\x0FB04") ]
 
+{-# NOINLINE reftab28 #-}
 reftab28 :: [(Text,Text)]
 reftab28 =
   [ ("ffr", "\x1D523"),
@@ -1247,6 +1280,7 @@
     ("gap", "\x02A86"),
     ("gbreve", "\x0011F") ]
 
+{-# NOINLINE reftab29 #-}
 reftab29 :: [(Text,Text)]
 reftab29 =
   [ ("gcirc", "\x0011D"),
@@ -1287,6 +1321,7 @@
     ("gsime", "\x02A8E"),
     ("gsiml", "\x02A90") ]
 
+{-# NOINLINE reftab30 #-}
 reftab30 :: [(Text,Text)]
 reftab30 =
   [ ("gt", "\x0003E"),
@@ -1327,6 +1362,7 @@
     ("hookrightarrow", "\x021AA"),
     ("hopf", "\x1D559") ]
 
+{-# NOINLINE reftab31 #-}
 reftab31 :: [(Text,Text)]
 reftab31 =
   [ ("horbar", "\x02015"),
@@ -1367,6 +1403,7 @@
     ("integers", "\x02124"),
     ("intercal", "\x022BA") ]
 
+{-# NOINLINE reftab32 #-}
 reftab32 :: [(Text,Text)]
 reftab32 =
   [ ("intlarhk", "\x02A17"),
@@ -1407,6 +1444,7 @@
     ("kopf", "\x1D55C"),
     ("kscr", "\x1D4C0") ]
 
+{-# NOINLINE reftab33 #-}
 reftab33 :: [(Text,Text)]
 reftab33 =
   [ ("lAarr", "\x021DA"),
@@ -1447,6 +1485,7 @@
     ("lbrkslu", "\x0298D"),
     ("lcaron", "\x0013E") ]
 
+{-# NOINLINE reftab34 #-}
 reftab34 :: [(Text,Text)]
 reftab34 =
   [ ("lcedil", "\x0013C"),
@@ -1487,6 +1526,7 @@
     ("lesseqqgtr", "\x02A8B"),
     ("lessgtr", "\x02276") ]
 
+{-# NOINLINE reftab35 #-}
 reftab35 :: [(Text,Text)]
 reftab35 =
   [ ("lesssim", "\x02272"),
@@ -1527,6 +1567,7 @@
     ("lopar", "\x02985"),
     ("lopf", "\x1D55D") ]
 
+{-# NOINLINE reftab36 #-}
 reftab36 :: [(Text,Text)]
 reftab36 =
   [ ("loplus", "\x02A2D"),
@@ -1567,6 +1608,7 @@
     ("ltrie", "\x022B4"),
     ("ltrif", "\x025C2") ]
 
+{-# NOINLINE reftab37 #-}
 reftab37 :: [(Text,Text)]
 reftab37 =
   [ ("lurdshar", "\x0294A"),
@@ -1607,6 +1649,7 @@
     ("mp", "\x02213"),
     ("mscr", "\x1D4C2") ]
 
+{-# NOINLINE reftab38 #-}
 reftab38 :: [(Text,Text)]
 reftab38 =
   [ ("mstpos", "\x0223E"),
@@ -1647,6 +1690,7 @@
     ("ncy", "\x0043D"),
     ("ndash", "\x02013") ]
 
+{-# NOINLINE reftab39 #-}
 reftab39 :: [(Text,Text)]
 reftab39 =
   [ ("ne", "\x02260"),
@@ -1687,6 +1731,7 @@
     ("nleftrightarrow", "\x021AE"),
     ("nleq", "\x02270") ]
 
+{-# NOINLINE reftab40 #-}
 reftab40 :: [(Text,Text)]
 reftab40 =
   [ ("nleqq", "\x02266\x00338"),
@@ -1727,6 +1772,7 @@
     ("nrightarrow", "\x0219B"),
     ("nrtri", "\x022EB") ]
 
+{-# NOINLINE reftab41 #-}
 reftab41 :: [(Text,Text)]
 reftab41 =
   [ ("nrtrie", "\x022ED"),
@@ -1767,6 +1813,7 @@
     ("nu", "\x003BD"),
     ("num", "\x00023") ]
 
+{-# NOINLINE reftab42 #-}
 reftab42 :: [(Text,Text)]
 reftab42 =
   [ ("numero", "\x02116"),
@@ -1807,6 +1854,7 @@
     ("ogon", "\x002DB"),
     ("ograve", "\x000F2") ]
 
+{-# NOINLINE reftab43 #-}
 reftab43 :: [(Text,Text)]
 reftab43 =
   [ ("ogt", "\x029C1"),
@@ -1847,6 +1895,7 @@
     ("ouml", "\x000F6"),
     ("ovbar", "\x0233D") ]
 
+{-# NOINLINE reftab44 #-}
 reftab44 :: [(Text,Text)]
 reftab44 =
   [ ("par", "\x02225"),
@@ -1887,6 +1936,7 @@
     ("popf", "\x1D561"),
     ("pound", "\x000A3") ]
 
+{-# NOINLINE reftab45 #-}
 reftab45 :: [(Text,Text)]
 reftab45 =
   [ ("pr", "\x0227A"),
@@ -1927,6 +1977,7 @@
     ("quatint", "\x02A16"),
     ("quest", "\x0003F") ]
 
+{-# NOINLINE reftab46 #-}
 reftab46 :: [(Text,Text)]
 reftab46 =
   [ ("questeq", "\x0225F"),
@@ -1967,6 +2018,7 @@
     ("rbrke", "\x0298C"),
     ("rbrksld", "\x0298E") ]
 
+{-# NOINLINE reftab47 #-}
 reftab47 :: [(Text,Text)]
 reftab47 =
   [ ("rbrkslu", "\x02990"),
@@ -2007,6 +2059,7 @@
     ("risingdotseq", "\x02253"),
     ("rlarr", "\x021C4") ]
 
+{-# NOINLINE reftab48 #-}
 reftab48 :: [(Text,Text)]
 reftab48 =
   [ ("rlhar", "\x021CC"),
@@ -2047,6 +2100,7 @@
     ("scaron", "\x00161"),
     ("sccue", "\x0227D") ]
 
+{-# NOINLINE reftab49 #-}
 reftab49 :: [(Text,Text)]
 reftab49 =
   [ ("sce", "\x02AB0"),
@@ -2087,6 +2141,7 @@
     ("sime", "\x02243"),
     ("simeq", "\x02243") ]
 
+{-# NOINLINE reftab50 #-}
 reftab50 :: [(Text,Text)]
 reftab50 =
   [ ("simg", "\x02A9E"),
@@ -2127,6 +2182,7 @@
     ("sqsupseteq", "\x02292"),
     ("squ", "\x025A1") ]
 
+{-# NOINLINE reftab51 #-}
 reftab51 :: [(Text,Text)]
 reftab51 =
   [ ("square", "\x025A1"),
@@ -2167,6 +2223,7 @@
     ("succnapprox", "\x02ABA"),
     ("succneqq", "\x02AB6") ]
 
+{-# NOINLINE reftab52 #-}
 reftab52 :: [(Text,Text)]
 reftab52 =
   [ ("succnsim", "\x022E9"),
@@ -2207,6 +2264,7 @@
     ("tau", "\x003C4"),
     ("tbrk", "\x023B4") ]
 
+{-# NOINLINE reftab53 #-}
 reftab53 :: [(Text,Text)]
 reftab53 =
   [ ("tcaron", "\x00165"),
@@ -2247,6 +2305,7 @@
     ("trianglelefteq", "\x022B4"),
     ("triangleq", "\x0225C") ]
 
+{-# NOINLINE reftab54 #-}
 reftab54 :: [(Text,Text)]
 reftab54 =
   [ ("triangleright", "\x025B9"),
@@ -2287,6 +2346,7 @@
     ("ulcrop", "\x0230F"),
     ("ultri", "\x025F8") ]
 
+{-# NOINLINE reftab55 #-}
 reftab55 :: [(Text,Text)]
 reftab55 =
   [ ("umacr", "\x0016B"),
@@ -2327,6 +2387,7 @@
     ("varpi", "\x003D6"),
     ("varpropto", "\x0221D") ]
 
+{-# NOINLINE reftab56 #-}
 reftab56 :: [(Text,Text)]
 reftab56 =
   [ ("varr", "\x02195"),
@@ -2367,6 +2428,7 @@
     ("weierp", "\x02118"),
     ("wfr", "\x1D534") ]
 
+{-# NOINLINE reftab57 #-}
 reftab57 :: [(Text,Text)]
 reftab57 =
   [ ("wopf", "\x1D568"),
@@ -2407,6 +2469,7 @@
     ("yicy", "\x00457"),
     ("yopf", "\x1D56A") ]
 
+{-# NOINLINE reftab58 #-}
 reftab58 :: [(Text,Text)]
 reftab58 =
   [ ("yscr", "\x1D4CE"),
diff --git a/src/Text/XmlHtml/HTML/Parse.hs b/src/Text/XmlHtml/HTML/Parse.hs
--- a/src/Text/XmlHtml/HTML/Parse.hs
+++ b/src/Text/XmlHtml/HTML/Parse.hs
@@ -15,8 +15,8 @@
 
 import qualified Text.Parsec as P
 
-import qualified Data.Set as S
-import qualified Data.Map as M
+import qualified Data.HashSet as S
+import qualified Data.HashMap.Strict as M
 
 import           Data.Text (Text)
 import qualified Data.Text as T
@@ -239,9 +239,10 @@
 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
--- a/src/Text/XmlHtml/HTML/Render.hs
+++ b/src/Text/XmlHtml/HTML/Render.hs
@@ -17,7 +17,7 @@
 import           Data.Text (Text)
 import qualified Data.Text as T
 
-import qualified Data.Set as S
+import qualified Data.HashSet as S
 
 ------------------------------------------------------------------------------
 -- | And, the rendering code.
@@ -30,6 +30,15 @@
           nodes | null ns   = mempty
                 | otherwise = firstNode e (head ns)
                     `mappend` (mconcat $ map (node e) (tail ns))
+
+
+------------------------------------------------------------------------------
+-- | 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)
 
 
 ------------------------------------------------------------------------------
diff --git a/src/Text/XmlHtml/TextParser.hs b/src/Text/XmlHtml/TextParser.hs
--- a/src/Text/XmlHtml/TextParser.hs
+++ b/src/Text/XmlHtml/TextParser.hs
@@ -2,8 +2,20 @@
 {-# 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
 import           Data.Maybe
@@ -12,13 +24,12 @@
 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
@@ -29,18 +40,6 @@
     | B.take 2 b == B.pack [ 0xFE, 0xFF ]       = (UTF16BE, B.drop 2 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
diff --git a/src/Text/XmlHtml/XML/Render.hs b/src/Text/XmlHtml/XML/Render.hs
--- a/src/Text/XmlHtml/XML/Render.hs
+++ b/src/Text/XmlHtml/XML/Render.hs
@@ -26,6 +26,15 @@
 
 
 ------------------------------------------------------------------------------
+-- | 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 "<?xml version=\"1.0\" encoding=\""
             `mappend` fromText e (encodingName e)
diff --git a/test/resources/oasis/p44fail3.xml.html.correct b/test/resources/oasis/p44fail3.xml.html.correct
new file mode 100644
--- /dev/null
+++ b/test/resources/oasis/p44fail3.xml.html.correct
@@ -0,0 +1,1 @@
+Dashes are allowed in HTML attribute names.
diff --git a/test/suite/Text/XmlHtml/Tests.hs b/test/suite/Text/XmlHtml/Tests.hs
--- a/test/suite/Text/XmlHtml/Tests.hs
+++ b/test/suite/Text/XmlHtml/Tests.hs
@@ -363,6 +363,7 @@
     testIt   "laxAttrName            " laxAttrName,
     testCase "badAttrName            " badAttrName,
     testIt   "emptyAttr              " emptyAttr,
+    testIt   "emptyAttr2             " emptyAttr2,
     testIt   "unquotedAttr           " unquotedAttr,
     testIt   "laxAttrVal             " laxAttrVal,
     testIt   "ampersandInText        " ampersandInText,
@@ -439,6 +440,10 @@
 emptyAttr     = parseHTML "" "<test attr></test>"
     == Right (HtmlDocument UTF8 Nothing [Element "test" [("attr", "")] []])
 
+emptyAttr2 :: Bool
+emptyAttr2     = parseHTML "" "<div itemscope itemtype=\"type\"></div>"
+    == Right (HtmlDocument UTF8 Nothing [Element "div" [("itemscope", ""), ("itemtype", "type")] []])
+
 unquotedAttr :: Bool
 unquotedAttr  = parseHTML "" "<test attr=you&amp;me></test>"
     == Right (HtmlDocument UTF8 Nothing [Element "test" [("attr", "you&me")] []])
@@ -947,7 +952,7 @@
         ]
 
 blazeTestEmpty :: Bool
-blazeTestEmpty = renderHtml mempty == HtmlDocument UTF8 Nothing []
+blazeTestEmpty = renderHtmlNodes mempty == []
 
 selectCustom :: Html
 selectCustom = H.select ! H.customAttribute "dojoType" "select" $ (mappend "foo " "bar")
diff --git a/test/xmlhtml-testsuite.cabal b/test/xmlhtml-testsuite.cabal
--- a/test/xmlhtml-testsuite.cabal
+++ b/test/xmlhtml-testsuite.cabal
@@ -8,19 +8,20 @@
   main-is:         TestSuite.hs
 
   build-depends:
-    HUnit == 1.2.*,
-    directory == 1.0.*,
-    QuickCheck >= 2.3.0.2,
-    base == 4.*,
-    blaze-builder >= 0.2 && <0.4,
-    blaze-html >= 0.3.2 && < 0.5,
-    bytestring == 0.9.*,
-    containers >= 0.3 && <0.5,
-    parsec >= 3.0 && < 3.2,
-    test-framework >= 0.3.1 && <0.4,
-    test-framework-hunit >= 0.2.5 && <0.3,
+    HUnit                      == 1.2.*,
+    directory                  >= 1.0   && < 1.2,
+    QuickCheck                 >= 2.3.0.2,
+    base                       == 4.*,
+    blaze-builder              >= 0.2   && < 0.4,
+    blaze-html                 >= 0.3.2 && < 0.5,
+    bytestring                 == 0.9.*,
+    containers                 >= 0.3   && < 0.5,
+    parsec                     >= 3.0   && < 3.2,
+    test-framework             >= 0.3.1 && < 0.4,
+    test-framework-hunit       >= 0.2.5 && < 0.3,
     test-framework-quickcheck2 >= 0.2.6 && < 0.3,
-    text >= 0.11 && < 0.12
-    
+    text                       >= 0.11  && < 0.12,
+    unordered-containers       >= 0.1.4 && < 0.2
+
   ghc-options: -O2 -Wall -fhpc -fwarn-tabs -funbox-strict-fields -threaded
                -fno-warn-unused-do-bind
diff --git a/xmlhtml.cabal b/xmlhtml.cabal
--- a/xmlhtml.cabal
+++ b/xmlhtml.cabal
@@ -1,5 +1,5 @@
 Name:                xmlhtml
-Version:             0.1.5.2
+Version:             0.1.6
 Synopsis:            XML parser and renderer with HTML 5 quirks mode
 Description:         Contains renderers and parsers for both XML and HTML 5
                      document fragments, which share data structures wo that
@@ -727,6 +727,7 @@
              test/resources/oasis/p46pass1.xml,
              test/resources/oasis/p02fail3.xml,
              test/resources/oasis/p44fail3.xml,
+             test/resources/oasis/p44fail3.xml.html.correct,
              test/resources/oasis/p14pass1.xml,
              test/resources/oasis/p03fail24.xml,
              test/resources/oasis/p10pass1.xml,
@@ -799,11 +800,17 @@
              test/resources/oasis/p44pass1.xml,
              test/resources/oasis/p27fail1.xml
 
+Source-repository head
+  Type:     git
+  Location: https://github.com/snapframework/xmlhtml.git
+
 Library
   Hs-source-dirs:      src
+
   Exposed-modules:     Text.XmlHtml,
                        Text.XmlHtml.Cursor,
                        Text.Blaze.Renderer.XmlHtml
+
   Other-modules:       Text.XmlHtml.Common,
                        Text.XmlHtml.TextParser,
                        Text.XmlHtml.XML.Parse,
@@ -811,12 +818,24 @@
                        Text.XmlHtml.HTML.Meta,
                        Text.XmlHtml.HTML.Parse,
                        Text.XmlHtml.HTML.Render
-  Build-depends:       base == 4.*,
-                       blaze-builder >= 0.2 && <0.4,
-                       blaze-html >= 0.3.2 && < 0.5,
-                       bytestring == 0.9.*,
-                       containers >= 0.3 && <0.5,
-                       parsec >= 3.0 && < 3.2,
-                       text >= 0.11 && < 0.12
 
+  Build-depends:       base                 >= 4     && < 5,
+                       blaze-builder        >= 0.2   && < 0.4,
+                       blaze-html           >= 0.3.2 && < 0.5,
+                       bytestring           >= 0.9   && < 0.10,
+                       containers           >= 0.3   && < 0.5,
+                       parsec               >= 3.1.2 && < 3.2,
+                       text                 >= 0.11  && < 0.12,
+                       unordered-containers >= 0.1.4 && < 0.2
+
+  extensions:
+    OverloadedStrings,
+    FlexibleInstances,
+    MultiParamTypeClasses,
+    TupleSections,
+    PatternGuards,
+    ScopedTypeVariables,
+    ExistentialQuantification
+
   Ghc-options:         -Wall -fwarn-tabs -fno-warn-orphans
+  ghc-prof-options:    -prof -auto-all
