% colitur ordo booklet -- LaTeX. flavour: latex % Build: colitur table --year 2027 --template ordo.tex > ordo.tex && pdflatex ordo.tex && % pdflatex ordo.tex (twice, so \pageref in the table of contents settles) % % A5, CONTINUOUS: days flow one after another with no forced page break per % week (Defect 2 -- the original one-week-per-page layout filled roughly % the top third of every page and cost 65 pages for a year that needed far % fewer; that requirement is reversed here on purpose, not merely relaxed). % Structure stays scannable through two header weights instead: every % week still opens with its own header line -- a Roman week number plus % the span of in-month dates it covers, e.g. Hebdomada I (Ian 1-2), with % no month name repeated, since the month heading above already % establishes it -- and the month's own FIRST week additionally gets a % large, ruled banner above that line (view field [first], lib/render/ % view.ml -- not template-side arithmetic, since this engine has no way % to test "is this the first item" any other way). % \needspace (a genuine, tiny dependency, not one of the deps this project % freezes at the OCaml level -- LaTeX packages are a template author's own % concern) keeps a header from being stranded alone at a page's bottom % with its first day box pushed to the next one: 18mm covers the month % banner's own rule+title plus the week header below it plus room for at % least one (now much shorter, see the density retune below) day box; % 9mm covers just the week header plus one day box. Both re-verified % against the actual typeset output, not derived from theory alone (the % task report has the before/after page counts and a scan proving no % header is ever left alone at a page's foot with nothing under it). % % \label fires AFTER both \needspace calls below, not before: a \label % placed before a \needspace that goes on to force a break captures the % OLD page number (\thepage at the point \label is processed, not where % its content actually lands) -- a step-stale \pageref found live in an % early draft's own TOC (week 3 read "page 3" while its own content % demonstrably started on page 4). Moving the label to fire only once the % page a week ACTUALLY starts on is already decided fixes it at the % source, cheaper than a third pdflatex pass, which would not have fixed % it either (the wrong page number was already committed to the .aux by % the second pass). % % Each day in a framed box with a colour swatch, tightened from an % earlier draft (top/bottom padding 0.4mm, before skip 0.5mm, \scriptsize % meta text, rank/colour and the citations on separate lines) for this % same continuous flow: a full 7-day week already occupies most of an A5 % page even at reduced size (measured: 55-65% of the text height for a % typical week, more with commemorations), so simply dropping the forced % per-week \clearpage only let the year's many PARTIAL boundary weeks % double up, not full ones -- a real but small saving on its own. Rank/ % colour folded onto the SAME line as the citations rather than a line of % its own -- an A5 box is far wider than it is tall (roughly 120mm of % usable width here), so "I classis . albus Epistola ... Evangelium ..." % fits with room to spare even on Holy Week's own longest citations % (measured against the rendered output, not assumed). % % DENSITY RETUNE (matched to ordo.typ's own decisions, task: bring ordo.tex % to Typst's density -- 53 pages/6.9 days-per-page down to 29 pages/12.6): % the document's own base size drops from \normalsize (10pt) to an explicit % 9pt/10.5 leading set once after \begin{document} (mirrors Typst's global % #set text(size: 9pt)); within a day box the SAME size hierarchy Typst % uses -- the day number and the feast name are BOTH the 9pt base (bold % is what distinguishes them, not size, exactly as ordo.typ decided), the % weekday name is 7pt, and every detail line (rank/colour/citations/ % commemorations) is 6.5pt. % % The one genuinely non-obvious lesson from getting there (cost a full % false-start): \fontsize{n}{lead}\selectfont set INSIDE a brace group % that CLOSES before the line-ending \\ has NO effect on the interline % glue TeX inserts for that break -- the glue uses whatever \baselineskip % is active in the OUTER scope at the point \\ actually executes, not the % value the just-closed group asked for. This is not a stylistic % preference; it was measured directly (a synthetic two-baselineskip test % file, \fontsize{9}{9.7}...\\ in a closed group nested inside an OUTER % \fontsize{9}{20}, produced an exact 20pt gap, not 9.7pt) and it is % exactly the shape of bug the ORIGINAL (pre-retune) day box already had: % every one of its \fontsize groups closed before its own \par, so the % only thing actually controlling interline spacing throughout the whole % box was the ambient \normalsize baselineskip (12pt at the old 10pt base) % -- the box's own careful-looking 9pt/6.5pt \fontsize choices were, for % LEADING purposes, inert. The fix used throughout below: \fontsize and % \selectfont are issued INLINE (no enclosing group), immediately before % the text they size, with \\ following in the SAME scope -- the size % declared right before a line's own text is what governs the gap ABOVE % that line, confirmed by the same synthetic test the other way (a 6.5pt/ % 7pt declaration right before a small line tightens only that one gap). % \bfseries/\mdseries are toggled the same inline way (no groups), which % is why a stray unbalanced brace anywhere in this box would fail loudly % at compile time rather than silently leak weight into later text. % % Two further, smaller finds while measuring the actual PDF, not assumed: % tcolorbox's default rounded corners undercount a box's own true height % when probed by scanning a fixed pixel column (the arc pulls the vertical % edge away near each corner) -- \texttt{sharp corners} removes the % ambiguity and, as a side effect, also matches Typst's own plain % rectangular block() more closely. And \parskip is set to 0pt globally % (\setlength{\parindent}{0pt} already was) since several day-box lines % are still separate \LaTeX{} paragraphs (broken by \\, not \par, so this % is defensive rather than load-bearing) and a nonzero default \parskip % would otherwise add unpredictable glue between them. % % 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. % % The observed day's own display name is a PLAIN resolved string % (View.of_days, Task 5), never a lang-keyed object -- there is no % dotted-la-with-slug-fallback idiom to write here at all; a day with no % name in the shipped data still resolves to something printable (its slug, % under --raw, or the lang table's own miss-echoes-the-key behaviour), so % the plain name field alone is always enough. % % 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, month name and abbreviated % month name fields (lib/render/view.ml) -- used throughout below instead % of a parent-path reference, which this engine cannot express. The same % view resolves the week's own Roman numeral too (num_roman, arabic num % kept alongside it for a tradition that wants it), the day-of-month of % its first and last in-month day (first_dom/last_dom), and single_day % (true for a one-day week) -- a punctuation choice (Ian 1 vs Ian 1-2) % this logic-less engine cannot make for itself, so the template below % picks the dash only inside an inverted single_day section. % % This template's own %-comments are plain text to the engine: it has no % awareness of LaTeX's comment syntax, and a stray double-brace pair inside % one would still be parsed as a tag -- which is why this whole header is % deliberately written without ever typing two curly braces next to each % other, even to name a field. \documentclass[10pt]{article} % includehead/includefoot: without them geometry seats the text block at % top=/bottom= and fancyhdr then places the running header/footer OUTSIDE % that block -- above the top margin and below the bottom one -- which on % this page's original top=11mm/bottom=12mm pushed the header partly above % the physical page edge (measured: yMin -5.5pt on a 0..595pt page) and the % footer to within 1pt of the bottom edge. With includehead/includefoot the % header/footer live INSIDE top=/bottom= instead, so headsep/footskip are % also set explicitly (3mm/7mm) rather than left at article's defaults % (25pt/30pt) -- those defaults alone would still overflow a 10mm margin % and, measured, silently added 20 extra pages to the whole booklet by % shrinking every day box. \headheight is left at fancyhdr's own default % (12pt, confirmed by the log, no "increase \headheight" warning) since a % single \small header line fits it without complaint. \usepackage[a5paper,top=10mm,bottom=10mm,inner=14mm,outer=10mm,includehead,includefoot,headsep=3mm,footskip=7mm]{geometry} \usepackage[T1]{fontenc} \usepackage[utf8]{inputenc} \usepackage{xcolor} \usepackage{tikz} \usepackage{tcolorbox} \usepackage{fancyhdr} \usepackage[hidelinks]{hyperref} \usepackage{needspace} \definecolor{licolwhite}{HTML}{FFFFFF} \definecolor{licolred}{HTML}{C1272D} \definecolor{licolgreen}{HTML}{2E7D32} \definecolor{licolviolet}{HTML}{6A1B9A} \definecolor{licolrose}{HTML}{E91E8C} \definecolor{licolblack}{HTML}{000000} % A framed square, always outlined in black regardless of fill -- so white % (and, on a black background page, black) still reads as a swatch rather % than a gap. tikz (a tcolorbox dependency already) draws the border; xcolor % alone cannot outline a filled rule. \newcommand{\swatch}[1]{\tikz[baseline=-0.6ex]{\fill[draw=black,line width=0.4pt,fill=#1] (0,0) rectangle (2.4ex,2.4ex);}} \pagestyle{fancy}\fancyhf{} \fancyhead[C]{\fontsize{8}{9}\selectfont {{term.ordo}} {{year}} \textperiodcentered\ {{rite_name}}} \fancyfoot[C]{\fontsize{8}{9}\selectfont\thepage} \renewcommand{\headrulewidth}{0.4pt} \setlength{\parindent}{0pt} \setlength{\parskip}{0pt} \begin{document} \fontsize{9}{10.5}\selectfont \begin{center} \fontsize{18}{20}\selectfont\bfseries {{term.ordo}} {{year}}\\[2pt] \fontsize{9}{10.5}\selectfont\mdseries {{rite_name}} \end{center} \vspace{3mm} {\bfseries {{term.contents}}}\par\vspace{1.5mm} {\fontsize{8}{9.2}\selectfont {{#months}} \textbf{ {{name}} }\par {{#weeks}}\hspace*{4mm}{{term.week}} {{num_roman}} ({{month_abbr}} {{first_dom}}{{^single_day}}--{{last_dom}}{{/single_day}})\dotfill\pageref{w{{month_num}}-{{num}}}\par {{/weeks}} {{/months}} } \clearpage {{#months}} {{#weeks}} {{#first}} \needspace{18mm} \vspace{1.5mm}\noindent\rule{\linewidth}{1pt}\par\vspace{0.6mm} {\fontsize{15}{16.5}\selectfont\bfseries {{month_name}} {{year}} }\par\vspace{0.8mm} {{/first}} \needspace{9mm} \vspace{0.6mm} \label{w{{month_num}}-{{num}}} {\fontsize{12}{13}\selectfont\bfseries {{term.week}} {{num_roman}} ({{month_abbr}} {{first_dom}}{{^single_day}}--{{last_dom}}{{/single_day}})}\par\vspace{0.3mm} {{#days}} {{#in_month}} \begin{tcolorbox}[colback=white,colframe=black!35,boxrule=0.3pt,sharp corners,boxsep=0mm,left=1.6mm,right=1.6mm,top=0.4mm,bottom=0.4mm,before skip=0.3mm,after skip=0mm] \fontsize{9}{9}\selectfont\bfseries {{dom}} \fontsize{7}{9}\selectfont\mdseries\;{{weekday}}\hfill\swatch{licol{{colour}}}\\ \fontsize{9}{9.7}\selectfont\bfseries {{name}}\\ \fontsize{6.5}{7.4}\selectfont\mdseries {{rank_name}} \textperiodcentered\ {{colour_name}} {{#first}}\quad {{term.epistle}}\ {{first}} {{/first}}{{#gospel}}\quad {{term.gospel}}\ {{gospel}} {{/gospel}}{{#comms}}\\ \fontsize{6.5}{7.4}\selectfont\mdseries {{term.commemoration}}\ {{name}}{{/comms}} \end{tcolorbox} {{/in_month}} {{/days}} {{/weeks}} {{/months}} \end{document}