diff options
Diffstat (limited to 'docs/site/site.typ')
| -rw-r--r-- | docs/site/site.typ | 161 |
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)] +]) |
