File: Visitors-Walkers-and-Rewriters.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 (69 lines) | stat: -rw-r--r-- 2,240 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
# Visitors, Walkers, and Rewriters

Use `MarkupVisitor` to transform, walk, and rewrite markup trees.

## Markup Visitor

The core ``MarkupVisitor`` protocol provides the basis for transforming, walking, or rewriting a markup tree.

```swift
public protocol MarkupVisitor {
    associatedtype Result
}
```

Using its ``MarkupVisitor/Result`` type, you can transform a markup tree into anything: another markup tree, or perhaps a tree of XML or HTML elements. There are two included refinements of `MarkupVisitor` for common uses.

## Markup Walker

The first refinement of `MarkupVisitor`, ``MarkupWalker``, has an associated `Result` type of `Void`, so it's meant for summarizing or detecting aspects of a markup tree. If you wanted to append to a string as elements are visited, this might be a good tool for that.

```swift
import Markdown

/// Counts `Link`s in a `Document`.
struct LinkCounter: MarkupWalker {
    var count = 0
    mutating func visitLink(_ link: Link) {
        if link.destination == "https://swift.org" {
            count += 1
        }
        descendInto(link)
    }
}

let source = "There are [two](https://swift.org) links to <https://swift.org> here."
let document = Document(parsing: source)
print(document.debugDescription())
var linkCounter = LinkCounter()
linkCounter.visit(document)
print(linkCounter.count)
// 2
```

## Markup Rewriter

The second refinement, ``MarkupRewriter``, has an associated `Result` type of an optional ``Markup`` element, so it's meant to change or even remove elements from a markup tree. You can return `nil` to delete an element, or return another element to substitute in its place.

```swift
import Markdown

/// Delete all **strong** elements in a markup tree.
struct StrongDeleter: MarkupRewriter {
    mutating func visitStrong(_ strong: Strong) -> Markup? {
        return nil
    }
}

let source = "Now you see me, **now you don't**"
let document = Document(parsing: source)
var strongDeleter = StrongDeleter()
let newDocument = strongDeleter.visit(document)

print(newDocument!.debugDescription())
// Document
// └─ Paragraph
//    └─ Text "Now you see me, "
```

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