• Stars
    star
    2,372
  • Rank 19,396 (Top 0.4 %)
  • Language
    Swift
  • License
    MIT License
  • Created about 4 years ago
  • Updated 4 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Display and customize Markdown text in SwiftUI

MarkdownUI

CI

Display and customize Markdown text in SwiftUI.

Overview

MarkdownUI is a powerful library for displaying and customizing Markdown text in SwiftUI. It is compatible with the GitHub Flavored Markdown Spec and can display images, headings, lists (including task lists), blockquotes, code blocks, tables, and thematic breaks, besides styled text and links.

MarkdownUI offers comprehensible theming features to customize how it displays Markdown text. You can use the built-in themes, create your own or override specific text and block styles.

Minimum requirements

You can use MarkdownUI on the following platforms:

  • macOS 12.0+
  • iOS 15.0+
  • tvOS 15.0+
  • watchOS 8.0+

Some features, like displaying tables or multi-image paragraphs, require macOS 13.0+, iOS 16.0+, tvOS 16.0+, and watchOS 9.0+.

Getting started

Creating a Markdown view

A Markdown view displays rich structured text using the Markdown syntax. It can display images, headings, lists (including task lists), blockquotes, code blocks, tables, and thematic breaks, besides styled text and links.

The simplest way of creating a Markdown view is to pass a Markdown string to the init(_:baseURL:imageBaseURL:) initializer.

let markdownString = """
  ## Try MarkdownUI

  **MarkdownUI** is a native Markdown renderer for SwiftUI
  compatible with the
  [GitHub Flavored Markdown Spec](https://github.github.com/gfm/).
  """

var body: some View {
  Markdown(markdownString)
}

A more convenient way to create a Markdown view is by using the init(baseURL:imageBaseURL:content:) initializer, which takes a Markdown content builder in which you can compose the view content, either by providing Markdown strings or by using an expressive domain-specific language.

var body: some View {
  Markdown {
    """
    ## Using a Markdown Content Builder
    Use Markdown strings or an expressive domain-specific language
    to build the content.
    """
    Heading(.level2) {
      "Try MarkdownUI"
    }
    Paragraph {
      Strong("MarkdownUI")
      " is a native Markdown renderer for SwiftUI"
      " compatible with the "
      InlineLink(
        "GitHub Flavored Markdown Spec",
        destination: URL(string: "https://github.github.com/gfm/")!
      )
      "."
    }
  }
}

You can also create a MarkdownContent value in your model layer and later create a Markdown view by passing the content value to the init(_:baseURL:imageBaseURL:) initializer. The MarkdownContent value pre-parses the Markdown string preventing the view from doing this step.

// Somewhere in the model layer
let content = MarkdownContent("You can try **CommonMark** [here](https://spec.commonmark.org/dingus/).")

// Later in the view layer
var body: some View {
  Markdown(self.model.content)
}

Styling Markdown

Markdown views use a basic default theme to display the contents. For more information, read about the basic theme.

Markdown {
  """
  You can quote text with a `>`.

  > Outside of a dog, a book is man's best friend. Inside of a
  > dog it's too dark to read.

  – Groucho Marx
  """
}

You can customize the appearance of Markdown content by applying different themes using the markdownTheme(_:) modifier. For example, you can apply one of the built-in themes, like gitHub, to either a Markdown view or a view hierarchy that contains Markdown views.

Markdown {
  """
  You can quote text with a `>`.

  > Outside of a dog, a book is man's best friend. Inside of a
  > dog it's too dark to read.

  – Groucho Marx
  """
}
.markdownTheme(.gitHub)

To override a specific text style from the current theme, use the markdownTextStyle(_:textStyle:) modifier. The following example shows how to override the code text style.

Markdown {
  """
  Use `git status` to list all new or modified files
  that haven't yet been committed.
  """
}
.markdownTextStyle(\.code) {
  FontFamilyVariant(.monospaced)
  FontSize(.em(0.85))
  ForegroundColor(.purple)
  BackgroundColor(.purple.opacity(0.25))
}

You can also use the markdownBlockStyle(_:body:) modifier to override a specific block style. For example, you can override only the blockquote block style, leaving other block styles untouched.

Markdown {
  """
  You can quote text with a `>`.

  > Outside of a dog, a book is man's best friend. Inside of a
  > dog it's too dark to read.

  – Groucho Marx
  """
}
.markdownBlockStyle(\.blockquote) { configuration in
  configuration.label
    .padding()
    .markdownTextStyle {
      FontCapsVariant(.lowercaseSmallCaps)
      FontWeight(.semibold)
      BackgroundColor(nil)
    }
    .overlay(alignment: .leading) {
      Rectangle()
        .fill(Color.teal)
        .frame(width: 4)
    }
    .background(Color.teal.opacity(0.5))
}

Another way to customize the appearance of Markdown content is to create your own theme. To create a theme, start by instantiating an empty Theme and chain together the different text and block styles in a single expression.

extension Theme {
  static let fancy = Theme()
    .code {
      FontFamilyVariant(.monospaced)
      FontSize(.em(0.85))
    }
    .link {
      ForegroundColor(.purple)
    }
    // More text styles...
    .paragraph { configuration in
      configuration.label
        .relativeLineSpacing(.em(0.25))
        .markdownMargin(top: 0, bottom: 16)
    }
    .listItem { configuration in
      configuration.label
        .markdownMargin(top: .em(0.25))
    }
    // More block styles...
}

Documentation

Swift Package Index kindly hosts the online documentation for all versions, available here:

Related content

You can learn more about MarkdownUI by referring to the following articles and third-party resources:

Demo

MarkdownUI comes with a few more tricks on the sleeve. You can explore the companion demo project and discover its complete set of capabilities.

Installation

Adding MarkdownUI to a Swift package

To use MarkdownUI in a Swift Package Manager project, add the following line to the dependencies in your Package.swift file:

.package(url: "https://github.com/gonzalezreal/swift-markdown-ui", from: "2.0.2")

Include "MarkdownUI" as a dependency for your executable target:

.target(name: "<target>", dependencies: [
  .product(name: "MarkdownUI", package: "swift-markdown-ui")
]),

Finally, add import MarkdownUI to your source code.

Adding MarkdownUI to an Xcode project

  1. From the File menu, select Add Packages…
  2. Enter https://github.com/gonzalezreal/swift-markdown-ui into the Search or Enter Package URL search field
  3. Link MarkdownUI to your application target

More Repositories

1

Groot

From JSON to Core Data and back.
Objective-C
534
star
2

Vertigo

Simple full screen image viewer with image zoom custom view controller transition
Objective-C
355
star
3

DefaultCodable

A convenient way to handle default values with Swift Codable types
Swift
353
star
4

AttributedText

Render attributed strings in SwiftUI
Swift
122
star
5

Markup

Lightweight markup text formatting in Swift
Swift
95
star
6

AdaptiveCardUI

Snippets of UI, authored in JSON and rendered with SwiftUI
Swift
92
star
7

ReadingList

An example on using the Mantle Modeling Framework with Overcoat AFNetworking extension.
Objective-C
86
star
8

NetworkImage

Asynchronous image loading in SwiftUI
Swift
69
star
9

SimpleNetworking

Scalable and composable API Clients using Swift Combine
Swift
51
star
10

IndeterminateTypesWithCodable

Indeterminate Types with Codable in Swift
Swift
37
star
11

Borders

Sample code for Consuming Web Services with Swift and ReactiveX
Swift
33
star
12

TGRDataSource

Convenience UITableView and UICollectionView data sources
Objective-C
24
star
13

SwiftCommonMark

Parse and create CommonMark documents in Swift.
C
23
star
14

Gig

A great Twitter API client for Objective-C
Objective-C
19
star
15

Reusable

iOS cell registration and reusing with generics and protocol extensions
Swift
13
star
16

DirectLine

Swift client library for Microsoft Bot Framework's Direct Line protocol
Swift
11
star
17

rxswift-gentle-introduction

A gentle introduction to RxSwift http://www.vsmobile.tech
7
star
18

swift-any-value

A Swift Codable type that serves as a placeholder for any JSON value
Swift
3
star
19

NSSpain2016

From Design to Code
3
star
20

TwitterTimeline

Source code for my article 'Implementando una timeline de Twitter con Core Data'
Objective-C
2
star