summaryrefslogtreecommitdiff
path: root/docs/typ/style.typ
diff options
context:
space:
mode:
Diffstat (limited to 'docs/typ/style.typ')
-rw-r--r--docs/typ/style.typ101
1 files changed, 101 insertions, 0 deletions
diff --git a/docs/typ/style.typ b/docs/typ/style.typ
new file mode 100644
index 00000000..7cb05e23
--- /dev/null
+++ b/docs/typ/style.typ
@@ -0,0 +1,101 @@
+// The semantic elements every docs/typ topic uses, and the one place they
+// are defined. Content files call them ("this is a key", "this is a
+// builtin"); how each looks is decided here, per output: paged outputs
+// (the A4 cheatsheet, later the book) draw them, HTML export gives them
+// elements and classes for a stylesheet. Page geometry and fonts belong to
+// the output wrappers beside this file.
+
+/// The `atelier` theme (src/themes/atelier.zig): pardes's acme homage,
+/// butter paper and blue-green tags.
+#let palette = (
+ paper: rgb("#fffdeb"),
+ ink: rgb("#293f35"),
+ tag-bg: rgb("#e4f0ed"),
+ tag-fg: rgb("#3d6055"),
+ tag-name: rgb("#6e4774"),
+ grip: rgb("#36826b"),
+ col-grip: rgb("#955815"),
+ str: rgb("#34743d"),
+ num: rgb("#9a5810"),
+ rule: rgb("#95baa2"),
+)
+#let mono = "DejaVu Sans Mono"
+
+/// Topic ids for #doc. Each names the document that holds the topic today;
+/// as topics move into docs/typ the value becomes the HTML page or chapter.
+#let topics = (
+ tags: "docs/tags.md",
+ fs: "docs/fs.md",
+ config: "docs/config.md",
+ themes: "docs/themes.md",
+ keys: "docs/helix-keys.md",
+ detached: "docs/detached.md",
+)
+
+#let html-out() = target() == "html"
+#let span(class, body) = html.elem("span", attrs: (class: class), body)
+#let m(s, fill: palette.ink) = text(font: mono, size: 0.92em, fill: fill, s)
+
+/// A key or a sequence of keys, one cap per space-separated chord.
+#let key(k) = context if html-out() {
+ k.split(" ").map(t => html.elem("kbd", t)).join(" ")
+} else {
+ k.split(" ").map(t => box(
+ fill: white, stroke: 0.4pt + palette.rule, radius: 1.5pt,
+ inset: (x: 1.6pt, y: 0pt), outset: (y: 1.4pt), m(t),
+ )).join(h(1pt))
+}
+
+/// A mouse button.
+#let btn(b) = context if html-out() { span("btn", b) } else {
+ box(
+ fill: palette.col-grip, radius: 2pt, inset: (x: 1.6pt, y: 0pt), outset: (y: 1.4pt),
+ text(font: mono, size: 0.85em, weight: "bold", fill: white, b),
+ )
+}
+
+/// A chord: the first button held, the others clicked.
+#let chord(..bs) = bs.pos().map(btn).join(text(fill: palette.col-grip)[--])
+
+/// A tag word or builtin, as it sits in a tag.
+#let word(w) = context if html-out() { span("word", raw(w)) } else {
+ box(fill: palette.tag-bg, inset: (x: 1.4pt, y: 0pt), outset: (y: 1.4pt), m(w, fill: palette.tag-fg))
+}
+
+/// 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"), {
+ if path != none { span("path", path); [ ] }
+ raw(words)
+ })
+} else {
+ block(width: 100%, fill: palette.tag-bg, inset: (x: 2pt, y: 2.4pt), spacing: 0.5em, {
+ box(fill: palette.grip, width: 0.55em, height: 0.75em, baseline: 0.1em)
+ h(3pt)
+ if path != none { m(path, fill: palette.tag-name); h(0.6em) }
+ m(words, fill: palette.tag-fg)
+ })
+}
+
+/// A look address.
+#let addr(a) = context if html-out() { span("addr", raw(a)) } else { m(a, fill: palette.tag-name) }
+
+/// A 9P path.
+#let file(p) = context if html-out() { span("file", raw(p)) } else { m(p, fill: palette.str) }
+
+/// A shell line.
+#let cmd(c) = context if html-out() { raw(c, block: true, lang: "sh") } else {
+ block(
+ width: 100%, inset: (left: 3pt, y: 1.2pt), spacing: 0.4em,
+ stroke: (left: 1pt + palette.rule),
+ text(font: mono, size: 0.85em, fill: palette.ink, c),
+ )
+}
+
+/// Where the full story is: a topic id from `topics`, and a section in it.
+#let doc(id, section: none) = {
+ let to = topics.at(id) + if section != none { "#" + section } else { "" }
+ context if html-out() { link(to)[→ #to] } else {
+ text(fill: palette.num)[→#m(to, fill: palette.num)]
+ }
+}