A Markdown to LaTeX converter.
Project description
TeXSmith
TeXSmith is a Python package and CLI tool to convert Markdown or HTML documents into LaTeX or Typst. It is designed to be extensible via templates and integrates with MkDocs for generating printable documents from documentation sites.
TL;DR
pip install texsmith
texsmith input.md input.bib -o build/ --build
Check the installed version with texsmith --version or in Python with texsmith.get_version().
Key features
- MkDocs-native Markdown – Ships with the same Material + pymdown extension stack you use in MkDocs, so tabs, callouts, annotations, tooltips, and data tables survive the conversion.
- Typed IR with multiple backends – Documents are lowered into a typed intermediate representation (
read(HTML) → IR → write(IR)), then emitted as LaTeX (default) or Typst (experimental) via--format. - Template-first runtime – Bundle multiple fragments into slots, merge front matter metadata, and emit LaTeX projects ready for Tectonic or latexmk with Docker-friendly manifests.
- CLI and Python parity – The Typer-powered CLI wraps the same ConversionService you can consume as a library, making CI/CD and notebooks behave like local runs.
- Actionable diagnostics – Structured emitters, verbosity switches, and
--debugtraces keep build issues debuggable even in automated pipelines. - Extensible converters – Override Markdown parsers, add reader lowerings (
@reads) and writer emitters (@writes), or ship diagram transformers (Mermaid, Draw.io, Svgbob) that plug directly into the pipeline.
Installation
# uv (recommended for isolated CLI installs)
uv tool install texsmith
# pip / pipx
pip install texsmith
pipx install texsmith
TeXSmith targets Python 3.10+ and expects a LaTeX distribution (TeX Live, MiKTeX, or MacTeX) when you pass --build with the default LaTeX backend. Optional converters such as Mermaid rely on Docker (minlag/mermaid-cli) unless you register custom handlers.
To build with the Typst backend (--format typst), install the embedded compiler as an extra:
pip install "texsmith[typst]"
# or with uv
uv tool install "texsmith[typst]"
This bundles the typst PyPI package, so no system binary is required. A system typst on PATH (Homebrew, cargo install typst-cli, or a GitHub release) is detected automatically as a fallback. See the Output backends guide for details.
Platform notes
- Linux – Install TeX Live (full) via your package manager or
install-tl. When running inside CI containers, cache~/.texliveYYso repeated latexmk runs stay fast—or use the default Tectonic engine to minimise setup. - macOS – Use MacTeX or
BasicTeXplus the tlmgr packages reported bytexsmith --template <name> --template-info. Homebrew’smactexcask works well when paired withuv. - Windows – TeXSmith runs via native Python or WSL. For PDF builds we recommend MiKTeX + PowerShell, or WSL2 with TeX Live and Docker Desktop (needed for Mermaid).
- Docker workflows – Run
texsmith --buildinside a TeX Live container, mounting your project plus the template directory. Copy tlmgr prerequisites from--template-infoso images compile without network access.
See the Getting Started guide for a step-by-step walkthrough, verification commands, and Python API examples.
Documentation
Browse the full documentation at yves-chevallier.github.io/texsmith for:
- Getting Started: installation, prerequisites, and API snippets.
- CLI Reference: every flag, including the template inspector.
- Markdown Directory: exhaustive syntax coverage.
- API Reference: ConversionService, TemplateSession, handlers, and plugins.
- Template Cookbook: practical recipes for slots, overrides, packaging, and testing.
- Release Notes & Compatibility: TeXSmith feature history plus template/TeX Live requirements.
Template catalog
Inspect templates by name or path to understand their slots, metadata attributes, TeX Live requirements, and declared assets:
texsmith --template article --template-info
# or inspect a local path
texsmith --template ./templates/nature --template-info
texsmith templates # view discovery order across built-ins/packages/local/home
Use this command before wiring slots or when you need to confirm which tlmgr packages to preinstall in CI.
Examples
The examples/ directory includes reproducible demos:
examples/paper– end-to-end render with bibliographies and latexmk (or Tectonic with--engine tectonic).examples/diagrams– Mermaid and Draw.io conversions.examples/markdown– exhaustive Markdown showcase with diagram/front-matter overrides.
Each example ships build instructions inside docs/examples/index.md.
Project layout
The source tree is organised around three top-level namespaces:
texsmith.corecontains the conversion pipeline, document models, diagnostics, and template helpers.texsmith.adaptershosts infrastructure integrations such as Markdown parsing, LaTeX rendering, Docker helpers, and transformer utilities.texsmith.uiprovides end-user interfaces, including the Typer-powered CLI.
Core architecture highlights
ConversionServiceencapsulates the orchestration that previously lived intexsmith.api.servicehelpers. Provide aConversionRequestand receive aConversionResponsewith rendered bundles and diagnostics.TemplateRenderernow owns slot aggregation and LaTeX assembly.TemplateSessionfocuses on session state, template options, and bibliography tracking.DocumentSlotsunify slot directives from front matter, CLI flags, and programmatic overrides. Every entry point now speaks the same data model.DiagnosticEmitterreplaces ad-hoc callback bags so warnings, errors, and structured events flow through a predictable interface (CLI usesCliEmitter; libraries can plug in their own).- Fragments use a
BaseFragment+ config dataclass model (fragment = YourFragment()export referenced byfragment.tomlentrypoints). No legacy factories remain.
Programmatic conversions with ConversionService
from pathlib import Path
from texsmith import ConversionRequest, ConversionService
service = ConversionService()
request = ConversionRequest(
documents=[Path("docs/index.html")],
bibliography_files=[Path("references.bib")],
template="article",
render_dir=Path("build"),
)
prepared = service.prepare_documents(request)
response = service.execute(request, prepared=prepared)
print("Main TeX:", response.render_result.main_tex_path)
print("Diagnostics:", [event.name for event in response.diagnostics])
If you only need a quick conversion, the high-level helpers (texsmith.Document, texsmith.convert_documents, texsmith.TemplateSession) continue to work, but they now reuse the same ConversionService plumbing as the CLI.
Refer to
UPGRADE.mdfor release notes and migration guidance from earlier builds.
Render pipeline
TeXSmith lowers every document into a typed intermediate representation (IR) and then emits a backend from that IR:
read(HTML) → IR (texsmith.ir) → write(IR) → LaTeX | Typst
- Readers (
texsmith.readers.html) turn BeautifulSoup nodes into backend-agnostic IR nodes. A reader lowering is a callable decorated with@reads(*tags, level, priority, name); it returns an IR node and never mutates the tree. - IR (
texsmith.ir) is a typed, backend-neutral node tree. Semantic hints travel asSpan/Divattributes rather than backend strings. - Writers emit a backend from the IR.
texsmith.writers.latex.LaTeXWriter(default) andtexsmith.writers.typst.TypstWriterregister emitters with@writes(NodeType), dispatched by node class along the MRO. A node without an emitter raises a clear, localised error naming the node and backend.
Select the backend with --format {latex,typst}. See the
Output backends guide and the
Readers & Writers reference for the decorators and a
runnable extension example.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file texsmith-0.4.0.tar.gz.
File metadata
- Download URL: texsmith-0.4.0.tar.gz
- Upload date:
- Size: 6.6 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
890750076d62c865ade48d306fa766d3847255bd5379236a8bb3bb7d557e210d
|
|
| MD5 |
67385b75f5463ac32ee0a4075b05a9ef
|
|
| BLAKE2b-256 |
42470c58da6e1d83f9d2b8644438a909a8e0385136ef4ce30bcb59fc9ea4d54b
|
Provenance
The following attestation bundles were made for texsmith-0.4.0.tar.gz:
Publisher:
ci.yml on yves-chevallier/texsmith
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
texsmith-0.4.0.tar.gz -
Subject digest:
890750076d62c865ade48d306fa766d3847255bd5379236a8bb3bb7d557e210d - Sigstore transparency entry: 1982755602
- Sigstore integration time:
-
Permalink:
yves-chevallier/texsmith@25835f268d8ab064d2bc3ad38bc328f541bc07ac -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/yves-chevallier
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@25835f268d8ab064d2bc3ad38bc328f541bc07ac -
Trigger Event:
push
-
Statement type:
File details
Details for the file texsmith-0.4.0-py3-none-any.whl.
File metadata
- Download URL: texsmith-0.4.0-py3-none-any.whl
- Upload date:
- Size: 627.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
df19b1d3efa1e6bf81deb6d3654f7764e5efc68d2f53b917fa5301fdc31ca1b7
|
|
| MD5 |
bccd466a6ee858ee2fe1442d2f7611d8
|
|
| BLAKE2b-256 |
76a5b45cdc3f48fd1cd9eb7bb88192794c6ec6ed82b950944df4a19868951c88
|
Provenance
The following attestation bundles were made for texsmith-0.4.0-py3-none-any.whl:
Publisher:
ci.yml on yves-chevallier/texsmith
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
texsmith-0.4.0-py3-none-any.whl -
Subject digest:
df19b1d3efa1e6bf81deb6d3654f7764e5efc68d2f53b917fa5301fdc31ca1b7 - Sigstore transparency entry: 1982755715
- Sigstore integration time:
-
Permalink:
yves-chevallier/texsmith@25835f268d8ab064d2bc3ad38bc328f541bc07ac -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/yves-chevallier
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@25835f268d8ab064d2bc3ad38bc328f541bc07ac -
Trigger Event:
push
-
Statement type: