File: Aside.swift

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 (194 lines) | stat: -rw-r--r-- 6,791 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
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
/*
 This source file is part of the Swift.org open source project

 Copyright (c) 2021-2023 Apple Inc. and the Swift project authors
 Licensed under Apache License v2.0 with Runtime Library Exception

 See https://swift.org/LICENSE.txt for license information
 See https://swift.org/CONTRIBUTORS.txt for Swift project authors
*/

import Foundation

/// An auxiliary aside element interpreted from a block quote.
///
/// Asides are written as a block quote starting with a special plain-text tag,
/// such as `note:` or `tip:`:
///
/// ```markdown
/// > Tip: This is a `tip` aside.
/// > It may have a presentation similar to a block quote, but with a
/// > different meaning, as it doesn't quote speech.
/// ```
public struct Aside {
    /// Describes the different kinds of aside.
    public struct Kind: RawRepresentable, CaseIterable, Equatable {
        /// A "note" aside.
        public static let note = Kind(rawValue: "Note")!
        
        /// A "tip" aside.
        public static let tip = Kind(rawValue: "Tip")!
        
        /// An "important" aside.
        public static let important = Kind(rawValue: "Important")!
        
        /// An "experiment" aside.
        public static let experiment = Kind(rawValue: "Experiment")!
        
        /// A "warning" aside.
        public static let warning = Kind(rawValue: "Warning")!
        
        /// An "attention" aside.
        public static let attention = Kind(rawValue: "Attention")!
        
        /// An "author" aside.
        public static let author = Kind(rawValue: "Author")!
        
        /// An "authors" aside.
        public static let authors = Kind(rawValue: "Authors")!
        
        /// A "bug" aside.
        public static let bug = Kind(rawValue: "Bug")!
        
        /// A "complexity" aside.
        public static let complexity = Kind(rawValue: "Complexity")!
        
        /// A "copyright" aside.
        public static let copyright = Kind(rawValue: "Copyright")!
        
        /// A "date" aside.
        public static let date = Kind(rawValue: "Date")!
        
        /// An "invariant" aside.
        public static let invariant = Kind(rawValue: "Invariant")!
        
        /// A "mutatingVariant" aside.
        public static let mutatingVariant = Kind(rawValue: "MutatingVariant")!
        
        /// A "nonMutatingVariant" aside.
        public static let nonMutatingVariant = Kind(rawValue: "NonMutatingVariant")!
        
        /// A "postcondition" aside.
        public static let postcondition = Kind(rawValue: "Postcondition")!
        
        /// A "precondition" aside.
        public static let precondition = Kind(rawValue: "Precondition")!
        
        /// A "remark" aside.
        public static let remark = Kind(rawValue: "Remark")!
        
        /// A "requires" aside.
        public static let requires = Kind(rawValue: "Requires")!
        
        /// A "since" aside.
        public static let since = Kind(rawValue: "Since")!
        
        /// A "todo" aside.
        public static let todo = Kind(rawValue: "ToDo")!
        
        /// A "version" aside.
        public static let version = Kind(rawValue: "Version")!
        
        /// A "throws" aside.
        public static let `throws` = Kind(rawValue: "Throws")!
        
        /// A "seeAlso" aside.
        public static let seeAlso = Kind(rawValue: "SeeAlso")!
        
        /// A collection of preconfigured aside kinds.
        public static var allCases: [Aside.Kind] {
            [
                note,
                tip,
                important,
                experiment,
                warning,
                attention,
                author,
                authors,
                bug,
                complexity,
                copyright,
                date,
                invariant,
                mutatingVariant,
                nonMutatingVariant,
                postcondition,
                precondition,
                remark,
                requires,
                since,
                todo,
                version,
                `throws`,
                seeAlso,
            ]
        }
        
        /// The heading text to use when rendering this kind of aside.
        ///
        /// For multi-word asides this value may differ from the aside's ``rawValue``.
        /// For example, the ``seeAlso`` aside's `rawValue` is `"SeeAlso"` but its
        /// `displayName` is `"See Also"`.
        /// Likewise, ``nonMutatingVariant``'s `rawValue` is
        /// `"NonMutatingVariant"` and its `displayName` is `"Non-Mutating Variant"`.
        ///
        /// For simpler, single-word asides like ``bug``, the `displayName` and `rawValue` will
        /// be the same.
        public var displayName: String {
            switch self {
            case .seeAlso:
                return "See Also"
            case .nonMutatingVariant:
                return "Non-Mutating Variant"
            case .mutatingVariant:
                return "Mutating Variant"
            case .todo:
                return "To Do"
            default:
                return rawValue
            }
        }
        
        /// The underlying raw string value.
        public var rawValue: String
        
        /// Creates an aside kind with the specified raw value.
        /// - Parameter rawValue: The string the aside displays as its title.
        public init?(rawValue: String) {
            self.rawValue = rawValue
        }
    }
    
    /// The kind of aside interpreted from the initial text of the ``BlockQuote``.
    public var kind: Kind

    /// The block elements of the aside taken from the ``BlockQuote``,
    /// excluding the initial text tag.
    public var content: [BlockMarkup]

    /// Create an aside from a block quote.
    public init(_ blockQuote: BlockQuote) {
        // Try to find an initial `tag:` text at the beginning.
        guard var initialText = blockQuote.child(through: [
            (0, Paragraph.self),
            (0, Text.self),
        ]) as? Text,
        let firstColonIndex = initialText.string.firstIndex(where: { $0 == ":" }) else {
            // Otherwise, default to a note aside.
            self.kind = .note
            self.content = Array(blockQuote.blockChildren)
            return
        }
        self.kind = Kind(rawValue: String(initialText.string[..<firstColonIndex]))!

        // Trim off the aside tag prefix.
        let trimmedText = initialText.string[initialText.string.index(after: firstColonIndex)...].drop {
            $0 == " " || $0 == "\t"
        }
        initialText.string = String(trimmedText)

        let newBlockQuote = initialText.parent!.parent! as! BlockQuote
        self.content = Array(newBlockQuote.blockChildren)
    }
}