krz/orgstar

A native macOS editor for org-mode files. editor org-mode swift

Sources/OrgCore/Semantic/SrcBlockInfo.swift

16086b4cf2caff5328774b2cd5ae3ffe1ab65ca4
orgstar/Sources/OrgCore/Semantic/SrcBlockInfo.swift history · blame · raw

36 lines · 1529 bytes

 1public struct SrcBlockInfo: Sendable, Equatable {
 2    public let range: Range<Int>
 3    public let heading: Int?
 4    /// From an attached `#+NAME:` line.
 5    public let name: String?
 6    public let language: String?
 7    /// Words like `-n` or `-r` between the language and the first header argument.
 8    public let switches: [String]
 9    /// The lines between the begin and end lines, unchanged.
10    public let body: String
11    /// Keys keep their leading colon (`:results`).
12    public let headerArguments: [String: Resolved<String>]
13}
14
15public enum HeaderArguments {
16    /// org-babel's global defaults.
17    public static let defaults: [String: String] = [
18        ":session": "none", ":results": "replace", ":exports": "code", ":cache": "no",
19        ":noweb": "no", ":hlines": "no", ":tangle": "no",
20    ]
21
22    /// `:key value :other value two` as ordered pairs. Keys are lower-cased and keep their colon;
23    /// words before the first key are dropped.
24    public static func parse(_ text: some StringProtocol) -> [(key: String, value: String)] {
25        var pairs: [(key: String, value: String)] = []
26        for word in text.split(whereSeparator: \.isWhitespace) {
27            if word.hasPrefix(":"), word.count > 1 {
28                pairs.append((word.lowercased(), ""))
29            } else if !pairs.isEmpty {
30                let current = pairs[pairs.count - 1].value
31                pairs[pairs.count - 1].value = current.isEmpty ? String(word) : current + " " + word
32            }
33        }
34        return pairs
35    }
36}