4 ms·
I am not the author of the site in question, but I suspect that your guess is right, and that Pandoc is the hub between the spokes. For my blog, I write posts
by tmoertel 6mo ago
I am not the author of the site in question, but I suspect that your guess is right, and that Pandoc is the hub between the spokes.
For my blog, I write posts in Markdown. Then the build process uses Pandoc to convert the posts into web pages and, for certain pages, PDF files typeset with TeX. For example, here is a post in both web and PDF versions:
(Web) https://blog.moertel.com/posts/2024-08-23-sampling-with-sql.html https://blog.moertel.com/posts/2024-08-23-sampling-with-sql....
(Typeset PDF) https://blog.moertel.com/images/public_html/blog/pix-20240601/sampling-with-sql.pdf https://blog.moertel.com/images/public_html/blog/pix-2024060...
- sillysaurusx 6mo agoBeautiful. I don't suppose you have public, detailed installation steps for how to go from "nothing exists" to "Pandoc can push posts to https://blog.moertel.com/ https://blog.moertel.com/"? :) The best I was able to do was http://github.com/shawwn/wiki http://github.com/shawwn/wiki, which has been broken since 2020. You can't spell Haskell without Hell. If you wouldn't mind pulling up a `claude` in your repo and running `/init` and showing the result, that'd give me at least a vague idea of what to do.
- tmoertel 6mo agoThanks. I do not have a public, detailed description of how my blog works. But in short, my site build system is powered by a Makefile that invokes Hakyll [1]. My Hakyll configuration has the following rule baked into it for generating HTML docs from Markdown docs in the `posts/` directory: match "posts/*" $ do route $ setExtension "html" let ctx = postCtx tags compile $ pandocMathCompiler >>= loadAndApplyTemplate "templates/post.html" ctx >>= saveSnapshot "content" >>= loadAndApplyTemplate "templates/add-comments.html" ctx >>= loadAndApplyTemplate "templates/default.html" ctx >>= relativizeUrls The `pandocMathCompiler` bit invokes Hakyll's Pandoc subsystem with support for rendering formulas using MathJax. The site Makefile also has rules to build PDF versions of the articles that I want to typeset. The rules just invoke Pandoc directly. For example, here's the rule used to generate the PDF file in my prior comment: sampling-with-sql.pdf: posts/2024-08-23-sampling-with-sql.md ( cd posts && pandoc --metadata-file=../templates/latex-header-includes.yaml -t pdf -o ../$@.tmp --pdf-engine=pdflatex ../$< && mv -f ../$@.tmp ../$@ ) It's basically a straightforward invocation of Pandoc with a little shell boilerplate to prevent the PDF file from being moved into its final location unless Pandoc exits with success. The Makefile has a final "push" target that makes sure the site's assets are up to date (invoking Hakyll if needed) and then pushes the static site up to the content distribution network I'm using to publish my website. [1] https://jaspervdj.be/hakyll/ https://jaspervdj.be/hakyll/
- sillysaurusx 6mo agoThank you so much! Would you be willing to paste your entire Makefile here? Or are there secrets in it? It would help me greatly — I don't have much experience with pandoc or hakyll. I understand the basics, but the actual usage in practice isn't so easy to set up from first principles. I've been using Claude to help me with a lot of this, but I'm extremely curious to compare notes vs your setup. If not, thank you anyway for your time.
- tmoertel 6mo agoSure, here's the Makefile. Also, if you want more examples of working Hakyll setups, there's a long list of them here: https://jaspervdj.be/hakyll/examples.html https://jaspervdj.be/hakyll/examples.html # Binary tool we use to build the website. bins = dist-newstyle/build/*/*/*/*/site/build/site tool = $(bins)/site # By default, we build everything if you invoke `make` without a target. all: build .PHONY: all # The tool used to build the site is a Hakyll binary configured by `site.hs`. # This rule automatically builds the tool if it's out of date. $(tool): site.hs site.cabal cabal v2-build # The `build` target builds the web site's out-of-date static assets. .PHONY: build build: $(tool) pdfs $(tool) build # The `rebuild` target forces a rebuild of all web assets. .PHONY: rebuild rebuild: $(tool) $(tool) rebuild # This `push` rule publishes the static site to our CDN (firebase). # It requires: # # - the `firebase` tool: # wget -O ~/bin/firebase https://firebase.tools/bin/linux/latest \ # && chmod +x ~/bin/firebase # # Docs: https://firebase.google.com/docs/cli#linux # # - `firebase login --no-localhost` to have been run. # # You may need to run `firebase login --no-localhost --reauth` if # the local authentical credentials time out. .PHONY: push push: build firebase deploy --only hosting # Generate PDF versions of selected blog posts. .PHONY: pdfs pdfs: images/public_html/blog/pix-20240601/sampling-with-sql.pdf images/public_html/blog/pix-20240601/sampling-with-sql.pdf: posts/2024-08-23-sampling-with-sql.md ( cd posts && pandoc --metadata-file=../templates/latex-header-includes.yaml -t pdf -o ../$@.tmp --pdf-engine=pdflatex ../$< && mv -f ../$@.tmp ../$@ )
- tmoertel 6mo agoADDED 2026-04-21: Confirmed that it’s Pandoc doing the typesetting. The end of the author’s typeset version of the blog posts includes this colophon: > This piece, like most all my words and software, was written by hand—mainly in Vim. I composed a Markdown outline in a mix of headers, bullet points, and prose, then reorganized it in a few passes. With the structure laid out, I rewrote the outline as prose, typeset with Pandoc. I went back to make substantial edits as I wrote, then made two full edit passes on typeset PDFs. For the first I used an iPad and stylus, for the second, the traditional pen and paper, read aloud.