@@ -16,7 +16,13 @@ import Data.Text (Text)
1616import Data.Tree
1717import Text.HTML.Parser
1818
19−
19+-- | construct a 'Forest' from a 'Token' list.
20+--
21+-- This code correctly handles void elements. Void elements are required to have a start tag and must not have an end tag. See 'nonClosing'.
22+--
23+-- This code does __not__ correctly handle optional tags. It assumes all optional start and end tags are present.
24+--
25+-- <https:\/\/www.w3.org\/TR\/html52\/syntax.html#optional-tags>
2026tokensToForest :: [Token] -> Either ParseTokenForestError (Forest Token)
2127tokensToForest = f (PStack [] [])
2228 where
@@ -33,8 +39,15 @@ tokensToForest = f (PStack [] [])
3339 Comment _ -> f (pushFlatSibling t pstack) ts
3440 Doctype _ -> f (pushFlatSibling t pstack) ts
3541
42+-- | void elements which must not have an end tag
43+--
44+-- This list does not include the obsolete @\<command\>@ and @\<keygen\>@ elements.
45+--
46+-- @ nonClosing = ["br", "hr", "img", "meta", "area", "base", "col", "embed", "input", "link", "param", "source", "track", "wbr"] @
47+--
48+-- <https:\/\/www.w3.org\/TR\/html52\/syntax.html#void-elements>
3649nonClosing :: [Text]
37−nonClosing = ["br", "hr", "img", "meta", "area", "base", "col", "command", "embed", "input", "keygen", "link", "param", "source", "track", "wbr"]
50+nonClosing = ["br", "hr", "img", "meta", "area", "base", "col", "embed", "input", "link", "param", "source", "track", "wbr"]
3851
3952data ParseTokenForestError =
4053 ParseTokenForestErrorBracketMismatch PStack (Maybe Token)
@@ -58,10 +71,15 @@ popParent n pstack
5871pushFlatSibling :: Token -> PStack -> PStack
5972pushFlatSibling t (PStack ss ps) = PStack (Node t [] : ss) ps
6073
61−
74+-- | convert a 'Forest' of 'Token' into a list of 'Token'.
75+--
76+-- This code correctly handles void elements. Void elements are required to have a start tag and must not have an end tag. See 'nonClosing'.
6277tokensFromForest :: Forest Token -> [Token]
6378tokensFromForest = mconcat . fmap tokensFromTree
6479
80+-- | convert a 'Tree' of 'Token' into a list of 'Token'.
81+--
82+-- This code correctly handles void elements. Void elements are required to have a start tag and must not have an end tag. See 'nonClosing'.
6583tokensFromTree :: Tree Token -> [Token]
6684tokensFromTree (Node o@(TagOpen n _) ts) | n `notElem` nonClosing
6785 = [o] <> tokensFromForest ts <> [TagClose n]