krz/orgstar

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

Sources/OrgCore/Semantic/FileSummary.swift

ab6ccec56eca03d0dadf2c9332aab10c4490eb62
orgstar/Sources/OrgCore/Semantic/FileSummary.swift history · blame · raw

32 lines · 1526 bytes

 1import Foundation
 2
 3/// What Spotlight shows and searches for a file: its keywords, tags and headings.
 4public struct FileSummary: Sendable, Equatable {
 5    public var title: String?
 6    public var author: String?
 7    public var description: String?
 8    /// `#+FILETAGS` and every heading's tags, in order, once each.
 9    public var tags: [String]
10    /// Heading titles, with TODO keywords, priorities and tags left out.
11    public var headings: [String]
12
13    public init(_ text: String) {
14        let tree = OrgParser.parse(text)
15        func keyword(_ name: String) -> String? {
16            let pattern = "^[ \\t]*#\\+" + name + ":[ \\t]*(.*?)[ \\t]*$"
17            guard let m = try! NSRegularExpression(pattern: pattern, options: [.anchorsMatchLines, .caseInsensitive])
18                .firstMatch(in: text, range: NSRange(location: 0, length: (text as NSString).length)) else { return nil }
19            let value = (text as NSString).substring(with: m.range(at: 1))
20            return value.isEmpty ? nil : value
21        }
22        title = keyword("TITLE")
23        author = keyword("AUTHOR")
24        description = keyword("DESCRIPTION")
25        let model = DocumentModel(tree: tree)
26        var tags = (keyword("FILETAGS") ?? "").split { $0 == ":" || $0 == " " }.map(String.init)
27        for heading in model.headings { tags += heading.localTags }
28        var seen = Set<String>()
29        self.tags = tags.filter { seen.insert($0).inserted }
30        headings = model.headings.map { Links.normalizedTitle($0.title) }
31    }
32}