summaryrefslogtreecommitdiff
path: root/docs/typ
diff options
context:
space:
mode:
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)
+}