92 lines
3.8 KiB
Markdown
92 lines
3.8 KiB
Markdown
# Architecture
|
|
|
|
How scriptorium is put together. Every node, package and arrow below exists in the
|
|
source tree; nothing is aspirational.
|
|
|
|
## Overview
|
|
|
|
```mermaid
|
|
flowchart TD
|
|
Caller[consumer] --> Root[scriptorium, public surface]
|
|
Root --> Markdown[internal/markdown]
|
|
Root --> Math[internal/mathml]
|
|
Root --> Diagram[internal/diagram]
|
|
Markdown --> Block[parse.go, block parser]
|
|
Markdown --> Inline[inline.go, inline parser]
|
|
Markdown --> Writer[render.go, HTML writer]
|
|
Math --> Tok[token.go, tokeniser]
|
|
Math --> MParse[parse.go and command.go, parser]
|
|
Math --> Tables[symbols.go, symbol tables]
|
|
Math --> Env[environments.go, tables]
|
|
Math --> Macros[macros.go, expansion]
|
|
Diagram --> DParse[flowparse.go and sequence.go, parsers]
|
|
Diagram --> DLayout[flowlayout.go and sequence.go, layout]
|
|
Diagram --> DWrite[svg.go, writer]
|
|
```
|
|
|
|
The root package is the whole public surface: `Render` hands Markdown source to
|
|
the Markdown engine, `RenderMath` and `RenderMathDisplay` hand TeX source to the
|
|
mathematics engine, `RenderDiagram` hands Mermaid source to the diagram engine,
|
|
and `SupportedDiagram` states the Mermaid scope. Everything else lives in
|
|
internal packages and reaches no caller.
|
|
|
|
The Markdown engine parses line by line into the block tree CommonMark defines;
|
|
`RenderHTML` walks the tree, parses the inline content of every leaf against the
|
|
document's link reference definitions and footnotes, and writes HTML.
|
|
|
|
The mathematics engine tokenises the TeX source, expands the bounded macros,
|
|
parses atoms with their scripts into a MathML tree and writes one line of XML. A
|
|
construct the tables do not carry degrades in place to its verbatim source inside
|
|
an merror element.
|
|
|
|
The diagram engine parses statement lines into flowchart or sequence models,
|
|
lays the flowchart out by rank and barycentre and the sequence along its
|
|
lifelines, and writes SVG. A diagram type outside the two grammars is refused
|
|
with an error naming it.
|
|
|
|
## Packages
|
|
|
|
| Package | Responsibility |
|
|
|---|---|
|
|
| `scriptorium` (root) | the public surface: `Render`, `RenderMath`, `RenderMathDisplay`, `RenderDiagram`, `SupportedDiagram`. Owns nothing else. |
|
|
| `internal/markdown` | the Markdown engine: block parsing, inline parsing, HTML writing, and the scanners both phases share. Carries no state between calls. |
|
|
| `internal/mathml` | the mathematics engine: tokenising, macro expansion, symbol tables, environments, accents, styles and the XML writer. Carries no state between calls. |
|
|
| `internal/diagram` | the diagram engine: the flowchart and sequence parsers, both layouts and the SVG writer. Carries no state between calls. |
|
|
|
|
## Data flow
|
|
|
|
```mermaid
|
|
sequenceDiagram
|
|
participant Caller
|
|
participant S as scriptorium.RenderMath
|
|
participant T as mathml tokeniser
|
|
participant P as mathml parser
|
|
participant W as mathml writer
|
|
Caller->>S: TeX source
|
|
S->>T: source
|
|
T-->>P: tokens
|
|
P->>P: expand macros, parse atoms and scripts
|
|
P-->>W: MathML tree
|
|
W-->>Caller: one math element
|
|
```
|
|
|
|
Rendering cannot fail. A construct outside the grammar stays in the output as its
|
|
literal source rather than becoming an error, and nothing is sanitised on the way
|
|
out: that is the consumer's policy.
|
|
|
|
Parsing and rendering are pure: no globals, no caches, no goroutines. The same source
|
|
produces byte-identical output on every call, which the tests assert.
|
|
|
|
## State and lifetime
|
|
|
|
- Everything is per-call: the block tree, the delimiter stack, the reference map,
|
|
the token list, the macro table, the diagram models and the layouts die with
|
|
the render.
|
|
- All functions are safe for concurrent use, because nothing is shared.
|
|
|
|
## Dependencies
|
|
|
|
None beyond the standard library. That is a contract of the project, not an
|
|
accident: every engine writes its own scanners and tables where the standard
|
|
library has nothing to offer.
|