diff --git a/Tuprules.tup b/Tuprules.tup
index 3712e6e..e342576 100644
--- a/Tuprules.tup
+++ b/Tuprules.tup
@@ -1,6 +1,5 @@
&root = .
&tmpl_dir = ./templates
-&gen_tmpl_dir = ./build/templates
HTML_TEMPLATE = main.html
@@ -10,8 +9,8 @@ HTML_TEMPLATE = main.html
--template=&(tmpl_dir)/$(HTML_TEMPLATE) \
--include-in-header=&(tmpl_dir)/header.html \
--include-before-body=&(tmpl_dir)/nav.html \
+ --include-after-body=&(tmpl_dir)/footer.html \
--css &(root)/css/style.css \
- --include-after-body=&(gen_tmpl_dir)/footer.html \
%f | sed 's|%%webRoot%%|&(root)|g' > %o \
|> %B.html
@@ -20,7 +19,17 @@ HTML_TEMPLATE = main.html
!compress_png = |> zopflipng %f %o |>
!compress_jpg = |> cjpeg -quality 80 -progressive -outfile %o %f |>
!compress_pdf = |> ps2pdf %f %o |>
+!avif = |> avifenc %f %o |> %B.avif
+!jxl = |> cjxl %f %o |> %B.jxl
JPG_OPT = -quality 80 -strip -interlace Plane
!blur_mini = |> ^ %f -> blur mini^ convert %f -resize 400x400 -blur 0x8 $(JPG_OPT) %o |> blur_mini.jpg
!thumbnail = |> ^ %f -> thumbnail^ convert %f -resize 200x200 $(JPG_OPT) %o |>
+
+#
+# Slides
+#
+MARP = npx @marp-team/marp-cli@latest
+MARP_OPTS = --allow-local-files --bespoke.progress
+!marp_pdf = |> $(MARP) $(MARP_OPTS) %f --pdf --output %o |> %B.pdf
+!marp_html = |> $(MARP) $(MARP_OPTS) %f --html --output %o |> %B.html
diff --git a/about.md b/about.md
index 7a69288..2762b5e 100644
--- a/about.md
+++ b/about.md
@@ -66,7 +66,7 @@ work on smart homes. I work in the Vision team, making home cameras smarter. I
am thrilled to work on computer vision again.
-
+
diff --git a/articles/Tupfile b/articles/Tupfile
index c8d9bfc..924243a 100644
--- a/articles/Tupfile
+++ b/articles/Tupfile
@@ -1,5 +1,5 @@
include_rules
HTML_TEMPLATE = article.html
-: *.md |> ./generate_listing.sh > %o |> index.md
+: *.md |> ./generate_listing.nu > %o |> index.md
: foreach *.md |> !html |>
diff --git a/articles/chasseur_cueilleur_parents.md b/articles/chasseur_cueilleur_parents.md
new file mode 100644
index 0000000..851edde
--- /dev/null
+++ b/articles/chasseur_cueilleur_parents.md
@@ -0,0 +1,378 @@
+---
+title: "Chasseur, cueilleur, parent"
+date: 2025-05-06
+---
+
+_Ceci est un résumé du livre [Chasseur, cueilleur, parent](https://www.editionsleduc.com/produit/2579/9791028521592/chasseur-cueilleur-parent)_
+
+## Méthode TEAM
+
+1. tendre camaraderie
+2. encouragements
+3. autonomie
+4. minimum d’ingérence
+
+## Comment élever des enfants serviables ?
+
+- Les enfants ont le désir inné d’aider leurs parents. Il peut donc sembler
+inapte ou empoté. C’est à ses parents de le former.
+
+- Ne découragez jamais un enfant d’aider. Si une tâche est trop difficile ou
+trop dangereuse, dites-lui d’observer. Ou divisez la tâche en sous-tâches plus
+réalisables.
+
+- Tâches simples mais réelles à effectuer ensemble, 1x / heure.
+ - aller chercher quelque chose dont vous avez besoin
+ - porter un petit sac de courses
+ - remuer une préparation dans une casserole
+ - couper un légume
+ - tenir la porte
+ - ouvrir le robinet du tuyau d’arrosage
+ - remettre un livre dans la bibliothèque
+
+- Pour les enfants plus grands (à partir de 7 ans) : essayez de déclencher son
+action en faisant une allusion indirecte à la tâche :
+ - "la gamelle du chien est vide"
+ - "il est l’heure de préparer le dîner"
+
+## Comment élever des enfants coopérants
+
+- Les enfants sont animés d’une motivation naturelle très forte pour le travai
+en équipe et la coopération.
+
+- Les activités centrées sur les enfants sapent cette motivation pour le travail
+en équipe.
+
+- À l’inverse, en incluant les enfants dans les activités d’adulte, on accroît
+leur motivation à coopérer et à faire comme les autres membres de la famille.
+
+- Les enfants ont tendance à mal se comporter lorsqu’ils doivent passer du monde
+des enfants au monde des adultes.
+
+- Dans la plupart des cultures, les parents ne passent pas leur temps à stimuler
+et à divertir les enfants.
+
+- Les enfants n’ont pas besoin qu’on les stimule ou qu’on les amuse.
+
+### Actions pour tous les enfants
+
+- Limitez les activités centrées sur les enfants. Veillez à ce que votre enfant
+ait accès à votre vie et à votre travail. Veillez à ce qu’il soit dans les
+parages lorsque vous vous adonnez à des tâches domestiques ou à d’autres
+activités d’adulte.
+
+- Réduisez les distractions telles que les écrans et les jouets. Moins l’enfant
+disposera d’objets de «divertissement», plus il sera attiré par votre univers et
+plus il sera susceptible de vouloir vous aider et de passer du temps avec vous.
+
+- Augmentez au maximum son exposition au monde des adultes. Vaquez à vos
+occupations avec votre enfant près de vous.
+
+- Le week-end, choisissez des activités qui vous font envie, celles que vous
+feriez même si vous n’aviez pas d’enfant.
+
+### Actions pour les enfants à partir de 7 ans
+
+- Laissez-le prévoir et organiser ses activités (les cours de sport, de musique,
+d’arts plastiques, toute autre activité extrascolaire, les goûters avec
+les copains...).
+
+- Augmentez progressivement les responsabilités de l’enfant dans la maison, y
+compris le fait de s’occuper de ses petits frères et sœurs, et sa participation
+à la préparation des repas et au ménage. Pensez à la manière dont il pourrait
+vous aider dans votre travail.
+
+- Si un enfant plus âgé a été peu exposé au monde des adultes, allez-y par
+paliers. Vaquez à vos occupations en emmenant votre enfant avec vous. S’il se
+conduit mal, expliquez-lui comment il doit se comporter dans le monde des
+adultes.
+
+- Si l’enfant a toujours un comportement perturbateur, soyez patient. Ne
+renoncez pas. Réessayez plus tard. Il apprendra.
+
+## Comment motiver les enfants
+
+- Si vous voulez motiver un enfant sans le soudoyer ou l’amadouer, il doit avoir
+l’impression :
+ - D’être relié à vous ou à une autre personne proche.
+ - De choisir d’accomplir la tâche sans que personne l’y oblige.
+ - D’être compétent, en sorte que sa participation sera valorisée.
+
+- Les compliments peuvent saper la motivation et générer de la compétition (et
+des querelles) entre frères et sœurs.
+
+- Les connaissances peuvent circuler dans un sens comme dans l’autre. Lorsqu’on
+accorde de l’attention aux idées et aux points de vue d’un enfant, on en tire
+souvent des informations précieuses et utiles.
+
+- Accepter les connaissances, les idées et les contributions d’un enfant est un
+excellent moyen de le motiver.
+
+- Résistez à l’envie de corriger un enfant, surtout quand il est en train de
+mettre la main à la pâte ou d’aider la famille.
+
+- Si un enfant refuse d’obéir à une demande (par exemple aider à débarrasser),
+vous êtes probablement trop insistant. L’enfant sait ce que vous voulez. Arrêtez
+de le demander. Attendez et laissez l’enfant prendre les rênes.
+
+- Soyez très attentif à la participation de l’enfant, puis inspirez-vous de ses
+idées plutôt que de vous y opposer.
+
+- Aidez un enfant à apprendre une tâche en le laissant pratiquer plutôt qu’en
+lui faisant un cours complet sur la manière de l’accomplir. Proposez de simples
+ajustements, avec parcimonie, pendant que l’enfant est à l’œuvre.
+
+- Acceptez la contribution de l’enfant, même si elle ne répond pas à vos
+attentes ou à vos désirs.
+
+- Usez des compliments avec modération. Associez vos félicitations à
+l’apprentissage d’une valeur globale («tu commences réellement à nous aider») ou
+à une certaine maturité («tu es en train de devenir une grande fille»).
+
+## Comment apprendre aux enfants à maîtriser leur colère
+
+- La colère contre un enfant est stérile. Elle génère du conflit, crée de la
+tension et coupe la communication. Chaque fois qu’on crie après un enfant,
+on lui apprend à hurler et à se mettre en colère au moindre problème ou à la
+moindre contrariété. L’enfant pratique la colère et les cris.
+
+- Vous pouvez interrompre ce cycle en répondant à l’enfant avec calme et
+gentillesse.
+
+- On surestime souvent l’intelligence émotionnelle des enfants.
+
+- Pour aider un enfant à savoir maîtriser sa colère, le mieux est de maîtriser
+sa propre colère devant lui.
+
+- Chaque fois qu’on répond avec calme et sang-froid à un enfant contrarié, on
+lui donne la possibilité de trouver cette réponse en lui.
+
+- Lorsque vous ressentez de la colère à l’égard d’un enfant, restez silencieux
+et attendez que la colère passe. Si vous parlez, l’enfant ressentira votre
+colère. Mieux vaut donc se taire.
+
+- Si vous ne parvenez pas à maîtriser votre colère, sortez de la pièce ou
+éloignez-vous de l’enfant. Revenez une fois que vous êtes calmé.
+
+- Apprenez à ressentir moins (voire pas du tout) de colère à l’égard des
+enfants.
+
+- **Modifiez votre point de vue sur leur comportement.** Attendez-vous à ce que
+les jeunes enfants se comportent mal et causent des problèmes.
+
+- **Ne vous disputez (et ne négociez) jamais avec un enfant.** Les disputes
+permettent à l’enfant de s’entraîner à argumenter. Taisez-vous et éloignez-vous.
+
+- **Arrêtez de forcer les enfants à faire des choses.** Cela engendre des
+conflits, érode la communication et fait monter la colère (des deux côtés).
+Utilisez les outils décrits dans le chapitre suivant pour favoriser un
+comportement approprié plutôt que de l’imposer.
+
+## Outils pour modifier le comportement
+
+- La parole est souvent le moyen de communication le moins efficace avec les
+enfants, en particulier les plus jeunes.
+
+- Les émotions de l’enfant sont le miroir de nos émotions.
+ - Si vous souhaitez que votre enfant soit calme, doux et silencieux, parlez peu
+ou pas du tout (les mots stimulent).
+ - Si vous souhaitez que votre enfant soit bruyant et très agité, soyez-le.
+Parlez beaucoup.
+
+- Les ordres et les leçons entraînent souvent des bras de fer, des négociations
+et des spirales de colère.
+
+- On peut rompre le cycle de la colère et des bras de fer grâce à des outils
+non verbaux ou en amenant l’enfant à réfléchir plutôt que de lui dire ce qu’il
+doit faire.
+
+- **Dompter les crises.** Les crises de colère se dissipent si vous réagissez
+avec calme.
+ - **L’énergie.** En restant aussi calme et paisible que possible, tenez-vous
+près de l’enfant, en silence, et montrez-lui que vous êtes là pour lui et que
+vous le soutenez.
+ - **Le contact physique.** Touchez doucement l’épaule de l’enfant ou tendez-lui
+la main.
+ - **L’émerveillement.** Aidez l’enfant à remplacer la colère par cette émotion
+qu’est l’émerveillement.
+ - **L’extérieur.** Si l’enfant ne se calme toujours pas, sortez-le prendre
+l’air. Conduisez-le dehors en douceur ou emmenez-le dans vos bras.
+
+- **Changer de comportement et transmettre des valeurs.** Au lieu d’ordonner à
+l’enfant de «ne pas faire ça», poussez-le à réfléchir.
+ - **Le regard-qui-dit-tout.** Prenez tout ce que vous avez envie de dire à
+un enfant qui se comporte mal et dirigez-le dans votre expression faciale.
+Ouvrez grand les yeux, plissez le nez ou secouez la tête. Puis jetez ce regard
+à l’enfant.
+ - **Le puzzle des conséquences.** Énoncez calmement quelles sont les
+conséquences de ses actes, puis partez (par exemple: «Tu vas tomber et te faire
+mal»).
+ - **Les questions.** Au lieu d’émettre des ordres et des consignes, posez une
+question à l’enfant (par exemple: «Qui est méchant avec Freddy?» quand il est
+en train de taper son frère, ou «Qui est irrespectueuse?» quand l’enfant ignore
+une demande).
+ - **La responsabilité.** Si un enfant se comporte mal, donnez-lui une tâche à
+réaliser (par exemple, dites à un enfant qui pleurniche le matin: «Viens m’aider
+à préparer ta boîte à goûter»).
+ - **Les actes.** Au lieu de demander à un enfant de faire quelque chose (par
+exemple sortir de la maison), faites-le. L’enfant suivra.
+
+## Modeler le comportement grâce aux histoires et au jeu théâtral
+
+- Quand un enfant est contrarié, il lui est difficile d’écouter et d’apprendre.
+
+- Quand un enfant est détendu et se sent protégé de toute punition, il est ouvert
+pour apprendre de nouvelles règles et réparer ses erreurs.
+
+- Si un enfant ne se montre pas coopérant dans une situation donnée (par exemple,
+faire ses devoirs), il est probable qu’il existe une tension sur cette question
+entre l’enfant et le parent. Une fois cette tension dissipée grâce au jeu
+théâtral ou à une histoire, l’enfant adoptera un meilleur comportement et sera
+plus coopérant.
+
+- Les enfants adorent apprendre à travers des récits oraux, surtout quand ces
+histoires parlent de personnages, d’expériences et d’objets de leur propre vie.
+Ils ont une tendance naturelle à apprendre de cette manière. Ils adorent par
+exemple:
+
+ – Qu’on leur parle de leur histoire familiale et de l’enfance de leurs parents.
+
+ – Imaginer des objets prendre vie et faire des erreurs.
+
+ – S’imaginer vivre entourés de fantômes, de monstres, de fées et d’autres
+créatures surnaturelles qui les aident à apprendre à se comporter correctement.
+
+- Les enfants adorent apprendre par le jeu. Cela leur permet de relâcher la
+tension et de s’entraîner à bien se comporter. Ils aiment rejouer une erreur ou
+un comportement problématique et observer les conséquences dans un environnement
+ludique et sans stress (sans craindre d’être punis).
+
+Plutôt que de vous lancer dans des leçons de morale et de vous appuyer sur un
+raisonnement adulte pour modifier le comportement d’un enfant ou lui inculquer
+une valeur, attendez un moment de calme et de détente et essayez l’un de ces
+outils:
+
+ - **Racontez une anecdote de votre enfance.** Expliquez comment vous et vos
+parents aviez géré une bêtise, un problème, un mauvais comportement. Aviez-vous
+été puni ? Comment aviez-vous réagi ?
+
+ - **Faites un spectacle de marionnettes.** Prenez un animal en peluche ou une
+paire de chaussettes pour mettre en scène les conséquences du comportement de
+l’enfant et lui montrer comment vous aimeriez qu’il se conduise. Demandez-lui de
+jouer l’un des personnages.
+
+ - **Déplacez le problème sur le terrain du jeu.** Dites à l’enfant: «J’ai remarqué
+qu’on se dispute beaucoup à propos de tes devoirs [ou du problème en question].
+Si on jouait à un jeu ? Qui as-tu envie de jouer ? Toi ou moi ?» Puis rejouez
+sur un ton humoristique ce qui se passe pendant les disputes. N’ayez pas peur
+de partir dans le délire et l’exagération. L’objectif, c’est d’en rire et de
+relâcher la tension qui s’est créée autour de cette question.
+
+ - **Ayez recours à un monstre.** Créez un monstre tapi près de la maison. Dites
+à l’enfant qu’un monstre le regarde et que, s’il se conduit mal, le monstre
+viendra l’enlever (seulement pour quelques jours).
+
+ - **Donnez vie à un objet inanimé.** Utilisez une peluche, un vêtement ou tout
+autre objet inanimé pour amadouer l’enfant et le persuader d’accomplir une
+tâche. Faites faire cette tâche à l’objet en question (brosser les dents
+d’une peluche) ou faites parler l’objet (c’est la brosse à dents qui demande à
+l’enfant de se brosser les dents, par exemple).
+
+## Comment élever un enfant sûr de lui
+
+- Tout comme les adultes, les enfants, petits et grands, n’aiment pas qu’on
+les commande. Ils ont, quel que soit leur âge, un penchant naturel pour
+l’apprentissage de l’autonomie sans qu’on s’en mêle.
+
+- Quand on mène un enfant à la baguette, on sape sa confiance en lui et son
+autonomie.
+
+- Quand on respecte l’autonomie de l’enfant et qu’on réduit ses instructions
+au minimum, on lui envoie le message qu’il est autonome et capable de régler
+lui-même les problèmes.
+
+- Donner de l’autonomie à un enfant est la meilleure façon de le protéger du
+stress et de l’anxiété.
+
+- L’indépendance et l’autonomie sont deux concepts distincts:
+
+ - Un enfant indépendant est déconnecté des autres, il n’est responsable de
+personne d’autre que lui.
+
+ - Un enfant autonome est maître de ses actes et prend ses propres décisions,
+mais il est en relation permanente avec sa famille et ses amis. On attend de lui
+aide, partage et bienveillance. On attend de lui qu’il rende au groupe chaque
+fois qu’il le peut.
+
+- **Soyez attentif à la fréquence des consignes que vous donnez à votre enfant.**
+Programmez le minuteur de votre téléphone sur vingt minutes. Comptez combien de
+commentaires, questions et demandes vous avez émis pendant ce laps de temps.
+
+- **Limitez-vous à trois ordres par heure.** Efforcez-vous de vous y tenir, notamment
+dans les activités génératrices de conflits et de disputes (se préparer
+pour aller à l’école ou pour aller au lit, par exemple). N’ayez recours aux
+ordres que pour apprendre à l’enfant la serviabilité, la générosité et les
+responsabilités envers sa famille.
+
+- **Trouvez une zone d’autonomie.** Identifiez des lieux autour de chez vous où les
+enfants de tous les âges peuvent évoluer en toute autonomie, où vous pouvez les
+surveiller de loin en interférant le moins possible. Pensez aux parcs et aux
+aires de jeux en plein air, aux prés et aux plages. Prenez de la lecture ou du
+travail et laissez les enfants jouer pendant quelques heures.
+
+- **Faites de votre jardin et de votre quartier une zone d’autonomie.** Formez votre
+enfant à gérer les dangers, chez vous et aux alentours. Tissez un «filet de
+protection invisible» en sympathisant avec vos voisins et leurs enfants.
+
+- **Cessez d’être ventriloque.** Mettez un point d’honneur à ne plus parler à la
+place de votre enfant ou lui dire ce qu’il doit dire. Laissez-le répondre aux
+questions qu’on lui pose, passer commande au restaurant, décider quand dire
+«s’il te plaît» et «merci». Faites en sorte qu’il soit capable de gérer lui-même
+toutes les conversations, y compris les discussions avec ses enseignants,
+entraîneurs ou moniteurs.
+
+## Comment protéger ses enfants de la dépression
+
+- Les bébés et les enfants sont conçus pour être élevés par toutes sortes
+de personnes. Grands-parents, tantes, nourrices, voisins... toutes sont
+importantes.
+
+- Ce réseau d’amour et de soutien aide l’enfant à voir le monde comme un lieu
+bénéfique et bienveillant, ce qui le protège de la dépression et d’autres
+troubles de santé mentale.
+
+- Un ou deux alloparents supplémentaires peuvent vraiment faire la différence
+dans la vie d’un enfant.
+
+- Les autres enfants peuvent être de fantastiques alloparents et ont tendance
+à faire de meilleurs enseignants et camarades de jeu que les adultes. Les
+enfants intègrent naturellement le jeu aux apprentissages et ont des niveaux de
+compétence plus proches de ceux des petits que les adultes.
+
+- Les amitiés intimes et profondes sont probablement tout aussi importantes pour
+votre santé et celle de votre enfant que l’exercice physique et une alimentation
+saine.
+
+- **Tissez un réseau de tantes et d’oncles.** Collaborez avec trois ou quatre
+autres familles pour vous partager les temps extrascolaires, en mettant en
+place un roulement pour chaque jour de la semaine. Ce réseau procure un soutien
+émotionnel aux enfants et permet aux parents de souffler.
+
+- **Créer un GEM (groupe d’enfants multiâges).** Encouragez votre enfant à jouer
+avec d’autres, de tous les âges et dans tout le quartier. Invitez les autres
+familles à des dîners ou des apéros. Organisez de grandes garderies de quartier
+le week-end, où vous invitez des enfants de tous les âges à jouer dans votre
+jardin ou dans un parc.
+
+- **Formez de mini-alloparents.** Apprenez très tôt aux enfants plus âgés à
+s’occuper de leurs petits frères et sœurs. Établissez un lien entre l’aide
+qu’ils apportent et leur maturité croissante («Tu aides ton petit frère parce
+que tu es une grande fille maintenant»). Récompensez l’enfant en augmentant ses
+responsabilités au fil du temps.
+
+- **Appréciez l’aide des alloparents déjà présents.** Travaillez main dans
+la main avec votre enfant pour exprimer votre reconnaissance aux nourrices,
+puéricultrices, professeurs et entraîneurs. Faites-lui rédiger des petits mots,
+préparer des biscuits et friandises pour les remercier. Considérez-les comme
+des membres importants de votre famille. Montrez l’exemple du respect et de
+la générosité.
diff --git a/articles/generate_listing.nu b/articles/generate_listing.nu
new file mode 100755
index 0000000..8df24a7
--- /dev/null
+++ b/articles/generate_listing.nu
@@ -0,0 +1,32 @@
+#!/usr/bin/env nu
+
+def get_metadata [path: string] {
+ let lines = open $path | lines
+ let anchors = $lines | enumerate | filter {|l| ($l.item | str starts-with "---")} | take 2
+ let header = $lines
+ | range (($anchors | first | get 'index') + 1)..(($anchors | last | get 'index') - 1)
+ let metadata = $header | split column -n 2 --regex '\s*:\s*' | rename key value
+ let record = $metadata | reduce -f {} {|it, acc| $acc | upsert $it.key ($it.value | str trim --char '"') }
+ $record |
+}
+
+let pages = (glob *.md) ++ (glob **/index.md)
+let sorted_pages = $pages | wrap 'path'
+ | upsert metadata {|row| (get_metadata $row.path)}
+ | sort-by --reverse metadata.date
+
+print "---
+title: Articles
+---
+"
+
+let _ = $sorted_pages | each {|p|
+ let rel_path = $p.path | path relative-to (pwd)
+ let html_path = $rel_path | path parse --extension md | upsert extension { 'html' } | path join
+ print --no-newline $"- ($p.metadata.date): [($p.metadata.title)]\(($html_path)\)"
+ if $p.metadata.update? != null {
+ print $" \(Updated: ($p.metadata.update)\)"
+ } else {
+ print ""
+ }
+}
diff --git a/articles/generate_listing.sh b/articles/generate_listing.sh
deleted file mode 100755
index cf62c2d..0000000
--- a/articles/generate_listing.sh
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/usr/bin/env bash
-
-set -euo pipefail
-
-cat << EOF
----
-title: Articles
----
-
-EOF
-
-listing=""
-for file in *.md; do
- if [ $file = "index.md" ]; then
- continue
- fi
-
- link=$(basename $file .md).html
- date=$(sed -n 's/date: \(.*\)/\1/p' $file)
- title=$(sed -n 's/title: \(.*\)/\1/p' $file)
- listing="$listing- $date: [$title]($link)\n"
-done
-echo -e $listing | sort --reverse
diff --git a/articles/jujutsu/Tupfile b/articles/jujutsu/Tupfile
new file mode 100644
index 0000000..a3775a5
--- /dev/null
+++ b/articles/jujutsu/Tupfile
@@ -0,0 +1,9 @@
+include_rules
+HTML_TEMPLATE = article.html
+
+: foreach *.png |> !avif |>
+: foreach *.png |> !jxl |>
+: index.md | ./ |> !html |>
+
+# images embedding not working in marp + tup
+# : slides.md |> !marp_pdf |> jujutsu_slides.pdf ./
diff --git a/articles/jujutsu/index.md b/articles/jujutsu/index.md
new file mode 100644
index 0000000..0b1863d
--- /dev/null
+++ b/articles/jujutsu/index.md
@@ -0,0 +1,154 @@
+---
+title: "Lightning talk: Jujutsu"
+date: 2025-02-17
+---
+
+_Slides available: [pdf](./jujutsu_slides.pdf)_
+
+
+
+
+
+
+
+
+
+## What is it?
+
+[Jujutsu](https://github.com/jj-vcs/jj) is a new version control software (VCS),
+like git, mercurial, etc. Git is the actual gold standard for VCS, even if its
+UX could be better. There is a whole ecosystem around git that makes switching
+to similar projects (eg. mercurial) a daunting task. How does jujutsu plan on
+making us switch?
+
+Jujutsu separates the frontend (what the user interacts with) and the
+backend (how the information is stored). And the main backend is actually git
+repositories. There is a native backend being developed but it's not ready for
+prime time. Sharing the same backend as the most popular VCS, Jujutsu aims to
+improve on the frontend.
+
+## How does it compare?
+
+### No branch, only revisions
+
+Jujutsu understand git commits, but operates at a higher level with revisions.
+Revisions wrap commits, however as you move revisions around (edit with changes,
+or rebase), they keep their id. Only their underlying commit id changes.
+
+With revision ids being stable, you don't need branches to start working: create
+a new revision, and start working. You will need to create a branch (or bookmark
+in jujutsu world) to push your changes, but it can be done at the end.
+
+There is no special mode like git's "Detached HEAD", you are always on a
+revision. You can jump around the history and you will always see the whole
+history, unlike git where you only see parents revisions.
+
+This emphasis on revisions changes the paradigm a bit: you tend to better split
+your revisions, whereas in git you often do smaller commits then clean the whole
+branch during a rebase phase.
+
+You can also modify revisions freely: unlike git where you can only modify
+the current branch, you can squash part of any revision into another unrelated
+revision.
+
+Some revisions (such as the `main` or `master` branch) are considered immutable,
+meaning you are not allowed to modify them. You can override this but this is a
+sane choice by default.
+
+### No staging area
+
+Every modification in jujutsu is stored. It removes a step from git and
+avoids scenarios where you cannot switch branches because of a untracked file
+collision, or when you forget to add a file (it works locally but not on the
+CI env).
+
+It does require a good .gitignore file to avoid adding unnecessary (big) files,
+but that is good practice anyway.
+
+You can mimic git staging area with a new revision on top of your work.[^1]
+
+### Conflicts are ok
+
+Conflicts during rebase are recorded but never stop the rebase. Revisions will
+be flagged as "conflicted" until the conflict markers are removed. You can then
+see how long the conflicts last (maybe a later revision fixes them).
+
+You deal with conflicts how you want, it is never a hurry. You can save your
+progress and change branch in the meanwhile. Once you fix a conflict you do
+not need to explicitely mark them as resolved, the absence of markers is enough
+for jujutsu.
+
+### Branch, bookmark
+
+A "branch" in git is named "bookmark" in jujutsu. You do not need one during
+dev, you can safely switch revisions trees without naming them. This is very
+useful when you need to try something on top of the main branch: you just
+create a new revision on top of it without creating an dedicated branch or even
+modifying the main branch (I often modified my local copy of the main branch
+this way with git).
+
+However, you need a bookmark when you want to push changes to a remote (which is often).
+I believe this could be skipped with a dedicated jujutsu backend.
+
+When creating a bookmark, it sticks to the revision it was created on, you need
+to manually update it if you add revision on top of it. This manual step is
+useful when you want to push your changes but keep a few revisions private until
+your work is done.
+
+Tracked bookmarks are similar to tracked branches in git, but they are
+automatically updated during fetching. No more out-of-date information between a
+local bookmark and its remote (I'm looking at you `origin/main`).
+
+### Tooling
+
+Jujutsu comes with nice CLI tools out-of-the-box: you can select part of a commit
+for squashing / splitting with a dedicated TUI, and the log are pretty-printed
+in graph format.
+
+But it cannot compare to the exhaustive ecosystem that exists for git: GUI,
+scripts, etc. Unfortunately, git tools are confused when you use jujutsu in
+your repository: they only see the detached HEAD, they are missing the overall
+picture.
+
+You can always come back to a regular git workflow based on branches (they are
+mapped on bookmarks), should you need it.
+
+### Takeaway
+
+Jujutsu shines when you are dealing with multiple tracks (bug hunting,
+work-in-progress, small tests).
+
+The need to specify bookmarks when pushing changes feels a bit heavy compared
+to how smooth it is working locally. A backend tailored for jujutsu, supporting
+revisions without bookmarks, would remove a lot of friction.
+
+Jujutsu has cool features, but I wouldn't consider them game-changing. It feels
+simpler though, which is good coming from git.
+
+The ecosystem is almost null, but it is growing.[^2]
+
+
+## VCS landscape
+
+Jujutsu seems to materialize what the next VCS after git should be: better
+conflict support and nicer UX.
+
+It is developed by Googlers and I believe the goal is to slowly replace git CLI
+at Google. It is making good progress with frequent releases.
+
+[Sapling](https://sapling-scm.com/) is another contender, developed at Facebook.
+It is more inspired by Mercurial (which is used at Facebook). Its feature set is
+similar to Jujutsu but it seems less popular.
+
+> I was part of the team at Meta that built Sapling for many years. I’m no
+> longer at Meta and I use jj full time.
+>
+> _[Discussion on Lobste.rs](https://lobste.rs/s/rojoz1/jujutsu_jj_git_compatible_vcs#c_foqya4)_
+
+[Pijul](https://pijul.org/) is less focusing on git compatibility and looks
+more like a research project, focusing on theory of patches. I am not sure how
+production ready it currently is, but the clean break with git means it needs to
+be rock solid to tempt people over.
+
+[^1]: [The Squash Workflow](https://steveklabnik.github.io/jujutsu-tutorial/real-world-workflows/the-squash-workflow.html)
+[^2]: [GUI and TUI](https://github.com/jj-vcs/jj/wiki/GUI-and-TUI)
diff --git a/articles/jujutsu/jj-logo.png b/articles/jujutsu/jj-logo.png
new file mode 100644
index 0000000..dc94ced
Binary files /dev/null and b/articles/jujutsu/jj-logo.png differ
diff --git a/articles/jujutsu/jj_01_commits.png b/articles/jujutsu/jj_01_commits.png
new file mode 100644
index 0000000..1d58bcf
Binary files /dev/null and b/articles/jujutsu/jj_01_commits.png differ
diff --git a/articles/jujutsu/jj_01_revs.png b/articles/jujutsu/jj_01_revs.png
new file mode 100644
index 0000000..1969406
Binary files /dev/null and b/articles/jujutsu/jj_01_revs.png differ
diff --git a/articles/jujutsu/jj_02.png b/articles/jujutsu/jj_02.png
new file mode 100644
index 0000000..af437d3
Binary files /dev/null and b/articles/jujutsu/jj_02.png differ
diff --git a/articles/jujutsu/jj_revision.drawio.png b/articles/jujutsu/jj_revision.drawio.png
new file mode 100644
index 0000000..66d7151
Binary files /dev/null and b/articles/jujutsu/jj_revision.drawio.png differ
diff --git a/articles/jujutsu/slides.md b/articles/jujutsu/slides.md
new file mode 100644
index 0000000..eb18126
--- /dev/null
+++ b/articles/jujutsu/slides.md
@@ -0,0 +1,131 @@
+---
+marp: false
+theme: gaia
+footer: '**Fabien Freling** - 2025-02-17'
+paginate: true
+---
+
+
+
+
+
+
+# Jujutsu
+
+
+
+---
+
+## What is it?
+
+* New version control software (VCS)
+* Separation of **frontend** and **backend**
+* Compatible with git
+* Slowly replacing git cli at Google (askip)
+* Aiming for a simpler workflow
+
+---
+
+## No branch, only revisions
+
+
+
+
+- @ working copy
+- ◆ immutable
+- × conflict
+
+---
+
+## Embrace the DETACHED HEAD
+
+- No need to be at the tip of a branch
+- Easy to change the current revision (no rebase step)
+- Each revision has a scope, you can switch / split / squash
+- You can modify other branches, not only the current one (there is none)
+
+---
+
+## Immutable revisions
+
+- New concept
+- By default `master` is immutable, sane choice
+- Clearly express what would create conflict, even local copy cannot change
+- You can override it (but don't)
+
+---
+
+## No staging area, everything is logged
+
+- You need a good gitignore
+- You can always switch commits without loss
+- You might want to recreate a "staging" commit
+
+---
+
+## Conflicts are ok
+
+- Conflicts are recorded but never stop a rebase
+- Conflicted commits are annotated
+- You can safely rebase, deal with conflicts later on
+- No need to mark as resolved
+
+---
+
+## Branches, bookmarks
+
+- Branches (git) = bookmarks (jujutsu)
+- Optional during dev
+- Mandatory when pushing
+- Stick to revision, manual step to update
+- Tracked bookmarks are updated during fetch
+ - No sync conflict between a local copy and its remote
+
+---
+
+## Back to git?
+
+- A way back is always possible
+- git view gets confused in detached HEAD
+
+---
+
+## Tooling
+
+- Battery included
+ - CLI tool for splitting commits
+- Git tools not compatible
+
+---
+
+## Takeaway
+
+- 🤩 Good when dealing with multiple tracks
+- 😔 Need to explicitely specify branch when pushing commits
+- Small improvements, not game-changing
+- 😔 No ecosystem, but it's growing (TUI)
+- Native backend (not ready yet) would remove a lot of friction
+
+---
+
+
+
+## Worth the switch?
+
+# ✋ Not yet
+
+---
+
+# References
+
+- [Official website](https://jj-vcs.github.io/jj/)
+ - [GUI & TUI](https://github.com/jj-vcs/jj/wiki/GUI-and-TUI)
+
diff --git a/articles/web_stack.md b/articles/web_stack.md
index 1ffc6d8..d3a41b8 100644
--- a/articles/web_stack.md
+++ b/articles/web_stack.md
@@ -1,6 +1,7 @@
---
title: Web stack
date: 2019-06-26
+update: 2024-11-26
---
Previous stacks
@@ -24,5 +25,5 @@ Pandoc + Tup = ❤️
I decided to use [Pandoc](https://pandoc.org/) to convert from Markdown to HTML.
It is widely used by other generators and takes care of the file conversion.
-For automation, I use a simple top-level Makefile and
+For automation, I use a simple top-level [Justfile](https://just.systems/) and
[Tup](http://gittup.org/tup/index.html).
diff --git a/flake.nix b/flake.nix
index b426747..994956d 100644
--- a/flake.nix
+++ b/flake.nix
@@ -7,10 +7,14 @@
devShell.x86_64-linux = with pkgs;
mkShell {
nativeBuildInputs = [
+ entr
+ graphviz-nox
imagemagick
just
libavif
libjxl
+ nodejs
+ nushell
pandoc
tup
];
diff --git a/justfile b/justfile
index 36a8e8f..04019d3 100644
--- a/justfile
+++ b/justfile
@@ -1,5 +1,5 @@
-# vim: set ft=make :
-root := `pwd`
+root := justfile_directory()
+build := root / "build"
# Build static website
build:
@@ -23,3 +23,13 @@ deploy: build
preview: build
python3 -m webbrowser -t "file://{{root}}/build/index.html"
+
+JJ_SLIDES_SRC := root / "articles/jujutsu/slides.md"
+JJ_SLIDES_OUT := build / "articles/jujutsu/jujutsu_slides.pdf"
+jj-slides:
+ npx @marp-team/marp-cli@latest --allow-local-files \
+ --bespoke.progress {{ JJ_SLIDES_SRC }} --pdf \
+ --output {{ JJ_SLIDES_OUT }}
+
+jj-slides-watch:
+ ls {{ JJ_SLIDES_SRC }} | entr just jj-slides
diff --git a/templates/Tupfile b/templates/Tupfile
deleted file mode 100644
index f179092..0000000
--- a/templates/Tupfile
+++ /dev/null
@@ -1 +0,0 @@
-: |> ./generate_footer.sh > %o |> footer.html ./
diff --git a/templates/footer.html b/templates/footer.html
new file mode 100755
index 0000000..d1d3b81
--- /dev/null
+++ b/templates/footer.html
@@ -0,0 +1,3 @@
+
diff --git a/templates/generate_footer.sh b/templates/generate_footer.sh
deleted file mode 100755
index 54df8f5..0000000
--- a/templates/generate_footer.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/usr/bin/env bash
-
-set -euo pipefail
-
-cat << EOF
-
-EOF