Skip to content

Instantly share code, notes, and snippets.

@dajare
Last active August 17, 2026 10:59
Show Gist options
  • Select an option

  • Save dajare/10c8464d0502c5bdecf64caaa24914ce to your computer and use it in GitHub Desktop.

Select an option

Save dajare/10c8464d0502c5bdecf64caaa24914ce to your computer and use it in GitHub Desktop.
Markdown to PDF converter, via Pandoc and Typst (HT: claude) | bash shell script
#!/usr/bin/env bash
#
# md2pdf - Convert a Markdown file to an A4 PDF via Pandoc + Typst
## With custom margins, footer, and optional full-justify / no-hyphenate styling.
## Default paragraph alignment is ragged-right (left-justified);
## + use --justify for full justification.
## Default font is Gentium https://software.sil.org/gentium/
## Footer uses Andika for pagenumbers (line 45) https://software.sil.org/andika/
#
# Usage: md2pdf.sh [--justify] [--no-hyphenate] [--font <name>] <input.md> [output.pdf]
set -euo pipefail
justify=false
no_hyphen=false
mainfont="Gentium"
while [ $# -gt 0 ]; do
case "$1" in
--justify) justify=true; shift ;;
--no-hyphenate) no_hyphen=true; shift ;;
--font) mainfont="${2:-}"; shift 2 ;;
--) shift; break ;;
-*) echo "Unknown option: $1" >&2; exit 1 ;;
*) break ;;
esac
done
if [ -z "${1:-}" ]; then
echo "Usage: md2pdf.sh [--justify] [--no-hyphenate] [--font <name>] <input.md> [output.pdf]"
exit 1
fi
input="$1"
output="${2:-${input%.md}.pdf}"
fname="$(basename "$input")"
stamp="$(date '+%Y-%m-%d %H:%M')"
text_opts="#set text(features: (\"onum\",))"
if [ "$no_hyphen" = true ]; then
text_opts="$text_opts
#set text(hyphenate: false)"
fi
layout_setup="#set page(margin: (left: 2.2cm, right: 2.2cm, top: 2.2cm, bottom: 2.2cm), footer: context [#grid(columns: (1fr, 1fr), align(left)[#text(size: 10pt, fill: rgb(40%,40%,40%))[${fname} ⬝ ${stamp}]], align(right)[#text(font: ((name: \"Andika\", covers: regex(\"[0-9]\")), \"${mainfont}\"), size: 10pt, fill: rgb(40%,40%,40%))[Page #counter(page).display()]])])
#set par(leading: .85em, first-line-indent: 1.5em)
#set list(spacing: 1.4em)
#set enum(spacing: 1.4em)"
if [ "$justify" = false ]; then
layout_setup="$layout_setup
#set par(justify: false)"
fi
pandoc "$input" -o "$output" \
--pdf-engine=typst \
-V papersize=a4 \
-V mainfont="$mainfont" \
-V "header-includes=$text_opts" \
-V "include-before=$layout_setup"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment