Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lack of BlockQuoteKind on TagEnd::BlockQuote is a big hassle #889

Open
ssokolow opened this issue May 16, 2024 · 0 comments
Open

Lack of BlockQuoteKind on TagEnd::BlockQuote is a big hassle #889

ssokolow opened this issue May 16, 2024 · 0 comments

Comments

@ssokolow
Copy link

ssokolow commented May 16, 2024

It's become a bit of a recurring pattern in my custom HTML renderer for pulldown-cmark that I more or less need to implement something like a tag stack... but I think blockquote tags is the first time I've so overtly needed to do so just to ensure proper HTML semantics are preserved when using the markup the way it was intended.

(Up to this point, it's been less overt stuff, like the need to synthesize a <tbody></tbody> pair if Tag::TableHead/TagEnd::TableHead are encountered.)

With the brand new blockquote tags option, I need to emit </blockquote> if the argument was None and something else (in my case, </aside>) if the argument was Some.

(Because these sorts of tagged blockquotes aren't really blockquotes, semantically... they're asides. They're just piggybacking on the blockquote markup as a generic "Markdown-semantic'd subdocument" syntax (i.e. <div> but for Markdown), in the same way that various use-cases will piggy-back on the fenced code block syntax as a generic "Raw/literal subdocument" syntax (i.e. <pre> plus CDATA)... now all we need is a generic "Markdown-semantic'd inline with arbitrary attributes" (i.e. <span>, but for Markdown) and we can finally match reStructuredText's extensibility.)

Specifically, here's the state of my TagEnd matches, with ones imposed by the interaction between pulldown-cmark itself and HTML semantics in bold:

  • TagEnd::Blockquote has the aforementioned requirement to store which kind it was from the Tag match
  • TagEnd::CodeBlock requires state tracking so I can implement things like ```svgbob which aren't rendered with </code></pre> endings.
  • TagEnd::Heading only has a second line because of ToC autogeneration
  • TagEnd::Item and TagEnd::Paragraph are only complicated because I want to support turning <li></li> into <li><details><summary>para 1</summary> para 2 +</details></li>
  • TagEnd::Table is complicated because of the need to keep track of whether TableHead was seen and synthesize <tbody></tbody> tags which don't have a representation in the pulldown-cmark token stream. (Heck, I still have a TODO for deferring the emission of <tbody> because the GFM spec says you shouldn't emit empty <tbody></tbody> elements.)

Everything else that I've implemented so far has just been a simple TagEnd::TableRow => output.push_str("</tr>"),-style line, or something like TagEnd::Image => (), // <img /> is self-closing and the only two things I haven't implemented yet are alignments for table columns and the metadata block extension that I'd forgotten about because I'm not sure if I will.

To me, it seems like a bad design and a footgun for things like ENABLE_GFM and TagEnd::Table to require that the user implement even minimal state tracking, just to be able to generate compliant HTML, when nothing else has.

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

No branches or pull requests

1 participant