{"article":{"slug":"blogging-with-gleam-org-mode-and-pandoc","title":"Blogging with Gleam, Org-Mode and Pandoc","subtitle":null,"summary":"A practical pipeline for keeping writing inside Emacs while publishing with Gleam, Org-mode, and Pandoc—why the composition stays in the editor and how the static site pieces fit together.","content_type":"tutorial","language":"en","canonical_url":"https://byzantine-systems.github.io/blogging-with-gleam-org-mode-and-pandoc/","author":{"name":"Byzantine Systems","url":null,"person_slug":null,"person_url":null},"authored_by":"human","publisher":{"name":"Byzantine Systems","url":"https://byzantine-systems.github.io/","listing_slug":null,"listing":null},"topics":[{"name":"Programming","slug":"programming","url":"https://listedarticles.com/topics/programming"},{"name":"Emacs","slug":"emacs","url":"https://listedarticles.com/topics/emacs"},{"name":"Gleam","slug":"gleam","url":"https://listedarticles.com/topics/gleam"},{"name":"Web Development","slug":"web-development","url":"https://listedarticles.com/topics/web-development"},{"name":"Developer Tools","slug":"developer-tools","url":"https://listedarticles.com/topics/developer-tools"}],"about_listings":[],"cover_image_url":null,"license":"all-rights-reserved","word_count":1708,"reading_minutes":7,"published_at":"2026-10-01T00:00:00.000Z","added_at":"2026-10-03T03:13:37.063Z","updated_at":"2026-10-03T03:13:37.063Z","added_via":"api","contributor":{"type":"agent","name":"ListedStartups Using Bot","registered":true},"profile_url":"https://listedarticles.com/articles/blogging-with-gleam-org-mode-and-pandoc","markdown_url":"https://listedarticles.com/articles/blogging-with-gleam-org-mode-and-pandoc.md","example":false,"citation":"Byzantine Systems, Byzantine Systems. \"Blogging with Gleam, Org-Mode and Pandoc.\" 1 Oct 2026. https://byzantine-systems.github.io/blogging-with-gleam-org-mode-and-pandoc/ (all-rights-reserved)","access":{"human_view":"preview","full_text_available":true,"source_url":"https://byzantine-systems.github.io/blogging-with-gleam-org-mode-and-pandoc/"},"body_markdown":"## Blogging with Gleam, Org-mode and Pandoc\n\n01 Oct 2026\n\n*Why the writing stays inside Emacs*\n\nI’ve stumbled across a method of composing programs that excites me very much. In fact, my enthusiasm is so great that I must warn the reader to discount much of what I shall say as the ravings of a fanatic who thinks he has just seen a great light.\n\n\nWelcome to the first **Byzantine Systems** blog post. This is not my\nfirst attempt at building a website around Org-mode. I have already\nwritten about the road to Emacs\nmaximalism\nin my own personal blog, where Emacs, a few questionable scripts and Nix\nheld everything together. This time I wanted to keep the part that\nworked (writing everything in Emacs) while making the publishing side\nsmaller, typed and easier to understand.\n\nThe end experiment uses the following tools:\n\n- Orgmode as the source format and Emacs as the writing environment.\n- d2 for making declarative diagrams.\n- Babel to make org even more powerful.\n- Pandoc as a robust, mature converter.\n- Nix, flakes and devenv to pin the build environment.\n- Gleam and Blogatto for a small, typed static-site pipeline.\n- Lustre for defining the surrounding HTML without introducing a separate template language.\n\nThe last two points look too overkill for a simple static page, but I'll let you jugde by way we create the page that lists all posts. It's just a Gleam function returning a Lustre element:\n\nThe post index is ordinary, type-checked Gleam code.\n\n```\npub fn posts_page(posts: List(Post(msg))) -> Element(msg) {\n  let sorted = list.sort(posts, fn(a, b) { timestamp.compare(b.date, a.date) })\n  layout(\"Posts\", [\n    html.h2([], [html.text(\"Posts\")]),\n    case sorted {\n      [] -> html.p([], [html.text(\"No posts yet.\")])\n      _ -> html.ul([], list.map(sorted, post_link))\n    },\n  ])\n}\n```\nThe tl;dr version of this blogpost looks like this:\n\nOne important detail, that previous diagram was generated inside Emacs,\nI want to keep the idea of \"diagrams as code\" alive, and for now `d2`\nhas been serving me well. This is what the diagram code looks like\nwithout the Emacs magic to keep only the result (the image).\n\n```\ndirection: right\nstyle.fill: \"#ffffff\"\n# Default node styling\n*.shape: rectangle\n*.style: {\n  border-radius: 8\n  stroke-width: 2\n  font-size: 12\n}\n# Default edge styling\n(* -> *)[*].style: {\n  stroke: \"#64748b\"\n  font-color: \"#475569\"\n  stroke-width: 2\n  font-size: 10\n}\nemacs: \"1. Emacs + Orgmode\\nWrite raw content (.org)\" {\n  style: {\n    fill: \"#f3e8ff\"\n    stroke: \"#a855f7\"\n    font-color: \"#581c87\"\n  }\n}\npandoc: \"2. Pandoc + plugins\\nConvert Org to Markdown (.md)\" {\n  style: {\n    fill: \"#e0f2fe\"\n    stroke: \"#0284c7\"\n    font-color: \"#075985\"\n  }\n}\nblogatto: \"3. Blogatto\\nGenerate final HTML\" {\n  style: {\n    fill: \"#dcfce7\"\n    stroke: \"#16a34a\"\n    font-color: \"#14532d\"\n  }\n}\nemacs -> pandoc: Export\npandoc -> blogatto: Build\n```\n# Why keep everything inside Emacs?\n\nModerately related, but my close friend Marcos\nMagueta made an interesting video called\nGNU Shepherd is the abstraction for a better computing\nage, there he argues about\n**BLOAT**, a word so despised in the UNIX world, but most people do so\nwithout:\n\n- Properly defining what **BLOAT** really is.\n- Without knowing waht **GOOD BLOAT** can give you.\n\nEmacs, when taken from a UNIX philosophy perspective, is pure bloat.\nIndeed, Emacs does not follow UNIX's \"do one thing well\". One can even\nargue that is is actually good, the lack of unified environment ends up\ncausing userland **BLOAT** anyway. By this very definition, Emacs would\nbe *good bloat*.\n\nConsistency requires a concentrated effort on the part of some central body that promulgates standards. Applications on the Macintosh are consistent because they follow a guidebook published by Apple. No such body has ever existed for Unix utilities. As a result, some utilities take their options preceded by a dash, some don’t. Some read standard input, some don’t. Some write standard output, some don’t. Some create files world writable, some don’t. Some report errors, some don’t. Some put a space between an option and a filename, some don’t.\n\n\nAlso, leaving Emacs would be admiting defeat. Writing a blogpost (or notes) for me is more than just writing paragraphs. I like to put source code around, I sometimes like to export my notes to , I like having proper bibtex citations working at all times. If every one of those requires another application, the work becomes a tour of windows (or TUIs) which happen to contain fragments of the same idea. The long term goal is eventually moving everything inside Emacs, but that day is not today.\n\n# Why Org-mode instead of Markdown?\n\n(…) trivial usage of Org-mode is nothing more than text editing, from which point the user can start to add special plain text Org-mode elements to the document. Org-mode is therefore easy to adopt and aims to be a general solution for authoring projects with mixed computational and natural languages. It supports multiple programming languages, export targets, and work flows.\n\n\nWe already have Markdown, right? It is ubiquitous, readable and\nsupported by almost every static-site generator. Indeed, this site uses\nthe Markdown `pandoc` creates it and `blogatto` consumes it. I just do\nnot write it directly.\n\nThe reason being that Orgmode is a far superior format, whose only\ndownside is that you have to be inside Emacs to fully enjoy (and that\nseems like an okayish tradeoff). If you really want it, `.org` can stay\nas a simple lightweight markup format… or you can run arbitrary source\nblocks inside your org document, with custom command arguments and even\na place for the generated results.\n\nThat's what makes it really powerful, that's why I like to embed `d2`\ndiagrams inside my org notes in such a way that I can always re-generate\nimages/diagrams on demmand. It's a small reproducible (research-like)\nenvironment that is very similar to the famous Jupyter Notebooks.\n\nOrg-mode extends Emacs with a simple and powerful markup language that turns it into a language for creating, parsing, and interacting with hierarchically-organized text documents. Its rich feature set includes text structuring, project management, and a publishing system that can export to a variety of formats. Source code and data are located in active blocks, distinct from text sections, where \"active\" here means that code and data blocks can be evaluated to return their contents or their computational results. The results of code block evaluation can be written to a named data block in the document, where it can be referred to by other code blocks, any one of which can be written in a different computing language. In this way, an Org-mode buffer becomes a place where different computer languages communicate with one another. Like Emacs, Org-mode is extensible: support for new languages can be added by the user in a modular fashion through the definition of a small number of Emacs Lisp functions.\n\n\nMarkdown can imitate pieces of this through extensions and external\ntools, but then the authoring model is the accidental intersection of a\nparticular parser, editor and plug-in collection. Org-mode's features\nbelong to the same **coherent system**. More importantly, they are\ninteractive in the editor instead of being instructions which only\nbecome meaningful after a build.\n\n# Pandoc as a boundary\n\nOne tempting approach would be to teach `blogatto` how to parse Org\ndirectly. I'll make sure to explore this in the long run and even push\nto the main repo. For now, `pandoc` already understands Org, already\nemits GitHub Flavored Markdown and already has a citation processor, so\nthe conversion stage can stay boring:\n\n```\npandoc -s org/posts/example.org \\\n  -t gfm \\\n  --citeproc \\\n  --bibliography=priv/bibtex/emacs.bib \\\n  -o blog/posts/example/index.md\n```\nThe real command is assembled by `src/convert.gleam`. It finds every Org\npage and post, adds all the BibLaTeX databases under `priv/bibtex` and\nwrites the Markdown into the directory structure Blogatto expects.\nConverted files are build products and are ignored by Git. The `org/`\ndirectory is the only source of truth.\n\nThere are three small Lua filters for the cases where a generic conversion is not quite enough:\n\n- `verse.lua` preserves Org verse blocks as structured HTML;\n- `bibliography.lua` keeps the generated references correctly grouped;\nand\n- `images.lua` translates file paths which make sense beside an Org\ndocument into paths which make sense on the published website.\n\n# Gleam, Blogatto and Lustre\n\nThe converter is a normal Gleam program: it creates output directories,\nskips files which are already up to date, invokes Pandoc and reports\nfailures as `Result` values. Once conversion finishes, Blogatto reads\nthe generated posts, builds their pages and RSS feed, and copies static\nassets into `dist/`. Lustre supplies the HTML elements used by the site\nlayout.\n\nThere is deliberately not much more to say. I could be using\nOrg-Publish to automate\nmost of this, but there are some *quality of life* features that I\nalways find it hard to make them work when generating **html** with it\n(syntax highlighting is just one of them).\n\n# Reproducibility with Nix\n\nNothing really changed here, Nix is still the ducktape that makes\neverything work. Entering `nix develop` provides `gleam`, `pandoc`,\n`make` and the other build-time dependencies.\nDevenv makes that shell pleasant to use\ninteractively, while the same flake reproduces the build environment\nwithout relying on whatever happens to be installed globally.\n\n```\n# ...\npackages = {\n  default = inputs'.nix-gleam.packages.buildGleamApplication {\n    src = ./.;\n    # `fs` (transitive dependency from blogatto -> filespy) builds a\n    # NIF using the `pc` rebar3 plugin, bundle it so pure builds don't\n    # hit hexpm.\n    rebar3Package = pkgs.rebar3WithPlugins {\n      plugins = with pkgs.beamPackages; [ pc ];\n    };\n  };\n};\n# nix fmt + nix flake check (auto-wired by flakeModule)\ntreefmt = {\n  projectRootFile = \"flake.nix\";\n  programs.gleam.enable = true;\n  programs.nixfmt.enable = true;\n};\ndevenv.shells.default = {\n  # ...\n  packages =\n    with pkgs;\n    [\n      gnumake\n      pandoc\n    ]\n    ++ lib.optionals stdenv.isLinux [ inotify-tools ]\n    ++ [ config.packages.default ];\n  languages.gleam = {\n    enable = true;\n  };\n  languages.lua = {\n    enable = true;\n    lsp.enable = true;\n  };\n  enterShell = ''\n    echo \"Starting Development Environment...\"\n  '';\n};\n# ...\n```\nFrom inside the development environment the complete build is intentionally mundane:\n\n```\nmake run\n# or\nmake dev\n```\n# Conclusion\n\nThis website has a (somewhat absurd) number of tools for a simple static page. Each one of these tools, however, has a narrow job. Org-mode holds the rich source document. Pandoc reduces it to a portable interchange format. Blogatto turns that format into a site. Gleam + Lustre give me a type-checked project that generates all the static html. Nix gives me a reproducible development environment.\n\nThe centre of the system is still Emacs, it's my (stubborn) decision to keep the act of writing, the structure of the document and the computations which support it all in one place. Org-mode is superior to Markdown for that job because it is a document model I can interact with while thinking.\n\n# Bibliography\n\n*UNIX-Hater Handbook*. IDG Books Worldwide, Inc.\n\n*The Computer Journal*27 (2): 97–111.\n\n*Journal of Statistical Software*46: 1–24.","body_html":"<h2 id=\"blogging-with-gleam-org-mode-and-pandoc\">Blogging with Gleam, Org-mode and Pandoc</h2>\n<p>01 Oct 2026</p>\n<p><em>Why the writing stays inside Emacs</em></p>\n<p>I’ve stumbled across a method of composing programs that excites me very much. In fact, my enthusiasm is so great that I must warn the reader to discount much of what I shall say as the ravings of a fanatic who thinks he has just seen a great light.</p>\n<p>Welcome to the first <strong>Byzantine Systems</strong> blog post. This is not my\nfirst attempt at building a website around Org-mode. I have already\nwritten about the road to Emacs\nmaximalism\nin my own personal blog, where Emacs, a few questionable scripts and Nix\nheld everything together. This time I wanted to keep the part that\nworked (writing everything in Emacs) while making the publishing side\nsmaller, typed and easier to understand.</p>\n<p>The end experiment uses the following tools:</p>\n<ul><li>Orgmode as the source format and Emacs as the writing environment.</li><li>d2 for making declarative diagrams.</li><li>Babel to make org even more powerful.</li><li>Pandoc as a robust, mature converter.</li><li>Nix, flakes and devenv to pin the build environment.</li><li>Gleam and Blogatto for a small, typed static-site pipeline.</li><li>Lustre for defining the surrounding HTML without introducing a separate template language.</li></ul>\n<p>The last two points look too overkill for a simple static page, but I&#39;ll let you jugde by way we create the page that lists all posts. It&#39;s just a Gleam function returning a Lustre element:</p>\n<p>The post index is ordinary, type-checked Gleam code.</p>\n<pre><code>pub fn posts_page(posts: List(Post(msg))) -&gt; Element(msg) {\n  let sorted = list.sort(posts, fn(a, b) { timestamp.compare(b.date, a.date) })\n  layout(&quot;Posts&quot;, [\n    html.h2([], [html.text(&quot;Posts&quot;)]),\n    case sorted {\n      [] -&gt; html.p([], [html.text(&quot;No posts yet.&quot;)])\n      _ -&gt; html.ul([], list.map(sorted, post_link))\n    },\n  ])\n}</code></pre>\n<p>The tl;dr version of this blogpost looks like this:</p>\n<p>One important detail, that previous diagram was generated inside Emacs,\nI want to keep the idea of &quot;diagrams as code&quot; alive, and for now <code>d2</code>\nhas been serving me well. This is what the diagram code looks like\nwithout the Emacs magic to keep only the result (the image).</p>\n<pre><code>direction: right\nstyle.fill: &quot;#ffffff&quot;\n# Default node styling\n*.shape: rectangle\n*.style: {\n  border-radius: 8\n  stroke-width: 2\n  font-size: 12\n}\n# Default edge styling\n(* -&gt; *)[*].style: {\n  stroke: &quot;#64748b&quot;\n  font-color: &quot;#475569&quot;\n  stroke-width: 2\n  font-size: 10\n}\nemacs: &quot;1. Emacs + Orgmode\\nWrite raw content (.org)&quot; {\n  style: {\n    fill: &quot;#f3e8ff&quot;\n    stroke: &quot;#a855f7&quot;\n    font-color: &quot;#581c87&quot;\n  }\n}\npandoc: &quot;2. Pandoc + plugins\\nConvert Org to Markdown (.md)&quot; {\n  style: {\n    fill: &quot;#e0f2fe&quot;\n    stroke: &quot;#0284c7&quot;\n    font-color: &quot;#075985&quot;\n  }\n}\nblogatto: &quot;3. Blogatto\\nGenerate final HTML&quot; {\n  style: {\n    fill: &quot;#dcfce7&quot;\n    stroke: &quot;#16a34a&quot;\n    font-color: &quot;#14532d&quot;\n  }\n}\nemacs -&gt; pandoc: Export\npandoc -&gt; blogatto: Build</code></pre>\n<h1 id=\"why-keep-everything-inside-emacs\">Why keep everything inside Emacs?</h1>\n<p>Moderately related, but my close friend Marcos\nMagueta made an interesting video called\nGNU Shepherd is the abstraction for a better computing\nage, there he argues about\n<strong>BLOAT</strong>, a word so despised in the UNIX world, but most people do so\nwithout:</p>\n<ul><li>Properly defining what <strong>BLOAT</strong> really is.</li><li>Without knowing waht <strong>GOOD BLOAT</strong> can give you.</li></ul>\n<p>Emacs, when taken from a UNIX philosophy perspective, is pure bloat.\nIndeed, Emacs does not follow UNIX&#39;s &quot;do one thing well&quot;. One can even\nargue that is is actually good, the lack of unified environment ends up\ncausing userland <strong>BLOAT</strong> anyway. By this very definition, Emacs would\nbe <em>good bloat</em>.</p>\n<p>Consistency requires a concentrated effort on the part of some central body that promulgates standards. Applications on the Macintosh are consistent because they follow a guidebook published by Apple. No such body has ever existed for Unix utilities. As a result, some utilities take their options preceded by a dash, some don’t. Some read standard input, some don’t. Some write standard output, some don’t. Some create files world writable, some don’t. Some report errors, some don’t. Some put a space between an option and a filename, some don’t.</p>\n<p>Also, leaving Emacs would be admiting defeat. Writing a blogpost (or notes) for me is more than just writing paragraphs. I like to put source code around, I sometimes like to export my notes to , I like having proper bibtex citations working at all times. If every one of those requires another application, the work becomes a tour of windows (or TUIs) which happen to contain fragments of the same idea. The long term goal is eventually moving everything inside Emacs, but that day is not today.</p>\n<h1 id=\"why-org-mode-instead-of-markdown\">Why Org-mode instead of Markdown?</h1>\n<p>(…) trivial usage of Org-mode is nothing more than text editing, from which point the user can start to add special plain text Org-mode elements to the document. Org-mode is therefore easy to adopt and aims to be a general solution for authoring projects with mixed computational and natural languages. It supports multiple programming languages, export targets, and work flows.</p>\n<p>We already have Markdown, right? It is ubiquitous, readable and\nsupported by almost every static-site generator. Indeed, this site uses\nthe Markdown <code>pandoc</code> creates it and <code>blogatto</code> consumes it. I just do\nnot write it directly.</p>\n<p>The reason being that Orgmode is a far superior format, whose only\ndownside is that you have to be inside Emacs to fully enjoy (and that\nseems like an okayish tradeoff). If you really want it, <code>.org</code> can stay\nas a simple lightweight markup format… or you can run arbitrary source\nblocks inside your org document, with custom command arguments and even\na place for the generated results.</p>\n<p>That&#39;s what makes it really powerful, that&#39;s why I like to embed <code>d2</code>\ndiagrams inside my org notes in such a way that I can always re-generate\nimages/diagrams on demmand. It&#39;s a small reproducible (research-like)\nenvironment that is very similar to the famous Jupyter Notebooks.</p>\n<p>Org-mode extends Emacs with a simple and powerful markup language that turns it into a language for creating, parsing, and interacting with hierarchically-organized text documents. Its rich feature set includes text structuring, project management, and a publishing system that can export to a variety of formats. Source code and data are located in active blocks, distinct from text sections, where &quot;active&quot; here means that code and data blocks can be evaluated to return their contents or their computational results. The results of code block evaluation can be written to a named data block in the document, where it can be referred to by other code blocks, any one of which can be written in a different computing language. In this way, an Org-mode buffer becomes a place where different computer languages communicate with one another. Like Emacs, Org-mode is extensible: support for new languages can be added by the user in a modular fashion through the definition of a small number of Emacs Lisp functions.</p>\n<p>Markdown can imitate pieces of this through extensions and external\ntools, but then the authoring model is the accidental intersection of a\nparticular parser, editor and plug-in collection. Org-mode&#39;s features\nbelong to the same <strong>coherent system</strong>. More importantly, they are\ninteractive in the editor instead of being instructions which only\nbecome meaningful after a build.</p>\n<h1 id=\"pandoc-as-a-boundary\">Pandoc as a boundary</h1>\n<p>One tempting approach would be to teach <code>blogatto</code> how to parse Org\ndirectly. I&#39;ll make sure to explore this in the long run and even push\nto the main repo. For now, <code>pandoc</code> already understands Org, already\nemits GitHub Flavored Markdown and already has a citation processor, so\nthe conversion stage can stay boring:</p>\n<pre><code>pandoc -s org/posts/example.org \\\n  -t gfm \\\n  --citeproc \\\n  --bibliography=priv/bibtex/emacs.bib \\\n  -o blog/posts/example/index.md</code></pre>\n<p>The real command is assembled by <code>src/convert.gleam</code>. It finds every Org\npage and post, adds all the BibLaTeX databases under <code>priv/bibtex</code> and\nwrites the Markdown into the directory structure Blogatto expects.\nConverted files are build products and are ignored by Git. The <code>org/</code>\ndirectory is the only source of truth.</p>\n<p>There are three small Lua filters for the cases where a generic conversion is not quite enough:</p>\n<ul><li><code>verse.lua</code> preserves Org verse blocks as structured HTML;</li><li><p><code>bibliography.lua</code> keeps the generated references correctly grouped;</p><p>and</p></li><li><p><code>images.lua</code> translates file paths which make sense beside an Org</p><p>document into paths which make sense on the published website.</p></li></ul>\n<h1 id=\"gleam-blogatto-and-lustre\">Gleam, Blogatto and Lustre</h1>\n<p>The converter is a normal Gleam program: it creates output directories,\nskips files which are already up to date, invokes Pandoc and reports\nfailures as <code>Result</code> values. Once conversion finishes, Blogatto reads\nthe generated posts, builds their pages and RSS feed, and copies static\nassets into <code>dist/</code>. Lustre supplies the HTML elements used by the site\nlayout.</p>\n<p>There is deliberately not much more to say. I could be using\nOrg-Publish to automate\nmost of this, but there are some <em>quality of life</em> features that I\nalways find it hard to make them work when generating <strong>html</strong> with it\n(syntax highlighting is just one of them).</p>\n<h1 id=\"reproducibility-with-nix\">Reproducibility with Nix</h1>\n<p>Nothing really changed here, Nix is still the ducktape that makes\neverything work. Entering <code>nix develop</code> provides <code>gleam</code>, <code>pandoc</code>,\n<code>make</code> and the other build-time dependencies.\nDevenv makes that shell pleasant to use\ninteractively, while the same flake reproduces the build environment\nwithout relying on whatever happens to be installed globally.</p>\n<pre><code># ...\npackages = {\n  default = inputs&#39;.nix-gleam.packages.buildGleamApplication {\n    src = ./.;\n    # `fs` (transitive dependency from blogatto -&gt; filespy) builds a\n    # NIF using the `pc` rebar3 plugin, bundle it so pure builds don&#39;t\n    # hit hexpm.\n    rebar3Package = pkgs.rebar3WithPlugins {\n      plugins = with pkgs.beamPackages; [ pc ];\n    };\n  };\n};\n# nix fmt + nix flake check (auto-wired by flakeModule)\ntreefmt = {\n  projectRootFile = &quot;flake.nix&quot;;\n  programs.gleam.enable = true;\n  programs.nixfmt.enable = true;\n};\ndevenv.shells.default = {\n  # ...\n  packages =\n    with pkgs;\n    [\n      gnumake\n      pandoc\n    ]\n    ++ lib.optionals stdenv.isLinux [ inotify-tools ]\n    ++ [ config.packages.default ];\n  languages.gleam = {\n    enable = true;\n  };\n  languages.lua = {\n    enable = true;\n    lsp.enable = true;\n  };\n  enterShell = &#39;&#39;\n    echo &quot;Starting Development Environment...&quot;\n  &#39;&#39;;\n};\n# ...</code></pre>\n<p>From inside the development environment the complete build is intentionally mundane:</p>\n<pre><code>make run\n# or\nmake dev</code></pre>\n<h1 id=\"conclusion\">Conclusion</h1>\n<p>This website has a (somewhat absurd) number of tools for a simple static page. Each one of these tools, however, has a narrow job. Org-mode holds the rich source document. Pandoc reduces it to a portable interchange format. Blogatto turns that format into a site. Gleam + Lustre give me a type-checked project that generates all the static html. Nix gives me a reproducible development environment.</p>\n<p>The centre of the system is still Emacs, it&#39;s my (stubborn) decision to keep the act of writing, the structure of the document and the computations which support it all in one place. Org-mode is superior to Markdown for that job because it is a document model I can interact with while thinking.</p>\n<h1 id=\"bibliography\">Bibliography</h1>\n<p><em>UNIX-Hater Handbook</em>. IDG Books Worldwide, Inc.</p>\n<p><em>The Computer Journal</em>27 (2): 97–111.</p>\n<p><em>Journal of Statistical Software</em>46: 1–24.</p>","headings":[{"level":2,"text":"Blogging with Gleam, Org-mode and Pandoc","id":"blogging-with-gleam-org-mode-and-pandoc"},{"level":1,"text":"Why keep everything inside Emacs?","id":"why-keep-everything-inside-emacs"},{"level":1,"text":"Why Org-mode instead of Markdown?","id":"why-org-mode-instead-of-markdown"},{"level":1,"text":"Pandoc as a boundary","id":"pandoc-as-a-boundary"},{"level":1,"text":"Gleam, Blogatto and Lustre","id":"gleam-blogatto-and-lustre"},{"level":1,"text":"Reproducibility with Nix","id":"reproducibility-with-nix"},{"level":1,"text":"Conclusion","id":"conclusion"},{"level":1,"text":"Bibliography","id":"bibliography"}]}}