Skip to main content

The Markdown to PDF conversion tool with styles

Project description

md2pdf logo

Convert Markdown files to PDF with styles.

GitHub Actions Workflow Status PyPI - Version

Installation

The easiest way to test md2pdf is to use uv:

$ uv tool install md2pdf[cli]

Nota bene: ensure, Weasyprint is fully functional before using md2pdf. You will find installation instructions in the project documentation: https://doc.courtbouillon.org/weasyprint/stable/first_steps.html#installation

Usage

As a CLI

 Usage: md2pdf [OPTIONS]                                                                              
                                                                                                      
 Markdown to PDF conversion tool with styles… and templates!                                          
                                                                                                      
╭─ Options ──────────────────────────────────────────────────────────────────────────────────────────╮
│ --input               -i      PATH     Markdown source file path (can be used multiple times).     │
│ --output              -o      PATH     PDF output file path (when a single md input is used).      │
│ --css                 -c      PATH     Input CSS file.                                             │
│ --extras              -e      TEXT     Extra markdown extension to activate (cam be used multiple  │
│                                        times).                                                     │
│ --config              -C      TEXT     Markdown extensions configuration (as a JSON string).       │
│ --workers             -W      INTEGER  Number of parallel workers to start. [default: 4]           │
│ --version             -V               Display program version.                                    │
│ --install-completion                   Install completion for the current shell.                   │
│ --show-completion                      Show completion for the current shell, to copy it or        │
│                                        customize the installation.                                 │
│ --help                                 Show this message and exit.                                 │
╰────────────────────────────────────────────────────────────────────────────────────────────────────╯

For example, try to generate the project documentation with:

$ md2pdf -i README.md 

A README.pdf should have been generated.

Optionally, you may load an external style sheet:

$ md2pdf \
    --css examples/custom-styles.css \
    -i README.md

And activate markdown extensions from PyMdown:

$ md2pdf \
    --css examples/custom-styles-with-pygments.css \
    --extras 'pymdownx.emoji' \
    -i README.md

Code blocks should be properly rendered when this extension is active.

As a library

If you have added md2pdf as a dependency for your python project, you can use md2pdf in your code, like:

from md2pdf.core import md2pdf

md2pdf(pdf,
       md=None,
       raw=None,
       css=None,
       base_url=None,
       extras=[],
       context={"foo": 1}
)

Function arguments:

  • pdf: output PDF file path
  • raw: input markdown raw string content (can contain Jinja instructions)
  • md: input markdown file path (can contain Jinja instructions)
  • css: input styles path (CSS)
  • base_url: absolute base path for markdown linked content (as images)
  • extras: markdown extra extensions that should be activated
  • context: variables to inject to rendered Jinja template

With Docker

Considering docker is installed, pull the latest Debian-based image:

$ docker pull jmaupetit/md2pdf:latest

And try to run a smoke test with this image:

$ docker run --rm -t \
    -v $PWD:/wrk \
    -u "$(id -u):$(id -g)" \
    -w /wrk \
    jmaupetit/md2pdf:latest -i README.md

There is also a smaller Alpine-based image tagged alpine. For a full list of available tags, check the project's DockerHub repository.

Use Jinja templates as input

Your input markdown file or raw content can include Jinja template tags, and context can be given in a frontmatter header:

---
groceries:
  - name: apple
    quantity: 4 
  - name: orange 
    quantity: 10
  - name: banana 
    quantity: 6
---

# Groceries

| Item | Quantity |
| ---- | -------- |
{% for item in groceries -%}
| {{ item.name }} | {{ item.quantity }} |
{% endfor %}

Or directly as a md2pdf argument (see library usage).

You can test this example using:

$ md2pdf \
    --css examples/gutenberg-modern.min.css \
    -i examples/my-music.md.j2 \
    -o examples/my-music.pdf

Contributing

Hacking

Clone this project first:

$ git clone git@github.com:jmaupetit/md2pdf.git

Install md2pdf along with its dependencies (using uv):

$ cd md2pdf
$ make bootstrap

Running the test suite

To run the test suite:

$ make test

Lint the code via:

$ make lint

Ease your life

If you are familiar with GNU Make, we also automate daily tasks using this lovely tool:

$ make help

License

md2pdf is released under the MIT License. See the bundled LICENSE file for details.

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

md2pdf-3.1.0.tar.gz (120.5 kB view details)

Uploaded Source

Built Distribution

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

md2pdf-3.1.0-py3-none-any.whl (9.2 kB view details)

Uploaded Python 3

File details

Details for the file md2pdf-3.1.0.tar.gz.

File metadata

  • Download URL: md2pdf-3.1.0.tar.gz
  • Upload date:
  • Size: 120.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for md2pdf-3.1.0.tar.gz
Algorithm Hash digest
SHA256 b6a7535b79f58baddaf0b5f78172213171f34bf7d466b713b37178e795af02ae
MD5 5b57cc6a2436f0a1d2427cf29c2ea71a
BLAKE2b-256 7e64c44e248307d158a51f50337e8d421dfc3ea0744dd62011b4f0dbffadfc6f

See more details on using hashes here.

Provenance

The following attestation bundles were made for md2pdf-3.1.0.tar.gz:

Publisher: package.yml on jmaupetit/md2pdf

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file md2pdf-3.1.0-py3-none-any.whl.

File metadata

  • Download URL: md2pdf-3.1.0-py3-none-any.whl
  • Upload date:
  • Size: 9.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for md2pdf-3.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 519dfb08855e6d93a9e638f8ba91829007dec635f912122c54e5deacb5623731
MD5 637849bb888fcd0bba0e90f8c4334661
BLAKE2b-256 1fd0a684cff8b6f721ae1e18f1d6e861c964bc0c128a8a290c8617aaca514f0b

See more details on using hashes here.

Provenance

The following attestation bundles were made for md2pdf-3.1.0-py3-none-any.whl:

Publisher: package.yml on jmaupetit/md2pdf

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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