Skip to content

fix(export): render Mermaid diagrams in exports#847

Merged
Nagi-ovo merged 12 commits into
Nagi-ovo:mainfrom
BattleAngelES:fix/mermaid-export-rendering
Jul 24, 2026
Merged

fix(export): render Mermaid diagrams in exports#847
Nagi-ovo merged 12 commits into
Nagi-ovo:mainfrom
BattleAngelES:fix/mermaid-export-rendering

Conversation

@BattleAngelES

@BattleAngelES BattleAngelES commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

AI-Assisted PR Policy / AI 辅助 PR 政策

  • The maintainer reviewed the final scope, implementation, diff, and validation results.
  • The expected behavior, affected export paths, fallback behavior, and verification plan were agreed before implementation.

Description / 描述

Voyager rendered Mermaid blocks in Gemini, but rich exports could still select the hidden source block or lose SVG labels in browser PDF/PNG renderers. This PR now:

  • exports rendered Mermaid diagrams for PDF and image output;
  • preserves fenced Mermaid source for Markdown/text output;
  • preserves list order, nested containers, neighboring code blocks, and the existing hasCode behavior;
  • normalizes Mermaid export output to the existing light document surface;
  • rasterizes only the Mermaid clone at 2x for browser-sensitive PDF and whole-document PNG rendering;
  • keeps the rest of PDF content as native text;
  • scales each diagram proportionally to no more than one printable page;
  • falls back to a sanitized SVG data image if Mermaid-only rasterization fails;
  • shares Mermaid sizing/isolation logic across conversation PDF, image export, and Deep Research PDF.

Root causes:

  1. .gv-mermaid-wrapper contains both a hidden code-block and the rendered SVG, and generic code-block extraction could win before traversal reached the diagram.
  2. Browser renderers can retain SVG geometry while dropping or clipping text inside Mermaid foreignObject labels.
  3. The earlier rasterization error path left the raw SVG in the print DOM instead of applying the intended isolated-image fallback.

Related work / 关联

Browser verification / 浏览器验证

Final implementation head: fb9ceb8e

  • Chrome: real Gemini conversation with a locally loaded Voyager build; PDF retained Mermaid labels, and a tall diagram stayed on one printable page.
  • Firefox 152.0.5: temporary production dist_firefox on a real signed-out Gemini conversation; source page rendered the diagram, PDF retained all Chinese labels, PNG retained all labels without right-edge clipping, and Markdown preserved fenced Mermaid source.
  • Safari: optional under .github/CONTRIBUTING.md. The previous community run on 3cb226b was inconclusive because the source page had not rendered Mermaid. Safari image export is disabled by existing product guards, so it is not treated as a PNG merge gate.

The successful Chrome/Firefox workflows were run on d43a3498. The only delta in final fb9ceb8e is the induced rasterization-failure fallback; it is covered by a regression test that forces the renderer to reject and verifies the sanitized data image, removal of the raw SVG, wrapper theme metadata, and accessible label.

Detailed maintainer verification:
#847 (comment)

Validation

  • bun run test: 248 files / 2284 tests passed
  • bun run typecheck: passed
  • bun run lint: passed with 0 errors (209 existing warnings)
  • bun run build:chrome: passed
  • bun run build:firefox: passed
  • git diff --check: passed
  • GitHub Actions CI is required again on the final head before merge.

Acknowledgements

Thanks @hulyhulyhuly for the Safari report that exposed the separate Traditional Chinese source-page precondition and helped keep this PR scoped correctly.

Checklist / 检查清单

  • The final implementation and affected export paths were reviewed.
  • Real Chrome and mandatory Firefox workflows were manually verified.
  • Markdown, PDF, PNG, nested list/code behavior, and failure fallback have regression coverage.
  • The change remains focused on Mermaid rendering inside exports.
  • Local lint, typecheck, full tests, and Chrome/Firefox builds pass.

@BattleAngelES
BattleAngelES marked this pull request as ready for review July 20, 2026 03:40

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 32ce37a3ac

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/features/export/services/DOMContentExtractor.ts
Comment thread src/features/export/services/DOMContentExtractor.ts Outdated
@BattleAngelES
BattleAngelES marked this pull request as draft July 20, 2026 06:19
@BattleAngelES
BattleAngelES marked this pull request as ready for review July 20, 2026 06:46

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4344ee7de5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/features/export/services/DOMContentExtractor.ts Outdated
Comment thread src/features/export/services/DeepResearchPDFPrintService.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6db8a80e2a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/features/export/services/DOMContentExtractor.ts

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f9abe55721

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/features/export/services/DOMContentExtractor.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d2f082f519

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/pages/content/mermaid/index.ts Outdated

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Already looking forward to the next diff.

Reviewed commit: 07f8a41b1c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@anontokyo-dev anontokyo-dev left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

结论

当前版本先 Request changes。自动初审提出的问题已经逐轮修复,CI 也全部通过,但仍有真实流程验证和一个可复现的导出回归需要补齐。

阻塞项

  1. 缺少真实 Gemini 导出链路的可视化验证。 PR 描述明确写了未进行 account-backed Gemini workflow,真实流程与约 15 分钟体验项也仍未勾选;现有两张图是构造的 Chromium fixture,不能证明已安装扩展后的真实会话能正确导出 PDF/PNG。请至少用真实 Gemini Mermaid 会话补充 PDF 与图片导出的截图或录屏,覆盖浅色/深色和一个较宽或较长的图,并确认 Markdown 仍保留 fenced Mermaid 源码。此改动也触及 Deep Research 导出,若本人无对应环境,请协调可复现环境的测试者给出证据。
  2. Firefox 目前只有 build,没有交互实测。 CONTRIBUTING 将 Firefox 标为必测;请补充实际加载扩展后的 Firefox 导出结果。Safari 可继续明确标注未测。
  3. 列表中的透明容器仍会破坏 Mermaid 文本导出。 详见行内评论;我已在当前提交复现 hasCode: false 且源码、语言标签和 SVG 文本被压成普通文本。

可维护性

请本轮顺手收敛重复实现:Mermaid 的 sizing/dark-surface CSS 目前散落在 PDFPrintServiceDeepResearchPDFPrintServiceImageExportService 的两个模板中,建议仿照现有 buildKatexExportStyles 提取共享 builder;processNodesextractList 的 Mermaid/code-block 发现逻辑也应共用一个按 DOM 顺序遍历的 helper,避免两条路径继续漂移。

CI

  • ✅ Format
  • ✅ Lint
  • ✅ Typecheck
  • ✅ Test
  • ✅ i18n
  • ✅ Build (chrome)
  • ✅ Build (edge)
  • ✅ Build (firefox)
  • ✅ Build (safari)
  • ✅ Native Swift Test & Xcode Build
本地增量验证
  • bun run typecheck 通过
  • 相关 5 个测试文件共 119 tests 通过
  • 全量套件在本机运行中被环境以 143 中止;GitHub Actions 的完整 Test job 已通过

Comment thread src/features/export/services/DOMContentExtractor.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1d071a5b89

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/features/export/services/DOMContentExtractor.ts Outdated

@anontokyo-dev anontokyo-dev left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Follow-up 结论

最新提交已经修复了我复现的列表嵌套问题,也把 Mermaid 导出样式收敛到了共享 builder。真实 Chrome 深色导出证据已补;我本地复验了相关 6 个测试文件(131 tests)和 typecheck,当前 CI 也全部通过。

不过目前仍有以下准入项需要处理:

  1. 当前结果还不是完整的 light/dark mode 适配。 导出容器以及 PNG/PDF 渲染仍然强制白色背景和深色正文,只有 dark Mermaid wrapper 使用深色背景,因此截图里呈现的是“白色文档中嵌一块深色图”。可读性没问题,但主题并不一致。

    • 如果产品决定继续保持现有白色导出,Mermaid 也应转换或重新渲染为 light theme;
    • 如果要支持 dark export,背景、正文、链接、边框、代码块、附件和 Mermaid 应一起切换到同一主题。

    请不要只给 Mermaid 单独铺深色底,并补充同一真实 Gemini 会话在 light/dark 两种主题下的 PNG/PDF 导出截图,证明整份产物的主题一致。

  2. Firefox 仍只有 build,没有实际加载扩展并验证受影响导出流程。 按仓库 CONTRIBUTING.md,Firefox 是必测环境,请补充实际测试结果。

  3. 当前最新提交 359d503 尚未有自动 Codex review;完成调整后请在最新 head 上重新触发一次。

因此这一轮仍然是 Request changes。前一轮的嵌套遍历与样式重复问题已经确认解决,不再阻塞。

@Nagi-ovo

Copy link
Copy Markdown
Owner

@anontokyo-dev 在群里继续推进一下

@anontokyo-dev

Copy link
Copy Markdown
Collaborator

收到,我会在群里按协作测试的方式继续推进。

我刚重新核对过:当前 head 仍是 359d503,没有新的实现提交;CI 全绿,但上一轮 Request Changes 的准入项还没有补齐。接下来按这个顺序走:

  1. 作者先完成主题策略。 可以选择“整份导出固定为 light,Mermaid 同步重渲染为 light”,或实现“整份导出随 light/dark 一起切换”;不能只在白色导出里给 Mermaid 单独铺深色底。
  2. 实现更新后补同一真实会话的 light/dark PNG 与 PDF 证据。 截图需要能看出整份导出的背景、正文、代码块/附件和 Mermaid 主题一致。
  3. 群内招募缺失环境。 Firefox 测试者需在最新 commit 实际加载扩展,覆盖 PNG、PDF、Markdown 以及一项相邻旧功能,并把系统/浏览器版本、commit SHA、步骤、结果和截图直接评论到本 PR;Safari 也会同步招募,但按仓库规则仍作为可选环境。
  4. 证据齐全后,在最新 head 重新触发自动 review,我再做最终复验。

协作测试者会在 PR 的测试矩阵中署名并链接证据;若测试过程沉淀了测试用例或文档,则由测试者提交对应 commit,形成可追踪的正式贡献。

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 49c56b5efe

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/pages/content/mermaid/index.ts
@anontokyo-dev

anontokyo-dev commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

887d7ba 增量复核

主题实现的代码方向已经对齐:导出产物继续保持现有白色 / light surface;页面处于 dark theme 时,Mermaid 额外生成一份 light SVG 供 PDF/PNG 导出使用,不再把深色图块直接嵌进白色文档。

我完成了以下复验:

  • bun run typecheck
  • ✅ 相关 6 个测试文件,133 tests
  • ✅ 最新链接颜色归一化提交的 ImageExportService,12 tests
  • ✅ 使用实际 Mermaid 运行验证:全局初始化为 dark 后,带 config.theme: default frontmatter 的第二次渲染会生成不同的 light palette,而不是继续沿用 dark palette
  • ✅ light 导出渲染失败时回退源码,不影响页面上的既有图表

当前 commit 887d7ba 可以作为协作测试基线。为了避免证据与代码错位,测试期间请不要继续改写该 commit;若再推提交,需要在新 SHA 上重测。

仍待完成

  1. PR 正文和现有截图仍描述旧的 dark surface 方案。请在真实 Gemini 的同一 Mermaid 会话中分别使用页面 light/dark theme,导出 PNG、PDF 与 Markdown;两组 PNG/PDF 都应呈现统一的浅色文档和浅色 Mermaid,并更新正文与截图。
  2. Firefox 仍需在 887d7ba 上实际加载扩展,验证 PNG / PDF / Markdown 和一项相邻旧导出功能,并由测试者把环境、步骤、结果与截图直接评论到本 PR。
  3. Safari 测试者已在群内认领;这是可选补充,证据格式与 Firefox 相同。
  4. 当前 CI 已全部通过:Format、Lint、Typecheck、Test、i18n、Chrome / Edge / Firefox / Safari Build、Native Swift Test & Xcode Build 均为绿色。

最新 head 887d7ba 的自动复审已经完成,没有新增行内问题。现在等待协作测试证据,齐全后再做最终结论。

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 887d7ba55a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/pages/content/mermaid/index.ts
@anontokyo-dev

Copy link
Copy Markdown
Collaborator

当前状态确认

我重新核对过了:head 仍是 887d7ba,CI 全绿,最新自动 review 没有新增问题;代码基线没有变化。

目前没有新的测试证据落到 PR,正文也仍是旧的 dark-surface 描述和旧截图,所以 Request Changes 状态保持不变。下一步不需要继续改代码,而是完成下面的协作验证:

  • 作者本人:在 887d7ba 上亲自跑真实 Chrome + Gemini 流程,补页面 light/dark 两组 PNG、PDF、Markdown 结果,并更新 PR 正文中的实现描述、测试说明和截图。这里需要说明自己测过哪些受影响功能,不能只转述 Agent 结论。
  • Firefox 测试者:实际加载该 commit,覆盖 PNG / PDF / Markdown 与一项相邻旧导出功能,把环境、步骤、结果和截图直接评论到本 PR。
  • Safari 测试者:已认领,可按相同格式补充可选平台证据。

证据评论都落到这里后再 @ 我,我会核对 SHA、证据和影响范围并给最终结论。当前不要 merge。

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 887d7ba55a

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/pages/content/mermaid/index.ts
@anontokyo-dev

anontokyo-dev commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

3cb226b 增量复核

这次提交把 light 导出主题从 Mermaid 11 的 frontmatter 改成跨版本 init directive,用于兼容 Firefox build 使用的 Mermaid 9.2.2。

我完成了实际版本验证,而不只依赖 mock:

  • ✅ Mermaid 11.12.2:全局 dark 配置下,末尾 directive 生成 light palette
  • ✅ Mermaid 11.12.2:已有 frontmatter(含 theme: dark)时,末尾 directive 仍生成 light palette
  • ✅ Mermaid 9.2.2:末尾和前置 directive 都生成 light palette
  • src/pages/content/mermaid/__tests__/mermaid.test.ts:64 tests
  • bun run typecheck

因此这项改动的代码方向没有新增阻塞;协作测试基线更新为 3cb226b,此前的 887d7ba 证据不再作为最终基线。请从现在起冻结 head,除非测试发现明确问题,不要再追加代码提交,否则协作测试需要重新开始。

仍待完成

  1. PR 正文仍描述旧的 dark-surface 方案,截图也是旧结果;请作者本人更新实现说明,并在 3cb226b 上补真实 Chrome + Gemini 的页面 light/dark 两组 PNG、PDF、Markdown 证据。
  2. Firefox 测试者需在 3cb226b 上实际加载扩展,覆盖 PNG / PDF / Markdown 和一项相邻旧导出功能,并直接评论环境、步骤、结果和截图。
  3. Safari 测试者已认领,需改用 3cb226b;Safari 仍为可选平台。
  4. 当前 CI 已全部通过:Format、Lint、Typecheck、Test、i18n、Chrome / Edge / Firefox / Safari Build、Native Swift Test & Xcode Build 均为绿色。
  5. 最新 head 3cb226b 的自动 review 已完成,没有新增问题。

代码与 CI 复核到此完成,现在等待作者及协作测试者把真实流程证据落到本 PR;证据齐全后再给最终结论。

@anontokyo-dev

Copy link
Copy Markdown
Collaborator

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep them coming!

Reviewed commit: 3cb226b0ea

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@anontokyo-dev

Copy link
Copy Markdown
Collaborator

自动复审确认

已确认自动 review 覆盖最新 head 3cb226b,没有新增代码问题;当前 CI 必需项也已全部通过。

现阶段只剩合并准入证据:

  • 作者更新 PR 正文,并补充最新提交下 Chrome + Gemini 的明暗页面导出验证与截图;
  • 补齐 Firefox 必测结果,覆盖 PNG / PDF / Markdown 及受影响的旧导出功能;
  • Safari 为可选协作验证,若提交证据也请明确基于 3cb226b

证据齐全前继续保持 Request Changes,暂不合并。

@hulyhulyhuly

hulyhulyhuly commented Jul 22, 2026

Copy link
Copy Markdown

Steps of build

  1. git clone https://github.com/BattleAngelES/voyager
  2. git switch 3cb226b
  3. bun run build:safari
  4. import Temporary Extension in Safari

macOS: 15.7.7
safari: 26.5


Gemini conversation immediately before export

圖片

Mermaid Playground

graph LR
    A[Step 1: Input Data] --> B[Step 2: Process & Validate]
    B --> C[Step 3: Generate Output]
Loading

https://mermaid.live/
unnamed


Export Markdown

unnamed

Export PNG

unnamed

Export PDF

unnamed

@anontokyo-dev

Copy link
Copy Markdown
Collaborator

@hulyhulyhuly Thank you. This is a useful Safari failure report bound to the correct 3cb226b baseline.

Result

  • ✅ Markdown preserves the fenced Mermaid source.
  • ❌ PNG shows the Mermaid source code block instead of the rendered diagram.
  • ❌ PDF also shows the Mermaid source code block instead of the rendered diagram.

The PNG/PDF screenshots therefore do not pass the expected behavior of this PR. One clarification is needed to locate the failure: please attach a screenshot of the Gemini conversation immediately before export, showing whether Voyager had already rendered the Mermaid diagram on the page.

  • If Gemini displayed the rendered diagram but PNG/PDF exported source, this is a Safari export-path regression.
  • If Gemini still displayed source, the renderer/setup precondition failed before export, so we need to diagnose the Safari content-script/runtime path first.

Please keep the current files and exact environment. There is no need to repeat every export yet. @BattleAngelES, please treat this as a blocker on the current head until the source-page state is confirmed and the Safari failure is understood. The PR remains in Request Changes.

中文说明

谢谢,这是一份绑定正确基线 3cb226b 的有效 Safari 失败报告:Markdown 正确保留了 Mermaid fenced 源码,但 PNG 和 PDF 都导出了源码代码块,没有渲染后的图,因此当前结果未通过。

请补一张“点击导出前”的 Gemini 会话页面截图,确认页面上当时是否已经显示 Mermaid 图。如果页面有图而导出变源码,就是 Safari 导出链路回归;如果页面本身还是源码,就要先排查 Safari 的渲染/内容脚本。现有文件和环境请保留,暂时不用把全部导出重跑一遍。

@anontokyo-dev

anontokyo-dev commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator

@hulyhulyhuly Thank you; the pre-export screenshot resolves the ambiguity.

Revised diagnosis

This run did not reach the Mermaid export path. The Gemini page itself still showed a normal source code block before export, so Markdown/PNG/PDF preserving that source is expected fallback behavior. The earlier Safari-export failure classification is therefore revised to inconclusive export validation.

The screenshot also reveals a separate localization gap. Gemini labels the block 程式碼片段 in Traditional Chinese. At the current 3cb226b head, GENERIC_LANGUAGE_LABELS includes Simplified Chinese and English generic labels, but not 程式碼片段; processCodeBlocks consequently treats it as a specific language and returns before Mermaid content detection.

Retest

Please keep the same commit and Safari environment, but first make Gemini return an explicitly fenced Mermaid block, for example by asking it to return exactly:

```mermaid
graph LR
  A[Input] --> B[Process]
  B --> C[Output]
```

Before exporting, confirm that Voyager has replaced the source block with a rendered diagram and attach that page screenshot. Then export Markdown, PNG, and PDF from that same conversation. Markdown should retain the fenced source; PNG/PDF should contain the rendered diagram.

The missing Traditional Chinese generic-label handling should be tracked as a separate rendering bug rather than folded into the export verdict. @BattleAngelES, no export-code change should be made based solely on the previous screenshots.

中文说明

补图已经确认:导出前 Gemini 页面本身还是普通源码块,所以这次并没有进入 Mermaid 导出路径;Markdown、PNG、PDF 保留源码属于预期回退。此前“Safari 导出失败”的结论修正为“导出验证前置条件未成立”。

同时发现一个独立的繁中适配缺口:Gemini 把代码块标为 程式碼片段,但当前通用标签列表只有简中和英文,没有这个繁中标签,因此代码在 Mermaid 内容检测前就跳过了。请仍在 3cb226b 上让 Gemini 明确返回带 mermaid 语言标记的 fenced code block,先确认页面已渲染成图,再从同一会话导出 Markdown、PNG、PDF。

繁中通用标签缺失应另行记录为渲染问题,不应根据上一组截图直接修改导出代码。

@anontokyo-dev

Copy link
Copy Markdown
Collaborator

The Traditional Chinese generic-label rendering gap is now tracked separately in #855. Please keep #847 focused on export behavior and retest only after the source page visibly renders the diagram.

Nagi-ovo added a commit to BattleAngelES/voyager that referenced this pull request Jul 24, 2026
Rasterize Mermaid print clones at 2x resolution so browser PDF renderers retain foreignObject labels, while keeping the rest of the document as native text and scaling each diagram to one printable page.

Follow-up for Nagi-ovo#847.

Fixes Nagi-ovo#840

Co-authored-by: Codex <codex@users.noreply.github.com>
@Nagi-ovo
Nagi-ovo force-pushed the fix/mermaid-export-rendering branch from 3cb226b to 60e82c7 Compare July 24, 2026 14:58

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 60e82c70f8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/features/export/services/mermaidSvgImage.ts Outdated
Nagi-ovo added a commit to BattleAngelES/voyager that referenced this pull request Jul 24, 2026
Rasterize Mermaid export clones at 2x resolution so browser renderers retain foreignObject labels in PDF and PNG exports, while keeping non-diagram PDF content as native text and scaling each diagram to one printable page.

Follow-up for Nagi-ovo#847.

Fixes Nagi-ovo#840

Co-authored-by: Codex <codex@users.noreply.github.com>
@Nagi-ovo
Nagi-ovo force-pushed the fix/mermaid-export-rendering branch from 60e82c7 to d43a349 Compare July 24, 2026 15:11
@Nagi-ovo

Copy link
Copy Markdown
Owner

Final verification update — d43a3498

This head is rebased onto current main (c31f0c19) and includes a follow-up for the Firefox foreignObject label loss/clipping found during real-browser testing.

Real browser verification

  • Firefox 152.0.5, temporary production dist_firefox, real signed-out Gemini conversation:
    • page Mermaid rendered with all Chinese labels;
    • PDF preview retained 开始 / 分析问题 / 是否完成 / 导出 PDF and kept the diagram on one page;
    • PNG retained every node label without right-edge clipping;
    • Markdown retained the original fenced mermaid source.
  • Chrome, locally loaded Voyager on a real Gemini conversation:
    • PDF retained Mermaid labels;
    • the tall diagram scaled proportionally to a single printable page instead of splitting across pages.
  • Safari remains optional and not conclusively validated because the earlier Traditional Chinese run did not render Mermaid on the source page; that locale rendering issue was handled separately through [Bug] Mermaid is not detected for Traditional Chinese generic code blocks #855/fix(mermaid): recognize localized generic code labels #856.

Implementation

Only the Mermaid export clone is rasterized at 2x before Firefox-sensitive PDF/whole-document PNG rendering. The rest of PDF content remains native text. SVG sizing is proportional and capped to one printable page. Markdown continues to use the fenced source.

Validation

  • bun run test: 248 files / 2283 tests passed
  • bun run typecheck: passed
  • bun run lint: passed with 0 errors (209 existing warnings)
  • bun run build:chrome: passed
  • bun run build:firefox: passed
  • git diff --check: passed

Thanks @hulyhulyhuly for the Safari report that exposed the separate locale precondition and helped keep #847 scoped correctly.

@codex review

@anontokyo-dev anontokyo-dev left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incremental review: changes required

The current head is d43a3498b5. All required CI checks are green, and the latest real-browser report is useful. However, one valid P2 and the final export evidence still block merge.

P2: the rasterization failure fallback never isolates the SVG

Codex finding:
#847 (comment)

The finding applies to the current d43a3498 code. In rasterizeMermaidSvgImages(), the catch path creates a plain <div>, appends a cloned <svg>, and calls isolateMermaidSvgImages(fallback). That helper only selects .gv-export-mermaid svg, so it finds nothing in this fallback container. image remains null and the original raw SVG stays in the print DOM, preserving the label/style-loss risk in exactly the recovery path.

Please wrap the clone in .gv-export-mermaid or make the isolation helper operate directly on the supplied SVG. Add a regression test that forces renderElementToImageBlob() to reject and verifies that:

  • the fallback replaces the original SVG with a gv-export-mermaid-image data image;
  • no raw SVG remains in the exported wrapper;
  • the wrapper/theme metadata and accessible label are preserved.

Review coverage race

The review summary says it reviewed 60e82c70f8, while the PR was rewritten to current head d43a3498b5; the inline P2 is attached to d43a3498 and is current. After the fix, wait for CI and trigger Codex once on the new exact head before requesting final review.

Final browser evidence is still incomplete

The latest Firefox/Chrome report is a good status update, but the PR body still describes an older state, says Firefox/Safari were not tested, and does not attach final-head Firefox output. The previous Safari run on 3cb226b was inconclusive because the source page never rendered Mermaid, so it is not a Safari export pass.

Conversation export is the explicit high-risk exception in this repository: the final head must be manually verified in Chromium, Firefox, and Safari. Please update the PR body with the exact final SHA and contributor self-test results, then attach reproducible evidence for:

  • a source-page screenshot where Voyager has already rendered an explicitly mermaid-labelled block;
  • Markdown preserving the fenced Mermaid source;
  • PNG and PDF containing the rendered diagram with labels visible and no clipping;
  • affected existing non-Mermaid/code/list export behavior still working;
  • Chromium, Firefox, and Safari environment versions and build steps;
  • consistent light export from both light and dark Gemini source themes, with one light/dark comparison set sufficient for theme consistency.

Community testers may provide browser-specific evidence, but the contributor still needs to state which affected workflows they personally tested on the final head. Safari can use an explicitly labelled mermaid fence so the earlier Traditional Chinese generic-label precondition does not interfere.

Current status remains Changes requested.

Rasterize Mermaid export clones at 2x resolution so browser renderers retain foreignObject labels in PDF and PNG exports, while keeping non-diagram PDF content as native text and scaling each diagram to one printable page.

Follow-up for Nagi-ovo#847.

Fixes Nagi-ovo#840

Co-authored-by: Codex <codex@users.noreply.github.com>
@Nagi-ovo
Nagi-ovo force-pushed the fix/mermaid-export-rendering branch from d43a349 to fb9ceb8 Compare July 24, 2026 15:15
@Nagi-ovo

Copy link
Copy Markdown
Owner

Review follow-up — fb9ceb8e

The valid rasterization-fallback P2 is fixed:

  • the catch path now isolates the supplied SVG directly into a sanitized SVG data image;
  • no raw SVG remains in the export wrapper;
  • wrapper theme metadata and the SVG accessible label are preserved;
  • a regression test forces renderElementToImageBlob() to reject and verifies all four properties.

Local validation on this exact head:

  • bun run test: 248 files / 2284 tests passed
  • bun run typecheck: passed
  • bun run lint: 0 errors
  • Chrome and Firefox production builds: passed

The PR body is now updated to the exact final SHA and current implementation. It also corrects the Safari gate: .github/CONTRIBUTING.md lines 54-55 and 342-343 define Firefox as mandatory and Safari as optional. Existing content-script rules also disable Safari image export, so Safari PNG cannot be a mandatory acceptance path for this PR. The prior Safari evidence remains credited and documented as inconclusive because Mermaid had not rendered on the source page.

All previously addressed but unresolved inline threads have now been replied to and resolved.

@codex review

@Nagi-ovo

Copy link
Copy Markdown
Owner

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🎉

Reviewed commit: fb9ceb8e3c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@Nagi-ovo
Nagi-ovo dismissed stale reviews from anontokyo-dev, anontokyo-dev, and anontokyo-dev July 24, 2026 15:25

Obsolete after the nested-list traversal, shared Mermaid export styling, current-main rebase, and real Chrome/Firefox workflow verification on the final implementation.

@Nagi-ovo Nagi-ovo left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maintainer approval on fb9ceb8: the valid fallback defect is fixed with regression coverage; real Chrome and mandatory Firefox export workflows pass; Markdown/PDF/PNG behavior is verified; all local checks and GitHub Actions are green. Safari remains optional under CONTRIBUTING and image export is disabled there.

@Nagi-ovo
Nagi-ovo merged commit 103c367 into Nagi-ovo:main Jul 24, 2026
11 checks passed

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fb9ceb8e3c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +198 to +199
root
.querySelectorAll<SVGForeignObjectElement>(MERMAID_FOREIGN_OBJECT_SELECTOR)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Include the root wrapper when inlining Mermaid styles

When rasterizeMermaidSvgImages renders a diagram it passes the cloned .gv-export-mermaid wrapper itself to renderElementToImageBlob; querySelectorAll() does not match the root element, so this selector finds no foreignObject labels in that path. That means the computed color/fill fixes are skipped for the exact Mermaid-only rasterization path, and diagrams whose labels depend on those styles can still render with missing or incorrect text; include the root wrapper in the match or query from a parent.

Useful? React with 👍 / 👎.


const container = document.createElement('div');
container.innerHTML = trimmed;
isolateMermaidSvgImages(container);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Rasterize Mermaid before Deep Research print

For Deep Research PDF exports that include a .gv-export-mermaid diagram, this sanitization only converts the SVG to a data-SVG image and the print path never calls rasterizeMermaidSvgImages as the conversation PDF path now does. Since the failure mode being fixed is browser PDF output dropping/clipping SVG/foreignObject labels, Chrome/Firefox Deep Research report PDFs can still lose Mermaid text even though regular conversation PDFs are protected.

Useful? React with 👍 / 👎.

try {
const exportResult = await mermaid.render(
exportId,
`${normalizedCode}\n${MERMAID_LIGHT_THEME_DIRECTIVE}`,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Override Mermaid frontmatter for light exports

When the original Mermaid block already contains YAML frontmatter such as config: { theme: dark }, Mermaid gives frontmatter higher precedence than %%{init}%% directives, so appending this light-theme directive after the source does not actually force the export render to light. In dark Gemini, those diagrams are saved as the supposed light export but still use the source's dark theme, which can put dark Mermaid colors onto Voyager's white PDF/PNG surface; rewrite or temporarily override the higher-priority config when generating the light export.

Useful? React with 👍 / 👎.

@anontokyo-dev

Copy link
Copy Markdown
Collaborator

Post-merge verification

I rechecked the exact final head fb9ceb8e3c after the completed Codex review.

  • ✅ The rasterization-fallback P2 is fixed: the fallback now replaces the supplied SVG directly, removes the raw SVG, and preserves theme metadata and the accessible label.
  • ✅ The regression test covers the forced rasterization-failure path.
  • ✅ The exact-head Codex review reports no new findings.
  • ✅ Format, lint, typecheck, tests, i18n, native checks, and all browser builds are green.
  • ✅ The recorded Chrome and Firefox evidence covers the enabled rich-export behavior and the affected Markdown fallback.

Residual validation note

Final-head Safari export validation was not completed. The older 3cb226b report is correctly classified as inconclusive, because Mermaid had not rendered on the source page; it must not be recorded as a Safari pass. Safari image export is disabled, but any Safari-supported export surface should retain this as a follow-up validation gap.

PR #847 was merged as 103c367c0230b4b1c176066cf777a246c6c84d8f. The code review on the merged head is clean. 🎇

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] 导出产物中支持 mermaid 渲染

4 participants