De auteur beschrijft een technische workflow voor het publiceren van een statische website, waarbij de focus ligt op reproduceerbaarheid en een krachtige auteurservaring. In plaats van Markdown te gebruiken als bron, kiest de auteur voor Org-mode binnen Emacs vanwege de superieure functies voor literate programming en de mogelijkheid om interactieve codeblokken (zoals d2-diagrammen) direct in het document te beheren.
De pipeline is als volgt opgebouwd:
- Bron: Org-mode documenten in Emacs.
- Conversie: Pandoc zet Org-bestanden om naar GitHub Flavored Markdown, inclusief citatieverwerking via BibTeX.
- Generatie: Een in Gleam geschreven programma, gebruikmakend van Blogatto en Lustre, transformeert de Markdown naar type-safe HTML.
- Infrastructuur: Nix (via flakes en devenv) zorgt ervoor dat de gehele build-omgeving en alle afhankelijkheden consistent en reproduceerbaar zijn.
De auteur beargumenteert dat het centraliseren van het proces in Emacs "goede bloat" is, omdat het voorkomt dat de schrijver moet schakelen tussen verschillende applicaties voor code, citaties en tekst.
Bloggen met Gleam, Org-mode en Pandoc
Ik ben op een methode voor het componeren van programma's gestuit die me zeer enthousiasmeert. Sterker nog, mijn enthousiasme is zo groot dat ik de lezer moet waarschuwen om veel van wat ik zal zeggen te beschouwen als het gezinnige gepraat van een fanaticus die denkt zojuist een groot licht te hebben gezien.
(Knuth 1984, 1)
Het uiteindelijke experiment maakt gebruik van de volgende instrumenten:
- Org-mode als bronformaat en Emacs als schrijvomgeving.
- d2 voor het maken van declaratieve diagrammen.
- Babel om Org nog krachtiger te maken.
- Pandoc als een robuuste, volwassen converter.
- Nix, flakes en devenv om de build-omgeving vast te leggen.
- Gleam en Blogatto voor een kleine, typed static-site pipeline.
- Lustre voor het definiëren van de omringende HTML zonder een aparte template-taal te introduceren.
De laatste twee punten lijken wellicht overbodig voor een eenvoudige statische pagina, maar ik laat u oordelen aan de hand van de manier waarop we de pagina maken die alle berichtentjes opsomt. Het is simpelweg een Gleam-functie die een Lustre-element retourneert:
De post-index is normale, type-checked Gleam-code.
pub fn posts_page(posts: List(Post(msg))) -> Element(msg) {
let sorted = list.sort(posts, fn(a, b) { timestamp.compare(b.date, a.date) })
layout("Posts", [
html.h2([], [html.text("Posts")]),
case sorted {
[] -> html.p([], [html.text("No posts yet.")])
_ -> html.ul([], list.map(sorted, post_link))
},
])
}
De tl;dr-versie van dit blogbericht is als volgt: ik interacteer alleen met de Org-documenten. Nix is de lijm die de rest van de pipeline aangenaam ongecompliceerd maakt.
Een belangrijk detail: het vorige diagram werd gegenereerd binnen Emacs. Ik wil het idee van "diagrammen als code" levend houden, en voorlopig dient d2 mij goed. Dit is hoe de diagramcode eruitziet zonder de Emacs-magie die alleen het resultaat (de afbeelding) behoudt:
direction: right
style.fill: "#ffffff"
# Default node styling
*.shape: rectangle
*.style: {
border-radius: 8
stroke-width: 2
font-size: 12
}
# Default edge styling
(* -> *)[*].style: {
stroke: "#64748b"
font-color: "#475569"
stroke-width: 2
font-size: 10
}
emacs: "1. Emacs + Orgmode\nWrite raw content (.org)" {
style: {
fill: "#f3e8ff"
stroke: "#a855f7"
font-color: "#581c87"
}
}
pandoc: "2. Pandoc + plugins\nConvert Org to Markdown (.md)" {
style: {
fill: "#e0f2fe"
stroke: "#0284c7"
font-color: "#075985"
}
}
blogatto: "3. Blogatto\nGenerate final HTML" {
style: {
fill: "#dcfce7"
stroke: "#16a34a"
font-color: "#14532d"
}
}
emacs -> pandoc: Export
pandoc -> blogatto: Build
Waarom alles binnen Emacs houden?
In een verwante context heeft mijn goede vriend Marcos Magueta een interessante video gemaakt genaamd GNU Shepherd is the abstraction for a better computing age. Daarin betoogt hij over BLOAT, een woord dat in de UNIX-wereld zeer veracht wordt, maar dat de meeste mensen doen zonder:
- Correct te definiëren wat BLOAT werkelijk is.
- Te weten wat GOEDE BLOAT je kan opleveren.
Emacs is, wanneer bekeken vanuit een UNIX-filosofie, pure bloat. Indeed, Emacs volgt niet het UNIX-principe van "één ding goed doen". Men zou zelfs kunnen beweren dat dit juist goed is; het gebrek aan een uniforme omgeving veroorzaakt uiteindelijk toch BLOAT in de gebruikerslaag. Volgens deze definitie zou Emacs "goede bloat" zijn.
Consistentie vereist een geconcentreerde inspanning van een centraal orgaan dat standaarden uitvaardigt. Applicaties op de Macintosh zijn consistent omdat ze een gids volgen die is gepubliceerd door Apple. Een dergelijk orgaan heeft voor Unix-utilities nooit bestaan. Als gevolg daarvan nemen sommige utilities hun opties voorafgegaan door een streepje, andere niet. Sommige lezen standaard input, andere niet. Sommige schrijven standaard output, andere niet. Sommige maken bestanden wereldwijd beschrijfbaar, andere niet. Sommige rapporteren fouten, andere niet. Sommige plaatsen een spatie tussen een optie en een bestandsnaam, andere niet.
(Garfinkle, Weise, and Strassmann 1994, 25–26 chap.2)
Daarnaast zou het verlaten van Emacs aanvoelen als een nederlaag. Het schrijven van een blogpost (of notities) is voor mij meer dan alleen het schrijven van paragrafen. Ik vind het fijn om broncode toe te voegen, ik exporteer soms mijn notities, en ik wil dat proper BibTeX-citaties altijd werken. Als elk van deze zaken een aparte applicatie vereist, wordt het werk een tournee langs vensters (of TUI's) die toevallig fragmenten van hetzelfde idee bevatten. Het langetermijndoel is om uiteindelijk alles naar Emacs te verplaatsen, maar die dag is niet vandaag.
Waarom Org-mode in plaats van Markdown?
(...) triviaal gebruik van Org-mode is niets meer dan tekstbewerking, van waaruit de gebruiker speciale plain text Org-mode elementen aan het document kan toevoegen. Org-mode is daarom gemakkelijk te adopteren en streeft ernaar een algemene oplossing te zijn voor het auteurswerk van projecten met gemengde computationele en natuurlijke talen. Het ondersteunt meerdere programmeertalen, exportdoelen en workflows.
(Schulte et al. 2012, 2)
We hebben al Markdown, toch? Het is overal aanwezig, leesbaar en wordt ondersteund door bijna elke static-site generator. Sterker nog, deze site gebruikt de Markdown die Pandoc creëert en Blogatto consumeert. Ik schrijf het alleen niet direct.
De reden hiervoor is dat Org-mode een superieur formaat is, waarvan het enige nadeel is dat je in Emacs moet zitten om er volledig van te genieten (en dat lijkt me een acceptabele afweging). Als je dat echt wilt, kan .org een simpel, lichtgewicht markup-formaat blijven... of je kunt willekeurige broncodeblokken in je Org-document uitvoeren, met aangepaste commando-argumenten en zelfs een plek voor de gegenereerde resultaten.
Dat is wat het echt krachtig maakt; dat is waarom ik d2-diagrammen in mijn Org-notities embed, zodat ik afbeeldingen/diagrammen altijd op aanvraag kan regenereren. Het is een kleine, reproduceerbare (onderzoek-achtige) omgeving die zeer vergelijkbaar is met de bekende Jupyter Notebooks.
Org-mode breidt Emacs uit met een eenvoudige en krachtige markup-taal die het transformeert in een taal voor het creëren, parsen en interageren met hiërarchisch georganiseerde tekstdocumenten. De rijke functies omvatten tekststructurering, projectbeheer en een publicatiesysteem dat kan exporteren naar diverse formaten. Broncode en data bevinden zich in actieve blokken, gescheiden van tekstsecties, waarbij "actief" betekent dat code- en datablokken kunnen worden uitgevoerd om hun inhoud of computationele resultaten terug te geven. De resultaten van codeblok-evaluaties kunnen worden geschreven naar een benoemd datablok in het document, waar ze kunnen worden aangeroepen door andere codeblokken, elk geschreven in een verschillende computertaal. Op deze manier wordt een Org-mode buffer een plek waar verschillende computertalen met elkaar communiceren. Net als Emacs is Org-mode uitbreidbaar: ondersteuning voor nieuwe talen kan door de gebruiker modulair worden toegevoegd via de definitie van een klein aantal Emacs Lisp-functies.
(Schulte et al. 2012, 7)
Markdown kan delen hiervan imiteren via extensies en externe tools, maar dan is het auteurmodel het toevallige snijvlak van een specifieke parser, editor en plug-in collectie. De functies van Org-mode behoren tot hetzelfde coherente systeem. Belangrijker is dat ze interactief zijn in de editor, in plaats van instructies die pas betekenis krijgen na een build.
Pandoc als grens
Een verleidelijke aanpak zou zijn om Blogatto te leren hoe het Org direct moet parsen. Ik zal dit op de lange termijn zeker onderzoeken en eventueel naar de hoofd-repo pushen. Voor nu begrijpt Pandoc al Org, genereert het GitHub Flavored Markdown en heeft het een citatie-processor, waardoor de conversiefase ongecompliceerd blijft:
pandoc -s org/posts/example.org \
-t gfm \
--citeproc \
--bibliography=priv/bibtex/emacs.bib \
-o blog/posts/example/index.md
Het werkelijke commando wordt samengesteld door src/convert.gleam. Het zoekt elke Org-pagina en post, voegt alle BibLaTeX-databases onder priv/bibtex toe en schrijft de Markdown in de mappenstructuur die Blogatto verwacht. Geconverteerde bestanden zijn build-producten en worden genegeerd door Git. De org/ directory is de enige bron van waarheid.
Er zijn drie kleine Lua-filters voor gevallen waarin een generieke conversie niet voldoende is:
verse.lua behoudt Org-versblokken als gestructureerde HTML;
bibliography.lua houdt de gegenereerde referenties correct gegroepeerd;
images.lua vertaalt bestandspaden die logisch zijn naast een Org-document naar paden die logisch zijn op de gepubliceerde website.
Gleam, Blogatto en Lustre
De converter is een normaal Gleam-programma: het maakt output-mappen aan, slaat bestanden over die al up-to-date zijn, roept Pandoc aan en rapporteert fouten als Result-waarden. Zodra de conversie is voltooid, leest Blogatto de gegenereerde posts, bouwt hun pagina's en RSS-feed, en kopieert statische assets naar dist/. Lustre levert de HTML-elementen die worden gebruikt door de site-layout.
Er is bewust niet veel meer over te zeggen. Ik zou Org-Publish kunnen gebruiken om het grootste deel hiervan te automatiseren, maar er zijn enkele quality of life functies die ik altijd lastig vind om werkend te krijgen bij het genereren van HTML (syntax-highlighting is er slechts één van).
Reproduceerbaarheid met Nix
Hier is niets wezenlijk veranderd; Nix is nog steeds de ducttape die alles laat werken. Het uitvoeren van nix develop biedt Gleam, Pandoc, Make en de andere build-time afhankelijkheden.
Devenv maakt die shell prettig om interactief te gebruiken, terwijl dezelfde flake de build-omgeving reproduceert zonder afhankelijk te zijn van wat er toevallig globaal is geïnstalleerd.
# ...
packages = {
default = inputs'.nix-gleam.packages.buildGleamApplication {
src = ./.;
# `fs` (transitive dependency from blogatto -> filespy) builds a
# NIF using the `pc` rebar3 plugin, bundle it so pure builds don't
# hit hexpm.
rebar3Package = pkgs.rebar3WithPlugins {
plugins = with pkgs.beamPackages; [ pc ];
};
};
};
# nix fmt + nix flake check (auto-wired by flakeModule)
treefmt = {
projectRootFile = "flake.nix";
programs.gleam.enable = true;
programs.nixfmt.enable = true;
};
devenv.shells.default = {
# ...
packages =
with pkgs;
[
gnumake
pandoc
]
++ lib.optionals stdenv.isLinux [ inotify-tools ]
++ [ config.packages.default ];
languages.gleam = {
enable = true;
};
languages.lua = {
enable = true;
lsp.enable = true;
};
enterShell = ''
echo "Starting Development Environment..."
'';
};
# ...
Vanuit de ontwikkelomgeving is de volledige build bewust banaal:
make run
# of
make dev
Conclusie
Deze website heeft een (sommig absurd) aantal tools voor een eenvoudige statische pagina. Elk van deze tools heeft echter een specifieke, beperkte taak. Org-mode bewaart het rijke brondocument. Pandoc reduceert dit tot een draagbaar uitwisselingsformaat. Blogatto zet dat formaat om in een site. Gleam + Lustre geven me een type-checked project dat alle statische HTML genereert. Nix geeft me een reproduceerbare ontwikkelomgeving.
Het centrum van het systeem is nog steeds Emacs; het is mijn (koppige) beslissing om de handeling van het schrijven, de structuur van het document en de berekeningen die dit ondersteunen allemaal op één plek te houden. Org-mode is superieur aan Markdown voor die taak, omdat het een documentmodel is waarmee ik kan interageren terwijl ik nadenk.
Bibliografie
- Garfinkle, Simson, Daniel Weise, and Steven Strassmann. 1994. UNIX-Hater Handbook. IDG Books Worldwide, Inc.
- Knuth, Donald Ervin. 1984. “Literate Programming.” The Computer Journal 27 (2): 97–111.
- Schulte, Eric, Dan Davison, Thomas Dye, and Carsten Dominik. 2012. “A Multi-Language Computing Environment for Literate Programming and Reproducible Research.” Journal of Statistical Software 46: 1–24.
Bloggen met Gleam, Org-mode en Pandoc
Ik ben op een methode voor het componeren van programma's gestuit die me zeer enthousiasmeert. Sterker nog, mijn enthousiasme is zo groot dat ik de lezer moet waarschuwen om veel van wat ik zal zeggen te beschouwen als het gezinnige gepraat van een fanaticus die denkt zojuist een groot licht te hebben gezien.
(Knuth 1984, 1)
Het uiteindelijke experiment maakt gebruik van de volgende instrumenten:
- Org-mode als bronformaat en Emacs als schrijvomgeving.
- d2 voor het maken van declaratieve diagrammen.
- Babel om Org nog krachtiger te maken.
- Pandoc als een robuuste, volwassen converter.
- Nix, flakes en devenv om de build-omgeving vast te leggen.
- Gleam en Blogatto voor een kleine, typed static-site pipeline.
- Lustre voor het definiëren van de omringende HTML zonder een aparte template-taal te introduceren.
De laatste twee punten lijken wellicht overbodig voor een eenvoudige statische pagina, maar ik laat u oordelen aan de hand van de manier waarop we de pagina maken die alle berichtentjes opsomt. Het is simpelweg een Gleam-functie die een Lustre-element retourneert:
De post-index is normale, type-checked Gleam-code.
pub fn posts_page(posts: List(Post(msg))) -> Element(msg) {
let sorted = list.sort(posts, fn(a, b) { timestamp.compare(b.date, a.date) })
layout("Posts", [
html.h2([], [html.text("Posts")]),
case sorted {
[] -> html.p([], [html.text("No posts yet.")])
_ -> html.ul([], list.map(sorted, post_link))
},
])
}
De tl;dr-versie van dit blogbericht is als volgt: ik interacteer alleen met de Org-documenten. Nix is de lijm die de rest van de pipeline aangenaam ongecompliceerd maakt.
Een belangrijk detail: het vorige diagram werd gegenereerd binnen Emacs. Ik wil het idee van "diagrammen als code" levend houden, en voorlopig dient d2 mij goed. Dit is hoe de diagramcode eruitziet zonder de Emacs-magie die alleen het resultaat (de afbeelding) behoudt:
direction: right
style.fill: "#ffffff"
# Default node styling
*.shape: rectangle
*.style: {
border-radius: 8
stroke-width: 2
font-size: 12
}
# Default edge styling
(* -> *)[*].style: {
stroke: "#64748b"
font-color: "#475569"
stroke-width: 2
font-size: 10
}
emacs: "1. Emacs + Orgmode\nWrite raw content (.org)" {
style: {
fill: "#f3e8ff"
stroke: "#a855f7"
font-color: "#581c87"
}
}
pandoc: "2. Pandoc + plugins\nConvert Org to Markdown (.md)" {
style: {
fill: "#e0f2fe"
stroke: "#0284c7"
font-color: "#075985"
}
}
blogatto: "3. Blogatto\nGenerate final HTML" {
style: {
fill: "#dcfce7"
stroke: "#16a34a"
font-color: "#14532d"
}
}
emacs -> pandoc: Export
pandoc -> blogatto: Build
Waarom alles binnen Emacs houden?
In een verwante context heeft mijn goede vriend Marcos Magueta een interessante video gemaakt genaamd GNU Shepherd is the abstraction for a better computing age. Daarin betoogt hij over BLOAT, een woord dat in de UNIX-wereld zeer veracht wordt, maar dat de meeste mensen doen zonder:
- Correct te definiëren wat BLOAT werkelijk is.
- Te weten wat GOEDE BLOAT je kan opleveren.
Emacs is, wanneer bekeken vanuit een UNIX-filosofie, pure bloat. Indeed, Emacs volgt niet het UNIX-principe van "één ding goed doen". Men zou zelfs kunnen beweren dat dit juist goed is; het gebrek aan een uniforme omgeving veroorzaakt uiteindelijk toch BLOAT in de gebruikerslaag. Volgens deze definitie zou Emacs "goede bloat" zijn.
Consistentie vereist een geconcentreerde inspanning van een centraal orgaan dat standaarden uitvaardigt. Applicaties op de Macintosh zijn consistent omdat ze een gids volgen die is gepubliceerd door Apple. Een dergelijk orgaan heeft voor Unix-utilities nooit bestaan. Als gevolg daarvan nemen sommige utilities hun opties voorafgegaan door een streepje, andere niet. Sommige lezen standaard input, andere niet. Sommige schrijven standaard output, andere niet. Sommige maken bestanden wereldwijd beschrijfbaar, andere niet. Sommige rapporteren fouten, andere niet. Sommige plaatsen een spatie tussen een optie en een bestandsnaam, andere niet.
(Garfinkle, Weise, and Strassmann 1994, 25–26 chap.2)
Daarnaast zou het verlaten van Emacs aanvoelen als een nederlaag. Het schrijven van een blogpost (of notities) is voor mij meer dan alleen het schrijven van paragrafen. Ik vind het fijn om broncode toe te voegen, ik exporteer soms mijn notities, en ik wil dat proper BibTeX-citaties altijd werken. Als elk van deze zaken een aparte applicatie vereist, wordt het werk een tournee langs vensters (of TUI's) die toevallig fragmenten van hetzelfde idee bevatten. Het langetermijndoel is om uiteindelijk alles naar Emacs te verplaatsen, maar die dag is niet vandaag.
Waarom Org-mode in plaats van Markdown?
(...) triviaal gebruik van Org-mode is niets meer dan tekstbewerking, van waaruit de gebruiker speciale plain text Org-mode elementen aan het document kan toevoegen. Org-mode is daarom gemakkelijk te adopteren en streeft ernaar een algemene oplossing te zijn voor het auteurswerk van projecten met gemengde computationele en natuurlijke talen. Het ondersteunt meerdere programmeertalen, exportdoelen en workflows.
(Schulte et al. 2012, 2)
We hebben al Markdown, toch? Het is overal aanwezig, leesbaar en wordt ondersteund door bijna elke static-site generator. Sterker nog, deze site gebruikt de Markdown die Pandoc creëert en Blogatto consumeert. Ik schrijf het alleen niet direct.
De reden hiervoor is dat Org-mode een superieur formaat is, waarvan het enige nadeel is dat je in Emacs moet zitten om er volledig van te genieten (en dat lijkt me een acceptabele afweging). Als je dat echt wilt, kan .org een simpel, lichtgewicht markup-formaat blijven... of je kunt willekeurige broncodeblokken in je Org-document uitvoeren, met aangepaste commando-argumenten en zelfs een plek voor de gegenereerde resultaten.
Dat is wat het echt krachtig maakt; dat is waarom ik d2-diagrammen in mijn Org-notities embed, zodat ik afbeeldingen/diagrammen altijd op aanvraag kan regenereren. Het is een kleine, reproduceerbare (onderzoek-achtige) omgeving die zeer vergelijkbaar is met de bekende Jupyter Notebooks.
Org-mode breidt Emacs uit met een eenvoudige en krachtige markup-taal die het transformeert in een taal voor het creëren, parsen en interageren met hiërarchisch georganiseerde tekstdocumenten. De rijke functies omvatten tekststructurering, projectbeheer en een publicatiesysteem dat kan exporteren naar diverse formaten. Broncode en data bevinden zich in actieve blokken, gescheiden van tekstsecties, waarbij "actief" betekent dat code- en datablokken kunnen worden uitgevoerd om hun inhoud of computationele resultaten terug te geven. De resultaten van codeblok-evaluaties kunnen worden geschreven naar een benoemd datablok in het document, waar ze kunnen worden aangeroepen door andere codeblokken, elk geschreven in een verschillende computertaal. Op deze manier wordt een Org-mode buffer een plek waar verschillende computertalen met elkaar communiceren. Net als Emacs is Org-mode uitbreidbaar: ondersteuning voor nieuwe talen kan door de gebruiker modulair worden toegevoegd via de definitie van een klein aantal Emacs Lisp-functies.
(Schulte et al. 2012, 7)
Markdown kan delen hiervan imiteren via extensies en externe tools, maar dan is het auteurmodel het toevallige snijvlak van een specifieke parser, editor en plug-in collectie. De functies van Org-mode behoren tot hetzelfde coherente systeem. Belangrijker is dat ze interactief zijn in de editor, in plaats van instructies die pas betekenis krijgen na een build.
Pandoc als grens
Een verleidelijke aanpak zou zijn om Blogatto te leren hoe het Org direct moet parsen. Ik zal dit op de lange termijn zeker onderzoeken en eventueel naar de hoofd-repo pushen. Voor nu begrijpt Pandoc al Org, genereert het GitHub Flavored Markdown en heeft het een citatie-processor, waardoor de conversiefase ongecompliceerd blijft:
pandoc -s org/posts/example.org \
-t gfm \
--citeproc \
--bibliography=priv/bibtex/emacs.bib \
-o blog/posts/example/index.md
Het werkelijke commando wordt samengesteld door src/convert.gleam. Het zoekt elke Org-pagina en post, voegt alle BibLaTeX-databases onder priv/bibtex toe en schrijft de Markdown in de mappenstructuur die Blogatto verwacht. Geconverteerde bestanden zijn build-producten en worden genegeerd door Git. De org/ directory is de enige bron van waarheid.
Er zijn drie kleine Lua-filters voor gevallen waarin een generieke conversie niet voldoende is:
verse.lua behoudt Org-versblokken als gestructureerde HTML;
bibliography.lua houdt de gegenereerde referenties correct gegroepeerd;
images.lua vertaalt bestandspaden die logisch zijn naast een Org-document naar paden die logisch zijn op de gepubliceerde website.
Gleam, Blogatto en Lustre
De converter is een normaal Gleam-programma: het maakt output-mappen aan, slaat bestanden over die al up-to-date zijn, roept Pandoc aan en rapporteert fouten als Result-waarden. Zodra de conversie is voltooid, leest Blogatto de gegenereerde posts, bouwt hun pagina's en RSS-feed, en kopieert statische assets naar dist/. Lustre levert de HTML-elementen die worden gebruikt door de site-layout.
Er is bewust niet veel meer over te zeggen. Ik zou Org-Publish kunnen gebruiken om het grootste deel hiervan te automatiseren, maar er zijn enkele quality of life functies die ik altijd lastig vind om werkend te krijgen bij het genereren van HTML (syntax-highlighting is er slechts één van).
Reproduceerbaarheid met Nix
Hier is niets wezenlijk veranderd; Nix is nog steeds de ducttape die alles laat werken. Het uitvoeren van nix develop biedt Gleam, Pandoc, Make en de andere build-time afhankelijkheden.
Devenv maakt die shell prettig om interactief te gebruiken, terwijl dezelfde flake de build-omgeving reproduceert zonder afhankelijk te zijn van wat er toevallig globaal is geïnstalleerd.
# ...
packages = {
default = inputs'.nix-gleam.packages.buildGleamApplication {
src = ./.;
# `fs` (transitive dependency from blogatto -> filespy) builds a
# NIF using the `pc` rebar3 plugin, bundle it so pure builds don't
# hit hexpm.
rebar3Package = pkgs.rebar3WithPlugins {
plugins = with pkgs.beamPackages; [ pc ];
};
};
};
# nix fmt + nix flake check (auto-wired by flakeModule)
treefmt = {
projectRootFile = "flake.nix";
programs.gleam.enable = true;
programs.nixfmt.enable = true;
};
devenv.shells.default = {
# ...
packages =
with pkgs;
[
gnumake
pandoc
]
++ lib.optionals stdenv.isLinux [ inotify-tools ]
++ [ config.packages.default ];
languages.gleam = {
enable = true;
};
languages.lua = {
enable = true;
lsp.enable = true;
};
enterShell = ''
echo "Starting Development Environment..."
'';
};
# ...
Vanuit de ontwikkelomgeving is de volledige build bewust banaal:
make run
# of
make dev
Conclusie
Deze website heeft een (sommig absurd) aantal tools voor een eenvoudige statische pagina. Elk van deze tools heeft echter een specifieke, beperkte taak. Org-mode bewaart het rijke brondocument. Pandoc reduceert dit tot een draagbaar uitwisselingsformaat. Blogatto zet dat formaat om in een site. Gleam + Lustre geven me een type-checked project dat alle statische HTML genereert. Nix geeft me een reproduceerbare ontwikkelomgeving.
Het centrum van het systeem is nog steeds Emacs; het is mijn (koppige) beslissing om de handeling van het schrijven, de structuur van het document en de berekeningen die dit ondersteunen allemaal op één plek te houden. Org-mode is superieur aan Markdown voor die taak, omdat het een documentmodel is waarmee ik kan interageren terwijl ik nadenk.
Bibliografie
- Garfinkle, Simson, Daniel Weise, and Steven Strassmann. 1994. UNIX-Hater Handbook. IDG Books Worldwide, Inc.
- Knuth, Donald Ervin. 1984. “Literate Programming.” The Computer Journal 27 (2): 97–111.
- Schulte, Eric, Dan Davison, Thomas Dye, and Carsten Dominik. 2012. “A Multi-Language Computing Environment for Literate Programming and Reproducible Research.” Journal of Statistical Software 46: 1–24.