summaryrefslogtreecommitdiff
path: root/build/jj-log.typ
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-03-27 14:27:19 -0300
committerGabriel Schneider <[email protected]>2026-03-27 15:16:44 -0300
commiteeb2d880626c72b1f94e6d84838d8a0342bb99c7 (patch)
tree510a7030fcbf29f49c6b313fe9602648de928e4f /build/jj-log.typ
parent5d935263f828f8be1037484f22f9181aa9f734c5 (diff)
download0x4200.cafe-eeb2d880626c72b1f94e6d84838d8a0342bb99c7.tar.gz
0x4200.cafe-eeb2d880626c72b1f94e6d84838d8a0342bb99c7.zip
Added jj metadata to page build, orchestrated with nushell and mise
Diffstat (limited to 'build/jj-log.typ')
-rw-r--r--build/jj-log.typ158
1 files changed, 158 insertions, 0 deletions
diff --git a/build/jj-log.typ b/build/jj-log.typ
new file mode 100644
index 0000000..a1b36a9
--- /dev/null
+++ b/build/jj-log.typ
@@ -0,0 +1,158 @@
+// jj-log.typ — Typst document that renders jj log JSON output
+//
+// Usage:
+// jj log -r '::@' --no-graph \
+// -T '{"commit": ' ++ json(self) ++ ', "bookmarks": ' ++ json(local_bookmarks) ++ ', "empty": ' ++ if(empty, "true", "false") ++ ', "conflict": ' ++ if(conflict, "true", "false") ++ ', "root": ' ++ if(root, "true", "false") ++ '}\n' \
+// > log.json
+// typst compile jj-log.typ --input data=log.json
+
+#let data-path = sys.inputs.at("data", default: "log.json")
+#let raw-text = read(data-path)
+#let lines = raw-text.split("\n").filter(l => l.trim() != "")
+#let commits = lines.map(l => json(bytes(l)))
+
+// Filter out root commit
+#let commits = commits.filter(c => not c.root)
+
+// --- Helpers ---
+
+#let mono(body) = text(font: "DejaVu Sans Mono", size: 0.85em, body)
+#let short(hash) = hash.slice(0, 8)
+#let tag-pill(name, color: rgb("#4a6fa5")) = {
+ box(
+ fill: color.lighten(75%),
+ stroke: 0.5pt + color,
+ radius: 3pt,
+ inset: (x: 4pt, y: 2pt),
+ text(size: 0.8em, font: "DejaVu Sans Mono", fill: color, weight: "bold", name),
+ )
+}
+
+#let format-date(ts) = {
+ // timestamp is ISO 8601, e.g. "2026-03-27T14:22:35-03:00"
+ // extract date + time portion
+ let date-part = ts.slice(0, 10)
+ let time-part = ts.slice(11, 16)
+ date-part + " " + time-part
+}
+
+// Collect all bookmarks across commits
+#let all-bookmarks = commits.map(c => {
+ c.bookmarks.map(b => (name: b.name, commit: short(c.commit.commit_id), change: short(c.commit.change_id), desc: c.commit.description.trim()))
+}).flatten()
+
+// --- Page setup ---
+
+#set page(paper: "a4", margin: 2cm)
+#set text(font: "DejaVu Sans", size: 10pt)
+#set par(leading: 0.6em)
+
+// --- Title ---
+
+#align(center)[
+ #text(size: 18pt, weight: "bold")[jj ancestor log]
+ #v(0.3em)
+ #text(size: 9pt, fill: gray)[
+ #commits.len() commits #h(1em)
+ #all-bookmarks.len() bookmarks #h(1em)
+ newest → oldest
+ ]
+]
+
+#v(1em)
+
+// --- Bookmarks index ---
+
+#if all-bookmarks.len() > 0 [
+ == Bookmarks
+
+ #for bm in all-bookmarks [
+ - #tag-pill(bm.name) #h(0.5em) at #mono(bm.commit) — #emph(bm.desc)
+ ]
+
+ #v(1em)
+]
+
+// --- Commit log table ---
+
+== Commit History
+
+#table(
+ columns: (auto, auto, 1fr, auto),
+ align: (center, center, left, right),
+ stroke: 0.4pt + luma(200),
+ inset: 6pt,
+
+ // Header
+ table.header(
+ text(weight: "bold")[Change],
+ text(weight: "bold")[Commit],
+ text(weight: "bold")[Description],
+ text(weight: "bold")[Date],
+ ),
+
+ // Rows — newest to oldest (jj log default order with ::@)
+ ..commits.map(c => {
+ let bookmarks = c.bookmarks.map(b => tag-pill(b.name))
+ let is-empty = c.empty
+ let has-conflict = c.conflict
+ let desc = c.commit.description.trim()
+ if desc == "" { desc = "(no description)" }
+
+ let badges = {
+ if is-empty { tag-pill("empty", color: rgb("#999")) }
+ if has-conflict { tag-pill("conflict", color: rgb("#c44")) }
+ }
+
+ (
+ mono(short(c.commit.change_id)),
+ mono(short(c.commit.commit_id)),
+ [
+ #desc
+ #if bookmarks.len() > 0 { h(0.5em); bookmarks.join(h(0.3em)) }
+ #badges
+ ],
+ text(size: 0.85em, fill: luma(100), format-date(c.commit.author.timestamp)),
+ )
+ }).flatten(),
+)
+
+// --- Detailed list ---
+
+#v(1.5em)
+
+== Commit Details
+
+#for (i, c) in commits.enumerate() [
+ #let desc = c.commit.description.trim()
+ #if desc == "" { desc = "(no description)" }
+ #let bookmarks = c.bookmarks.map(b => tag-pill(b.name))
+
+ #block(
+ width: 100%,
+ inset: 8pt,
+ radius: 4pt,
+ stroke: 0.3pt + luma(200),
+ fill: if calc.even(i) { luma(252) } else { white },
+ )[
+ #grid(
+ columns: (auto, 1fr),
+ column-gutter: 1em,
+ row-gutter: 0.4em,
+ text(fill: luma(120), size: 0.85em)[change:], mono(short(c.commit.change_id)),
+ text(fill: luma(120), size: 0.85em)[commit:], mono(short(c.commit.commit_id)),
+ text(fill: luma(120), size: 0.85em)[author:], [#c.commit.author.name #text(fill: luma(120))[\<#c.commit.author.email\>]],
+ text(fill: luma(120), size: 0.85em)[date:], format-date(c.commit.author.timestamp),
+ ..if bookmarks.len() > 0 {(
+ text(fill: luma(120), size: 0.85em)[bookmarks:],
+ bookmarks.join(h(0.3em)),
+ )},
+ )
+ #v(0.3em)
+ #text(weight: "bold", size: 1.05em, desc)
+ #if c.empty [ #text(fill: luma(150), size: 0.85em)[\[empty\]] ]
+ #if c.conflict [ #text(fill: rgb("#c44"), size: 0.85em)[\[conflict\]] ]
+ ]
+
+ #v(0.5em)
+]