summaryrefslogtreecommitdiff
path: root/docs/typ
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-10-01 11:11:25 -0300
committerGabriel Schneider <[email protected]>2026-10-01 12:24:31 -0300
commit5874742494a293c5e285d2f1284c748e39d980f8 (patch)
treee3fa445947f90e2e6262b3466430b901d2e62295 /docs/typ
parentd3638abbb3d177ea08beed3b09cd9682b3732daf (diff)
downloadpardes-5874742494a293c5e285d2f1284c748e39d980f8.tar.gz
pardes-5874742494a293c5e285d2f1284c748e39d980f8.zip
The docs become a website: a page per chapter, a landing page with recordings, one Typst bundle run
docs/site/site.typ writes every page in one bundle compile: the landing page (the tagline, the recordings listed in media/clips.toml, links to start from), a page per entry of `chapters` in style.typ, and the tutor. Every page shares a tag-line header with the chapter words; #doc links resolve to the right page and anchor; a chapter with four or more sections gets an "On this page" list. Links are relative and pages flat, so it reads from file:// or any static server. `zig build site` installs it to <prefix>/share/doc/pardes/site and fails plainly without typst. The look is 0x4200.cafe's lapis layout (framed panels, hard shadows, a tag-line trail, Departure Mono headings over Crimson Pro) in orchard's greens and amber, forestbones_light when the reader prefers light; both fonts are OFL and shipped. In HTML a key is one pill with its + and ›, and a mouse button is an inline SVG in currentColor. The tagline lives once in style.typ for the sheet, the book and the site, and the single page html.typ gives way to the site. The landing leads with one plain sentence (columns of panes, click to run or open, helix keys, scripts through files), then the tagline and a line on where it runs; a hero image is the first ready clip's poster; "Start: the guide" leads the links, "Hands on: the tutor" next, the rest a plain row; the captions use no undefined words. docs/typ/install.typ holds the install lines once: setup.typ has an Install section that includes it, and the landing includes it too. Building says up front it is for contributors and points at setup to install. In HTML the guide's glossary is a closed <details> (#glossary, the same heading and table on paper), each drawn mouse carries hidden text (left-click, hold left, click middle) for screen readers, w3m and copying, and the footer takes a source link and a licence from `project` in style.typ once decided. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'docs/typ')
-rw-r--r--docs/typ/README8
-rw-r--r--docs/typ/book.typ4
-rw-r--r--docs/typ/building.typ3
-rw-r--r--docs/typ/cheatsheet-a4.typ4
-rw-r--r--docs/typ/guide.typ6
-rw-r--r--docs/typ/html.typ24
-rw-r--r--docs/typ/install.typ8
-rw-r--r--docs/typ/setup.typ3
-rw-r--r--docs/typ/style.typ63
9 files changed, 84 insertions, 39 deletions
diff --git a/docs/typ/README b/docs/typ/README
index 048e5d01..522d99ff 100644
--- a/docs/typ/README
+++ b/docs/typ/README
@@ -10,8 +10,9 @@ docs/typ: the Typst documentation corpus
cheatsheet-a4.typ output wrapper: the one-page A4 cheatsheet.
book.typ output wrapper: an A4 book, title page, contents,
every chapter, then the tutor (src/tutor.txt).
- html.typ output wrapper: one HTML page, every chapter under
- an anchor named by its id, then the tutor.
+ ../site/site.typ output wrapper: the website, a page per chapter plus
+ the landing page and the tutor, in one Typst bundle
+ run (see docs/site/README).
Wrappers hold layout only, never facts.
Chapters: `chapters` in style.typ lists them in reading order (guide, setup,
@@ -27,7 +28,8 @@ Build (from the repo root):
typst compile --ignore-system-fonts docs/typ/cheatsheet-a4.typ
zig build cheatsheet -Dplatform=tty --prefix DIR # DIR/share/doc/pardes/cheatsheet.pdf
typst compile --root . --ignore-system-fonts docs/typ/book.typ
- typst compile --root . --features html --format html docs/typ/html.typ pardes.html
+ typst compile --root . --format bundle --features bundle,html docs/site/site.typ OUT
+ zig build site -Dplatform=tty --prefix DIR # DIR/share/doc/pardes/site/
(--root . because book and HTML read the tutor from src/tutor.txt.)
The contract for content files
diff --git a/docs/typ/book.typ b/docs/typ/book.typ
index a89b52cc..7223ea1d 100644
--- a/docs/typ/book.typ
+++ b/docs/typ/book.typ
@@ -2,7 +2,7 @@
// content files named by `chapters` in style.typ; this is layout only.
// typst compile --root . --ignore-system-fonts docs/typ/book.typ
// (--root . because the tutor is read from src/tutor.txt.)
-#import "style.typ": palette, mono, chapters, tutor-path, doc-links
+#import "style.typ": palette, mono, chapters, tutor-path, doc-links, tagline
#set document(title: "pardes")
#doc-links.update(true)
@@ -29,7 +29,7 @@
v(1fr)
text(size: 34pt, weight: "bold", fill: palette.tag-name)[pardes]
v(4mm)
- text(size: 13pt, style: "italic", fill: palette.tag-fg)[acme's tags and three buttons, helix's keys, terminals as panes, the editor as a 9P filesystem]
+ text(size: 13pt, style: "italic", fill: palette.tag-fg, tagline)
v(2fr)
})
diff --git a/docs/typ/building.typ b/docs/typ/building.typ
index a261a913..ab26e44c 100644
--- a/docs/typ/building.typ
+++ b/docs/typ/building.typ
@@ -3,6 +3,9 @@
// threads, detached sessions, the 9P engine, the listeners and mounts.
#import "style.typ": key, keys, btn, chord, word, tag, addr, file, cmd, doc, pairs
+For contributors: how pardes is built, tested and released, and how its
+pieces fit. To install it, see #doc("setup", section: "install").
+
= Platforms
Zig *0.16.0* (`build.zig.zon` pins `minimum_zig_version`). Dependencies are
diff --git a/docs/typ/cheatsheet-a4.typ b/docs/typ/cheatsheet-a4.typ
index 6f22f723..7694382f 100644
--- a/docs/typ/cheatsheet-a4.typ
+++ b/docs/typ/cheatsheet-a4.typ
@@ -2,7 +2,7 @@
// cheatsheet.typ and the elements' look in style.typ; this is page,
// type and headings only.
// typst compile --ignore-system-fonts docs/typ/cheatsheet-a4.typ
-#import "style.typ": palette, mono, density
+#import "style.typ": palette, mono, density, tagline
#set page(paper: "a4", fill: palette.paper, margin: (x: 9mm, y: 8mm), columns: 3)
#set columns(gutter: 4.5mm)
@@ -21,7 +21,7 @@
block(width: 100%, inset: (bottom: 2pt), stroke: (bottom: 0.6pt + palette.grip), {
text(size: 15pt, weight: "bold", fill: palette.tag-name)[pardes]
h(1fr)
- text(size: 9pt, style: "italic", fill: palette.tag-fg)[acme's tags and three buttons, helix's keys, terminals as panes, the editor as a 9P filesystem]
+ text(size: 9pt, style: "italic", fill: palette.tag-fg, tagline)
}))
#show heading.where(level: 2): it => block(
width: 100%, fill: palette.tag-bg, inset: (x: 2pt, y: 2pt), above: 0.75em, below: 0.4em,
diff --git a/docs/typ/guide.typ b/docs/typ/guide.typ
index a7320865..855fcde4 100644
--- a/docs/typ/guide.typ
+++ b/docs/typ/guide.typ
@@ -1,7 +1,7 @@
// The guide: pardes day to day, the path a newcomer reads once. Edge cases
// live in the reference, the pager and the language servers in setup, the
// keys on the cheatsheet.
-#import "style.typ": key, keys, btn, chord, word, tag, addr, file, cmd, doc, pairs
+#import "style.typ": key, keys, btn, chord, word, tag, addr, file, cmd, doc, pairs, glossary
pardes is a screen of columns. Each column holds panes, and each pane is a
tag (a line of words) over a body: a file, a terminal, a PDF or an image.
@@ -9,9 +9,7 @@ Above the columns runs the workspace tag, and each column has a tag of its
own. Any text anywhere can be clicked: #btn("B2") runs it, #btn("B3") looks
at it. The keys are helix's, in modes.
-= Words you'll see <words>
-
-#pairs(
+#glossary("Words you'll see", <words>,
[tag], [the line of words over a pane, a column or the screen; every word in it can be clicked],
[the pane with the keyboard], [where your keys go; one pane at a time],
[the session's directory], [where pardes started, or the directory `pardes DIR` named; workspace and column tags run there],
diff --git a/docs/typ/html.typ b/docs/typ/html.typ
deleted file mode 100644
index 5f9082cd..00000000
--- a/docs/typ/html.typ
+++ /dev/null
@@ -1,24 +0,0 @@
-// The HTML documentation: one page holding every topic in reading order,
-// each under an anchor named by its id, then the tutor.
-// typst compile --root . --features html --format html docs/typ/html.typ pardes.html
-// One page because Typst 0.15's HTML export writes one document per run.
-#import "style.typ": chapters, tutor-path, doc-links
-
-#set document(title: "pardes")
-#doc-links.update(true)
-
-#html.elem("nav", {
- for ch in chapters [- #link(label("ch-" + ch.id), ch.title)]
- [- #link(<tutor>)[The tutor]]
-})
-
-#for ch in chapters [
- #heading(level: 1, ch.title) #label("ch-" + ch.id)
- #if ch.file == none [_This chapter is not written yet._] else {
- set heading(offset: 1)
- include ch.file
- }
-]
-
-= The tutor <tutor>
-#raw(read(tutor-path), block: true)
diff --git a/docs/typ/install.typ b/docs/typ/install.typ
new file mode 100644
index 00000000..9114f44c
--- /dev/null
+++ b/docs/typ/install.typ
@@ -0,0 +1,8 @@
+// Installing pardes, in three lines: included by setup.typ and by the
+// site's landing page, so it is written once.
+#import "style.typ": cmd
+
+With Zig 0.16 (the build fetches everything else):
+#cmd("zig build -Dplatform=tty --prefix ~/.local # pardes, in a terminal")
+#cmd("zig build -Dplatform=gui --prefix ~/.local # pardes-gui, its own window")
+Then run `pardes` or `pardes FILE`.
diff --git a/docs/typ/setup.typ b/docs/typ/setup.typ
index 45767757..1ed6447b 100644
--- a/docs/typ/setup.typ
+++ b/docs/typ/setup.typ
@@ -5,6 +5,9 @@
pardes runs as it is; a few lines elsewhere make it fit.
+= Install <install>
+#include "install.typ"
+
= A 9P mount: 9ns <ninens>
`9ns`, from cloud9 (`git.sr.ht/~gbrls/cloud9`, whose `zig build` builds it
diff --git a/docs/typ/style.typ b/docs/typ/style.typ
index cf55ae86..903a8273 100644
--- a/docs/typ/style.typ
+++ b/docs/typ/style.typ
@@ -56,9 +56,12 @@
(id: "scripting", title: "Scripting", file: "scripting.typ"),
(id: "reference", title: "Reference", file: "reference.typ"),
(id: "themes", title: "Themes", file: "themes.typ"),
- (id: "building", title: "Building", file: "building.typ"),
+ (id: "building", title: "Building, for contributors", file: "building.typ"),
)
+/// The one-line pitch: the A4 sheet's header and the site's landing page.
+#let tagline = "acme's tags and three buttons, helix's keys, terminals as panes, the editor as a 9P filesystem"
+
/// The tutor, shown as it is in the editor (`Tutor`), from the repo root.
#let tutor-path = "/src/tutor.txt"
@@ -75,7 +78,9 @@
/// pill: a combination's parts joined by a muted +, a sequence's steps by a
/// muted › (`Ctrl-w h` reads Ctrl + w › h).
#let key(k) = context if html-out() {
- html.elem("kbd", k.split(" ").map(t => html.elem("kbd", t)).join(" "))
+ let sep(c, cls) = html.elem("span", attrs: (class: cls, "aria-hidden": "true"), c)
+ let press(t) = (if t.len() > 1 and t.contains("-") { t.split("-") } else { (t,) }).join(sep("+", "plus"))
+ html.elem("kbd", attrs: (class: "key"), k.split(" ").map(press).join(sep("›", "then")))
} else {
let muted(c) = text(fill: palette.grip.transparentize(25%), size: 0.85em, c)
let press(t) = (if t.len() > 1 and t.contains("-") { t.split("-") } else { (t,) }).join(muted[+])
@@ -91,6 +96,9 @@
#let keys(..ks) = context ks.pos().map(key).join(if html-out() [ ] else { h(0.25em) })
#let button-names = ("B1": "left button", "B2": "wheel", "B3": "right button")
+#let click-names = ("B1": "left", "B2": "middle", "B3": "right")
+/// Text that is read and copied but not shown, beside a drawn glyph.
+#let hidden(t) = html.elem("span", attrs: (class: "vh"), t)
/// A mouse, about cap height: left button, wheel, right button. The parts
/// in `pressed` ("B1", "B2", "B3") are filled.
@@ -116,10 +124,33 @@
})
}
+/// The same mouse as inline SVG for HTML. Each part is classed `on`
+/// (pressed) or `off`, and the stylesheet colours them: the pressed part
+/// filled in the accent, the rest outlined and muted.
+#let mouse-svg(pressed) = {
+ let cls(b) = if b in pressed { "on" } else { "off" }
+ let part(d, b) = html.elem("path", attrs: (class: cls(b), d: d))
+ html.elem("svg", attrs: (class: "mouse", viewBox: "-6 -6 96 132", "aria-hidden": "true"), {
+ // taller buttons and a slimmer wheel than on paper, so a pressed
+ // button shows as a solid block at body size
+ part("M0 64H84V78A42 42 0 0 1 0 78Z", none)
+ part("M0 64V42A42 42 0 0 1 42 0V64Z", "B1")
+ part("M42 0A42 42 0 0 1 84 42V64H42Z", "B3")
+ // a pressed wheel is drawn wider, so it reads as pressed, not as a seam
+ let (hx, hw, wx, ww) = if "B2" in pressed { ("27", "30", "31", "22") } else { ("31", "22", "35", "14") }
+ html.elem("rect", attrs: (class: "halo", x: hx, y: "4", width: hw, height: "48", rx: "13"))
+ html.elem("rect", attrs: (class: "wheel " + cls("B2"), x: wx, y: "8", width: ww, height: "40", rx: "9"))
+ })
+}
+
/// A mouse button; `shift: true` for the button with Shift held.
#let btn(b, shift: false) = context if html-out() {
let label = (if shift { "shift " } else { "" }) + button-names.at(b)
- html.elem("span", attrs: (class: "btn", aria-label: label, title: label), (if shift { "⇧" } else { "" }) + b)
+ html.elem("span", attrs: (class: "btn", title: label), {
+ if shift { html.elem("span", attrs: (class: "shift", "aria-hidden": "true"), "⇧") }
+ mouse-svg((b,))
+ hidden((if shift { "Shift-" } else { "" }) + click-names.at(b) + "-click")
+ })
} else {
if shift { text(size: 0.8em, fill: palette.col-grip)[⇧] }
mouse((b,))
@@ -130,7 +161,13 @@
/// down, with arrows between.
#let chord(..bs) = context if html-out() {
let label = bs.pos().map(b => button-names.at(b)).join(" then ")
- html.elem("span", attrs: (class: "chord", aria-label: label, title: label), bs.pos().join("-"))
+ let (held, ..clicks) = bs.pos()
+ let arrow = html.elem("span", attrs: (class: "then", "aria-hidden": "true"), "›")
+ let said = "hold " + click-names.at(held) + ", click " + clicks.map(c => click-names.at(c)).join(", then ")
+ html.elem("span", attrs: (class: "chord", title: label), {
+ ((mouse-svg((held,)),) + clicks.map(c => mouse-svg((held, c)))).join(arrow)
+ hidden(said)
+ })
} else {
let (held, ..clicks) = bs.pos()
let arrow = text(size: 0.75em, fill: palette.col-grip)[#h(0.5pt)›#h(0.5pt)]
@@ -145,6 +182,7 @@
/// A whole tagline: its grip, the path, then its words.
#let tag(words, path: none) = context if html-out() {
html.elem("div", attrs: (class: "tag"), {
+ html.elem("span", attrs: (class: "grip", "aria-hidden": "true"))[]
if path != none { span("path", path); [ ] }
raw(words)
})
@@ -215,3 +253,20 @@
}
}
}
+
+/// Where pardes lives and under what licence, for the site's footer (and
+/// any output that wants them). none until decided.
+#let project = (source: none, license: none)
+
+/// A glossary: like #pairs, under its own heading. On paper the heading
+/// and the table; in HTML a <details> that starts closed, its summary the
+/// heading and the count, so a reader who knows the words skips them.
+#let glossary(title, lbl, ..cells) = context if html-out() {
+ html.elem("details", attrs: (class: "glossary"), {
+ html.elem("summary", [#heading(title) #lbl #html.elem("span", attrs: (class: "count"), "(" + str(calc.quo(cells.pos().len(), 2)) + ")")])
+ pairs(..cells)
+ })
+} else {
+ [#heading(title) #lbl]
+ pairs(..cells)
+}