From 1d4baf02b5097c78266e0687afdc6b59cd0d077b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E7=90=A6?= Date: Sun, 12 Jul 2026 10:00:02 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E9=A1=B5=E9=9D=A2=E3=80=81?= =?UTF-8?q?=E4=BF=AE=E5=A4=8DBUG?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/utils/articlePptSlides.ts | 29 ++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/client/src/utils/articlePptSlides.ts b/client/src/utils/articlePptSlides.ts index 4026aca..aa2c93c 100644 --- a/client/src/utils/articlePptSlides.ts +++ b/client/src/utils/articlePptSlides.ts @@ -47,6 +47,16 @@ export type PptSlide = PptTitleSlide | PptSectionSlide const PPT_SLIDE_BOTTOM = 5.1 const SECTION_HEADER_HEIGHT = 0.85 const IMAGE_PLACEHOLDER_GLOBAL_RE = /\[图片(?::[^\]]*)?\]/g +const IMAGE_FILENAME_SUFFIX_RE = + /\s+[\w\u4e00-\u9fa5.-]+\.(jpg|jpeg|png|gif|webp|svg|bmp)\s*$/i + +function stripTrailingImageFilenames(text: string): string { + let result = text + while (IMAGE_FILENAME_SUFFIX_RE.test(result)) { + result = result.replace(IMAGE_FILENAME_SUFFIX_RE, '') + } + return result +} let markdownParser: MarkdownIt | null = null @@ -82,9 +92,11 @@ function renderInlineText(inlineToken: Token): string { return renderTokenChildren(inlineToken.children) } -/** 移除 inline 渲染产生的 [图片: ...] 占位片段 */ +/** 移除 inline 渲染产生的 [图片: ...] 占位片段与段尾图片文件名 */ export function stripImagePlaceholders(text: string): string { - return text.replace(IMAGE_PLACEHOLDER_GLOBAL_RE, '').replace(/\s+/g, ' ').trim() + let result = text.replace(IMAGE_PLACEHOLDER_GLOBAL_RE, '') + result = stripTrailingImageFilenames(result) + return result.replace(/\s+/g, ' ').trim() } function getImgSrc(el: Element): string { @@ -454,7 +466,9 @@ export function dedupeImageCaptionBlocks(blocks: ContentBlock[]): ContentBlock[] const prev = result[result.length - 1] if (block.type === 'paragraph') { - const text = block.text.trim() + const text = stripImagePlaceholders(block.text) + if (!text) continue + const next = blocks[i + 1] if (prev?.type === 'image' && isImageCaptionLike(text, prev)) { @@ -463,12 +477,15 @@ export function dedupeImageCaptionBlocks(blocks: ContentBlock[]): ContentBlock[] if (next?.type === 'image' && isImageCaptionLike(text, next)) { continue } - result.push(block) + result.push(text === block.text ? block : { ...block, text }) continue } - if (block.type === 'list' && prev?.type === 'image') { - const items = block.items.filter((item) => !isImageCaptionLike(item, prev)) + if (block.type === 'list') { + const items = block.items + .map((item) => stripImagePlaceholders(item)) + .filter(Boolean) + .filter((item) => !(prev?.type === 'image' && isImageCaptionLike(item, prev))) if (items.length) { result.push({ ...block, items }) }