md2

command module
v0.3.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 1, 2026 License: MIT Imports: 15 Imported by: 0

README

md2

CI

Convert markdown files to other formats. Pure Go by default, extensible to new output formats.

Currently supported:

  • PDF (.pdf)
  • HTML (.html) — self-contained; local images embedded as data URIs. Diagrams render via inlined mermaid.js, or as static images with -flatten (e.g. for Google Docs import)
  • Plain text (.txt)

Install

Homebrew (macOS):

brew install rapatao/tap/md2

Nix (flakes):

nix run github:rapatao/md2 -- input.md     # run without installing
nix profile install github:rapatao/md2     # install into your profile

Prebuilt binaries: download the archive for your OS/arch from the latest release. Each release is signed (keyless, via cosign) — see Verifying a release.

Go:

go install github.com/rapatao/md2@latest

Or build locally:

go build -o md2 .

Verifying a release

Each release publishes checksums.txt plus a keyless cosign signature (checksums.txt.sig) and certificate (checksums.txt.pem), proving the checksums were produced by the release.yml workflow in this repo (not a tampered fork or mirror).

cosign verify-blob checksums.txt \
  --certificate checksums.txt.pem \
  --signature checksums.txt.sig \
  --certificate-identity-regexp "https://github.com/rapatao/md2/.github/workflows/release.yml@.*" \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com

Then confirm your downloaded archive matches a line in the verified checksums.txt:

sha256sum --ignore-missing -c checksums.txt

Usage

md2 input.md                  # writes input.pdf (default format)
md2 -f html input.md          # writes input.html
md2 -f txt input.md           # writes input.txt (plain text)
md2 -f pdf,html input.md      # writes input.pdf and input.html
md2 -f html -render mermaid -flatten input.md  # self-contained html, diagrams as images (Google Docs)
md2 -o report.pdf input.md    # explicit output (format from extension)
md2 -f html -stdout input.md  # write html to stdout (no file), e.g. to pipe

Flags:

  • -o output file. Default: input name with the format extension. Cannot be combined with multiple formats.
  • -f output format(s), comma-separated. Default: inferred from -o extension, else pdf. Duplicates are ignored.
  • -render diagram renderer(s) to enable, comma-separated (currently mermaid), or all. Default: none — diagrams render as plain code unless enabled.
  • -flatten (HTML only) flatten diagrams to static images instead of inlining mermaid.js, for a self-contained file with no JS runtime needed to view it (e.g. importing into Google Docs). Requires a browser.
  • -stdout write the converted result to standard output instead of a file, for piping into other tools. Single format only. With -o it also writes the file.
  • -allow-download authorize downloading Chromium for the browser renderer without prompting (useful in CI).
  • -version print the version and exit.

PDF engine

PDF uses a two-stage strategy:

  1. Pure Go (goldmark-pdf) — fast, no external runtime. Handles most documents.
  2. Headless browser fallback — if the pure-Go renderer fails (e.g. complex tables, or glyphs like emoji it cannot lay out), md2 prints a styled HTML version to PDF with Chrome/Chromium for full fidelity.

The fallback prefers a browser already installed on the system. If none is found it asks before downloading Chromium (~150MB, cached for later runs):

No Chrome/Chromium found. Download Chromium (~150MB) to render the PDF? [y/N]:

On a non-interactive terminal it declines unless -allow-download is passed. Simple documents never launch a browser.

Diagrams

Diagram rendering is off by default and enabled per run with -render. Without it, a diagram code block is rendered as plain code.

```mermaid
graph TD; A-->B;
```
md2 -f html -render mermaid input.md            # enable mermaid (interactive)
md2 -f html -render mermaid -flatten input.md   # diagrams as static images
md2 -f pdf  -render all     input.md            # enable every supported renderer

When enabled:

  • HTML — by default the mermaid library is inlined into the output (no network access needed to view it), and the block renders to SVG in the browser — interactive, but needing a JS runtime to display. With -flatten, md2 renders the document in a headless browser and replaces each diagram with a static PNG image, producing a self-contained file that displays anywhere — including a Google Docs import (upload the .html to Drive, then "Open with > Google Docs"), which runs no JavaScript.
  • PDF — a mermaid block forces the headless-browser engine (the pure-Go renderer cannot run JavaScript), so the diagram is captured as vector graphics.
  • Plain text — no diagram; the mermaid source is kept as code.

Inlining the library adds ~3 MB to each HTML file that contains a diagram; -flatten avoids that (the diagrams become images instead). Files without a diagram are unaffected either way.

Currently only mermaid is supported; the -render flag is designed to take additional renderers (e.g. plantuml) in the future.

Output naming

When -o is omitted, each output keeps the input's path and base name, swapping the extension for the format — docs/report.md with -f pdf,html produces docs/report.pdf and docs/report.html.

Supported formats

Format Extension Engine
pdf .pdf goldmark-pdf (pure Go), browser fallback (go-rod)
html .html goldmark (GFM), styled standalone document; local images embedded as data URIs; diagrams as mermaid.js or, with -flatten, static PNGs (go-rod)
txt .txt goldmark AST walker, markup stripped, structure kept

Adding a format

Each format lives in its own package under internal/converter/. Create a new one that implements converter.Converter and registers itself in an init:

// internal/converter/docx/docx.go
package docx

import "github.com/rapatao/md2/internal/converter"

type Converter struct{}

func (Converter) Convert(src []byte, w io.Writer) error { /* ... */ }

func init() { converter.Register("docx", Converter{}) }

Then blank-import the package in main.go so its init runs:

_ "github.com/rapatao/md2/internal/converter/docx"

The CLI picks it up automatically — no other changes. It then works standalone (-f docx) and in any comma list (-f pdf,docx).

Layout

main.go                       CLI entry: arg parsing, format resolution, I/O
                              (blank-imports each format package)
flags.go                      flag set
main_test.go                  parseFormats + run end-to-end tests
internal/converter/
  converter.go                Converter interface + format registry
  converter_test.go           registry tests
  pdf/pdf.go                  markdown -> PDF: pure-Go first, browser fallback
  html/html.go                markdown -> styled HTML document (+ Render helper)
  text/text.go                markdown -> plain text (AST walker)
  chrome/chrome.go            HTML -> PDF via headless browser (go-rod)

Test

go test ./...

License

MIT © rapatao

Documentation

Overview

Command md2 converts markdown files to other formats (currently PDF).

Usage:

md2 [-o output] [-f format] input.md

If -o is omitted, the output filename is the input with its extension replaced by the format. If -f is omitted, the format is inferred from the output extension, defaulting to pdf.

With -stdout the converted result is written to standard output instead of a file (single format only); pass -o as well to also write the file.

Directories

Path Synopsis
internal
converter
Package converter defines the conversion interface and a registry of available output formats.
Package converter defines the conversion interface and a registry of available output formats.
converter/chrome
Package chrome renders markdown to PDF by printing a styled HTML document with a headless Chrome/Chromium browser.
Package chrome renders markdown to PDF by printing a styled HTML document with a headless Chrome/Chromium browser.
converter/html
Package html renders markdown to a complete, styled HTML document.
Package html renders markdown to a complete, styled HTML document.
converter/pdf
Package pdf renders markdown to PDF.
Package pdf renders markdown to PDF.
converter/text
Package text renders markdown to readable plain text, stripping markup while preserving structure (headings, lists, code, tables).
Package text renders markdown to readable plain text, stripping markup while preserving structure (headings, lists, code, tables).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL