A CLI utility which, as the name implies, generates a PDF from Markdown.
This package depends on two other packages:
- gomarkdown parser to read the markdown source
- fpdf to generate the PDF
- Syntax highlighting (for code blocks)
- Dark and light themes
- Customised themes (by passing a JSON file to
md2pdf
) - Support of non-Latin charsets and multiple fonts
- Pagination control (using horizontal lines - especially useful for presentations)
- Page Footer (consisting of author, title and page number)
- Emphasised and strong text
- Headings 1-6
- Ordered and unordered lists
- Nested lists
- Images
- Tables
- Links
- Code blocks and backticked text
You can obtain the pre-built md2pdf
binary for your OS and arch
here;
you can also install the md2pdf
binary directly onto your $GOBIN
dir with:
$ go install github.com/mandolyte/mdtopdf/v2/cmd/md2pdf@latest
md2pdf
is also available via Homebrew:
$ brew install md2pdf
mdtopdf
supports colourised output via the gohighlight module.
For examples, see testdata/syntax_highlighting.md and testdata/syntax_highlighting.pdf
md2pdf
supports both light and dark themes out of the box (use --theme light
or --theme dark
- no config required).
However, if you wish to customise the font faces, sizes and colours, you can use the JSONs in
custom_themes as a starting point. Edit to your liking and pass --theme /path/to/json
to md2pdf
$ cd cmd/md2pdf
$ go run md2pdf.go -i test.md -o test.pdf
To benefit from Syntax highlighting, invoke thusly:
$ go run md2pdf.go -i syn_test.md -s /path/to/syntax_files -o test.pdf
To convert multiple MD files into a single PDF, use:
$ go run md2pdf.go -i /path/to/md/directory -o test.pdf
This repo has the gohighlight module configured as a submodule, so if you clone
with --recursive
, you will have the highlight
dir in its root. Alternatively, you may issue the following command to update an
existing clone:
git submodule update --remote --init
Note 1: the cmd
folder has an example for the syntax highlighting.
See the script run_syntax_highlighting.sh
. This example assumes that
the folder with the syntax files is located at a relative location:
../../../jessp01/gohighlight/syntax_files
.
Note 2: when annotating the code block to specify the language, the annotation name must match the syntax base filename.
-author string
Author name; used if -footer is passed
-font-file string
path to font file to use
-font-name string
Font name ID; e.g 'Helvetica-1251'
-help
Show usage message
-i string
Input filename, dir consisting of .md|.markdown files or HTTP(s) URL; default is os.Stdin
-log-file string
Path to log file
-new-page-on-hr
Interpret HR as a new page; useful for presentations
-o string
Output PDF filename; required
-orientation string
[portrait | landscape] (default "portrait")
-page-size string
[A3 | A4 | A5] (default "A4")
-s string
Path to github.com/jessp01/gohighlight/syntax_files
-theme string
[light | dark | /path/to/custom/theme.json] (default "light")
-title string
Presentation title
-unicode-encoding string
e.g 'cp1251'
-version
Print version and build info
-with-footer
Print doc footer (<author> <title> <page number>)
For example, the below will:
- Set the title to
My Grand Title
- Set
Random Bloke
as the author (used in the footer) - Set the dark theme
- Start a new page when encountering an HR (
---
); useful for creating presentations - Print a footer (
author name, title, page number
)
$ go run md2pdf.go -i /path/to/md \
-o /path/to/pdf --title "My Grand Title" --author "Random Bloke" \
--theme dark --new-page-on-hr --with-footer
To use a non-ASCII language, the PDF generator must be configured with WithUnicodeTranslator
:
// https://en.wikipedia.org/wiki/Windows-1251
pf := mdtopdf.NewPdfRenderer("", "", *output, "trace.log", mdtopdf.WithUnicodeTranslator("cp1251"))
In addition, this package's Styler
must be used to set the font to match what is configured with the PDF generator.
A complete working example can be found for Russian in the cmd
folder named
russian.go
.
For a full example, run:
$ go run md2pdf.go -i russian.md -o russian.pdf \
--unicode-encoding cp1251 --font-file helvetica_1251.json --font-name Helvetica_1251
The tests included in this repo (see the testdata
folder) were taken from the BlackFriday package.
While the tests may complete without errors, visual inspection of the created PDF is the
only way to determine if the tests really pass!
The tests create log files that trace the gomarkdown parser callbacks. This is a valuable debugging tool, showing each callback and the data provided while the AST is presented.
- It is common for Markdown to include HTML. HTML is treated as a "code block". There is no attempt to convert raw HTML to PDF.
- Github-flavoured Markdown permits strikethrough using tildes. This is not supported by
fpdf
as a font style at present. - The markdown link title (which would show when converted to HTML as hover-over text) is not supported. The generated PDF will show the URL, but this is a function of the PDF viewer.
- Definition lists are not supported
- The following text features may be tweaked: font, size, spacing, style, fill colour, and text colour. These are exported and available via the
Styler
struct. Note that fill colour only works when usingCellFormat()
. This is the case for tables, code blocks, and backticked text.
- Set up and run pre-commit hooks:
# Install the needed GO packages:
go install github.com/go-critic/go-critic/cmd/gocritic@latest
go install golang.org/x/tools/cmd/goimports@latest
go install golang.org/x/lint/golint@latest
go install github.com/gordonklaus/ineffassign@latest
# Install the `pre-commit` util:
pip install pre-commit
# Generate `.git/hooks/pre-commit`:
pre-commit install
Following that, these tests will run every time you invoke git commit
:
go fmt...................................................................Passed
go imports...............................................................Passed
go vet...................................................................Passed
go lint..................................................................Passed
go-critic................................................................Passed
- Submit a pull request and include a succinct description of the feature or issue it addresses