-
Notifications
You must be signed in to change notification settings - Fork 0
Fix markdown rendering issues and add lint:md to CI (#73) #74
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,7 +1,7 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #!/usr/bin/env bun | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * lint-md.mjs — Lints Markdown files for encoding issues that break GitHub | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * rendering of KaTeX math and Mermaid diagrams. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * rendering of KaTeX math, Mermaid diagrams, code blocks, and tables. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * rendering of KaTeX math, Mermaid diagrams, code blocks, and tables. | |
| * rendering of KaTeX math, Mermaid diagrams, and code blocks. |
Copilot
AI
Mar 21, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fencedCodeBlocks() treats any line starting with backticks/tildes as a close fence, without verifying it matches the opening fence character (``` vs ~~~) and length. This can mis-parse valid Markdown that uses different fence lengths/chars (or includes a shorter fence inside a longer fenced block), leading to missed or spurious lint violations. Track the opening fence marker (char + count) and only close when encountering the same marker with >= the opening length (optionally allowing trailing spaces).
| let buf = []; | |
| for (let i = 0; i < lines.length; i++) { | |
| const trimmed = lines[i].trim(); | |
| if (/^(`{3,}|~{3,})/.test(trimmed)) { | |
| if (!inside) { | |
| inside = true; | |
| isMermaid = trimmed === '```mermaid'; | |
| buf = []; | |
| } else { | |
| if (!isMermaid) blocks.push(buf); | |
| inside = false; | |
| } | |
| } else if (inside) { | |
| buf.push({ text: lines[i], lineNo: i + 1 }); | |
| let fenceChar = ''; | |
| let fenceLength = 0; | |
| let buf = []; | |
| for (let i = 0; i < lines.length; i++) { | |
| const line = lines[i]; | |
| const trimmed = line.trim(); | |
| if (!inside) { | |
| // Opening fence: capture marker and info string. | |
| const openMatch = trimmed.match(/^(`{3,}|~{3,})(.*)$/); | |
| if (openMatch) { | |
| inside = true; | |
| const marker = openMatch[1]; | |
| fenceChar = marker[0]; | |
| fenceLength = marker.length; | |
| const info = openMatch[2].trim(); | |
| // Treat as Mermaid if info string is "mermaid" or starts with "mermaid ". | |
| isMermaid = info === 'mermaid' || info.startsWith('mermaid '); | |
| buf = []; | |
| } | |
| } else { | |
| // Potential closing fence: must match opening char and have length >= opening. | |
| const closeMatch = trimmed.match(/^([`~]{3,})\s*$/); | |
| if (closeMatch) { | |
| const closeMarker = closeMatch[1]; | |
| if (closeMarker[0] === fenceChar && closeMarker.length >= fenceLength) { | |
| if (!isMermaid) blocks.push(buf); | |
| inside = false; | |
| isMermaid = false; | |
| fenceChar = ''; | |
| fenceLength = 0; | |
| continue; | |
| } | |
| } | |
| buf.push({ text: line, lineNo: i + 1 }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that
checkrunslint:mdin CI, note thatscripts/lint-md.mjs(per its current default behavior) only lints*.mdin the repo root. This means Markdown files underdocs/(and other subdirs) will still bypass CI linting unless they’re passed explicitly. Consider updating the linter’s default file discovery (or thelint:mdscript) to include all tracked Markdown files (e.g., recursive walk orgit ls-files '*.md').