-
Notifications
You must be signed in to change notification settings - Fork 919
feat(web): render LaTeX math in chat via KaTeX #1035
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
7fce349
b0bf409
bdb5c35
f71c58f
08deac2
50c9256
06201d3
35346a8
1b4a575
8343b59
961c172
6f8220d
df0bba4
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 |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| "@moonshot-ai/kimi-code": patch | ||
| --- | ||
|
|
||
| Render LaTeX display math (`$$…$$`) in the web chat via KaTeX. Single `$` is intentionally left as literal text, so prices, env vars, and shell paths (e.g. `$PATH`, `$5/$10`, `$HOME/bin`) are never swallowed as a formula. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,7 +2,8 @@ | |
| <script setup lang="ts"> | ||
| import { computed, inject, nextTick, onMounted, onUnmounted, reactive, ref, watch } from 'vue'; | ||
| import { useI18n } from 'vue-i18n'; | ||
| import { MarkdownRender } from 'markstream-vue'; | ||
| import { MarkdownRender, enableKatex } from 'markstream-vue'; | ||
| import type { MarkdownIt } from 'markstream-vue'; | ||
| import { useIsDark } from '../../composables/useIsDark'; | ||
| import type { FilePreviewRequest } from '../../types'; | ||
| import { collectFilePathAliases, findFilePathLinks } from '../../lib/filePathLinks'; | ||
|
|
@@ -13,6 +14,23 @@ import { copyTextToClipboard } from '../../lib/clipboard'; | |
| // Terminal Pro. Importing the same file from multiple components is a no-op | ||
| // after the first (Vite dedups the CSS import). | ||
| import 'markstream-vue/index.px.css'; | ||
| // KaTeX math: markstream renders `$$…$$` display math only after the optional | ||
| // katex peer is enabled, and its stylesheet (+ bundled fonts) is what gives | ||
| // formulas their layout. enableKatex() registers the default `import('katex')` | ||
| // loader; it runs once on first import of this module and is safe at module | ||
| // scope. Without the CSS the math renders unstyled, so both must travel | ||
| // together. | ||
| import 'katex/dist/katex.min.css'; | ||
| enableKatex(); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When KaTeX is enabled globally here, ordinary assistant text that contains two literal dollar-prefixed tokens, such as Useful? React with 👍 / 👎. |
||
|
|
||
| // Only `$$…$$` display math is rendered; single `$` inline math is disabled so | ||
| // prices, env vars, and shell paths (`$5`, `$PATH`, `$HOME/bin`) stay literal | ||
| // without any escaping or code-detection gymnastics. `math_block` (the $$ rule) | ||
| // is left enabled. | ||
| function disableInlineMath(md: MarkdownIt): MarkdownIt { | ||
| md.inline.ruler.disable('math'); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When a model writes display math in the common paragraph form, e.g. Useful? React with 👍 / 👎.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good catch. I am going to keep this out of this PR intentionally: the current change only guarantees the block/display forms that |
||
| return md; | ||
| } | ||
|
|
||
| const { t } = useI18n(); | ||
|
|
||
|
|
@@ -353,6 +371,7 @@ function copyDiff(code: string, idx: number) { | |
| <MarkdownRender | ||
| v-if="seg.kind === 'md'" | ||
| :content="seg.text" | ||
| :custom-markdown-it="disableInlineMath" | ||
| mode="chat" | ||
| :code-renderer="renderPlan.codeRenderer" | ||
| :is-dark="isDark" | ||
|
|
@@ -575,6 +594,19 @@ function copyDiff(code: string, idx: number) { | |
| text-decoration: underline; | ||
| } | ||
|
|
||
| /* KaTeX math. Colour already inherits (--text) since KaTeX draws with | ||
| currentColor, so the only skinning needed is layout: let a wide display | ||
| formula scroll inside its own box instead of overflowing the chat column and | ||
| breaking the mobile layout. Inline math stays in the text flow. */ | ||
| .md :deep(.katex-display) { | ||
| overflow-x: auto; | ||
| overflow-y: hidden; | ||
| /* room for the horizontal scrollbar so it doesn't clip the bottom of the | ||
| formula (e.g. integral/sum subscripts) */ | ||
| padding: 2px 0 6px; | ||
| margin: 0.6em 0; | ||
| } | ||
|
|
||
| /* Blockquote */ | ||
| .md :deep(blockquote) { | ||
| margin: 0.5em 0; | ||
|
|
||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
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.
In the Nix packaging path,
flake.nixincludespnpm-lock.yamlin the fixed-outputfetchPnpmDepssource and pins it with the hash atflake.nix:153; addingkatexchanges the lockfile/dependency set but this commit leaves that hash unchanged, sonix buildwill fail with a fixed-output hash mismatch before the app builds. Please update thepnpmDepshash together with this new dependency.Useful? React with 👍 / 👎.
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.
Checked this one: no
flake.nixhash update is needed for the current diff.katex@0.16.47was already present inpnpm-lock.yamlviamarkstream-vueonmain; this PR only adds it as a direct importer dependency forapps/kimi-web, so the fetched dependency store content is unchanged. The Nix CI also confirms it:nix build .#kimi-codepassed on commit961c172706(job https://github.com/MoonshotAI/kimi-code/actions/runs/28083761728/job/83144618679).