Last active
February 5, 2026 22:12
-
-
Save cartok/0c5c625086602f5d8bd04ecd3e2b5806 to your computer and use it in GitHub Desktop.
[cli] Generate .pdf or .html from .md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env zsh | |
| function md-to-pdf() { | |
| -md-to "$1" pdf | |
| } | |
| function md-to-html() { | |
| -md-to "$1" html | |
| } | |
| function -md-to() { | |
| if (( "${#funcstack[@]}" == 0 )); then | |
| echo "Use md-to-pdf or md-to-html instead." | |
| return 1 | |
| fi | |
| local tempFiles=() | |
| function cleanup() { | |
| (( ${#tempFiles[@]} )) && rm -f -- "${tempFiles[@]}" | |
| } | |
| trap cleanup EXIT INT TERM HUP | |
| local inputFilePath="$1" | |
| local outputFormat="$2" | |
| if [[ -z "$inputFilePath" ]]; then | |
| echo "Bad parameters" | |
| echo "\n" | |
| echo "Usage: md-to-$outputFormat <file>" | |
| echo "Hint: Supply pandoc arguments via inline yaml inside the markdown file. Therefore read \`man pandoc\` and search for \" Variables\"." | |
| echo "" | |
| echo "Example markdown file that includes YAML configuration header:" | |
| echo "" | |
| echo "\t" '---' | |
| echo "\t" 'title: Tale of the Utterly Gutsy Shinobi' | |
| echo "\t" 'author: Jiraiya' | |
| echo "\t" 'fontsize: 12pt' | |
| echo "\t" 'mainfont: Cantarell' | |
| echo "\t" '---' | |
| echo "" | |
| echo "\t" '## Hidden Leaf Stories' | |
| echo "" | |
| echo "\t" '## Chapter 1.' | |
| echo "" | |
| echo "\t" 'In the dense forests surrounding Konoha, Naruto Uzumaki prepared his next jutsu.' | |
| echo "\t" 'The wind whispered through the trees, carrying the scent of chakra and danger.' | |
| echo "" | |
| echo "\t" 'Naruto takes a deep breath.' | |
| echo "\t" '"Shadow Clone Jutsu!" he shouts.' | |
| echo "\t" 'Suddenly, five perfect copies of him vanish into the mist, ready to fight anything!' | |
| return 1 | |
| fi | |
| if [[ "${inputFilePath##*.}" != "md" ]]; then | |
| echo "Error: Input file must have .md extension" | |
| return 1 | |
| fi | |
| local outputFilePathWithBaseName="${inputFilePath%.md}" | |
| local outputFilePath="${outputFilePathWithBaseName}.${outputFormat}" | |
| local modifiedInputFilePath="$(mktemp)" | |
| tempFiles+=($modifiedInputFilePath) | |
| cp -- "$inputFilePath" "$modifiedInputFilePath" | |
| local pandocArguments=( | |
| "$modifiedInputFilePath" | |
| --output "$outputFilePath" | |
| --standalone | |
| ) | |
| local latexHeaderFilePath="$(mktemp)" | |
| tempFiles+=($latexHeaderFilePath) | |
| # TODO: Parse yaml header of the markdown file to allow overwriting some of the here set variables, like `fontsize`. Otherwise the parameters here take precedence, thus its impossible to define them in markdown. Implement it by reading the lines between `---` into a string pass it throuhg `yaml2json` and use `jq` and read those variables of those below which shall still be configurable. Could then also stip the yaml of the markdown file, write the combined yaml and then the markdown content. This way I could define such default parameters as a multiline yaml string here. | |
| if [[ "$outputFormat" == "pdf" ]]; then | |
| pandocArguments+=( | |
| --from markdown+hard_line_breaks+raw_tex | |
| --pdf-engine=xelatex | |
| --variable documentclass=scrartcl | |
| --variable papersize=a4 | |
| --variable geometry=margin=1in | |
| --variable fontsize=11pt | |
| --include-in-header "$latexHeaderFilePath" | |
| ) | |
| print -r -- "\usepackage{sectsty}" >> "$latexHeaderFilePath" | |
| print -r -- "\subsectionfont{\Large\bfseries}" >> "$latexHeaderFilePath" | |
| elif [[ "$outputFormat" == "html" ]]; then | |
| sd -f i '^\\newpage\s*$' '' "$modifiedInputFilePath" | |
| # TODO: Check if there is a usefull application of latex commands for HTML generation. If so make GFM a commandline argument instead. As for PDF generation its mandatory to me that pagebreaks must be supported but I also would like to have GFM, I now only use GFM for HTML output. | |
| pandocArguments+=( | |
| --from gfm+hard_line_breaks | |
| --variable fontsize=12pt | |
| --variable maxwidth=52em | |
| ) | |
| fi | |
| pandoc "${pandocArguments[@]}" 2>/dev/null | |
| cleanup | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment