Skip to main content

Module markdown-pdf

GitHub Workflow Status GitHub Workflow Status Codacy Badge Codacy Badge PyPI - Downloads

The free, open source Python module markdown-pdf will create a PDF file from your markdown content.

When creating a PDF file you can:

  • Use UTF-8 encoded text in markdown in any language
  • Embed images used in markdown
  • Break text into pages in the desired order
  • Create a TableOfContents (bookmarks) from markdown headings
  • Tune the necessary elements using your CSS code
  • Use different page sizes within single pdf
  • Create tables in markdown
  • Use clickable hyperlinks. Thanks a lot @thongtmtrust for ideas and collaboration.
  • Render plantuml and mermaid code to pdf images with plugins.

The module utilizes the functions of two great libraries.

Installation

pip install markdown-pdf

Usage

Create a compressed pdf with TOC (bookmarks) from headings up to level 2.

from markdown_pdf import MarkdownPdf

pdf = MarkdownPdf(toc_level=2, optimize=True)

Add the first section to the pdf. The title is not included in the table of contents. After adding a section to a pdf, the page_count property in the section contains the number of pdf pages created for the added section.

from markdown_pdf import Section

section = Section("# Title\n", toc=False)
assert section.page_count == 0
pdf.add_section(section)
assert section.page_count == 1

Add a second section with external and internal hyperlinks. In the pdf file it starts on a new page.

text = """# Section with links

- [External link](https://github.com/vb64/markdown-pdf)
- [Internal link to Head1](#head1)
- [Internal link to Head3](#head3)
"""

pdf.add_section(Section(text))

Add a third section. The title is centered using CSS, included in the table of contents of the pdf file, and an image from the file img/python.png is embedded on the page.

pdf.add_section(
  Section("# <a name='head1'></a>Head1\n\n![python](img/python.png)\n\nbody\n"),
  user_css="h1 {text-align:center;}"
)

Add a next section. Two headings of different levels from this section are included in the TOC of the pdf file. The section has landscape orientation of A4 pages.

pdf.add_section(Section("## Head2\n\n### <a id='head3'></a>Head3\n\n", paper_size="A4-L"))

Add a section with a table.

text = """# Section with Table

|TableHeader1|TableHeader2|
|--|--|
|Text1|Text2|
|ListCell|<ul><li>FirstBullet</li><li>SecondBullet</li></ul>|
"""

css = "table, th, td {border: 1px solid black;}"

pdf.add_section(Section(text), user_css=css)

The sections property of the MarkdownPdf class contains a list of added sections in the order in which they were added.

assert len(pdf.sections) > 1

Set the properties of the pdf document.

pdf.meta["title"] = "User Guide"
pdf.meta["author"] = "Vitaly Bogomolov"

Save to file.

pdf.save("guide.pdf")

Or save to file-like object.

import io

out = io.BytesIO()
pdf.save_bytes(out)
assert out.getbuffer().nbytes > 0

Pdf

Settings and options

The Section class defines a portion of markdown data, which is processed according to the same rules. The next Section data starts on a new page.

The Section class can set the following attributes.

  • toc: whether to include the headers <h1> - <h6> of this section in the TOC. Default is True.
  • root: the name of the root directory from which the image file paths starts in markdown. Default ".".
  • paper_size: either the name of a paper size, as described here, or a list/tuple containing the width and height in mm. Default "A4".
  • borders: size of borders. Default (36, 36, -36, -36).

The following document properties are available for assignment (dictionary MarkdownPdf.meta) with the default values indicated.

  • creationDate: current date
  • modDate: current date
  • creator: "PyMuPDF library: https://pypi.org/project/PyMuPDF"
  • producer: ""
  • title: ""
  • author: ""
  • subject: ""
  • keywords: ""

Plugins

The module allows you to process specially marked sections of code using plugins.

For example, you convert the following Markdown text to PDF:

# Title plantuml

Document with plantuml code.

```plantuml
@startuml
Alice -> Bob: Hello Bob
Bob --> Alice: Hi!
@enduml
```

End of document

Without using the plugin, you will get the following result in pdf:

Without plantuml.jpg

You can use a plugin to render plantuml code into an image.

from markdown_pdf import MarkdownPdf, Section
from markdown_pdf.pligins import Plugin

plantuml_text = """# Title plantuml

Document with plantuml code.

```plantuml
@startuml
Alice -> Bob: Hello Bob
Bob --> Alice: Hi!
@enduml
```

End of document
"""

plugins = {
  Plugin.Plantuml: {'url': 'http://www.plantuml.com/plantuml/img/'}
}

pdf = MarkdownPdf(plugins=plugins)
pdf.add_section(Section(plantuml_text))
pdf.save("plantuml.pdf")

In this case, the plugin will send the code marked as plantuml to the specified internet server and replace the code text with an image generated by the server www.plantuml.com.

In the created file plantuml.pdf, you will see the following result:

With plantuml.jpg

You can find a more detailed description of the plugins here.

Command Line Interface script

As an example, you can download the pdf file created from this README. This Python script was used to create the PDF file.

You can create your own CLI script, tailored to your needs, using this script as a starting point.

Development

git clone git@github.com:vb64/markdown-pdf.git
cd markdown-pdf
make setup PYTHON_BIN=/path/to/python3
make tests

Metadata

Release files for markdown-pdf 1.13.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for markdown-pdf 1.13.3
File Size Uploaded
markdown_pdf-1.13.3.tar.gz 23.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for markdown-pdf 1.13.3
File Interpreter ABI Platform
markdown_pdf-1.13.3-py3-none-any.whl Python 3 none any Details

Total release size: 44.4 kB

Release files / markdown_pdf-1.13.3.tar.gz

Download URL markdown_pdf-1.13.3.tar.gz
Size 23.1 kB
Tags Source
SHA-256 checksum
How to use checksums
9800f16c597b5a8b6d62f98d141a23aadba973aceb0fb544a87fba127fdeb7b6
BLAKE2b-256 checksum
How to use checksums
f9e38d5f175783e53c741c2c8276137f774b84145f23708cf32d0499331ba8f6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.0

Release files / markdown_pdf-1.13.3-py3-none-any.whl

Download URL markdown_pdf-1.13.3-py3-none-any.whl
Size 21.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
eeeb4e3f91404f32a564a7764ee205996c5f6680c3ddbe447d25aa5fc976cca1
BLAKE2b-256 checksum
How to use checksums
bb4a15df7a92b54c3b7a8c04c368390939568eb8e18ee1babcc3df8b0b8dfc84
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.0

Release history Release notifications | RSS feed

This release

1.13.3 This release

2 release files

1.13.2

2 release files

1.13.1

2 release files

1.13

2 release files

1.12

2 release files

1.11

2 release files

1.10

2 release files

1.9

2 release files

1.8

2 release files

1.7

2 release files

1.6

2 release files

1.5

2 release files

1.4

2 release files

1.3.4

2 release files

1.3.3

2 release files

1.3.2

2 release files

1.3.1

2 release files

1.3

2 release files

1.2

2 release files

1.1

2 release files

1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page