Skip to content

ChrisGVE/MarkdownExtendedView

Repository files navigation

MarkdownExtendedView

License: MIT GitHub Release CI Swift Package Index Swift Package Index Documentation iOS 16+ macOS 13+

A native SwiftUI Markdown renderer with LaTeX equation support.

Features

  • GitHub Flavored Markdown parsing via Apple's swift-markdown
  • LaTeX equations rendered natively via SwiftMath
    • Inline math: $...$
    • Display math: $$...$$
  • Task lists with checkbox rendering (- [ ] and - [x])
  • Clickable links with in-app browser (iOS) or system browser (macOS)
  • Remote image loading using AsyncImage
  • Syntax highlighting for 13+ languages
  • Mermaid diagrams via embedded WKWebView
  • Theming system with built-in themes (default, gitHub, compact)
  • Privacy-first - network features disabled by default
  • Cross-platform support for iOS 16+ and macOS 13+
  • Pure SwiftUI - minimal WebView usage (only for Mermaid)

Supported Markdown Elements

Element Syntax Status
Headings # H1 through ###### H6 Supported
Bold **text** or __text__ Supported
Italic *text* or _text_ Supported
Strikethrough ~~text~~ Supported
Inline code `code` Supported
Code blocks ``` fenced blocks Supported (with syntax highlighting)
Block quotes > quote Supported
Ordered lists 1. item Supported (with nesting)
Unordered lists - item or * item Supported (with nesting)
Task lists - [ ] and - [x] Supported
Tables GFM pipe tables Supported
Links [text](url) Opt-in (.links feature)
Images ![alt](url) Opt-in (.images feature)
Mermaid diagrams ```mermaid Opt-in (.mermaid feature)
Footnotes [^1] and [^1]: text Opt-in (.footnotes feature)
Thematic breaks --- or *** Supported
Inline LaTeX $E=mc^2$ Supported
Display LaTeX $$...$$ Supported

Installation

Add to your Package.swift:

dependencies: [
    .package(url: "https://github.com/ChrisGVE/MarkdownExtendedView.git", from: "1.0.0")
]

Then add the dependency to your target:

.target(
    name: "YourApp",
    dependencies: ["MarkdownExtendedView"]
)

Or in Xcode: File > Add Package Dependencies and enter the repository URL.

Usage

import SwiftUI
import MarkdownExtendedView

struct ContentView: View {
    var body: some View {
        ScrollView {
            MarkdownView("""
                # Hello World

                This is **bold** and this is *italic*.

                Inline equation: $E = mc^2$

                Display equation:
                $$\\int_0^\\infty e^{-x^2} dx = \\frac{\\sqrt{\\pi}}{2}$$
            """)
            .padding()
        }
    }
}

Theming

MarkdownView(content)
    .markdownTheme(.gitHub)

Available themes:

  • .default - Clean, readable defaults that adapt to system appearance
  • .gitHub - GitHub-style rendering with specific font sizes
  • .compact - Reduced spacing for dense content

Custom Theme

Create a custom theme by modifying any of the available properties:

var customTheme = MarkdownTheme.default

// Typography
customTheme.bodyFont = .system(size: 15)
customTheme.heading1Font = .system(size: 28, weight: .bold)
customTheme.codeFont = .system(.body, design: .monospaced)
customTheme.codeBlockFont = .system(.callout, design: .monospaced)

// Colors
customTheme.textColor = .primary
customTheme.secondaryTextColor = .secondary
customTheme.linkColor = .blue
customTheme.codeBackgroundColor = Color(white: 0.95)
customTheme.blockQuoteBorderColor = Color(white: 0.75)
customTheme.tableBorderColor = Color(white: 0.80)
customTheme.tableHeaderBackgroundColor = Color(white: 0.90)

// Spacing
customTheme.paragraphSpacing = 12
customTheme.listItemSpacing = 4
customTheme.indentation = 20
customTheme.codeBlockPadding = 12

MarkdownView(content)
    .markdownTheme(customTheme)

Feature Flags

For privacy, network-dependent features are disabled by default. Enable them using the .markdownFeatures() modifier:

// Enable clickable links
MarkdownView(content)
    .markdownFeatures(.links)

// Enable multiple features
MarkdownView(content)
    .markdownFeatures([.links, .images, .syntaxHighlighting])

// Enable all features
MarkdownView(content)
    .markdownFeatures(.all)

Available Features

Feature Description Network Required
.links Makes links tappable. iOS opens in SFSafariViewController, macOS opens in default browser Optional
.images Loads and displays remote images using AsyncImage Yes
.syntaxHighlighting Colorizes code blocks based on language No
.mermaid Renders Mermaid diagrams using WKWebView Yes (CDN)
.footnotes Processes footnote syntax ([^1]) and renders as superscripts No

Custom Link Handler

Override the default link behavior:

MarkdownView(content)
    .markdownFeatures(.links)
    .onLinkTap { url in
        // Custom handling
        print("Tapped: \(url)")
    }

Syntax Highlighting

When .syntaxHighlighting is enabled, code blocks with language specifiers are colorized:

MarkdownView("""
    ```swift
    let greeting = "Hello, World!"
    print(greeting)
    ```
""")
.markdownFeatures(.syntaxHighlighting)

Supported languages: Swift, Python, JavaScript, TypeScript, Java, C, C++, Go, Rust, Ruby, Kotlin, PHP, C#.

Customize syntax colors via the theme:

var theme = MarkdownTheme.default
theme.syntaxColors.keyword = .purple
theme.syntaxColors.string = .red
theme.syntaxColors.comment = .gray

Mermaid Diagrams

When .mermaid is enabled, Mermaid code blocks are rendered as diagrams:

MarkdownView("""
    ```mermaid
    graph TD
        A[Start] --> B{Decision}
        B -->|Yes| C[OK]
        B -->|No| D[Cancel]
    ```
""")
.markdownFeatures(.mermaid)

Supports all Mermaid diagram types: flowcharts, sequence diagrams, class diagrams, state diagrams, Gantt charts, pie charts, and more.

Footnotes

When .footnotes is enabled, footnote syntax is processed and rendered:

MarkdownView("""
    This statement needs a citation[^1].

    Another point with a named reference[^note].

    [^1]: Source: Academic Paper, 2024.
    [^note]: See the documentation for details.
""")
.markdownFeatures(.footnotes)

Footnotes are:

  • Rendered as superscript numbers (¹, ², ³...)
  • Collected and displayed in a footnotes section at the end
  • Numbered in order of first appearance in the text

LaTeX Support

MarkdownExtendedView uses ExtendedSwiftMath for native LaTeX rendering (a fork of SwiftMath with extended symbol coverage).

Inline Math

Use single dollar signs for inline equations that flow with text:

The famous equation $E = mc^2$ changed physics.

Display Math

Use double dollar signs for centered, block-level equations:

The quadratic formula:

$$x = \frac{-b \pm \sqrt{b^2-4ac}}{2a}$$

Supported LaTeX Commands

SwiftMath supports a wide range of LaTeX math commands including:

  • Greek letters: \alpha, \beta, \gamma, \pi, \theta, etc.
  • Operators: \sum, \prod, \int, \lim, \log, \sin, \cos, etc.
  • Fractions: \frac{a}{b}
  • Roots: \sqrt{x}, \sqrt[n]{x}
  • Superscripts/subscripts: x^2, x_i, x_i^2
  • Brackets: \left(, \right), \{, \}, \langle, \rangle
  • Matrices: \begin{matrix}...\end{matrix}, \begin{pmatrix}...\end{pmatrix}
  • Accents: \hat{x}, \bar{x}, \vec{x}, \dot{x}
  • Symbols: \infty, \partial, \nabla, \forall, \exists

For a complete reference, see the SwiftMath documentation.

Known Limitations

Current limitations that may be addressed in future versions:

Feature Status Notes
Reference-style links Not verified [text][ref] syntax may not work
HTML blocks Partial Raw HTML is not rendered
Definition lists Not supported Not part of GFM

Requirements

  • iOS 16.0+ / macOS 13.0+
  • Swift 5.9+
  • Xcode 15.0+

Dependencies

Contributing

Contributions are welcome! Please feel free to submit issues and pull requests.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

MIT License - Copyright (c) 2025 Christian C. Berclaz. See LICENSE for details.

About

Native SwiftUI Markdown renderer with LaTeX support using swift-markdown and SwiftMath

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors