fix: resolve math formula display abnormal after editing report

This fix addresses the issue where math formulas become corrupted or
incorrectly displayed after editing the generated report in the editor.

**Root Cause:**
The issue occurred due to incompatibility between markdown processing
in the display component and the Tiptap editor:
1. Display component used \[\] and \(\) LaTeX delimiters
2. Tiptap Mathematics extension expects $ and 70868 delimiters
3. tiptap-markdown didn't have built-in math node serialization
4. Math syntax was lost/corrupted during editor save operations

**Solution Implemented:**
1. Created MathematicsWithMarkdown extension that adds markdown
   serialization support to Tiptap's Mathematics nodes
2. Added math delimiter normalization functions:
   - normalizeMathForEditor(): Converts LaTeX delimiters to $/70868
   - normalizeMathForDisplay(): Standardizes all delimiters to 70868
3. Updated Markdown component to use new normalization
4. Updated ReportEditor to normalize content before loading

**Changes:**
- web/src/components/editor/math-serializer.ts (new)
- web/src/components/editor/extensions.tsx
- web/src/components/editor/index.tsx
- web/src/components/deer-flow/markdown.tsx
- web/src/core/utils/markdown.ts
- web/tests/markdown-math-editor.test.ts (new)
- web/tests/markdown-katex.test.ts

**Testing:**
- Added 15 comprehensive tests for math normalization round-trip
- All tests passing (math editor + existing katex tests)
- Verified TypeScript compilation and linting

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
This commit is contained in:
Willem Jiang
2025-10-15 08:13:49 +08:00
committed by Willem Jiang
parent 24e2d86f7b
commit 58c1743ed5
7 changed files with 208 additions and 19 deletions

View File

@@ -31,6 +31,7 @@ import GenerativeMenuSwitch from "./generative/generative-menu-switch";
import { uploadFn } from "./image-upload";
import { TextButtons } from "./selectors/text-buttons";
import { slashCommand, suggestionItems } from "./slash-command";
import { normalizeMathForEditor } from "~/core/utils/markdown";
// import { defaultEditorContent } from "./content";
import "~/styles/prosemirror.css";
@@ -45,7 +46,13 @@ export interface ReportEditorProps {
}
const ReportEditor = ({ content, onMarkdownChange }: ReportEditorProps) => {
const [initialContent, setInitialContent] = useState<Content>(() => content);
const [initialContent, setInitialContent] = useState<Content>(() => {
// Normalize math delimiters for editor consumption
if (typeof content === "string") {
return normalizeMathForEditor(content);
}
return content;
});
const [saveStatus, setSaveStatus] = useState("Saved");
const [openNode, setOpenNode] = useState(false);