[Review] Fix math block delimiter parsing#13
Conversation
|
@claude /review focus on multiline display math rendering, DOM text/br reconstruction, repeated KaTeX rendering, and inline/display delimiter edge cases |
|
Claude finished @wargoblin's task in 3m 30s —— View job PR Review: Fix math block delimiter parsing
OverviewThis PR introduces a proper preprocessing pipeline for display math blocks (replacing the fragile Overall the approach is sound, but there are a few correctness issues worth addressing before merging. 1.
|
| Issue | Severity | Status |
|---|---|---|
processInlineMath walks inside [data-math] elements |
Medium | Needs fix |
findInlineMathEnd -1 on digit aborts whole span |
Medium | Acceptable with a comment |
Empty $$\n$$ silently dropped |
Low | Consider a warning |
previousWasBreak strips only one \n |
Low | Acceptable |
| Tight-list display math missed | Low | Acceptable |
[data-math] selector widened consistently |
✅ Correct | — |
data-math-source re-render guard |
✅ Correct | — |
processDisplayMathBlocks call order |
✅ Correct | — |
The structural approach is solid. The data-math-source + [data-math] pattern is a meaningful improvement over the previous el.textContent approach for re-render correctness. Addressing item 1 (walker skipping [data-math] elements) before merging to upstream would prevent a subtle renderMathInElement double-pass on display math content.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ff206bc0a0
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| } | ||
|
|
||
| function processDisplayMathBlocks(root: Element, doc: Document) { | ||
| for (const element of Array.from(root.querySelectorAll("p"))) { |
There was a problem hiding this comment.
Include tight list items in display math preprocessing
When a multiline $$ block is the only content of a tight list item, Comrak renders the item body as text/<br> children of <li> rather than wrapping it in a <p>, so this loop never calls extractDisplayMathBlock for inputs like - $$\n a+b\n $$. Because KaTeX auto-render still cannot match $$ delimiters split across separate text/br nodes, the math remains literal in list items even though top-level paragraphs now work.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in c5f0ae8: display math preprocessing now also considers tight-list li nodes, while still requiring the element to contain only text/BR children before marking it as math.
ff206bc to
dd84b2c
Compare
There was a problem hiding this comment.
Pull request overview
This PR improves Markdown math delimiter handling by introducing explicit display-math block extraction ($$...$$) and replacing the prior regex-based inline parsing with a more robust inline delimiter conversion. It also updates KaTeX rendering to support both inline and display math elements via a unified [data-math] selector and a stable data-math-source attribute.
Changes:
- Add display-math block detection for paragraphs that contain only
$$...$$(including cases split by<br>), emittingdata-math="display"+data-math-source. - Replace regex-based
$...$inline conversion withconvertInlineMathDelimiters(...)to better handle escapes/adjacent spans. - Update KaTeX rendering to read from
data-math-sourceand to target all[data-math]elements; remove duplicated inline-math preprocessing inMarkdownViewer.svelte.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| src/lib/utils/markdown.ts | Adds display-math block extraction + new inline delimiter conversion and updates KaTeX rendering input/selection. |
| src/lib/MarkdownViewer.svelte | Removes redundant inline-math preprocessing and aligns KaTeX rendering with the new data-math(-source) approach. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Claude finished @wargoblin's task in 2m 40s —— View job PR Review: dd84b2c — data-math ancestor skip verification
Actionable comment from prior review — RESOLVED ✅
The ancestor-walking acceptNode(node) {
let curr = node.parentElement;
while (curr && curr !== root) {
if (curr.hasAttribute("data-math")) // ← new guard
return NodeFilter.FILTER_REJECT;
if (["CODE", "PRE", "SCRIPT", "STYLE"].includes(curr.tagName))
return NodeFilter.FILTER_REJECT;
curr = curr.parentElement;
}
return NodeFilter.FILTER_ACCEPT;
},This fully closes the loop identified previously. Because The bonus fix at line 142 is also correct — Remaining correctness issues1.
// A following `$` may open an adjacent inline span; the outer loop handles it.
if (/\s/.test(beforeEnd) || /\d/.test(afterEnd)) return -1;The comment explains the // Trailing digit after closing $ likely means a unit/number context (e.g. "$10 USD"), not math.
if (/\s/.test(beforeEnd) || /\d/.test(afterEnd)) return -1;2. Tight-list display math — still not reached (Low, pre-existing)
3. Empty display block — silently dropped (Low, pre-existing)
No new correctness issues foundThe KaTeX render pipeline in VerdictThe Medium-severity blocker is resolved. The two remaining low-severity pre-existing issues (tight lists, empty block) are acceptable scope for a follow-up. Only the digit-guard comment (item 1 above) is a minor omission worth a one-line fix before merging. |
| const mathElement = doc.createElement("div"); | ||
| mathElement.setAttribute("data-math", "display"); | ||
| mathElement.setAttribute("data-math-source", math); | ||
| mathElement.textContent = math; | ||
| element.replaceWith(mathElement); |
There was a problem hiding this comment.
Fixed in c5f0ae8: the preprocessing now preserves the original p/li element and its attributes such as data-sourcepos, replacing only its children with the normalized math source.
dd84b2c to
c5f0ae8
Compare
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
Claude finished @wargoblin's task in 1m 42s —— View job PR Review: c5f0ae8 — Codex/Copilot comment verification
Previous Codex/Copilot comments — both resolved ✅Codex P2 — Tight-list
for (const element of Array.from(root.querySelectorAll("p, li"))) {Confirmed. The selector now covers both Copilot — Original
element.setAttribute("data-math", "display");
element.setAttribute("data-math-source", math);
element.replaceChildren(doc.createTextNode(math));Confirmed. The original element is mutated in-place — no Remaining items — all low severity, pre-existing, non-blocking1.
// A following `$` may open an adjacent inline span; the outer loop handles it.
if (/\s/.test(beforeEnd) || /\d/.test(afterEnd)) return -1;The comment explains the // Trailing digit (e.g. "$10") is treated as currency, not math; abort rather than risk a false match later.
if (/\s/.test(beforeEnd) || /\d/.test(afterEnd)) return -1;No correctness impact — the behavior is intentionally conservative. 2. Empty display block silently dropped
VerdictBoth actionable comments from Codex and Copilot are correctly resolved in c5f0ae8. No new correctness blockers introduced. The two low-severity pre-existing items are acceptable scope for a follow-up. This is ready to merge to upstream. |
|
Internal review complete for c5f0ae8: fork CI passed, Claude confirmed the previous findings are addressed, Copilot re-reviewed with no new comments, and Codex review was skipped due usage limit. |
|
Closing after internal review completion; upstream PR alecdotdev#142 is updated from this branch. |
Internal review PR before updating upstream alecdotdev#142.