grace/typst_web_magic

Typst SSG powering grace.pink and words.gay

git clone https://git.gae.moe/grace/typst_web_magic

Grace Yoderadded template, readme, and minor changes5b6c1ba

main
2.7 KiB103 linesraw

#import "metadata.typ": author-text, format-date#import "color/rose-pine-dawn.typ": rose-pine-dawn as dawn#import "color/rose-pine-moon.typ": rose-pine-moon as moon

#let code-theme = moon.codeThemePath

#let rule(length: 100%, fade-both: false) = line( length: length, stroke: 1pt + if fade-both { gradient.linear( (dawn.rose.transparentize(100%), 0%), (dawn.rose, 15%), (dawn.rose, 85%), (dawn.rose.transparentize(100%), 100%), angle: 0deg, ) } else { gradient.linear( (dawn.rose, 0%), (dawn.rose, 55%), (dawn.rose.transparentize(100%), 65%), (dawn.rose.transparentize(100%), 100%), angle: 0deg, ) }, )

#let pdf-header(ctx) = { let info = ctx.page set par(spacing: 9pt) if info.title != none { text(size: 28pt, weight: "bold", fill: dawn.text, info.title) } if info.subtitle != none [ #parbreak() #text(size: 14pt, fill: dawn.subtle, info.subtitle) ] v(1em) if info.by.len() > 0 [ #parbreak() #text(size: 12pt, fill: dawn.subtle, [#author-text(info.by)]) ] if info.date != none [ #parbreak() #text(size: 12pt, fill: dawn.iris, format-date(info.date)) ] if info.description != none [ #parbreak() #v(1em) #info.description ] rule() }

#let page-band(ctx, top: true) = context { set text(size: 8pt, fill: dawn.subtle) let info = ctx.page let title = if info.title == none { ctx.site.title } else { info.title } let url = ctx.page.at("url", default: none) let author = info.author.join(", ") let date = if info.date != none { format-date(info.date) } else { [] } let details = grid( columns: (1fr, auto), column-gutter: 12pt, align: (left, right), if top { if url == none { title } else { link(url, title) } } else { author }, if top { date } else { counter(page).display("1") }, ) if top { stack(dir: ttb, spacing: 6pt, details, rule(fade-both: true)) } else { stack(dir: ttb, spacing: 6pt, rule(fade-both: true), details) } }

#let pdf-layout(ctx, body) = [ #show raw.where(block: true): set raw(theme: code-theme) #set text(font: "Montserrat", size: 11pt, fill: dawn.text) #show math.equation: set text(font: "Fira Math", fallback: false) #show raw.where(block: true): it => block( width: 100%, fill: moon.base, inset: 10pt, radius: 6pt, breakable: true, )[ #set text(fill: moon.text) #it ] #show heading: set text(size: 1.1em) #show heading.where(depth: 1): it => [ #it #block(above: 0pt, below: 8pt, rule(length: 55%)) ] #set page( margin: 1in, fill: dawn.base, header: page-band(ctx), footer: page-band(ctx, top: false), paper: "us-letter", ) #(ctx.site.theme.header)(ctx) #body ]

1#import "metadata.typ": author-text, format-date
2#import "color/rose-pine-dawn.typ": rose-pine-dawn as dawn
3#import "color/rose-pine-moon.typ": rose-pine-moon as moon
4
5#let code-theme = moon.codeThemePath
6
7#let rule(length: 100%, fade-both: false) = line(
8  length: length,
9  stroke: 1pt + if fade-both {
10    gradient.linear(
11      (dawn.rose.transparentize(100%), 0%),
12      (dawn.rose, 15%),
13      (dawn.rose, 85%),
14      (dawn.rose.transparentize(100%), 100%),
15      angle: 0deg,
16    )
17  } else {
18    gradient.linear(
19      (dawn.rose, 0%),
20      (dawn.rose, 55%),
21      (dawn.rose.transparentize(100%), 65%),
22      (dawn.rose.transparentize(100%), 100%),
23      angle: 0deg,
24    )
25  },
26)
27
28#let pdf-header(ctx) = {
29  let info = ctx.page
30
31  set par(spacing: 9pt)
32  if info.title != none { text(size: 28pt, weight: "bold", fill: dawn.text, info.title) }
33  if info.subtitle != none [
34    #parbreak()
35    #text(size: 14pt, fill: dawn.subtle, info.subtitle)
36  ]
37  v(1em)
38  if info.by.len() > 0 [
39    #parbreak()
40    #text(size: 12pt, fill: dawn.subtle, [#author-text(info.by)])
41  ]
42  if info.date != none [
43    #parbreak()
44    #text(size: 12pt, fill: dawn.iris, format-date(info.date))
45  ]
46  if info.description != none [
47    #parbreak()
48    #v(1em)
49    #info.description
50  ]
51  rule()
52}
53
54#let page-band(ctx, top: true) = context {
55  set text(size: 8pt, fill: dawn.subtle)
56  let info = ctx.page
57  let title = if info.title == none { ctx.site.title } else { info.title }
58  let url = ctx.page.at("url", default: none)
59  let author = info.author.join(", ")
60  let date = if info.date != none { format-date(info.date) } else { [] }
61  let details = grid(
62    columns: (1fr, auto),
63    column-gutter: 12pt,
64    align: (left, right),
65    if top { if url == none { title } else { link(url, title) } } else { author },
66    if top { date } else { counter(page).display("1") },
67  )
68  if top {
69    stack(dir: ttb, spacing: 6pt, details, rule(fade-both: true))
70  } else {
71    stack(dir: ttb, spacing: 6pt, rule(fade-both: true), details)
72  }
73}
74
75#let pdf-layout(ctx, body) = [
76  #show raw.where(block: true): set raw(theme: code-theme)
77  #set text(font: "Montserrat", size: 11pt, fill: dawn.text)
78  #show math.equation: set text(font: "Fira Math", fallback: false)
79  #show raw.where(block: true): it => block(
80    width: 100%,
81    fill: moon.base,
82    inset: 10pt,
83    radius: 6pt,
84    breakable: true,
85  )[
86    #set text(fill: moon.text)
87    #it
88  ]
89  #show heading: set text(size: 1.1em)
90  #show heading.where(depth: 1): it => [
91    #it
92    #block(above: 0pt, below: 8pt, rule(length: 55%))
93  ]
94  #set page(
95    margin: 1in,
96    fill: dawn.base,
97    header: page-band(ctx),
98    footer: page-band(ctx, top: false),
99    paper: "us-letter",
100  )
101  #(ctx.site.theme.header)(ctx)
102  #body
103]