feat: Latex support (#929)

* feat: implement LaTeX math rendering via KaTeX

- Add katex, remark-math, and rehype-katex dependencies
- Integrate KaTeX CSS with light/dark theme color overrides
- Wire remark-math and rehype-katex plugins into MarkdownRenderer
- Support inline ($...$) and display ($$...$$) math delimiters
- Add plan and task documentation

* fix(katex): display inline error messages for invalid LaTeX

- Configure rehypeKatex with throwOnError: false to render errors inline
- Use destructive color var for error text
- Update feature documentation with verification results

* chore: remove latex PR artifacts and hardcoded color fallback

---------

Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
This commit is contained in:
ricautomation
2026-04-16 23:30:52 +03:00
committed by GitHub
co-authored by Bohdan Triapitsyn
parent 2fbfd803f7
commit 324cf49755
4 changed files with 72 additions and 2 deletions
@@ -3,6 +3,8 @@ import { renderMermaidASCII, renderMermaidSVG } from 'beautiful-mermaid';
import ReactMarkdown from 'react-markdown';
import type { Components } from 'react-markdown';
import remarkGfm from 'remark-gfm';
import remarkMath from 'remark-math';
import rehypeKatex from 'rehype-katex';
import { marked, type Tokens } from 'marked';
import remend from 'remend';
import { FadeInOnReveal } from './message/FadeInOnReveal';
@@ -817,7 +819,7 @@ const MarkdownBlockView: React.FC<{
components: Components;
}> = React.memo(({ block, components }) => {
return (
<ReactMarkdown remarkPlugins={[remarkGfm]} components={components}>
<ReactMarkdown remarkPlugins={[remarkGfm, remarkMath]} rehypePlugins={[[rehypeKatex, { throwOnError: false, errorColor: 'var(--destructive)' }]]} components={components}>
{block.src}
</ReactMarkdown>
);
+20
View File
@@ -1,10 +1,30 @@
@import "tailwindcss";
@import "tw-animate-css";
@import "katex/dist/katex.min.css";
@import "./styles/design-system.css";
@import "./styles/typography.css";
@import "./styles/mobile.css";
@source "./**/*.{ts,tsx,css}";
/* KaTeX theme overrides for light/dark mode */
.katex {
color: var(--foreground);
}
.katex .mord,
.katex .mopen,
.katex .mclose,
.katex .mbin,
.katex .mrel,
.katex .mpunct,
.katex .mord,
.katex .mop,
.katex .minner {
color: inherit;
}
.katex-error {
color: var(--destructive);
}
@custom-variant dark (&:is(.dark *));
:root.oc-theme-switching *,