Skip to content

feat: add JSON and YAML viewing with syntax highlighting - #45

Open
lpichler wants to merge 1 commit into
Ladas:mainfrom
lpichler:feat/json-yaml-viewer
Open

feat: add JSON and YAML viewing with syntax highlighting#45
lpichler wants to merge 1 commit into
Ladas:mainfrom
lpichler:feat/json-yaml-viewer

Conversation

@lpichler

@lpichler lpichler commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add support for opening and viewing .json, .yaml, and .yml files with syntax highlighting
  • Files are rendered through the existing marked.js + highlight.js pipeline by wrapping content in Markdown code fences
  • Register both file types with macOS Launch Services so the app appears in Finder's "Open With" menu

How it works

When a JSON or YAML file is opened, HTMLRenderer.wrapForRendering(_:fileExtension:) wraps the raw text in a fenced code block (```json or ```yaml). The existing rendering pipeline handles the rest — marked.js parses the code fence, highlight.js applies syntax coloring, and DOMPurify sanitizes the output.

The wrapping only affects the rendering path. Raw operations (Copy Source, TOC parsing, review notes, file watching) continue to use the original file content unchanged.

Changes

File Change
MarkdownDocument.swift Add .json and .yaml to readableContentTypes
HTMLRenderer.swift Add wrapForRendering(_:fileExtension:) — wraps JSON/YAML in code fences, passes other types through
ContentView.swift Use markdownForRendering (delegates to HTMLRenderer) for the MarkdownWebView input
Info.plist Register JSON (public.json) and YAML (public.yaml) document types with LSHandlerRank: Alternate
DataFileRenderingTests.swift ~40 tests across 10 suites: content type registration, JSON/YAML wrapping, passthrough for other types, code fence structure, JS escaping integration, TOC interaction, and full render pipeline

Design decisions

  • LSHandlerRank: Alternate (not Owner) — the app offers to view JSON/YAML without claiming to be the default handler, unlike Markdown where it's the primary viewer
  • Code fence wrapping rather than a separate renderer — reuses the entire existing pipeline (marked.js → highlight.js → DOMPurify → WKWebView) with zero new JS or CSS
  • Case-insensitive extension matching — handles .JSON, .Yaml, .YML etc.
  • Extracted to HTMLRenderer — the wrapping logic is a public static method, making it testable independently of SwiftUI views

Test plan

  • Open a .json file → should render with syntax highlighting (colored keys, strings, numbers)
  • Open a .yaml file → should render with syntax highlighting
  • Open a .yml file → same as .yaml
  • Open a .md file → unchanged behavior, no code fence wrapping
  • Copy Source (Cmd+Shift+C) on a JSON file → copies raw JSON, not code-fenced version
  • Search (Cmd+F) works within JSON/YAML content
  • Zoom (Cmd+/Cmd-) works on JSON/YAML views
  • Right-click a .json in Finder → "Open With" shows Markdown Viewer
  • All existing tests still pass

🤖 Generated with Claude Code

Wrap JSON/YAML file content in Markdown code fences so the existing
marked.js + highlight.js pipeline renders them with syntax coloring.
Register both file types with macOS Launch Services as Alternate
viewers so the app appears in "Open With" without claiming ownership.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@lpichler
lpichler requested a review from Ladas as a code owner July 7, 2026 08:58
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.

1 participant