- Pour les utilisateurs qui veulent lire des articles web directement dans le terminal, James' Coffee Blog propose aussi ses articles au format pages de manuel Linux
- Pour une même URL, si le client envoie
Accept: text/roff, il reçoit un document roff au lieu du HTML grâce à la négociation de contenu HTTP
- Le fichier
.man de chaque article est généré à partir d’un modèle avec les sections TITLE, AUTHOR, PUBLISHED, POST et URL
- Le corps utilise le Markdown d’origine pour le rendre plus lisible que du HTML, même si l’espacement n’est pas toujours parfaitement propre dans une page de manuel
- NGINX détecte les requêtes
text/roff et réécrit l’URL vers un fichier .man, ce qui permet de l’enregistrer avec curl puis de l’ouvrir avec man ./post.page
Lire un article de blog avec man
- Les pages de manuel de Linux sont le moyen standard de consulter l’utilisation d’une commande dans le terminal, généralement avec
man <command>
- Par exemple, on peut consulter le manuel de la commande
tac ainsi
man tac
- James' Coffee Blog met en place un flux qui permet de lire aussi les articles du blog de cette manière, en téléchargeant la version
roff de l’URL d’un article puis en l’ouvrant avec man
- Voici un exemple réel de requête
curl -sL -H "Accept: text/roff" https://jamesg.blog/2024/02/28/programming-projects/ > post.page && man ./post.page
Choisir le format avec la négociation de contenu HTTP
- Le cœur de l’implémentation repose sur la négociation de contenu HTTP, qui permet au client d’indiquer au serveur le format de réponse souhaité
- L’en-tête
Accept sert à transmettre le type de contenu voulu
- Par exemple,
Accept: image/png signifie qu’on souhaite recevoir un fichier PNG si possible
- Il est aussi possible d’indiquer plusieurs types de contenu et leurs priorités, mais ici seul un format précis est demandé
- Pour recevoir un article de blog au format page de manuel, on envoie l’en-tête
Accept: text/roff
- Le serveur lit cet en-tête et renvoie une réponse text/roff ouvrable avec
man au lieu du HTML
Comment les fichiers .man sont générés
- Les pages de manuel Linux sont écrites avec la syntaxe roff
- Le site a été modifié pour générer une version
man pour chaque article de blog
- La structure du modèle utilisé est la suivante
.TH jamesg.blog 1 "" "jamesg.blog"
.SH TITLE
...
.SH AUTHOR
James' Coffee Blog (https://jamesg.blog)
.SH PUBLISHED
...
.SH POST
...
.SH URL
...
- Le modèle utilise le nom de domaine comme en-tête et crée cinq sections
- TITLE
- AUTHOR
- PUBLISHED
- POST
- URL
- Le corps reprend le Markdown d’origine
- L’espacement n’est pas toujours parfaitement rendu dans une page de manuel
- Malgré cela, c’est plus lisible que du HTML et cela préserve mieux les informations de titres et de paragraphes que du simple texte
Récupérer avec curl et ouvrir avec man
- La version
roff d’un article de blog peut être demandée avec la commande suivante
curl -sL -H "Accept: text/roff" https://jamesg.blog/2024/02/28/programming-projects/ > post.page
- Le résultat enregistré peut ensuite être ouvert comme une page de manuel locale
man ./post.page
- Si un navigateur classique demande l’URL du même article, il reçoit la version HTML
- En revanche, la commande
curl ci-dessus demande explicitement la version text/roff pour cette même URL
Réécriture vers les fichiers .man dans NGINX
- Le serveur gère séparément les requêtes
text/roff avec quelques lignes de configuration NGINX
- Dans
/etc/nginx/nginx.conf, des variables sont déclarées pour lever un indicateur lorsqu’un type de contenu précis est détecté
map $uri $redirect_suffix {
~^/(.*)/$ $1;
default "";
}
map $http_accept $redirect_location {
default "";
"~^text/roff" 1;
}
- Dans le fichier de configuration du site, sous
/etc/nginx/sites-enabled, une règle est ajoutée pour traiter les requêtes de pages roff
server {
...
location / {
if ($redirect_location = 1) {
rewrite ^/(.*)/$ /$1.man last;
}
...
}
}
- Cette configuration supprime la barre oblique finale de l’URL et ajoute
.man lorsqu’elle voit l’en-tête Accept: text/roff
- En pratique, NGINX lit alors le fichier
.man correspondant au lieu du index.html de chaque article
- On peut ainsi lire un même article de blog en HTML dans un navigateur web, ou comme page de manuel Linux dans le terminal
1 commentaires
Commentaires sur Hacker News
Ce serait chouette de proposer un dépôt deb comme mode d’abonnement à un blog
L’idée serait de récupérer tous les articles avec
apt update, puis de voir le dernier article et les liens vers l’index complet avecman your-blogJe pense que j’aurais peur de m’y abonner
On peut les consulter en local avec le paquet dwww : « Read all on-line documentation with a WWW browser »
https://packages.debian.org/bookworm/dwww
Joerg Jaspert était l’ancien mainteneur du paquet Linux Gazette : https://people.debian.org/~joerg/ (2002)
C’est l’un des meilleurs exemples que j’aie vus d’intégration de la diffusion d’information et de la documentation dans un système d’exploitation, et cela rend notamment les documents man/info plus utiles que les interfaces traditionnelles en terminal
Il existe aussi Debian Planet, un blog lié à Debian, mais il ne semble jamais avoir été fourni comme paquet Debian lui-même
Honnêtement, pour s’abonner à un blog, RSS est probablement un meilleur choix
https://github.com/capjamesg/jamesg.blog.deb contient de quoi créer, avec les commandes ci-dessous, un fichier deb ne contenant que des pages man
git clone [https://github.com/capjamesg/jamesg.blog.deb](<https://github.com/capjamesg/jamesg.blog.deb>)cd jamesg.blog.debdpkg-deb --build --root-owner-group jamesg.blogsudo dpkg -i jamesg.blog.debVous devriez alors voir une sortie du type
Processing triggers for man-db (2.9.1-1) ..., ce qui signifie que la page de manuel pourman jamesg.blogest disponiblePour l’instant, il n’y a qu’un placeholder, mais je finirai probablement demain
Cela deviendra peut-être bientôt un billet de blog
On peut directement le piper vers
man, sans fork ni fichier intermédiairecurl -sL -H "Accept: text/roff" [https://jamesg.blog/2024/02/28/programming-projects/](<https://jamesg.blog/2024/02/28/programming-projects/>) | man -l -{curl,wget}vers une commande recommenceUn ami ne laisse pas un ami piper directement un flux vers une commande
https://news.ycombinator.com/item?id=39554044
Pour info,
curl -sL -H "Accept: text/roff" [https://jamesg.blog/2024/02/28/programming-projects/](<https://jamesg.blog/2024/02/28/programming-projects/>) | man -l /dev/stdinfonctionne chez moiPas besoin d’enregistrer le fichier roff en local
bashdes commandes ou du contenu récupérés sur Internet est généralement considéré comme une mauvaise pratiquePersonnellement, je trouve ça acceptable. Les personnes qui comprennent les implications de sécurité connaissent presque certainement aussi ce genre de méthode de conversion, donc inutile de le leur indiquer
En revanche, ce n’est pas une bonne chose à montrer aux débutants. Un jour, ils pourraient se faire avoir. En gagnant en compétence, ils découvriront naturellement ce type de fonctionnalité, et j’espère qu’à ce moment-là ils en auront aussi compris les implications
Ce n’est pas moi qui ai écrit cet article : https://www.seancassidy.me/dont-pipe-to-your-shell.html
/usr/bin/man: illegal option -- lJ’ai essayé de faire une commande en une ligne avec un pipe sur Mac, mais j’obtenais toujours des erreurs
L’implémentation de
mansur macOS n’a pas le flag-l. J’ai vérifié la page de manuelman -l <(curl -sL -H "Accept: text/roff" https://jamesg.blog/2024/02/28/programming-projects/)À propos des URL qui font des choses amusantes dans le terminal, j’en avais vu une autrefois sur textfiles.com
Elle affiche un court film d’animation avec des codes de terminal VT100, le tout servi depuis un seul URI
Sur les systèmes modernes, on peut la regarder en limitant le débit
curl --limit-rate 1000 [http://textfiles.com/sf/STARTREK/trek.vt](<http://textfiles.com/sf/STARTREK/trek.vt>) && resetLe
resetest là parce que le terminal peut se retrouver dans un sale étatParmi les autres URI orientées terminal,
curl cheat.sh/tarrécupère des exemples d’utilisation du programme après le/, etcurl wttr.in/berlinrécupère la météo mise en forme pour le terminalEn pratique, c’est assez simple ; le plus difficile est la génération des images
Ça peut se faire avec
ffmpeg+img2txt.py: https://github.com/bfontaine/RickASCIIRoll/tree/master/movie...Il dispose d’un ancien miroir de https://16colo.rs/, ce qui permet de voir la plupart des œuvres ANSI publiées jusqu’ici
Exemple :
curl ansi.hrtk.in/ungenannt_1453.anshttps://itsfoss.com/star-wars-linux/
tritty, on peut simuler des débits de transmission de 1200/9600 BPSIl ne manque plus qu’un convertisseur de Markdown vers roff, et en cherchant un peu, il en existe déjà
https://github.com/postmodern/kramdown-man
https://rtomayko.github.io/ronn/ronn.1.html
https://kristaps.bsd.lv/lowdown/
[0] : https://pandoc.org/
md2groffexiste depuis longtemps dans les communautés proches de suckless/2f30/cat-vhttps://codeberg.org/nereusx/md2roff
Il existe un paquet Emacs qui installe le SICP d’Abelson et Sussman dans le répertoire Info
Il suffit de taper
M-x package-install sicp RETEn voyant ça, je me suis dit qu’on pourrait aussi installer toute une bibliothèque d’archives de blogs avec un lecteur de flux modifié
Lire Info dans Emacs permet aussi d’utiliser des signets
chicken-scheme. Ensuite, l’exécuter en rootchicken-install srfi-203chicken-install srtfi216Le
~/.csircpour SICP ressemble à ceci(import scheme)(import (srfi 203))(import (srfi 216))(define (inc x) (+ x 1))(define (dec x) (- x 1))Ensuite, on utilise comme d’habitude user geiser et geiser pour chicken
Je pourrais sans doute trouver la réponse sur Internet, mais j’aimerais poser la question sur HN
Au lycée, sur HP-UX, je me souviens que quelqu’un m’avait montré comment sauter vers un mot souligné, c’est-à-dire une référence de section, avec une combinaison de touches, mais impossible de me rappeler laquelle
J’ai aussi vérifié
man(1)etman(7), sans trouver. C’est peut-être un faux souvenirman ohmanrevient essentiellement ànroff -man /usr/share/man/man1/ohman.1 | $PAGERAutrement dit, on n’interagit pas avec man ou nroff, mais avec le pager
Aujourd’hui,
lessest le plus courant, etmoreest très probablement less en pratique, mais autrefois il y en avait d’autres, et HPUX utilisait peut-être quelque chose commepgpgvenait de la lignée AT&T,morede la lignée BSD, etlessde la lignée GNULes trois lancent une recherche par expression régulière avec
/, donc on peut trouver le terme qu’il soit souligné ou nonlessprend aussi en charge les fichiers de tags, ce qui permet de sauter au tag suivant avectdthelpview, le visualiseur d’aide CDE. Il pouvait peut-être afficher des pages maninfoIroniquement, une bonne partie de la documentation groff d’origine est écrite en texinfo : https://lists.gnu.org/archive/html/groff/2005-10/msg00107.ht...
Je ne sais pas pourquoi ce détail insignifiant a déclenché mon instinct de pinaillage. Peut-être parce que quelqu’un sur Internet avait un peu tort
C’est peut-être parce que c’était inutilement centré sur Linux dès le départ, ou parce que je m’attendais à autre chose et qu’au final ce n’était qu’une courte démo de négociation de contenu avec NGINX
Bref, il y a quelques remarques inutiles que j’ai quand même envie de faire
À strictement parler, ce n’est pas du roff qui est renvoyé. Des éléments comme
.THne font pas partie de roff lui-même, mais d’un package de macros destiné à l’écriture de pages manJ’ai été déçu qu’il n’y ait pas de conversion Markdown-to-roff. Je pensais que ce serait la partie intéressante de l’article, et au moins un outil existant aurait pu être utilisé
De même, à cause de cela, la mise en forme du texte n’est en fait pas vraiment correcte. L’entrée roff est censée avoir une phrase par ligne, afin de distinguer le
.en fin de phrase du.utilisé à d’autres finsDe plus, toute ligne commençant par
.peut être interprétée comme une commande et poser problèmeOu alors je ne suis peut-être qu’un vieux ronchon
L’existence d’autres outils comme
groffetnroffrendait les choses encore plus confusesUn article qui expliquerait simplement “ce que sont roff/les pages man/nroff/les autres variantes et comment on les utilise” suffirait largement à faire un billet de blog à part entière
J’aurais apprécié une explication courte et claire, et je pense qu’elle serait utile à d’autres aussi
Je voyais la conversion Markdown-to-roff comme une v2. Quand j’ai commencé à réfléchir à l’implémentation d’un parseur, quelqu’un m’a indiqué https://github.com/sunaku/md2man, et cela semble régler le problème
Il faudra que je voie comment l’intégrer à mon site Python qui tourne sur GitHub Pages, donc il y aura un peu de travail d’adaptation
Pandoc peut convertir du Markdown en roff de page man très facilement
En l’insérant dans le template donné, le résultat ressemblerait davantage à une vraie page man
Le bon type de média, selon la RFC 4263, est text/troff : https://www.rfc-editor.org/rfc/rfc4263.html
Super idée. Maintenant, il ne reste plus qu’à lancer le chrono jusqu’à “proposer mes billets de blog sous forme de DOOM WAD jouable”