mirror of
https://github.com/NeuralNomadsAI/CodeNomad.git
synced 2026-07-10 00:14:27 +00:00
Fix(ui): Support Markdown Math Rendering (#381)
Add `KaTeX` extension for math formula rendering It solves the issue #379 . Now the interface acts like this when processing formulas: `$\mathbb{R}$`: <img width="1016" height="83" alt="image" src="https://github.com/user-attachments/assets/7a7534c0-3128-4a98-a01f-336db42e0f26" /> `$$ \mathbb{R} $$`: <img width="1016" height="89" alt="image" src="https://github.com/user-attachments/assets/9da7d2e4-06cc-41e8-b598-eab8b3be7677" /> ```markdown $$ \mathbb{R} $$ ``` : <img width="1016" height="88" alt="image" src="https://github.com/user-attachments/assets/a1be91e3-7ff1-4cf9-8982-c2657348317d" /> Closes #379 --------- Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
parent
0f7267743e
commit
dd72c8a8d6
5 changed files with 89 additions and 4 deletions
37
package-lock.json
generated
37
package-lock.json
generated
|
|
@ -8306,6 +8306,31 @@
|
|||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/katex": {
|
||||
"version": "0.16.45",
|
||||
"resolved": "https://registry.npmjs.org/katex/-/katex-0.16.45.tgz",
|
||||
"integrity": "sha512-pQpZbdBu7wCTmQUh7ufPmLr0pFoObnGUoL/yhtwJDgmmQpbkg/0HSVti25Fu4rmd1oCR6NGWe9vqTWuWv3GcNA==",
|
||||
"funding": [
|
||||
"https://opencollective.com/katex",
|
||||
"https://github.com/sponsors/katex"
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"commander": "^8.3.0"
|
||||
},
|
||||
"bin": {
|
||||
"katex": "cli.js"
|
||||
}
|
||||
},
|
||||
"node_modules/katex/node_modules/commander": {
|
||||
"version": "8.3.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
|
||||
"integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 12"
|
||||
}
|
||||
},
|
||||
"node_modules/keyv": {
|
||||
"version": "4.5.4",
|
||||
"dev": true,
|
||||
|
|
@ -8514,6 +8539,16 @@
|
|||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/marked-katex-extension": {
|
||||
"version": "5.1.8",
|
||||
"resolved": "https://registry.npmjs.org/marked-katex-extension/-/marked-katex-extension-5.1.8.tgz",
|
||||
"integrity": "sha512-TsV9OCHHDjVBf4IH0RSjLs4Eqsjj8HGfmVCKlimrS391EtBBxzXj2gBYdF9tY7f7oXu9tb1kHV86ExJsG3iMhw==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"katex": ">=0.16 <0.17",
|
||||
"marked": ">=4 <19"
|
||||
}
|
||||
},
|
||||
"node_modules/matcher": {
|
||||
"version": "3.0.0",
|
||||
"dev": true,
|
||||
|
|
@ -13309,8 +13344,10 @@
|
|||
"ansi-sequence-parser": "^1.1.3",
|
||||
"debug": "^4.4.3",
|
||||
"github-markdown-css": "^5.8.1",
|
||||
"katex": "^0.16.45",
|
||||
"lucide-solid": "^0.300.0",
|
||||
"marked": "^12.0.0",
|
||||
"marked-katex-extension": "^5.1.8",
|
||||
"monaco-editor": "^0.52.2",
|
||||
"qrcode": "^1.5.3",
|
||||
"shiki": "^3.13.0",
|
||||
|
|
|
|||
|
|
@ -25,8 +25,10 @@
|
|||
"ansi-sequence-parser": "^1.1.3",
|
||||
"debug": "^4.4.3",
|
||||
"github-markdown-css": "^5.8.1",
|
||||
"katex": "^0.16.45",
|
||||
"lucide-solid": "^0.300.0",
|
||||
"marked": "^12.0.0",
|
||||
"marked-katex-extension": "^5.1.8",
|
||||
"monaco-editor": "^0.52.2",
|
||||
"qrcode": "^1.5.3",
|
||||
"shiki": "^3.13.0",
|
||||
|
|
|
|||
|
|
@ -9,6 +9,18 @@ const log = getLogger("session")
|
|||
|
||||
type MarkdownModule = typeof import("../lib/markdown")
|
||||
|
||||
interface ResolvedMarkdownSnapshot {
|
||||
part: TextPart
|
||||
text: string
|
||||
themeKey: string
|
||||
highlightEnabled: boolean
|
||||
escapeRawHtml: boolean
|
||||
partId: string | undefined
|
||||
cacheId: string
|
||||
version: string
|
||||
requestKey: string
|
||||
}
|
||||
|
||||
let markdownModulePromise: Promise<MarkdownModule> | null = null
|
||||
|
||||
function loadMarkdownModule(): Promise<MarkdownModule> {
|
||||
|
|
@ -124,7 +136,7 @@ export function Markdown(props: MarkdownProps) {
|
|||
})
|
||||
|
||||
const commitCacheEntry = (
|
||||
snapshot: ReturnType<typeof resolved>,
|
||||
snapshot: ResolvedMarkdownSnapshot,
|
||||
renderedHtml: string,
|
||||
options?: { cache?: boolean },
|
||||
) => {
|
||||
|
|
@ -141,7 +153,7 @@ export function Markdown(props: MarkdownProps) {
|
|||
notifyRendered()
|
||||
}
|
||||
|
||||
const renderSnapshot = async (snapshot: ReturnType<typeof resolved>) => {
|
||||
const renderSnapshot = async (snapshot: ResolvedMarkdownSnapshot): Promise<void> => {
|
||||
const markdown = await loadMarkdownModule()
|
||||
markdown.setMarkdownTheme(snapshot.themeKey === "dark")
|
||||
const rendered = await markdown.renderMarkdown(snapshot.text, {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { marked } from "marked"
|
||||
import markedKatex from "marked-katex-extension"
|
||||
import { getLogger } from "./logger"
|
||||
import { tGlobal } from "./i18n"
|
||||
import type { Highlighter } from "shiki/bundle/full"
|
||||
|
|
@ -16,6 +17,11 @@ let rendererSetup = false
|
|||
let shikiModulePromise: Promise<typeof import("shiki/bundle/full")> | null = null
|
||||
let bundledLanguagesCache: typeof import("shiki/bundle/full")["bundledLanguages"] | null = null
|
||||
|
||||
// Math rendering is handled by marked-katex-extension (registered in setupRenderer).
|
||||
// Delimiter rules, boundaries, CJK punctuation, and block/inline rendering are
|
||||
// all delegated to the maintained extension so we avoid ~200 lines of fragile
|
||||
// hand-rolled tokenizer code.
|
||||
|
||||
const ALLOWED_RAW_HTML_TAGS = new Set([
|
||||
"a",
|
||||
"blockquote",
|
||||
|
|
@ -374,6 +380,12 @@ function setupRenderer(isDark: boolean) {
|
|||
gfm: true,
|
||||
})
|
||||
|
||||
marked.use(markedKatex({
|
||||
throwOnError: false,
|
||||
nonStandard: true,
|
||||
strict: "ignore",
|
||||
}))
|
||||
|
||||
const renderer = new marked.Renderer()
|
||||
|
||||
renderer.code = (code: string, lang: string | undefined) => {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,23 @@
|
|||
@import "github-markdown-css/github-markdown-light.css" layer(github-markdown-base);
|
||||
@import "github-markdown-css/github-markdown-light.css"
|
||||
layer(github-markdown-base);
|
||||
@import "katex/dist/katex.min.css" layer(katex-base);
|
||||
|
||||
@layer katex-overrides {
|
||||
.markdown-body .katex-display {
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
padding: 0.25rem 0;
|
||||
}
|
||||
|
||||
.markdown-body .katex {
|
||||
font-size: 1.05em;
|
||||
}
|
||||
|
||||
.markdown-body .katex .frac-line {
|
||||
border-bottom-width: 0.1em !important;
|
||||
border-color: currentColor !important;
|
||||
}
|
||||
}
|
||||
|
||||
@layer components {
|
||||
.markdown-body {
|
||||
|
|
@ -239,7 +258,10 @@
|
|||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
color: var(--text-secondary);
|
||||
transition: background-color 150ms ease, color 150ms ease, border-color 150ms ease;
|
||||
transition:
|
||||
background-color 150ms ease,
|
||||
color 150ms ease,
|
||||
border-color 150ms ease;
|
||||
margin-inline-start: auto;
|
||||
font-size: var(--font-size-sm);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue