Adds a typed view of the tree beside the untyped one. Additive: parseOrg and
OrgJSON are unchanged, so upgrading from v0.1.1 breaks nothing.
let doc = try OrgDocument(parsing: source)
for h in doc.allHeadlines where h.todo == "TODO" {
print(h.level, h.title.plainText, h.tags)
}
55 node types, 8 enums, 3 shared value types. Required schema fields are
non-optional, so a headline's level is Int rather than Int?. The eight
enumerated fields are real enums. A switch over OrgNode is exhaustive. A table
exposes a Flavour enum, so org-flavour rows and table.el text stop being a
folklore distinction.
Also: walk() depth-first including secondary strings, allHeadlines, allLinks,
plainText, subscript access on affiliated keywords, and a renderOrg overload
taking the typed tree.
GENERATED, NOT HAND-WRITTEN. harness/regen-ast.py reads
schema/org-node.schema.json and emits the whole file, so the schema stays the
single source of truth. swift test runs the drift check, so the generated Swift
cannot fall behind the schema.
What says the layer is complete and lossless: OrgJSON -> OrgNode -> OrgJSON is
asserted identical for all 1,432 stored trees, which are Emacs's own answers,
and a companion test asserts the corpus exercises every one of the 55 types.