|
|
@@ -57,6 +57,29 @@ process.stdin.on('end', () => {
|
|
|
}
|
|
|
});
|
|
|
|
|
|
+/**
|
|
|
+ * 解码 HTML 实体
|
|
|
+ */
|
|
|
+function decodeHtmlEntities(text) {
|
|
|
+ return text
|
|
|
+ .replace(/</g, '<')
|
|
|
+ .replace(/>/g, '>')
|
|
|
+ .replace(/&/g, '&')
|
|
|
+ .replace(/"/g, '"')
|
|
|
+ .replace(/'/g, "'")
|
|
|
+ .replace(/ /g, ' ');
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 编码 HTML 实体(用于安全输出)
|
|
|
+ */
|
|
|
+function encodeHtmlEntities(text) {
|
|
|
+ return text
|
|
|
+ .replace(/&/g, '&')
|
|
|
+ .replace(/</g, '<')
|
|
|
+ .replace(/>/g, '>');
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* 渲染 HTML 中的所有数学公式
|
|
|
*/
|
|
|
@@ -90,38 +113,51 @@ function processDelimiter(html, left, right, displayMode) {
|
|
|
const rightEscaped = escapeRegex(right);
|
|
|
|
|
|
// 构建正则表达式
|
|
|
- // 对于 $ ... $,需要确保不匹配 $$ ... $$
|
|
|
+ // 【关键修复】排除包含 HTML 标签的内容(不匹配 < 或 >)
|
|
|
let pattern;
|
|
|
if (left === '$' && right === '$') {
|
|
|
- // 单个 $ 不能紧跟另一个 $
|
|
|
- pattern = new RegExp(`(?<!\\$)\\$(?!\\$)([^$]+?)(?<!\\$)\\$(?!\\$)`, 'g');
|
|
|
+ // 单个 $...$:不匹配 $$,不匹配包含 < > 的内容
|
|
|
+ pattern = new RegExp(`(?<!\\$)\\$(?!\\$)([^$<>]+?)(?<!\\$)\\$(?!\\$)`, 'g');
|
|
|
+ } else if (left === '$$' && right === '$$') {
|
|
|
+ // $$...$$:不匹配包含 < > 的内容
|
|
|
+ pattern = new RegExp(`\\$\\$([^<>]*?)\\$\\$`, 'g');
|
|
|
} else {
|
|
|
- pattern = new RegExp(`${leftEscaped}([\\s\\S]*?)${rightEscaped}`, 'g');
|
|
|
+ // \(...\) 和 \[...\]:不匹配包含 < > 的内容
|
|
|
+ pattern = new RegExp(`${leftEscaped}([^<>]*?)${rightEscaped}`, 'g');
|
|
|
}
|
|
|
|
|
|
return html.replace(pattern, (match, latex) => {
|
|
|
try {
|
|
|
- // 清理 LaTeX 内容
|
|
|
- let cleanLatex = latex.trim();
|
|
|
+ // 清理 LaTeX 内容 - 先解码 HTML 实体
|
|
|
+ let cleanLatex = decodeHtmlEntities(latex.trim());
|
|
|
|
|
|
// 跳过空内容
|
|
|
if (!cleanLatex) {
|
|
|
return match;
|
|
|
}
|
|
|
|
|
|
+ // 【安全检查】如果内容看起来不像 LaTeX,跳过
|
|
|
+ // 跳过只有普通文本的内容(没有任何 LaTeX 特征)
|
|
|
+ if (!/[\\^_{}]/.test(cleanLatex) && !/[a-zA-Z]{2,}/.test(cleanLatex)) {
|
|
|
+ // 可能只是普通数字或单字母,检查是否有意义
|
|
|
+ if (/^[\d\s\.\,\-\+]+$/.test(cleanLatex)) {
|
|
|
+ return match; // 纯数字,不渲染
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
// 渲染 KaTeX
|
|
|
const rendered = katex.renderToString(cleanLatex, {
|
|
|
displayMode: displayMode,
|
|
|
throwOnError: false,
|
|
|
strict: false,
|
|
|
trust: true,
|
|
|
- output: 'html', // 使用 HTML 输出(比 mathml 兼容性更好)
|
|
|
+ output: 'html',
|
|
|
});
|
|
|
|
|
|
return rendered;
|
|
|
} catch (error) {
|
|
|
// 渲染失败时保留原始内容
|
|
|
- console.error(`KaTeX error for "${latex.substring(0, 50)}...":`, error.message);
|
|
|
+ // console.error(`KaTeX error for "${latex.substring(0, 50)}...":`, error.message);
|
|
|
return match;
|
|
|
}
|
|
|
});
|