Skip to content

Fix markdown rendering issues and add lint:md to CI (#73) - #74

Merged
devlux76 merged 1 commit into
mainfrom
claude/fix-design-md-linting-tgkWe
Mar 21, 2026
Merged

Fix markdown rendering issues and add lint:md to CI (#73)#74
devlux76 merged 1 commit into
mainfrom
claude/fix-design-md-linting-tgkWe

Conversation

@devlux76

Copy link
Copy Markdown
Owner

DESIGN.md had Unicode subscripts/superscripts in code blocks and tables that don't render reliably in monospace fonts. These slipped through because lint-md.mjs only checked inside $$...$$ and ```mermaid blocks, and the check script didn't include lint:md at all.

Fixes:

  • Replace Unicode subscripts/arrows/operators in pseudocode block with ASCII equivalents (v₀ -> v[0], ← -> <-, ≠ -> !=, etc.)
  • Replace Unicode subscripts in key-layout table with inline LaTeX
  • Replace Q² with Q2 in table header
  • Fix same class of issues in RESULTS.md code blocks
  • Expand lint-md.mjs with Rule 5: scan fenced code blocks for Unicode subscripts, superscripts, math arrows, and math operators
  • Add lint:md to the check script so CI catches markdown issues

https://claude.ai/code/session_017b5kMJ5gECv63yLCHJ3SXP

Description

Related Issue

Closes #

Checklist

  • This PR references at least one open issue (see above)
  • Tests have been added or updated where applicable
  • Linting and type-checking pass (bun run check)
  • All tests pass (bun run test)

DESIGN.md had Unicode subscripts/superscripts in code blocks and tables
that don't render reliably in monospace fonts. These slipped through
because lint-md.mjs only checked inside $$...$$ and ```mermaid blocks,
and the check script didn't include lint:md at all.

Fixes:
- Replace Unicode subscripts/arrows/operators in pseudocode block with
  ASCII equivalents (v₀ -> v[0], ← -> <-, ≠ -> !=, etc.)
- Replace Unicode subscripts in key-layout table with inline LaTeX
- Replace Q² with Q2 in table header
- Fix same class of issues in RESULTS.md code blocks
- Expand lint-md.mjs with Rule 5: scan fenced code blocks for Unicode
  subscripts, superscripts, math arrows, and math operators
- Add lint:md to the check script so CI catches markdown issues

https://claude.ai/code/session_017b5kMJ5gECv63yLCHJ3SXP
Copilot AI review requested due to automatic review settings March 21, 2026 03:55
@devlux76
devlux76 merged commit c125c2a into main Mar 21, 2026
3 of 4 checks passed
@devlux76
devlux76 deleted the claude/fix-design-md-linting-tgkWe branch March 21, 2026 03:55

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR aims to prevent Markdown rendering regressions (especially from Unicode glyphs that don’t render reliably) by normalizing problematic characters in docs and strengthening Markdown linting so CI can catch future issues.

Changes:

  • Replaced fragile Unicode math/subscript glyphs with ASCII (and inline LaTeX for subscripts in tables) in DESIGN.md and RESULTS.md.
  • Extended scripts/lint-md.mjs with a new rule to detect problematic Unicode ranges inside fenced code blocks.
  • Updated bun run check to include lint:md, so Markdown lint runs in CI.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
scripts/lint-md.mjs Adds fenced-code-block Unicode scanning (Rule 5) and updates linter scope description.
package.json Runs lint:md as part of check (therefore in CI).
RESULTS.md Normalizes Unicode math notation inside fenced blocks to ASCII equivalents.
DESIGN.md Normalizes Unicode glyphs in pseudocode/table headers; uses inline LaTeX for subscripts in a table row.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread scripts/lint-md.mjs
Comment on lines +66 to +79
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 });

Copilot AI Mar 21, 2026

Copy link

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).

Suggested change
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 });

Copilot uses AI. Check for mistakes.
Comment thread package.json
@@ -11,7 +11,7 @@
"lint": "eslint --no-inline-config --max-warnings 0 --fix src test --ext .js,.ts,.html,.yml,.yaml && eslint --no-inline-config --max-warnings 0 src test --ext .js,.ts,.html,.yml,.yaml",
"lint:css": "stylelint --max-warnings 0 --allow-empty-input --fix \"**/*.{css,html}\" && stylelint --max-warnings 0 --allow-empty-input \"**/*.{css,html}\"",
"lint:md": "bun scripts/lint-md.mjs",

Copilot AI Mar 21, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that check runs lint:md in CI, note that scripts/lint-md.mjs (per its current default behavior) only lints *.md in the repo root. This means Markdown files under docs/ (and other subdirs) will still bypass CI linting unless they’re passed explicitly. Consider updating the linter’s default file discovery (or the lint:md script) to include all tracked Markdown files (e.g., recursive walk or git ls-files '*.md').

Suggested change
"lint:md": "bun scripts/lint-md.mjs",
"lint:md": "bun scripts/lint-md.mjs $(git ls-files \"*.md\")",

Copilot uses AI. Check for mistakes.
Comment thread scripts/lint-md.mjs
/**
* 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.

Copilot AI Mar 21, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The file header now says this linter covers “code blocks, and tables”, but the implemented rules only scan display-math ($$...$$), Mermaid fenced blocks, and non-Mermaid fenced code blocks. Unicode rendering issues inside Markdown tables (outside fenced blocks) still won’t be detected. Either adjust the description to match current behavior, or add a table/prose scanning rule if table linting is intended.

Suggested change
* rendering of KaTeX math, Mermaid diagrams, code blocks, and tables.
* rendering of KaTeX math, Mermaid diagrams, and code blocks.

Copilot uses AI. Check for mistakes.
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.

3 participants