File: Parsing-Building-and-Modifying%20Markup-Trees.md

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (86 lines) | stat: -rw-r--r-- 2,733 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# Parsing, Building, and Modifying Markup Trees

Get started with Swift-Markdown's markup trees.

## Parsing

To create a new ``Document`` by parsing markdown content, use Document's ``Document/init(parsing:options:)`` initializer, supplying a `String` or `URL`:

```swift
import Markdown

let source = "This is a markup *document*."
let document = Document(parsing: source)
print(document.debugDescription())
// Document
// └─ Paragraph
//    ├─ Text "This is a markup "
//    ├─ Emphasis
//    │  └─ Text "document"
//    └─ Text "."
```

Parsing text is just one way to build a tree of ``Markup`` elements. You can also build them yourself declaratively.

## Building Markup Trees

You can build trees using initializers for the various element types provided.

```swift
import Markdown

let document = Document(
    Paragraph(
        Text("This is a "),
        Emphasis(
            Text("paragraph."))))
```

This would be equivalent to parsing `"This is a *paragraph.*"` but allows you to programmatically insert content from other data sources into individual elements.

## Modifying Markup Trees with Persistence

Swift Markdown uses a [persistent](https://en.wikipedia.org/wiki/Persistent_data_structure) tree for its backing storage, providing effectively immutable, copy-on-write value types that only copy the substructure necessary to create a unique root without affecting the previous version of the tree.

### Modifying Elements Directly

If you just need to make a quick change, you can modify an element anywhere in a tree, and Swift Markdown will create copies of substructure that cannot be shared.

```swift
import Markdown

let source = "This is *emphasized.*"
let document = Document(parsing: source)
print(document.debugDescription())
// Document
// └─ Paragraph
//    ├─ Text "This is "
//    └─ Emphasis
//       └─ Text "emphasized."

var text = document.child(through:
    0, // Paragraph
    1, // Emphasis
    0) as! Text // Text

text.string = "really emphasized!"
print(text.root.debugDescription())
// Document
// └─ Paragraph
//    ├─ Text "This is "
//    └─ Emphasis
//       └─ Text "really emphasized!"

// The original document is unchanged:

print(document.debugDescription())
// Document
// └─ Paragraph
//    ├─ Text "This is "
//    └─ Emphasis
//       └─ Text "emphasized."
```

If you find yourself needing to systematically change many parts of a tree, or even provide a complete transformation into something else, maybe the familiar [Visitor Pattern](https://en.wikipedia.org/wiki/Visitor_pattern) is what you want.

<!-- Copyright (c) 2021-2022 Apple Inc and the Swift Project authors. All Rights Reserved. -->