feat: render Markdown, mathematics and Mermaid diagrams server-side
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user