Skip to main content

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 .docx or .dotx Word 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

If the output file already exists, the command refuses rather than silently overwriting. Use --force (or -f) to overwrite:

mark-my-word render document.md --theme themes/my-theme/ --force

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}}. You can also supply a fallback: {{title: Untitled}} is used when title is not set. Matching is case-insensitive.

Set values 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


Download files

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

Source Distribution

mark_my_word-0.2.1.tar.gz (175.8 kB view details)

Uploaded Source

Built Distribution

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

mark_my_word-0.2.1-py3-none-any.whl (26.2 kB view details)

Uploaded Python 3

File details

Details for the file mark_my_word-0.2.1.tar.gz.

File metadata

  • Download URL: mark_my_word-0.2.1.tar.gz
  • Upload date:
  • Size: 175.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

Hashes for mark_my_word-0.2.1.tar.gz
Algorithm Hash digest
SHA256 60aecba73e926c03cec0ca6354a9b49c0b9e20106e6dccb0bacd7b20a9b73a94
MD5 a01e5317ebee85ca3147e67dc80b9f8a
BLAKE2b-256 61b5b1e6a3c2e9f5aa7ca17d0af19534bd70229606d48bd6eae31cb57dd5d478

See more details on using hashes here.

File details

Details for the file mark_my_word-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: mark_my_word-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 26.2 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

Hashes for mark_my_word-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 957bf977c09b6a66be01152121ec46b68c21b40021fa9b8ee2bd13dd27d0421d
MD5 765c0ba836c9eef498f90aea40b920b9
BLAKE2b-256 b02ab848321c4a64be192da020d21de5770b8a179c92a3bf18e556874381b741

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