Skip to main content

Markdown to Typst converter with multiple parser support

Project description

md2typst

A robust Markdown to Typst converter in Python with support for multiple Markdown parsers.

Features

  • Multiple parser backends: Choose from markdown-it-py, mistune, or marko at runtime
  • GFM support: Tables, strikethrough, and other GitHub Flavored Markdown extensions
  • Configurable: TOML configuration files and CLI options
  • Extensible: Plugin support for parser-specific extensions
  • Well-tested: Comprehensive test suite with TCK validation against CommonMark

Installation

# Using pip
pip install md2typst

# Using uv
uv add md2typst

Quick Start

Command Line

# Convert a file
md2typst input.md -o output.typ

# Convert from stdin
echo "# Hello **World**" | md2typst

# Use a specific parser
md2typst --parser mistune input.md

# Convert directly to PDF (requires typst CLI)
md2pdf input.md
md2pdf input.md -o custom-output.pdf

# List available parsers
md2typst --list-parsers

Python API

from md2typst import convert

# Simple conversion
typst = convert("# Hello **World**")
print(typst)
# Output: = Hello *World*

# With specific parser
typst = convert("~~deleted~~", parser="mistune")
print(typst)
# Output: #strike[deleted]

# With configuration
from md2typst import convert_with_config
from md2typst.config import Config

config = Config(parser="marko", plugins=["gfm"])
typst = convert_with_config("| A | B |\n|---|---|\n| 1 | 2 |", config)

Supported Parsers

Parser CLI Name Description
markdown-it-py markdown-it Default. CommonMark compliant, extensible
mistune mistune Fast, pure Python
marko marko CommonMark compliant, extensible

All parsers have GFM extensions (tables, strikethrough) enabled by default.

Markdown to Typst Mapping

Markdown Typst
# Heading = Heading
## Heading 2 == Heading 2
*italic* _italic_
**bold** *bold*
~~strike~~ #strike[strike]
`code` `code`
[text](url) #link("url")[text]
![alt](url) #image("url", alt: "alt")
> quote #block(...)[quote]
--- #line(length: 100%)
GFM tables #table(...)

Configuration

Configuration is loaded from multiple sources (highest priority first):

  1. CLI arguments (--parser, --plugin)
  2. Explicit config file (--config path/to/config.toml)
  3. .md2typst.toml in the current or parent directories
  4. [tool.md2typst] section in pyproject.toml

Example Configuration

.md2typst.toml:

parser = "mistune"
plugins = ["strikethrough", "table"]

[parser_options]
html = true

pyproject.toml:

[tool.md2typst]
parser = "markdown-it"
plugins = ["gfm"]

Front Matter

Markdown files can include YAML front matter for metadata, stylesheets, and raw Typst preamble:

---
title: My Document
author: Jane Doe
stylesheet: my-style
preamble: |
  #set text(lang: "fr", hyphenate: true)
  #set par(justify: true)
  #show heading.where(level: 1): it => { it; v(0.5em) }
---

# Hello World

This generates:

#let doc-title = "My Document"
#let doc-author = "Jane Doe"

#import "my-style.typ": *

#set text(lang: "fr", hyphenate: true)
#set par(justify: true)
#show heading.where(level: 1): it => { it; v(0.5em) }

= Hello World

The output ordering is: variables, stylesheet imports, preamble, then content.

CLI Options

md2typst --help

Options:
  -o, --output FILE      Output file (default: stdout)
  -p, --parser NAME      Parser to use (markdown-it, mistune, marko)
  --plugin NAME          Load parser plugin (can be repeated)
  --stylesheet NAME      Import Typst stylesheet (can be repeated)
  --config FILE          Path to configuration file
  --list-parsers         List available parsers
  --show-config          Show effective configuration

Development

Setup

git clone https://github.com/user/md2typst.git
cd md2typst
uv sync

Running Tests

# Run all tests (benchmarks skipped by default)
uv run pytest

# Run by category
uv run pytest -m unit          # Unit tests (fast)
uv run pytest -m integration   # Integration tests
uv run pytest -m e2e          # End-to-end tests
uv run pytest -m benchmark    # Benchmark tests

Test Structure

tests/
├── a_unit/           # Unit tests (AST, generator)
├── b_integration/    # Integration tests (parsers, config, TCK)
├── c_e2e/           # End-to-end tests
├── d_benchmark/     # Performance benchmarks
└── fixtures/        # Test fixtures (CommonMark, GFM)

Code Quality

# Type checking
uv run mypy src/

# Linting
uv run ruff check src/

# Formatting
uv run ruff format src/

Architecture

Markdown Input → Parser → AST → Generator → Typst Output

The converter uses a parser-agnostic AST (Abstract Syntax Tree) that decouples parsing from code generation. This allows:

  • Swapping parsers without changing the generator
  • Consistent output regardless of parser choice
  • Easy extension with new parsers

License

MIT

Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Add tests for new functionality
  4. Ensure all tests pass
  5. Submit a pull request

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

md2typst-0.2.3.tar.gz (21.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

md2typst-0.2.3-py3-none-any.whl (27.6 kB view details)

Uploaded Python 3

File details

Details for the file md2typst-0.2.3.tar.gz.

File metadata

  • Download URL: md2typst-0.2.3.tar.gz
  • Upload date:
  • Size: 21.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.1 {"installer":{"name":"uv","version":"0.11.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for md2typst-0.2.3.tar.gz
Algorithm Hash digest
SHA256 f4149c7c724f0d063434d54c4f76f25fb3afca1cf9ab43d31a2b348999a87506
MD5 33499262dd33fdf3a93cf8a4dcb1594b
BLAKE2b-256 92eb55ec61aa71d9c13e85074fe676ba7c4a1413ae13654953fb77e973dd4884

See more details on using hashes here.

File details

Details for the file md2typst-0.2.3-py3-none-any.whl.

File metadata

  • Download URL: md2typst-0.2.3-py3-none-any.whl
  • Upload date:
  • Size: 27.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.1 {"installer":{"name":"uv","version":"0.11.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for md2typst-0.2.3-py3-none-any.whl
Algorithm Hash digest
SHA256 3a47f7309a43ce620e26240cffb8d1a64500dbb18869dcb2f3c328561f0b8d5e
MD5 036cb89bf4c53b8274f55a257a4af8d8
BLAKE2b-256 e3e7cbb85959285c9752f11a542602679f2f9a17530a5c417c248d376753d162

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page