216 lines
8.2 KiB
HTML
216 lines
8.2 KiB
HTML
<!DOCTYPE html>
|
||
<html>
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<title>KaTeX 错误诊断</title>
|
||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.4/dist/katex.min.css">
|
||
<script src="https://cdn.jsdelivr.net/npm/katex@0.16.4/dist/katex.min.js"></script>
|
||
<style>
|
||
body {
|
||
font-family: 'Microsoft YaHei', Arial, sans-serif;
|
||
max-width: 1200px;
|
||
margin: 20px auto;
|
||
padding: 20px;
|
||
background: #f5f5f5;
|
||
}
|
||
.test-case {
|
||
background: white;
|
||
margin: 20px 0;
|
||
padding: 25px;
|
||
border-radius: 8px;
|
||
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
|
||
}
|
||
.success { color: #27ae60; font-weight: bold; }
|
||
.fail { color: #e74c3c; font-weight: bold; }
|
||
.result {
|
||
border: 3px solid #3498db;
|
||
padding: 20px;
|
||
margin: 15px 0;
|
||
background: #f8f9fa;
|
||
border-radius: 8px;
|
||
min-height: 50px;
|
||
}
|
||
.error {
|
||
background: #ffe3e3;
|
||
border: 2px solid #e74c3c;
|
||
padding: 15px;
|
||
margin: 10px 0;
|
||
border-radius: 4px;
|
||
font-family: 'Courier New', monospace;
|
||
color: #c92a2a;
|
||
}
|
||
.source {
|
||
background: #f1f3f5;
|
||
padding: 15px;
|
||
margin: 10px 0;
|
||
border-radius: 4px;
|
||
font-family: 'Courier New', monospace;
|
||
font-size: 12px;
|
||
white-space: pre-wrap;
|
||
word-break: break-all;
|
||
}
|
||
h2 { color: #2c3e50; border-bottom: 3px solid #3498db; padding-bottom: 10px; }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<h1>🔍 KaTeX 错误诊断</h1>
|
||
|
||
<div id="output"></div>
|
||
|
||
<script>
|
||
const output = document.getElementById('output');
|
||
|
||
// 测试用例
|
||
const testCases = [
|
||
{
|
||
name: '问题 1: \\tag 在行内公式中',
|
||
original: `i = \\left| {{0.37}{v}_{\\mathrm{r}}}\\right| + \\left| {{0.28}{d}_{\\mathrm{r}}}\\right| + \\left| {{0.2}{o}_{\\mathrm{r}}}\\right| + \\left| {{0.15}{t}_{\\mathrm{r}}}\\right| \\tag{7}`,
|
||
displayMode: false,
|
||
error: 'KaTeX parse error: \\tag works only in display equations'
|
||
},
|
||
{
|
||
name: '修复 1: 使用块级公式(displayMode: true)',
|
||
original: `i = \\left| {{0.37}{v}_{\\mathrm{r}}}\\right| + \\left| {{0.28}{d}_{\\mathrm{r}}}\\right| + \\left| {{0.2}{o}_{\\mathrm{r}}}\\right| + \\left| {{0.15}{t}_{\\mathrm{r}}}\\right| \\tag{7}`,
|
||
displayMode: true,
|
||
isFix: true
|
||
},
|
||
{
|
||
name: '问题 2: \\;^\\circ 语法错误',
|
||
original: `0.1 - 0.2 \\mathrm{\\;^\\circ C}`,
|
||
displayMode: false,
|
||
error: 'KaTeX parse error: Got group of unknown type: \'internal\''
|
||
},
|
||
{
|
||
name: '修复 2a: 使用 ^{\\circ}',
|
||
original: `0.1 - 0.2 \\mathrm{\\;^{\\circ} C}`,
|
||
displayMode: false,
|
||
isFix: true
|
||
},
|
||
{
|
||
name: '修复 2b: 使用 \\degree',
|
||
original: `0.1 - 0.2 \\,\\mathrm{^\\circ C}`,
|
||
displayMode: false,
|
||
isFix: true
|
||
},
|
||
{
|
||
name: '修复 2c: 调整空格和括号',
|
||
original: `0.1 - 0.2\\,^{\\circ}\\mathrm{C}`,
|
||
displayMode: false,
|
||
isFix: true
|
||
},
|
||
{
|
||
name: '问题分析: 双花括号 {{...}}',
|
||
original: `\\left| {{0.37}{v}_{\\mathrm{r}}}\\right|`,
|
||
displayMode: false,
|
||
note: '双花括号 {{...}} 会被解析为内部组'
|
||
},
|
||
{
|
||
name: '修复 3: 移除多余花括号',
|
||
original: `\\left| {0.37}{v}_{\\mathrm{r}}\\right|`,
|
||
displayMode: false,
|
||
isFix: true
|
||
}
|
||
];
|
||
|
||
testCases.forEach(test => {
|
||
const testDiv = document.createElement('div');
|
||
testDiv.className = 'test-case';
|
||
|
||
testDiv.innerHTML = `
|
||
<h2>${test.name}</h2>
|
||
<p><strong>公式源码:</strong></p>
|
||
<div class="source">${test.original}</div>
|
||
`;
|
||
|
||
if (test.error) {
|
||
testDiv.innerHTML += `
|
||
<p><strong>错误信息:</strong></p>
|
||
<div class="error">${test.error}</div>
|
||
`;
|
||
}
|
||
|
||
if (test.note) {
|
||
testDiv.innerHTML += `<p><em>${test.note}</em></p>`;
|
||
}
|
||
|
||
// 尝试渲染
|
||
const resultDiv = document.createElement('div');
|
||
resultDiv.className = 'result';
|
||
|
||
try {
|
||
const html = katex.renderToString(test.original, {
|
||
displayMode: test.displayMode || false,
|
||
throwOnError: false,
|
||
errorColor: '#e74c3c'
|
||
});
|
||
|
||
resultDiv.innerHTML = html;
|
||
|
||
// 检查是否有错误
|
||
const hasError = html.includes('katex-error') || html.includes('parseerror');
|
||
|
||
if (test.isFix) {
|
||
testDiv.innerHTML += hasError
|
||
? `<p class="fail">✗ 修复失败</p>`
|
||
: `<p class="success">✓ 修复成功</p>`;
|
||
}
|
||
|
||
testDiv.innerHTML += `<p><strong>渲染结果:</strong></p>`;
|
||
testDiv.appendChild(resultDiv);
|
||
|
||
} catch (error) {
|
||
testDiv.innerHTML += `
|
||
<p class="fail">✗ 渲染异常</p>
|
||
<div class="error">${error.message}</div>
|
||
`;
|
||
}
|
||
|
||
output.appendChild(testDiv);
|
||
});
|
||
|
||
// 添加建议
|
||
setTimeout(() => {
|
||
const suggestionDiv = document.createElement('div');
|
||
suggestionDiv.className = 'test-case';
|
||
suggestionDiv.innerHTML = `
|
||
<h2>💡 修复建议</h2>
|
||
|
||
<h3>问题 1: \\tag 只能在块级公式中使用</h3>
|
||
<p><strong>原因:</strong> KaTeX 的 <code>\\tag</code> 命令只能用于 display mode(块级公式,即 <code>$$...$$</code>)</p>
|
||
<p><strong>解决方案:</strong></p>
|
||
<ul>
|
||
<li><strong>方案 A:</strong> 使用块级公式 <code>$$...\\tag{7}$$</code></li>
|
||
<li><strong>方案 B:</strong> 移除 <code>\\tag</code>,改用文本标注</li>
|
||
<li><strong>方案 C:</strong> 在 formula_post_processor.js 中自动移除行内公式的 <code>\\tag</code></li>
|
||
</ul>
|
||
|
||
<h3>问题 2: \\;^\\circ 语法错误</h3>
|
||
<p><strong>原因:</strong> <code>\\;</code> 后面直接跟 <code>^</code> 会产生内部组错误</p>
|
||
<p><strong>解决方案:</strong></p>
|
||
<ul>
|
||
<li><strong>推荐:</strong> <code>\\,^{\\circ}\\mathrm{C}</code> 或 <code>^{\\circ}\\mathrm{C}</code></li>
|
||
<li><strong>或:</strong> <code>\\mathrm{\\,^{\\circ}C}</code>(花括号包围上标)</li>
|
||
</ul>
|
||
|
||
<h3>问题 3: 双花括号 {{...}}</h3>
|
||
<p><strong>原因:</strong> 双花括号在 LaTeX 中有特殊含义,可能导致解析错误</p>
|
||
<p><strong>解决方案:</strong></p>
|
||
<ul>
|
||
<li>只使用单层花括号 <code>{0.37}</code></li>
|
||
<li>或者完全移除不必要的花括号</li>
|
||
</ul>
|
||
|
||
<h3>🔧 自动修复建议</h3>
|
||
<p>在 <code>formula_post_processor.js</code> 中添加以下修复规则:</p>
|
||
<ol>
|
||
<li>检测行内公式中的 <code>\\tag{...}</code> 并移除或转换为块级</li>
|
||
<li>修复 <code>\\;^\\circ</code> → <code>\\,^{\\circ}</code></li>
|
||
<li>移除多余的双花括号 <code>{{...}}</code> → <code>{...}</code></li>
|
||
</ol>
|
||
`;
|
||
output.appendChild(suggestionDiv);
|
||
}, 100);
|
||
</script>
|
||
</body>
|
||
</html>
|