aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--man/colitur-templates.5109
1 files changed, 96 insertions, 13 deletions
diff --git a/man/colitur-templates.5 b/man/colitur-templates.5
index ec883cb..a7e4992 100644
--- a/man/colitur-templates.5
+++ b/man/colitur-templates.5
@@ -149,8 +149,10 @@ carry a
.I name
field (each an object keyed by language, e.g.
.BR la " and " en ).
-Written naively, inside
-.BR {{#days}} ,
+Written naively, when
+.B {{#days}}
+is nested inside
+.BR {{#months}} ,
a bare
.B {{name.la}}
does
@@ -166,8 +168,36 @@ falls back to the outer scope, which does have one. This is not a corner
case: on an ordinary month, most days carry no Latin name at all (only named
sanctoral days do), so the naive form renders the
.I month's
-name on nearly every day \(em in a flat booklet, dozens of wrong lines; in a
-month grid, EVERY cell reads the month's own name.
+name on nearly every day \(em in a per\-month booklet, dozens of wrong
+lines; in a month grid (whose
+.B {{#weeks}}
+is itself only ever reachable through
+.BR {{#months}} ,
+since
+.I weeks
+is a field of
+.IR month ,
+never a top\-level list) EVERY cell reads the month's own name.
+.PP
+.B The collision needs a month actually on the scope stack to fire.
+Iterating the TOP\-LEVEL, flat
+.B days
+list directly (
+.B {{#days}}...{{/days}}
+at the outermost level, never passing through
+.B {{#months}}
+first) puts no month object anywhere on the stack, so the naive form does
+.I not
+silently substitute the wrong answer there \(em it silently resolves to
+nothing, exactly as any other absent key would, because there is no
+outer scope left to climb to. This is precisely what makes the hazard easy
+to miss: an author who tries the naive form against the flat list first
+sees the unnamed days come out empty, reasonably concludes the form is
+safe, and then hits the real collision the moment the identical fields are
+read from inside
+.BR {{#months}} ,
+which is what every shipped template that produces a grid or a per\-month
+booklet actually does.
.TP
.B num
Both a
@@ -630,15 +660,17 @@ an eighth, empty column and
.B pdflatex
would reject the file outright.
.SH A WORKED MINIMAL TEMPLATE
-A plain\-text booklet, one line per day, using the safe name idiom from
-.BR "SCOPE AND LOOKUP" :
+A plain\-text booklet, days nested inside months \(em the shape every
+shipped template actually uses, and the shape the
+.B SCOPE AND LOOKUP
+hazard needs to fire \(em using the safe name idiom from that section:
.RS
.nf
{{rite}} {{year}}
-{{#days}}
+{{#months}}{{#days}}
{{iso}} {{#name}}{{la}}{{^la}}{{slug}}{{/la}}{{/name}} {{colour}}{{#comms}} +{{slug}}{{/comms}}
-{{/days}}
+{{/days}}{{/months}}
.fi
.RE
.PP
@@ -672,14 +704,65 @@ supplies
instead. The third shows the non\-fallback case: 3 January
.I does
carry a Latin name (the votive Office of the Blessed Virgin Mary on
-Saturday), and the idiom prints it correctly. A template using the unsafe,
-bare
+Saturday), and the idiom prints it correctly.
+.PP
+Now swap only the interpolation \(em the safe idiom above becomes the
+naive, unsafe
+.B {{name.la}} ,
+nesting left exactly as it was:
+.RS
+.nf
+
+{{rite}} {{year}}
+{{#months}}{{#days}}
+{{iso}} {{name.la}} {{colour}}
+{{/days}}{{/months}}
+.fi
+.RE
+.PP
+Rendered against the identical year, same extension and flavour:
+.RS
+.nf
+
+.B colitur table \-\-year 2026 \-\-template minimal\-unsafe.txt | head \-7
+ef 2026
+
+2026\-01\-01 Ianuarius white
+
+2026\-01\-02 Ianuarius white
+
+2026\-01\-03 Officium sanctae Mariae in sabbato white
+.fi
+.RE
+.PP
+The collision fires for real on the first two lines: with a month on the
+scope stack, the day's own missing
+.B la
+key falls back all the way out to the ENCLOSING MONTH's own
+.RB \(lq Ianuarius \(rq
+rather than failing. The third line is untouched, because 3 January's own
+.I name
+object genuinely has a
+.B la
+key, so the dotted path resolves without ever needing to fall back.
+.PP
+.B This is specific to nesting, and that is the point.
+The identical naive
.B {{name.la}}
-form would instead have printed
+written against the TOP\-LEVEL, flat
+.B days
+list (no
+.B {{#months}}
+wrapping it) does
+.I not
+print
.RB \(lq Ianuarius \(rq
-on BOTH of those lines \(em the enclosing month's own name \(em see
+anywhere \(em there is no month on the stack to fall back to, so it prints
+nothing on an unnamed day instead, silently but not wrongly. See
.B SCOPE AND LOOKUP
-above.
+above for why testing the naive form only against a flat list is exactly
+how this hazard goes unnoticed until a template is later nested under
+.BR {{#months}} .
.SH SEE ALSO
.BR colitur (1)
for