Skip to content

Update nonVoids for HTML5 void elements; accept whitespace in close tags - #1

Open
JeremyIV wants to merge 3 commits into
galenhuntington:masterfrom
JeremyIV:fix-void-elements-and-close-tag
Open

Update nonVoids for HTML5 void elements; accept whitespace in close tags#1
JeremyIV wants to merge 3 commits into
galenhuntington:masterfrom
JeremyIV:fix-void-elements-and-close-tag

Conversation

@JeremyIV

Copy link
Copy Markdown

Three small fixes, one commit each:

1. nonVoids list vs. the current WHATWG void-element list

  • source is a void element, but it was listed as non-void, so <source src=x/> compiled to <source src="x"></source> — closing a void element is an HTML5 parse error.
  • picture, slot, and search are ordinary elements but were missing from the list, so <picture/> rendered via renderSelf as a literal <picture/>, which HTML5 parses as an unclosed open tag (the slash is ignored) — everything after it ends up inside the picture element.

Fix: remove source; add picture, slot, search in alphabetical position. I also added math next to svg under the existing "since commonly used" comment — easy to drop that hunk if you'd rather not.

After the fix:

$ printf '<source src=x/>\n<picture/>\n<slot/>\n<search/>\n<math/>\n' | hxml
<source src="x"/>
<picture></picture>
<slot></slot>
<search></search>
<math></math>

2. Whitespace before > in close tags

Open tags tolerate trailing whitespace (sp <- many spaceChar before the >), but close tags didn't, so </div > failed to parse. XML's grammar allows it (ETag ::= '</' Name S? '>'). Fix: void $ many spaceChar >> char '>' in the close branch. Verified that </div >, </ >, and a close tag split across lines all parse now.

3. renderAttrVal totality

The case BLC.uncons v of Just (x, _) | ... | __ -> ... had no Nothing alternative — unreachable from current call sites (fromMaybe n v is never empty), but a latent crash. Folded the empty case into the catch-all quoting branch; no behavior change.

Verification

  • cabal build clean on GHC 9.14.1 / megaparsec 9.x (only pre-existing -Wx-partial warnings).
  • The test.hxmltest.html fixture comparison passes after every commit (hxml < test.hxml | diff - test.html).
  • Hand-tested the examples shown above against the built binary.

This came out of an AI review pass Jeremy ran over your repos for fun. Every finding was verified as described above, but the usual skepticism applies.

🤖 Generated with Claude Code

JeremyIV and others added 3 commits June 9, 2026 23:53
`source` is a WHATWG void element, so listing it as non-void made
<source src=x/> compile to <source src="x"></source>, which is an
HTML5 parse error.  Conversely `picture`, `slot`, and `search` are
ordinary (non-void) elements, so <picture/> rendered as a literal
self-closed tag, which HTML5 treats as an unclosed open tag.

Remove `source`; add `picture`, `slot`, `search`; also add `math`
alongside `svg` under the same "commonly used" rationale.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Open tags already tolerate trailing whitespace (`sp <- many
spaceChar`), but close tags did not, so `</div >` failed to parse.
XML's grammar permits it: ETag ::= '</' Name S? '>'.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The Nothing (empty value) case was unhandled — unreachable from
current call sites, but a latent crash.  Folding it into the
catch-all quoting branch makes the function total with no behavior
change.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant