Markdown in SwiftUI, and some other interesting components.

Overview

RoomTime

RoomTime is a bundle of tools developed in my app RoomTime Lite. ( 😊 RoomTime Lite is still in development)

Features

Requirements

  • iOS 13 or newer
  • tvOS 13 or newer
  • watchOS 6 or newer
  • macOS is not supported currently

Installation

  1. In Xcode project, navigate to File -> Swift Packages -> Add Package Dependency... .
  2. Paste https://github.com/RainbowTalaxy/RoomTime and click Next.

Usage

TextArea

TextArea uses like SwiftUI's TextEditor, but not supports internal modifiers such as .font(_).

import RoomTime

struct TextAreaDemo: View {
    @State private var text = ""
    
    var body: some View {
        // 'extraHeight' is default by 0
        TextArea(text: $text, extraHeight: 100)
    }
}

AutoWrap

AutoWrap can let views wrap automaticly:

AutoWrap

import RoomTime

struct AutoWrapDemo: View {
    let data = [
        "RoomTime", "AutoWrap", "Talaxy", "FlowLayout", "cold",
        "Swift", "", "SwiftUI", "Overwatch", "Good Days", "back to school"
    ]
    
    var body: some View {
        // 'vSpacing' and 'hSpacing' are both default by 0
        AutoWrap(data, id: \.self, vSpacing: 5, hSpacing: 5) { text in
            Tag(text, bgcolor: RTColor.Tag.random())
        }
        .padding()
    }
}

Markdown

Markdown is a separate module, so you just need to import Markdown.

Here is a brief usage:

import Markdown

struct MarkdownDemo: View {
    let text: String
    
    var body: some View {
        ScrollView {
            Markdown(text: text) { element in
                ElementView(element: element)
            }
            .padding()
        }
    }
}

Syntax support

  • header 1-6
  • quote
  • order or unorder list
  • indent or block code
  • border
  • table
  • more in development ...

Here gives a text which shows what Markdown supports:

# Heading 1
## Heading 2
### Heading 3
#### Heading 4
##### Heading 5
###### Heading 6

# Quote

> An apple a day keeps the doctor away.

>> Quote can also be nested,
> > > and spaces are allowed bewteen arrows.

# List

* Unorder list

  - apple
  + banana
  * strawberry

* Order list

  1. eat
  2. code!
  3. sleep

  You can also specify the offset:
  
  11. eat
  2. code!
  3. sleep

# Code

Supports indent code:

    var name = "Talaxy"

and code block syntax:

```swift
// example
struct Demo: View {
    var body: some View {
        Text("Hello world!")
    }
}
```

# Border

---
* * *
__ ___ ____

# Table

Alignment syntax is supported.

| Property | Type   | Description |
|:-------- |:------:| -----------:|
| title    | String | The title of the news. |
| date     | Date   | The date of the news. |
| author   | String | The author ... |

Demo

Mechanism

Markdown uses Resolver to convert text into markdown elements.

Resolver has two rendering stages: "Spliting" and "Mapping" :

Markdown mechanism

In "Spliting" stage, Resolver splits text into Raws by SplitRule instances orderly.

Here is the definetion of the Raw:

public struct Raw: Hashable {
    public let lock: Bool
    public let text: String
    public let type: String?
}
  • lock tells the Resolver whether wants to be splited by further split rules.
  • text contains the text itself.
  • type is for "Mapping" stage.

In "Mapping" stage, Resolver converts Raws into Element objects.

Extend syntax supports

With Markdown rendering mechanism, you can customize your rendering rule.

For Example, if you want to highlight lines which starts with $ sign, you can implement by steps below:

First, create render rule:

import Markdown

class DollarLineElement: Element {
    let text: String
    
    init(text: String) {
        self.text = text
    }
}

fileprivate let dollerLineType = "doller"
fileprivate let dollerLineRegex = #"^\$ +.*$"#
fileprivate let dollerSignRegex = #"^\$ +(?=.*$)"#

class DollarSplitRule: SplitRule {
    override func split(from text: String) -> [Raw] {
        // You can use the inherited method `split(by:text:type:)`
        // to easily split text by Regex.
        return split(by: dollerLineRegex, text: text, type: dollerLineType)
    }
}

class DollarMapRule: MapRule {
    override func map(from raw: Raw, resolver: Resolver?) -> Element? {
        if raw.type == dollerLineType {
            // `replace(by:with:)` is a method nested in Markdown.
            // It helps you replace text by Regex easily.
            let line = raw.text.replace(by: dollerSignRegex, with: "")
            return DollarLineElement(text: line)
        } else {
            return nil
        }
    }
}

Second, define DollarLine view:

import SwiftUI

struct DollarLine: View {
    let element: DollarLineElement
    
    var body: some View {
        Text(element.text)
            .bold()
            .foregroundColor(Color.yellow)
    }
}

Third, configure the Resolver:

let splitRules: [SplitRule] = defaultSplitRules + [
    DollarSplitRule(priority: 4.5)
]

let mapRules: [MapRule] = defaultMapRules + [
    DollarMapRule(priority: 4.5)
]

let resolver = Resolver(splitRules: splitRules, mapRules: mapRules)

Finally, use Markdown and extend element view:

struct MarkdownDemo: View {
    let text: String = """
        # DollarLine
        $ Here is a dollar line.
        """
    
    var body: some View {
        ScrollView {
            Markdown(text: text, resolver: resolver) { element in
                // default view mapping
                ElementView(element: element)
                
                switch element {
                case let dollarLine as DollarLineElement:
                    DollarLine(element: dollarLine)
                default:
                    EmptyView()
                }
            }
            .padding()
        }
    }
}

Here is the output:

Dollar line

You might also like...
Swift markdown library
Swift markdown library

Markdown ![Swift version](https://img.shields.io/badge/Swift-2.1 | 2.2-blue.svg) ![GitHub license](https://img.shields.io/badge/license-LGPL v3-green.

A Pure Swift implementation of the markdown mark-up language

SmarkDown A pure Swift markdown implementation consistent with Gruber's 1.0.1 version. It is released under the BSD license so please feel free to use

`resultBuilder` support for `swift-markdown`

SwiftMarkdownBuilder resultBuilder support for swift-markdown. The default way to build Markdown in swift-markdown is to use varargs initializers, e.g

Leverages Apple's Swift-based Markdown parser to output NSAttributedString.
Leverages Apple's Swift-based Markdown parser to output NSAttributedString.

Markdownosaur 🦖 Markdownosaur uses Apple's excellent and relatively new Swift Markdown library to analyze a Markdown source, and then takes that anal

AttributedString Markdown initializer with custom styling
AttributedString Markdown initializer with custom styling

AttributedString Markdown initializer with custom styling AttributedString in iOS 15 and macOS 12 comes with a Markdown initializer. But: There is no

An Objective-C framework for converting Markdown to HTML.

MMMarkdown MMMarkdown is an Objective-C framework for converting Markdown to HTML. It is compatible with OS X 10.7+, iOS 8.0+, tvOS, and watchOS. Unli

Markdown syntax highlighter for iOS
Markdown syntax highlighter for iOS

Marklight Markdown syntax highlighter for iOS and macOS. Description Marklight is a drop in component to easily add realtime Markdown syntax highlight

Rich Markdown editing control for iOS
Rich Markdown editing control for iOS

MarkdownTextView Rich Markdown Editing for iOS MarkdownTextView is an iOS framework for adding rich Markdown editing capabilities. Support for Markdow

Blazing fast Markdown / CommonMark rendering in Swift, built upon cmark.
Blazing fast Markdown / CommonMark rendering in Swift, built upon cmark.

Down Blazing fast Markdown (CommonMark) rendering in Swift, built upon cmark v0.29.0. Is your app using it? Let us know! If you're looking for iwasrob

Releases(0.1.0)
Owner
Chen SiWei
Chen SiWei
Generate SwiftUI Text or AttributedString from markdown strings with custom style names.

iOS 15.0 / macOS 12.0 / tvOS 15.0 / watchOS 8.0 StyledMarkdown is a mini library that lets you define custom styles in code and use them in your local

null 19 Dec 7, 2022
Render Markdown text in SwiftUI, preview based on the Marked implementation

Markdown Render Markdown text in SwiftUI. It is a preview based on the Marked implementation. swiftui-markdown.mov Installation You can add MarkdownUI

小弟调调™ 26 Dec 20, 2022
Rendering Markdown text natively in SwiftUI.

MarkdownView MarkdownView is a Swift Package for rendering Markdown text natively in SwiftUI. Thanks to apple/swift-markdown, it can fully compliant w

LiYanan2004 13 Oct 22, 2022
Markdown parsing and rendering for iOS and OS X

CocoaMarkdown Markdown parsing and rendering for iOS and macOS CocoaMarkdown is a cross-platform framework for parsing and rendering Markdown, built o

Indragie Karunaratne 1.2k Dec 12, 2022
A simple and customizable Markdown Parser for Swift

MarkdownKit MarkdownKit is a customizable and extensible Markdown parser for iOS and macOS. It supports many of the standard Markdown elements through

Bruno Oliveira 687 Dec 18, 2022
MarkdownView is a WKWebView based UI element, and internally use bootstrap, highlight.js, markdown-it.

MarkdownView is a WKWebView based UI element, and internally use bootstrap, highlight.js, markdown-it.

Keita Oouchi 1.8k Dec 21, 2022
Converts Markdown files and strings into NSAttributedStrings with lots of customisation options.

SwiftyMarkdown 1.0 SwiftyMarkdown converts Markdown files and strings into NSAttributedStrings using sensible defaults and a Swift-style syntax. It us

Simon Fairbairn 1.5k Dec 22, 2022
Marky Mark is a parser written in Swift that converts markdown into native views.

Marky Mark is a parser written in Swift that converts markdown into native views. The way it looks it highly customizable and the supported markdown syntax is easy to extend.

M2mobi 287 Nov 29, 2022
Notepad - A fully themeable iOS markdown editor with live syntax highlighting.

Notepad is just like any other UITextView, but you need to use the convenience initializer in order to use the themes. To create a new theme, copy one of the existing themes and edit the JSON.

Rudd Fawcett 802 Dec 31, 2022
Markdown parser for iOS

Marky Mark Marky Mark is a parser written in Swift that converts markdown into native views. The way it looks it highly customizable and the supported

M2mobi 254 Jun 11, 2021