Skip to content

A CLI utility that generates PDF from Markdown. Features: syntax highlighting (for code blocks), dark, light and custom themes, tables, pagination control (using horizontal lines - especially useful for presentations), page Footer (consisting of author, title and page number), support of non-Latin charsets and multiple fonts

License

Notifications You must be signed in to change notification settings

solworktech/md2pdf

Repository files navigation

CI GoDoc GoReportCard License

Markdown to PDF

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

Features

Supported Markdown elements

  • Emphasised and strong text
  • Headings 1-6
  • Ordered and unordered lists
  • Nested lists
  • Images
  • Tables
  • Links
  • Code blocks and backticked text

Installation

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

Syntax highlighting

mdtopdf supports colourised output via the gohighlight module.

For examples, see testdata/syntax_highlighting.md and testdata/syntax_highlighting.pdf

Custom themes

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

Quick start

$ 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.

Additional options

  -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

Using non-ASCII Glyphs/Fonts

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

Tests

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.

Limitations and Known Issues

  • 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 using CellFormat(). This is the case for tables, code blocks, and backticked text.

Contributions

  • 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

About

A CLI utility that generates PDF from Markdown. Features: syntax highlighting (for code blocks), dark, light and custom themes, tables, pagination control (using horizontal lines - especially useful for presentations), page Footer (consisting of author, title and page number), support of non-Latin charsets and multiple fonts

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 11