In dit artikel beschrijft de auteur hoe hij een versie van zijn website heeft ontwikkeld die specifiek bedoeld is voor weergave in de terminal via curl.
De belangrijkste technische aspecten zijn:
- ANSI-opmaak: Voor de styling is gebruikgemaakt van ANSI-escapecodes. Sommige pagina's zijn handmatig geschreven, waarbij de auteur referentie maakte aan Wikipedia en Gopher-pagina's.
- Automatisering met Gemroff: De auteur maakt gebruik van een eigen opmaaktaal en static site generator (SSG) genaamd Gemroff. Omdat deze SSG modulair is en meerdere outputformaten ondersteunt, konden blogberichten automatisch worden omgezet naar ANSI-tekst.
- Serverconfiguratie: Via Nginx is de server zo ingesteld dat gebruikers met een
curl user-agent automatisch de ANSI-versie ontvangen, met de mogelijkheid om via een specifieke header (X-Original: true) alsnog de standaard HTTP-respons op te vragen.
Fancy Curl-sites
Een tijdje geleden heb ik een leuke curl-versie van mijn site toegevoegd, bedoeld om in de terminal te bekijken. Probeer deze commando's eens uit:
curl nytpu.com/gemlog/2026-03-18
# of
curl nytpu.com
(Excuses aan de Windows-gebruikers; het is niet mijn schuld dat ANSI-escapecodes standaard zijn uitgeschakeld in cmd.exe. En het is ook niet mijn schuld dat je in Powershell curl.exe moet gebruiken in plaats van curl, omdat Powershell dat onverklaarbaar heeft gekoppeld aan Invoke-WebRequest.)
Ik heb hier kort over gepost op het Fediverse, maar ik ben er verder niet dieper op ingegaan omdat ik dacht dat het vrij zelfverklarend was. Maar een handvol mensen heeft me gevraagd hoe ik het heb gedaan, dus ik besloot dat het waarschijnlijk de moeite waard was om een bericht te schrijven over mijn aanpak (…zo'n zeven maanden te laat).
Ik moet vermelden dat dit idee voortkomt uit de curl-sites van trinkey (curl trinkey.com) en strongsand (curl proot.party); ik heb het niet zelf bedacht. Hoewel ik het heel anders heb aangepakt dan zij, gaat alle eer voor dit coole idee naar hen. (UPDATE: helaas zijn beide curl-versies sinds 14-10-2026 niet meer functioneel.)
Het genereren van ANSI-bestanden
Ten eerste, omdat dit het meest interessante deel is: het genereren van de bestanden met ANSI-opmaak die naar de clients worden gestuurd. De indexpagina en de 'over mij'-pagina heb ik volledig handmatig geschreven.
Ik vermoed dat trinkey en strongsand die van hen on-the-fly genereren met de ratatui-bibliotheek (of iets soortgelijks), wat waarschijnlijk handiger is; voor mij leek handmatig schrijven echter sneller.
Ik had de belangrijkste escapecode—ESC[, oftewel \x1b[—in een Vim-register geplaatst om deze gemakkelijk te kunnen plakken wanneer nodig, en ik hield de Wikipedia-pagina voor de belangrijkste grafische codes open als referentie voor de specifieke escapecodes. Dat is eigenlijk alles. Ik heb geëxperimenteerd om tot een consistente styling te komen die ik mooi vond, en ik heb de Gopher-versie van mijn pagina's als referentie gebruikt bij het maken van de opgemaakte curl-pagina's.
Automatisering via Gemroff
Het opvallende aan mijn versie is dat ik curl-versies heb van mijn volledige blog, in plaats van dat er slechts één of twee pagina's beschikbaar zijn. Dit is volledig te danken aan een handige samenloop van omstandigheden: ruim vier jaar geleden heb ik in mijn eigen opmaaktaal voor mijn blog, Gemroff, de mogelijkheid geïmplementeerd om ANSI-opgemaakte platte tekst uit te voeren. Oorspronkelijk was dit alleen bedoeld om concepten tijdens het schrijven gemakkelijk in de terminal te kunnen bekijken; maar het was triviaal om dit aan mijn static site generator (SSG) te koppelen om direct Curl-versies te laten genereren.
Ik heb handmatig een wrapper-template geschreven voor blogberichten, evenals een template voor de indexpagina waarop de berichten staan vermeld. Samen met een paar extra regels in mijn static site generator was dat alles wat nodig was om het werkend te krijgen.
Dit is precies waarom het lastig is om te zeggen dat het "eenvoudig" is! Voor mij was het alleen maar eenvoudig omdat ik een volledig eigen opmaaktaal en static site generator gebruik, en omdat ik jaren geleden de juiste ontwerpkeuzes heb gemaakt. Mijn SSG ondersteunt bijvoorbeeld al meerdere, modulaire outputformaten in plaats van uitsluitend HTML, zoals andere SSG's dat doen, aangezien ik mijn site drievoudig host op HTTP, Gemini en Gopher.
Overigens is het aanbieden van slechts een paar handgeschreven pagina's voor de leuk een volkomen acceptabele manier om zo'n site op te zetten, aangezien het gewoon een leuk gimmick is en niemand het waarschijnlijk langer dan een paar minuten zal gebruiken.
Serverconfiguratie
De laatste stap is het presenteren van de Curl-versie van je site aan elke user agent die curl bevat. Voor mij betekende dit slechts een paar wijzigingen in mijn Nginx-configuratie; bij andere servers zal dit vermoedelijk even eenvoudig zijn. De belangrijkste functie die ik wilde, was een override-header (X-Original: true), zodat je nog steeds een ongewijzigde HTTP-respons kon krijgen, wat iemand die toevallig Curl gebruikt waarschijnlijk zou willen. Daarnaast wilde ik dat alles statisch bleef worden geserveerd.
En… dat is het eigenlijk wel! Zoals ik al zei, toen ik het voor het eerst instelde, leek het me vrij zelfverklarend, maar het wijkt sterk af van wat mensen normaal gesproken doen met webservers of ANSI-escapecodes, dus ik begrijp waar de nieuwsgierigheid of verwarring vandaan komt. Het zou leuk zijn om te zien dat meer sites deze truc toepassen!
***
Een noot over em-dashes
EMDASH! AI-GEGENEREERD! Eigenlijk moet ik je vertellen dat mijn opmaaktaal sinds november 2022 een expliciet opmaakelement voor em-dashes heeft. En geloof het of niet: LLM's zijn getraind op teksten die zijn gekopieerd van echte auteurs, dus LLM's zouden geen em-dashes gebruiken als ze niet al werden gebruikt in door mensen geschreven werken.
En wat, moet ik nu vermijden om twintig parentheses per alinea te hebben, waardoor ik em-dashes voel nodig om er variatie in te brengen? Ondenkbaar!
Fancy Curl-sites
Een tijdje geleden heb ik een leuke curl-versie van mijn site toegevoegd, bedoeld om in de terminal te bekijken. Probeer deze commando's eens uit:
curl nytpu.com/gemlog/2026-03-18
# of
curl nytpu.com
(Excuses aan de Windows-gebruikers; het is niet mijn schuld dat ANSI-escapecodes standaard zijn uitgeschakeld in cmd.exe. En het is ook niet mijn schuld dat je in Powershell curl.exe moet gebruiken in plaats van curl, omdat Powershell dat onverklaarbaar heeft gekoppeld aan Invoke-WebRequest.)
Ik heb hier kort over gepost op het Fediverse, maar ik ben er verder niet dieper op ingegaan omdat ik dacht dat het vrij zelfverklarend was. Maar een handvol mensen heeft me gevraagd hoe ik het heb gedaan, dus ik besloot dat het waarschijnlijk de moeite waard was om een bericht te schrijven over mijn aanpak (…zo'n zeven maanden te laat).
Ik moet vermelden dat dit idee voortkomt uit de curl-sites van trinkey (curl trinkey.com) en strongsand (curl proot.party); ik heb het niet zelf bedacht. Hoewel ik het heel anders heb aangepakt dan zij, gaat alle eer voor dit coole idee naar hen. (UPDATE: helaas zijn beide curl-versies sinds 14-10-2026 niet meer functioneel.)
Het genereren van ANSI-bestanden
Ten eerste, omdat dit het meest interessante deel is: het genereren van de bestanden met ANSI-opmaak die naar de clients worden gestuurd. De indexpagina en de 'over mij'-pagina heb ik volledig handmatig geschreven.
Ik vermoed dat trinkey en strongsand die van hen on-the-fly genereren met de ratatui-bibliotheek (of iets soortgelijks), wat waarschijnlijk handiger is; voor mij leek handmatig schrijven echter sneller.
Ik had de belangrijkste escapecode—ESC[, oftewel \x1b[—in een Vim-register geplaatst om deze gemakkelijk te kunnen plakken wanneer nodig, en ik hield de Wikipedia-pagina voor de belangrijkste grafische codes open als referentie voor de specifieke escapecodes. Dat is eigenlijk alles. Ik heb geëxperimenteerd om tot een consistente styling te komen die ik mooi vond, en ik heb de Gopher-versie van mijn pagina's als referentie gebruikt bij het maken van de opgemaakte curl-pagina's.
Automatisering via Gemroff
Het opvallende aan mijn versie is dat ik curl-versies heb van mijn volledige blog, in plaats van dat er slechts één of twee pagina's beschikbaar zijn. Dit is volledig te danken aan een handige samenloop van omstandigheden: ruim vier jaar geleden heb ik in mijn eigen opmaaktaal voor mijn blog, Gemroff, de mogelijkheid geïmplementeerd om ANSI-opgemaakte platte tekst uit te voeren. Oorspronkelijk was dit alleen bedoeld om concepten tijdens het schrijven gemakkelijk in de terminal te kunnen bekijken; maar het was triviaal om dit aan mijn static site generator (SSG) te koppelen om direct Curl-versies te laten genereren.
Ik heb handmatig een wrapper-template geschreven voor blogberichten, evenals een template voor de indexpagina waarop de berichten staan vermeld. Samen met een paar extra regels in mijn static site generator was dat alles wat nodig was om het werkend te krijgen.
Dit is precies waarom het lastig is om te zeggen dat het "eenvoudig" is! Voor mij was het alleen maar eenvoudig omdat ik een volledig eigen opmaaktaal en static site generator gebruik, en omdat ik jaren geleden de juiste ontwerpkeuzes heb gemaakt. Mijn SSG ondersteunt bijvoorbeeld al meerdere, modulaire outputformaten in plaats van uitsluitend HTML, zoals andere SSG's dat doen, aangezien ik mijn site drievoudig host op HTTP, Gemini en Gopher.
Overigens is het aanbieden van slechts een paar handgeschreven pagina's voor de leuk een volkomen acceptabele manier om zo'n site op te zetten, aangezien het gewoon een leuk gimmick is en niemand het waarschijnlijk langer dan een paar minuten zal gebruiken.
Serverconfiguratie
De laatste stap is het presenteren van de Curl-versie van je site aan elke user agent die curl bevat. Voor mij betekende dit slechts een paar wijzigingen in mijn Nginx-configuratie; bij andere servers zal dit vermoedelijk even eenvoudig zijn. De belangrijkste functie die ik wilde, was een override-header (X-Original: true), zodat je nog steeds een ongewijzigde HTTP-respons kon krijgen, wat iemand die toevallig Curl gebruikt waarschijnlijk zou willen. Daarnaast wilde ik dat alles statisch bleef worden geserveerd.
En… dat is het eigenlijk wel! Zoals ik al zei, toen ik het voor het eerst instelde, leek het me vrij zelfverklarend, maar het wijkt sterk af van wat mensen normaal gesproken doen met webservers of ANSI-escapecodes, dus ik begrijp waar de nieuwsgierigheid of verwarring vandaan komt. Het zou leuk zijn om te zien dat meer sites deze truc toepassen!
***
Een noot over em-dashes
EMDASH! AI-GEGENEREERD! Eigenlijk moet ik je vertellen dat mijn opmaaktaal sinds november 2022 een expliciet opmaakelement voor em-dashes heeft. En geloof het of niet: LLM's zijn getraind op teksten die zijn gekopieerd van echte auteurs, dus LLM's zouden geen em-dashes gebruiken als ze niet al werden gebruikt in door mensen geschreven werken.
En wat, moet ik nu vermijden om twintig parentheses per alinea te hebben, waardoor ik em-dashes voel nodig om er variatie in te brengen? Ondenkbaar!