summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/site/site.css3
-rw-r--r--docs/site/site.typ31
-rw-r--r--docs/typ/guide.typ5
-rw-r--r--docs/typ/style.typ22
4 files changed, 44 insertions, 17 deletions
diff --git a/docs/site/site.css b/docs/site/site.css
index dc682eff..260a1b35 100644
--- a/docs/site/site.css
+++ b/docs/site/site.css
@@ -214,3 +214,6 @@ main[data-page="builtins"] .content h4 + p { margin-top:0; }
.mode-box { display:inline-flex; align-items:center; justify-content:center; width:1.15em; height:1.15em; vertical-align:-.15em;
font:700 .8em var(--mono); background:var(--tag); color:var(--ink); border:2px solid var(--leaf); border-radius:2px; }
.mode-box.unsaved { background:var(--amber); border-color:var(--amber); color:#1b120a; }
+/* a recording inside a chapter */
+.content .clip.inline { margin:1.2em 0; max-width:640px; }
+.clip.inline video { display:block; width:100%; height:auto; aspect-ratio:960/700; background:var(--deep); }
diff --git a/docs/site/site.typ b/docs/site/site.typ
index 62b1292e..f50a8d9b 100644
--- a/docs/site/site.typ
+++ b/docs/site/site.typ
@@ -98,6 +98,20 @@
]
]
+#let in-view-script = el("script")[#(
+ "(() => { if (!('IntersectionObserver' in window)) return;
+" +
+ " const p = el => el.player || (el.tagName === 'VIDEO' ? el : null);
+" +
+ " const io = new IntersectionObserver(es => { for (const e of es) { const r = p(e.target); if (!r) continue;
+" +
+ " if (e.isIntersecting) Promise.resolve(r.play()).catch(() => {}); else r.pause(); } }, {threshold: 0.25});
+" +
+ " for (const el of document.querySelectorAll('.clip video, .cast .player')) io.observe(el);
+" +
+ "})();"
+)]
+
#let shell(id, title, body) = html.html(lang: "en", {
html.head({
html.meta(charset: "utf-8")
@@ -122,6 +136,9 @@
#el("a", (href: "player/LICENSE-asciinema-player.txt"))[asciinema-player] (Apache-2.0)
]
]
+ // after the page's own scripts (the landing's players), on every page
+ // that has a recording
+ in-view-script
})
})
@@ -179,19 +196,6 @@
/// Plays a recording while it is on screen and pauses it once it leaves.
/// The casts wait for it (autoPlay off) so each shows its poster frame
/// until then; the videos autoplay by themselves too.
-#let in-view-script = el("script")[#(
- "(() => { if (!('IntersectionObserver' in window)) return;
-" +
- " const p = el => el.player || (el.tagName === 'VIDEO' ? el : null);
-" +
- " const io = new IntersectionObserver(es => { for (const e of es) { const r = p(e.target); if (!r) continue;
-" +
- " if (e.isIntersecting) Promise.resolve(r.play()).catch(() => {}); else r.pause(); } }, {threshold: 0.25});
-" +
- " for (const el of document.querySelectorAll('.clip video, .cast .player')) io.observe(el);
-" +
- "})();"
-)]
#document(href("index"), title: "pardes", shell("index", "pardes")[
#el("h1", (class: "masthead"))[pardes]
@@ -231,7 +235,6 @@
el("link", (rel: "stylesheet", href: "player/asciinema-player.css"))[]
player-script
}
- #in-view-script
])
#for p in pages.slice(1, -1) {
diff --git a/docs/typ/guide.typ b/docs/typ/guide.typ
index 9149969a..cf1e758c 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, glossary, annotated
+#import "style.typ": key, keys, btn, chord, word, tag, addr, file, cmd, doc, pairs, glossary, annotated, clip
Two clicks carry pardes: #word("Look") (right-click) opens `src/bar.c:12`, and #word("Exec") (middle-click) runs `make`.
@@ -73,8 +73,7 @@ before #key("Ctrl-w") or #key("Alt-n").
[Super-click (Cmd)], [#btn("B3"); not in a terminal, which never passes Super],
[Ctrl-click], [the language server's definition],
)
-// TODO: embed the `chords` clip here on the site once it lands (needs a
-// clip hook in style.typ).
+#clip("chords")
A program that takes the mouse gets the plain click.
diff --git a/docs/typ/style.typ b/docs/typ/style.typ
index 23bdab3c..9753eedf 100644
--- a/docs/typ/style.typ
+++ b/docs/typ/style.typ
@@ -584,3 +584,25 @@
fill: if unsaved { white } else { palette.ink }, mark)))
}
}
+
+/// A recording from docs/site/media/clips.toml, by name. On the site the
+/// same video as the landing's (poster, autoplay muted loop, played while
+/// in view) and its caption; in print its poster, small, and the caption.
+#let clip(name) = {
+ let c = toml("../site/media/clips.toml").clip.find(c => c.name == name)
+ assert(c != none, message: "no clip named " + name + " in clips.toml")
+ let said = if c.caption.contains("#") { eval(c.caption, mode: "markup") } else { c.caption }
+ context if html-out() {
+ html.elem("figure", attrs: (class: "clip inline", id: "rec-" + c.name), {
+ html.elem("video", attrs: (poster: "media/" + c.name + ".png", autoplay: "", muted: "", loop: "",
+ playsinline: "", controls: ""), {
+ html.elem("source", attrs: (src: "media/" + c.name + ".webm", type: "video/webm"))
+ html.elem("source", attrs: (src: "media/" + c.name + ".mp4", type: "video/mp4"))
+ })
+ html.elem("figcaption", said)
+ })
+ } else {
+ figure(image("/docs/site/media/" + c.name + ".png", width: 7cm, alt: c.caption),
+ caption: text(size: 0.9em, said), numbering: none, kind: "clip", supplement: none)
+ }
+}