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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
/// A block-level element of a Norg document, including its line position in
/// the source.
public enum NorgBlock: Equatable, Hashable, Sendable, Codable {
case heading(level: Int, status: TaskStatus?, content: [InlineSpan], line: Int)
case paragraph(content: [InlineSpan], line: Int)
case unorderedListItem(level: Int, status: TaskStatus?, content: [InlineSpan], line: Int)
case orderedListItem(level: Int, status: TaskStatus?, content: [InlineSpan], line: Int)
case quote(level: Int, status: TaskStatus?, content: [InlineSpan], line: Int)
case codeBlock(language: String?, code: String, line: Int)
case definition(title: [InlineSpan], status: TaskStatus?, body: [NorgBlock], line: Int)
case footnote(title: [InlineSpan], status: TaskStatus?, body: [NorgBlock], line: Int)
case tableCell(title: [InlineSpan], status: TaskStatus?, body: [NorgBlock], line: Int)
case rangedTag(name: [String], parameters: [String], content: String, line: Int)
case horizontalRule(line: Int)
case weakDelimiter(line: Int)
case strongDelimiter(line: Int)
/// The source line on which the block begins.
public var line: Int {
switch self {
case .heading(_, _, _, let line),
.paragraph(_, let line),
.unorderedListItem(_, _, _, let line),
.orderedListItem(_, _, _, let line),
.quote(_, _, _, let line),
.codeBlock(_, _, let line),
.definition(_, _, _, let line),
.footnote(_, _, _, let line),
.tableCell(_, _, _, let line),
.rangedTag(_, _, _, let line),
.horizontalRule(let line),
.weakDelimiter(let line),
.strongDelimiter(let line):
return line
}
}
/// The task status attached to the block, if any.
public var status: TaskStatus? {
switch self {
case .heading(_, let status, _, _),
.unorderedListItem(_, let status, _, _),
.orderedListItem(_, let status, _, _),
.quote(_, let status, _, _),
.definition(_, let status, _, _),
.footnote(_, let status, _, _),
.tableCell(_, let status, _, _):
return status
default:
return nil
}
}
/// The block's inline styled content (eg. text of a heading/paragraph, or
/// title of a definition/footnote).
public var content: [InlineSpan]? {
switch self {
case .heading(_, _, let content, _),
.paragraph(let content, _),
.unorderedListItem(_, _, let content, _),
.orderedListItem(_, _, let content, _),
.quote(_, _, let content, _):
return content
case .definition(let title, _, _, _),
.footnote(let title, _, _, _),
.tableCell(let title, _, _, _):
return title
default:
return nil
}
}
/// The nested blocks owned by a range-able block (definition, footnote, or
/// table cell).
public var body: [NorgBlock]? {
switch self {
case .definition(_, _, let body, _),
.footnote(_, _, let body, _),
.tableCell(_, _, let body, _):
return body
default:
return nil
}
}
/// Returns a copy of the block with its task status replaced (pass `nil` to
/// clear it). Blocks that cannot carry a status are returned unchanged.
public func settingStatus(_ status: TaskStatus?) -> NorgBlock {
switch self {
case .heading(let level, _, let content, let line):
return .heading(level: level, status: status, content: content, line: line)
case .unorderedListItem(let level, _, let content, let line):
return .unorderedListItem(level: level, status: status, content: content, line: line)
case .orderedListItem(let level, _, let content, let line):
return .orderedListItem(level: level, status: status, content: content, line: line)
case .quote(let level, _, let content, let line):
return .quote(level: level, status: status, content: content, line: line)
case .definition(let title, _, let body, let line):
return .definition(title: title, status: status, body: body, line: line)
case .footnote(let title, _, let body, let line):
return .footnote(title: title, status: status, body: body, line: line)
case .tableCell(let title, _, let body, let line):
return .tableCell(title: title, status: status, body: body, line: line)
default:
return self
}
}
}
|