diff options
Diffstat (limited to 'templates/ef')
| -rw-r--r-- | templates/ef/grid.typ | 105 | ||||
| -rw-r--r-- | templates/ef/ordo.typ | 121 |
2 files changed, 226 insertions, 0 deletions
diff --git a/templates/ef/grid.typ b/templates/ef/grid.typ new file mode 100644 index 0000000..c197ad2 --- /dev/null +++ b/templates/ef/grid.typ @@ -0,0 +1,105 @@ +// colitur wall calendar -- A4 landscape, one month per page. Typst. flavour: typst +// Build: colitur table --year 2027 --template grid.typ > grid.typ && typst compile grid.typ +// ONE compile pass: this template has no table of contents and no +// cross-references (unlike ordo.typ), so there is nothing for a second pass +// to resolve even in principle -- unlike pdflatex's own two-pass need for +// grid.tex's sibling ordo.tex, though grid.tex itself already needed only +// one pass too. +// +// The grid must FILL the page, not sit in its top quarter. grid.tex's own +// header explains why it computes an explicit fixed row height by hand +// (\cellh) and why that leaves a 5-week month only 5/6 full rather than +// 6/6 -- LaTeX's tabular has no notion of "share out whatever is left". +// Typst's table/grid DOES: a row-size list shorter than the actual row +// count repeats its OWN LAST entry for every remaining row (verified live: +// a 5-row table given `rows: (auto, 1fr)` renders five equal 1fr rows, not +// one), so `rows: (auto, 1fr)` below fills the page COMPLETELY regardless +// of whether the month has 5 or 6 Sunday-started weeks, with no week count +// arithmetic in this file at all. This is a genuine, disclosed DIVERGENCE +// from grid.tex's own behaviour, not an oversight: LaTeX leaves a 5-week +// month's bottom sixth blank on purpose (documented there); this template +// instead stretches every month to fill the whole page every time, because +// Typst makes that the simpler option, not the harder one. +// +// Real names, not slugs: the observed day's own display name is a PLAIN +// resolved string (View.of_days), interpolated directly as a plain var +// below -- there is no dotted-la-with-slug-fallback idiom left to write +// (see ordo.typ's own header for the full reasoning; it applies here +// unchanged). +// +// The weekday header row comes from the view's top-level weekday_headings +// list (name/last objects), not a hard-coded Dom/Lun/Mar row: the engine +// rejects an EMPTY tag path -- a bare dot inside a section, on its own -- +// as a parse error, so the loop below names a field on each heading object +// rather than interpolating the section's own value directly, and a +// hard-coded row would not be localised anyway. +// +// No separator flag needed: grid.tex's own `last` field exists because a +// LaTeX tabular row needs its ampersand BETWEEN cells, never after the +// final one, and the engine has no "unless last" construct to lean on +// instead -- so that template renders the flag as data. Typst's own +// #table() takes a flat, comma-separated argument list and wraps it into +// rows itself, by column count, so the SAME rule applies to every cell, +// header row included, with no special case for the last one -- verified +// live that a trailing comma before a function call's closing parenthesis +// is accepted, not a syntax error. `last` is therefore simply unused here; +// left in the view model for grid.tex's own sake, not removed for this one. +// +// Sigla, compactly: each cell also carries the day's Epistle and Gospel +// references (view fields first/gospel), joined by a centred dot rather +// than repeating Ep./Ev. labels -- the same choice grid.tex and grid.ms +// already made, kept consistent rather than invented a second way. A +// #v(1fr) inside each cell's own content -- verified live to work the same +// way inside a table cell as inside any other block -- pushes the rank +// line and the sigla to the bottom of the cell, leaving the day number and +// name at the top, so the two short lines never collide with a long entry +// above them the way a single crammed line would. +#set page(paper: "a4", flipped: true, margin: 10mm, numbering: none) +#set text(size: 8pt) +#set par(justify: false) + +#let cgrid = ( + white: rgb("#FFFFFF"), red: rgb("#F8DCDC"), green: rgb("#DDEEDD"), + violet: rgb("#E6DAF0"), rose: rgb("#FADCE8"), black: rgb("#DCDCDC"), +) +#let cpad = luma(248) + +{{#months}} +#text(size: 20pt, weight: "bold")[{{name}} {{year}}] +#v(2mm) +#table( + columns: (1fr,) * 7, + rows: (auto, 1fr), + stroke: 0.4pt + luma(150), + inset: 1.6mm, + align: left + top, + {{#weekday_headings}} + table.cell(align: center + horizon)[#text(weight: "bold")[{{name}}]], + {{/weekday_headings}} + {{#weeks}} + {{#days}} + {{#in_month}} + table.cell(fill: cgrid.at("{{colour}}"))[ + // One paragraph, a trailing backslash between the rank line and the + // sigla line rather than a bare newline: two markup lines joined only + // by a bare newline stay on ONE rendered line (still the same soft- + // wrapped paragraph) -- verified live, the first draft of this cell + // merged "III classis" straight into the citation. grid.tex's own + // header explains why the rank line and the sigla get their own line + // EACH rather than being crammed onto one -- the same reasoning + // applies here, so this keeps the two-line shape it settled on. + #set par(leading: 0.35em) + #text(weight: "bold")[{{dom}}] #text(size: 7pt)[{{name}}] + #v(1fr) + #text(size: 6.5pt)[{{rank_name}}] \ + #text(size: 6.5pt)[{{#first}}{{first}}{{/first}}{{#gospel}}{{#first}} #sym.dot.c {{/first}}{{gospel}}{{/gospel}}] + ], + {{/in_month}} + {{^in_month}} + table.cell(fill: cpad)[], + {{/in_month}} + {{/days}} + {{/weeks}} +) +#pagebreak(weak: true) +{{/months}} diff --git a/templates/ef/ordo.typ b/templates/ef/ordo.typ new file mode 100644 index 0000000..33bc802 --- /dev/null +++ b/templates/ef/ordo.typ @@ -0,0 +1,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}}]], +) +#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}} +] +#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}} |
