Output backends¶
TeXSmith lowers every document into a typed intermediate representation (IR) and then emits a backend from that IR:
tmark.parse → IR → TeXSmith passes → tmark.resolve → tmark.write → LaTeX | Typst
Both backends are fed by the same IR, the same passes and the same single resolve: only the last step differs. So you choose the output format with a single flag:
texsmith doc.md -tarticle --format latex # default
texsmith doc.md -tarticle --format typst
--format is case-insensitive and accepts latex (default) or typst.
LaTeX backend (default)¶
The LaTeX body comes from tmark's LaTeX writer; the LaTeX backend around it is
the full-featured path: it drives the template/fragment runtime, fonts and
script matching, glossary and index engines, asset transformers, and compiles
through a TeX engine
(Tectonic by default, or latexmk with --engine lualatex / --engine
xelatex). This is the backend assumed throughout most of this documentation.
Typst backend¶
Experimental
The Typst backend is experimental. The LaTeX backend remains the
default and the supported path; Typst covers a subset of it, leans on the
third-party mitex package for math (which can fail on some constructs —
see below), and approximates or drops a few constructs. Use it for new,
Typst-first documents and check the output; do not assume LaTeX-level
fidelity yet.
Typst is a modern, Rust-based typesetting system. The body
comes from tmark's Typst writer; texsmith.writers.typst wraps it into a
compilable .typ source. It is a lean, Typst-native path and intentionally
covers a subset of the LaTeX backend (see Scope).
# Emit a .typ file (no compiler required)
texsmith doc.md -tarticle --format typst --output build/
# Emit and compile to PDF
texsmith doc.md -tarticle --format typst --build --output build/
Without a template, the body is wrapped in a minimal standalone preamble. With the article or book template, the body is wrapped in the template's Typst scaffolding (title, authors, date, abstract, table of contents, sectioning, and a native Typst bibliography).
What the .typ carries¶
The Typst writer calls one #ts-… function per contract, the mirror of the
LaTeX contract macros — #ts-callout, #ts-code, #ts-keys, #ts-gls, and
so on. They are defined in src/texsmith/templates/common/texsmith.typ, and
that library is inlined ahead of the body in the generated .typ, so the
file compiles on its own with nothing beside it. A template redefines a
function after that point, the way a LaTeX template redefines a contract macro
after \VAR{extra_packages}. See Contract macros.
Math is the one external dependency, and it is pinned: a document with math opens with
#import "@preview/mitex:0.2.7": mi, mitex
which Typst fetches from its package registry on first compile. Nothing else is imported.
Typst output and LaTeX-only flags
--format typst cannot be combined with --template-info or
--template-scaffold: those inspect the LaTeX fragment/engine machinery,
which the Typst path does not use.
Installing a Typst compiler¶
Emitting the .typ source never needs a compiler; compilation does. Two paths
are supported, tried in this order:
The typst PyPI package embeds the Rust compiler, so nothing needs to be
on your PATH:
pip install "texsmith[typst]"
# or
uv pip install -e ".[typst]"
# or
uv tool install "texsmith[typst]"
Install typst on your PATH and TeXSmith detects it automatically as a
fallback:
brew install typst # Homebrew
cargo install typst-cli # Cargo
# or download a release from https://github.com/typst/typst/releases
Prefer the system binary for recent math
The compiler embedded in the typst PyPI package can lag behind recent
Typst releases. Math is rendered through the mitex package (a LaTeX-math
renderer for Typst); documents that rely on a recent mitex may fail
with the embedded compiler where an up-to-date system binary only emits a
warning. For math-heavy documents, prefer the system binary.
If no compiler is available, the .typ is still written and TeXSmith reports
that compilation was skipped, with an actionable install hint.
Scope and limitations¶
The Typst backend covers a real templated document (article and book) and the common Markdown/HTML constructs:
- Document structure, paragraphs, and headings.
- Inline emphasis (emphasis, strong, strikeout, underline, highlight, small caps, sub/superscript, quotes), inline code, and links.
- Code blocks, block quotes, bullet and ordered lists, definition lists, admonitions, horizontal rules.
- Images, figures, simple (GFM) tables, and rich (
yaml/data-ts) tables rebuilt as a native Typst#table. - Footnotes, TeX logos, keystrokes, progress bars.
- Math (rendered through the Typst
mitexpackage) and equation cross-references (#ref). - Native citations (
#cite) resolved against the bibliography collection the CLI builds (.bibfiles plus inline DOI), wired through#bibliography(...).
Approximated or dropped on the Typst path (no exact equivalent — the content is preserved as closely as possible rather than producing wrong output):
MarginNoterenders as a#footnote(thesidehint has no counterpart).- Index entries (
<abbr>markers) keep their visible text but emit no index marker — Typst has nomakeindexequivalent here. - Remote (
http(s)://,data:) or unresolved local images are dropped to keep the document compilable. - The
ts-*fragments themselves are LaTeX packages and are not loaded on the Typst path: the#ts-…functions oftexsmith.typstand in for them, so a fragment's LaTeX-only configuration (the glossary and index engines,ts-geometry,ts-frame) has no effect there. Acronyms still reach the backmatter, and the--numbering tmarkmode makes the two backends print the same numbers.
Any IR node that still has no Typst emitter raises an explicit, localised
TypstWriteError (naming the node and the backend) rather than emitting wrong
output. For anything beyond this subset, use the default LaTeX backend.