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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
import NorgKit
import SwiftUI
/// Typography and colours used when rendering a Norg document.
public struct NorgTheme: Sendable {
/// Font for a heading at the given (1-based) level.
public var heading: @Sendable (Int) -> Font
/// Base font for body text, list items and paragraphs.
public var body: Font
/// Font for the title of a definition, footnote or table cell.
public var termFont: Font
/// Foreground colour for `verbatim` inline spans.
public var verbatimColor: Color
/// Foreground colour for `spoiler` inline spans.
public var spoilerForeground: Color
/// Background colour for `spoiler` inline spans.
public var spoilerBackground: Color
/// Foreground colour applied to link spans.
public var linkColor: Color
/// Baseline offset applied to `superscript` spans.
public var superscriptOffset: CGFloat
/// Baseline offset applied to `subscript` spans.
public var subscriptOffset: CGFloat
/// Foreground colour for block quotes.
public var quoteColor: Color
/// Fill colour for the vertical bar drawn alongside a quote.
public var quoteBarColor: Color
/// Background fill for fenced code blocks and ranged tags.
public var codeBackground: AnyShapeStyle
/// Font for code block and ranged-tag contents.
public var codeFont: Font
/// Horizontal indentation applied per nesting level.
public var indentWidth: CGFloat
/// Tint for a task's status symbol.
public var statusTint: @Sendable (TaskStatus) -> Color
/// SF Symbol name for a task's status symbol.
public var statusSymbol: @Sendable (TaskStatus) -> String
/// Localized label for a task status, shown in the status menu and used
/// for accessibility. Defaults to ``TaskStatus/displayName``; override to
/// supply wording from your own string catalog.
public var statusLabel: @Sendable (TaskStatus) -> LocalizedStringResource
public init(
heading: @escaping @Sendable (Int) -> Font,
body: Font,
termFont: Font,
verbatimColor: Color,
spoilerForeground: Color,
spoilerBackground: Color,
linkColor: Color,
superscriptOffset: CGFloat,
subscriptOffset: CGFloat,
quoteColor: Color,
quoteBarColor: Color,
codeBackground: AnyShapeStyle,
codeFont: Font,
indentWidth: CGFloat,
statusTint: @escaping @Sendable (TaskStatus) -> Color,
statusSymbol: @escaping @Sendable (TaskStatus) -> String,
statusLabel: @escaping @Sendable (TaskStatus) -> LocalizedStringResource = { $0.displayName }
) {
self.heading = heading
self.body = body
self.termFont = termFont
self.verbatimColor = verbatimColor
self.spoilerForeground = spoilerForeground
self.spoilerBackground = spoilerBackground
self.linkColor = linkColor
self.superscriptOffset = superscriptOffset
self.subscriptOffset = subscriptOffset
self.quoteColor = quoteColor
self.quoteBarColor = quoteBarColor
self.codeBackground = codeBackground
self.codeFont = codeFont
self.indentWidth = indentWidth
self.statusTint = statusTint
self.statusSymbol = statusSymbol
self.statusLabel = statusLabel
}
/// The default theme.
public static let `default` = NorgTheme(
heading: { level in
switch level {
case 1: return .title.bold()
case 2: return .title2.bold()
case 3: return .title3.bold()
case 4: return .headline
case 5: return .subheadline.bold()
default: return .subheadline
}
},
body: .body,
termFont: .body.bold(),
verbatimColor: .pink,
spoilerForeground: .secondary,
spoilerBackground: .secondary.opacity(0.25),
linkColor: .accentColor,
superscriptOffset: 5,
subscriptOffset: -3,
quoteColor: .secondary,
quoteBarColor: .secondary,
codeBackground: AnyShapeStyle(.quaternary),
codeFont: .system(.callout, design: .monospaced),
indentWidth: 18,
statusTint: { status in
switch status {
case .done: return .green
case .urgent: return .red
case .pending: return .blue
default: return .secondary
}
},
statusSymbol: { status in
switch status {
case .undone: return "circle"
case .done: return "checkmark.circle.fill"
case .needsInput: return "questionmark.circle"
case .urgent: return "exclamationmark.circle"
case .recurring: return "repeat.circle"
case .pending: return "ellipsis.circle"
case .onHold: return "pause.circle"
case .cancelled: return "xmark.circle"
}
}
)
}
|