diff --git a/Tuprules.tup b/Tuprules.tup
index 3712e6e..a1c3ed5 100644
--- a/Tuprules.tup
+++ b/Tuprules.tup
@@ -24,3 +24,11 @@ HTML_TEMPLATE = main.html
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 2762b5e..7a69288 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/generate_listing.nu b/articles/generate_listing.nu
index 8df24a7..2af678a 100755
--- a/articles/generate_listing.nu
+++ b/articles/generate_listing.nu
@@ -1,31 +1,39 @@
#!/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 |
+#
+def title [path: string] -> string {
+ open $path | lines | filter {|l| (str starts-with "title:")} | first | split row --regex 'title\s*:\s*' | get 1 | str trim --char "\""
}
-
+
+def creation_date [path: string] -> string {
+ open $path | lines | filter {|l| (str starts-with "date:")} | first | split row --regex '\s*:\s*' | get 1
+}
+
+def update_date [path: string] -> string? {
+ let updates = open $path | lines | filter {|l| (str starts-with "update:")}
+ if ($updates | length) > 0 {
+ return ($updates | first | split row --regex '\s*:\s*' | get 1)
+ } else {
+ return null
+ }
+}
+
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
+ | upsert title {|row| (title $row.path)}
+ | upsert creation {|row| (creation_date $row.path)}
+ | upsert update {|row| (update_date $row.path)}
+ | sort-by --reverse creation
print "---
title: Articles
---
"
-let _ = $sorted_pages | each {|p|
+$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)\)"
+ print --no-newline $"- ($p.creation): [($p.title)]\(($rel_path)\)"
+ if $p.update? != null {
+ print $" \(Updated: ($p.update)\)"
} else {
print ""
}
diff --git a/articles/generate_listing.sh b/articles/generate_listing.sh
new file mode 100755
index 0000000..cf62c2d
--- /dev/null
+++ b/articles/generate_listing.sh
@@ -0,0 +1,23 @@
+#!/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..df556c8
--- /dev/null
+++ b/articles/jujutsu/Tupfile
@@ -0,0 +1,6 @@
+include_rules
+HTML_TEMPLATE = article.html
+
+: slides.md |> !marp_pdf |> jujutsu_slides.pdf ./
+: index.md | ./ |> !html |>
+
diff --git a/articles/jujutsu/index.md b/articles/jujutsu/index.md
new file mode 100644
index 0000000..78dcf25
--- /dev/null
+++ b/articles/jujutsu/index.md
@@ -0,0 +1,16 @@
+---
+title: "Lightning talk: Jujutsu"
+date: 2024-11-26
+---
+
+_This article is also available as a lightning talk: [pdf](./jujutsu_slides.pdf)_
+
+## What is it?
+
+## How does it compare?
+
+## VCS landscape
+> 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)_
diff --git a/articles/jujutsu/slides.md b/articles/jujutsu/slides.md
new file mode 100644
index 0000000..b3ab148
--- /dev/null
+++ b/articles/jujutsu/slides.md
@@ -0,0 +1,23 @@
+---
+marp: true
+theme: gaia
+footer: '**Fabien Freling** - 2024-11-26'
+paginate: true
+---
+
+
+
+
+
+
+# Jujutsu
+
+Life after Git
+
+---
diff --git a/articles/web_stack.md b/articles/web_stack.md
index 1ffc6d8..bface29 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
diff --git a/flake.nix b/flake.nix
index e0c7923..df507e3 100644
--- a/flake.nix
+++ b/flake.nix
@@ -7,10 +7,12 @@
devShell.x86_64-linux = with pkgs;
mkShell {
nativeBuildInputs = [
+ graphviz-nox
imagemagick
just
libavif
libjxl
+ nodejs
nushell
pandoc
tup