|
@@ -262,46 +262,42 @@ class MathFormulaProcessor
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* 清理定界符内部的 HTML 标签
|
|
* 清理定界符内部的 HTML 标签
|
|
|
|
|
+ * 【修复】不再使用 strip_tags(),因为它会把 LaTeX 中的 < > 当作标签删除
|
|
|
|
|
+ * 例如:$x<4$ 中的 <4 会被 strip_tags 误删
|
|
|
*/
|
|
*/
|
|
|
private static function cleanInsideDelimiters(string $content): string
|
|
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. 处理 $$...$$ 显示公式
|
|
// 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);
|
|
}, $content);
|
|
|
|
|
|
|
|
// 2. 处理 \(...\) 行内公式
|
|
// 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);
|
|
}, $content);
|
|
|
|
|
|
|
|
// 3. 处理 \[...\] 显示公式
|
|
// 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);
|
|
}, $content);
|
|
|
|
|
|
|
|
// 4. 最后处理 $...$ 行内公式(避免与$$冲突)
|
|
// 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);
|
|
}, $content);
|
|
|
|
|
|
|
|
return $content;
|
|
return $content;
|