Skip to content

Address issue #541: render Mermaid/Graphviz in HTML export when highlighting is off - #542

Open
schuyler wants to merge 2 commits into
mainfrom
claude/issue-541-export-diagram-highlighting-dj1tbk
Open

Address issue #541: render Mermaid/Graphviz in HTML export when highlighting is off#542
schuyler wants to merge 2 commits into
mainfrom
claude/issue-541-export-diagram-highlighting-dj1tbk

Conversation

@schuyler

Copy link
Copy Markdown
Owner

Summary

Fixes the export-path counterpart of #533/#540: Mermaid and Graphviz diagrams now render in exported HTML regardless of the export panel's "include highlighting" option.

In -[MPRenderer HTMLForExportWithStyles:highlighting:], diagram script inclusion was nested inside the if (withHighlighting) gate — which also drives scriptsOption. With highlighting off, the diagram scripts were never added and scriptsOption stayed MPAssetNone (so MPGetHTML would drop them anyway), leaving exported diagram fences as plain code blocks.

The fix:

  • Hoists the Mermaid and Graphviz blocks out of the withHighlighting gate into their own top-level if blocks.
  • Sets scriptsOption = MPAssetEmbedded when either diagram type is enabled, mirroring the existing MathJax branch (both parts are required — hoisting alone would leave the scripts silently dropped).
  • Leaves Prism gated on withHighlighting, and leaves stylesOption, the MathJax branch, and the live-preview -scripts path untouched.

Related Issue

Related to #541 (interpretation posted here: #541 (comment))

Judgment Calls

  • Two-part fix, not a pure hoist. The scriptsOption promotion is load-bearing: without it, hoisted scripts render to nothing (MPAssetNone → nil → skipped). Mirroring the MathJax branch keeps the idiom consistent.
  • Embedded, not linked. Export continues to embed diagram JS (MPAssetEmbedded), keeping exported files self-contained — consistent with existing export behavior and MathJax.
  • Test assertions use inlined content, never filenames. Because export embeds (inlines) JS, tests assert on mermaid.initialize( and function doGraphviz(engine) { (each verified to occur exactly once in the init scripts, absent from the bundled libraries). Filename substrings only work on the linked preview path.
  • Prism asserted absent only. The Prism submodule/embedded-content substring is version-fragile, so highlighting-off tests assert Prism absence (always safe); the highlighting-on regression is guarded by diagram-script no-duplication (occurrence count == 1) rather than a Prism-presence check.
  • Strengthened the two weak tests in place. testRendererWithMermaidEnabled/testRendererWithGraphvizEnabled previously asserted only XCTAssertNotNil — which is why the bug shipped undetected — so they were upgraded rather than left alongside new tests.

No open questions block this change.

Testing

Automated (headless, via the mock renderer delegate; the final test gate is the macOS CI run on this branch):

  • Strengthened testRendererWithMermaidEnabled / testRendererWithGraphvizEnabled: diagram scripts embedded and Prism absent with highlighting off.
  • New: both diagrams together (highlighting off); each diagram embedded exactly once when highlighting is on (double-inclusion guard); diagrams disabled → no scripts; withStyles:NO independence; MathJax coexistence.

Generated by Claude Code

Mermaid and Graphviz script inclusion in
-[MPRenderer HTMLForExportWithStyles:highlighting:] was nested inside the
`if (withHighlighting)` gate, which also drives scriptsOption. With
"include highlighting" off, the diagram scripts were never added and
scriptsOption stayed MPAssetNone, so exported HTML left mermaid/graphviz
fences as plain code blocks.

Hoist the Mermaid and Graphviz blocks out of the highlighting gate, each
promoting scriptsOption to MPAssetEmbedded (mirroring the MathJax branch).
Prism remains gated on highlighting. This is the export-path counterpart to
the preview-path fix from #540.

Strengthen the two weak export edge-case tests to assert the diagram scripts
are embedded (and Prism absent) with highlighting off, and add coverage for
both diagrams together, no double-inclusion when highlighting is on, disabled
diagrams, withStyles independence, and MathJax coexistence.

Related to #541
@github-actions

github-actions Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Report

Current Coverage: 64.62%

Coverage Details (Summary)
Name                                                                                                                                   Coverage             
-------------------------------------------------------------------------------------------------------------------------------------- -------------------- 
MASPreferences.bundle                                                                                                                  0.00% (0/0)          
MacDown 3000.app                                                                                                                       65.00% (9800/15077)  
    /Users/runner/work/macdown3000/macdown3000/MacDown/Code/Extension/NSColor+HTML.m                                                   94.05% (332/353)     
        +[NSColor(HTML) colorWithHexString:]                                                                                           94.12% (16/17)       
        +[NSColor(HTML) colorWithHTMLName:]                                                                                            89.13% (164/184)     
        __35+[NSColor(HTML) colorWithHTMLName:]_block_invoke                                                                           100.00% (152/152)    
    /Users/runner/work/macdown3000/macdown3000/MacDown/Code/Preferences/MPHtmlPreferencesViewController.m                              0.00% (0/113)        
        MPPrismDefaultThemeName                                                                                                        0.00% (0/2)          
        -[MPHtmlPreferencesViewController viewIdentifier]                                                                              0.00% (0/3)          
        -[MPHtmlPreferencesViewController toolbarItemImage]                                                                            0.00% (0/3)          
        -[MPHtmlPreferencesViewController toolbarItemLabel]                                                                            0.00% (0/2)          
        -[MPHtmlPreferencesViewController viewWillAppear]                                                                              0.00% (0/4)          
        -[MPHtmlPreferencesViewController changeStylesheet:]                                                                           0.00% (0/7)          
        -[MPHtmlPreferencesViewController changeHighlightingTheme:]                                                                    0.00% (0/7)          
        -[MPHtmlPreferencesViewController invokeStylesheetFunction:]                                                                   0.00% (0/23)         
        -[MPHtmlPreferencesViewController invokeHighlightingThemeFunction:]                                                            0.00% (0/33)         
        -[MPHtmlPreferencesViewController loadStylesheets]                                                                             0.00% (0/14)         
        -[MPHtmlPreferencesViewController loadHighlightingThemes]                                                                      0.00% (0/15)         
    /Users/runner/work/macdown3000/macdown3000/MacDown/Code/Utility/FileURLInlining.m                                                  26.60% (25/94)       
        +[FileURLInlining inlineFromIterable:]                                                                                         0.00% (0/11)         
        -[FileURLInlining initWithURL:]                                                                                                0.00% (0/6)          
        -[FileURLInlining init]                                                                                                        100.00% (3/3)        
        -[FileURLInlining inlineContent]                                                                                               0.00% (0/9)          
        -[FileURLInlining imageContent]                                                                                                0.00% (0/12)         
        +[FileURLInlining mimeTypeForFilePath:]                                                                                        100.00% (22/22)      
        -[FileURLInlining clippingContent]                                                                                             0.00% (0/4)          
        +[FileURLInlining isTextClippingAtPath:]                                                                                       0.00% (0/12)         
        +[FileURLInlining textContentFromClipping:]                                                                                    0.00% (0/15)         
    /Users/runner/work/macdown3000/macdown3000/Dependency/peg-markdown-highlight/HGMarkdownHighlightingStyle.m                         89.23% (58/65)       
        +[HGMarkdownHighlightingStyle colorFromARGBColor:]                                                                             100.00% (6/6)        
        -[HGMarkdownHighlightingStyle initWithType:attributesToAdd:toRemove:fontTraitsToAdd:]                                          88.89% (8/9)         
        -[HGMarkdownHighlightingStyle initWithStyleAttributes:baseFont:]                                                               88.00% (44/50)       
    /Users/runner/work/macdown3000/macdown3000/MacDown/Code/Utility/MPResourceWatcherSet.m                                             93.75% (90/96)       
        -[MPResourceWatcherSet init]                                                                                                   100.00% (6/6)        
        -[MPResourceWatcherSet dealloc]                                                                                                0.00% (0/3)          
        -[MPResourceWatcherSet watchedPaths]                                                                                           100.00% (3/3)        
        -[MPResourceWatcherSet updateWatchedPaths:]                                                                                    100.00% (16/16)      
        -[MPResourceWatcherSet addWatcherForPath:]                                                                                     100.00% (34/34)      
        __42-[MPResourceWatcherSet addWatcherForPath:]_block_invoke                                                                    100.00% (6/6)        
        __42-[MPResourceWatcherSet addWatcherForPath:]_block_invoke.5                                                                  93.33% (14/15)       
        __42-[MPResourceWatcherSet addWatcherForPath:]_block_invoke_2                                                                  75.00% (6/8)         
        -[MPResourceWatcherSet stopAll]                                                                                                100.00% (5/5)        
    /Users/runner/work/macdown3000/macdown3000/MacDown/Code/Document/MPPDFAnchorInjector.m                                             82.89% (155/187)     
        +[MPPDFAnchorLink linkWithText:slug:]                                                                                          100.00% (6/6)        
        +[MPPDFAnchorHeading headingWithSlug:text:]                                                                                    100.00% (6/6)        
        MPPDFAnchorStringIsBlank                                                                                                       100.00% (8/8)        
        +[MPPDFAnchorMatch matchWithPageIndex:bounds:height:]                                                                          100.00% (9/9)        
        MPPDFAnchorSnapshotMatches                                                                                                     64.00% (16/25)       

... (3575 more lines truncated)

📊 **Full coverage report available in workflow artifacts**

Self-review follow-ups for the HTML-export diagram fix:

- Assert the opposite diagram's script is absent in the single-diagram
  export tests, guarding against a transposed-array regression in the two
  structurally identical Mermaid/Graphviz blocks.
- Add a Graphviz withStyles:NO test mirroring the Mermaid one, confirming
  diagram scripts embed independently of the styles option.

Related to #541

Copy link
Copy Markdown
Owner Author

Maintainer notes (from self-review — observed, deliberately not addressed here)

  • Preview/export duplication (follow-up refactor): the "hoist Mermaid/Graphviz scripts out of the highlighting gate + promote scriptsOption" logic now exists in both -[MPRenderer scripts] (preview, fixed under Mermaid/Graphviz don't render when syntax highlighting is off #533/Render Mermaid/Graphviz when syntax highlighting is off (with test updates) #540) and -[MPRenderer HTMLForExportWithStyles:highlighting:] (export, this PR), with near-identical comments. That duplication is why the same bug had to be found and fixed twice. A shared private helper (e.g. appending diagram scripts + setting the asset option) would prevent future drift when another diagram type or toggle is added. Left out of this focused fix to keep the diff minimal and low-risk; worth a follow-up.

Generated by Claude Code

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.

2 participants