summaryrefslogtreecommitdiff
path: root/docs/site/site.typ
diff options
context:
space:
mode:
Diffstat (limited to 'docs/site/site.typ')
-rw-r--r--docs/site/site.typ161
1 files changed, 161 insertions, 0 deletions
diff --git a/docs/site/site.typ b/docs/site/site.typ
new file mode 100644
index 00000000..03d9a15d
--- /dev/null
+++ b/docs/site/site.typ
@@ -0,0 +1,161 @@
+// The website: one Typst bundle run writes every page, the stylesheet, the
+// fonts and the media. Pages come from `chapters` in ../typ/style.typ, so a
+// new chapter is a new page; the only prose of its own is the landing page.
+// typst compile --root . --format bundle --features bundle,html docs/site/site.typ OUT
+// Every link is relative and every page sits at the top of OUT, so the site
+// works from file:// and from any static server.
+#import "../typ/style.typ": chapters, tutor-path, doc-links, tagline, project
+
+#let clips = toml("media/clips.toml").clip
+#let pages = (
+ (id: "index", title: "pardes"),
+ ..chapters.filter(c => c.file != none).map(c => (id: c.id, title: c.title, file: c.file)),
+ (id: "tutor", title: "The tutor"),
+)
+#let href(id) = id + ".html"
+
+// --- the files that are not pages --------------------------------------------
+
+#asset("site.css", read("site.css", encoding: none))
+#for f in ("DepartureMono-Regular.woff2", "CrimsonPro-VF-normal.woff2", "CrimsonPro-VF-italic.woff2",
+ "LICENSE-DepartureMono.txt", "LICENSE-CrimsonPro.txt") {
+ asset("fonts/" + f, read("fonts/" + f, encoding: none))
+}
+#asset("media/placeholder.svg", read("media/placeholder.svg", encoding: none))
+#for c in clips.filter(c => c.ready) {
+ for ext in ("webm", "mp4", "png") {
+ asset("media/" + c.name + "." + ext, read("media/" + c.name + "." + ext, encoding: none))
+ }
+}
+
+// --- the shell every page sits in ---------------------------------------------
+
+/// An HTML element: el("a", (href: "x.html"))[text], or el("li")[text].
+#let el(tag, ..args) = {
+ let p = args.pos()
+ html.elem(tag, attrs: if p.len() > 1 { p.first() } else { (:) }, p.last())
+}
+
+/// The running head: a tagline, the way a pane's tag reads, with the path
+/// of this page and the chapters as its words.
+#let trail(id, title) = el("header", (class: "trail"))[
+ #el("span", (class: "grip", "aria-hidden": "true"))[]
+ #el("a", (class: "home", href: href("index")))[pardes]
+ #if id != "index" {
+ el("span", (class: "sep", "aria-hidden": "true"))[/]
+ el("span", (class: "here", "aria-current": "page"))[#title]
+ }
+ #el("nav", (class: "words", "aria-label": "Chapters"))[
+ #for p in pages.slice(1) {
+ if p.id == id { el("a", (href: href(p.id), "aria-current": "page"))[#p.title] }
+ else { el("a", (href: href(p.id)))[#p.title] }
+ }
+ ]
+]
+
+#let shell(id, title, body) = html.html(lang: "en", {
+ html.head({
+ html.meta(charset: "utf-8")
+ el("meta", (name: "viewport", content: "width=device-width, initial-scale=1"))[]
+ el("meta", (name: "color-scheme", content: "dark light"))[]
+ html.title(if id == "index" { "pardes" } else { title + " · pardes" })
+ el("link", (rel: "stylesheet", href: "site.css"))[]
+ })
+ html.body({
+ el("div", (class: "shell"))[
+ #trail(id, title)
+ #el("main", (class: "panel", "data-page": id))[
+ #el("article", (class: "content"))[#body]
+ ]
+ #el("footer", (class: "colophon"))[
+ pardes ·
+ #if project.source != none [#el("a", (href: project.source))[source] · ]
+ #if project.license != none [#project.license · ]
+ built from `docs/typ` with Typst ·
+ #el("a", (href: "fonts/LICENSE-DepartureMono.txt"))[fonts] (OFL)
+ ]
+ ]
+ })
+})
+
+/// The headings of this page only, as a contents list, when there are
+/// enough of them to need one.
+#let toc(id) = context {
+ let hs = query(selector(heading.where(level: 2)).after(label("start-" + id)).before(label("end-" + id)))
+ if hs.len() >= 4 {
+ el("nav", (class: "toc", "aria-label": "On this page"))[
+ #el("div", (class: "toc-bar"))[#el("span")[On this page]]
+ #el("ol")[#for h in hs { el("li")[#link(h.location(), h.body)] }]
+ ]
+ }
+}
+
+// --- the pages ------------------------------------------------------------------
+
+#doc-links.update(true)
+
+#let ready = clips.filter(c => c.ready)
+#let start = (
+ (id: "guide", label: [Start: the guide], note: [about 15 min]),
+ (id: "tutor", label: [Hands on: the tutor], note: none),
+)
+
+#document(href("index"), title: "pardes", shell("index", "pardes")[
+ #el("h1", (class: "masthead"))[pardes]
+ #el("p", (class: "lead"))[pardes is an editor and terminal in columns of panes, each
+ a file, a terminal, a PDF or an image. Click any text to run it or open
+ it; the keys are helix's; scripts drive it through files.]
+ #el("p", (class: "pitch"))[#tagline.]
+ #el("p", (class: "runs"))[It runs in a terminal or in its own window (SDL), on Linux;
+ macOS and browser builds are in the tree.]
+ #if ready.len() > 0 {
+ el("img", (class: "hero", src: "media/" + ready.first().name + ".png", alt: ready.first().caption))[]
+ }
+ #el("div", (class: "start"))[
+ #for s in start {
+ el("a", (class: "go", href: href(s.id)))[#s.label#if s.note != none [ #el("span")[(#s.note)]]]
+ }
+ ]
+ #el("p", (class: "rest"))[
+ #for p in pages.slice(1).filter(p => p.id not in start.map(s => s.id)) {
+ el("a", (href: href(p.id)))[#p.title]
+ }
+ ]
+ #el("div", (class: "clips"))[
+ #for c in clips {
+ el("figure", (class: "clip"))[
+ #if c.ready {
+ el("video", (poster: "media/" + c.name + ".png", muted: "", loop: "", playsinline: "",
+ controls: "", preload: "none"))[
+ #el("source", (src: "media/" + c.name + ".webm", type: "video/webm"))[]
+ #el("source", (src: "media/" + c.name + ".mp4", type: "video/mp4"))[]
+ ]
+ } else {
+ el("img", (src: "media/placeholder.svg", alt: "", width: "640", height: "400"))[]
+ }
+ #el("figcaption")[#c.caption]
+ ]
+ }
+ ]
+ #el("h2", (class: "install"))[Install]
+ #include "../typ/install.typ"
+])
+
+#for p in pages.slice(1, -1) {
+ document(href(p.id), title: p.title, shell(p.id, p.title)[
+ #metadata(none) #label("start-" + p.id)
+ #heading(level: 1, p.title) #label("ch-" + p.id)
+ #toc(p.id)
+ #{
+ set heading(offset: 1)
+ include "../typ/" + p.file
+ }
+ #metadata(none) #label("end-" + p.id)
+ ])
+}
+
+#document(href("tutor"), title: "The tutor", shell("tutor", "The tutor")[
+ #heading(level: 1)[The tutor] <tutor>
+ The tutor as the editor shows it (#raw("Tutor"), or #raw("SPC h t")).
+ #el("pre", (class: "tutor"))[#read(tutor-path)]
+])