Update README (#183)
* Test header image * Update README * Update README
BIN
Examples/Demo/Screenshot.png
Normal file
|
After Width: | Height: | Size: 839 KiB |
BIN
Examples/Demo/Screenshot~dark.png
Normal file
|
After Width: | Height: | Size: 919 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 120 KiB |
|
Before Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 6.0 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 37 KiB |
476
README.md
@@ -4,330 +4,244 @@
|
||||
[](https://swiftpackageindex.com/gonzalezreal/MarkdownUI)
|
||||
[](https://twitter.com/gonzalezreal)
|
||||
|
||||
MarkdownUI is a Swift package for rendering Markdown in SwiftUI, fully compliant with the
|
||||
[CommonMark Spec](https://spec.commonmark.org/current/).
|
||||
Display and customize Markdown text in SwiftUI.
|
||||
|
||||
## Supported Platforms
|
||||
## Overview
|
||||
|
||||
You can use MarkdownUI in the following platforms:
|
||||
MarkdownUI is a powerful library for displaying and customizing Markdown text in SwiftUI. It is
|
||||
compatible with the [GitHub Flavored Markdown Spec](https://github.github.com/gfm/) and can
|
||||
display images, headings, lists (including task lists), blockquotes, code blocks, tables,
|
||||
and thematic breaks, besides styled text and links.
|
||||
|
||||
* macOS 11.0+
|
||||
* iOS 14.0+
|
||||
* tvOS 14.0+
|
||||
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.
|
||||
|
||||
## Usage
|
||||

|
||||

|
||||
|
||||
You can create a `Markdown` view by providing a Markdown-formatted string.
|
||||
## Minimum requirements
|
||||
|
||||
You can use MarkdownUI 2 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.
|
||||
|
||||
```swift
|
||||
Markdown("You can try **CommonMark** [here](https://spec.commonmark.org/dingus/).")
|
||||
```
|
||||
let markdownString = """
|
||||
## Try MarkdownUI
|
||||
|
||||

|
||||
|
||||
If you have already parsed a Markdown-formatted string into a CommonMark document, you can
|
||||
initialize a `Markdown` view with it.
|
||||
|
||||
```swift
|
||||
let document = try! Document(
|
||||
markdown: "You can try **CommonMark** [here](https://spec.commonmark.org/dingus/)."
|
||||
)
|
||||
**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(document)
|
||||
Markdown(markdownString)
|
||||
}
|
||||
```
|
||||
|
||||
Alternatively, you can use an embedded DSL to describe the content of a Markdown view.
|
||||

|
||||

|
||||
|
||||
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.
|
||||
|
||||
```swift
|
||||
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.
|
||||
|
||||
```swift
|
||||
// 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.
|
||||
|
||||
```swift
|
||||
Markdown {
|
||||
Heading(level: 2) {
|
||||
"Markdown lists"
|
||||
}
|
||||
OrderedList {
|
||||
"One"
|
||||
"Two"
|
||||
"Three"
|
||||
}
|
||||
BulletList {
|
||||
"Start a line with a star"
|
||||
"Profit!"
|
||||
}
|
||||
"""
|
||||
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
|
||||
"""
|
||||
}
|
||||
```
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
### Relative URLs
|
||||
|
||||
When creating a `Markdown` view, specify a base URL if you want to use relative URLs in your
|
||||
Markdown content.
|
||||
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.
|
||||
|
||||
```swift
|
||||
Markdown(
|
||||
#"""
|
||||
You can explore all the capabilities of this package in the
|
||||
[companion demo project](Examples/MarkdownUIDemo).
|
||||
"""#,
|
||||
baseURL: URL(string: "https://github.com/gonzalezreal/MarkdownUI/raw/main/")
|
||||
)
|
||||
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)
|
||||
```
|
||||
|
||||
### Loading asset images
|
||||

|
||||

|
||||
|
||||
A `Markdown` view downloads and presents the images it finds in the Markdown-formatted content. You
|
||||
may want to store some of your content's images locally. In that case, you can configure a
|
||||
`Markdown` view to load images with a given URL scheme from the asset catalog.
|
||||
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.
|
||||
|
||||
```swift
|
||||
Markdown(
|
||||
#"""
|
||||
The Markdown view loads this image from the network:
|
||||

|
||||
|
||||
And looks for this other image in the app's bundle:
|
||||

|
||||
"""#
|
||||
)
|
||||
.setImageHandler(.assetImage(), forURLScheme: "asset")
|
||||
```
|
||||
|
||||
### Customizing appearance
|
||||
|
||||
A `Markdown` view renders its content with a default base font, color, and measurements appropriate
|
||||
for the current environment. You can customize some or all of these values by passing a new
|
||||
`MarkdownStyle` to the `markdownStyle(_:)` view modifier.
|
||||
|
||||
```swift
|
||||
Markdown(
|
||||
#"""
|
||||
## Inline code
|
||||
If you have inline code blocks, wrap them in backticks: `var example = true`.
|
||||
"""#
|
||||
)
|
||||
.markdownStyle(
|
||||
MarkdownStyle(
|
||||
font: .system(.body, design: .serif),
|
||||
foregroundColor: .indigo,
|
||||
measurements: .init(
|
||||
codeFontScale: 0.8,
|
||||
headingSpacing: 0.3
|
||||
)
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||

|
||||
|
||||
### Customizing link handling
|
||||
|
||||
By default, a `Markdown` view opens the links in its content using the appropriate system service.
|
||||
However, you can provide a custom Markdown link handler using the `onOpenMarkdownLink` modifier.
|
||||
|
||||
```swift
|
||||
struct ContentView: View {
|
||||
@State private var url: URL? = nil
|
||||
@State private var showingAlert = false
|
||||
|
||||
var body: some View {
|
||||
Markdown(
|
||||
#"""
|
||||
**MarkdownUI** is a library for rendering Markdown in *SwiftUI*, fully compliant with the
|
||||
[CommonMark Spec](https://spec.commonmark.org/current/).
|
||||
"""#
|
||||
)
|
||||
.onOpenMarkdownLink { url in
|
||||
self.url = url
|
||||
self.showingAlert = true
|
||||
}
|
||||
.alert(isPresented: $showingAlert) {
|
||||
Alert(
|
||||
title: Text("Open Link"),
|
||||
message: Text(self.url?.absoluteString ?? "nil")
|
||||
)
|
||||
}
|
||||
}
|
||||
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))
|
||||
}
|
||||
```
|
||||
|
||||
Alternatively, if your deployment target is macOS 12.0+ or iOS 15.0+, you can customize Markdown
|
||||
link handling by setting the `openURL` environment value.
|
||||

|
||||

|
||||
|
||||
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.
|
||||
|
||||
```swift
|
||||
Markdown(
|
||||
#"""
|
||||
**MarkdownUI** is a library for rendering Markdown in *SwiftUI*, fully compliant with the
|
||||
[CommonMark Spec](https://spec.commonmark.org/current/).
|
||||
"""#
|
||||
)
|
||||
.environment(
|
||||
\.openURL,
|
||||
OpenURLAction { url in
|
||||
self.url = url
|
||||
self.showingAlert = true
|
||||
return .handled
|
||||
}
|
||||
)
|
||||
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))
|
||||
}
|
||||
```
|
||||
|
||||
## Supported Markdown Elements
|
||||
MarkdownUI uses the [CommonMark](https://github.com/commonmark/cmark) reference parser and
|
||||
fully complies with the [CommonMark Spec](https://spec.commonmark.org/current/).
|
||||

|
||||

|
||||
|
||||
Below you can see a few examples of how MarkdownUI renders Markdown elements. Additionally, you can
|
||||
explore the full MarkdownUI capabilities in the [companion demo project](Demo/).
|
||||
|
||||

|
||||
|
||||
### Block Quotes
|
||||
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.
|
||||
|
||||
```swift
|
||||
Markdown(
|
||||
#"""
|
||||
> “I sent the club a wire stating,
|
||||
> **PLEASE ACCEPT MY RESIGNATION. I DON'T
|
||||
> WANT TO BELONG TO ANY CLUB THAT WILL ACCEPT ME AS A MEMBER**.”
|
||||
|
||||
― Groucho Marx
|
||||
"""#
|
||||
)
|
||||
extension Theme {
|
||||
static let fancy = Theme()
|
||||
.code {
|
||||
FontFamilyVariant(.monospaced)
|
||||
FontSize(.em(0.85))
|
||||
}
|
||||
.link {
|
||||
ForegroundColor(.purple)
|
||||
}
|
||||
// More text styles...
|
||||
.paragraph { label in
|
||||
label
|
||||
.relativeLineSpacing(.em(0.25))
|
||||
.markdownMargin(top: 0, bottom: 16)
|
||||
}
|
||||
.listItem { label in
|
||||
label.markdownMargin(top: .em(0.25))
|
||||
}
|
||||
// More block styles...
|
||||
}
|
||||
```
|
||||
|
||||

|
||||
## Demo
|
||||
|
||||
### Lists
|
||||
MarkdownUI comes with a few more tricks on the sleeve. You can explore the
|
||||
[companion demo project](Examples/Demo/) and discover its complete set of capabilities.
|
||||
|
||||
```swift
|
||||
Markdown(
|
||||
#"""
|
||||
List of humorous units of measurement:
|
||||
|
||||
1. Systems
|
||||
- FFF units
|
||||
- Great Underground Empire (Zork)
|
||||
- Potrzebie
|
||||
1. Quantity
|
||||
- Sagan
|
||||
1. Length
|
||||
- Altuve
|
||||
- Attoparsec
|
||||
- Beard-second
|
||||
|
||||
― From Wikipedia, the free encyclopedia
|
||||
"""#
|
||||
)
|
||||
```
|
||||
|
||||

|
||||
|
||||
### Code Blocks
|
||||
|
||||
```swift
|
||||
Markdown(
|
||||
#"""
|
||||
Use a group to collect multiple views into a single instance,
|
||||
without affecting the layout of those views. After creating a
|
||||
group, any modifier you apply to the group affects all of that
|
||||
group’s members.
|
||||
|
||||
Group {
|
||||
Text("SwiftUI")
|
||||
Text("Combine")
|
||||
Text("Swift System")
|
||||
}
|
||||
.font(.headline)
|
||||
|
||||
― From Apple Developer Documentation
|
||||
"""#
|
||||
)
|
||||
```
|
||||
|
||||

|
||||
|
||||
### Headings
|
||||
|
||||
```swift
|
||||
Markdown(
|
||||
#"""
|
||||
# Heading 1
|
||||
A paragraph of text.
|
||||
## Heading 2
|
||||
A paragraph of text.
|
||||
### Heading 3
|
||||
A paragraph of text.
|
||||
#### Heading 4
|
||||
A paragraph of text.
|
||||
"""#
|
||||
)
|
||||
```
|
||||
|
||||

|
||||
|
||||
### Thematic Breaks
|
||||
|
||||
```swift
|
||||
Markdown(
|
||||
#"""
|
||||
# SwiftUI
|
||||
|
||||
Declare the user interface and behavior for your app
|
||||
on every platform.
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
SwiftUI provides views, controls, and layout structures
|
||||
for declaring your app’s user interface.
|
||||
|
||||
---
|
||||
|
||||
― From Apple Developer Documentation
|
||||
"""#
|
||||
)
|
||||
```
|
||||
|
||||

|
||||
|
||||
### Images
|
||||
|
||||
```swift
|
||||
Markdown(
|
||||
#"""
|
||||

|
||||
|
||||
― Photo by André Spieker
|
||||
"""#
|
||||
)
|
||||
```
|
||||
|
||||

|
||||
|
||||
### Emphasized Text
|
||||
|
||||
```swift
|
||||
Markdown(
|
||||
#"""
|
||||
It's very easy to make some words **bold** and other words *italic* with Markdown.
|
||||
|
||||
**Want to experiment with Markdown?** Play with the [reference CommonMark
|
||||
implementation](https://spec.commonmark.org/dingus/).
|
||||
"""#
|
||||
)
|
||||
```
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
## Installation
|
||||
You can add MarkdownUI to an Xcode project by adding it as a package dependency.
|
||||
You can add MarkdownUI to an Xcode project as a package dependency.
|
||||
|
||||
1. From the **File** menu, select **Add Packages…**
|
||||
1. Enter `https://github.com/gonzalezreal/MarkdownUI` into the *Search or Enter Package URL* search
|
||||
field
|
||||
1. Enter `https://github.com/gonzalezreal/swift-markdown-ui` into the
|
||||
*Search or Enter Package URL* search field
|
||||
1. Link **MarkdownUI** to your application target
|
||||
|
||||
## Other Libraries
|
||||
* [CommonMarkAttributedString](https://github.com/mattt/CommonMarkAttributedString)
|
||||
* [Down](https://github.com/johnxnguyen/Down)
|
||||
* [AttributedText](https://github.com/gonzalezreal/AttributedText)
|
||||
|
||||