Преглед изворни кода

fix: 知识点公式解析 bug 跟踪。

yemeishu пре 1 недеља
родитељ
комит
9ce89d85d1
2 измењених фајлова са 44 додато и 8 уклоњено
  1. 5 0
      app/Services/KatexRenderer.php
  2. 39 8
      app/Services/MathFormulaProcessor.php

+ 5 - 0
app/Services/KatexRenderer.php

@@ -189,6 +189,11 @@ class KatexRenderer
             $tex = preg_replace('/<br\\s*\\/?>/i', '', $tex);
             $tex = preg_replace('/\\r\\n|\\r|\\n/', '', $tex);
 
+            // 处理 KaTeX 不支持的操作符命令
+            $tex = preg_replace('/\\\\Arg\\b/', '\\\\operatorname{Arg}', $tex);
+            // 修复漏空格的 \quad/\qquad(如 \quadz、\quadx)
+            $tex = preg_replace('/\\\\q(u)?ad(?=[A-Za-z0-9])/', '\\\\q$1ad ', $tex);
+
             return $this->fixCasesLineBreaks($tex);
         };
 

+ 39 - 8
app/Services/MathFormulaProcessor.php

@@ -2,6 +2,8 @@
 
 namespace App\Services;
 
+use Illuminate\Support\Facades\Log;
+
 class MathFormulaProcessor
 {
     /**
@@ -89,19 +91,48 @@ class MathFormulaProcessor
         // 保留 \\+大写字母 的情况(换行符后跟文本,如 \\CD 应保持为 \\CD)
         // 保留 \\+数字 或 \\+空白 的情况(矩阵换行符)
         $fixEscapedCommands = function ($tex) {
-            // 保护 cases 环境中的换行符 \\,避免被误判为 LaTeX 命令
-            $placeholder = '__KATEX_CASES_BR__';
-            $tex = preg_replace_callback('/\\\\begin\{cases\}([\s\S]*?)\\\\end\{cases\}/', function ($m) use ($placeholder) {
-                $content = str_replace('\\\\', $placeholder, $m[1]);
-                return '\\begin{cases}' . $content . '\\end{cases}';
-            }, $tex);
+            // 保护多行环境中的换行符 \\,避免被误判为 LaTeX 命令
+            $placeholder = '__KATEX_BR__';
+            $originalTex = $tex;
+            $protectedEnvs = [];
+            $environments = [
+                'cases',
+                'aligned',
+                'align',
+                'align*',
+                'array',
+                'matrix',
+                'pmatrix',
+                'bmatrix',
+                'vmatrix',
+                'Vmatrix',
+                'gather',
+                'split',
+                'eqnarray',
+            ];
+            foreach ($environments as $env) {
+                $pattern = '/\\\\begin\{' . preg_quote($env, '/') . '\}([\s\S]*?)\\\\end\{' . preg_quote($env, '/') . '\}/';
+                $tex = preg_replace_callback($pattern, function ($m) use ($env, $placeholder) {
+                    $content = str_replace('\\\\', $placeholder, $m[1]);
+                    return '\\begin{' . $env . '}' . $content . '\\end{' . $env . '}';
+                }, $tex);
+                if ($tex !== $originalTex && !in_array($env, $protectedEnvs, true)) {
+                    $protectedEnvs[] = $env;
+                }
+            }
 
             // \\sqrt -> \sqrt, \\frac -> \frac, 但 \\CD 或 \\2 保持不变
             // 【修复】只匹配小写字母,因为 LaTeX 命令都是小写
             $tex = preg_replace('/\\\\\\\\([a-z])/', '\\\\$1', $tex);
 
-            // 还原 cases 换行
-            return str_replace($placeholder, '\\\\', $tex);
+            // 还原多行环境换行
+            $tex = str_replace($placeholder, '\\\\', $tex);
+            if ($protectedEnvs) {
+                Log::debug('MathFormulaProcessor: protected multiline line breaks', [
+                    'envs' => $protectedEnvs,
+                ]);
+            }
+            return $tex;
         };
 
         // 1. 处理 $$...$$ 块级公式