Skip to content

Fix(ui): Support Markdown Math Rendering#381

Open
jollyxenon wants to merge 2 commits intoNeuralNomadsAI:devfrom
jollyxenon:codenomad/issue-379
Open

Fix(ui): Support Markdown Math Rendering#381
jollyxenon wants to merge 2 commits intoNeuralNomadsAI:devfrom
jollyxenon:codenomad/issue-379

Conversation

@jollyxenon
Copy link
Copy Markdown

Add KaTeX extension for math formula rendering

It solves the issue #379 .

Now the interface acts like this when processing formulas:

$ \mathbb{R}$:
image

$$ \mathbb{R} $$:
image

$$
\mathbb{R}
$$

:
image

Closes #379

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Copilot AI review requested due to automatic review settings April 28, 2026 02:09
@github-actions
Copy link
Copy Markdown

PR builds are available as GitHub Actions artifacts:

https://github.com/NeuralNomadsAI/CodeNomad/actions/runs/25030077463

Artifacts expire in 7 days.
Artifacts: (none found on this run)

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds KaTeX-based math rendering support to the UI’s Markdown pipeline to address #379 (“Support Markdown Formula”).

Changes:

  • Introduces custom marked extensions to tokenize/render inline and block math via KaTeX.
  • Adds KaTeX styling (CSS import + markdown-specific layout tweaks for KaTeX output).
  • Adds katex as a UI dependency and refines Markdown component typing for cached render snapshots.

Reviewed changes

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

File Description
packages/ui/src/styles/markdown.css Adds KaTeX-specific Markdown styles (scrolling display math, font sizing).
packages/ui/src/lib/markdown.ts Implements math tokenizers/renderers and registers them with marked.
packages/ui/src/components/markdown.tsx Imports KaTeX CSS and tightens snapshot typing used by the render/cache pipeline.
packages/ui/package.json Adds katex dependency required for rendering.

Comment on lines 6 to 8
import { useI18n } from "../lib/i18n"
import "katex/dist/katex.min.css"

Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

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

Importing katex/dist/katex.min.css here makes KaTeX styles unlayered and globally applied, which also prevents the layered overrides in styles/markdown.css from taking effect (unlayered styles outrank layered ones). Consider moving the KaTeX CSS import into styles/markdown.css using a named layer and declaring layer order, so KaTeX base styles and your overrides compose predictably.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

The judgment is true, but the suggestion sucks. I'll fix the problem in my next commit.

Comment thread packages/ui/src/lib/markdown.ts Outdated
Comment on lines +40 to +43
function canOpenInlineMath(src: string): boolean {
const nextCharacter = src[1]
return Boolean(nextCharacter) && !/\s/.test(nextCharacter)
}
Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

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

The $...$ inline math tokenizer currently refuses to open when the character after $ is whitespace (canOpenInlineMath), which means inputs like $ \mathbb{R}$ / $ FORMULA $ won’t be recognized even though normalizeMathContent() trims whitespace (and the issue/PR description explicitly calls out this format). Consider allowing optional leading/trailing spaces inside the delimiters and rely on trimming + additional heuristics (e.g., avoid parsing when adjacent to digits/word chars) to reduce currency false-positives instead of hard-rejecting whitespace.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

A problem caused by my mistake. I'll fix it later.

Comment thread packages/ui/src/lib/markdown.ts Outdated

const blockMathPattern = /^\$\$([\s\S]+?)\$\$(?:\n+|$)/
const bracketBlockMathPattern = /^\\\[([\s\S]+?)\\\](?:\n+|$)/
const inlineParenMathPattern = /^\\\(([\s\S]+?)\\\)/
Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

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

inlineParenMathPattern (\\((...[\s\S]+?)\\)) can match across newlines, so \(...\) could accidentally consume large multi-line spans. This is inconsistent with the $...$ matcher (which rejects newlines) and can lead to surprising parsing. Consider restricting this inline pattern to a single line (e.g., disallow \n).

Suggested change
const inlineParenMathPattern = /^\\\(([\s\S]+?)\\\)/
const inlineParenMathPattern = /^\\\(([^\n]+?)\\\)/

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Good Insight Good Suggestion. I'll fix it.

Comment thread packages/ui/src/styles/markdown.css Outdated
Comment on lines +3 to +13
@layer components {
.markdown-body .katex-display {
overflow-x: auto;
overflow-y: hidden;
padding: 0.25rem 0;
}

.markdown-body .katex {
font-size: 1.05em;
}

Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

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

These KaTeX overrides are inside @layer components, but KaTeX’s own stylesheet is imported unlayered (from components/markdown.tsx). In the cascade-layer model, unlayered styles outrank layered ones regardless of selector specificity, so KaTeX’s base .katex / .katex-display declarations will override these adjustments. To ensure these rules apply, either move them out of a layer, or import KaTeX CSS into a named layer and order layers so components comes after it.

Suggested change
@layer components {
.markdown-body .katex-display {
overflow-x: auto;
overflow-y: hidden;
padding: 0.25rem 0;
}
.markdown-body .katex {
font-size: 1.05em;
}
.markdown-body .katex-display {
overflow-x: auto;
overflow-y: hidden;
padding: 0.25rem 0;
}
.markdown-body .katex {
font-size: 1.05em;
}
@layer components {

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

The patch is a baloney though the problem exists indeed.

Comment thread packages/ui/src/lib/markdown.ts Outdated
Comment on lines +93 to +97
function renderMathToken(content: string, displayMode: boolean): string {
const normalizedContent = normalizeMathContent(content)
if (!normalizedContent) {
return escapeHtml(content)
}
Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

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

renderMathToken falls back to escapeHtml(content) on empty/invalid formulas, but content is the inner math text (without $...$ / \(...\) delimiters). That makes failures less obvious and changes what the user typed. Consider falling back to the original raw token (including delimiters) or wrapping the fallback in a consistent error element so users can still see the exact input.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Valid advice.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
@github-actions
Copy link
Copy Markdown

PR builds are available as GitHub Actions artifacts:

https://github.com/NeuralNomadsAI/CodeNomad/actions/runs/25031698002

Artifacts expire in 7 days.
Artifacts: (none found on this run)

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.

[Feature] Support Markdown Formula

2 participants