fix(w3c): feed + article remainder (S8-S10, F13, F14) — strict ratchet #25
Loading…
Reference in a new issue
No description provided.
Delete branch "w3c-feed-p-figure"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Implements the remainder of
specs/w3c-validation.md: S8 (<p><figure>restructure), S9 (feed iframe policy), S10 (CharacterData allowlist), the strict-by-default ratchet — plus two pre-existing bugs the work exposed (F13, F14). Stacked on #24 (w3c-html-fixes).S8 —
BlockFigureParagraphGate(src/filters/markdown.rs)Streaming event filter wrapping the pulldown-cmark output:
<p>emission is deferred until inline content actually arrives → image-only paragraphs emit a bare<figure>at block level (no<p><figure>…</figure></p>)<p>first; trailing inline content reopens a fresh one (figures render block-level anyway, so visuals are unchanged)<p>materializes)CodeBlockinsideParagraphevents; only images were affectedF13 — external-image markup mismatch (pre-existing, exposed by S8)
Start(Tag::Image)renders non-/URLs as a bare<img …>, butEnd(TagEnd::Image)unconditionally emitted</figcaption></figure>— plus the alt text leaked as visible duplicate text. Nowin_bare_imgstate suppresses both for that path (title already lives in thealtattribute).F14 — raw
&in hand-built attributessrcs like…?u=x&f=1&nofb=1were interpolated verbatim intoformatdoc!tags → invalid HTMLhrefhad the same issue: lol_htmlget_attribute()returns serialized values,before()inserts raw HTMLescape_attr(markdown.rs) and entity-awareescape_raw_ampersands(feed.rs — never double-escapes existing&)S9 — feed embed policy
Every
<iframe>in feed content becomes a host-labeled link card —▶ watch on Twitch/▶ watch on YouTube/▶ listen on Spotify/▶ open the embedded content— with the src absolutized; srcless shells dropped. The site keeps the live embeds (feed-only policy).S10 + ratchet
CharacterDataallowlisted (escape-form style preference, both well-formed XML).validate-feedis now strict by default (LAX=1drops back to errors-only for investigating new warnings).Verification
cargo test: 60 passed — 8 new markdown-shape tests, 3 iframe-policy tests, and corpus-wide audits (no<iframe>, no<p>-nested blocks in any rendered post)just validate-feed local: VALID — zero non-allowlisted warnings, strict mode greenjust validate-html local: 0 errors on all 5 default pages (incl. the article page that carried the F8 stray</p>)🪦 Live preview
removed (PR closed)
Follow-up (
2467968): the F13in_bare_imgsuppression misread author intent — the visible alt text after external images was the desired caption behavior (mirroring local images); the old workaround just lacked the<figure><figcaption>opener. External + SVG paths now share one simple-figure arm, the caption text flows into<figcaption>naturally, and the End(Image) closer is unconditional again. Net: −15 lines. External images verified live with centered captions (first-weekly beyerdynamic photo); feed-strict and all 5 Nu pages still clean.Fix for the deformed paragraphs reported on the preview (
6c4a33e): the paragraph gate matched anyEvent::Htmlstarting with<figure— including hand-written<figure>blocks in post sources (like the pi-logo one in week-with-my-pi-agent). Those are emitted by pulldown at block level (outside Paragraph events) and close with a plain</figure>that never matches the gate's exact end matcher → the figure flag stuck and every following paragraph lost its<p>wrapper. The flag is now only set while inside a paragraph span, where a figure-startEvent::Htmlis provably one of our generated ones. Guarded by a regression test for the exact corpus shape and a corpus-wide feed audit (no long bare text runs after</figure>). Re-verified: page 0 Nu errors, 0 bare runs, feed strict VALID, 61 tests pass. Preview should update shortly.