Skip to content

Fix fenced code block rendering issues (#36, #37)#272

Merged
schuyler merged 3 commits intomainfrom
claude/review-preprocessor-fixes-kLbR4
Jan 13, 2026
Merged

Fix fenced code block rendering issues (#36, #37)#272
schuyler merged 3 commits intomainfrom
claude/review-preprocessor-fixes-kLbR4

Conversation

@schuyler
Copy link
Copy Markdown
Owner

@schuyler schuyler commented Jan 13, 2026

Summary

Extends the markdown preprocessor to fix two related code block rendering issues:

  1. Issue Fix code block formatting when no blank line before block #36: Code blocks immediately following text (without blank line) render incorrectly
  2. Issue Fix code block rendering with square brackets #37: Square brackets in code blocks (e.g., [key: string]: any) vanish

Both fixes are minimal preprocessor additions (~25 lines total) that work around Hoedown parser limitations.

Related Issues

Related to #36
Related to #37

Technical Details

Issue #36 Fix: Insert blank lines before fenced code blocks

// Pattern matches text immediately followed by fence
@"^(\\S.*)\\n(`{3,}|~{3,})(?=\\S|\\n.)"

The lookahead (?=\\S|\\n.) ensures only OPENING fences are matched (not closing fences).

Issue #37 Fix: Break reference link pattern inside code blocks

// Find fenced blocks and replace ]: with ]\u200B: (zero-width space)
content = [content stringByReplacingOccurrencesOfString:@"]: "
                                             withString:@"]\u200B: "];

This prevents Hoedown's is_ref() from matching TypeScript index signatures as reference links. The ZWSP is invisible in rendered output and only affects copy-paste from the preview pane (not the editor).

Known Limitations

  • Block elements inside existing code blocks may be incorrectly modified (documented edge case)
  • Blockquotes with code blocks may need special handling

Manual Testing Plan

  1. Create document with code block immediately after text (no blank line)
  2. Verify code renders as proper <pre><code> block
  3. Test TypeScript code with [key: string]: any patterns
  4. Verify square bracket lines are preserved in rendered output
  5. Test both ``` and ~~~ fence types

Files Changed

Extend the markdown preprocessor to insert blank lines before fenced
code blocks (``` and ~~~) when they immediately follow text. This
ensures Hoedown correctly recognizes them as code blocks.

The regex uses a lookahead to only match OPENING fences (followed by
content like a language specifier or code), not closing fences.

The fix also resolves square bracket rendering issues inside code
blocks, since properly recognized code blocks don't have their
contents parsed for link syntax.

Updates:
- MPRenderer.m: Add fenceRegex to MPPreprocessMarkdown
- regression-issue36.html: Update golden file to reflect correct output
- MPMarkdownRenderingTests.m: Update test comment to mark as FIXED

Related to #36
Related to #37
Mark issue #36 as FIXED in plan documents. Issue #37 remains a
hoedown limitation (is_ref() runs before code blocks are identified).

Related to #36
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Jan 13, 2026

Code Coverage Report

Current Coverage: 52.39%

Coverage Details (Summary)
Name                                                                                                                                   Coverage            
-------------------------------------------------------------------------------------------------------------------------------------- ------------------- 
MASPreferences.bundle                                                                                                                  0.00% (0/0)         
MacDown 3000.app                                                                                                                       58.62% (7524/12835) 
    /Users/runner/work/macdown3000/macdown3000/MacDown/Code/Extension/DOMNode+Text.m                                                   0.00% (0/94)        
        -[NSString(WordCount) numberOfWords]                                                                                           0.00% (0/11)        
        __36-[NSString(WordCount) numberOfWords]_block_invoke                                                                          0.00% (0/3)         
        -[NSString(WordCount) lengthWithoutNewlines]                                                                                   0.00% (0/11)        
        __44-[NSString(WordCount) lengthWithoutNewlines]_block_invoke                                                                  0.00% (0/3)         
        -[NSString(WordCount) lengthWithoutWhitespacesAndNewlines]                                                                     0.00% (0/11)        
        __58-[NSString(WordCount) lengthWithoutWhitespacesAndNewlines]_block_invoke                                                    0.00% (0/3)         
        MPGetChildrenNodetextCount                                                                                                     0.00% (0/6)         
        MPGetNodeTextCount                                                                                                             0.00% (0/38)        
        -[DOMNode(Text) textCount]                                                                                                     0.00% (0/8)         
    /Users/runner/work/macdown3000/macdown3000/MacDown/Code/Document/MPAsset.m                                                         93.69% (104/111)    
        -[MPAsset typeName]                                                                                                            100.00% (3/3)       
        -[MPAsset defaultTypeName]                                                                                                     100.00% (3/3)       
        +[MPAsset assetWithURL:andType:]                                                                                               100.00% (3/3)       
        -[MPAsset initWithURL:andType:]                                                                                                87.50% (7/8)        
        -[MPAsset init]                                                                                                                100.00% (3/3)       
        -[MPAsset templateForOption:]                                                                                                  0.00% (0/6)         
        -[MPAsset htmlForOption:]                                                                                                      100.00% (28/28)     
        -[MPStyleSheet defaultTypeName]                                                                                                100.00% (3/3)       
        +[MPStyleSheet CSSWithURL:]                                                                                                    100.00% (3/3)       
        -[MPStyleSheet templateForOption:]                                                                                             100.00% (20/20)     
        -[MPScript defaultTypeName]                                                                                                    100.00% (3/3)       
        +[MPScript javaScriptWithURL:]                                                                                                 100.00% (3/3)       
        -[MPScript templateForOption:]                                                                                                 100.00% (20/20)     
        -[MPEmbeddedScript htmlForOption:]                                                                                             100.00% (5/5)       
    /Users/runner/work/macdown3000/macdown3000/Dependency/peg-markdown-highlight/HGMarkdownHighlightingStyle.m                         87.69% (57/65)      
        +[HGMarkdownHighlightingStyle colorFromARGBColor:]                                                                             100.00% (6/6)       
        -[HGMarkdownHighlightingStyle initWithType:attributesToAdd:toRemove:fontTraitsToAdd:]                                          88.89% (8/9)        
        -[HGMarkdownHighlightingStyle initWithStyleAttributes:baseFont:]                                                               86.00% (43/50)      
    /Users/runner/work/macdown3000/macdown3000/MacDown/Code/Extension/hoedown_html_patch.c                                             86.47% (115/133)    
        hoedown_patch_reset_checkbox_index                                                                                             100.00% (3/3)       
        hoedown_patch_get_checkbox_index                                                                                               0.00% (0/3)         
        hoedown_patch_render_blockcode                                                                                                 89.09% (49/55)      
        hoedown_patch_render_listitem                                                                                                  100.00% (44/44)     
        hoedown_patch_render_toc_header                                                                                                67.86% (19/28)      
    /Users/runner/work/macdown3000/macdown3000/MacDown/Code/Application/MPMainController.m                                             42.91% (106/247)    
        MPOpenBundledFile                                                                                                              96.67% (29/30)      
        __MPOpenBundledFile_block_invoke                                                                                               85.71% (6/7)        
        treat                                                                                                                          20.00% (6/30)       
        __treat_block_invoke                                                                                                           0.00% (0/3)         
        -[MPMainController applicationDidFinishLaunching:]                                                                             100.00% (6/6)       
        -[MPMainController openUrlSchemeAppleEvent:withReplyEvent:]                                                                    0.00% (0/45)        
        __59-[MPMainController openUrlSchemeAppleEvent:withReplyEvent:]_block_invoke                                                   0.00% (0/7)         
        -[MPMainController valueForKey:fromQueryItems:]                                                                                0.00% (0/5)         
        -[MPMainController preferences]                                                                                                100.00% (3/3)       
        -[MPMainController preferencesWindowController]                                                                                0.00% (0/18)        

... (2440 more lines truncated)

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

@schuyler schuyler force-pushed the claude/review-preprocessor-fixes-kLbR4 branch from 2fb53a4 to d232249 Compare January 13, 2026 19:31
Extend the markdown preprocessor to insert zero-width space between
] and : inside fenced code blocks. This prevents Hoedown's is_ref()
from matching TypeScript index signatures and similar patterns as
reference link definitions.

The fix finds fenced code block content and replaces `]: ` with
`]\u200B: `. The ZWSP is invisible in rendered output and only
affects copy-paste from the preview pane (not the editor).

Related to #37
@schuyler schuyler force-pushed the claude/review-preprocessor-fixes-kLbR4 branch from d232249 to 59c0563 Compare January 13, 2026 19:43
@schuyler schuyler merged commit 8eb9375 into main Jan 13, 2026
10 checks passed
@schuyler schuyler deleted the claude/review-preprocessor-fixes-kLbR4 branch January 13, 2026 21:59
@schuyler schuyler changed the title Fix fenced code block rendering without preceding blank line Fix fenced code block rendering issues (#36, #37) Jan 13, 2026
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