|
|
@@ -26,15 +26,19 @@ class MathFormulaProcessor
|
|
|
}
|
|
|
$content = trim($content);
|
|
|
|
|
|
- // 1. 如果已有正确的定界符,只清理内部 HTML,不做其他修改
|
|
|
- if (self::hasDelimiters($content)) {
|
|
|
- return self::cleanInsideDelimiters($content);
|
|
|
+ // 1. 【关键修复】处理公式内的双反斜杠 -> 单反斜杠
|
|
|
+ // 数据库存储时 \sqrt 变成 \\sqrt,需要还原
|
|
|
+ $content = self::normalizeBackslashesInDelimiters($content);
|
|
|
+
|
|
|
+ // 2. 如果内容中包含定界符,清理内部 HTML
|
|
|
+ if (self::containsDelimiters($content)) {
|
|
|
+ $content = self::cleanInsideDelimiters($content);
|
|
|
}
|
|
|
|
|
|
- // 2. 检测内容类型:纯数学、混合内容还是纯文本
|
|
|
+ // 3. 检测内容类型:纯数学、混合内容还是纯文本
|
|
|
$contentType = self::detectContentType($content);
|
|
|
|
|
|
- // 3. 根据内容类型采取不同的处理策略
|
|
|
+ // 4. 根据内容类型采取不同的处理策略
|
|
|
switch ($contentType) {
|
|
|
case 'pure_math':
|
|
|
// 纯数学表达式,如 "4x^2 - 25y^2" 或 "f(x) = x^2 - 4x + 5"
|
|
|
@@ -51,6 +55,48 @@ class MathFormulaProcessor
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 【新增】将公式定界符内的双反斜杠转为单反斜杠
|
|
|
+ * 与前端 MathText.tsx 的 preprocessText 逻辑保持一致
|
|
|
+ */
|
|
|
+ private static function normalizeBackslashesInDelimiters(string $content): string
|
|
|
+ {
|
|
|
+ // 1. 处理 $$...$$ 块级公式内的双反斜杠
|
|
|
+ $content = preg_replace_callback('/\$\$([\s\S]*?)\$\$/', function ($matches) {
|
|
|
+ $tex = str_replace('\\\\', '\\', $matches[1]);
|
|
|
+ return '$$' . $tex . '$$';
|
|
|
+ }, $content);
|
|
|
+
|
|
|
+ // 2. 处理 $...$ 行内公式内的双反斜杠(避免与$$冲突)
|
|
|
+ $content = preg_replace_callback('/(?<!\$)\$([^$\n]+?)\$(?!\$)/', function ($matches) {
|
|
|
+ $tex = str_replace('\\\\', '\\', $matches[1]);
|
|
|
+ return '$' . $tex . '$';
|
|
|
+ }, $content);
|
|
|
+
|
|
|
+ // 3. 处理 \(...\) 行内公式
|
|
|
+ $content = preg_replace_callback('/\\\\\(([\s\S]*?)\\\\\)/', function ($matches) {
|
|
|
+ $tex = str_replace('\\\\', '\\', $matches[1]);
|
|
|
+ return '\\(' . $tex . '\\)';
|
|
|
+ }, $content);
|
|
|
+
|
|
|
+ // 4. 处理 \[...\] 块级公式
|
|
|
+ $content = preg_replace_callback('/\\\\\[([\s\S]*?)\\\\\]/', function ($matches) {
|
|
|
+ $tex = str_replace('\\\\', '\\', $matches[1]);
|
|
|
+ return '\\[' . $tex . '\\]';
|
|
|
+ }, $content);
|
|
|
+
|
|
|
+ return $content;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 【新增】检查内容中是否包含任意定界符(不要求整个字符串被包裹)
|
|
|
+ */
|
|
|
+ private static function containsDelimiters(string $content): bool
|
|
|
+ {
|
|
|
+ // 检查是否包含 $...$, $$...$$, \(...\), \[...\]
|
|
|
+ return preg_match('/\$\$[\s\S]*?\$\$|\$[^$\n]+?\$|\\\\\([\s\S]*?\\\\\)|\\\\\[[\s\S]*?\\\\\]/', $content) === 1;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 检测内容类型
|
|
|
* 优化:加入中文检测,避免包裹包含中文的混合内容
|