The AST library (KAST)
Pandoc represents your document as an abstract syntax tree (AST) — the nodes a
Lua filter reads and rewrites. In Keystone, every handler and filter goes through
a single library to touch that tree: KAST (Keystone AST). Instead of calling
Pandoc's constructors, readers, writers, and walkers directly, code acquires KAST
with ks_require("ast") and works through it.
One seam, for two reasons:
- Consistency — constructing, serializing, and inspecting the AST happens one way across the whole engine, so handlers compose and behave predictably.
- Insulation — when Pandoc's API shifts, the change is absorbed in one place rather than scattered through every handler.
By convention, no file outside the AST library names Pandoc's constructors,
read / write, utils, or :walk directly — they all go through KAST. (The
host surface Pandoc hands the script — FORMAT, pandoc.path, system, yaml
— is exempt.) In the canonical project this rule is enforced; in your copy of the
engine it's simply the discipline the code follows, and matching it keeps your
changes consistent with everything around them.
The practical upshot when you work in the engine: you'll see KAST throughout the
handlers, and when you write or edit one, you reach for it the same way they do
rather than for pandoc.*. The existing handlers are the working examples.