Convert Markdown file to PDF using themes extracted directly from Word templates
Project description
mark-my-word
You have a Word template — the right fonts, colours, headers, footers. You have a Markdown file you want to print. mark-my-word connects the two: it reads your Word template and uses it to render your Markdown as a styled PDF.
Is this for me?
It's a good fit if:
- You have a
.docxor.dotxWord template with the styling you want - You want your PDFs to match that template without manual CSS work
- You're happy running a command-line tool
It's probably not for you if you need pixel-perfect fidelity to complex Word layouts (tables with merged cells, tracked changes, etc.) or if you need to render Word documents directly — this tool works with Markdown input.
Install
uv tool install mark-my-word
# or
pipx install mark-my-word
Requires Python 3.11+. WeasyPrint (the PDF engine) needs some system libraries — see the WeasyPrint docs if the install fails.
Basic usage
Step 1 — extract a theme from your Word template
mark-my-word extract my-template.dotx --output themes/my-theme/
This reads your Word template and writes a theme directory containing a stylesheet and HTML fragments for your headers and footers. You only need to do this once (or whenever your template changes).
Step 2 — render your Markdown to PDF
mark-my-word render document.md --theme themes/my-theme/
Output lands next to the input file by default (document.pdf). Use --output to put it somewhere else:
mark-my-word render document.md --theme themes/my-theme/ --output /tmp/document.pdf
Or do it in one step
If you don't want to keep the extracted theme around, you can pass the Word template directly:
mark-my-word render document.md --template my-template.dotx
The theme is extracted on the fly and discarded. Add --save-theme themes/my-theme/ if you change your mind later.
Document frontmatter
Headers and footers in your theme can include placeholders like {title} or {author}. Set them in your Markdown file's YAML frontmatter:
---
title: Q1 Report
author: Daniel
---
# Introduction
...
Pass extra values on the command line with --set:
mark-my-word render document.md --theme themes/my-theme/ --set version=draft
Skipping preamble
If you write notes in an app like NotePlan, there's often metadata at the top — tags, links, app-specific syntax — that you don't want in the PDF. Put <!--more--> on its own line to mark where your real content starts:
@project(Quarterly Review)
[[linked-note]]
<!--more-->
# Q1 Report
...
Everything before <!--more--> is ignored. Everything after renders normally. If <!--more--> appears inside a code block in the body, put a second one at the top of the document to act as the separator instead.
What gets extracted
From your Word template, mark-my-word extract pulls:
- Page margins
- Theme colours → CSS custom properties (
--color-body,--color-heading, etc.) - Base font and heading styles (H1–H6)
- Header and footer content, including tab-separated left/right layouts and page numbers
- Watermark images
The result is a plain directory you can inspect and edit. The stylesheet uses CSS custom properties throughout, so tweaking colours or fonts is a one-line change.
Theme directory layout
themes/my-theme/
style.css required
header.html header on all pages (or cont-header.html / first-header.html)
footer.html footer on all pages (or cont-footer.html / first-footer.html)
watermark.png optional full-page background image
If your Word template has a different header on the first page, extract writes first-header.html and cont-header.html separately. render handles both layouts automatically.
Options
mark-my-word render --help
mark-my-word extract --help
Links
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 mark_my_word-0.2.0.tar.gz.
File metadata
- Download URL: mark_my_word-0.2.0.tar.gz
- Upload date:
- Size: 168.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.15 {"installer":{"name":"uv","version":"0.11.15","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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
38194d29367c6a28c27c9da26d83ebaf297f22d51f07e792753f4d3af18dedc2
|
|
| MD5 |
194399ddba8a2c0a959527c508b8ae3c
|
|
| BLAKE2b-256 |
10e094d82756474de3f06c4da654a5b3407c20956fd914fd56d536cce291b6b7
|
File details
Details for the file mark_my_word-0.2.0-py3-none-any.whl.
File metadata
- Download URL: mark_my_word-0.2.0-py3-none-any.whl
- Upload date:
- Size: 23.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.15 {"installer":{"name":"uv","version":"0.11.15","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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b160f06fb83abdc2bae7dbab5f4e4b1eb3c0f41ccb6d7358e0de4cc27ff1a772
|
|
| MD5 |
43a72d2b6519c4e79d9fe212578fef99
|
|
| BLAKE2b-256 |
fd56950d7c48859d32577cd5b459a1bcda4c1ed262d1ca74f54d101c9411180b
|