Skip to main content

Lightweight, themeable Markdown to Documents converter. CLI, SDK, and API.

Project description

mtd

CI coverage Python 3.14+ License: MIT Ruff

Yet another Markdown to Documents converter. Lightweight, themeable, and API-ready.

Convert your Markdown files to DOCX and ODT with custom themes. Available as a CLI tool, a Python SDK, or a local HTTP microservice for integration with other systems.

Features

  • 📄 Convert Markdown to .docx and .odt
  • 🎨 Built-in themes: default, academic, modern
  • 🧩 Custom themes via simple YAML files
  • 📝 YAML frontmatter support (title, author, date, theme)
  • 📑 Title page and headers/footers support
  • 🐍 Python SDK for programmatic use
  • 🌐 HTTP API microservice (FastAPI) for system integration
  • ⚡ Fast and lightweight with minimal dependencies
  • 🛠️ CLI, SDK, and API: three ways to use it

Install

# Global install with uv (recommended)
uv tool install yamtd

# With the HTTP API included
uv tool install "yamtd[api]"

# With pipx
pipx install yamtd

# With pip (in a venv)
pip install yamtd

Or install directly from the repository:

uv tool install git+https://github.com/Dxsk/mtd.git

Quick Start

# Scaffold a template in the current directory
mtd init
mtd init -o my-report.md

# Convert to DOCX
mtd convert README.md -o output.docx

# Convert to ODT with a theme
mtd convert README.md -o output.odt --theme modern

# List available themes
mtd themes list

# Show theme details
mtd themes show academic

SDK / Python API

Use mtd as a library in your own Python projects.

Install

pip install yamtd

Quick Convert

from mtd import convert

# Markdown file to DOCX
convert("report.md", "report.docx")

# With a theme
convert("report.md", "report.docx", theme="academic")

# To ODT
convert("report.md", "report.odt", theme="modern")

Convert from String

from mtd import convert_string

markdown = """
---
title: Generated Report
author: Automation Bot
---

# Results

Processing completed successfully.
"""

convert_string(markdown, "report.docx", theme="modern")

Granular API

For more control, use the lower-level functions:

from mtd import parse_markdown, write_docx, write_odt, load_theme, Document

# Parse
doc = parse_markdown("report.md")
print(doc.title)       # from frontmatter
print(doc.author)
print(doc.theme)       # "default" if not set
print(doc.titlepage)   # HTML of titlepage block, or None
print(doc.header)      # header config dict, or None
print(doc.footer)      # footer config dict, or None

# Load a theme
theme = load_theme("academic")
# Or from a custom YAML file
theme = load_theme("path/to/custom.yaml")

# Write to DOCX
write_docx(doc, "output.docx", theme)

# Write to ODT
write_odt(doc, "output.odt", theme)

Available Exports

Import Description
convert(input, output, theme=) High-level one-liner conversion
convert_string(markdown, output, theme=) Convert from a Markdown string
parse_markdown(source) Parse a file or string into a Document
Document Parsed document dataclass
write_docx(doc, output, theme=) Write Document to DOCX
write_odt(doc, output, theme=) Write Document to ODT
load_theme(name_or_path) Load a theme by name or YAML path
list_themes() List available built-in theme names
Theme Theme configuration dataclass

HTTP API

mtd includes an optional HTTP API server for integration with other systems.

WARNING: This API is for local/internal use only. It has no authentication or security hardening. Do not expose it to the public internet. Use it behind a reverse proxy or within a private network.

Install

pip install "yamtd[api]"

Start the Server

# Via CLI
mtd serve --port 8484

# Or directly with uvicorn
uvicorn mtd.server:app --host 127.0.0.1 --port 8484

API documentation is available at http://127.0.0.1:8484/docs (Swagger UI).

Endpoints

Method Endpoint Description
GET /health Health check
GET /themes List available themes
GET /themes/{name} Get theme details
POST /convert Convert Markdown text (form data)
POST /convert/file Convert uploaded Markdown file

Examples

# Health check
curl http://127.0.0.1:8484/health

# List themes
curl http://127.0.0.1:8484/themes

# Convert Markdown text to DOCX
curl -X POST http://127.0.0.1:8484/convert \
  -F "markdown=# Hello World" \
  -F "format=docx" \
  -F "theme=modern" \
  -o output.docx

# Upload and convert a file
curl -X POST http://127.0.0.1:8484/convert/file \
  -F "file=@document.md" \
  -F "format=odt" \
  -F "theme=academic" \
  -o output.odt

Themes

mtd ships with 3 built-in themes:

Theme Description
default Clean and neutral. Serif body, sans-serif headings
academic Formal. Times New Roman, wide margins, double spacing
modern Contemporary. Sans-serif, tight spacing, accent colors

Custom Themes

Create a YAML file with your style preferences:

name: my-theme
fonts:
  heading: Helvetica
  body: Georgia
  code: Fira Code
colors:
  primary: "#2563eb"
  text: "#1f2937"
page:
  margin_top: 2.5cm
  margin_bottom: 2.5cm

Then use it:

mtd convert doc.md -o doc.docx --theme path/to/my-theme.yaml

Markdown Template

mtd extends standard Markdown with special blocks for professional document generation. A complete example is available in examples/template.md.

Full Example

---
title: Quarterly Report
subtitle: Q1 2026 Results
author: Jane Doe
date: 2026-03-20
theme: modern
header:
  left: "Quarterly Report"
  center: ""
  right: "{page}"
footer:
  left: "Jane Doe"
  center: "Confidential"
  right: "{date}"
---

:::titlepage
# Quarterly Report
## Q1 2026 Results
Jane Doe
ACME Corp.
March 2026
:::

# Introduction

Document content starts here...

Frontmatter Reference

The YAML frontmatter block (---) at the top of the file controls all document metadata and layout.

Field Type Description
title string Document title (used in metadata and {title} placeholder)
subtitle string Subtitle (displayed on title page)
author string Author name (used in metadata and {author} placeholder)
date string Date in YYYY-MM-DD format (used in metadata and {date} placeholder)
theme string Theme name or path to a .yaml file. Defaults to default
header object Header configuration (see below)
footer object Footer configuration (see below)

Headers and Footers

Headers and footers support three zones: left, center, and right. Each zone is optional and defaults to empty.

header:
  left: "Company Name"
  center: ""
  right: "{page}"
footer:
  left: "{author}"
  center: "Draft"
  right: "{date}"

Available placeholders:

Placeholder Replaced with
{page} Current page number (auto-incremented)
{date} Document date from frontmatter
{title} Document title from frontmatter

Headers and footers are repeated on every page. When a title page is present, it is excluded from headers/footers automatically.

Title Page Block

The :::titlepage block generates a dedicated cover page before the document content. Content inside the block is centered with larger fonts.

:::titlepage
# Main Title
## Subtitle
Author Name
Organization
Date or other info
:::

Rendering rules:

Element Style
# Heading 1 Large bold title (28pt by default, configurable via theme)
## Heading 2 Subtitle (20pt by default)
Plain text Info lines (14pt by default, centered)

The title page sizes are controlled by the theme:

titlepage:
  title_size: 28      # H1 font size in pt
  subtitle_size: 20   # H2 font size in pt
  info_size: 14       # Plain text font size in pt
  spacing_top: "7cm"  # Top margin before content

A page break is automatically inserted after the title page.

Supported Markdown Elements

Element Syntax DOCX ODT
Headings # H1 to ###### H6 Yes Yes
Bold **text** Yes Yes
Italic *text* Yes Yes
Bold + Italic ***text*** Yes Yes
Strikethrough ~~text~~ Yes Yes
Inline code `code` Yes Yes
Fenced code blocks ```python Yes Yes
Unordered lists - item (supports nesting) Yes Yes
Ordered lists 1. item (supports nesting) Yes Yes
Task lists - [x] done / - [ ] todo Yes Yes
Tables Pipe syntax with alignment Yes Yes
Blockquotes > quote (supports nesting) Yes Yes
Links [text](url) Yes Yes
Images ![alt](url) Yes Yes
Horizontal rules --- Yes Yes
Footnotes text[^1] / [^1]: note Yes Yes

Minimal Template

The simplest valid mtd document:

---
title: My Document
author: Your Name
---

# Hello World

This is a paragraph.

Full-Featured Template

For a production-ready template with all features, copy the example:

cp examples/template.md my-document.md
mtd convert my-document.md -o my-document.docx --theme academic

License

MIT

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

yamtd-0.1.1.tar.gz (100.0 kB view details)

Uploaded Source

Built Distribution

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

yamtd-0.1.1-py3-none-any.whl (30.6 kB view details)

Uploaded Python 3

File details

Details for the file yamtd-0.1.1.tar.gz.

File metadata

  • Download URL: yamtd-0.1.1.tar.gz
  • Upload date:
  • Size: 100.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.12 {"installer":{"name":"uv","version":"0.10.12","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for yamtd-0.1.1.tar.gz
Algorithm Hash digest
SHA256 519f722d9144dbf420b4645597ec0ee666689089b2df1f211fca964e229efe94
MD5 35415f41f5b03bce3882882cd7c07e19
BLAKE2b-256 9c2bfff2fa425aeae315731de3ecda15df4f415e6f5a3cf378a2f47ddb5477d7

See more details on using hashes here.

File details

Details for the file yamtd-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: yamtd-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 30.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.12 {"installer":{"name":"uv","version":"0.10.12","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for yamtd-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 4f9042f5194c1cb170f742317fe53cb5e1fd72ec3ce43a003b8706da2ac40b1b
MD5 08e6e109d7bcb4b24d5d72a923133eaa
BLAKE2b-256 6bd11bc0569cbb5bb9369c00508bb6d564061e4f6f0ed364242ec07ad9fec837

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