fix(export): render Mermaid diagrams in exports#847
Conversation
There was a problem hiding this comment.
💡 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".
There was a problem hiding this comment.
💡 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".
There was a problem hiding this comment.
💡 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".
|
@codex review |
There was a problem hiding this comment.
💡 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".
There was a problem hiding this comment.
💡 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".
|
@codex review |
|
Codex Review: Didn't find any major issues. Already looking forward to the next diff. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
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
left a comment
There was a problem hiding this comment.
结论
当前版本先 Request changes。自动初审提出的问题已经逐轮修复,CI 也全部通过,但仍有真实流程验证和一个可复现的导出回归需要补齐。
阻塞项
- 缺少真实 Gemini 导出链路的可视化验证。 PR 描述明确写了未进行 account-backed Gemini workflow,真实流程与约 15 分钟体验项也仍未勾选;现有两张图是构造的 Chromium fixture,不能证明已安装扩展后的真实会话能正确导出 PDF/PNG。请至少用真实 Gemini Mermaid 会话补充 PDF 与图片导出的截图或录屏,覆盖浅色/深色和一个较宽或较长的图,并确认 Markdown 仍保留 fenced Mermaid 源码。此改动也触及 Deep Research 导出,若本人无对应环境,请协调可复现环境的测试者给出证据。
- Firefox 目前只有 build,没有交互实测。 CONTRIBUTING 将 Firefox 标为必测;请补充实际加载扩展后的 Firefox 导出结果。Safari 可继续明确标注未测。
- 列表中的透明容器仍会破坏 Mermaid 文本导出。 详见行内评论;我已在当前提交复现
hasCode: false且源码、语言标签和 SVG 文本被压成普通文本。
可维护性
请本轮顺手收敛重复实现:Mermaid 的 sizing/dark-surface CSS 目前散落在 PDFPrintService、DeepResearchPDFPrintService 和 ImageExportService 的两个模板中,建议仿照现有 buildKatexExportStyles 提取共享 builder;processNodes 与 extractList 的 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 已通过
There was a problem hiding this comment.
💡 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".
anontokyo-dev
left a comment
There was a problem hiding this comment.
Follow-up 结论
最新提交已经修复了我复现的列表嵌套问题,也把 Mermaid 导出样式收敛到了共享 builder。真实 Chrome 深色导出证据已补;我本地复验了相关 6 个测试文件(131 tests)和 typecheck,当前 CI 也全部通过。
不过目前仍有以下准入项需要处理:
-
当前结果还不是完整的 light/dark mode 适配。 导出容器以及 PNG/PDF 渲染仍然强制白色背景和深色正文,只有 dark Mermaid wrapper 使用深色背景,因此截图里呈现的是“白色文档中嵌一块深色图”。可读性没问题,但主题并不一致。
- 如果产品决定继续保持现有白色导出,Mermaid 也应转换或重新渲染为 light theme;
- 如果要支持 dark export,背景、正文、链接、边框、代码块、附件和 Mermaid 应一起切换到同一主题。
请不要只给 Mermaid 单独铺深色底,并补充同一真实 Gemini 会话在 light/dark 两种主题下的 PNG/PDF 导出截图,证明整份产物的主题一致。
-
Firefox 仍只有 build,没有实际加载扩展并验证受影响导出流程。 按仓库
CONTRIBUTING.md,Firefox 是必测环境,请补充实际测试结果。 -
当前最新提交
359d503尚未有自动 Codex review;完成调整后请在最新 head 上重新触发一次。
因此这一轮仍然是 Request changes。前一轮的嵌套遍历与样式重复问题已经确认解决,不再阻塞。
|
@anontokyo-dev 在群里继续推进一下 |
|
收到,我会在群里按协作测试的方式继续推进。 我刚重新核对过:当前 head 仍是
协作测试者会在 PR 的测试矩阵中署名并链接证据;若测试过程沉淀了测试用例或文档,则由测试者提交对应 commit,形成可追踪的正式贡献。 |
There was a problem hiding this comment.
💡 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".
|
There was a problem hiding this comment.
💡 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".
当前状态确认我重新核对过了:head 仍是 目前没有新的测试证据落到 PR,正文也仍是旧的 dark-surface 描述和旧截图,所以 Request Changes 状态保持不变。下一步不需要继续改代码,而是完成下面的协作验证:
证据评论都落到这里后再 @ 我,我会核对 SHA、证据和影响范围并给最终结论。当前不要 merge。 |
There was a problem hiding this comment.
💡 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".
|
|
@codex review |
|
Codex Review: Didn't find any major issues. Keep them coming! Reviewed commit: ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
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". |
自动复审确认已确认自动 review 覆盖最新 head 现阶段只剩合并准入证据:
证据齐全前继续保持 Request Changes,暂不合并。 |
Steps of build
macOS: 15.7.7 Gemini conversation immediately before export
Mermaid Playgroundgraph LR
A[Step 1: Input Data] --> B[Step 2: Process & Validate]
B --> C[Step 3: Generate Output]
Export Markdown
Export PNG
Export PDF
|
|
@hulyhulyhuly Thank you. This is a useful Safari failure report bound to the correct Result
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.
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. 中文说明谢谢,这是一份绑定正确基线 请补一张“点击导出前”的 Gemini 会话页面截图,确认页面上当时是否已经显示 Mermaid 图。如果页面有图而导出变源码,就是 Safari 导出链路回归;如果页面本身还是源码,就要先排查 Safari 的渲染/内容脚本。现有文件和环境请保留,暂时不用把全部导出重跑一遍。 |
|
@hulyhulyhuly Thank you; the pre-export screenshot resolves the ambiguity. Revised diagnosisThis 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 RetestPlease 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: 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 把代码块标为 繁中通用标签缺失应另行记录为渲染问题,不应根据上一组截图直接修改导出代码。 |
Inline the computed Mermaid foreignObject label colors before html-to-image serializes the export. Preserve the visible color through Chromium's -webkit-text-fill-color handling and cover the scoped behavior with a regression test.
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>
3cb226b to
60e82c7
Compare
There was a problem hiding this comment.
💡 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".
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>
60e82c7 to
d43a349
Compare
Final verification update —
|
anontokyo-dev
left a comment
There was a problem hiding this comment.
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-imagedata 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>
d43a349 to
fb9ceb8
Compare
Review follow-up —
|
|
@codex review |
|
Codex Review: Didn't find any major issues. 🎉 Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
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". |
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
left a comment
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
💡 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".
| root | ||
| .querySelectorAll<SVGForeignObjectElement>(MERMAID_FOREIGN_OBJECT_SELECTOR) |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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}`, |
There was a problem hiding this comment.
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 👍 / 👎.
Post-merge verificationI rechecked the exact final head
Residual validation noteFinal-head Safari export validation was not completed. The older PR #847 was merged as |





AI-Assisted PR Policy / AI 辅助 PR 政策
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:
hasCodebehavior;Root causes:
.gv-mermaid-wrappercontains both a hiddencode-blockand the rendered SVG, and generic code-block extraction could win before traversal reached the diagram.foreignObjectlabels.Related work / 关联
main.Browser verification / 浏览器验证
Final implementation head:
fb9ceb8edist_firefoxon 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..github/CONTRIBUTING.md. The previous community run on3cb226bwas 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 finalfb9ceb8eis 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 passedbun run typecheck: passedbun run lint: passed with 0 errors (209 existing warnings)bun run build:chrome: passedbun run build:firefox: passedgit diff --check: passedAcknowledgements
Thanks @hulyhulyhuly for the Safari report that exposed the separate Traditional Chinese source-page precondition and helped keep this PR scoped correctly.
Checklist / 检查清单