Typst
Typed, deterministic construction of Typst source documents.
This package owns Typst syntax composition and escaping. It deliberately knows nothing about presentations, slides, themes, or Spectra. Typst’s own distinction between markup and code mode is a typed one here: a Doc is markup (document lines, prose, content), an Expr is a code-mode expression (calls, values, arrays), and the only bridges are code, which prefixes the # marker itself, and content, which wraps markup in a content block. A code expression cannot land in markup position without the marker, because the types refuse it.
Trust has exactly two doors: atom (markup) and sym (code) admit raw Typst spelling verbatim, and raw admits multi-line markup; everything else escapes by construction. Typst’s value vocabulary (lengths, colors, alignment, direction) comes typed from Typst.Value and is re-exported here, so an invalid length is unrepresentable and rendering owns every spelling.
fn main() =
println(document([
set_rule("page", [named("width", pt(300)), named("height", pt(200))]),
set_rule("text", [named("size", pt(12))]),
code(call("heading", [string("Hello from Prism")])),
text_line("Each line of this document came from a typed combinator."),
]))
#set page(width: 300pt, height: 200pt)
#set text(size: 12pt)
#heading("Hello from Prism")
Each line of this document came from a typed combinator.
Types
Doc
type Doc = TypstDoc(Pretty.Doc)
A markup-mode document fragment.
Expr
type Expr = TypstExpr(Pretty.Doc)
A code-mode expression.
Functions and Values
empty
empty : () -> Doc
An empty markup fragment.
atom
atom : (String) -> Doc
One atomic piece of trusted Typst markup. One of the two trust doors: the argument is emitted verbatim.
raw
raw : (String) -> Doc
Multi-line trusted Typst markup, preserving line boundaries; atom iterated over lines, so the same door.
text_line
text_line : (String) -> Doc
A line of prose with Typst’s markup control characters escaped, so any Prism string renders as itself.
render(96, text_line("prices in # and * stay literal"))
prices in \# and \* stay literal
lines
lines : (List(Doc)) -> Doc
Markup fragments separated by forced line breaks.
join
join : (Doc, List(Doc)) -> Doc
Markup fragments separated by sep.
concat_docs
concat_docs : (List(Doc)) -> Doc
Concatenate markup fragments without a separator.
sym
sym : (String) -> Expr
One atomic piece of trusted code-mode Typst: an identifier, an operator, a literal spelling the caller owns. The code-mode trust door.
none_expr
none_expr : () -> Expr
The none value, for optional argument positions.
boolean
boolean : (Bool) -> Expr
A boolean literal.
int
int : (Int) -> Expr
An integer literal.
string
string : (String) -> Expr
Escape arbitrary text as a Typst string value.
len
len : (Typst.Value.Length) -> Expr
A typed length value.
pt
pt : (Int) -> Expr
A point length.
em
em : (Int) -> Expr
An em length.
percent
percent : (Int) -> Expr
A percentage length.
fr
fr : (Int) -> Expr
A fraction length.
color
color : (Typst.Value.Color) -> Expr
A typed color value.
alignment
alignment : (Typst.Value.Alignment) -> Expr
A typed alignment value.
direction
direction : (Typst.Value.Dir) -> Expr
A typed direction value.
call
call : (String, List(Expr)) -> Expr
A Typst function call.
named
named : (String, Expr) -> Expr
A named argument.
tuple
tuple : (List(Expr)) -> Expr
A parenthesized tuple or argument group.
array
array : (List(Expr)) -> Expr
An array literal.
concat_exprs
concat_exprs : (List(Expr)) -> Expr
Concatenate code expressions without a separator.
sum
sum : (List(Expr)) -> Expr
Code expressions joined with Typst’s content +, the idiom for building one content value out of many.
suite
suite : (List(Expr)) -> Expr
A braced code suite with stable indentation.
if_suite
if_suite : (String, List(Expr)) -> Expr
An if condition { ... } code suite.
content_call
content_call : (String, List(Expr), Expr) -> Expr
A call carrying a trailing content block whose body is one code expression, name(args)[#(body)].
code
code : (Expr) -> Doc
Lift a code expression into markup position by prefixing Typst’s # marker. The only way an expression reaches a document line.
content
content : (Doc) -> Expr
Wrap markup as a code-mode content value, [...].
set_rule
set_rule : (String, List(Expr)) -> Doc
A top-level #set name(...) rule.
show_rule
show_rule : (String, Expr) -> Doc
A top-level #show selector: body rule.
let_function
let_function : (String, List(Expr), List(Expr)) -> Doc
A #let name(params) = { ... } function binding.
let_binding
let_binding : (String, Expr) -> Doc
A #let name = value binding.
render
render : (Int, Doc) -> String
Render markup at a selected source width. Rendering is pure: equal documents render equally, always.
render_expr
render_expr : (Int, Expr) -> String
Render one code expression at a selected source width, without the markup marker: the caller owns the position it lands in.
document
document : (List(Doc)) -> String
Render a conventional 96-column Typst source document.