Explorar o código

fix(pdf): avoid orphan dot after media and normalize dot before trailing note

yemeishu hai 3 semanas
pai
achega
08d0989412

+ 23 - 2
app/Support/BlankPlaceholderRenderer.php

@@ -168,14 +168,35 @@ class BlankPlaceholderRenderer
             return $content;
         }
 
-        // 句尾若已有终止符号(中英文句号/问号/叹号/分号/冒号),则不再追加
-        if (preg_match('/[\..。!!\??;;::](\s*(?:(?:<\/[^>]+>|<[^>]+\/>)\s*)*)$/us', $content)) {
+        // 末尾若是图像类媒体标签(例如 <image .../>),不追加标点,避免出现独立一行的孤立小点。
+        if (preg_match('/(?:<\s*image\b[^>]*\/?>|<\s*img\b[^>]*\/?>|<\s*svg\b[\s\S]*<\/\s*svg\s*>)(?:\s*(?:(?:<\/[^>]+>|<[^>]+\/>)\s*)*)$/iu', $content)) {
+            return $content;
+        }
+
+        // 句尾若已有终止符号(按“可见文本”判断,避免把 HTML 实体中的分号误判为终止符)
+        $visibleText = html_entity_decode(strip_tags($content), ENT_QUOTES | ENT_HTML5, 'UTF-8');
+        $visibleText = rtrim($visibleText);
+        if ($visibleText !== '' && preg_match('/[\..。!!\??;;::]$/u', $visibleText)) {
             return $content;
         }
 
         return rtrim($content).$punctuation;
     }
 
+    /**
+     * 填空题常见写法:"...。 (说明)" / "...。(说明)"(后面可能跟图片标签)
+     * 将该处句号统一为英文小点,避免句尾媒体标签场景下出现错误补点。
+     */
+    public static function normalizePeriodBeforeTrailingParentheticalNote(string $content, string $replacement = '.'): string
+    {
+        return preg_replace(
+            '/[。.\.](?=\s*[((][^))]{1,80}[))]\s*(?:(?:<[^>]+>\s*)*)$)/u',
+            $replacement,
+            $content,
+            1
+        ) ?? $content;
+    }
+
     private static function normalizeChineseTerminalPeriod(string $content): string
     {
         // 仅在存在中文语境时,把句末英文句号统一为中文句号。

+ 2 - 0
resources/views/components/exam/paper-body.blade.php

@@ -293,6 +293,8 @@
             }
             // 填空题:句尾统一为实心小圆点(英文句点)。
             $renderedContent = \App\Support\BlankPlaceholderRenderer::normalizeTerminalPunctuation($renderedContent, 'dot');
+            // 填空题:若末尾是“句号 + 括注说明”(后可跟图片),将该句号统一为英文小点。
+            $renderedContent = \App\Support\BlankPlaceholderRenderer::normalizePeriodBeforeTrailingParentheticalNote($renderedContent, '.');
             $renderedContent = \App\Support\BlankPlaceholderRenderer::appendTerminalPunctuationIfMissing($renderedContent, '.');
             $renderedContent = $mathProcessed ? $renderedContent : \App\Services\MathFormulaProcessor::processFormulas($renderedContent);
         @endphp