feat: 集成KaTeX库支持LaTeX数学公式渲染
This commit is contained in:
parent
b5c56d4946
commit
682744e4b8
Binary file not shown.
|
|
@ -1,71 +1,77 @@
|
||||||
{
|
{
|
||||||
"hash": "1229e8fa",
|
"hash": "76772e52",
|
||||||
"browserHash": "5c2510fa",
|
"browserHash": "b5df73c3",
|
||||||
"optimized": {
|
"optimized": {
|
||||||
"axios": {
|
"axios": {
|
||||||
"src": "../../axios/index.js",
|
"src": "../../axios/index.js",
|
||||||
"file": "axios.js",
|
"file": "axios.js",
|
||||||
"fileHash": "c14dff39",
|
"fileHash": "d5a6fb13",
|
||||||
"needsInterop": false
|
"needsInterop": false
|
||||||
},
|
},
|
||||||
"mammoth": {
|
"mammoth": {
|
||||||
"src": "../../mammoth/lib/index.js",
|
"src": "../../mammoth/lib/index.js",
|
||||||
"file": "mammoth.js",
|
"file": "mammoth.js",
|
||||||
"fileHash": "9331e90f",
|
"fileHash": "8e0b13e7",
|
||||||
"needsInterop": true
|
"needsInterop": true
|
||||||
},
|
},
|
||||||
"marked": {
|
"marked": {
|
||||||
"src": "../../marked/lib/marked.esm.js",
|
"src": "../../marked/lib/marked.esm.js",
|
||||||
"file": "marked.js",
|
"file": "marked.js",
|
||||||
"fileHash": "d9459e29",
|
"fileHash": "330cfdd3",
|
||||||
"needsInterop": false
|
"needsInterop": false
|
||||||
},
|
},
|
||||||
"pdfjs-dist": {
|
"pdfjs-dist": {
|
||||||
"src": "../../pdfjs-dist/build/pdf.mjs",
|
"src": "../../pdfjs-dist/build/pdf.mjs",
|
||||||
"file": "pdfjs-dist.js",
|
"file": "pdfjs-dist.js",
|
||||||
"fileHash": "4db246e9",
|
"fileHash": "63546997",
|
||||||
"needsInterop": false
|
"needsInterop": false
|
||||||
},
|
},
|
||||||
"prismjs": {
|
"prismjs": {
|
||||||
"src": "../../prismjs/prism.js",
|
"src": "../../prismjs/prism.js",
|
||||||
"file": "prismjs.js",
|
"file": "prismjs.js",
|
||||||
"fileHash": "e122bdaf",
|
"fileHash": "3730e60a",
|
||||||
"needsInterop": true
|
"needsInterop": true
|
||||||
},
|
},
|
||||||
"prismjs/components/prism-css": {
|
"prismjs/components/prism-css": {
|
||||||
"src": "../../prismjs/components/prism-css.js",
|
"src": "../../prismjs/components/prism-css.js",
|
||||||
"file": "prismjs_components_prism-css.js",
|
"file": "prismjs_components_prism-css.js",
|
||||||
"fileHash": "b1805788",
|
"fileHash": "b5dc8638",
|
||||||
"needsInterop": true
|
"needsInterop": true
|
||||||
},
|
},
|
||||||
"prismjs/components/prism-javascript": {
|
"prismjs/components/prism-javascript": {
|
||||||
"src": "../../prismjs/components/prism-javascript.js",
|
"src": "../../prismjs/components/prism-javascript.js",
|
||||||
"file": "prismjs_components_prism-javascript.js",
|
"file": "prismjs_components_prism-javascript.js",
|
||||||
"fileHash": "c034dce0",
|
"fileHash": "a3fb501c",
|
||||||
"needsInterop": true
|
"needsInterop": true
|
||||||
},
|
},
|
||||||
"prismjs/components/prism-json": {
|
"prismjs/components/prism-json": {
|
||||||
"src": "../../prismjs/components/prism-json.js",
|
"src": "../../prismjs/components/prism-json.js",
|
||||||
"file": "prismjs_components_prism-json.js",
|
"file": "prismjs_components_prism-json.js",
|
||||||
"fileHash": "1379480f",
|
"fileHash": "2d44f86b",
|
||||||
"needsInterop": true
|
"needsInterop": true
|
||||||
},
|
},
|
||||||
"prismjs/components/prism-python": {
|
"prismjs/components/prism-python": {
|
||||||
"src": "../../prismjs/components/prism-python.js",
|
"src": "../../prismjs/components/prism-python.js",
|
||||||
"file": "prismjs_components_prism-python.js",
|
"file": "prismjs_components_prism-python.js",
|
||||||
"fileHash": "fa615091",
|
"fileHash": "ca5259af",
|
||||||
"needsInterop": true
|
"needsInterop": true
|
||||||
},
|
},
|
||||||
"prismjs/components/prism-sql": {
|
"prismjs/components/prism-sql": {
|
||||||
"src": "../../prismjs/components/prism-sql.js",
|
"src": "../../prismjs/components/prism-sql.js",
|
||||||
"file": "prismjs_components_prism-sql.js",
|
"file": "prismjs_components_prism-sql.js",
|
||||||
"fileHash": "31352c1e",
|
"fileHash": "4a89443c",
|
||||||
"needsInterop": true
|
"needsInterop": true
|
||||||
},
|
},
|
||||||
"vue": {
|
"vue": {
|
||||||
"src": "../../vue/dist/vue.runtime.esm-bundler.js",
|
"src": "../../vue/dist/vue.runtime.esm-bundler.js",
|
||||||
"file": "vue.js",
|
"file": "vue.js",
|
||||||
"fileHash": "7f03e6bd",
|
"fileHash": "a7d38f14",
|
||||||
|
"needsInterop": false
|
||||||
|
},
|
||||||
|
"katex": {
|
||||||
|
"src": "../../katex/dist/katex.mjs",
|
||||||
|
"file": "katex.js",
|
||||||
|
"fileHash": "d08a8bdf",
|
||||||
"needsInterop": false
|
"needsInterop": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
|
|
@ -9,6 +9,7 @@
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^1.5.0",
|
"axios": "^1.5.0",
|
||||||
|
"katex": "^0.16.22",
|
||||||
"mammoth": "^1.10.0",
|
"mammoth": "^1.10.0",
|
||||||
"marked": "^16.2.1",
|
"marked": "^16.2.1",
|
||||||
"markmap-lib": "^0.18.12",
|
"markmap-lib": "^0.18.12",
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^1.5.0",
|
"axios": "^1.5.0",
|
||||||
|
"katex": "^0.16.22",
|
||||||
"mammoth": "^1.10.0",
|
"mammoth": "^1.10.0",
|
||||||
"marked": "^16.2.1",
|
"marked": "^16.2.1",
|
||||||
"markmap-lib": "^0.18.12",
|
"markmap-lib": "^0.18.12",
|
||||||
|
|
|
||||||
|
|
@ -710,6 +710,28 @@ Level 4 标题用 #####
|
||||||
|
|
||||||
// 格式化Markdown为结构化文本
|
// 格式化Markdown为结构化文本
|
||||||
const formatMarkdownToText = (markdown) => {
|
const formatMarkdownToText = (markdown) => {
|
||||||
|
// 首先检查是否是表格内容,如果是表格则不进行转换
|
||||||
|
if (markdown.includes('|') && markdown.includes('-')) {
|
||||||
|
const lines = markdown.split('\n');
|
||||||
|
let hasTableRow = false;
|
||||||
|
let hasSeparator = false;
|
||||||
|
|
||||||
|
for (const line of lines) {
|
||||||
|
const trimmedLine = line.trim();
|
||||||
|
if (trimmedLine.includes('|') && trimmedLine.split('|').length >= 3) {
|
||||||
|
hasTableRow = true;
|
||||||
|
}
|
||||||
|
if (trimmedLine.includes('|') && trimmedLine.includes('-') && /^[\s\|\-\:]+$/.test(trimmedLine)) {
|
||||||
|
hasSeparator = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasTableRow && hasSeparator) {
|
||||||
|
console.log('🚫 formatMarkdownToText: 检测到表格内容,跳过转换');
|
||||||
|
return markdown; // 返回原始表格内容
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return markdown
|
return markdown
|
||||||
// 处理标题
|
// 处理标题
|
||||||
.replace(/^### (.*$)/gim, '📋 $1') // 三级标题
|
.replace(/^### (.*$)/gim, '📋 $1') // 三级标题
|
||||||
|
|
|
||||||
|
|
@ -3340,9 +3340,9 @@ const updateMindMapRealtime = async (data, title) => {
|
||||||
maxScale: 5,
|
maxScale: 5,
|
||||||
minScale: 0.1,
|
minScale: 0.1,
|
||||||
markdown: (text, nodeObj) => {
|
markdown: (text, nodeObj) => {
|
||||||
console.log('🔍 实时更新 Mind Elixir markdown函数被调用:', text.substring(0, 100) + '...');
|
// console.log('🔍 实时更新 Mind Elixir markdown函数被调用:', text.substring(0, 100) + '...');
|
||||||
// 直接检查内容是否包含表格或其他markdown语法
|
// 直接检查内容是否包含表格、数学公式或其他markdown语法
|
||||||
if (text.includes('|') || text.includes('**') || text.includes('`') || text.includes('#')) {
|
if (text.includes('|') || text.includes('**') || text.includes('`') || text.includes('#') || text.includes('$')) {
|
||||||
console.log('🎨 实时更新 检测到markdown内容,开始渲染:', text.substring(0, 100) + '...');
|
console.log('🎨 实时更新 检测到markdown内容,开始渲染:', text.substring(0, 100) + '...');
|
||||||
const result = smartRenderNodeContent(text);
|
const result = smartRenderNodeContent(text);
|
||||||
console.log('🎨 实时更新 渲染结果:', result.substring(0, 200) + '...');
|
console.log('🎨 实时更新 渲染结果:', result.substring(0, 200) + '...');
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,13 @@
|
||||||
|
|
||||||
import { marked } from 'marked';
|
import { marked } from 'marked';
|
||||||
import Prism from 'prismjs';
|
import Prism from 'prismjs';
|
||||||
|
import katex from 'katex';
|
||||||
import 'prismjs/components/prism-javascript';
|
import 'prismjs/components/prism-javascript';
|
||||||
import 'prismjs/components/prism-css';
|
import 'prismjs/components/prism-css';
|
||||||
import 'prismjs/components/prism-json';
|
import 'prismjs/components/prism-json';
|
||||||
import 'prismjs/components/prism-python';
|
import 'prismjs/components/prism-python';
|
||||||
import 'prismjs/components/prism-sql';
|
import 'prismjs/components/prism-sql';
|
||||||
|
import 'katex/dist/katex.min.css';
|
||||||
|
|
||||||
// 配置marked选项
|
// 配置marked选项
|
||||||
marked.setOptions({
|
marked.setOptions({
|
||||||
|
|
@ -52,9 +54,39 @@ export const renderMarkdownToHTML = (markdown) => {
|
||||||
*/
|
*/
|
||||||
const preprocessMarkdown = (markdown) => {
|
const preprocessMarkdown = (markdown) => {
|
||||||
return markdown
|
return markdown
|
||||||
// 处理数学公式(如果需要的话)
|
// 处理块级数学公式($$...$$)
|
||||||
.replace(/\$\$(.*?)\$\$/g, '<div class="math-block">$$$1$$</div>')
|
.replace(/\$\$([\s\S]*?)\$\$/g, (match, formula) => {
|
||||||
.replace(/\$(.*?)\$/g, '<span class="math-inline">$$1$</span>');
|
try {
|
||||||
|
const rendered = katex.renderToString(formula.trim(), {
|
||||||
|
displayMode: true,
|
||||||
|
throwOnError: false
|
||||||
|
});
|
||||||
|
return `<div class="math-block">${rendered}</div>`;
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('数学公式渲染失败:', error);
|
||||||
|
return `<div class="math-error">数学公式错误: ${formula}</div>`;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// 处理行内数学公式($...$),但避免匹配单个$符号
|
||||||
|
.replace(/\$([^$\n]+?)\$/g, (match, formula) => {
|
||||||
|
// 检查是否包含LaTeX命令或数学符号
|
||||||
|
if (formula.includes('\\') || formula.includes('{') || formula.includes('}') ||
|
||||||
|
formula.includes('^') || formula.includes('_') || formula.includes('=') ||
|
||||||
|
formula.includes('+') || formula.includes('-') || formula.includes('*') ||
|
||||||
|
formula.includes('/') || formula.includes('(') || formula.includes(')')) {
|
||||||
|
try {
|
||||||
|
const rendered = katex.renderToString(formula.trim(), {
|
||||||
|
displayMode: false,
|
||||||
|
throwOnError: false
|
||||||
|
});
|
||||||
|
return `<span class="math-inline">${rendered}</span>`;
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('数学公式渲染失败:', error);
|
||||||
|
return `<span class="math-error">数学公式错误: ${formula}</span>`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return match; // 如果不包含数学符号,保持原样
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -67,10 +99,7 @@ const postprocessHTML = (html) => {
|
||||||
// 为表格添加样式类
|
// 为表格添加样式类
|
||||||
.replace(/<table>/g, '<table class="markdown-table">')
|
.replace(/<table>/g, '<table class="markdown-table">')
|
||||||
// 为代码块添加样式类
|
// 为代码块添加样式类
|
||||||
.replace(/<pre><code/g, '<pre class="markdown-code"><code')
|
.replace(/<pre><code/g, '<pre class="markdown-code"><code');
|
||||||
// 为数学公式添加样式类
|
|
||||||
.replace(/<div class="math-block">/g, '<div class="math-block markdown-math">')
|
|
||||||
.replace(/<span class="math-inline">/g, '<span class="math-inline markdown-math">');
|
|
||||||
|
|
||||||
// 创建临时DOM元素来处理语法高亮
|
// 创建临时DOM元素来处理语法高亮
|
||||||
const tempDiv = document.createElement('div');
|
const tempDiv = document.createElement('div');
|
||||||
|
|
@ -320,8 +349,27 @@ const addMarkdownStyles = (container) => {
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
|
||||||
.markdown-math {
|
.math-block {
|
||||||
font-family: 'Times New Roman', serif;
|
text-align: center;
|
||||||
|
margin: 4px 0;
|
||||||
|
padding: 4px;
|
||||||
|
background: #f8f9fa;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.math-inline {
|
||||||
|
display: inline;
|
||||||
|
margin: 0 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.math-error {
|
||||||
|
color: #dc3545;
|
||||||
|
background: #f8d7da;
|
||||||
|
border: 1px solid #f5c6cb;
|
||||||
|
padding: 2px 4px;
|
||||||
|
border-radius: 3px;
|
||||||
|
font-size: 10px;
|
||||||
|
font-family: monospace;
|
||||||
}
|
}
|
||||||
|
|
||||||
.markdown-error {
|
.markdown-error {
|
||||||
|
|
@ -400,6 +448,8 @@ export const hasMarkdownSyntax = (content) => {
|
||||||
/^\s*\d+\.\s+/m, // 有序列表
|
/^\s*\d+\.\s+/m, // 有序列表
|
||||||
/\[.*?\]\(.*?\)/, // 链接
|
/\[.*?\]\(.*?\)/, // 链接
|
||||||
/!\[.*?\]\(.*?\)/, // 图片
|
/!\[.*?\]\(.*?\)/, // 图片
|
||||||
|
/\$\$.*?\$\$/, // 块级数学公式
|
||||||
|
/\$.*?\$/, // 行内数学公式
|
||||||
];
|
];
|
||||||
|
|
||||||
return markdownPatterns.some(pattern => pattern.test(content));
|
return markdownPatterns.some(pattern => pattern.test(content));
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue