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

fix: 大于小于号公式显示问题:strip_tags 的误删行为

gwd пре 1 недеља
родитељ
комит
02aad935d2
1 измењених фајлова са 21 додато и 25 уклоњено
  1. 21 25
      app/Services/MathFormulaProcessor.php

+ 21 - 25
app/Services/MathFormulaProcessor.php

@@ -262,46 +262,42 @@ class MathFormulaProcessor
 
     /**
      * 清理定界符内部的 HTML 标签
+     * 【修复】不再使用 strip_tags(),因为它会把 LaTeX 中的 < > 当作标签删除
+     * 例如:$x<4$ 中的 <4 会被 strip_tags 误删
      */
     private static function cleanInsideDelimiters(string $content): string
     {
         // 修复:使用更精确的正则表达式,避免模式冲突
-        // 先处理 $$...$$ 模式,然后处理单个 $...$ 模式(但确保不被$$包含)
+        // 只移除真正的 HTML 标签(如 <span>, <br>, </div> 等),保留数学符号 < >
+
+        // 定义安全的 HTML 标签清理函数(只移除真正的 HTML 标签)
+        $cleanHtmlTags = function (string $tex): string {
+            // 只移除看起来像 HTML 标签的内容(以字母开头的标签)
+            // 例如:<span>, </div>, <br/>, 但保留 <4, >0, x<y 等数学表达式
+            $tex = preg_replace('/<\/?[a-zA-Z][a-zA-Z0-9]*[^>]*>/', '', $tex);
+            // 解码 HTML 实体
+            $tex = html_entity_decode($tex, ENT_QUOTES, 'UTF-8');
+            return trim($tex);
+        };
 
         // 1. 处理 $$...$$ 显示公式
-        $content = preg_replace_callback('/\$\$([\s\S]*?)\$\$/', function ($matches) {
-            $cleanContent = strip_tags($matches[1]);
-            $cleanContent = html_entity_decode($cleanContent, ENT_QUOTES, 'UTF-8');
-            $cleanContent = trim($cleanContent);
-
-            return '$$'.$cleanContent.'$$';
+        $content = preg_replace_callback('/\$\$([\s\S]*?)\$\$/', function ($matches) use ($cleanHtmlTags) {
+            return '$$' . $cleanHtmlTags($matches[1]) . '$$';
         }, $content);
 
         // 2. 处理 \(...\) 行内公式
-        $content = preg_replace_callback('/\\\\\(([\s\S]*?)\\\\\)/', function ($matches) {
-            $cleanContent = strip_tags($matches[1]);
-            $cleanContent = html_entity_decode($cleanContent, ENT_QUOTES, 'UTF-8');
-            $cleanContent = trim($cleanContent);
-
-            return '\\('.$cleanContent.'\\)';
+        $content = preg_replace_callback('/\\\\\(([\s\S]*?)\\\\\)/', function ($matches) use ($cleanHtmlTags) {
+            return '\\(' . $cleanHtmlTags($matches[1]) . '\\)';
         }, $content);
 
         // 3. 处理 \[...\] 显示公式
-        $content = preg_replace_callback('/\\\\\[([\s\S]*?)\\\\\]/', function ($matches) {
-            $cleanContent = strip_tags($matches[1]);
-            $cleanContent = html_entity_decode($cleanContent, ENT_QUOTES, 'UTF-8');
-            $cleanContent = trim($cleanContent);
-
-            return '\\['.$cleanContent.'\\]';
+        $content = preg_replace_callback('/\\\\\[([\s\S]*?)\\\\\]/', function ($matches) use ($cleanHtmlTags) {
+            return '\\[' . $cleanHtmlTags($matches[1]) . '\\]';
         }, $content);
 
         // 4. 最后处理 $...$ 行内公式(避免与$$冲突)
-        $content = preg_replace_callback('/(?<!\$)\$([^$\n]+?)\$(?!\$)/', function ($matches) {
-            $cleanContent = strip_tags($matches[1]);
-            $cleanContent = html_entity_decode($cleanContent, ENT_QUOTES, 'UTF-8');
-            $cleanContent = trim($cleanContent);
-
-            return '$'.$cleanContent.'$';
+        $content = preg_replace_callback('/(?<!\$)\$([^$\n]+?)\$(?!\$)/', function ($matches) use ($cleanHtmlTags) {
+            return '$' . $cleanHtmlTags($matches[1]) . '$';
         }, $content);
 
         return $content;