Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

27 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MDView

A SwiftUI application that implements a custom markdown renderer using Apple's swift-markdown parser. Built entirely with Claude Code as a learning exercise in pure SwiftUI development. Feel free to play, hack and use as you want.

Features

  • Custom Markdown Rendering: Built from scratch using Apple's swift-markdown parser
  • Pure SwiftUI: All components implemented using native SwiftUI views without UIKit/AppKit bridges
  • Grid-based Tables: Modern SwiftUI Grid API for proper table layout with dividers
  • Task Lists: Support for GitHub-style task lists with interactive checkboxes
  • Rich Text Support: Full inline markdown formatting (bold, italic, links, code, etc.)
  • Image Handling: Async loading with error states, placeholders, and size constraints
  • Cross-Platform: Works on iOS, macOS, and visionOS
  • Live Preview: Side-by-side editor and preview with smooth animated transitions
  • Debug View: Inspect the parsed markdown AST structure
  • Minimal Dependencies: Only uses essential Swift packages (no syntax highlighting libraries)

Components

Markdown Elements Supported

  • Headings (H1-H6) with proper sizing and semantic styling
  • Paragraphs with full inline markdown formatting support
  • Code Blocks with monospaced font, language labels, and adaptive colors
  • Blockquotes with visual left border and nested content support
  • Lists (ordered, unordered, and interactive task lists with checkboxes)
  • Tables with Grid layout, black dividers, and inline markdown in cells
  • Images with async loading, error handling, placeholders, and size constraints
  • Links rendered as tappable native Text views
  • Horizontal Rules (thematic breaks) supporting ---, ***, and ___ styles

Architecture

MDView/
├── App/
│   └── MDViewApp.swift          # Main app entry point
├── Views/
│   ├── ContentView.swift        # Main UI with editor/preview panels
│   ├── EditorView.swift         # Markdown text editor
│   ├── DebugStructView.swift    # Debug tree view
│   └── MarkdownView.swift       # Third-party comparison view
└── MDView/
    ├── SwiftMardownView.swift   # Main renderer that parses and delegates
    └── Blocks/
        ├── SMHeading.swift      # Heading renderer (H1-H6)
        ├── SMParagraph.swift    # Paragraph with inline markdown
        ├── SMCode.swift         # Code blocks with clean styling
        ├── SMBlockquote.swift   # Blockquote with border styling
        ├── SMUnorderedList.swift  # Bullet and task lists
        ├── SMOrderedList.swift   # Numbered lists
        ├── SMTable.swift         # Table rendering
        ├── SMImage.swift         # Async image loading
        └── SMThematicBreak.swift # Horizontal rules

Dependencies

Usage

Basic Implementation

import SwiftUI

struct ContentView: View {
    let markdown = """
    # Hello World

    This is a **bold** text with `inline code`.

    ```swift
    func greet() {
        print("Hello!")
    }
    ```
    """

    var body: some View {
        SwiftMardownView(markdown: markdown)
    }
}

Task Lists

- [ ] Unchecked task
- [x] Completed task
- Regular list item

Code Blocks

```swift
struct ContentView: View {
    var body: some View {
        Text("Hello, World!")
    }
}
```

```python
def fibonacci(n):
    if n <= 1:
        return n
    return fibonacci(n-1) + fibonacci(n-2)
```

Nested Lists

1. First item
   - Nested bullet
   - Another nested item
     1. Deep nested numbered
     2. Another deep item
2. Second item
   - [x] Nested task
   - [ ] Unchecked task

Tables

| Feature | Status | Priority |
|---------|--------|----------|
| **Bold text** | ✅ Complete | High |
| *Italic text* | ✅ Complete | Medium |
| `Code blocks` | 🔄 In Progress | High |
| [Links](https://example.com) | ⏳ Pending | Low |

| Name | Age | City |
|------|-----|------|
| John Doe | 30 | New York |
| Jane Smith | 25 | London |

Images

![Beautiful landscape](https://images.unsplash.com/photo-123456)

![Error handling demo](https://broken-url.com/image.jpg)

![Placeholder example](https://via.placeholder.com/300x200)

Horizontal Rules

Regular paragraph above.

---

New section with three hyphens.

***

Another section with three asterisks.

___

Final section with three underscores.

Building

Requirements

  • Xcode 15.0+
  • iOS 17.0+ / macOS 14.0+
  • Swift 5.9+

Instructions

  1. Clone the repository:

    git clone https://github.com/cguegan/MarkdownView.git
    cd MarkdownView
  2. Open in Xcode:

    open MDView.xcodeproj
  3. Build and run (⌘R)

Command Line Build

# Build
xcodebuild -project MDView.xcodeproj -scheme MDView -configuration Debug build

# Clean
xcodebuild -project MDView.xcodeproj clean

Features in Detail

View Modes

The app provides multiple viewing modes accessible via toolbar:

  • Editor/Debug Toggle: Switch between markdown editor and parsed AST structure view
  • Preview Toggle: Show/hide the rendered markdown preview with smooth animations
  • Split View: Resizable panels for comfortable editing and preview

Table Rendering

Tables are rendered using SwiftUI's Grid API:

  • Automatic column sizing and alignment
  • Black dividers between rows for clear separation
  • Bold header row with thick bottom border
  • Support for inline markdown formatting in cells
  • Proper handling of tables with uneven row lengths
  • Clean, native SwiftUI implementation

Image Handling

Enhanced image support with:

  • Asynchronous loading with Kingfisher
  • Error state with customizable placeholder
  • Loading progress indicators
  • Maximum size constraints (600x400)
  • Alt text display for accessibility
  • Graceful handling of broken URLs

Code Block Styling

Code blocks feature:

  • Monospaced font for readability
  • Language label display when specified
  • Adaptive background color for light/dark mode
  • Clean borders and padding
  • Text selection support
  • No external syntax highlighting dependencies

List Handling

Advanced list features:

  • Unlimited nesting depth
  • Mixed list types (ordered within unordered, etc.)
  • Interactive task list checkboxes with SF Symbols
  • Proper indentation and spacing
  • Support for complex content within list items
  • Trimmed whitespace for consistent rendering

Text Formatting

Native SwiftUI Text view with AttributedString handles:

  • Bold and italic text
  • Inline code spans with background
  • Tappable links
  • Combinations like bold italic
  • Proper markdown parsing in all contexts

Implementation Details

Pure SwiftUI Approach

All components are implemented using native SwiftUI views:

  • No UIViewRepresentable/NSViewRepresentable wrappers
  • No external syntax highlighting libraries (removed Highlightr)
  • Grid API for modern table layout
  • AttributedString for markdown text formatting
  • Minimal external dependencies
  • Clean, maintainable, idiomatic SwiftUI code

Performance Optimizations

  • Lazy loading of markdown blocks
  • Efficient text rendering with AttributedString
  • Minimal view rebuilds with proper state management
  • Trimmed whitespace to fix list spacing issues
  • Async image loading with caching via Kingfisher

Recent Improvements

  • Grid-based Tables: Migrated from HStack to Grid for proper table layout
  • Enhanced Images: Added error handling, placeholders, and size constraints
  • Horizontal Rules: Added support for thematic breaks (---, ***, ___)
  • Table Formatting: Fixed inline markdown support in table cells
  • Pure SwiftUI: Removed Highlightr dependency for simpler implementation

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is available under the MIT license. See the LICENSE file for more info.

Acknowledgments

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages