fix(print): keep PDF exports readable in all themes - #359
Merged
Conversation
Mermaid bakes the active theme into the SVG it emits — fills, strokes and label colours are attributes on the generated elements, not variables a stylesheet can retarget. Exporting from a dark preview therefore produced diagrams that were unreadable on paper. Recolouring that output from the print stylesheet means enumerating Mermaid's internal class names, and those differ per diagram type and drift between releases: flowchart nodes sit under `g.node`, sequence actors are a bare `rect.actor`, flowchart labels moved into `foreignObject` in v11 while sequence labels are still `<text>`. Missing one is worse than no override at all — the label rule lands, the fill rule does not, and dark text ends up painted on a near-black box. Measured against Mermaid 11.12 with the dark theme, the enumerated rules left sequence diagrams at a contrast ratio of 1.18 while flowcharts reached 4.94. Rebuild the diagrams instead. The screen render now keeps the diagram source on its container, and an export re-renders every diagram with Mermaid's light theme before printing, restoring the on-screen rendering afterwards. The same contrast measurement gives 4.75 for sequence diagrams and leaves flowcharts unchanged, and the result stays correct for diagram types this version has never seen. The theme decision is shared by the screen render and the restore so the two cannot drift. The 36 lines of diagram recolouring in the print stylesheet are removed; pagination rules for diagrams stay. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
PathGao
force-pushed
the
fix/pdf-export-print-layout
branch
from
August 2, 2026 16:56
0c5d810 to
665b476
Compare
PathGao
added a commit
that referenced
this pull request
Aug 2, 2026
**Find counted matches nobody could reach.** The tree walker skipped only script, style, noscript and its own marks, so text inside a collapsed heading section or a collapsed callout stayed in the DOM and stayed countable — but both containers clip to zero height, so pressing Enter onto one of those matches scrolled nowhere and looked like the search was broken. Matching a match now reveals its folds. That is what the surrounding software does: Chrome reveals `hidden=until-found` content and closed `<details>` when find lands inside them, VS Code unfolds a region when navigating to a match, and Obsidian tracks "counted but never revealed" as a bug. Simply skipping folded text would have been the other consistent answer, but it makes folding silently remove text from search with no signal, which nothing does. The reveal goes through the viewer's own fold toggle rather than stripping the class. `collapsedHeaders` is the source of truth and is re-applied on every render, so a class removed here would come back on the next one, and the table of contents would disagree in the meantime. Dispatching the toggle's own click keeps the DOM and that Set in step. **Find highlights were printed into exported PDFs.** Nothing cleared them before printing and `print-color-adjust: exact` made sure they came through. They cannot go in the print block's `display: none` list — the mark wraps document text, so hiding it would delete the matched words from the page — so its background, shadow and colour are neutralised instead and the text survives. Highlights authored with `==…==` are untouched. **Images and diagrams taller than a page were clipped rather than scaled.** `break-inside: avoid` was set with no height cap, and a replaced element cannot fragment, so anything taller than the printable area simply lost its bottom. They now cap at 9in with `object-fit: contain`, which fits both Letter (9.5in printable) and A4 (10.19in). Mermaid containers also need `overflow: visible` in print, because their on-screen `overflow-x: auto` computes `overflow-y` to `auto` and would re-crop what the cap just fixed. The size cap is purely additive to #359, whose mermaid work is a light-theme re-render carrying deliberately zero mermaid print CSS. No existing declaration in the print block was changed. Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This was referenced Aug 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
PDF exports now use a paper layout of their own instead of inheriting the active screen theme, and diagrams are rebuilt for paper rather than recoloured.
Paper layout. The page gets its margin from the document body so a dark theme no longer leaves the sheet edges unpainted. Wide tables distribute columns from their content and wrap at word boundaries, alerts and table rows stay inside page boundaries, and the properties panel no longer overflows.
Diagrams. Mermaid bakes the active theme into the SVG it emits — fills, strokes and label colours are attributes on the generated elements, not variables a stylesheet can retarget. My first attempt overrode them from the print stylesheet, which means enumerating Mermaid's internal class names; those differ per diagram type and drift between releases. Flowchart nodes sit under
g.node, sequence actors are a barerect.actor, and flowchart labels moved intoforeignObjectin v11 while sequence labels are still<text>.Missing one is worse than no override at all: the label rule lands, the fill rule does not, and dark text ends up painted on a near-black box. Measured against Mermaid 11.12 rendered with the dark theme, the enumerated rules left sequence diagrams at a contrast ratio of 1.18 — effectively invisible — while flowcharts reached 4.94.
So this now rebuilds the diagrams instead. The screen render keeps the diagram source on its container, and an export re-renders every diagram with Mermaid's light theme before printing, restoring the on-screen rendering afterwards. The same measurement gives 4.75 for sequence diagrams and leaves flowcharts unchanged. It stays correct for diagram types this version has never seen, and the 36 lines of recolouring CSS are gone. Diagram pagination rules stay.
Fixes #232
Validation
npm run check— 0 errors, 0 warningsnpm test— 161/161, including a newscripts/mermaidPrintTheme.test.tscovering the theme decision, source round-trip, re-render, idempotent restore, and the failure path where a diagram that cannot be rebuilt keeps its screen rendering