aboutsummaryrefslogtreecommitdiff
path: root/templates/ef/ordo.typ
blob: 162a485f6a2b849c30db9d383cb4c3d1ec9ca415 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
// colitur ordo booklet -- Typst. flavour: typst
// Build: colitur table --year 2027 --template ordo.typ > ordo.typ && typst compile ordo.typ
//
// ONE compile pass, not two: Typst resolves its own table of contents (built
// from headings via the outline function below) and every page number it
// shows internally, inside a single invocation -- there is no LaTeX-style
// pageref/aux-file dance and no "run it twice so the numbers settle". That is
// a genuine advantage of this flavour over ordo.tex, not merely a different
// syntax for the same thing.
//
// A5, one week per page, each day in a framed box with a colour swatch.
// Every fixed string (headings, the Epistle/Gospel/Commemoration/Week
// labels) comes from the view's term vocabulary rather than being written
// into this file, so a translated booklet needs no template edit -- only a
// different --lang. Same discipline as ordo.tex; see that file's own header
// for the full reasoning, repeated only where Typst changes it below.
//
// The observed day's own display name is a PLAIN resolved string
// (View.of_days), never a lang-keyed object, exactly as in every other
// shipped flavour -- there is no dotted-la-with-slug-fallback idiom to
// write here at all.
//
// The engine has no parent-path syntax: nested inside a month's own week
// loop, a bare week-number reference finds the WEEK's own number, and there
// is no way to reach the enclosing month's from there. That is why each
// week object carries its own month number and month name fields
// (lib/render/view.ml), used below via month_name/month_num instead of a
// parent-path reference the engine cannot express.
//
// The engine also rejects an empty tag path outright (a bare-dot section or
// variable is a parse error, not an invented "current context" behaviour),
// so every loop below names a field on the object it walks rather than
// trying to interpolate the object itself.
//
// This template's own line comments are plain text to the engine: it has no
// awareness of Typst's // syntax, and a stray double-brace pair inside one
// would still be parsed as a tag -- which is why this whole header, like
// ordo.tex's own, is written without ever typing two curly braces next to
// each other, even to name a field.
//
// One TOC level, not two: LaTeX's own ordo.tex prints the month name ONCE
// per month with its weeks dotted-and-paginated underneath, because it
// walks the months-then-weeks nesting directly in its own hand-built TOC
// loop. Typst's outline instead builds its table of contents automatically
// from real document headings, and there is no "is this the month's first
// week" flag in the view model for a template to test -- inventing one
// would be new engine state for a cosmetic grouping, not a real gap. Each
// week page therefore carries ONE flat heading, "Month . Week N", which is
// both what a reader sees at the top of that page and, automatically, its
// own single-line entry in the table of contents below.
//
// Colour swatch: the six colour names this rite emits (white, red, green,
// violet, rose, black -- Colour.to_string's own closed vocabulary) are used
// as literal dictionary keys inside a Typst string argument below, the same
// trick ordo.tex's own \swatch{licol...} macro-name concatenation relies
// on. Both templates depend on that vocabulary staying plain lowercase
// ASCII words with no markup metacharacter in it; the escaper still runs
// over the substituted value regardless; a value outside that closed set
// would need a different placement, not a different escaper.
#set page(
  paper: "a5",
  margin: (inside: 14mm, outside: 10mm, top: 12mm, bottom: 12mm),
  numbering: "1",
  header: align(center)[#text(size: 8pt)[{{term.ordo}} {{year}} #sym.dot.c {{rite_name}}]],
)
#set text(size: 9pt)
#set par(justify: false)
#show heading: it => {
  set text(size: 12pt, weight: "bold")
  block(above: 3mm, below: 2mm)[#it.body]
}

#let licol = (
  white: rgb("#FFFFFF"), red: rgb("#C1272D"), green: rgb("#2E7D32"),
  violet: rgb("#6A1B9A"), rose: rgb("#E91E8C"), black: rgb("#000000"),
)

// A framed swatch, always stroked in black regardless of fill -- so white
// (and, were the page ever black, black) still reads as a mark rather than
// a gap in the row. Mirrors ordo.tex's own \swatch macro.
#let swatch(colour) = box(width: 2.4mm, height: 2.4mm, fill: licol.at(colour), stroke: 0.4pt + black)

#align(center)[
  #text(size: 18pt, weight: "bold")[{{term.ordo}} {{year}}] \
  {{rite_name}}
]
#v(4mm)
#text(weight: "bold")[{{term.contents}}]
#v(1mm)
#outline(title: none, depth: 1, indent: 4mm)
#pagebreak(weak: true)

{{#months}}
{{#weeks}}
= {{month_name}} #sym.dot.c {{term.week}} {{num}}

{{#days}}
{{#in_month}}
#block(width: 100%, above: 0.6mm, below: 0mm, breakable: false, stroke: 0.4pt + luma(160), inset: (x: 1.6mm, y: 0.6mm))[
  // A single Typst paragraph throughout, deliberately: two markup lines
  // separated only by a bare newline stay on ONE rendered line (they are
  // still the same paragraph, soft-wrapped) -- verified live, the first
  // draft of this box merged the rank/colour line into the citation line
  // for exactly that reason. A trailing backslash forces a real line
  // break WITHOUT starting a new paragraph (no inter-paragraph spacing
  // to tune down), which is what a compact multi-line box wants; #par's
  // own block-level break, used further up for the day/weekday/swatch
  // row against the name below it, is reserved for the one place this
  // box actually wants a fresh paragraph.
  #set par(leading: 0.42em)
  #text(weight: "bold")[{{dom}}] #h(2mm) #text(size: 8pt)[{{weekday}}] #h(1fr) #swatch("{{colour}}") \
  #text(weight: "bold")[{{name}}] \
  #text(size: 7pt)[{{rank_name}} #sym.dot.c {{colour_name}}] \
  #text(size: 7pt)[{{#first}}{{term.epistle}} {{first}}{{/first}}{{#gospel}}{{#first}} #h(2mm) {{/first}}{{term.gospel}} {{gospel}}{{/gospel}}]{{#comms}} \
  #text(size: 7pt)[{{term.commemoration}} {{name}}]{{/comms}}
]
{{/in_month}}
{{/days}}
#pagebreak(weak: true)
{{/weeks}}
{{/months}}