diff options
| author | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-08-19 11:48:30 +0200 |
|---|---|---|
| committer | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-08-19 11:48:30 +0200 |
| commit | 6762ce46af3cb12bc6ae37cda762c5d95add7903 (patch) | |
| tree | bc1d8c86050d0149ff961a9a4ff838f9c474ac2a | |
| parent | 897c274fd28402159ca6d45eedc1257b1ce98696 (diff) | |
| parent | 390bc6ac5196a946c473d0dbe7760fa41837c428 (diff) | |
| download | colitur-6762ce46af3cb12bc6ae37cda762c5d95add7903.tar.gz colitur-6762ce46af3cb12bc6ae37cda762c5d95add7903.zip | |
feat: output, rendering and publishing
Gives colitur a publishable exit. Until now its only output was terminal
rows; it can now print an ordo booklet and a wall calendar, publish an
iCalendar feed people subscribe to, and serve a static JSON/XML API.
lib/render escaping (six flavours + RFC 5545 folding), a deliberately
logic-less template engine, the view model, and five
emitters (CSV, JSON, XML, iCalendar, S-expression)
CLI emit, table, render, publish -- all accepting --overlay
templates ordo booklet in six flavours, wall grid in three
schema day-v1.json and colitur-v1.xsd, the published contract
man colitur-templates.5, plus colitur.1 updates
The view model is why the engine can stay logic-less: a month grid needs
leading blank cells, week bucketing and an in-month test, and a
logic-less template can compute none of it. Shaping the data in OCaml
keeps the engine safe for untrusted templates and makes the grid
trivial.
Formats split by whether correctness is mechanical. Presentation goes
through templates; iCalendar and XML get dedicated emitters, because
folding, exclusive DTEND, stable UIDs and schema fidelity are rules a
template cannot enforce and each fails silently in a subscriber's
client rather than loudly at generation.
publish is deterministic and non-destructive: two runs produce a
byte-identical tree, and --prune removes only files a previous run
created, refusing any manifest entry that escapes the output directory.
No new dependencies. The kernel and rite modules are untouched, and
colitur day and colitur readings remain byte-identical.
54 files changed, 21217 insertions, 43 deletions
@@ -10,6 +10,11 @@ MAN5DIR := $(PREFIX)/share/man/man5 # (<prefix>/share/colitur/ef), so `dune install` -- not a hand-rolled copy -- # is what places the four .sexp files where a running colitur will look for # them. See bin/main.ml's own [data_dir] for the full resolution order. +# Task 13 (schema/dune, templates/dune) extends the same `dune install` +# mechanism to <prefix>/share/colitur/schema/ (bin/main.ml's own +# [schema_path], read by `colitur publish`) and <prefix>/share/colitur/ +# templates/ (a convenience install -- `--template` takes a plain file path, +# nothing in colitur probes this location the way [data_dir]/[schema_path] do). # # dune needs the project-local opam switch on PATH. Every recipe that invokes # dune goes through this, so `make` works from a plain shell with no @@ -17,7 +22,7 @@ MAN5DIR := $(PREFIX)/share/man/man5 # over documenting the dune commands. DUNE := opam exec -- -.PHONY: help build test check install uninstall reinstall clean fmt man doc release +.PHONY: help build test check check-schema check-templates install uninstall reinstall clean fmt man doc release help: ## show this help @grep -hE '^[a-z-]+:.*##' $(MAKEFILE_LIST) | sed -E 's/:.*## /\t/' | sort @@ -30,19 +35,69 @@ test: ## fast suite (~5s): properties sample 200 years check: ## full gate (~2min): every year 1583-9999, not a sample COLITUR_EXHAUSTIVE_SWEEP=1 $(DUNE) dune test --force -install: build ## install binary, calendar data and man page into PREFIX (default ~/.local) +check-schema: build ## validate emitted XML against schema/colitur-v1.xsd (needs xmllint; skipped if absent) + @if command -v xmllint >/dev/null 2>&1; then \ + opam exec -- dune exec colitur -- emit --format xml --from 2027 --to 2027 > /tmp/colitur-check.xml && \ + xmllint --noout --schema schema/colitur-v1.xsd /tmp/colitur-check.xml && \ + echo "xml: valid against schema/colitur-v1.xsd"; \ + else \ + echo "SKIPPED: xmllint not installed -- XML is emitted but NOT schema-validated"; \ + fi + +# Typesets every shipped template through the real tool that would typeset it +# for a reader, not merely through this program's own renderer. The golden +# tests already prove `colitur table` PRODUCES the expected LaTeX/groff/HTML +# text; only this proves that text actually TYPESETS -- a template can render +# byte-for-byte as pinned and still be malformed LaTeX or groff. Each tool is +# genuinely optional (neither is in colitur's own frozen deps), so absence is +# printed LOUDLY as SKIPPED rather than silently treated as a pass -- a +# silent skip reads as a pass, which is the whole failure mode this guards +# against. +check-templates: build ## typeset every shipped template (needs pdflatex/groff; skipped if absent) + @ok=1; \ + if command -v pdflatex >/dev/null 2>&1; then \ + for t in ordo grid; do \ + opam exec -- dune exec colitur -- table --year 2027 --template templates/ef/$$t.tex > /tmp/$$t.tex && \ + (cd /tmp && pdflatex -halt-on-error -interaction=nonstopmode $$t.tex >/dev/null) && \ + echo "pdflatex: $$t.tex OK" || { echo "pdflatex: $$t.tex FAILED"; ok=0; }; \ + done; \ + else echo "SKIPPED: pdflatex not installed -- LaTeX templates render but are NOT typeset"; fi; \ + if command -v groff >/dev/null 2>&1; then \ + for t in ordo grid; do \ + gflags=""; \ + [ "$$t" = grid ] && gflags="-P-pa4l"; \ + if opam exec -- dune exec colitur -- table --year 2027 --template templates/ef/$$t.ms \ + > /tmp/$$t.ms 2>/tmp/$$t-render.err; then \ + groff -ms -t -Tpdf $$gflags /tmp/$$t.ms > /tmp/$$t-ms.pdf 2>/tmp/$$t-ms.warnings; \ + if [ -s /tmp/$$t-ms.warnings ]; then \ + echo "groff: $$t.ms FAILED (groff exits 0 on a tbl/troff warning -- this target"; \ + echo " treats ANY stderr output as a failure, since a warning here has meant"; \ + echo " silently lost table columns before):"; \ + cat /tmp/$$t-ms.warnings; ok=0; \ + else \ + echo "groff: $$t.ms OK"; \ + fi; \ + else \ + echo "groff: $$t.ms FAILED (colitur table render):"; cat /tmp/$$t-render.err; ok=0; \ + fi; \ + done; \ + else echo "SKIPPED: groff not installed -- groff templates render but are NOT typeset"; fi; \ + test $$ok -eq 1 + +install: build ## install binary, calendar data, templates, schema and man pages into PREFIX (default ~/.local) $(DUNE) dune install --prefix $(PREFIX) @mkdir -p $(MANDIR) install -m 644 man/colitur.1 $(MANDIR)/colitur.1 @mkdir -p $(MAN5DIR) install -m 644 man/colitur-overlay.5 $(MAN5DIR)/colitur-overlay.5 - @echo "installed $(BINDIR)/$(COLITUR), data in $(PREFIX)/share/colitur/ef, man pages in $(MANDIR) and $(MAN5DIR)" + install -m 644 man/colitur-templates.5 $(MAN5DIR)/colitur-templates.5 + @echo "installed $(BINDIR)/$(COLITUR), data in $(PREFIX)/share/colitur/{ef,templates,schema}, man pages in $(MANDIR) and $(MAN5DIR)" @command -v $(COLITUR) >/dev/null 2>&1 || \ echo "note: $(BINDIR) is not on PATH -- add it, or run $(BINDIR)/$(COLITUR) directly" uninstall: ## remove everything install put into PREFIX -$(DUNE) dune uninstall --prefix $(PREFIX) - rm -f $(MANDIR)/colitur.1 $(MAN5DIR)/colitur-overlay.5 + rm -f $(MANDIR)/colitur.1 $(MAN5DIR)/colitur-overlay.5 $(MAN5DIR)/colitur-templates.5 @echo "removed $(COLITUR) from $(PREFIX)" reinstall: uninstall install ## uninstall then install (the installed copy is a snapshot, not a link) @@ -50,10 +105,12 @@ reinstall: uninstall install ## uninstall then install (the installed copy is a man: ## preview the man pages man -l man/colitur.1 man -l man/colitur-overlay.5 + man -l man/colitur-templates.5 doc: ## lint the man pages (groff warnings; silence means clean) groff -man -Tutf8 -ww -z man/colitur.1 groff -man -Tutf8 -ww -z man/colitur-overlay.5 + groff -man -Tutf8 -ww -z man/colitur-templates.5 fmt: ## format the OCaml sources $(DUNE) dune build @fmt --auto-promote @@ -21,6 +21,18 @@ dune exec colitur -- temporal 2026 # the EF temporal cycle only, one line per d dune exec colitur -- day 2026 # the full resolved EF calendar (temporal + sanctoral) ``` +## Rendering + +```sh +dune exec colitur -- table --year 2027 --template templates/ef/ordo.tex > ordo.tex && pdflatex ordo.tex +dune exec colitur -- table --year 2027 --template templates/ef/grid.tex > grid.tex && pdflatex grid.tex +dune exec colitur -- publish --from 2027 --to 2027 --out ./public +``` + +See `colitur-templates(5)` for the template format (syntax, escaping, the +full field reference) and `colitur(1)` for `emit`, `table`/`render` and +`publish` in full. + ## License AGPL-3.0-or-later. See `LICENSE`. @@ -2,4 +2,8 @@ (name main) (public_name colitur) (package colitur) - (libraries colitur_kernel rite_ef)) + ; [unix] ships with the OCaml compiler -- it is not a new entry in + ; colitur.opam's frozen depends, only a new library this executable links + ; against. Used by Task 12's [mkdir_p] (colitur publish, recursive + ; directory creation) and nowhere else. + (libraries colitur_kernel rite_ef colitur_render unix)) diff --git a/bin/main.ml b/bin/main.ml index 231d003..6f64582 100644 --- a/bin/main.ml +++ b/bin/main.ml @@ -314,12 +314,15 @@ let load_ef_data ?(user_overlays = []) () = | Error msg -> Error msg | Ok commons -> Ok (layer, lectionary, commons))) -(* The resolved-year walk, shared by [day_report] and [readings_report]: they - differ only in how each day is printed, and the two-liturgical-year - indexing below (with its own reasoning about civil-vs-liturgical spans) is - exactly the part that must not be duplicated and drift. [line] is the only - difference between the two commands. *) -let resolved_year_report ~line ~overlays y = +(* The resolved-year walk, shared by [day_report], [readings_report] and + [emit_report] (Task 8): they differ only in what happens to each day, and + the two-liturgical-year indexing below (with its own reasoning about + civil-vs-liturgical spans) is exactly the part that must not be duplicated + and drift. [resolved_year_days] owns that walk and returns the resolved + days, in date order, for one civil year; every caller layers its own + handling (a line-printer, an accumulator for a whole-year [Template.value]) + on top rather than repeating the indexing. *) +let resolved_year_days ~overlays y = match load_ef_data ~user_overlays:overlays () with | Error msg -> Printf.eprintf "colitur: %s\n" msg; @@ -341,9 +344,10 @@ let resolved_year_report ~line ~overlays y = let jan1 = match D.make ~year:y ~month:1 ~day:1 with Ok t -> t | Error e -> failwith e in let dec31 = match D.make ~year:y ~month:12 ~day:31 with Ok t -> t | Error e -> failwith e in let d = ref jan1 in + let acc = ref [] in while D.compare !d dec31 <= 0 do (match Hashtbl.find_opt by_rata (D.to_rata !d) with - | Some day -> line day + | Some day -> acc := day :: !acc | None -> (* Unreachable for any [y] in 1583..9999: the two indexed liturgical years jointly cover [year_start (y-1), year_start @@ -357,11 +361,451 @@ let resolved_year_report ~line ~overlays y = loudly on stderr rather than as a quietly short year. *) Printf.eprintf "colitur: internal error: no resolved day for %s\n" (D.to_iso8601 !d)); d := D.add_days !d 1 - done + done; + List.rev !acc + +let resolved_year_report ~line ~overlays y = + List.iter line (resolved_year_days ~overlays y) let day_report ~overlays y = resolved_year_report ~line:day_line ~overlays y let readings_report ~overlays y = resolved_year_report ~line:readings_line ~overlays y +(* Task 8: `colitur emit` -- the five template-family emitters built in + Tasks 5-7, wired to a year RANGE rather than a single year, because a + published feed (ics) or a data export (csv/json/xml) is usually wanted + for more than one civil year at a time. Reuses [resolved_year_days] + rather than re-walking the two-liturgical-year index: see that + function's own comment. + + CSV is the one format that spans years in a single stream deliberately + printed as ONE header followed by every year's rows: emitting a fresh + header per year would make `wc -l` and `awk 'NR>1'` both wrong on a + multi-year run, and nothing about RFC 4180 requires a header per file + rather than per stream. json/xml/sexp/ics are printed once per year + instead -- concatenating whole JSON objects or VCALENDARs into one + stream is what each of those formats itself expects a multi-document + feed to look like (SEXP: printed one form per line, matching the + sexp-per-day shape [Liturgical_day.t] already uses elsewhere in this + file; XML: one document per year, the schema's own root is a single + year; ICS: one VCALENDAR per year, valid to concatenate for a + subscriber that reads multiple files). *) +(* [--dtstamp] is the only user string that reaches [emit]/[publish] output + unescaped and unvalidated (it becomes an ICS DTSTAMP: property value + directly, Colitur_render.Emit_ics.year's own [dtstamp] parameter) -- + every OTHER interpolated value in this project's output is either + escaped (Escape.apply) or engine-computed, never raw user input placed + straight into a line-oriented format. RFC 5545 section 3.3.5 defines + DATE-TIME's UTC form as exactly 8 digits, "T", 6 digits, "Z" + (e.g. "20270101T000000Z"); rejecting anything else is what stops + "--dtstamp hello" from silently emitting a malformed "DTSTAMP:hello" AND + what stops a value carrying its own CRLF (e.g. "X\r\nBEGIN:VEVENT\r\n...") + from being injected verbatim into every VEVENT -- a value shaped exactly + like the real form cannot contain either character. *) +let dtstamp_well_formed s = + let is_digit c = c >= '0' && c <= '9' in + String.length s = 16 + && String.for_all is_digit (String.sub s 0 8) + && s.[8] = 'T' + && String.for_all is_digit (String.sub s 9 6) + && s.[15] = 'Z' + +let check_dtstamp = function + | None -> () + | Some s when dtstamp_well_formed s -> () + | Some s -> + Printf.eprintf + "colitur: --dtstamp %S is not RFC 5545 UTC form (want 8 digits, 'T', 6 digits, 'Z', e.g. \ + 20270101T000000Z)\n" + s; + exit 2 + +let emit_report ~format ~overlays ~dtstamp ~from_y ~to_y = + check_dtstamp dtstamp; + if from_y > to_y then begin + Printf.eprintf "colitur: --from %d is after --to %d\n" from_y to_y; + exit 2 + end; + for y = from_y to to_y do + let days = resolved_year_days ~overlays y in + let v = + Colitur_render.View.of_days ~vocab:Rite_ef.Vocab_ef.vocab ~rite:"ef" ~year:y days + in + match format with + | "csv" -> + (* One header for the whole run, not one per year. *) + let body = Colitur_render.Emit_csv.year v in + if y = from_y then print_string body + else + print_string + (match String.index_opt body '\n' with + | Some i -> String.sub body (i + 1) (String.length body - i - 1) + | None -> body) + | "json" -> print_string (Colitur_render.Emit_json.year v) + | "xml" -> print_string (Colitur_render.Emit_xml.year v) + | "ics" -> print_string (Colitur_render.Emit_ics.year ?dtstamp v) + | "sexp" -> + List.iter + (fun d -> + print_string + (Sexplib.Sexp.to_string_hum + (Colitur_kernel.Liturgical_day.sexp_of_t + Rite_ef.Vocab_ef.sexp_of_season Rite_ef.Vocab_ef.sexp_of_rank d)); + print_newline ()) + days + | other -> + Printf.eprintf "colitur: unknown format %S (want csv, json, sexp, xml or ics)\n" other; + exit 2 + done + +(* Task 9: `colitur table` and `colitur render` -- compute a year and render it + through a user-supplied template, in ONE process. + + The design's own sketch was `compute | render` as a Unix pipe, with `render` + reading a serialised view back from stdin. That is deliberately NOT built: + honouring the pipe would need a JSON *parser*, purely to re-read the view + this same process just serialised -- a second hand-rolled component, and a + second place for the published contract to drift, for no benefit over + calling [View.of_days] directly. So `table --year Y --template F` computes + and renders in one process (the command that actually gets used), and + `render --template F --year Y` is the identical operation under the name + the design used, kept so that documented vocabulary still works. There is + no stdin-fed `render`; `colitur emit --format json | jq` still composes for + real pipe use, because JSON there is the OUTPUT, never something colitur + itself has to parse back in. *) + +(* The open is guarded separately from the read: a missing file fails at + [open_in_bin] with a plain, path-only message (matching the wording this + project already uses for every other "no such file" case), while a file + that opens but cannot be READ -- a directory, a device node, anything + whose length or content changes between [open] and [read] -- fails inside + the [Fun.protect]'d body instead, carrying the raised exception's own text + (mirrors {!Colitur_kernel.Layer.load}/{!Colitur_kernel.Overlay.load}'s own + catch-all shape, lib/kernel/layer.ml and lib/kernel/overlay.ml). Either + way the channel is closed on EVERY path -- success, exception, or an + early return -- because [close_in_noerr] runs in [~finally], which + [Fun.protect] guarantees runs even when the protected function raises; a + bare [close_in] after [really_input_string] only ever ran on the success + path, leaking the descriptor on every failure. The whole read is inside + the [try], not only [open_in_bin], because [in_channel_length] and + [really_input_string] can themselves raise [Sys_error] (a directory opens + fine but is not readable as bytes) -- a template is user input, and this + project's own rule is that user input must never crash the program. *) +let read_file path = + match open_in_bin path with + | exception Sys_error _ -> Error ("cannot read template " ^ path) + | ic -> ( + try + Fun.protect + ~finally:(fun () -> close_in_noerr ic) + (fun () -> + let n = in_channel_length ic in + let s = really_input_string ic n in + Ok s) + with exn -> Error (Printf.sprintf "cannot read template %s: %s" path (Printexc.to_string exn))) + +let extension path = + match String.rindex_opt path '.' with + | Some i -> String.sub path i (String.length path - i) + | None -> "" + +(* An unknown extension with no [--flavour] is an ERROR, never a silent + fallback to [Escape.None_]: guessing the flavour wrong produces malformed + output (unescaped LaTeX/HTML metacharacters) that looks fine until it does + not -- the same "never silently substitute" discipline [data_dir]'s own + [COLITUR_DATA_DIR] handling documents above. *) +let table_report ~template ~flavour_opt ~overlays y = + let flavour = + match flavour_opt with + | Some name -> ( + match Colitur_render.Escape.of_string name with + | Some f -> f + | None -> + Printf.eprintf "colitur: unknown flavour %S (want latex, groff, html, xml, ics or none)\n" + name; + exit 2) + | None -> ( + match Colitur_render.Escape.of_extension (extension template) with + | Some f -> f + | None -> + Printf.eprintf + "colitur: cannot infer a flavour from %S; pass --flavour latex|groff|html|xml|ics|none\n" + (extension template); + exit 2) + in + match read_file template with + | Error msg -> + Printf.eprintf "colitur: %s\n" msg; + exit 2 + | Ok src -> ( + let days = resolved_year_days ~overlays y in + let v = Colitur_render.View.of_days ~vocab:Rite_ef.Vocab_ef.vocab ~rite:"ef" ~year:y days in + match Colitur_render.Template.render_string ~flavour src v with + | Error e -> + (* The template is user input; a parse failure is reported with the + parser's OWN reason and exits 2, never an uncaught exception. *) + Printf.eprintf "colitur: template %s: %s\n" template e; + exit 2 + | Ok out -> print_string out) + +(* Task 12: `colitur publish` -- writes the static tree that IS this + project's API: a set of files any web server or git repo can serve as-is, + computed once, with nothing running at request time. + + Two properties matter more than anything else here: + + DETERMINISTIC -- publishing the same year range twice must produce a + byte-identical tree. That is what makes publishing into a git repo safe: + `git status` shows only genuine change, and a human reviews a real diff + before pushing. Nothing below reads a wall clock; [dtstamp] is threaded + through as a plain parameter all the way to + {!Colitur_render.Emit_ics.year}, exactly as `emit --format ics` already + requires (see that command's own comment above). + + NON-DESTRUCTIVE -- publish writes only files it owns, names every one of + them in a manifest ([.colitur-manifest], one relative path per line, + itself never subject to pruning), and [--prune] removes only entries + THAT MANIFEST lists which this run did not rewrite. A file the caller put + in the output directory themselves is never in the manifest, so it is + never touched, with or without [--prune] -- asserted in both directions + in test/cli.t. *) + +let rec mkdir_p path = + if path <> "" && path <> "/" && not (Sys.file_exists path) then begin + mkdir_p (Filename.dirname path); + try Unix.mkdir path 0o755 with Unix.Unix_error (Unix.EEXIST, _, _) -> () + end + +let write_file path contents = + mkdir_p (Filename.dirname path); + let oc = open_out_bin path in + output_string oc contents; + close_out oc + +let manifest_name = ".colitur-manifest" + +(* [read_file] rather than a second hand-rolled reader -- see its own + comment above for why the whole read, not only the open, is guarded. A + missing manifest (the very first publish into a fresh directory) is not + an error here: it just means there is nothing yet to prune against. *) +let read_manifest out = + match read_file (Filename.concat out manifest_name) with + | Error _ -> [] + | Ok contents -> String.split_on_char '\n' contents |> List.filter (fun l -> l <> "") + +(* Fix round 1 (coordinator review), CRITICAL: a manifest entry is + UNTRUSTED input the moment [--prune] reads it back. The manifest is a + plain-text file that lives INSIDE the very tree this feature exists to + have committed into a git repo -- an ordinary bad merge or a hand-edit is + enough to put an arbitrary path in it, no attacker required. Without a + check, an entry like "../outside/CANARY.txt" resolves, via + [Filename.concat out entry], to a path OUTSIDE [out], and the prune loop + below would [Sys.remove] it -- deleting a file [publish] never wrote, + breaking the "never deletes a file it does not own" contract outright. + + Two independent checks, deliberately, because either alone is easy to + regress later without anyone noticing in review: + + 1. STRUCTURAL ([manifest_entry_is_safe]) -- reject an entry that is + absolute, or that has a ".." path component anywhere. Split on '/' + and compare COMPONENTS, never a bare substring test: substring- + matching ".." would wrongly reject a legitimate name like + "foo..bar", which contains the two characters but has no ".." + component of its own. + 2. CONTAINMENT ([resolves_under]) -- even an entry that passes check 1 + is not trusted until the path it actually resolves to, symlinks + included, is verified to sit under [out]. [Unix.realpath] resolves + symlinks as well as "..", so this also catches an entry that a + symlink planted inside [out] could use to defeat check 1 alone. A + plain string-prefix compare is not enough by itself either: + "/tmp/pub1" is a byte-prefix of "/tmp/pub1-evil", a directory that is + not nested inside it at all, so [is_under] insists the character + right after the prefix is the path separator (or that the paths are + identical). *) +let manifest_entry_is_safe entry = + entry <> "" + && entry.[0] <> '/' + && not (List.mem ".." (String.split_on_char '/' entry)) + +let is_under ~root path = + let root = + if String.length root > 1 && root.[String.length root - 1] = '/' then + String.sub root 0 (String.length root - 1) + else root + in + String.equal path root + || (String.length path > String.length root + && String.sub path 0 (String.length root) = root + && path.[String.length root] = '/') + +(* [Unix.realpath] requires the path to exist, which is fine here: every + caller below checks [Sys.file_exists]/[Sys.readdir] first. Any failure + (missing path, dangling symlink, permission error) is treated as "not + contained" -- refuse to act rather than guess. *) +let resolves_under out p = + match Unix.realpath out with + | exception (Unix.Unix_error _ | Sys_error _) -> false + | out_real -> ( + match Unix.realpath p with + | exception (Unix.Unix_error _ | Sys_error _) -> false + | p_real -> is_under ~root:out_real p_real) + +(* [--prune] deletes the FILES a stale manifest entry names, but that alone + can leave their parent directories (ef/<year>/<mm>/, then ef/<year>/) + empty behind them -- and an empty directory still makes `test -d + out/ef/<year>` true, which is exactly the check a caller uses to confirm + an old year is gone. Walk upward from each deleted file's own directory, + removing it while it is empty, stopping at (never including) [out] + itself: [out] is the caller's own directory, never ours to remove, even + when it is empty. The same containment discipline as the file deletions + above applies here too ([resolves_under]), not only structurally (this + function is only ever reached via a [p] the file-deletion path already + validated, but re-checking each directory step is the belt to that + entry's braces -- see the two-layer reasoning above). *) +let rec prune_empty_dirs ~out dir = + if + dir <> out + && String.length dir > String.length out + && Sys.file_exists dir + && resolves_under out dir + then + match Sys.readdir dir with + | [||] -> + (try Unix.rmdir dir with Unix.Unix_error _ -> ()); + prune_empty_dirs ~out (Filename.dirname dir) + | _ -> () + | exception Sys_error _ -> () + +(* schema/day-v1.json is resolved the same prefix-relative way [data_dir] + above resolves data/ef/*.sexp -- NOT from the process's own cwd, which + would break an installed binary invoked from an arbitrary directory. Two + candidates, installed then build-tree, the same shape as [data_dir]; a + candidate counts only if the file is actually there. No COLITUR_DATA_DIR + override here: that variable's whole contract is about the directory + holding sanctoral.sexp, and schema/ is not nested inside it. + + The installed candidate assumes schema/ lands at + <prefix>/share/colitur/schema/day-v1.json, mirroring data/dune's own ef/ + layout. Adding that install rule is explicitly Task 13's job, not this + one -- this function only has to be ready to find the file once the rule + exists, which is why it is PROBED rather than assumed, exactly like + [data_dir]'s own installed candidate. *) +let schema_path () = + let prefix = Filename.dirname (Filename.dirname Sys.executable_name) in + let installed = + List.fold_left Filename.concat prefix [ "share"; "colitur"; "schema"; "day-v1.json" ] + in + let build_tree = List.fold_left Filename.concat prefix [ "schema"; "day-v1.json" ] in + if Sys.file_exists installed then Some installed else if Sys.file_exists build_tree then Some build_tree else None + +(* An ordinary OCaml string, NOT a template: it describes the TREE, not the + calendar, so it has no business in the template vocabulary. *) +let index_html ~from_y ~to_y = + let b = Buffer.create 4096 in + Buffer.add_string b + "<!doctype html>\n<html lang=\"en\"><head><meta charset=\"utf-8\">\n\ + <title>colitur</title>\n\ + <style>body{font-family:sans-serif;max-width:40em;margin:2em auto;line-height:1.5}\n\ + code{background:#f4f4f4;padding:.1em .3em}</style></head><body>\n\ + <h1>colitur</h1>\n\ + <p>Liturgical calendar of the 1962 Missale Romanum. Citations only \xe2\x80\x94 never scripture text.</p>\n"; + Buffer.add_string b "<h2>Subscribe</h2>\n<ul>\n"; + for y = from_y to to_y do + Buffer.add_string b (Printf.sprintf "<li><a href=\"ef/%d.ics\">ef/%d.ics</a></li>\n" y y) + done; + Buffer.add_string b "</ul>\n<h2>Data</h2>\n<ul>\n"; + for y = from_y to to_y do + Buffer.add_string b + (Printf.sprintf + "<li>%d: <a href=\"ef/%d.json\">json</a> <a href=\"ef/%d.csv\">csv</a> \ + <a href=\"ef/%d.xml\">xml</a> \xe2\x80\x94 per-day at <code>ef/%d/MM/DD.json</code></li>\n" + y y y y y) + done; + Buffer.add_string b + "</ul>\n<p>Contract: <a href=\"schema/day-v1.json\">schema/day-v1.json</a></p>\n\ + </body></html>\n"; + Buffer.contents b + +let publish_report ~from_y ~to_y ~out ~overlays ~dtstamp ~prune = + check_dtstamp dtstamp; + if from_y > to_y then begin + Printf.eprintf "colitur: --from %d is after --to %d\n" from_y to_y; + exit 2 + end; + (* Resolved and read BEFORE any file is written, so a missing/unreadable + schema fails fast, before the output directory has anything half- + written in it. [read_file]'s own error text says "cannot read + template ..." (it was built for Task 9's template reads) -- accurate + about the mechanism, wrong about the noun, so the message here is + rebuilt rather than printed verbatim. *) + let schema = + match schema_path () with + | None -> + Printf.eprintf + "colitur: cannot find schema/day-v1.json (looked in the installed and build-tree locations)\n"; + exit 2 + | Some p -> ( + match read_file p with + | Error _ -> + Printf.eprintf "colitur: cannot read schema %s\n" p; + exit 2 + | Ok s -> s) + in + let written = ref [] in + let emit rel contents = + write_file (Filename.concat out rel) contents; + written := rel :: !written + in + for y = from_y to to_y do + let days = resolved_year_days ~overlays y in + let v = Colitur_render.View.of_days ~vocab:Rite_ef.Vocab_ef.vocab ~rite:"ef" ~year:y days in + let ys = string_of_int y in + emit ("ef/" ^ ys ^ ".json") (Colitur_render.Emit_json.year v); + emit ("ef/" ^ ys ^ ".csv") (Colitur_render.Emit_csv.year v); + emit ("ef/" ^ ys ^ ".xml") (Colitur_render.Emit_xml.year v); + emit ("ef/" ^ ys ^ ".ics") (Colitur_render.Emit_ics.year ?dtstamp v); + (* One file per day: the static equivalent of a per-day endpoint. + [View.of_days] with a one-day list yields 12 months, 11 empty, one + populated -- exactly the shape a single day's own page needs. *) + List.iter + (fun d -> + let iso = D.to_iso8601 d.Colitur_kernel.Liturgical_day.date in + let mm = String.sub iso 5 2 and dd = String.sub iso 8 2 in + let one = Colitur_render.View.of_days ~vocab:Rite_ef.Vocab_ef.vocab ~rite:"ef" ~year:y [ d ] in + emit (Printf.sprintf "ef/%s/%s/%s.json" ys mm dd) (Colitur_render.Emit_json.year one)) + days + done; + emit "schema/day-v1.json" schema; + emit "index.html" (index_html ~from_y ~to_y); + let now = List.sort compare !written in + (* Every stale entry is validated TWICE before anything is removed -- + see [manifest_entry_is_safe]/[resolves_under]'s own comment above for + why both layers exist. A rejected entry is skipped and warned about on + stderr, never fatal: a corrupt or hand-mangled manifest must not make + `publish` itself unusable -- it completes, having refused to act on + the bad line. *) + if prune then + List.iter + (fun old -> + if not (List.mem old now) then + if not (manifest_entry_is_safe old) then + Printf.eprintf + "colitur: refusing to prune manifest entry %S (absolute path or .. component) +" old + else begin + let p = Filename.concat out old in + if Sys.file_exists p then + if resolves_under out p then begin + Sys.remove p; + prune_empty_dirs ~out (Filename.dirname p) + end + else + Printf.eprintf "colitur: refusing to prune %s (resolves outside %s) +" p out + end) + (read_manifest out); + write_file (Filename.concat out manifest_name) (String.concat "\n" now ^ "\n"); + Printf.printf "colitur: wrote %d files to %s\n" (List.length now) out + (* Help and usage are deliberately DIFFERENT things, and the difference is the Unix convention rather than a preference: asking for help is a request that SUCCEEDED, so [--help] prints to stdout and exits 0 (it can be piped into a @@ -388,6 +832,19 @@ usage: colitur day <year> the resolved day identity, one line per day colitur readings <year> the Mass reading citations, one line per day colitur day|readings <year> --overlay FILE [--overlay FILE ...] + colitur emit --format csv|json|sexp|xml|ics --from Y --to Y + [--overlay FILE ...] [--dtstamp S] + render a resolved year range through one of five emitters + colitur table --year Y --template FILE [--flavour X] [--overlay FILE ...] + colitur render --template FILE --year Y [--flavour X] [--overlay FILE ...] + compute year Y and render it through FILE, a logic-less + Mustache-family template; table and render are the same + operation, two names (see "rendering" below) + colitur publish --from Y --to Y --out DIR [--overlay FILE ...] [--prune] + [--dtstamp S] + write the static tree: per-year csv/json/xml/ics, one JSON + file per day, the schema and a generated index (see + "publish" below) colitur new-overlay print a starter overlay file to stdout colitur convert FILE.ini flat INI overlay -> S-expression, on stdout colitur check FILE ... load an overlay, say what it does, exit 2 if not @@ -407,14 +864,21 @@ output formats: day stays space-separated; that is why they are separate commands rather than extra columns. + emit one schema (season, week, slug, rank, colour, subject, names, + citations, commemorations), rendered five ways: csv (RFC 4180, + one header for the whole run), json, sexp, xml (schema/colitur- + v1.xsd) and ics (RFC 5545). --from/--to give a civil-year range, + inclusive. --dtstamp fixes the ics DTSTAMP so two runs over the + same data are byte-identical -- the engine reads no clock. + overlays: --overlay FILE (repeatable, ordered; -o) applies a user calendar ON TOP of the shipped universal one, never instead of it, so local feasts add to it rather than replacing it. Later files win over earlier ones, and over the universal calendar, when they name the same - slug. Accepted on `day` and `readings` only -- the other commands - read no sanctoral data, so the flag is refused there rather than - silently ignored. + slug. Accepted on `day`, `readings`, `emit`, `table`, `render` and + `publish` -- `easter` and `temporal` read no sanctoral data, so + the flag is refused there rather than silently ignored. An overlay is applied, NOT validated: colitur's test layers assert things about the shipped calendar and cannot vouch for a file you @@ -443,6 +907,84 @@ overlays: (Nth_weekday (month M) (nth N) (weekday W)) with N negative to count from the end of the month. +rendering: + --template FILE (required on `table`/`render`) is a logic-less Mustache- + family template: {{placeholder}}, {{#section}}...{{/section}}, + {{^inverted}}...{{/inverted}}, {{!comment}} -- nothing else. It is + DATA, never a program: no partials, no lambdas, no expression + evaluation, no filesystem or process access, and no "raw" or + triple-brace form that could opt out of escaping. The value it + renders against is the same schema `emit` uses (season, week, + slug, rank, colour, subject, names, citations, commemorations), + reshaped into a booklet (`days`) and a month grid (`weeks`, with + padding cells for the leading/trailing blanks); see + colitur-templates(5) for the full field list, the syntax and the + scope-shadowing hazard (an inner key silently loses to an outer + key of the same name -- a bare {{name.la}} inside a day resolves + to the enclosing MONTH's name, not the day's own). + + --flavour X selects how interpolated VALUES are escaped (never the + template's own literal markup, which is the author's). One of: + + latex groff html xml ics none + + Inferred from --template's extension when --flavour is omitted: + + .tex -> latex + .ms .mom .me -> groff + .html .htm -> html + .xml -> xml + .ics -> ics + .md .adoc .txt -> none (no metacharacters are escaped; + Markdown/AsciiDoc/plain text have no fixed + metacharacter set, so escaping them here + would produce worse output than leaving + them alone) + + An extension colitur does not recognise is a hard ERROR naming + the six flavours above, never a silent fallback to `none`: + guessing wrong produces output that looks fine until the + metacharacters it silently failed to escape show up. + + `table` and `render` are the SAME operation under two names. The design + this project followed originally sketched `compute | render` as a + Unix pipe, with `render` reading a serialised view back from + stdin. That is deliberately not built: honouring the pipe would + need a JSON *parser*, purely so this program could re-read a view + it had just serialised itself -- a second hand-rolled component, + and a second place for the published contract to drift, for no + benefit over calling the view builder directly in the same + process. There is therefore no stdin-fed `render`; `colitur emit + --format json | jq` still composes for real pipe use, because + that JSON is the OUTPUT, never something colitur itself parses + back in. + +publish: + --out DIR (required) writes the static tree that IS this program's API: + any web server or git repo can serve it as-is, and nothing runs + at request time. + + ef/<year>.{json,csv,xml,ics} one civil year, all days + ef/<year>/<mm>/<dd>.json one file per day + schema/day-v1.json the published JSON contract + index.html a generated index page + .colitur-manifest every path this run wrote + + Deterministic: publishing the same --from/--to range twice + produces a byte-identical tree (--dtstamp behaves exactly as on + `emit`). That is what makes publishing into a git repo safe -- + `git status` shows only real change, and you review an actual + diff before pushing. + + Non-destructive: publish writes only files it owns, and records + every one in .colitur-manifest. A file you put in the output + directory yourself is never in that manifest, so it is never + touched, whether or not --prune is given. --prune additionally + removes manifest entries from a PREVIOUS run that this run did + not rewrite (e.g. an earlier year's per-day files, when you + publish a different range into the same directory) -- never + anything the manifest does not name. + environment: COLITUR_DATA_DIR Read the calendar data from this directory instead of the @@ -456,7 +998,10 @@ exit status: Reading references only (e.g. "Jn 3:16"); never scripture text. See colitur(1) for the full description and the sources it computes against, -and colitur-overlay(5) for the overlay file format in full.|} +colitur-overlay(5) for the overlay file format in full, and +colitur-templates(5) for the template format in full -- the syntax, the +scope-shadowing hazard, the six flavours' escaping, and the full view-model +field reference.|} let print_help () = print_endline help_text; @@ -465,7 +1010,9 @@ let print_help () = let usage () = prerr_endline "colitur: usage: colitur easter <year> | colitur temporal <year> | colitur day <year> | colitur \ - readings <year> | colitur check FILE | colitur new-overlay (try: colitur --help)"; + readings <year> | colitur emit --format FMT --from Y --to Y | colitur table --year Y --template \ + FILE | colitur render --template FILE --year Y | colitur publish --from Y --to Y --out DIR | \ + colitur check FILE | colitur new-overlay (try: colitur --help)"; exit 2 let with_year ys f = @@ -485,12 +1032,55 @@ let with_year ys f = [--overlay] accumulates in the order given, and that order is load-bearing ({!Overlay.merge} is last-writer-wins), so the list is reversed exactly - once at the end rather than callers guessing. *) + once at the end rather than callers guessing. + + [--format]/[--from]/[--to]/[--dtstamp] (Task 8, `emit`) are each single- + valued, unlike [--overlay], so they are plain [string option] fields + rather than accumulating lists. *) +(* [year]/[template]/[flavour] (Task 9, `table`/`render`) are each single- + valued, the same shape as [format]/[from_y]/[to_y]/[dtstamp] above -- + `table`/`render` take one year and one template file, never a range or a + repeatable list. *) +(* [out] (Task 12, `publish`) is single-valued like [format]/[year]/etc. + [prune] is the one plain boolean flag in this whole record -- every other + field here takes a value, but [--prune] does not, so it cannot reuse the + `"--flag" :: v :: rest` shape the value-taking flags share below. *) +type parsed_args = { + overlays : string list; + format : string option; + from_y : string option; + to_y : string option; + dtstamp : string option; + year : string option; + template : string option; + flavour : string option; + out : string option; + prune : bool; + positional : string list; +} + let parse_args argv = - let rec go overlays positional = function - | [] -> Ok (List.rev overlays, List.rev positional) - | ("--overlay" | "-o") :: path :: rest -> go (path :: overlays) positional rest + let rec go acc = function + | [] -> Ok { acc with overlays = List.rev acc.overlays; positional = List.rev acc.positional } + | ("--overlay" | "-o") :: path :: rest -> go { acc with overlays = path :: acc.overlays } rest | [ ("--overlay" | "-o") ] -> Error "--overlay needs a file path" + | "--format" :: v :: rest -> go { acc with format = Some v } rest + | [ "--format" ] -> Error "--format needs a value" + | "--from" :: v :: rest -> go { acc with from_y = Some v } rest + | [ "--from" ] -> Error "--from needs a value" + | "--to" :: v :: rest -> go { acc with to_y = Some v } rest + | [ "--to" ] -> Error "--to needs a value" + | "--dtstamp" :: v :: rest -> go { acc with dtstamp = Some v } rest + | [ "--dtstamp" ] -> Error "--dtstamp needs a value" + | "--year" :: v :: rest -> go { acc with year = Some v } rest + | [ "--year" ] -> Error "--year needs a value" + | "--template" :: v :: rest -> go { acc with template = Some v } rest + | [ "--template" ] -> Error "--template needs a value" + | "--flavour" :: v :: rest -> go { acc with flavour = Some v } rest + | [ "--flavour" ] -> Error "--flavour needs a value" + | "--out" :: v :: rest -> go { acc with out = Some v } rest + | [ "--out" ] -> Error "--out needs a directory path" + | "--prune" :: rest -> go { acc with prune = true } rest (* The recognised bare flags pass through as positional words for the dispatch below to match; anything else beginning with '-' is rejected rather than silently treated as a command or a year. *) @@ -499,9 +1089,24 @@ let parse_args argv = && arg.[0] = '-' && not (List.mem arg [ "-h"; "--help"; "-V"; "--version" ]) -> Error (Printf.sprintf "unknown option %s" arg) - | arg :: rest -> go overlays (arg :: positional) rest + | arg :: rest -> go { acc with positional = arg :: acc.positional } rest in - go [] [] argv + go + { overlays = []; format = None; from_y = None; to_y = None; dtstamp = None; year = None; + template = None; flavour = None; out = None; prune = false; positional = [] } + argv + +(* Sibling to [reject_overlays_for]: `emit`'s own four flags have no meaning + on any other command (they take a single [<year>] positional, not a + [--from]/[--to] range), so accepting and silently dropping them would be + the same failure mode `--overlay` already refuses on `easter`/`temporal`. *) +let reject_emit_flags_for cmd ~format ~from_y ~to_y ~dtstamp = + if format <> None || from_y <> None || to_y <> None || dtstamp <> None then begin + Printf.eprintf + "colitur: --format/--from/--to/--dtstamp have no effect on `%s`; refusing rather than ignoring them\n" + cmd; + exit 2 + end (* [easter] reads no calendar data at all, and [temporal] deliberately runs the temporal cycle BEFORE any sanctoral layer exists, so an overlay could not @@ -513,6 +1118,39 @@ let reject_overlays_for cmd overlays = exit 2 end +(* Sibling to [reject_emit_flags_for]/[reject_overlays_for]: `table`/`render`'s + own three flags (Task 9) have no meaning on any other command, so accepting + and silently dropping them would be the same failure mode this project + already refuses everywhere else. *) +let reject_table_flags_for cmd ~year ~template ~flavour = + if year <> None || template <> None || flavour <> None then begin + Printf.eprintf + "colitur: --year/--template/--flavour have no effect on `%s`; refusing rather than ignoring them\n" + cmd; + exit 2 + end + +(* Sibling to [reject_emit_flags_for]/[reject_table_flags_for]: `--format` + has no meaning on `publish` (it always writes all four whole-year + formats plus the per-day JSON tree, never a single chosen one), so + accepting and silently dropping it would be the same failure mode this + project already refuses everywhere else. Narrower than + [reject_emit_flags_for] on purpose -- `publish` legitimately takes + --from/--to/--dtstamp, so that blanket check cannot be reused here. *) +let reject_format_for cmd format = + if format <> None then begin + Printf.eprintf "colitur: --format has no effect on `%s`; refusing rather than ignoring it\n" cmd; + exit 2 + end + +(* Sibling to the three rejectors above: `--out`/`--prune` (Task 12) have no + meaning on any command except `publish`. *) +let reject_publish_flags_for cmd ~out ~prune = + if out <> None || prune then begin + Printf.eprintf "colitur: --out/--prune have no effect on `%s`; refusing rather than ignoring them\n" cmd; + exit 2 + end + (* `colitur check FILE...` -- load a user overlay, apply it to the real shipped calendar, and say what it did, without printing a year of output. @@ -677,31 +1315,129 @@ let () = | Error msg -> Printf.eprintf "colitur: %s\n" msg; usage () - | Ok (overlays, positional) -> ( + | Ok { overlays; format; from_y; to_y; dtstamp; year; template; flavour; out; prune; positional } -> ( + let reject_emit = reject_emit_flags_for ~format ~from_y ~to_y ~dtstamp in + let reject_table = reject_table_flags_for ~year ~template ~flavour in + let reject_publish = reject_publish_flags_for ~out ~prune in match positional with | [ ("-h" | "--help" | "help") ] -> reject_overlays_for "--help" overlays; + reject_emit "--help"; + reject_table "--help"; + reject_publish "--help"; print_help () | [ ("-V" | "--version" | "version") ] -> reject_overlays_for "--version" overlays; + reject_emit "--version"; + reject_table "--version"; + reject_publish "--version"; print_endline version; exit 0 | [ "easter"; ys ] -> reject_overlays_for "easter" overlays; + reject_emit "easter"; + reject_table "easter"; + reject_publish "easter"; with_year ys easter_report | [ "temporal"; ys ] -> reject_overlays_for "temporal" overlays; + reject_emit "temporal"; + reject_table "temporal"; + reject_publish "temporal"; with_year ys temporal_report | "check" :: (_ :: _ as files) -> reject_overlays_for "check" overlays; + reject_emit "check"; + reject_table "check"; + reject_publish "check"; check_report files | [ "convert"; path ] -> reject_overlays_for "convert" overlays; + reject_emit "convert"; + reject_table "convert"; + reject_publish "convert"; convert_report path | [ "new-overlay" ] -> reject_overlays_for "new-overlay" overlays; + reject_emit "new-overlay"; + reject_table "new-overlay"; + reject_publish "new-overlay"; print_string new_overlay_template; exit 0 - | [ "day"; ys ] -> with_year ys (day_report ~overlays) - | [ "readings"; ys ] -> with_year ys (readings_report ~overlays) + | [ "day"; ys ] -> + reject_emit "day"; + reject_table "day"; + reject_publish "day"; + with_year ys (day_report ~overlays) + | [ "readings"; ys ] -> + reject_emit "readings"; + reject_table "readings"; + reject_publish "readings"; + with_year ys (readings_report ~overlays) + | [ "emit" ] -> ( + reject_table "emit"; + reject_publish "emit"; + match format with + | None -> + Printf.eprintf "colitur: emit requires --format csv|json|sexp|xml|ics\n"; + exit 2 + | Some format -> ( + match (from_y, to_y) with + | None, _ | _, None -> + Printf.eprintf "colitur: emit requires --from YEAR and --to YEAR\n"; + exit 2 + | Some from_ys, Some to_ys -> + with_year from_ys (fun from_y -> + with_year to_ys (fun to_y -> emit_report ~format ~overlays ~dtstamp ~from_y ~to_y)))) + | [ ("table" | "render") as cmd ] -> ( + reject_emit cmd; + reject_publish cmd; + match template with + | None -> + Printf.eprintf "colitur: %s requires --year YEAR and --template FILE\n" cmd; + exit 2 + | Some template -> ( + match year with + | None -> + Printf.eprintf "colitur: %s requires --year YEAR and --template FILE\n" cmd; + exit 2 + | Some ys -> with_year ys (fun y -> table_report ~template ~flavour_opt:flavour ~overlays y) + )) + | [ "publish" ] -> ( + reject_table "publish"; + reject_format_for "publish" format; + match out with + | None -> + Printf.eprintf "colitur: publish requires --out DIR\n"; + exit 2 + | Some out -> ( + match (from_y, to_y) with + | None, _ | _, None -> + Printf.eprintf "colitur: publish requires --from YEAR and --to YEAR\n"; + exit 2 + | Some from_ys, Some to_ys -> + with_year from_ys (fun from_y -> + with_year to_ys (fun to_y -> + (* [publish_report] writes many files across a whole + year range ([mkdir_p]/[write_file], both above) -- + an unwritable [--out] parent (EACCES) or an [--out] + that names an existing plain file (ENOTDIR) raises + from deep inside that loop, same defect class as + the template read this project already guards + (commit 6bd741b): "--out" is user input too, and + the WHOLE call is guarded here rather than each + [write_file] site individually, for the same + reason that fix guarded the whole read and not + only the open. [Unix.mkdir] raises + [Unix.Unix_error] directly; [open_out_bin] + (stdlib, not the Unix module) wraps the same + underlying errno in [Sys_error] instead -- both + are real on this path, so both are caught. *) + try publish_report ~from_y ~to_y ~out ~overlays ~dtstamp ~prune with + | Unix.Unix_error (e, fn, arg) -> + Printf.eprintf "colitur: %s: %s: %s\n" fn arg (Unix.error_message e); + exit 2 + | Sys_error e -> + Printf.eprintf "colitur: %s\n" e; + exit 2)))) | _ -> usage ()) @@ -23,10 +23,22 @@ ; this file was originally written to close applied to it too -- a fresh ; `dune build` left it absent from _build/default/data/ef/, only ever ; materialised there as a side effect of test/dune's own deps. +; +; schema/day-v1.json added here for the identical reason again (Task 12, +; `colitur publish`): unlike data/ef/, the top-level schema/ directory has +; no dune file of its own, so nothing makes dune copy it into +; _build/default/ by default -- confirmed empirically, a clean `dune build` +; left _build/default/schema/ missing entirely. bin/main.ml's own +; [schema_path] resolves it the same prefix-relative way [data_dir] resolves +; the sanctoral data, and that resolution needs the file actually present in +; the build tree, not only in the source tree. This is a BUILD-TIME +; convenience only -- it says nothing about `dune install`, which is +; Task 13's own job (see schema_path's comment in bin/main.ml). (alias (name default) (deps (alias_rec install) data/ef/sanctoral.sexp data/ef/adjustments.sexp - data/ef/lectionary.sexp)) + data/ef/lectionary.sexp + schema/day-v1.json)) diff --git a/lib/render/dune b/lib/render/dune new file mode 100644 index 0000000..7880188 --- /dev/null +++ b/lib/render/dune @@ -0,0 +1,5 @@ +(library + (name colitur_render) + (libraries colitur_kernel sexplib) + (preprocess + (pps ppx_sexp_conv))) diff --git a/lib/render/emit_csv.ml b/lib/render/emit_csv.ml new file mode 100644 index 0000000..b478265 --- /dev/null +++ b/lib/render/emit_csv.ml @@ -0,0 +1,44 @@ +(* emit_csv.ml *) +module T = Template + +let escape_field s = + let needs = + String.exists (fun c -> c = ',' || c = '"' || c = '\n' || c = '\r') s + in + if not needs then s + else begin + let b = Buffer.create (String.length s + 8) in + Buffer.add_char b '"'; + String.iter (fun c -> if c = '"' then Buffer.add_string b "\"\"" else Buffer.add_char b c) s; + Buffer.add_char b '"'; + Buffer.contents b + end + +let get v k = match v with T.Obj kvs -> List.assoc_opt k kvs | _ -> None +let s v k = match get v k with Some (T.Str x) -> x | _ -> "" +let nested v a b = match get v a with Some inner -> s inner b | None -> "" + +let columns = + [ "date"; "rite"; "season"; "week"; "slug"; "rank"; "colour"; "subject"; + "name_la"; "name_en"; "first"; "gospel"; "comms" ] + +let row ~rite d = + let comms = + match get d "comms" with + | Some (T.List l) -> String.concat " " (List.map (fun c -> s c "slug") l) + | _ -> "" + in + String.concat "," + (List.map escape_field + [ s d "iso"; rite; s d "season"; s d "week"; s d "slug"; s d "rank"; + s d "colour"; s d "subject"; nested d "name" "la"; nested d "name" "en"; + s d "first"; s d "gospel"; comms ]) + +let year v = + let rite = s v "rite" in + let days = match get v "days" with Some (T.List l) -> l | _ -> [] in + let b = Buffer.create (64 * 400) in + Buffer.add_string b (String.concat "," columns); + Buffer.add_char b '\n'; + List.iter (fun d -> Buffer.add_string b (row ~rite d); Buffer.add_char b '\n') days; + Buffer.contents b diff --git a/lib/render/emit_csv.mli b/lib/render/emit_csv.mli new file mode 100644 index 0000000..262f660 --- /dev/null +++ b/lib/render/emit_csv.mli @@ -0,0 +1,9 @@ +(* emit_csv.mli *) +(** One row per day, RFC 4180. Consumes the VIEW, not the kernel, so every + emitter describes exactly the same fields as every template. *) + +(** RFC 4180 section 2: quote a field containing a comma, a quote or a newline; + double an embedded quote. Exposed for testing. *) +val escape_field : string -> string + +val year : Template.value -> string diff --git a/lib/render/emit_ics.ml b/lib/render/emit_ics.ml new file mode 100644 index 0000000..41efb95 --- /dev/null +++ b/lib/render/emit_ics.ml @@ -0,0 +1,107 @@ +(* emit_ics.ml *) +module T = Template + +let get v k = match v with T.Obj kvs -> List.assoc_opt k kvs | _ -> None +let s v k = match get v k with Some (T.Str x) -> x | _ -> "" + +let compact iso = (* "2027-01-13" -> "20270113" *) + String.concat "" (String.split_on_char '-' iso) + +(* Civil-date successor without touching the kernel: parse, add, re-format via + Colitur_kernel.Date, which is already total and validated over 1583..9999. *) +let next_day iso = + match Colitur_kernel.Date.of_iso8601 iso with + | Ok d -> Colitur_kernel.Date.to_iso8601 (Colitur_kernel.Date.add_days d 1) + (* Dead on shipped data: [event]'s own [iso <> ""] guard is the only + caller, and every real [iso] it passes came from [Date.to_iso8601] in + the first place, so it always parses. Left total rather than raising + (the kernel/render determinism rule), but a caller relying on this + branch would silently get DTEND == DTSTART -- a zero-length event -- + with no diagnostic, if it were ever actually reached. Documented, not + fixed: nothing exercises it. *) + | Error _ -> iso + +(* RFC 5545 section 3.6.1: a VEVENT with a DATE-valued DTSTART and NEITHER + DTEND NOR DURATION has an implicit duration of exactly one day, so + omitting DTEND for the domain's own last day is the standard's own + correct way to say precisely what we mean -- not a workaround. + + Needed because [Date.add_days] is itself UNBOUNDED (date.mli: "may + denote a year outside 1583..9999 -- only [make] enforces the domain"): + the successor of 9999-12-31 is a real [Date.t] that [next_day] above + happily renders as "10000-01-01" (date.ml's [to_iso8601] pads with + [Printf.sprintf "%04d-..."] but never truncates), which [compact] would + turn into a 9-digit, non-conformant DATE. [Date.make] is the ONE kernel + function that actually enforces 1583..9999 (date.mli), so this takes + [next_day]'s own successor string, re-derives its year/month/day, and + re-validates THOSE through [make] before trusting the string at all. + [None] means "one day past the domain's own last day"; the caller omits + DTEND entirely rather than clamp, truncate, or fall back to DURATION. *) +let dtend_of iso = + let next = next_day iso in + match String.split_on_char '-' next with + | [ y; m; d ] -> ( + match (int_of_string_opt y, int_of_string_opt m, int_of_string_opt d) with + | Some year, Some month, Some day -> ( + match Colitur_kernel.Date.make ~year ~month ~day with + | Ok _ -> Some next + | Error _ -> None) + | _ -> None) + | _ -> None + +let esc x = Escape.apply Escape.Ics x +let line b l = Buffer.add_string b (Escape.fold_ics l) + +let event b ~rite ~dtstamp d = + let iso = s d "iso" in + if iso <> "" then begin + let name = + match get d "name" with + | Some (T.Obj kvs) -> ( + match List.assoc_opt "en" kvs with + | Some (T.Str x) when x <> "" -> x + | _ -> ( match List.assoc_opt "la" kvs with Some (T.Str x) -> x | _ -> s d "slug")) + | _ -> s d "slug" + in + let summary = Printf.sprintf "%s (%s, %s)" name (s d "rank") (s d "colour") in + let desc = + String.concat "\n" + (List.filter (fun x -> x <> "") + [ (if s d "first" <> "" then "Epistle " ^ s d "first" else ""); + (if s d "gospel" <> "" then "Gospel " ^ s d "gospel" else "") ]) + in + line b "BEGIN:VEVENT"; + (* RFC 5545 section 3.8.4.7: the UID must be stable across regenerations, + or every subscriber gets a duplicate of the whole year. *) + line b (Printf.sprintf "UID:%s-%s@colitur" (compact iso) rite); + line b ("DTSTAMP:" ^ dtstamp); + line b ("DTSTART;VALUE=DATE:" ^ compact iso); + (* RFC 5545 section 3.6.1: DTEND is EXCLUSIVE for an all-day event -- and + omitted entirely, rather than emitted malformed, for the one event + whose successor falls outside the engine's own 1583..9999 domain + (see [dtend_of] above). *) + (match dtend_of iso with + | Some next -> line b ("DTEND;VALUE=DATE:" ^ compact next) + | None -> ()); + line b ("SUMMARY:" ^ esc summary); + if desc <> "" then line b ("DESCRIPTION:" ^ esc desc); + line b "TRANSP:TRANSPARENT"; + line b "END:VEVENT" + end + +let year ?dtstamp ?calname v = + let rite = s v "rite" in + let y = s v "year" in + let dtstamp = match dtstamp with Some x -> x | None -> y ^ "0101T000000Z" in + let calname = match calname with Some x -> x | None -> "colitur " ^ rite ^ " " ^ y in + let b = Buffer.create (256 * 1024) in + line b "BEGIN:VCALENDAR"; + line b "VERSION:2.0"; + line b "PRODID:-//colitur//liturgical calendar//EN"; + line b "CALSCALE:GREGORIAN"; + line b "METHOD:PUBLISH"; + (* Non-standard but universally honoured; without it clients show the URL. *) + line b ("X-WR-CALNAME:" ^ esc calname); + (match get v "days" with Some (T.List l) -> List.iter (event b ~rite ~dtstamp) l | _ -> ()); + line b "END:VCALENDAR"; + Buffer.contents b diff --git a/lib/render/emit_ics.mli b/lib/render/emit_ics.mli new file mode 100644 index 0000000..270bd76 --- /dev/null +++ b/lib/render/emit_ics.mli @@ -0,0 +1,15 @@ +(* emit_ics.mli *) +(** RFC 5545 iCalendar. NOT a template job: folding, escaping, exclusive DTEND + and stable UIDs are rules a logic-less template cannot enforce, and getting + any of them wrong produces a feed that fails silently in a subscriber's + client (spec section 6). *) + +(** [year ?dtstamp ?calname view]. + + [dtstamp] defaults to [YYYY0101T000000Z] for the view's own year. It is a + PARAMETER, never a clock read: RFC 5545 requires DTSTAMP, the obvious + implementation reads the wall clock, and that would both violate the + kernel's determinism rule and make two feeds from identical data differ + byte-for-byte -- defeating reproducible builds and a reviewable git diff on + a published tree. Same data in, same bytes out. *) +val year : ?dtstamp:string -> ?calname:string -> Template.value -> string diff --git a/lib/render/emit_json.ml b/lib/render/emit_json.ml new file mode 100644 index 0000000..272e4ca --- /dev/null +++ b/lib/render/emit_json.ml @@ -0,0 +1,47 @@ +(* emit_json.ml *) +module T = Template + +let escape_string s = + let b = Buffer.create (String.length s + 8) in + Buffer.add_char b '"'; + String.iter + (fun c -> + match c with + | '"' -> Buffer.add_string b "\\\"" + | '\\' -> Buffer.add_string b "\\\\" + | '\n' -> Buffer.add_string b "\\n" + | '\r' -> Buffer.add_string b "\\r" + | '\t' -> Buffer.add_string b "\\t" + | c when Char.code c < 0x20 -> Buffer.add_string b (Printf.sprintf "\\u%04x" (Char.code c)) + | c -> Buffer.add_char b c) + s; + Buffer.add_char b '"'; + Buffer.contents b + +(* Emit the view tree directly. Bools stay bools; everything else is a string, + an array or an object -- there are no numbers in the view, deliberately, so a + consumer never has to guess whether "week" is 2 or "2". *) +let rec write b (v : T.value) = + match v with + | T.Str s -> Buffer.add_string b (escape_string s) + | T.Bool x -> Buffer.add_string b (if x then "true" else "false") + | T.List l -> + Buffer.add_char b '['; + List.iteri (fun i x -> if i > 0 then Buffer.add_char b ','; write b x) l; + Buffer.add_char b ']' + | T.Obj kvs -> + Buffer.add_char b '{'; + List.iteri + (fun i (k, x) -> + if i > 0 then Buffer.add_char b ','; + Buffer.add_string b (escape_string k); + Buffer.add_char b ':'; + write b x) + kvs; + Buffer.add_char b '}' + +let year v = + let b = Buffer.create (64 * 1024) in + write b v; + Buffer.add_char b '\n'; + Buffer.contents b diff --git a/lib/render/emit_json.mli b/lib/render/emit_json.mli new file mode 100644 index 0000000..91c8f48 --- /dev/null +++ b/lib/render/emit_json.mli @@ -0,0 +1,10 @@ +(* emit_json.mli *) +(** JSON writer. Hand-rolled: the dependency list is frozen (spec section 1), + and writing JSON is a page of code where escaping is the only subtlety. + Output shape is pinned by schema/day-v1.json, the published contract. *) + +(** RFC 8259 section 7, including \u-escaping of control characters below 0x20. + Returns the value WITH its surrounding quotes. Exposed for testing. *) +val escape_string : string -> string + +val year : Template.value -> string diff --git a/lib/render/emit_xml.ml b/lib/render/emit_xml.ml new file mode 100644 index 0000000..4e4b51a --- /dev/null +++ b/lib/render/emit_xml.ml @@ -0,0 +1,48 @@ +(* emit_xml.ml *) +module T = Template + +let escape s = Escape.apply Escape.Xml s + +let get v k = match v with T.Obj kvs -> List.assoc_opt k kvs | _ -> None +let s v k = match get v k with Some (T.Str x) -> x | _ -> "" +let el b name value = + Buffer.add_string b (" <" ^ name ^ ">" ^ escape value ^ "</" ^ name ^ ">\n") + +let day b d = + Buffer.add_string b (" <day date=\"" ^ escape (s d "iso") ^ "\">\n"); + el b "season" (s d "season"); + el b "week" (s d "week"); + el b "slug" (s d "slug"); + el b "rank" (s d "rank"); + el b "colour" (s d "colour"); + el b "subject" (s d "subject"); + (match get d "name" with + | Some (T.Obj kvs) -> + List.iter + (fun (lang, v) -> + match v with + | T.Str x -> Buffer.add_string b (" <name lang=\"" ^ escape lang ^ "\">" ^ escape x ^ "</name>\n") + | _ -> ()) + kvs + | _ -> ()); + (match get d "comms" with + | Some (T.List l) -> + List.iter (fun c -> Buffer.add_string b (" <commemoration>" ^ escape (s c "slug") ^ "</commemoration>\n")) l + | _ -> ()); + let cite name value = + if value <> "" then + Buffer.add_string b (" <citation part=\"" ^ name ^ "\">" ^ escape value ^ "</citation>\n") + in + cite "first" (s d "first"); + cite "gospel" (s d "gospel"); + Buffer.add_string b " </day>\n" + +let year v = + let b = Buffer.create (128 * 1024) in + Buffer.add_string b "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; + Buffer.add_string b + ("<calendar rite=\"" ^ escape (s v "rite") ^ "\" year=\"" ^ escape (s v "year") ^ "\">\n"); + Buffer.add_string b " <days>\n"; + (match get v "days" with Some (T.List l) -> List.iter (day b) l | _ -> ()); + Buffer.add_string b " </days>\n</calendar>\n"; + Buffer.contents b diff --git a/lib/render/emit_xml.mli b/lib/render/emit_xml.mli new file mode 100644 index 0000000..4d539d6 --- /dev/null +++ b/lib/render/emit_xml.mli @@ -0,0 +1,8 @@ +(* emit_xml.mli *) +(** Element-per-field XML. Attributes carry identity only (rite, year, date); + everything else is an element, and there is no mixed content -- so a + consumer's XPath never has to distinguish the two. Shape pinned by + schema/colitur-v1.xsd. *) + +val escape : string -> string +val year : Template.value -> string diff --git a/lib/render/escape.ml b/lib/render/escape.ml new file mode 100644 index 0000000..f506c44 --- /dev/null +++ b/lib/render/escape.ml @@ -0,0 +1,95 @@ +type flavour = Latex | Groff | Html | Xml | Ics | None_ + +let all = [ Latex; Groff; Html; Xml; Ics; None_ ] + +let to_string = function + | Latex -> "latex" | Groff -> "groff" | Html -> "html" + | Xml -> "xml" | Ics -> "ics" | None_ -> "none" + +let of_string = function + | "latex" -> Some Latex | "groff" -> Some Groff | "html" -> Some Html + | "xml" -> Some Xml | "ics" -> Some Ics | "none" -> Some None_ + | _ -> None + +let of_extension = function + | ".tex" -> Some Latex + | ".ms" | ".mom" | ".me" -> Some Groff + | ".html" | ".htm" -> Some Html + | ".xml" -> Some Xml + | ".ics" -> Some Ics + | ".md" | ".adoc" | ".txt" -> Some None_ + | _ -> None + +(* Replace each character with its expansion, in ONE pass. A sequence of + String.concat replacements would double-escape: "&" -> "\\&" then the + backslash rule would rewrite the backslash it just introduced. *) +let expand f s = + let b = Buffer.create (String.length s + 16) in + String.iter (fun c -> Buffer.add_string b (f c)) s; + Buffer.contents b + +let latex = function + | '\\' -> "\\textbackslash{}" + | '{' -> "\\{" | '}' -> "\\}" + | '$' -> "\\$" | '&' -> "\\&" | '#' -> "\\#" + | '_' -> "\\_" | '%' -> "\\%" + | '^' -> "\\textasciicircum{}" + | '~' -> "\\textasciitilde{}" + | c -> String.make 1 c + +let html = function + | '&' -> "&" | '<' -> "<" | '>' -> ">" + | '"' -> """ | '\'' -> "'" + | c -> String.make 1 c + +let ics = function + | '\\' -> "\\\\" | ';' -> "\\;" | ',' -> "\\," + | '\n' -> "\\n" | '\r' -> "" + | c -> String.make 1 c + +(* groff: a backslash starts an escape, and a '.' or '\'' in COLUMN ONE starts a + request. \& is the zero-width non-printing character that defuses it. *) +let groff s = + let escaped = expand (function '\\' -> "\\e" | c -> String.make 1 c) s in + if String.length escaped > 0 && (escaped.[0] = '.' || escaped.[0] = '\'') then "\\&" ^ escaped + else escaped + +let apply flavour s = + match flavour with + | Latex -> expand latex s + | Groff -> groff s + | Html | Xml -> expand html s + | Ics -> expand ics s + | None_ -> s + +(* RFC 5545 section 3.1. A continuation byte is 0x80-0xBF; backing off to a + non-continuation byte keeps every fold on a character boundary. *) +let fold_ics line = + let n = String.length line in + let b = Buffer.create (n + (n / 70) + 8) in + let is_cont c = Char.code c land 0xC0 = 0x80 in + let rec go pos first = + let limit = if first then 75 else 74 (* the leading space costs one octet *) in + if n - pos <= limit then ( + if not first then Buffer.add_char b ' '; + Buffer.add_string b (String.sub line pos (n - pos)); + Buffer.add_string b "\r\n") + else begin + let cut = ref (pos + limit) in + while !cut > pos && is_cont line.[!cut] do decr cut done; + (* Valid UTF-8's longest continuation run is 3, so backoff finds a + boundary within a few bytes. But this function must stay TOTAL on + ARBITRARY octet strings, not only valid UTF-8: 74+ consecutive + continuation bytes back `cut` all the way down to `pos`, which would + yield a zero-length chunk and recurse on the identical position + forever. When backoff finds no boundary inside the window, cut hard + at the limit instead -- forward progress is then unconditional. *) + if !cut = pos then cut := pos + limit; + if not first then Buffer.add_char b ' '; + Buffer.add_string b (String.sub line pos (!cut - pos)); + Buffer.add_string b "\r\n"; + go !cut false + end + in + go 0 true; + Buffer.contents b diff --git a/lib/render/escape.mli b/lib/render/escape.mli new file mode 100644 index 0000000..97cf050 --- /dev/null +++ b/lib/render/escape.mli @@ -0,0 +1,28 @@ +(** Per-flavour escaping for the template engine, plus RFC 5545 line folding. + + Knows nothing about calendars. Pure and total: every function is defined on + every string, and none reads the clock, the environment or the filesystem. *) + +(** The six escaping modes. Markdown, AsciiDoc and plain text all use [None_]: + their metacharacter sets are context-dependent, and escaping them + aggressively produces worse output than not escaping at all (spec section 5). + This is a documented limitation of those flavours. *) +type flavour = Latex | Groff | Html | Xml | Ics | None_ + +val all : flavour list +val to_string : flavour -> string +val of_string : string -> flavour option + +(** [of_extension ".tex"] is [Some Latex]. Returns [None] for an unrecognised + extension: the caller must treat that as an error, never as a fallback to + [None_] (spec section 5 -- guessing wrong here produces malformed output + that looks fine until it does not). *) +val of_extension : string -> flavour option + +(** Escape one interpolated value for [flavour]. *) +val apply : flavour -> string -> string + +(** Fold one unfolded content line per RFC 5545 section 3.1: at most 75 octets + per line, continuation lines prefixed with one space, CRLF terminators, + never splitting a UTF-8 sequence. The returned string ends with CRLF. *) +val fold_ics : string -> string diff --git a/lib/render/template.ml b/lib/render/template.ml new file mode 100644 index 0000000..7efa92b --- /dev/null +++ b/lib/render/template.ml @@ -0,0 +1,151 @@ +type value = + | Str of string + | Bool of bool + | List of value list + | Obj of (string * value) list + +type node = + | Text of string + | Var of string list + | Section of string list * node list + | Inverted of string list * node list + +type tag = TVar of string list | TOpen of string list | TInv of string list | TClose of string list | TComment + +let trim = String.trim + +let path s = + String.split_on_char '.' (trim s) |> List.map trim |> List.filter (fun x -> x <> "") + +(* Lex into a flat list of text and tags. Returns Error on an unterminated tag + rather than treating the remainder as text: silently swallowing "{{name" is + how a typo becomes invisible missing output. *) +let lex src = + let n = String.length src in + let out = ref [] in + let buf = Buffer.create 256 in + let flush () = + if Buffer.length buf > 0 then (out := `Text (Buffer.contents buf) :: !out; Buffer.clear buf) + in + let rec go i = + if i >= n then (flush (); Ok (List.rev !out)) + else if i + 1 < n && src.[i] = '{' && src.[i + 1] = '{' then + match String.index_from_opt src (i + 2) '}' with + | Some j when j + 1 < n && src.[j + 1] = '}' -> + let body = String.sub src (i + 2) (j - i - 2) in + flush (); + let tag = + let b = trim body in + if b = "" then Error "empty tag {{}}" + else + (* Every sigil form (var, #, ^, /) resolves a dotted path; an + empty path ("{{.}}", "{{#}}", "{{^}}", "{{/}}") names + nothing -- there is no "current context" concept for a bare + dot to mean, so it is a parse error rather than an invented + behaviour Task 3 would have to define. *) + let with_path ctor rest = + match path rest with + | [] -> Error "empty tag path: {{.}} and {{#}} name nothing" + | p -> Ok (ctor p) + in + match b.[0] with + | '#' -> with_path (fun p -> TOpen p) (String.sub b 1 (String.length b - 1)) + | '^' -> with_path (fun p -> TInv p) (String.sub b 1 (String.length b - 1)) + | '/' -> with_path (fun p -> TClose p) (String.sub b 1 (String.length b - 1)) + | '!' -> Ok TComment + | '>' -> Error "partials are not supported: a template may not include another file" + | _ -> with_path (fun p -> TVar p) b + in + (match tag with + | Error e -> Error e + | Ok t -> out := `Tag t :: !out; go (j + 2)) + | _ -> Error "unterminated tag: '{{' with no matching '}}'" + else (Buffer.add_char buf src.[i]; go (i + 1)) + in + go 0 + +(* Fold the flat list into a tree, checking that every close matches its open. *) +let build items = + let rec go acc stack items = + match items with + | [] -> ( + match stack with + | [] -> Ok (List.rev acc) + | (p, _, _) :: _ -> Error ("unclosed section {{#" ^ String.concat "." p ^ "}}")) + | `Text "" :: rest -> go acc stack rest + | `Text t :: rest -> go (Text t :: acc) stack rest + | `Tag TComment :: rest -> go acc stack rest + | `Tag (TVar p) :: rest -> go (Var p :: acc) stack rest + | `Tag (TOpen p) :: rest -> go [] ((p, `Sec, acc) :: stack) rest + | `Tag (TInv p) :: rest -> go [] ((p, `Inv, acc) :: stack) rest + | `Tag (TClose p) :: rest -> ( + match stack with + | [] -> Error ("close tag {{/" ^ String.concat "." p ^ "}} with no open section") + | (op, kind, outer) :: tl -> + if op <> p then + Error + ("mismatched close: {{#" ^ String.concat "." op ^ "}} closed by {{/" + ^ String.concat "." p ^ "}}") + else + let inner = List.rev acc in + let node = match kind with `Sec -> Section (op, inner) | `Inv -> Inverted (op, inner) in + go (node :: outer) tl rest) + in + go [] [] items + +let parse src = match lex src with Error e -> Error e | Ok items -> build items + +(* Scope is a STACK, innermost first: a section pushes its own object, and a + lookup falls back outward. Without the fallback a grid template could not + reach the year number from inside a week. *) +let rec lookup stack path = + match stack with + | [] -> None + | top :: rest -> ( + match descend top path with Some v -> Some v | None -> lookup rest path) + +and descend v path = + match (v, path) with + | _, [] -> Some v + | Obj kvs, k :: tl -> ( + match List.assoc_opt k kvs with Some v' -> descend v' tl | None -> None) + | _ -> None + +let truthy = function + | Bool b -> b + | Str "" -> false + | Str _ -> true + | List [] -> false + | List _ -> true + | Obj _ -> true + +let render ~flavour nodes value = + let b = Buffer.create 4096 in + let rec go stack nodes = + List.iter + (fun node -> + match node with + | Text t -> Buffer.add_string b t + | Var p -> ( + match lookup stack p with + | Some (Str s) -> Buffer.add_string b (Escape.apply flavour s) + | Some (Bool true) -> Buffer.add_string b "true" + | Some (Bool false) -> () + | Some (List _) | Some (Obj _) | None -> ()) + | Section (p, body) -> ( + match lookup stack p with + | None -> () + | Some (List items) -> List.iter (fun it -> go (it :: stack) body) items + | Some v when truthy v -> go (v :: stack) body + | Some _ -> ()) + | Inverted (p, body) -> ( + match lookup stack p with + | None -> go stack body + | Some v -> if not (truthy v) then go stack body)) + nodes + in + go [ value ] nodes; + Buffer.contents b + +let render_string ~flavour src value = + match parse src with Error e -> Error e | Ok nodes -> Ok (render ~flavour nodes value) diff --git a/lib/render/template.mli b/lib/render/template.mli new file mode 100644 index 0000000..4118496 --- /dev/null +++ b/lib/render/template.mli @@ -0,0 +1,37 @@ +(** A deliberately logic-less template engine (spec section 5). + + A template is DATA, never a program: placeholders, sections, inverted + sections and comments, and nothing else. There are no partials, no lambdas, + no expression evaluation, no arithmetic, and no filesystem or process + access. There is deliberately no "raw" or triple-brace form -- a template + cannot opt out of its flavour's escaping. + + Anything a calendar needs that this cannot express (a month grid's leading + blanks, week bucketing) is computed in {!View} and handed in as data. That + division is the design, not a workaround. *) + +(** What a template can be rendered against. *) +type value = + | Str of string + | Bool of bool + | List of value list + | Obj of (string * value) list + +type node = + | Text of string + | Var of string list (** dotted path, e.g. ["name"; "la"] *) + | Section of string list * node list + | Inverted of string list * node list + +(** Never raises; a malformed template is an [Error] with a human-readable + reason, because the template is user input. *) +val parse : string -> (node list, string) result + +(** Render against a value. Escaping is applied to every interpolated value and + NEVER to the template's own literal text, which is the author's markup. + A missing key renders as the empty string -- the one deliberate silence, so + that a template survives a rite that does not set every optional field. *) +val render : flavour:Escape.flavour -> node list -> value -> string + +(** [parse] then [render]. *) +val render_string : flavour:Escape.flavour -> string -> value -> (string, string) result diff --git a/lib/render/view.ml b/lib/render/view.ml new file mode 100644 index 0000000..733aa45 --- /dev/null +++ b/lib/render/view.ml @@ -0,0 +1,149 @@ +module K = Colitur_kernel +module T = Template + +let str s = T.Str s +let bool b = T.Bool b + +let month_names = + [| ("Ianuarius", "January"); ("Februarius", "February"); ("Martius", "March"); + ("Aprilis", "April"); ("Maius", "May"); ("Iunius", "June"); + ("Iulius", "July"); ("Augustus", "August"); ("September", "September"); + ("October", "October"); ("November", "November"); ("December", "December") |] + +let names_value (n : K.Names.t) = + T.Obj (List.map (fun (l, s) -> (K.Lang.to_string l, str s)) (K.Names.to_list n)) + +let dow_int = function + | K.Date.Sun -> 0 | K.Date.Mon -> 1 | K.Date.Tue -> 2 | K.Date.Wed -> 3 + | K.Date.Thu -> 4 | K.Date.Fri -> 5 | K.Date.Sat -> 6 + +let citation_ref cits part = + match + List.find_opt (fun (c : K.Citation.t) -> c.K.Citation.part = part) cits + with + | Some c -> c.K.Citation.reference + | None -> "" + +let comm_value (c, priv) = + T.Obj + [ ("slug", str (K.Slug.to_string c.K.Celebration.slug)); + ("name", names_value c.K.Celebration.names); + ("privileged", bool (priv = K.Precedence.Privileged)) ] + +(* A padding cell: present so a grid row always has seven entries, and flagged + so a template can render it blank. Every field a real day has is present and + empty, so a template never hits a missing key on a padding cell. *) +let padding_cell dow = + T.Obj + [ ("iso", str ""); ("dom", str ""); ("dow", str (string_of_int dow)); + ("in_month", bool false); + ("season", str ""); ("week", str ""); ("slug", str ""); + ("name", T.Obj []); ("rank", str ""); + ("colour", str ""); + ("is_white", bool false); ("is_red", bool false); ("is_green", bool false); + ("is_violet", bool false); ("is_rose", bool false); ("is_black", bool false); + ("subject", str ""); ("comms", T.List []); + ("transferred_in", T.List []); ("transferred_out", T.List []); + ("first", str ""); ("gospel", str ""); ("last", bool false) ] + +let day_value ~vocab (d : ('s, 'r) K.Liturgical_day.t) = + let date = d.K.Liturgical_day.date in + let tmp = d.K.Liturgical_day.temporal in + let cel = d.K.Liturgical_day.observed in + let colour = cel.K.Celebration.colour in + let is c = bool (colour = c) in + T.Obj + [ ("iso", str (K.Date.to_iso8601 date)); + ("dom", str (string_of_int (K.Date.day date))); + ("dow", str (string_of_int (dow_int (K.Date.weekday date)))); + ("in_month", bool true); + ("season", str (vocab.K.Vocab.season_to_string tmp.K.Temporal.season)); + ("week", str (match tmp.K.Temporal.week with Some w -> string_of_int w | None -> "")); + ("slug", str (K.Slug.to_string cel.K.Celebration.slug)); + ("name", names_value cel.K.Celebration.names); + (* [rank] is the kernel's own class string ("class-1"); there is + deliberately no separate localized rank label here -- the kernel + has no per-language rank names to draw one from, and a field + whose contents cannot honestly differ from [name] should not + exist just to exist. Do not re-add one until the kernel can. *) + ("rank", str (vocab.K.Vocab.rank_to_string cel.K.Celebration.rank)); + ("colour", str (K.Colour.to_string colour)); + ("is_white", is K.Colour.White); ("is_red", is K.Colour.Red); + ("is_green", is K.Colour.Green); ("is_violet", is K.Colour.Violet); + ("is_rose", is K.Colour.Rose); ("is_black", is K.Colour.Black); + ("subject", str (K.Subject.to_string cel.K.Celebration.subject)); + ("comms", T.List (List.map comm_value d.K.Liturgical_day.commemorations)); + ( "transferred_in", + T.List + (match d.K.Liturgical_day.transferred_in with + | None -> [] + | Some c -> [ T.Obj [ ("slug", str (K.Slug.to_string c.K.Celebration.slug)) ] ]) ); + ( "transferred_out", + T.List + (List.map + (fun (c, dest) -> + T.Obj + [ ("slug", str (K.Slug.to_string c.K.Celebration.slug)); + ("to", str (K.Date.to_iso8601 dest)) ]) + d.K.Liturgical_day.transferred_out) ); + ("first", str (citation_ref d.K.Liturgical_day.citations K.Citation.First)); + ("gospel", str (citation_ref d.K.Liturgical_day.citations K.Citation.Gospel)); + (* overwritten per grid row by [set_last]; false in the flat [days] list *) + ("last", bool false) ] + +(* Bucket a month's day values into Sunday-started weeks of exactly seven cells, + padding both ends. This is the computation the template cannot do. *) +(* [last] is true on the seventh cell of a row. A table row needs its separator + BETWEEN cells and the engine has no "unless last" construct, so the flag is + data -- the same rule as [in_month]. Without it the LaTeX grid emits eight + columns for seven cells and pdflatex rejects the file. *) +let set_last cells = + List.mapi + (fun i c -> match c with T.Obj kvs -> T.Obj (("last", bool (i = 6)) :: List.remove_assoc "last" kvs) | v -> v) + cells + +let weeks_of_month ~first_dow day_values = + let lead = List.init first_dow (fun i -> padding_cell i) in + let cells = lead @ day_values in + let rec chunk acc = function + | [] -> List.rev acc + | rest -> + let take = min 7 (List.length rest) in + let week = List.filteri (fun i _ -> i < take) rest in + let tl = List.filteri (fun i _ -> i >= take) rest in + let week = + if take = 7 then week + else week @ List.init (7 - take) (fun i -> padding_cell (take + i)) + in + chunk (week :: acc) tl + in + List.mapi + (fun i w -> T.Obj [ ("num", str (string_of_int (i + 1))); ("days", T.List (set_last w)) ]) + (chunk [] cells) + +let of_days ~vocab ~rite ~year days = + let dvs = List.map (fun d -> (d, day_value ~vocab d)) days in + let months = + List.init 12 (fun i -> + let m = i + 1 in + let own = + List.filter (fun (d, _) -> K.Date.month d.K.Liturgical_day.date = m) dvs + in + let day_values = List.map snd own in + let first_dow = + match own with + | (d, _) :: _ -> dow_int (K.Date.weekday d.K.Liturgical_day.date) + | [] -> 0 + in + let la, en = month_names.(i) in + T.Obj + [ ("num", str (string_of_int m)); + ("name", T.Obj [ ("la", str la); ("en", str en) ]); + ("days", T.List day_values); + ("weeks", T.List (weeks_of_month ~first_dow day_values)) ]) + in + T.Obj + [ ("rite", str rite); + ("year", str (string_of_int year)); + ("months", T.List months); + ("days", T.List (List.map snd dvs)) ] diff --git a/lib/render/view.mli b/lib/render/view.mli new file mode 100644 index 0000000..fb48590 --- /dev/null +++ b/lib/render/view.mli @@ -0,0 +1,24 @@ +(** Shapes a civil year of resolved days into the value a template renders + against (spec section 4). + + This layer exists because a month grid needs leading blank cells, week + bucketing and an "is this cell in the current month" test, and a logic-less + template can compute none of it. Shaping the data here keeps the engine + logic-less AND makes the grid template trivial. The view model IS the design. + + Both [weeks] and [days] are offered at every level: the booklet walks + [days], the grid walks [weeks]. One model, two artefacts, no second code + path that could drift. + + Colours are exposed as six booleans rather than a hex string: hex would bake + a presentation policy into the engine, and LaTeX, groff and HTML each want a + different colour expression. Exactly one of the six is true on every day. *) + +val of_days : + vocab:('s, 'r) Colitur_kernel.Vocab.t -> + rite:string -> + year:int -> + ('s, 'r) Colitur_kernel.Liturgical_day.t list -> + Template.value +(** [of_days ~vocab ~rite ~year days] where [days] is one civil year, 1 January + to 31 December, in order. Pure and total. *) diff --git a/man/colitur-templates.5 b/man/colitur-templates.5 new file mode 100644 index 0000000..2f42d68 --- /dev/null +++ b/man/colitur-templates.5 @@ -0,0 +1,788 @@ +.TH COLITUR\-TEMPLATES 5 "2026" "colitur" "File Formats" +.SH NAME +colitur\-templates \- template format for colitur(1)'s table, render and publish +.SH SYNOPSIS +.I booklet.tex +.br +.I calendar.html +.br +.I feed.ics +.SH DESCRIPTION +A +.B colitur +template is the file named by +.BR "colitur table" 's +and +.BR "colitur render" 's +.B \-\-template +flag (and used internally by +.BR "colitur publish" ). +It is a deliberately logic\-less, Mustache\-family format: the file is +.I data, +never a program. There are exactly four constructs \(em variable +interpolation, a section, an inverted section, and a comment \(em and nothing +else. +.PP +.B There are no partials, no lambdas, no arithmetic, no expression +.B evaluation, and no "raw" or triple\-brace form that could opt out of +.B escaping. +A template cannot include another file, cannot compute anything, and cannot +choose to skip the escaping its own flavour applies. Everything a rendered +document needs \(em conditionals on emptiness, iteration over days or weeks, +formatting \(em is expressed with the four constructs below over the fields +.B VIEW MODEL +describes; nothing else is available, and nothing else will be added by +supplying cleverer template syntax \(em that is what the escaping and +scope rules exist to prevent. +.SH SYNTAX +.TP +.BI "{{" name "}}" +Interpolates the value at +.I name, +a dot\-separated path resolved against the current scope (see +.B SCOPE AND LOOKUP +below). A string value is escaped per the active flavour and inserted; a +boolean +.B true +renders as the literal text +.RB \(lq true \(rq, +.B false +renders as nothing; a list or an object value used as a plain variable also +renders as nothing \(em only a section can iterate one. A path that resolves +to nothing renders as nothing, silently: this is the one deliberate silence +in the engine, so a template survives a day that does not carry every +optional field (an empty +.I week +on a day the rite does not number, an empty +.I first +or +.I gospel +citation, and so on). +.TP +.BI "{{#" name "}}...{{/" name "}}" +A section. If +.I name +resolves to a +.B list, +the body is rendered once per item, with each item pushed onto the scope +stack (see below). If it resolves to a truthy non\-list value (a non\-empty +string, or an object), the body is rendered once, with that value pushed onto +the stack. If it resolves to nothing, or to a falsy value (an empty string, +.BR false , +or an empty list), the body is skipped entirely. +.TP +.BI "{{^" name "}}...{{/" name "}}" +An inverted section: the mirror image of +.BR # . +The body renders \(em exactly once, without pushing anything new onto the +scope \(em only when +.I name +resolves to nothing, or to a falsy value. This is how a template supplies a +fallback for an optional or absent field. +.TP +.BI "{{!" " text " "}}" +A comment. Everything between +.B {{! +and the closing +.B }} +is discarded; nothing is written to the rendered output. See +.B HOST\-LANGUAGE COMMENTS +below before relying on this for documentation inside a template that also +has its own comment syntax. +.PP +A section and its inverted counterpart, and a section and its close tag, must +name the identical path \(em +.BR {{#days}} " ... " {{/months}} +is a parse error, not a silently mismatched close. An empty path +( +.BR {{.}} ", " {{#}} ", " {{^}} ", " {{/}} +) is also a parse error: there is no "current context" concept for a bare dot +to mean, so nothing is guessed on a template's behalf. +.PP +A malformed template \(em an unterminated +.BR {{ , +a section left unclosed, a close tag with no matching open \(em is reported +with the parser's own reason and exits 2. A template is user input, exactly +like an +.BR colitur\-overlay (5) +file, and is never allowed to crash the program that reads it. +.SH SCOPE AND LOOKUP +.B This section documents a real hazard, not a theoretical one \(em it has +.B produced wrong output during this program's own development. +.PP +Scope is a stack. Rendering starts with the whole view (the year) as the one +entry on the stack; each +.B {{#section}} +pushes the value it iterates or opens onto the stack for the duration of its +body, and pops it again at +.BR {{/section}} . +A lookup for +.I name +is tried against the +.I innermost +(most recently pushed) entry first. If +.I name +is not found there, the lookup falls back to the +.I next +entry outward, and so on to the outermost (the year itself). This fallback is +deliberate and necessary \(em without it, a cell deep inside +.B {{#months}}{{#weeks}}{{#days}} +could never reach +.BR {{year}} , +which lives only on the outermost object. +.PP +.B The hazard: a DOTTED PATH that resolves only PART WAY inward falls back +.B WHOLESALE to an outer scope of the SAME NAME. +A bare key inside the immediately enclosing section is not at risk this way +\(em it either resolves right there or fails outright (see +.B num +below); it is specifically a dotted path, one step of which is missing from +the inner object, that abandons the whole path and restarts the lookup one +level out. Falling back outward means a name that exists at +.I both +levels never fails and never warns \(em it just silently resolves to the +.I outer +one, because the inner object's own absence of that key is indistinguishable +from "look further out" and "this key does not apply here". Two collisions +are known to exist in the shipped view model: +.TP +.B name +Both a +.B month +and a +.B day +carry a +.I name +field (each an object keyed by language, e.g. +.BR la " and " en ). +Written naively, when +.B {{#days}} +is nested inside +.BR {{#months}} , +a bare +.B {{name.la}} +does +.I not +resolve to the day's own Latin name. It resolves to the +.I enclosing month's +Latin name, because the day's own +.I name +object either has no +.B la +key (an unnamed day) or the dotted path fails partway and the WHOLE path +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 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 +.B month +and a +.B week +carry a +.I num +field. Inside +.BR {{#weeks}} , +a bare +.B {{num}} +is the week's own number, correctly \(em but only because nothing between +the week and the day currently redefines it. A template that reaches +.I num +from any scope where the immediately enclosing section does not itself +carry it will silently climb to whichever ancestor does, and that may not be +the one the author meant. +.PP +.B The safe idiom. +Push the object you actually want onto the scope stack yourself, with a +.B {{#name}} +section, before reading its fields \(em then a bare field inside that +section can only resolve against the object you just pushed, or fail +outright and fall through to an inverted fallback you write explicitly: +.RS +.nf + +{{#name}}{{la}}{{^la}}{{slug}}{{/la}}{{/name}} +.fi +.RE +This opens the day's own +.I name +object (never the month's \(em a +.B {{#section}} +always resolves its OWN path from the point it appears, which for +.B {{#name}} +written inside +.B {{#days}} +is the day's +.IR name , +shadowing the month's identically\-named field exactly as intended), reads +.B la +from it, and falls back to the day's own +.B slug +only when +.B la +is genuinely absent from +.I that +object \(em never when it is merely absent from an ancestor. Every shipped +template that prints a day's name uses exactly this idiom; none uses the +bare dotted form. +.SH HOST\-LANGUAGE COMMENTS +.B The engine has no awareness of the target language's own comment syntax. +A +.B {{...}} +tag inside a LaTeX +.BR % , +a groff +.BR .\e" , +or an HTML +.B <!\-\- \-\-> +comment is still lexed and rendered exactly as if it were live template +markup \(em the engine sees only its own +.B {{ +/ +.B }} +delimiters, never the host format's comment sigils, because a template is +rendered as one flat character stream, not parsed as LaTeX, groff or HTML +first. This broke a shipped template during development: an explanatory +.B {{example}} +written inside a LaTeX +.B % +comment, meant purely as documentation for a future reader, was parsed as a +real variable reference. +.PP +Write in\-template documentation without any +.B {{ +or +.B }} +characters in it, in whatever host\-comment syntax the target format uses. +Use +.B {{!comment}} +only where the surrounding host format has no comment syntax of its own that +would otherwise be preferable (its own body is safe \(em text between +.B {{! +and +.B }} +is discarded unparsed, so a stray +.B {{ +inside a +.B {{!...}} +comment is not itself a hazard \(em but the comment's own delimiters are +still ordinary +.B {{ +/ +.B }} +tokens, so they compete with the host format's own comment syntax for the +same file exactly as any other tag would). +.SH FLAVOURS +.B \-\-flavour +selects how an interpolated +.I value +is escaped before being written. It never touches the template's own literal +markup (the LaTeX, groff, HTML, XML or ICS surrounding a +.BR {{tag}} ), +which is the template author's and is trusted exactly as written. One of six: +.TP +.B latex +.BR \e " \(-> " \etextbackslash{} , +.BR { " \(-> " \e{ , +.BR } " \(-> " \e} , +.BR $ " \(-> " \e$ , +.BR & " \(-> " \e& , +.BR # " \(-> " \e# , +.BR _ " \(-> " \e_ , +.BR % " \(-> " \e% , +.BR ^ " \(-> " \etextasciicircum{} , +.BR ~ " \(-> " \etextasciitilde{} . +Every LaTeX special character is covered; nothing else is touched. +.TP +.B groff +A backslash is escaped to +.BR \ee , +because a bare backslash starts a groff escape. If the ESCAPED string then +begins with +.B . +or +.BR ' , +the zero\-width non\-printing character +.B \e& +is prefixed \(em a +.B . +or +.B ' +in column one would otherwise start a request rather than print literally. +.TP +.B html +(also used for the +.B xml +flavour, identically) +.BR & " \(-> " & , +.BR < " \(-> " < , +.BR > " \(-> " > , +.BR \(dq " \(-> " " , +.BR ' " \(-> " ' . +.TP +.B xml +Identical to +.B html +above. +.TP +.B ics +Per RFC 5545: a backslash doubles, a semicolon and a comma are each +backslash\-escaped, a newline becomes the two\-character sequence +.BR \en , +and a carriage return is dropped outright (never doubled or passed through). +Line folding at 75 octets, on a UTF\-8 character boundary, is applied +separately to the whole rendered line \(em it is not part of value escaping +and is not something a template can see or control. +.TP +.B none +Escapes nothing at all: the value is inserted byte\-for\-byte. See +.B LIMITATIONS +below \(em this is not an oversight, and it is not safe to treat as one. +.PP +.B \-\-flavour +is inferred from +.BR \-\-template 's +own file extension when the flag is omitted: +.RS +.nf + +.I .tex \(-> latex +.I .ms .mom .me \(-> groff +.I .html .htm \(-> html +.I .xml \(-> xml +.I .ics \(-> ics +.I .md .adoc .txt \(-> none +.fi +.RE +.PP +An extension +.B colitur +does not recognise is a hard +.B ERROR +naming the six flavours above; it is +.I never +a silent fallback to +.BR none . +Guessing the flavour wrong would produce output that looks fine right up +until the metacharacters it silently failed to escape appear in a rendered +document. +.SH LIMITATIONS +.B AsciiDoc and Markdown are NOT escaped. +The +.B none +flavour (selected for +.IR .md " and " .adoc , +as well as +.IR .txt ) +passes every interpolated value through unchanged. This is a deliberate +choice, not a gap: unlike LaTeX, groff, HTML, XML or ICS, AsciiDoc and +Markdown have no fixed, small metacharacter set that could be escaped +mechanically \(em their own metacharacters are context\-dependent (a +.B * +means something different at the start of a line than in the middle of a +word), and escaping them here, generically, would produce +.I worse +output than leaving values alone in the ordinary case. +.PP +The consequence is real and is stated here plainly rather than left for a +reader to discover: a feast name, or any other interpolated field, containing +.B * +or +.B _ +renders as Markdown/AsciiDoc emphasis in the rendered document, not as a +literal asterisk or underscore. No shipped sanctoral name currently contains +either character, but a +.BR colitur\-overlay (5) +file supplying a local celebration's own name is not validated against this +constraint, and its author is responsible for avoiding both characters, or +accepting the emphasis, in any name rendered through a +.I .md +or +.I .adoc +template. +.PP +Only the Extraordinary Form (1962) view model is documented below; see +.BR colitur (1) +for the rite's own scope and limitations (readings cover only the Epistle +and Gospel; the votive Office of the Blessed Virgin Mary on Saturday does not +yet select among its five seasonal Masses). +.SH VIEW MODEL +The value a template renders against is built once per +.B colitur table +/ +.B render +/ +.B publish +invocation, from the same resolved calendar +.B colitur emit +uses, and is shaped for two artefacts from one model: a flat booklet (the +.B days +list, one entry per day of the requested year) and a month grid (the +.B months +list, each carrying its own +.B weeks +list of Sunday\-started, seven\-cell rows, padded at both ends with blank +cells so every row has exactly seven). This is the same shape published at +.IR schema/day\-v1.json , +described here in prose; the JSON Schema is the machine\-checked contract and +this page is its worked explanation. +.SS Top level +.TP +.B rite +The rite identifier, currently always the string +.BR ef . +.TP +.B year +The civil year requested, as a four\-digit string. +.TP +.B months +A list of twelve +.B month +objects, January through December. +.TP +.B days +A flat list of every day's own +.B day +object, in date order, for the whole requested year \(em what a booklet +template iterates over directly, without going through +.BR months . +.SS month +.TP +.B num +The month number, 1 through 12, as a string. +.TP +.B name +An object keyed by language (currently +.B la +and +.BR en ), +each value the month's own name in that language (e.g. +.RB \(lq Ianuarius \(rq +/ +.RB \(lq January \(rq ). +.TP +.B days +This month's own +.B day +objects, in date order, only the days that actually fall in this month. +.TP +.B weeks +This month's +.B day +objects grouped into Sunday\-started rows of exactly seven, the first and +last rows padded with blank cells (see +.B day \(-> in_month +below) so every row has seven entries regardless of which weekday the month +starts or ends on. +.SS week +.TP +.B num +The week's ordinal within its month (1, 2, 3, ...), as a string. This is +.I not +a liturgical week number \(em see +.B day \(-> week +below for that. +.TP +.B days +Exactly seven +.B day +objects, Sunday first. +.SS day +Every key below is always present on every day object, including a padding +cell (see +.BR in_month ), +so a template never hits a missing key on a real day OR a blank grid cell \(em +the one deliberate exception is that a padding cell's own string fields are +all set to the empty string and its boolean and list fields to +.B false +/empty, which read as absent under +.BR # / ^ / {{var}} +exactly as a genuinely unset field would. +.TP +.B iso +The date, ISO\-8601 (\c +.IR YYYY\-MM\-DD ). +Empty on a grid padding cell. +.TP +.B dom +The day of the month, as a string (no leading zero). Empty on a padding +cell. +.TP +.B dow +The day of the week as a string digit, +.B 0 +for Sunday through +.B 6 +for Saturday. Present, and meaningful, even on a padding cell \(em it is how +a grid template knows which column a blank cell belongs in. +.TP +.B in_month +Boolean. +.B false +on a padding cell (a blank cell added so a month's first or last week has +seven entries); a template checks this, not +.BR iso 's +emptiness, to decide whether to render a cell's contents. +.TP +.B season +The liturgical season's own string name (e.g. +.BR paschaltide ", " lent ). +.TP +.B week +The liturgical week number within the season, as a string, or the empty +string on a day the rite does not number (this is +.I not +the same field as a +.B week +object's own +.BR num , +described above \(em see +.B SCOPE AND LOOKUP +for why the two identically\-named fields do not collide here: a plain +.B day +object has no +.B num +key of its own at all, only +.BR week , +so there is nothing for it to shadow). +.TP +.B slug +The observed celebration's stable identifier (e.g. +.BR ef\-easter\-sunday ). +.TP +.B name +An object keyed by language, the observed celebration's own name in each +language colitur's data supplies one for. Frequently has no +.B la +or +.B en +key at all (most temporal days, most sanctoral entries in the shipped data) +\(em see +.B SCOPE AND LOOKUP +above for the resulting month\-name collision and its safe idiom. +.TP +.B rank +The observed celebration's class, as the kernel's own string (e.g. +.BR class\-1 ). +There is deliberately no separate, localized rank label: the kernel carries +no per\-language rank names to draw one from. +.TP +.B colour +The observed celebration's liturgical colour, lowercase (one of +.BR white ", " red ", " green ", " violet ", " rose ", " black , +or the empty string). +.TP +.BR is_white ", " is_red ", " is_green ", " is_violet ", " is_rose ", " is_black +Six booleans, exactly one true (matching +.BR colour ) +on a real day, all false on a padding cell. Provided so a template can +select styling (a cell background colour, a class name) with a plain +.B {{#is_white}} +section instead of a string comparison the engine does not offer \(em there +is no expression evaluation, so this is the only way a template branches on +colour at all. +.TP +.B subject +Whose feast this is, lowercase (one of +.BR lord ", " bvm ", " saint ", " temporal ). +.TP +.B comms +A list of commemoration objects admitted on this day, each carrying +.BR slug , +.B name +(an object keyed by language, same shape as the day's own +.BR name ), +and +.B privileged +(boolean: true for a privileged commemoration under RG 109, which survives +even where an ordinary one would be capped out). Empty list on a day with no +commemorations, and always an empty list \(em never absent \(em on a padding +cell. +.TP +.B transferred_in +A list of at most one object, present when a feast impeded elsewhere was +transferred onto THIS day (RG 96\(en98); carries the transferred +celebration's own +.BR slug . +Empty list when nothing transferred in. +.TP +.B transferred_out +A list of objects, one per celebration that would have fallen on this day +but was displaced and moved to a later date; each carries +.B slug +and +.B to +(the ISO\-8601 date it was moved to). Empty on the ordinary day. +.TP +.B first +The Epistle/Lesson reading citation (e.g. +.RB \(lq "Heb 1:1\-12" \(rq ), +never scripture text \(em a reference only. Empty string when none resolved. +.TP +.B gospel +The Gospel reading citation, same shape as +.BR first . +.TP +.B last +Boolean, true on the seventh (final) cell of a grid row, false everywhere +else including every entry of the flat +.B days +list. Exists because the engine offers no "unless this is the last item" +construct, so a template that must print a separator BETWEEN cells but not +after the last one (a table row's column rule, for instance) reads this flag +rather than computing it: without it, a seven\-column LaTeX grid would emit +an eighth, empty column and +.B pdflatex +would reject the file outright. +.SH A WORKED MINIMAL TEMPLATE +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}} +{{#months}}{{#days}} +{{iso}} {{#name}}{{la}}{{^la}}{{slug}}{{/la}}{{/name}} {{colour}}{{#comms}} +{{slug}}{{/comms}} +{{/days}}{{/months}} +.fi +.RE +.PP +Rendered (extension +.IR .txt , +so flavour +.BR none , +no escaping applied; the blank lines are the template's own \(em its section +body starts and ends with a literal newline, and this engine does not trim +one): +.RS +.nf + +.B colitur table \-\-year 2026 \-\-template minimal.txt | head \-7 +ef 2026 + +2026\-01\-01 ef\-circumcision white + +2026\-01\-02 ef\-christmas\-1\-friday white + +2026\-01\-03 Officium sanctae Mariae in sabbato white +.fi +.RE +.PP +The second data line shows the fallback firing: 2 January carries no Latin +.B name +in the shipped data, so +.B {{^la}} +supplies +.B {{slug}} +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. +.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}} +written against the TOP\-LEVEL, flat +.B days +list (no +.B {{#months}} +wrapping it) does +.I not +print +.RB \(lq Ianuarius \(rq +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 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 +.BR table ", " render " and " publish , +and for the five +.B emit +formats that share this same view model. +.PP +.BR colitur\-overlay (5) +for the local\-calendar file format that supplies the celebrations a +template's +.B name +and +.B slug +fields can carry. +.SH LICENSE +AGPL\-3.0\-or\-later. diff --git a/man/colitur.1 b/man/colitur.1 index 58e46ff..005cc0a 100644 --- a/man/colitur.1 +++ b/man/colitur.1 @@ -13,6 +13,30 @@ colitur \- deterministic liturgical calendar and lectionary engine (Roman rite, .RI [ ... ] .br .B colitur +.B emit +.BI \-\-format " FMT" +.BI \-\-from " YEAR" +.BI \-\-to " YEAR" +.RB [ \-\-overlay " FILE" " ...]" +.RB [ \-\-dtstamp " STAMP" ] +.br +.B colitur +.BR table | render +.BI \-\-year " YEAR" +.BI \-\-template " FILE" +.RB [ \-\-flavour " FLAVOUR" ] +.RB [ \-\-overlay " FILE" " ...]" +.br +.B colitur +.B publish +.BI \-\-from " YEAR" +.BI \-\-to " YEAR" +.BI \-\-out " DIR" +.RB [ \-\-overlay " FILE" " ...]" +.RB [ \-\-prune ] +.RB [ \-\-dtstamp " STAMP" ] +.br +.B colitur .BR \-h | \-\-help .SH DESCRIPTION .B colitur @@ -65,6 +89,32 @@ occurrence, commemoration and transfer. .BI readings " YEAR" The Mass reading citations, one line per day. .TP +.B emit +Render a civil\-year range through one of five emitters \(em +.BR csv ", " json ", " sexp ", " xml " or " ics . +See +.B EMIT +below. +.TP +.BR table | render +Compute one civil year and render it through a user\-supplied template, in one +process. +.B table +and +.B render +are the same operation under two names \(em see +.B RENDERING +below for why there is no separate, stdin\-fed +.B render . +.TP +.B publish +Write the static tree that +.I is +this program's API: a civil\-year range rendered once, as files, so any web +server or git repository can serve it and nothing runs at request time. See +.B PUBLISH +below. +.TP .BI convert " FILE" .ini Convert a flat INI overlay to the S\-expression form, on standard output. The conversion verifies its own output before emitting it: the generated text is @@ -97,13 +147,81 @@ below. .TP .BI \-\-overlay " FILE" Apply a user calendar on top of the shipped one. Repeatable and ordered; -.B day -and -.B readings +.BR day ", " readings ", " emit ", " table ", " render " and " publish only. See .B OVERLAYS below. .TP +.BI \-\-format " FMT" +.RB ( "colitur emit" " only)" +One of +.BR csv ", " json ", " sexp ", " xml " or " ics . +Required. See +.B EMIT +below. +.TP +.BI \-\-from " YEAR" ", " \-\-to " YEAR" +.RB ( "colitur emit" " and " "colitur publish" " only)" +The inclusive civil\-year range to render, each +.B 1583..9999 +as elsewhere. +.I FROM +must not be after +.IR TO . +Both required. +.TP +.BI \-\-dtstamp " STAMP" +.RB ( "colitur emit \-\-format ics" " and " "colitur publish" " only)" +Fix the feed's own DTSTAMP instead of the default +.IR YYYY0101T000000Z , +where +.I YYYY +is the emitted year. Never a clock read either way \(em see +.B EMIT +below. +.TP +.BI \-\-out " DIR" +.RB ( "colitur publish" " only)" +The directory to write the static tree into. Created if it does not exist. +Required. See +.B PUBLISH +below. +.TP +.B \-\-prune +.RB ( "colitur publish" " only)" +Remove files a previous +.B publish +run into the same +.B \-\-out +wrote that this run did not rewrite. Never removes a file that is not +recorded in +.IR out /.colitur\-manifest , +regardless of this flag. See +.B PUBLISH +below. +.TP +.BI \-\-year " YEAR" +.RB ( "colitur table" " and " "colitur render" " only)" +The civil year to compute, +.B 1583..9999 +as elsewhere. Required. +.TP +.BI \-\-template " FILE" +.RB ( "colitur table" " and " "colitur render" " only)" +The template file to render the year through. Required. See +.B RENDERING +below. +.TP +.BI \-\-flavour " FLAVOUR" +.RB ( "colitur table" " and " "colitur render" " only)" +One of +.BR latex ", " groff ", " html ", " xml ", " ics " or " none . +Overrides the flavour that would otherwise be inferred from +.BR \-\-template 's +own extension. See +.B RENDERING +below. +.TP .BR \-h ", " \-\-help Print a usage summary to standard output and exit 0. .TP @@ -162,6 +280,349 @@ Both reports are one line per day and ordered by date, so they compose with and .BR join (1) in the ordinary way. +.SH EMIT +.BI "colitur emit " \-\-format " FMT " \-\-from " YEAR " \-\-to " YEAR" +renders the same resolved day \(em season, week, slug, rank, colour, +subject, Latin and English names, citations, commemorations \(em through one +of five emitters, for every day in the inclusive civil\-year range +.IR FROM .. TO . +Every emitter consumes one shared view of the data, so all five describe +exactly the same fields. +.TP +.B csv +RFC 4180. One header row for the whole run, not one per year, so a +multi\-year range still has exactly one header and +.BR wc (1) +or +.B "awk 'NR>1'" +behave as expected. +.RS +.nf + +.B colitur emit \-\-format csv \-\-from 2026 \-\-to 2026 | head \-2 +date,rite,season,week,slug,rank,colour,subject,name_la,name_en,first,gospel,comms +2026\-01\-01,ef,christmastide,,ef\-circumcision,class\-1,white,temporal,,,Titus 2:11\-15,Luke 2:21, +.fi +.RE +.TP +.B json +One JSON object per requested year, concatenated. Shape pinned by +.IR schema/day\-v1.json . +.RS +.nf + +.B colitur emit \-\-format json \-\-from 2026 \-\-to 2026 | head \-c 40 +{"rite":"ef","year":"2026","months":[{... +.fi +.RE +.TP +.B sexp +One S\-expression per day, one per line \(em the same +.I Liturgical_day.t +shape used internally, printed with +.IR sexplib "'s " to_string_hum . +.TP +.B xml +Element\-per\-field, one +.I <calendar> +document per requested year, concatenated. Attributes carry identity only +(rite, year, date); everything else is an element. Shape pinned by +.IR schema/colitur\-v1.xsd , +checked by +.B make check\-schema +when +.BR xmllint (1) +is installed. +.TP +.B ics +RFC 5545. One +.I VCALENDAR +per requested year, concatenated, one all\-day +.I VEVENT +per day. Lines are folded at 75 octets and end +.RI ( CRLF ), +matching the protocol exactly \(em +.RB \(lq " cat \-A " \(rq +on the output shows +.B ^M$ +at each line end. +.RS +.nf + +.B colitur emit \-\-format ics \-\-from 2026 \-\-to 2026 | head \-1 +BEGIN:VCALENDAR +.fi +.RE +.PP +.B \-\-dtstamp +fixes the feed's own +.I DTSTAMP +field, which RFC 5545 requires on every event. Without it the value defaults +to +.I YYYY0101T000000Z +for the emitted year \(em a fixed value, not a clock read \(em so two +.B emit \-\-format ics +runs over identical data are byte\-identical, which matters for a +reproducible build or a diffable published calendar file. Nothing in the +.B emit +path reads the wall clock, for any format. +.PP +.BR \-\-overlay +is accepted exactly as on +.B day +and +.BR readings : +applied on top of the shipped calendar, in order, before the range is +rendered. See +.B OVERLAYS +below. +.SH RENDERING +.BI "colitur table " \-\-year " YEAR " \-\-template " FILE" +and +.BI "colitur render " \-\-template " FILE " \-\-year " YEAR" +are the +.I same +operation under two names: compute the resolved year, shape it into the +same view +.B emit +uses, and render it through +.I FILE +in one process. Both accept +.BR \-\-flavour " and " \-\-overlay +identically. +.SS Why there is no stdin\-fed render +The design this project followed originally sketched a Unix pipe, +.BR "compute | render" , +with +.B render +reading a serialised view back from standard input. That is deliberately +.I not +built. +Honouring the pipe would require a JSON +.I parser +inside +.B colitur +\(em a second hand\-rolled component, purely so this program could read back a +view it had just serialised itself, and a second place for the published +output schema to drift out of step with what the parser actually accepts. +That is a real cost for no benefit over calling the same view builder +directly in the same process, which is what +.B table +and +.B render +both do. +.PP +Unix composition is not abandoned, only narrowed to where it is cheap and +honest: +.B "colitur emit \-\-format json | jq" +still composes fine, because that JSON is the +.I output +of the pipeline, never something +.B colitur +itself has to parse back in. +.SS Templates +.I FILE +is a deliberately logic\-less, Mustache\-family template: it is +.I data, +never a program. The only constructs are +.BR {{placeholder}} , +.BR {{#section}}...{{/section}} , +.BR {{^inverted}}...{{/inverted}} +and +.BR {{!comment}} . +There are no partials, no lambdas, no expression evaluation, no arithmetic, +and no filesystem or process access from inside a template. There is +deliberately no "raw" or triple\-brace form either \(em a template cannot opt +out of its flavour's escaping. +.PP +The template renders against the same schema +.B emit +uses (season, week, slug, rank, colour, subject, names, citations, +commemorations), reshaped for two artefacts from one model: a flat booklet +(the +.B days +list, one entry per day of the year) and a month grid (the +.B weeks +list, with padding cells flagged for the leading and trailing blanks a grid +needs and a booklet does not). A key absent on a given day (an optional field +a rite does not always set) renders as the empty string rather than an error +\(em the one deliberate silence, so a template survives a day that does not +carry every optional field. +.PP +See +.BR colitur\-templates (5) +for the full syntax, the escaping table per flavour, the complete +view\-model field reference, and \(em before writing a template of any +complexity \(em its +.B SCOPE AND LOOKUP +section: an inner key silently loses to an outer key of the same name (a bare +.B {{name.la}} +inside a day resolves to the enclosing MONTH's name, not the day's own), +which has produced wrong output in this project's own templates. +.SS Flavours +.BI \-\-flavour +controls how interpolated +.I values +are escaped for the target format. It never touches the template's own +literal markup, which is the author's and is trusted as\-is. One of: +.RS +.nf + +latex groff html xml ics none +.fi +.RE +.PP +When +.B \-\-flavour +is omitted it is inferred from +.BR \-\-template 's +own file extension: +.RS +.nf + +.I .tex -> latex +.I .ms .mom .me -> groff +.I .html .htm -> html +.I .xml -> xml +.I .ics -> ics +.I .md .adoc .txt -> none +.fi +.RE +.PP +.B none +escapes nothing: Markdown, AsciiDoc and plain text have no fixed +metacharacter set, so escaping them here would produce worse output than +leaving them alone. +.PP +An extension +.B colitur +does not recognise is a hard error naming the six flavours above; it is +.I never +a silent fallback to +.BR none . +Guessing the flavour wrong produces output that looks fine right up until +the metacharacters it silently failed to escape show up in a rendered +document. +.RS +.nf + +.B colitur table \-\-year 2027 \-\-template invite.wat +colitur: cannot infer a flavour from ".wat"; pass \-\-flavour latex|groff|html|xml|ics|none +.fi +.RE +.PP +A malformed template reports the parser's own reason and exits 2, never a +crash \(em a template is user input, exactly like an overlay file. +.RS +.nf + +.B colitur table \-\-year 2027 \-\-template bad.txt +colitur: template bad.txt: unclosed section {{#days}} +.fi +.RE +.SH PUBLISH +.BI "colitur publish " \-\-from " YEAR " \-\-to " YEAR " \-\-out " DIR" +writes the static tree that +.I is +this program's API: every file a civil\-year range can be asked for, +computed once and written out, so any web server or git repository can +serve the result as\-is and nothing runs at request time. +.RS +.nf + +ef/<year>.json one civil year, all days, whole\-year emitters +ef/<year>.csv +ef/<year>.xml +ef/<year>.ics +ef/<year>/<mm>/<dd>.json one file per day +schema/day\-v1.json the published JSON contract +index.html a generated index page, not a template +\&.colitur\-manifest every path this run wrote, one per line +.fi +.RE +.PP +Every emitted file goes through the same emitters +.B emit +uses; a published +.I .ics +file for a given year is byte\-for\-byte what +.B "colitur emit \-\-format ics" +would print for that year, and +.B \-\-dtstamp +means exactly what it means there. The per\-day JSON files carry the same +shape as the whole\-year one, scoped to a single day \(em +.B "colitur table" +and template authors needing one day's data can read either. +.PP +.B Deterministic. +Publishing the same +.B \-\-from / \-\-to +range into an empty directory twice produces a byte\-identical tree. Nothing +in the publish path reads the wall clock; the +.I .ics +files' own DTSTAMP defaults to a fixed value derived from the emitted year, +exactly as it does under +.B emit +(see +.B EMIT +above), and +.B \-\-dtstamp +overrides it the same way. This is what makes publishing into a git +repository safe: +.B git status +shows only genuine change, and you review an actual diff before pushing, +never a rewrite of files that did not change. +.PP +.B Non\-destructive. +.B publish +writes only files it owns, and records the relative path of every one of +them in +.IR out /.colitur\-manifest +(itself never subject to pruning). A file you put in the output directory +yourself \(em by hand, or from some other tool \(em is never named in that +manifest, so it is never touched, +.I whether or not +.B \-\-prune +is given. +.RS +.nf + +.B "touch out/MY\-NOTES.txt" +.B "colitur publish \-\-from 2027 \-\-to 2027 \-\-out out \-\-prune" +.B "test \-f out/MY\-NOTES.txt && echo kept" +kept +.fi +.RE +.PP +.B \-\-prune +removes exactly the entries a +.I previous +publish into the same +.B \-\-out +wrote that this run did not rewrite \(em typically an earlier year's own +per\-day files, when a later +.B publish +targets a different +.B \-\-from / \-\-to +range into the same directory. A directory a stale entry's removal leaves +empty is removed too (so, for example, +.I out/ef/2027/ +itself goes away once every file under it is gone), but nothing above +.B \-\-out +is ever touched, and +.B \-\-out +itself is never removed even when nothing is left in it. Without +.BR \-\-prune , +old entries are left in place, and only the manifest is rewritten to +describe the current run. +.PP +.BR \-\-overlay +is accepted exactly as on +.BR day ", " readings " and " emit : +applied on top of the shipped calendar, in order, before each year in the +range is rendered. See +.B OVERLAYS +below. .SH OVERLAYS .TP .BI \-\-overlay " FILE" @@ -242,11 +703,9 @@ shapes: .RE .PP Accepted on -.B day -and -.B readings -only. The other commands read no sanctoral data at all, so the flag would have -no effect there and is +.BR day ", " readings ", " emit ", " table ", " render " and " publish . +.BR easter " and " temporal +read no sanctoral data at all, so the flag would have no effect there and is .I refused rather than silently ignored. .PP @@ -347,6 +806,25 @@ Run against a checkout's data rather than the installed copy: .B COLITUR_DATA_DIR=~/git/projects/colitur/data/ef colitur day 2026 .fi .RE +.PP +Render a year through a template, flavour inferred from the extension: +.RS +.nf + +.B colitur table \-\-year 2026 \-\-template booklet.tex > booklet.tex.out +.fi +.RE +.PP +Publish a year range as a static tree, then keep it in step with +.B \-\-prune +as the range moves: +.RS +.nf + +.B colitur publish \-\-from 2026 \-\-to 2027 \-\-out ~/public/colitur +.B colitur publish \-\-from 2027 \-\-to 2028 \-\-out ~/public/colitur \-\-prune +.fi +.RE .SH SOURCES The calendar is computed against the 1962 .I Missale Romanum @@ -376,6 +854,13 @@ reading citations fall back to the day's ordinary ones. for the overlay file format \(em every directive, every field, the three date shapes and worked examples. .PP +.BR colitur\-templates (5) +for the template format used by +.BR table ", " render " and " publish +\(em the four syntax forms, the six flavours and their escaping, the full +view\-model field reference, and the scope\-shadowing hazard a template author +will hit. +.PP .BR lectio (1) .SH LICENSE AGPL\-3.0\-or\-later. diff --git a/schema/colitur-v1.xsd b/schema/colitur-v1.xsd new file mode 100644 index 0000000..46af9a9 --- /dev/null +++ b/schema/colitur-v1.xsd @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"> + <xs:element name="calendar"> + <xs:complexType> + <xs:sequence> + <xs:element name="days"> + <xs:complexType> + <xs:sequence> + <xs:element name="day" maxOccurs="unbounded"> + <xs:complexType> + <xs:sequence> + <xs:element name="season" type="xs:string"/> + <xs:element name="week" type="xs:string"/> + <xs:element name="slug" type="xs:string"/> + <xs:element name="rank" type="xs:string"/> + <xs:element name="colour" type="xs:string"/> + <xs:element name="subject" type="xs:string"/> + <xs:element name="name" minOccurs="0" maxOccurs="unbounded"> + <xs:complexType> + <xs:simpleContent> + <xs:extension base="xs:string"> + <xs:attribute name="lang" type="xs:string" use="required"/> + </xs:extension> + </xs:simpleContent> + </xs:complexType> + </xs:element> + <xs:element name="commemoration" type="xs:string" minOccurs="0" maxOccurs="unbounded"/> + <xs:element name="citation" minOccurs="0" maxOccurs="unbounded"> + <xs:complexType> + <xs:simpleContent> + <xs:extension base="xs:string"> + <xs:attribute name="part" type="xs:string" use="required"/> + </xs:extension> + </xs:simpleContent> + </xs:complexType> + </xs:element> + </xs:sequence> + <xs:attribute name="date" type="xs:string" use="required"/> + </xs:complexType> + </xs:element> + </xs:sequence> + </xs:complexType> + </xs:element> + </xs:sequence> + <xs:attribute name="rite" type="xs:string" use="required"/> + <xs:attribute name="year" type="xs:string" use="required"/> + </xs:complexType> + </xs:element> +</xs:schema> diff --git a/schema/day-v1.json b/schema/day-v1.json new file mode 100644 index 0000000..b48133a --- /dev/null +++ b/schema/day-v1.json @@ -0,0 +1,73 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://colitur/schema/day-v1.json", + "title": "colitur liturgical year, v1", + "type": "object", + "required": ["rite", "year", "months", "days"], + "properties": { + "rite": { "type": "string" }, + "year": { "type": "string", "pattern": "^[0-9]{4}$" }, + "months": { "type": "array", "items": { "$ref": "#/$defs/month" } }, + "days": { "type": "array", "items": { "$ref": "#/$defs/day" } } + }, + "$defs": { + "month": { + "type": "object", + "required": ["num", "name", "days", "weeks"], + "properties": { + "num": { "type": "string" }, + "name": { "type": "object", "additionalProperties": { "type": "string" } }, + "days": { "type": "array", "items": { "$ref": "#/$defs/day" } }, + "weeks": { "type": "array", "items": { "$ref": "#/$defs/week" } } + } + }, + "week": { + "type": "object", + "required": ["num", "days"], + "properties": { + "num": { "type": "string" }, + "days": { "type": "array", "minItems": 7, "maxItems": 7, "items": { "$ref": "#/$defs/day" } } + } + }, + "day": { + "type": "object", + "required": ["iso", "dom", "dow", "in_month", "season", "week", "slug", + "name", "rank", "colour", "is_white", "is_red", "is_green", + "is_violet", "is_rose", "is_black", "subject", "comms", + "transferred_in", "transferred_out", "first", "gospel", "last"], + "properties": { + "iso": { "type": "string", "description": "empty on a grid padding cell" }, + "dom": { "type": "string" }, + "dow": { "type": "string", "description": "0 = Sunday" }, + "in_month": { "type": "boolean", "description": "false = grid padding cell" }, + "season": { "type": "string" }, + "week": { "type": "string", "description": "empty when the rite numbers no week here" }, + "slug": { "type": "string" }, + "name": { "type": "object", "additionalProperties": { "type": "string" } }, + "rank": { "type": "string" }, + "colour": { "type": "string", "enum": ["white","red","green","violet","rose","black",""] }, + "is_white": { "type": "boolean" }, "is_red": { "type": "boolean" }, + "is_green": { "type": "boolean" }, "is_violet":{ "type": "boolean" }, + "is_rose": { "type": "boolean" }, "is_black": { "type": "boolean" }, + "subject": { "type": "string" }, + "comms": { + "type": "array", + "items": { + "type": "object", + "required": ["slug", "name", "privileged"], + "properties": { + "slug": { "type": "string" }, + "name": { "type": "object", "additionalProperties": { "type": "string" } }, + "privileged": { "type": "boolean" } + } + } + }, + "transferred_in": { "type": "array", "items": { "type": "object" } }, + "transferred_out": { "type": "array", "items": { "type": "object" } }, + "first": { "type": "string", "description": "Epistle/Lesson citation, never scripture text" }, + "gospel": { "type": "string", "description": "Gospel citation, never scripture text" }, + "last": { "type": "boolean", "description": "true on the 7th cell of a grid row" } + } + } + } +} diff --git a/schema/dune b/schema/dune new file mode 100644 index 0000000..b3c7dfe --- /dev/null +++ b/schema/dune @@ -0,0 +1,16 @@ +; The published contracts, installed into <prefix>/share/colitur/schema/ so +; an installed `colitur` can find schema/day-v1.json from an arbitrary +; working directory, not only a build-tree checkout -- bin/main.ml's own +; [schema_path] (`colitur publish`) probes exactly this location as its +; INSTALLED candidate, mirroring data/dune's own ef/ layout. Task 13. +; +; colitur-v1.xsd ships alongside it as the XML sibling contract (`colitur +; emit --format xml`); nothing in colitur itself reads it at runtime -- only +; `make check-schema`, via xmllint, and a template author who wants to +; validate their own rendered XML by hand. +(install + (section share) + (package colitur) + (files + (day-v1.json as schema/day-v1.json) + (colitur-v1.xsd as schema/colitur-v1.xsd))) diff --git a/templates/dune b/templates/dune new file mode 100644 index 0000000..e5918a0 --- /dev/null +++ b/templates/dune @@ -0,0 +1,22 @@ +; The shipped templates, installed into <prefix>/share/colitur/templates/ +; so a user can render a booklet or a wall calendar straight from an +; installed `colitur`, without a source checkout on hand -- the same +; "runnable documentation" reasoning data/dune already gives +; examples/diocesan-example.sexp. Nothing in colitur's own code path looks +; these up (--template takes a plain, user-given file path, read exactly +; like an overlay file), so this is a convenience install, not something a +; probe function depends on the way [data_dir]/[schema_path] depend on +; data/ef/ and schema/. Task 13. +(install + (section share) + (package colitur) + (files + (ef/ordo.tex as templates/ef/ordo.tex) + (ef/ordo.ms as templates/ef/ordo.ms) + (ef/ordo.html as templates/ef/ordo.html) + (ef/ordo.adoc as templates/ef/ordo.adoc) + (ef/ordo.md as templates/ef/ordo.md) + (ef/ordo.txt as templates/ef/ordo.txt) + (ef/grid.tex as templates/ef/grid.tex) + (ef/grid.ms as templates/ef/grid.ms) + (ef/grid.html as templates/ef/grid.html))) diff --git a/templates/ef/grid.html b/templates/ef/grid.html new file mode 100644 index 0000000..b92e14a --- /dev/null +++ b/templates/ef/grid.html @@ -0,0 +1,35 @@ +<!-- colitur wall calendar -- HTML. flavour: html --> +<!-- Day label falls back to the slug when the day carries no Latin name + (most temporal days, and most sanctoral entries, which are Latin-less + in the shipped data) -- see ordo.tex's own comment for why the fallback + is written as a name-section wrapping a plain var and its inverse, + rather than a single dotted lookup and its inverse: the enclosing month + object also carries its own name.la, and a dotted lookup that misses + climbs the WHOLE path to that outer scope instead of falling back. --> +<!doctype html> +<html lang="la"><head><meta charset="utf-8"> +<title>Calendarium {{year}}</title> +<style> + body{font-family:sans-serif;margin:1em} + table{border-collapse:collapse;width:100%;margin-bottom:1.5em;page-break-inside:avoid} + caption{font-size:1.2em;font-weight:bold;padding:.4em} + th{font-size:.8em;padding:.2em;border-bottom:1px solid #999} + td{border:1px solid #ddd;vertical-align:top;height:5em;width:14.28%;padding:.2em;font-size:.75em} + td.pad{background:#fafafa;border-color:#eee} + .dom{font-weight:bold;display:block} + .white{background:#fff} .red{background:#fdd} .green{background:#dfd} + .violet{background:#eae} .rose{background:#fde} .black{background:#ddd} + @media print{@page{size:landscape}body{margin:0}} +</style></head><body> +<h1>Calendarium {{year}} · {{rite}}</h1> +{{#months}} +<table> + <caption>{{name.la}}</caption> + <tr><th>Dom</th><th>Lun</th><th>Mar</th><th>Mer</th><th>Iov</th><th>Ven</th><th>Sab</th></tr> + {{#weeks}}<tr> + {{#days}}{{#in_month}}<td class="{{colour}}"><span class="dom">{{dom}}</span>{{#name}}{{la}}{{^la}}{{slug}}{{/la}}{{/name}}</td>{{/in_month}}{{^in_month}}<td class="pad"></td>{{/in_month}}{{/days}} + </tr> + {{/weeks}} +</table> +{{/months}} +</body></html> diff --git a/templates/ef/grid.ms b/templates/ef/grid.ms new file mode 100644 index 0000000..703f46b --- /dev/null +++ b/templates/ef/grid.ms @@ -0,0 +1,95 @@ +.\" colitur wall calendar -- groff ms with tbl. flavour: groff +.\" Build: colitur table --year 2027 --template grid.ms | groff -ms -t -Tpdf -P-pa4l > grid.pdf +.\" +.\" LANDSCAPE, not the ms default portrait: with allbox cells and Latin-less +.\" days falling back to the raw slug (some fallback slugs run past 40 +.\" characters, e.g. "commemoration-of-the-baptism-of-the-lord"), seven +.\" columns of real content do not fit a portrait line length at any +.\" reasonable point size. "-P-pa4l" is gropdf's own landscape papersize +.\" (groff_font(5): a trailing "l" on a papersize name swaps width/height at +.\" the OUTPUT DEVICE level) -- it must be a command-line flag, not a request +.\" inside this file: an in-document "\X'papersize=a4l'" escape was tried and +.\" rejected (it does not actually rotate gropdf's page in this groff, and +.\" throws diagnostics doing it). ".pl"/".po"/".ll" below independently widen +.\" TROFF's OWN idea of the page to match -- ".pl"/".ll" are requests, unlike +.\" the device's own physical page size, and are not implied by "-P-pa4l" -- +.\" so both halves are needed, or one side clips the other. +.\" +.\" ".TL" (the ms title macro, s.tmac) ITSELF narrows the line length to +.\" 5/6 of register "LL" for the title text, and never widens it back +.\" afterward -- there is no third place in s.tmac that ever does. Setting +.\" only the primitive ".ll" before ".TL" is therefore not enough: ".TL" +.\" overwrites it and every table for the rest of the document inherits +.\" the NARROWED value, silently, which is a second, independent way the +.\" original template lost its width (found by reading s.tmac itself, not +.\" guessed). Fixed by setting register "LL" (what ".TL" actually reads) +.\" and re-asserting ".ll" once more, explicitly, right after the title. +.\" +.\" Every column is a FIXED-WIDTH, WRAPPING tbl "w()" block, not a plain "l": +.\" without "w()" tbl sizes a column to its single widest entry and does NOT +.\" wrap, so a 40-character slug forces every column that wide -- seven of +.\" them together run far past any line length, tbl warns "table wider than +.\" line length", and whatever falls past the physical page edge is not a +.\" rendering nicety missing, it is GONE: `pdftotext -layout` (and a printed +.\" page) show only however many columns fit, not all seven. "w()" makes +.\" each column wrap its own text block instead, the same fix grid.tex +.\" already uses via LaTeX's "p{2.6cm}" (see that file's own comment) -- +.\" this is the tbl-native equivalent, not a different design. +.\" +.\" "w()" alone is NOT sufficient, and this is the part that actually cost +.\" the time: tbl only wraps a cell as a text block when its content is +.\" delimited by "T{"/"T}" on their own lines. A PLAIN cell entry in a +.\" "w()" column (what the first attempt at this fix used) is never +.\" wrapped at all -- tbl just widens the column past the requested "w()" +.\" to fit the single longest unbroken entry, exactly reproducing the +.\" original bug. Confirmed directly against tbl's own generated troff +.\" code (`tbl grid.ms`, grep "3w0 .*>?"): every column width register is +.\" `max(w(), \w'cell text')`, so an un-delimited 40-character cell always +.\" wins that max. Every day cell below is therefore its own "T{"/"T}" +.\" block; the closing "T}" and the following column's opening "T{" share +.\" one line with the tab between them (the standard tbl idiom: "T}<TAB> +.\" T{"). The template writes that as "{{#last}}T}{{/last}}{{^last}}T} +.\" <TAB>{{/last}}" rather than "T}{{^last}}<TAB>{{/last}}T{" so that no +.\" literal "T{" ever sits directly against a "{{"/"}}" delimiter in the +.\" source -- three braces in a row there parses as a malformed tag, not +.\" as literal text followed by a tag. +.\" +.\" ".na" (no-adjust, ragged right) is required alongside the wrap, not +.\" cosmetic: a hyphenated slug like "commemoration-of-the-baptism-of-the- +.\" lord" DOES break at its own hyphens once wrapping is active (verified: +.\" troff's filler treats an ASCII hyphen as a break point), but adjusted +.\" (justified) fill in a column this narrow cannot always stretch such a +.\" line to the full measure and troff warns "cannot adjust line" for +.\" every such row -- another warning `make check-templates` must fail on. +.\" Ragged-right removes the stretching, not the wrapping. +.\" +.\" Day label falls back to the slug when the day carries no Latin name (most +.\" temporal days, and most sanctoral entries, which are Latin-less in the +.\" shipped data) -- see ordo.tex's own comment for why the fallback is +.\" written as a name-section wrapping a plain var and its inverse, rather +.\" than a single dotted lookup and its inverse. +.\" +.\" Every cell also carries a last flag, true on the seventh of its row: tbl +.\" needs the tab separator BETWEEN columns, not after the last one, and the +.\" engine has no unless-last construct, so the flag comes from data. +.pl 8.27i +.po 0.3i +.nr LL 10.9i +.ll \n[LL]u +.TL +Calendarium {{year}} \(bu {{rite}} +.ll \n[LL]u +.na +{{#months}} +.SH +{{name.la}} +.TS +allbox; +cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) +lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i). +Dom Lun Mar Mer Iov Ven Sab +{{#weeks}}{{#days}}T{ +{{#in_month}}\fB{{dom}}\fP \s-2{{#name}}{{la}}{{^la}}{{slug}}{{/la}}{{/name}}\s+2{{/in_month}} +{{#last}}T}{{/last}}{{^last}}T} {{/last}}{{/days}} +{{/weeks}}.TE +{{/months}} diff --git a/templates/ef/grid.tex b/templates/ef/grid.tex new file mode 100644 index 0000000..51432e9 --- /dev/null +++ b/templates/ef/grid.tex @@ -0,0 +1,35 @@ +% colitur wall calendar -- LaTeX. flavour: latex +% Build: colitur table --year 2027 --template grid.tex > grid.tex && pdflatex grid.tex +% +% Day label falls back to the slug when the day carries no Latin name (most +% temporal days, and most sanctoral entries, which are Latin-less in the +% shipped data). The fallback is written as a name-section wrapping a plain +% var and its inverse, deliberately NOT as a single dotted-path lookup +% followed by its own inverse: a dotted lookup that misses climbs to the +% enclosing scope for the WHOLE path, and the month object also carries a +% same-named key one level up, so the naive form would render the month's +% own Latin name on every day lacking one, and never fall back at all. +% +% Every cell also carries a last flag, true on the seventh of its row: the +% engine has no unless-last construct, so the separator BETWEEN cells comes +% from data, not the template. A trailing separator on every cell would give +% eight columns for seven and pdflatex would reject the file outright. +\documentclass[10pt,landscape]{article} +\usepackage[a4paper,margin=10mm]{geometry} +\usepackage[T1]{fontenc} +\usepackage[utf8]{inputenc} +\usepackage[table]{xcolor} +\definecolor{lwhite}{HTML}{FFFFFF}\definecolor{lred}{HTML}{FFDDDD} +\definecolor{lgreen}{HTML}{DDFFDD}\definecolor{lviolet}{HTML}{EEAAEE} +\definecolor{lrose}{HTML}{FFDDEE}\definecolor{lblack}{HTML}{DDDDDD} +\begin{document} +{{#months}} +\section*{ {{name.la}} {{year}} } +\begin{tabular}{|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|} +\hline Dom & Lun & Mar & Mer & Iov & Ven & Sab \\ \hline +{{#weeks}}{{#days}}{{#in_month}}\cellcolor{l{{colour}}}\textbf{ {{dom}} } \footnotesize {{#name}}{{la}}{{^la}}{{slug}}{{/la}}{{/name}}{{/in_month}}{{^last}} & {{/last}}{{/days}} \\ \hline +{{/weeks}} +\end{tabular} +\newpage +{{/months}} +\end{document} diff --git a/templates/ef/ordo.adoc b/templates/ef/ordo.adoc new file mode 100644 index 0000000..13d09ec --- /dev/null +++ b/templates/ef/ordo.adoc @@ -0,0 +1,25 @@ +// colitur ordo booklet -- AsciiDoc. flavour: none (see man colitur-overlay) +// AsciiDoc's own metacharacters (*, _, +, `, ...) are context-dependent, so +// this template's flavour deliberately does NOT escape interpolated values. +// A feast name containing `*` or `_` will render as emphasis. That is a +// documented limitation, not a bug to fix. +// +// Day label falls back to the slug when the day carries no Latin name (most +// temporal days, and most sanctoral entries, which are Latin-less in the +// shipped data) -- see ordo.tex's own comment for why the fallback is +// written as a name-section wrapping a plain var and its inverse, rather +// than a single dotted lookup and its inverse. += Ordo {{year}} · {{rite}} +:toc: + +{{#months}} +== {{name.la}} + +{{#days}} +*{{dom}}* {{#name}}{{la}}{{^la}}{{slug}}{{/la}}{{/name}} + +{{rank}} · {{colour}} + +{{#first}}Ep. {{first}} {{/first}}{{#gospel}}Ev. {{gospel}}{{/gospel}} +{{#comms}} + +Com. {{slug}}{{/comms}} + +{{/days}}{{/months}} diff --git a/templates/ef/ordo.html b/templates/ef/ordo.html new file mode 100644 index 0000000..e516816 --- /dev/null +++ b/templates/ef/ordo.html @@ -0,0 +1,28 @@ +<!-- colitur ordo booklet -- HTML. flavour: html --> +<!-- Day label falls back to the slug when the day carries no Latin name + (most temporal days, and most sanctoral entries, which are Latin-less + in the shipped data) -- see ordo.tex's own comment for why the fallback + is written as a name-section wrapping a plain var and its inverse, + rather than a single dotted lookup and its inverse. --> +<!doctype html> +<html lang="la"><head><meta charset="utf-8"> +<title>Ordo {{year}}</title> +<style> + body{font-family:serif;max-width:40em;margin:2em auto;line-height:1.4} + .day{margin:.6em 0;padding-left:2.5em;text-indent:-2.5em} + .dom{display:inline-block;width:2em;font-weight:bold} + .meta{font-size:.85em;color:#555} + .white{border-left:4px solid #ccc} .red{border-left:4px solid #b00} + .green{border-left:4px solid #070} .violet{border-left:4px solid #609} + .rose{border-left:4px solid #e7a} .black{border-left:4px solid #000} + @media print{body{margin:0}} +</style></head><body> +<h1>Ordo {{year}} · {{rite}}</h1> +{{#months}}<h2>{{name.la}}</h2> +{{#days}}<div class="day {{colour}}"> + <span class="dom">{{dom}}</span>{{#name}}{{la}}{{^la}}{{slug}}{{/la}}{{/name}} + <div class="meta">{{rank}} · {{colour}}{{#first}} · Ep. {{first}}{{/first}}{{#gospel}} · Ev. {{gospel}}{{/gospel}}</div> + {{#comms}}<div class="meta">Com. {{slug}}</div>{{/comms}} +</div> +{{/days}}{{/months}} +</body></html> diff --git a/templates/ef/ordo.md b/templates/ef/ordo.md new file mode 100644 index 0000000..606ea01 --- /dev/null +++ b/templates/ef/ordo.md @@ -0,0 +1,23 @@ +<!-- colitur ordo booklet -- Markdown. flavour: none --> +<!-- Markdown's own metacharacters (*, _, `, [, ...) are context-dependent, + so this template's flavour deliberately does NOT escape interpolated + values. A feast name containing `*` or `_` will render as emphasis. + That is a documented limitation, not a bug to fix. --> +<!-- Day label falls back to the slug when the day carries no Latin name + (most temporal days, and most sanctoral entries, which are Latin-less + in the shipped data) -- see ordo.tex's own comment for why the fallback + is written as a name-section wrapping a plain var and its inverse, + rather than a single dotted lookup and its inverse. --> +# Ordo {{year}} · {{rite}} + +{{#months}} +## {{name.la}} + +{{#days}} +**{{dom}}** {{#name}}{{la}}{{^la}}{{slug}}{{/la}}{{/name}} +`{{rank}}` · {{colour}}{{#first}} · Ep. {{first}}{{/first}}{{#gospel}} · Ev. {{gospel}}{{/gospel}} +{{#comms}} +- Com. {{slug}} +{{/comms}} + +{{/days}}{{/months}} diff --git a/templates/ef/ordo.ms b/templates/ef/ordo.ms new file mode 100644 index 0000000..db9b9fc --- /dev/null +++ b/templates/ef/ordo.ms @@ -0,0 +1,27 @@ +.\" colitur ordo booklet -- groff ms. flavour: groff +.\" Build: colitur table --year 2027 --template ordo.ms | groff -ms -Tpdf > ordo.pdf +.\" +.\" Day label falls back to the slug when the day carries no Latin name (most +.\" temporal days, and most sanctoral entries, which are Latin-less in the +.\" shipped data) -- see ordo.tex's own comment for why the fallback is +.\" written as a name-section wrapping a plain var and its inverse, rather +.\" than a single dotted lookup and its inverse. +.TL +ORDO {{year}} \(bu {{rite}} +{{#months}} +.SH +{{name.la}} +.LP +{{#days}} +.IP "{{dom}}" 4 +{{#name}}{{la}}{{^la}}{{slug}}{{/la}}{{/name}} +.br +\s-2{{rank}} \(bu {{colour}}\s+2 +{{#first}}.br +\s-2Ep. {{first}}\s+2 +{{/first}}{{#gospel}}.br +\s-2Ev. {{gospel}}\s+2 +{{/gospel}}{{#comms}}.br +\s-2Com. {{slug}}\s+2 +{{/comms}}{{/days}} +{{/months}} diff --git a/templates/ef/ordo.tex b/templates/ef/ordo.tex new file mode 100644 index 0000000..6012753 --- /dev/null +++ b/templates/ef/ordo.tex @@ -0,0 +1,33 @@ +% colitur ordo booklet -- LaTeX. flavour: latex +% Build: colitur table --year 2027 --template ordo.tex > ordo.tex && pdflatex ordo.tex +% +% Day label falls back to the slug when the day carries no Latin name (most +% temporal days, and most sanctoral entries, which are Latin-less in the +% shipped data). The fallback is written as a name-section wrapping a plain +% var and its inverse, deliberately NOT as a single dotted-path lookup +% followed by its own inverse: a dotted lookup that misses climbs to the +% enclosing scope for the WHOLE path, and the month object also carries a +% same-named key one level up, so the naive form would render the month's +% own Latin name on every day lacking one, and never fall back at all. +\documentclass[10pt,twoside]{article} +\usepackage[a5paper,margin=15mm]{geometry} +\usepackage[T1]{fontenc} +\usepackage[utf8]{inputenc} +\usepackage{fancyhdr} +\pagestyle{fancy} +\fancyhead[C]{ORDO {{year}} \textperiodcentered\ {{rite}}} +\setlength{\parindent}{0pt} +\begin{document} +{{#months}} +\section*{ {{name.la}} } +{{#days}} +\textbf{ {{dom}} } \quad {{#name}}{{la}}{{^la}}{{slug}}{{/la}}{{/name}}\\ +\small {{rank}} \textperiodcentered\ {{colour}}\\ +{{#first}}\small Ep. {{first}}\quad{{/first}}{{#gospel}}\small Ev. {{gospel}}{{/gospel}}\\ +{{#comms}}\small Com. {{slug}}\\ +{{/comms}} +\medskip + +{{/days}} +{{/months}} +\end{document} diff --git a/templates/ef/ordo.txt b/templates/ef/ordo.txt new file mode 100644 index 0000000..aba121a --- /dev/null +++ b/templates/ef/ordo.txt @@ -0,0 +1,10 @@ +{{#months}} +{{name.la}} {{year}} +{{#days}} +{{dom}} {{slug}} + {{rank}} · {{colour}} +{{#first}} Ep. {{first}} +{{/first}}{{#gospel}} Ev. {{gospel}} +{{/gospel}}{{#comms}} Com. {{slug}} +{{/comms}}{{/days}} +{{/months}} @@ -17,7 +17,7 @@ A year outside the supported domain is rejected (exit 2): No/garbage arguments give a usage error (exit 2): $ colitur - colitur: usage: colitur easter <year> | colitur temporal <year> | colitur day <year> | colitur readings <year> | colitur check FILE | colitur new-overlay (try: colitur --help) + colitur: usage: colitur easter <year> | colitur temporal <year> | colitur day <year> | colitur readings <year> | colitur emit --format FMT --from Y --to Y | colitur table --year Y --template FILE | colitur render --template FILE --year Y | colitur publish --from Y --to Y --out DIR | colitur check FILE | colitur new-overlay (try: colitur --help) [2] The EF temporal cycle for a year, one line per day: @@ -327,14 +327,14 @@ A flag needing a value, given none: $ colitur day 2026 --overlay colitur: --overlay needs a file path - colitur: usage: colitur easter <year> | colitur temporal <year> | colitur day <year> | colitur readings <year> | colitur check FILE | colitur new-overlay (try: colitur --help) + colitur: usage: colitur easter <year> | colitur temporal <year> | colitur day <year> | colitur readings <year> | colitur emit --format FMT --from Y --to Y | colitur table --year Y --template FILE | colitur render --template FILE --year Y | colitur publish --from Y --to Y --out DIR | colitur check FILE | colitur new-overlay (try: colitur --help) [2] An unknown option is rejected rather than treated as a positional word: $ colitur day 2026 --diocese colitur: unknown option --diocese - colitur: usage: colitur easter <year> | colitur temporal <year> | colitur day <year> | colitur readings <year> | colitur check FILE | colitur new-overlay (try: colitur --help) + colitur: usage: colitur easter <year> | colitur temporal <year> | colitur day <year> | colitur readings <year> | colitur emit --format FMT --from Y --to Y | colitur table --year Y --template FILE | colitur render --template FILE --year Y | colitur publish --from Y --to Y --out DIR | colitur check FILE | colitur new-overlay (try: colitur --help) [2] The shipped example overlay is runnable documentation, and it must actually @@ -415,3 +415,677 @@ displaced silently. $ colitur day 2026 --overlay ben.sexp | grep '^2026-03-21' 2026-03-21 saturday lent 4 transitus-of-our-holy-father-benedict class-1 white +ef-lent-4-saturday + +CSV emits a header and one row per day: + + $ colitur emit --format csv --from 2027 --to 2027 | head -2 + date,rite,season,week,slug,rank,colour,subject,name_la,name_en,first,gospel,comms + 2027-01-01,ef,christmastide,,ef-circumcision,class-1,white,temporal,,,Titus 2:11-15,Luke 2:21, + + $ colitur emit --format csv --from 2027 --to 2027 | wc -l + 366 + +JSON is one object, ICS one VCALENDAR: + + $ colitur emit --format json --from 2027 --to 2027 | cut -c1-20 + {"rite":"ef","year": + + $ colitur emit --format ics --from 2027 --to 2027 | head -1 | cat -A | head -1 + BEGIN:VCALENDAR^M$ + +Two runs are byte-identical (no clock read anywhere): + + $ colitur emit --format ics --from 2027 --to 2027 > /tmp/a.ics + $ colitur emit --format ics --from 2027 --to 2027 > /tmp/b.ics + $ cmp /tmp/a.ics /tmp/b.ics && echo identical + identical + +A multi-year range concatenates years in order, one header for the whole +CSV run rather than one per year: + + $ colitur emit --format csv --from 2027 --to 2028 | grep -c '^2028-' + 366 + + $ colitur emit --format csv --from 2027 --to 2028 | wc -l + 732 + +sexp and xml are also available: + + $ colitur emit --format sexp --from 2027 --to 2027 | wc -l + 8472 + + $ colitur emit --format xml --from 2027 --to 2027 | head -2 + <?xml version="1.0" encoding="UTF-8"?> + <calendar rite="ef" year="2027"> + +An unknown format is a usage error on stderr, exit 2: + + $ colitur emit --format yaml --from 2027 --to 2027 + colitur: unknown format "yaml" (want csv, json, sexp, xml or ics) + [2] + +--dtstamp is the only user string that reaches ICS output unescaped and +unvalidated -- it must be exactly RFC 5545's UTC DATE-TIME form (8 digits, +"T", 6 digits, "Z") or refused outright, rather than either silently +emitting a malformed DTSTAMP or, worse, letting an embedded CRLF inject +extra lines into every VEVENT: + + $ colitur emit --format ics --from 2027 --to 2027 --dtstamp hello + colitur: --dtstamp "hello" is not RFC 5545 UTC form (want 8 digits, 'T', 6 digits, 'Z', e.g. 20270101T000000Z) + [2] + + $ colitur emit --format ics --from 2027 --to 2027 --dtstamp "$(printf 'X\r\nBEGIN:VEVENT\r\nUID:evil')" + colitur: --dtstamp "X\r\nBEGIN:VEVENT\r\nUID:evil" is not RFC 5545 UTC form (want 8 digits, 'T', 6 digits, 'Z', e.g. 20270101T000000Z) + [2] + +A well-formed value is threaded through unchanged. (The events themselves +end in CRLF per RFC 5545 -- match the substring, not a `$`-anchored full +line, or a shell that does not mangle the trailing "\r" is doing the +grep-anchor's job for it by accident.) + + $ colitur emit --format ics --from 2027 --to 2027 --dtstamp 20270101T000000Z | grep -c 'DTSTAMP:20270101T000000Z' + 365 + +emit refuses a reversed range rather than emitting nothing: + + $ colitur emit --format csv --from 2028 --to 2027 + colitur: --from 2028 is after --to 2027 + [2] + +emit's own flags have no effect on the other commands, refused rather than +silently ignored, the same discipline --overlay already gets: + + $ colitur day 2027 --format csv + colitur: --format/--from/--to/--dtstamp have no effect on `day`; refusing rather than ignoring them + [2] + +day and readings are untouched: + + $ colitur day 2027 | head -1 + 2027-01-01 friday christmastide - ef-circumcision class-1 white + + $ colitur readings 2027 | head -1 + 2027-01-01 ef-circumcision | Titus 2:11-15 | Luke 2:21 + +A minimal inline template renders -- table computes and renders in one +process (2 January 2027 is a Saturday, not a Sunday, so Holy Name Sunday +falls on the 3rd, not the 2nd, that year): + + $ printf '{{#days}}{{iso}} {{slug}}\n{{/days}}' > /tmp/t.txt + $ colitur table --year 2027 --template /tmp/t.txt | head -2 + 2027-01-01 ef-circumcision + 2027-01-02 ef-christmas-1-saturday + +render is the same operation under the name the design used: + + $ colitur render --template /tmp/t.txt --year 2027 | head -2 + 2027-01-01 ef-circumcision + 2027-01-02 ef-christmas-1-saturday + +Flavour is inferred from the extension and escapes data -- Sts. Peter & +Paul (29 June) and its vigil are the only two 2035 entries whose English +name needs LaTeX escaping: + + $ printf '{{#days}}{{name.en}}\n{{/days}}' > /tmp/t.tex + $ colitur table --year 2035 --template /tmp/t.tex | grep -c 'Peter \\& Paul' + 2 + +An unknown extension with no --flavour is an error, not a silent fallback: + + $ printf 'x' > /tmp/t.wat + $ colitur table --year 2027 --template /tmp/t.wat + colitur: cannot infer a flavour from ".wat"; pass --flavour latex|groff|html|xml|ics|none + [2] + + $ colitur table --year 2027 --template /tmp/t.wat --flavour none + x + +An unrecognised --flavour value is also an error naming the six valid ones: + + $ colitur table --year 2027 --template /tmp/t.txt --flavour bogus + colitur: unknown flavour "bogus" (want latex, groff, html, xml, ics or none) + [2] + +A malformed template is a clear error, not a crash: + + $ printf '{{#days}}oops' > /tmp/bad.txt + $ colitur table --year 2027 --template /tmp/bad.txt + colitur: template /tmp/bad.txt: unclosed section {{#days}} + [2] + +A missing template file is an error: + + $ colitur table --year 2027 --template /tmp/nope.txt + colitur: cannot read template /tmp/nope.txt + [2] + +Pointing --template at a directory is an error, not a crash: the read +itself is guarded, not only the open (F1, fix round 1). "." is used rather +than a fixed /tmp path so this does not depend on anything outside the +cram sandbox itself: + + $ colitur table --year 2027 --template . --flavour none + colitur: cannot read template .: Sys_error("Value too large for defined data type") + [2] + +table and render both require --year and --template: + + $ colitur table --year 2027 + colitur: table requires --year YEAR and --template FILE + [2] + + $ colitur render --template /tmp/t.txt + colitur: render requires --year YEAR and --template FILE + [2] + +table/render's own flags have no effect on the other commands, refused +rather than silently ignored: + + $ colitur emit --format csv --from 2027 --to 2027 --year 2028 + colitur: --year/--template/--flavour have no effect on `emit`; refusing rather than ignoring them + [2] + +publish writes the documented tree (Task 12): the manifest itself +(.colitur-manifest) is a real file `find` sees too, since it lives in the +same directory as everything else it tracks. Every /tmp/pub* path below is +cleared first, so this section is self-contained across repeat runs: + + $ rm -rf /tmp/pub /tmp/pub1 /tmp/pub2 /tmp/pub3 + + $ colitur publish --from 2027 --to 2027 --out /tmp/pub >/dev/null + $ find /tmp/pub -type f | sed 's|/tmp/pub/||' | sort + .colitur-manifest + ef/2027.csv + ef/2027.ics + ef/2027.json + ef/2027.xml + ef/2027/01/01.json + ef/2027/01/02.json + ef/2027/01/03.json + ef/2027/01/04.json + ef/2027/01/05.json + ef/2027/01/06.json + ef/2027/01/07.json + ef/2027/01/08.json + ef/2027/01/09.json + ef/2027/01/10.json + ef/2027/01/11.json + ef/2027/01/12.json + ef/2027/01/13.json + ef/2027/01/14.json + ef/2027/01/15.json + ef/2027/01/16.json + ef/2027/01/17.json + ef/2027/01/18.json + ef/2027/01/19.json + ef/2027/01/20.json + ef/2027/01/21.json + ef/2027/01/22.json + ef/2027/01/23.json + ef/2027/01/24.json + ef/2027/01/25.json + ef/2027/01/26.json + ef/2027/01/27.json + ef/2027/01/28.json + ef/2027/01/29.json + ef/2027/01/30.json + ef/2027/01/31.json + ef/2027/02/01.json + ef/2027/02/02.json + ef/2027/02/03.json + ef/2027/02/04.json + ef/2027/02/05.json + ef/2027/02/06.json + ef/2027/02/07.json + ef/2027/02/08.json + ef/2027/02/09.json + ef/2027/02/10.json + ef/2027/02/11.json + ef/2027/02/12.json + ef/2027/02/13.json + ef/2027/02/14.json + ef/2027/02/15.json + ef/2027/02/16.json + ef/2027/02/17.json + ef/2027/02/18.json + ef/2027/02/19.json + ef/2027/02/20.json + ef/2027/02/21.json + ef/2027/02/22.json + ef/2027/02/23.json + ef/2027/02/24.json + ef/2027/02/25.json + ef/2027/02/26.json + ef/2027/02/27.json + ef/2027/02/28.json + ef/2027/03/01.json + ef/2027/03/02.json + ef/2027/03/03.json + ef/2027/03/04.json + ef/2027/03/05.json + ef/2027/03/06.json + ef/2027/03/07.json + ef/2027/03/08.json + ef/2027/03/09.json + ef/2027/03/10.json + ef/2027/03/11.json + ef/2027/03/12.json + ef/2027/03/13.json + ef/2027/03/14.json + ef/2027/03/15.json + ef/2027/03/16.json + ef/2027/03/17.json + ef/2027/03/18.json + ef/2027/03/19.json + ef/2027/03/20.json + ef/2027/03/21.json + ef/2027/03/22.json + ef/2027/03/23.json + ef/2027/03/24.json + ef/2027/03/25.json + ef/2027/03/26.json + ef/2027/03/27.json + ef/2027/03/28.json + ef/2027/03/29.json + ef/2027/03/30.json + ef/2027/03/31.json + ef/2027/04/01.json + ef/2027/04/02.json + ef/2027/04/03.json + ef/2027/04/04.json + ef/2027/04/05.json + ef/2027/04/06.json + ef/2027/04/07.json + ef/2027/04/08.json + ef/2027/04/09.json + ef/2027/04/10.json + ef/2027/04/11.json + ef/2027/04/12.json + ef/2027/04/13.json + ef/2027/04/14.json + ef/2027/04/15.json + ef/2027/04/16.json + ef/2027/04/17.json + ef/2027/04/18.json + ef/2027/04/19.json + ef/2027/04/20.json + ef/2027/04/21.json + ef/2027/04/22.json + ef/2027/04/23.json + ef/2027/04/24.json + ef/2027/04/25.json + ef/2027/04/26.json + ef/2027/04/27.json + ef/2027/04/28.json + ef/2027/04/29.json + ef/2027/04/30.json + ef/2027/05/01.json + ef/2027/05/02.json + ef/2027/05/03.json + ef/2027/05/04.json + ef/2027/05/05.json + ef/2027/05/06.json + ef/2027/05/07.json + ef/2027/05/08.json + ef/2027/05/09.json + ef/2027/05/10.json + ef/2027/05/11.json + ef/2027/05/12.json + ef/2027/05/13.json + ef/2027/05/14.json + ef/2027/05/15.json + ef/2027/05/16.json + ef/2027/05/17.json + ef/2027/05/18.json + ef/2027/05/19.json + ef/2027/05/20.json + ef/2027/05/21.json + ef/2027/05/22.json + ef/2027/05/23.json + ef/2027/05/24.json + ef/2027/05/25.json + ef/2027/05/26.json + ef/2027/05/27.json + ef/2027/05/28.json + ef/2027/05/29.json + ef/2027/05/30.json + ef/2027/05/31.json + ef/2027/06/01.json + ef/2027/06/02.json + ef/2027/06/03.json + ef/2027/06/04.json + ef/2027/06/05.json + ef/2027/06/06.json + ef/2027/06/07.json + ef/2027/06/08.json + ef/2027/06/09.json + ef/2027/06/10.json + ef/2027/06/11.json + ef/2027/06/12.json + ef/2027/06/13.json + ef/2027/06/14.json + ef/2027/06/15.json + ef/2027/06/16.json + ef/2027/06/17.json + ef/2027/06/18.json + ef/2027/06/19.json + ef/2027/06/20.json + ef/2027/06/21.json + ef/2027/06/22.json + ef/2027/06/23.json + ef/2027/06/24.json + ef/2027/06/25.json + ef/2027/06/26.json + ef/2027/06/27.json + ef/2027/06/28.json + ef/2027/06/29.json + ef/2027/06/30.json + ef/2027/07/01.json + ef/2027/07/02.json + ef/2027/07/03.json + ef/2027/07/04.json + ef/2027/07/05.json + ef/2027/07/06.json + ef/2027/07/07.json + ef/2027/07/08.json + ef/2027/07/09.json + ef/2027/07/10.json + ef/2027/07/11.json + ef/2027/07/12.json + ef/2027/07/13.json + ef/2027/07/14.json + ef/2027/07/15.json + ef/2027/07/16.json + ef/2027/07/17.json + ef/2027/07/18.json + ef/2027/07/19.json + ef/2027/07/20.json + ef/2027/07/21.json + ef/2027/07/22.json + ef/2027/07/23.json + ef/2027/07/24.json + ef/2027/07/25.json + ef/2027/07/26.json + ef/2027/07/27.json + ef/2027/07/28.json + ef/2027/07/29.json + ef/2027/07/30.json + ef/2027/07/31.json + ef/2027/08/01.json + ef/2027/08/02.json + ef/2027/08/03.json + ef/2027/08/04.json + ef/2027/08/05.json + ef/2027/08/06.json + ef/2027/08/07.json + ef/2027/08/08.json + ef/2027/08/09.json + ef/2027/08/10.json + ef/2027/08/11.json + ef/2027/08/12.json + ef/2027/08/13.json + ef/2027/08/14.json + ef/2027/08/15.json + ef/2027/08/16.json + ef/2027/08/17.json + ef/2027/08/18.json + ef/2027/08/19.json + ef/2027/08/20.json + ef/2027/08/21.json + ef/2027/08/22.json + ef/2027/08/23.json + ef/2027/08/24.json + ef/2027/08/25.json + ef/2027/08/26.json + ef/2027/08/27.json + ef/2027/08/28.json + ef/2027/08/29.json + ef/2027/08/30.json + ef/2027/08/31.json + ef/2027/09/01.json + ef/2027/09/02.json + ef/2027/09/03.json + ef/2027/09/04.json + ef/2027/09/05.json + ef/2027/09/06.json + ef/2027/09/07.json + ef/2027/09/08.json + ef/2027/09/09.json + ef/2027/09/10.json + ef/2027/09/11.json + ef/2027/09/12.json + ef/2027/09/13.json + ef/2027/09/14.json + ef/2027/09/15.json + ef/2027/09/16.json + ef/2027/09/17.json + ef/2027/09/18.json + ef/2027/09/19.json + ef/2027/09/20.json + ef/2027/09/21.json + ef/2027/09/22.json + ef/2027/09/23.json + ef/2027/09/24.json + ef/2027/09/25.json + ef/2027/09/26.json + ef/2027/09/27.json + ef/2027/09/28.json + ef/2027/09/29.json + ef/2027/09/30.json + ef/2027/10/01.json + ef/2027/10/02.json + ef/2027/10/03.json + ef/2027/10/04.json + ef/2027/10/05.json + ef/2027/10/06.json + ef/2027/10/07.json + ef/2027/10/08.json + ef/2027/10/09.json + ef/2027/10/10.json + ef/2027/10/11.json + ef/2027/10/12.json + ef/2027/10/13.json + ef/2027/10/14.json + ef/2027/10/15.json + ef/2027/10/16.json + ef/2027/10/17.json + ef/2027/10/18.json + ef/2027/10/19.json + ef/2027/10/20.json + ef/2027/10/21.json + ef/2027/10/22.json + ef/2027/10/23.json + ef/2027/10/24.json + ef/2027/10/25.json + ef/2027/10/26.json + ef/2027/10/27.json + ef/2027/10/28.json + ef/2027/10/29.json + ef/2027/10/30.json + ef/2027/10/31.json + ef/2027/11/01.json + ef/2027/11/02.json + ef/2027/11/03.json + ef/2027/11/04.json + ef/2027/11/05.json + ef/2027/11/06.json + ef/2027/11/07.json + ef/2027/11/08.json + ef/2027/11/09.json + ef/2027/11/10.json + ef/2027/11/11.json + ef/2027/11/12.json + ef/2027/11/13.json + ef/2027/11/14.json + ef/2027/11/15.json + ef/2027/11/16.json + ef/2027/11/17.json + ef/2027/11/18.json + ef/2027/11/19.json + ef/2027/11/20.json + ef/2027/11/21.json + ef/2027/11/22.json + ef/2027/11/23.json + ef/2027/11/24.json + ef/2027/11/25.json + ef/2027/11/26.json + ef/2027/11/27.json + ef/2027/11/28.json + ef/2027/11/29.json + ef/2027/11/30.json + ef/2027/12/01.json + ef/2027/12/02.json + ef/2027/12/03.json + ef/2027/12/04.json + ef/2027/12/05.json + ef/2027/12/06.json + ef/2027/12/07.json + ef/2027/12/08.json + ef/2027/12/09.json + ef/2027/12/10.json + ef/2027/12/11.json + ef/2027/12/12.json + ef/2027/12/13.json + ef/2027/12/14.json + ef/2027/12/15.json + ef/2027/12/16.json + ef/2027/12/17.json + ef/2027/12/18.json + ef/2027/12/19.json + ef/2027/12/20.json + ef/2027/12/21.json + ef/2027/12/22.json + ef/2027/12/23.json + ef/2027/12/24.json + ef/2027/12/25.json + ef/2027/12/26.json + ef/2027/12/27.json + ef/2027/12/28.json + ef/2027/12/29.json + ef/2027/12/30.json + ef/2027/12/31.json + index.html + schema/day-v1.json + + $ ls /tmp/pub/ef/2027/01/*.json | wc -l + 31 + + $ test -f /tmp/pub/schema/day-v1.json && echo schema-present + schema-present + + $ test -f /tmp/pub/index.html && echo index-present + index-present + +Publishing twice is byte-identical -- safe to publish into a git repo: + + $ colitur publish --from 2027 --to 2027 --out /tmp/pub1 >/dev/null + $ colitur publish --from 2027 --to 2027 --out /tmp/pub2 >/dev/null + $ diff -r /tmp/pub1 /tmp/pub2 && echo identical + identical + +The published .ics is byte-identical to `emit --format ics` for the same +year -- both walk through the identical Emit_ics.year: + + $ colitur emit --format ics --from 2027 --to 2027 > /tmp/emit-2027.ics + $ diff /tmp/pub1/ef/2027.ics /tmp/emit-2027.ics && echo ics-identical + ics-identical + +publish never deletes a file it does not own: + + $ touch /tmp/pub1/MY-NOTES.txt + $ colitur publish --from 2027 --to 2027 --out /tmp/pub1 >/dev/null + $ test -f /tmp/pub1/MY-NOTES.txt && echo kept + kept + +--prune removes only files a previous run created: + + $ colitur publish --from 2027 --to 2027 --out /tmp/pub1 --prune >/dev/null + $ test -f /tmp/pub1/MY-NOTES.txt && echo still-kept + still-kept + + $ colitur publish --from 2028 --to 2028 --out /tmp/pub1 --prune >/dev/null + $ test -d /tmp/pub1/ef/2027 || echo pruned-2027 + pruned-2027 + $ test -f /tmp/pub1/MY-NOTES.txt && echo notes-survived-prune + notes-survived-prune + +--out is required: + + $ colitur publish --from 2027 --to 2027 + colitur: publish requires --out DIR + [2] + +publish writes many files across a whole year range (mkdir_p/write_file), +same as the template read guarded in commit 6bd741b -- --out is user input +too, and an unwritable parent used to surface as an uncaught +Unix.Unix_error instead of the project's one-line form. The read-only +directory below lives in this test's own cram sandbox, not /tmp: a failed +`rm -rf` of an unwritable directory would otherwise leave it behind in a +shared location, so it is restored to writable before the test ends either +way: + + $ mkdir ro-parent && chmod 555 ro-parent + $ colitur publish --from 2027 --to 2027 --out ro-parent/sub + colitur: mkdir: ro-parent/sub: Permission denied + [2] + $ chmod 755 ro-parent + +publish's own flags have no effect on the other commands, and other +commands' flags have no effect on publish -- refused rather than silently +ignored, the same discipline as everywhere else: + + $ colitur publish --from 2027 --to 2027 --out /tmp/pub3 --format json + colitur: --format has no effect on `publish`; refusing rather than ignoring it + [2] + + $ colitur day 2027 --out /tmp/pub3 --prune + colitur: --out/--prune have no effect on `day`; refusing rather than ignoring them + [2] + +--prune's manifest-driven deletion is hardened against a manifest entry it +did not itself write (fix round 1, F1, CRITICAL): the manifest lives INSIDE +the tree publish writes into, so a bad merge or a hand-edit can put an +arbitrary path in it -- no attacker required. This is the exact CANARY +reproduction the finding was raised with: a ".." entry appended to the +manifest must never let --prune delete outside --out. + + $ rm -rf /tmp/pub-sec /tmp/pub-sec-outside + $ mkdir -p /tmp/pub-sec-outside + $ touch /tmp/pub-sec-outside/CANARY.txt + $ colitur publish --from 2027 --to 2027 --out /tmp/pub-sec >/dev/null + $ echo '../pub-sec-outside/CANARY.txt' >> /tmp/pub-sec/.colitur-manifest + $ colitur publish --from 2028 --to 2028 --out /tmp/pub-sec --prune >/dev/null + colitur: refusing to prune manifest entry "../pub-sec-outside/CANARY.txt" (absolute path or .. component) + $ test -f /tmp/pub-sec-outside/CANARY.txt && echo canary-survives + canary-survives + +The same run's own legitimate stale entries (2027's files, superseded by +2028) still prune normally -- the hardening does not disable pruning, only +unsafe entries: + + $ test -d /tmp/pub-sec/ef/2027 || echo 2027-pruned-normally + 2027-pruned-normally + +An absolute-path entry is refused the same way, not only a ".." one: + + $ echo '/tmp/pub-sec-outside/CANARY.txt' >> /tmp/pub-sec/.colitur-manifest + $ colitur publish --from 2028 --to 2028 --out /tmp/pub-sec --prune >/dev/null + colitur: refusing to prune manifest entry "/tmp/pub-sec-outside/CANARY.txt" (absolute path or .. component) + $ test -f /tmp/pub-sec-outside/CANARY.txt && echo canary-still-survives + canary-still-survives + +A legitimate filename that merely CONTAINS two dots -- but has no ".." path +COMPONENT -- is not caught by the same check, proving it is not +over-broad: it still prunes normally when stale. + + $ touch /tmp/pub-sec/ef/2027..old.json + $ echo 'ef/2027..old.json' >> /tmp/pub-sec/.colitur-manifest + $ colitur publish --from 2029 --to 2029 --out /tmp/pub-sec --prune >/dev/null + $ test -f /tmp/pub-sec/ef/2027..old.json || echo dotted-name-pruned + dotted-name-pruned + +...and that same run is an ordinary --prune cycle in every other respect -- +2028's own files, now stale relative to 2029, are gone too: + + $ test -d /tmp/pub-sec/ef/2028 || echo pruned-2028 + pruned-2028 @@ -1,6 +1,6 @@ (test (name test_colitur) - (libraries colitur_kernel rite_ef alcotest qcheck qcheck-alcotest sexplib) + (libraries colitur_kernel colitur_render rite_ef alcotest qcheck qcheck-alcotest sexplib) (deps ../data/ef/sanctoral.sexp ../data/ef/adjustments.sexp @@ -12,7 +12,25 @@ fixtures/lectio-ef-2005-2050.txt fixtures/missalemeum-ef-2026-2027.txt fixtures/missalemeum-ef-2038.txt - fixtures/missalemeum-ef-2035.txt) + fixtures/missalemeum-ef-2035.txt + ../templates/ef/ordo.tex + ../templates/ef/ordo.ms + ../templates/ef/ordo.html + ../templates/ef/ordo.adoc + ../templates/ef/ordo.md + ../templates/ef/ordo.txt + ../templates/ef/grid.tex + ../templates/ef/grid.ms + ../templates/ef/grid.html + golden/ordo-2027.tex + golden/ordo-2027.ms + golden/ordo-2027.html + golden/ordo-2027.adoc + golden/ordo-2027.md + golden/ordo-2027.txt + golden/grid-2027.tex + golden/grid-2027.ms + golden/grid-2027.html) (preprocess (pps ppx_sexp_conv))) @@ -25,4 +43,10 @@ ../data/ef/sanctoral.sexp ../data/ef/adjustments.sexp ../data/ef/lectionary.sexp - ../data/ef/commons.sexp)) + ../data/ef/commons.sexp + ; Task 12, `colitur publish`: the cram sandbox only ever gets what this + ; stanza names explicitly (unlike a plain `dune build`, it does not fall + ; back to the workspace root's own default alias), so schema/day-v1.json + ; needs its own entry here too, exactly like every other runtime file + ; above. + ../schema/day-v1.json)) diff --git a/test/golden/grid-2027.html b/test/golden/grid-2027.html new file mode 100644 index 0000000..9068788 --- /dev/null +++ b/test/golden/grid-2027.html @@ -0,0 +1,287 @@ +<!-- colitur wall calendar -- HTML. flavour: html --> +<!-- Day label falls back to the slug when the day carries no Latin name + (most temporal days, and most sanctoral entries, which are Latin-less + in the shipped data) -- see ordo.tex's own comment for why the fallback + is written as a name-section wrapping a plain var and its inverse, + rather than a single dotted lookup and its inverse: the enclosing month + object also carries its own name.la, and a dotted lookup that misses + climbs the WHOLE path to that outer scope instead of falling back. --> +<!doctype html> +<html lang="la"><head><meta charset="utf-8"> +<title>Calendarium 2027</title> +<style> + body{font-family:sans-serif;margin:1em} + table{border-collapse:collapse;width:100%;margin-bottom:1.5em;page-break-inside:avoid} + caption{font-size:1.2em;font-weight:bold;padding:.4em} + th{font-size:.8em;padding:.2em;border-bottom:1px solid #999} + td{border:1px solid #ddd;vertical-align:top;height:5em;width:14.28%;padding:.2em;font-size:.75em} + td.pad{background:#fafafa;border-color:#eee} + .dom{font-weight:bold;display:block} + .white{background:#fff} .red{background:#fdd} .green{background:#dfd} + .violet{background:#eae} .rose{background:#fde} .black{background:#ddd} + @media print{@page{size:landscape}body{margin:0}} +</style></head><body> +<h1>Calendarium 2027 · ef</h1> + +<table> + <caption>Ianuarius</caption> + <tr><th>Dom</th><th>Lun</th><th>Mar</th><th>Mer</th><th>Iov</th><th>Ven</th><th>Sab</th></tr> + <tr> + <td class="pad"></td><td class="pad"></td><td class="pad"></td><td class="pad"></td><td class="pad"></td><td class="white"><span class="dom">1</span>ef-circumcision</td><td class="white"><span class="dom">2</span>Officium sanctae Mariae in sabbato</td> + </tr> + <tr> + <td class="white"><span class="dom">3</span>Sanctissimi Nominis Iesu</td><td class="white"><span class="dom">4</span>ef-christmas-1-monday</td><td class="white"><span class="dom">5</span>ef-christmas-1-tuesday</td><td class="white"><span class="dom">6</span>ef-epiphany</td><td class="white"><span class="dom">7</span>ef-christmas-2-thursday</td><td class="white"><span class="dom">8</span>ef-christmas-2-friday</td><td class="white"><span class="dom">9</span>Officium sanctae Mariae in sabbato</td> + </tr> + <tr> + <td class="white"><span class="dom">10</span>Sanctae Familiae Iesu, Mariae, Ioseph</td><td class="white"><span class="dom">11</span>ef-time-after-epiphany-1-monday</td><td class="white"><span class="dom">12</span>ef-time-after-epiphany-1-tuesday</td><td class="white"><span class="dom">13</span>commemoration-of-the-baptism-of-the-lord</td><td class="white"><span class="dom">14</span>hilary</td><td class="white"><span class="dom">15</span>paul-the-first-hermit</td><td class="red"><span class="dom">16</span>marcellus-i</td> + </tr> + <tr> + <td class="green"><span class="dom">17</span>ef-time-after-epiphany-sunday-2</td><td class="green"><span class="dom">18</span>ef-time-after-epiphany-2-monday</td><td class="green"><span class="dom">19</span>ef-time-after-epiphany-2-tuesday</td><td class="red"><span class="dom">20</span>sts-fabian-sebastian</td><td class="red"><span class="dom">21</span>agnes</td><td class="red"><span class="dom">22</span>sts-vincent-anastasius</td><td class="white"><span class="dom">23</span>raymond-of-pe-afort</td> + </tr> + <tr> + <td class="violet"><span class="dom">24</span>ef-septuagesima-sunday-1</td><td class="white"><span class="dom">25</span>conversion-of-st-paul</td><td class="red"><span class="dom">26</span>polycarp</td><td class="white"><span class="dom">27</span>john-chrysostom</td><td class="white"><span class="dom">28</span>peter-nolasco</td><td class="white"><span class="dom">29</span>francis-de-sales</td><td class="red"><span class="dom">30</span>martina</td> + </tr> + <tr> + <td class="violet"><span class="dom">31</span>ef-septuagesima-sunday-2</td><td class="pad"></td><td class="pad"></td><td class="pad"></td><td class="pad"></td><td class="pad"></td><td class="pad"></td> + </tr> + +</table> + +<table> + <caption>Februarius</caption> + <tr><th>Dom</th><th>Lun</th><th>Mar</th><th>Mer</th><th>Iov</th><th>Ven</th><th>Sab</th></tr> + <tr> + <td class="pad"></td><td class="red"><span class="dom">1</span>ignatius-of-antioch</td><td class="white"><span class="dom">2</span>purification-of-the-blessed-virgin-mary</td><td class="violet"><span class="dom">3</span>ef-septuagesima-2-wednesday</td><td class="white"><span class="dom">4</span>andrew-corsini</td><td class="red"><span class="dom">5</span>agatha</td><td class="white"><span class="dom">6</span>titus</td> + </tr> + <tr> + <td class="violet"><span class="dom">7</span>ef-septuagesima-sunday-3</td><td class="white"><span class="dom">8</span>john-of-matha</td><td class="white"><span class="dom">9</span>cyril-of-alexandria</td><td class="violet"><span class="dom">10</span>ef-ash-wednesday</td><td class="violet"><span class="dom">11</span>ef-lent-after-ashes-thursday</td><td class="violet"><span class="dom">12</span>ef-lent-after-ashes-friday</td><td class="violet"><span class="dom">13</span>ef-lent-after-ashes-saturday</td> + </tr> + <tr> + <td class="violet"><span class="dom">14</span>ef-lent-sunday-1</td><td class="violet"><span class="dom">15</span>ef-lent-1-monday</td><td class="violet"><span class="dom">16</span>ef-lent-1-tuesday</td><td class="violet"><span class="dom">17</span>ef-lent-ember-wed</td><td class="violet"><span class="dom">18</span>ef-lent-1-thursday</td><td class="violet"><span class="dom">19</span>ef-lent-ember-fri</td><td class="violet"><span class="dom">20</span>ef-lent-ember-sat</td> + </tr> + <tr> + <td class="violet"><span class="dom">21</span>ef-lent-sunday-2</td><td class="white"><span class="dom">22</span>chair-of-st-peter</td><td class="violet"><span class="dom">23</span>ef-lent-2-tuesday</td><td class="red"><span class="dom">24</span>matthias</td><td class="violet"><span class="dom">25</span>ef-lent-2-thursday</td><td class="violet"><span class="dom">26</span>ef-lent-2-friday</td><td class="violet"><span class="dom">27</span>ef-lent-2-saturday</td> + </tr> + <tr> + <td class="violet"><span class="dom">28</span>ef-lent-sunday-3</td><td class="pad"></td><td class="pad"></td><td class="pad"></td><td class="pad"></td><td class="pad"></td><td class="pad"></td> + </tr> + +</table> + +<table> + <caption>Martius</caption> + <tr><th>Dom</th><th>Lun</th><th>Mar</th><th>Mer</th><th>Iov</th><th>Ven</th><th>Sab</th></tr> + <tr> + <td class="pad"></td><td class="violet"><span class="dom">1</span>ef-lent-3-monday</td><td class="violet"><span class="dom">2</span>ef-lent-3-tuesday</td><td class="violet"><span class="dom">3</span>ef-lent-3-wednesday</td><td class="violet"><span class="dom">4</span>ef-lent-3-thursday</td><td class="violet"><span class="dom">5</span>ef-lent-3-friday</td><td class="violet"><span class="dom">6</span>ef-lent-3-saturday</td> + </tr> + <tr> + <td class="rose"><span class="dom">7</span>ef-lent-sunday-4</td><td class="violet"><span class="dom">8</span>ef-lent-4-monday</td><td class="violet"><span class="dom">9</span>ef-lent-4-tuesday</td><td class="violet"><span class="dom">10</span>ef-lent-4-wednesday</td><td class="violet"><span class="dom">11</span>ef-lent-4-thursday</td><td class="violet"><span class="dom">12</span>ef-lent-4-friday</td><td class="violet"><span class="dom">13</span>ef-lent-4-saturday</td> + </tr> + <tr> + <td class="violet"><span class="dom">14</span>ef-passion-sunday</td><td class="violet"><span class="dom">15</span>ef-passiontide-1-monday</td><td class="violet"><span class="dom">16</span>ef-passiontide-1-tuesday</td><td class="violet"><span class="dom">17</span>ef-passiontide-1-wednesday</td><td class="violet"><span class="dom">18</span>ef-passiontide-1-thursday</td><td class="white"><span class="dom">19</span>joseph-spouse-of-the-bl-virgin-mary</td><td class="violet"><span class="dom">20</span>ef-passiontide-1-saturday</td> + </tr> + <tr> + <td class="violet"><span class="dom">21</span>ef-palm-sunday</td><td class="violet"><span class="dom">22</span>ef-passiontide-2-monday</td><td class="violet"><span class="dom">23</span>ef-passiontide-2-tuesday</td><td class="violet"><span class="dom">24</span>ef-passiontide-2-wednesday</td><td class="white"><span class="dom">25</span>Feria V in Cena Domini</td><td class="black"><span class="dom">26</span>Feria VI in Passione et Morte Domini</td><td class="violet"><span class="dom">27</span>Sabbato sancto</td> + </tr> + <tr> + <td class="white"><span class="dom">28</span>ef-easter-sunday</td><td class="white"><span class="dom">29</span>ef-easter-1-monday</td><td class="white"><span class="dom">30</span>ef-easter-1-tuesday</td><td class="white"><span class="dom">31</span>ef-easter-1-wednesday</td><td class="pad"></td><td class="pad"></td><td class="pad"></td> + </tr> + +</table> + +<table> + <caption>Aprilis</caption> + <tr><th>Dom</th><th>Lun</th><th>Mar</th><th>Mer</th><th>Iov</th><th>Ven</th><th>Sab</th></tr> + <tr> + <td class="pad"></td><td class="pad"></td><td class="pad"></td><td class="pad"></td><td class="white"><span class="dom">1</span>ef-easter-1-thursday</td><td class="white"><span class="dom">2</span>ef-easter-1-friday</td><td class="white"><span class="dom">3</span>ef-easter-1-saturday</td> + </tr> + <tr> + <td class="white"><span class="dom">4</span>ef-low-sunday</td><td class="white"><span class="dom">5</span>annunciation-of-the-blessed-virgin-mary</td><td class="white"><span class="dom">6</span>ef-easter-2-tuesday</td><td class="white"><span class="dom">7</span>ef-easter-2-wednesday</td><td class="white"><span class="dom">8</span>ef-easter-2-thursday</td><td class="white"><span class="dom">9</span>ef-easter-2-friday</td><td class="white"><span class="dom">10</span>Officium sanctae Mariae in sabbato</td> + </tr> + <tr> + <td class="white"><span class="dom">11</span>ef-easter-sunday-3</td><td class="white"><span class="dom">12</span>ef-easter-3-monday</td><td class="red"><span class="dom">13</span>hermenegild</td><td class="red"><span class="dom">14</span>justin</td><td class="white"><span class="dom">15</span>ef-easter-3-thursday</td><td class="white"><span class="dom">16</span>ef-easter-3-friday</td><td class="white"><span class="dom">17</span>Officium sanctae Mariae in sabbato</td> + </tr> + <tr> + <td class="white"><span class="dom">18</span>ef-easter-sunday-4</td><td class="white"><span class="dom">19</span>ef-easter-4-monday</td><td class="white"><span class="dom">20</span>ef-easter-4-tuesday</td><td class="white"><span class="dom">21</span>anselm</td><td class="red"><span class="dom">22</span>sts-soter-caius</td><td class="white"><span class="dom">23</span>ef-easter-4-friday</td><td class="red"><span class="dom">24</span>fidelis-of-sigmaringen</td> + </tr> + <tr> + <td class="white"><span class="dom">25</span>ef-easter-sunday-5</td><td class="red"><span class="dom">26</span>sts-cletus-marcellinus</td><td class="white"><span class="dom">27</span>peter-canisius</td><td class="white"><span class="dom">28</span>paul-of-the-cross</td><td class="red"><span class="dom">29</span>peter-of-verona</td><td class="white"><span class="dom">30</span>catherine-of-siena</td><td class="pad"></td> + </tr> + +</table> + +<table> + <caption>Maius</caption> + <tr><th>Dom</th><th>Lun</th><th>Mar</th><th>Mer</th><th>Iov</th><th>Ven</th><th>Sab</th></tr> + <tr> + <td class="pad"></td><td class="pad"></td><td class="pad"></td><td class="pad"></td><td class="pad"></td><td class="pad"></td><td class="white"><span class="dom">1</span>joseph-the-workman</td> + </tr> + <tr> + <td class="white"><span class="dom">2</span>ef-easter-sunday-6</td><td class="violet"><span class="dom">3</span>ef-rogation-monday</td><td class="white"><span class="dom">4</span>monica</td><td class="white"><span class="dom">5</span>ef-ascension-vigil</td><td class="white"><span class="dom">6</span>ef-ascension</td><td class="red"><span class="dom">7</span>stanislaus</td><td class="white"><span class="dom">8</span>Officium sanctae Mariae in sabbato</td> + </tr> + <tr> + <td class="white"><span class="dom">9</span>ef-easter-sunday-7</td><td class="white"><span class="dom">10</span>antoninus</td><td class="red"><span class="dom">11</span>sts-philip-james</td><td class="red"><span class="dom">12</span>sts-nereus-achilleus-domitilla-pancras</td><td class="white"><span class="dom">13</span>robert-bellarmine</td><td class="white"><span class="dom">14</span>ef-easter-7-friday</td><td class="red"><span class="dom">15</span>ef-pentecost-vigil</td> + </tr> + <tr> + <td class="red"><span class="dom">16</span>ef-pentecost</td><td class="red"><span class="dom">17</span>ef-easter-8-monday</td><td class="red"><span class="dom">18</span>ef-easter-8-tuesday</td><td class="red"><span class="dom">19</span>ef-pentecost-ember-wed</td><td class="red"><span class="dom">20</span>ef-easter-8-thursday</td><td class="red"><span class="dom">21</span>ef-pentecost-ember-fri</td><td class="red"><span class="dom">22</span>ef-pentecost-ember-sat</td> + </tr> + <tr> + <td class="white"><span class="dom">23</span>ef-trinity</td><td class="green"><span class="dom">24</span>ef-time-after-pentecost-1-monday</td><td class="white"><span class="dom">25</span>gregory-vii</td><td class="white"><span class="dom">26</span>philip-neri</td><td class="white"><span class="dom">27</span>ef-corpus-christi</td><td class="white"><span class="dom">28</span>augustine-of-canterbury</td><td class="white"><span class="dom">29</span>mary-magdalene-de-pazzi</td> + </tr> + <tr> + <td class="green"><span class="dom">30</span>ef-time-after-pentecost-sunday-2</td><td class="white"><span class="dom">31</span>queenship-of-the-blessed-virgin-mary</td><td class="pad"></td><td class="pad"></td><td class="pad"></td><td class="pad"></td><td class="pad"></td> + </tr> + +</table> + +<table> + <caption>Iunius</caption> + <tr><th>Dom</th><th>Lun</th><th>Mar</th><th>Mer</th><th>Iov</th><th>Ven</th><th>Sab</th></tr> + <tr> + <td class="pad"></td><td class="pad"></td><td class="white"><span class="dom">1</span>angela-merici</td><td class="green"><span class="dom">2</span>ef-time-after-pentecost-2-wednesday</td><td class="green"><span class="dom">3</span>ef-time-after-pentecost-2-thursday</td><td class="white"><span class="dom">4</span>ef-sacred-heart</td><td class="red"><span class="dom">5</span>boniface</td> + </tr> + <tr> + <td class="green"><span class="dom">6</span>ef-time-after-pentecost-sunday-3</td><td class="green"><span class="dom">7</span>ef-time-after-pentecost-3-monday</td><td class="green"><span class="dom">8</span>ef-time-after-pentecost-3-tuesday</td><td class="green"><span class="dom">9</span>ef-time-after-pentecost-3-wednesday</td><td class="white"><span class="dom">10</span>margaret-of-scotland</td><td class="red"><span class="dom">11</span>barnabas</td><td class="white"><span class="dom">12</span>john-of-san-fecundo</td> + </tr> + <tr> + <td class="green"><span class="dom">13</span>ef-time-after-pentecost-sunday-4</td><td class="white"><span class="dom">14</span>basil-the-great</td><td class="green"><span class="dom">15</span>ef-time-after-pentecost-4-tuesday</td><td class="green"><span class="dom">16</span>ef-time-after-pentecost-4-wednesday</td><td class="white"><span class="dom">17</span>gregory-barbarigo</td><td class="white"><span class="dom">18</span>ephrem-of-syria</td><td class="white"><span class="dom">19</span>julia-of-falconieri</td> + </tr> + <tr> + <td class="green"><span class="dom">20</span>ef-time-after-pentecost-sunday-5</td><td class="white"><span class="dom">21</span>aloysius-gongzaga</td><td class="white"><span class="dom">22</span>paulinus-of-nola</td><td class="violet"><span class="dom">23</span>vigil-of-the-nativity-of-st-john-the-baptist</td><td class="white"><span class="dom">24</span>nativity-of-st-john-the-baptist</td><td class="white"><span class="dom">25</span>william</td><td class="red"><span class="dom">26</span>sts-john-paul</td> + </tr> + <tr> + <td class="green"><span class="dom">27</span>ef-time-after-pentecost-sunday-6</td><td class="violet"><span class="dom">28</span>vigil-of-sts-peter-paul</td><td class="red"><span class="dom">29</span>sts-peter-paul</td><td class="red"><span class="dom">30</span>in-commemoratione-sancti-pauli-apostoli</td><td class="pad"></td><td class="pad"></td><td class="pad"></td> + </tr> + +</table> + +<table> + <caption>Iulius</caption> + <tr><th>Dom</th><th>Lun</th><th>Mar</th><th>Mer</th><th>Iov</th><th>Ven</th><th>Sab</th></tr> + <tr> + <td class="pad"></td><td class="pad"></td><td class="pad"></td><td class="pad"></td><td class="red"><span class="dom">1</span>precious-blood-of-our-lord-jesus-christ</td><td class="white"><span class="dom">2</span>visitation-of-the-blessed-virgin-mary</td><td class="red"><span class="dom">3</span>irenaeus</td> + </tr> + <tr> + <td class="green"><span class="dom">4</span>ef-time-after-pentecost-sunday-7</td><td class="white"><span class="dom">5</span>anthony-mary-zaccariah</td><td class="green"><span class="dom">6</span>ef-time-after-pentecost-7-tuesday</td><td class="white"><span class="dom">7</span>sts-cyril-methodius</td><td class="white"><span class="dom">8</span>elizabeth-of-portugal</td><td class="green"><span class="dom">9</span>ef-time-after-pentecost-7-friday</td><td class="red"><span class="dom">10</span>seven-holy-brothers-and-sts-rufina-secunda</td> + </tr> + <tr> + <td class="green"><span class="dom">11</span>ef-time-after-pentecost-sunday-8</td><td class="white"><span class="dom">12</span>john-gualbert</td><td class="green"><span class="dom">13</span>ef-time-after-pentecost-8-tuesday</td><td class="white"><span class="dom">14</span>bonaventure</td><td class="white"><span class="dom">15</span>henry-the-emperor</td><td class="green"><span class="dom">16</span>ef-time-after-pentecost-8-friday</td><td class="white"><span class="dom">17</span>Officium sanctae Mariae in sabbato</td> + </tr> + <tr> + <td class="green"><span class="dom">18</span>ef-time-after-pentecost-sunday-9</td><td class="white"><span class="dom">19</span>vincent-de-paul</td><td class="white"><span class="dom">20</span>jerome-emiliani</td><td class="white"><span class="dom">21</span>laurence-of-brindisi</td><td class="white"><span class="dom">22</span>mary-magdalene</td><td class="red"><span class="dom">23</span>apollinaris</td><td class="white"><span class="dom">24</span>Officium sanctae Mariae in sabbato</td> + </tr> + <tr> + <td class="green"><span class="dom">25</span>ef-time-after-pentecost-sunday-10</td><td class="white"><span class="dom">26</span>anne-mother-of-the-blessed-virgin</td><td class="green"><span class="dom">27</span>ef-time-after-pentecost-10-tuesday</td><td class="red"><span class="dom">28</span>sts-nazarius-celsus-st-victor-i-st-innocent-i</td><td class="white"><span class="dom">29</span>martha</td><td class="green"><span class="dom">30</span>ef-time-after-pentecost-10-friday</td><td class="white"><span class="dom">31</span>ignatius-loyola</td> + </tr> + +</table> + +<table> + <caption>Augustus</caption> + <tr><th>Dom</th><th>Lun</th><th>Mar</th><th>Mer</th><th>Iov</th><th>Ven</th><th>Sab</th></tr> + <tr> + <td class="green"><span class="dom">1</span>ef-time-after-pentecost-sunday-11</td><td class="white"><span class="dom">2</span>alphonsus-liguori</td><td class="green"><span class="dom">3</span>ef-time-after-pentecost-11-tuesday</td><td class="white"><span class="dom">4</span>dominic</td><td class="white"><span class="dom">5</span>dedication-of-the-basilica-of-st-mary-major</td><td class="white"><span class="dom">6</span>transfiguration-of-our-lord</td><td class="white"><span class="dom">7</span>cajetan</td> + </tr> + <tr> + <td class="green"><span class="dom">8</span>ef-time-after-pentecost-sunday-12</td><td class="violet"><span class="dom">9</span>vigil-of-st-lawrence</td><td class="red"><span class="dom">10</span>lawrence</td><td class="green"><span class="dom">11</span>ef-time-after-pentecost-12-wednesday</td><td class="white"><span class="dom">12</span>clare</td><td class="green"><span class="dom">13</span>ef-time-after-pentecost-12-friday</td><td class="violet"><span class="dom">14</span>vigil-of-the-assumption</td> + </tr> + <tr> + <td class="white"><span class="dom">15</span>assumption-of-the-blessed-virgin-mary</td><td class="white"><span class="dom">16</span>joachim-father-of-the-blessed-virgin</td><td class="white"><span class="dom">17</span>hyacinth</td><td class="green"><span class="dom">18</span>ef-time-after-pentecost-13-wednesday</td><td class="white"><span class="dom">19</span>john-eudes</td><td class="white"><span class="dom">20</span>bernard-of-clairvaux</td><td class="white"><span class="dom">21</span>jane-frances-de-chantal</td> + </tr> + <tr> + <td class="green"><span class="dom">22</span>ef-time-after-pentecost-sunday-14</td><td class="white"><span class="dom">23</span>philip-benizi</td><td class="red"><span class="dom">24</span>bartholomew</td><td class="white"><span class="dom">25</span>louis-ix</td><td class="green"><span class="dom">26</span>ef-time-after-pentecost-14-thursday</td><td class="white"><span class="dom">27</span>joseph-calasance</td><td class="white"><span class="dom">28</span>augustine</td> + </tr> + <tr> + <td class="green"><span class="dom">29</span>ef-time-after-pentecost-sunday-15</td><td class="white"><span class="dom">30</span>rose-of-lima</td><td class="white"><span class="dom">31</span>raymond-nonnatus</td><td class="pad"></td><td class="pad"></td><td class="pad"></td><td class="pad"></td> + </tr> + +</table> + +<table> + <caption>September</caption> + <tr><th>Dom</th><th>Lun</th><th>Mar</th><th>Mer</th><th>Iov</th><th>Ven</th><th>Sab</th></tr> + <tr> + <td class="pad"></td><td class="pad"></td><td class="pad"></td><td class="green"><span class="dom">1</span>ef-time-after-pentecost-15-wednesday</td><td class="white"><span class="dom">2</span>stephen-of-hungary</td><td class="white"><span class="dom">3</span>pius-x</td><td class="white"><span class="dom">4</span>Officium sanctae Mariae in sabbato</td> + </tr> + <tr> + <td class="green"><span class="dom">5</span>ef-time-after-pentecost-sunday-16</td><td class="green"><span class="dom">6</span>ef-time-after-pentecost-16-monday</td><td class="green"><span class="dom">7</span>ef-time-after-pentecost-16-tuesday</td><td class="white"><span class="dom">8</span>nativity-of-the-blessed-virgin-mary</td><td class="green"><span class="dom">9</span>ef-time-after-pentecost-16-thursday</td><td class="white"><span class="dom">10</span>nicholas-of-tolentino</td><td class="white"><span class="dom">11</span>Officium sanctae Mariae in sabbato</td> + </tr> + <tr> + <td class="green"><span class="dom">12</span>ef-time-after-pentecost-sunday-17</td><td class="green"><span class="dom">13</span>ef-time-after-pentecost-17-monday</td><td class="red"><span class="dom">14</span>exaltation-of-the-holy-cross</td><td class="white"><span class="dom">15</span>seven-sorrows-of-the-blessed-virgin-mary</td><td class="red"><span class="dom">16</span>sts-cornelius-cyprian</td><td class="green"><span class="dom">17</span>ef-time-after-pentecost-17-friday</td><td class="white"><span class="dom">18</span>joseph-of-cupertino</td> + </tr> + <tr> + <td class="green"><span class="dom">19</span>ef-time-after-pentecost-sunday-18</td><td class="green"><span class="dom">20</span>ef-time-after-pentecost-18-monday</td><td class="red"><span class="dom">21</span>matthew</td><td class="violet"><span class="dom">22</span>ef-september-ember-wed</td><td class="red"><span class="dom">23</span>linus</td><td class="violet"><span class="dom">24</span>ef-september-ember-fri</td><td class="violet"><span class="dom">25</span>ef-september-ember-sat</td> + </tr> + <tr> + <td class="green"><span class="dom">26</span>ef-time-after-pentecost-sunday-19</td><td class="red"><span class="dom">27</span>sts-cosmas-damian</td><td class="red"><span class="dom">28</span>wenceslaus</td><td class="white"><span class="dom">29</span>dedication-of-st-michael-the-archangel</td><td class="white"><span class="dom">30</span>jerome</td><td class="pad"></td><td class="pad"></td> + </tr> + +</table> + +<table> + <caption>October</caption> + <tr><th>Dom</th><th>Lun</th><th>Mar</th><th>Mer</th><th>Iov</th><th>Ven</th><th>Sab</th></tr> + <tr> + <td class="pad"></td><td class="pad"></td><td class="pad"></td><td class="pad"></td><td class="pad"></td><td class="green"><span class="dom">1</span>ef-time-after-pentecost-19-friday</td><td class="white"><span class="dom">2</span>holy-guardian-angels</td> + </tr> + <tr> + <td class="green"><span class="dom">3</span>ef-time-after-pentecost-sunday-20</td><td class="white"><span class="dom">4</span>francis-of-assisi</td><td class="green"><span class="dom">5</span>ef-time-after-pentecost-20-tuesday</td><td class="white"><span class="dom">6</span>bruno</td><td class="white"><span class="dom">7</span>our-lady-of-the-rosary</td><td class="white"><span class="dom">8</span>bridget-of-sweden</td><td class="white"><span class="dom">9</span>john-leonardi</td> + </tr> + <tr> + <td class="green"><span class="dom">10</span>ef-time-after-pentecost-sunday-21</td><td class="white"><span class="dom">11</span>maternity-of-the-blessed-virgin-mary</td><td class="green"><span class="dom">12</span>ef-time-after-pentecost-21-tuesday</td><td class="white"><span class="dom">13</span>edward</td><td class="red"><span class="dom">14</span>callistus-i</td><td class="white"><span class="dom">15</span>teresa-of-avila</td><td class="white"><span class="dom">16</span>hedwig</td> + </tr> + <tr> + <td class="green"><span class="dom">17</span>ef-time-after-pentecost-sunday-22</td><td class="red"><span class="dom">18</span>luke-the-evangelist</td><td class="white"><span class="dom">19</span>peter-of-alcantara</td><td class="white"><span class="dom">20</span>john-cantius</td><td class="green"><span class="dom">21</span>ef-time-after-pentecost-22-thursday</td><td class="green"><span class="dom">22</span>ef-time-after-pentecost-22-friday</td><td class="white"><span class="dom">23</span>anthony-mary-claret</td> + </tr> + <tr> + <td class="green"><span class="dom">24</span>ef-time-after-pentecost-sunday-23</td><td class="green"><span class="dom">25</span>ef-time-after-pentecost-23-monday</td><td class="green"><span class="dom">26</span>ef-time-after-pentecost-23-tuesday</td><td class="green"><span class="dom">27</span>ef-time-after-pentecost-23-wednesday</td><td class="red"><span class="dom">28</span>sts-simon-jude</td><td class="green"><span class="dom">29</span>ef-time-after-pentecost-23-friday</td><td class="white"><span class="dom">30</span>Officium sanctae Mariae in sabbato</td> + </tr> + <tr> + <td class="white"><span class="dom">31</span>ef-christ-the-king</td><td class="pad"></td><td class="pad"></td><td class="pad"></td><td class="pad"></td><td class="pad"></td><td class="pad"></td> + </tr> + +</table> + +<table> + <caption>November</caption> + <tr><th>Dom</th><th>Lun</th><th>Mar</th><th>Mer</th><th>Iov</th><th>Ven</th><th>Sab</th></tr> + <tr> + <td class="pad"></td><td class="white"><span class="dom">1</span>all-saints</td><td class="black"><span class="dom">2</span>commemoration-of-all-souls</td><td class="green"><span class="dom">3</span>ef-time-after-pentecost-24-wednesday</td><td class="white"><span class="dom">4</span>charles-borromeo</td><td class="green"><span class="dom">5</span>ef-time-after-pentecost-24-friday</td><td class="white"><span class="dom">6</span>Officium sanctae Mariae in sabbato</td> + </tr> + <tr> + <td class="green"><span class="dom">7</span>ef-time-after-epiphany-sunday-5</td><td class="green"><span class="dom">8</span>ef-time-after-pentecost-25-monday</td><td class="white"><span class="dom">9</span>dedication-of-the-archbasilica-of-our-holy-savior</td><td class="white"><span class="dom">10</span>andrew-avellino</td><td class="white"><span class="dom">11</span>martin-of-tours</td><td class="red"><span class="dom">12</span>martin-i</td><td class="white"><span class="dom">13</span>didacus</td> + </tr> + <tr> + <td class="green"><span class="dom">14</span>ef-time-after-epiphany-sunday-6</td><td class="white"><span class="dom">15</span>albert-the-great</td><td class="white"><span class="dom">16</span>gertrude-the-great</td><td class="white"><span class="dom">17</span>gregory-the-wonderworker</td><td class="white"><span class="dom">18</span>dedication-of-the-basilicas-of-sts-peter-paul</td><td class="white"><span class="dom">19</span>elizabeth-of-hungary</td><td class="white"><span class="dom">20</span>felix-of-valois</td> + </tr> + <tr> + <td class="green"><span class="dom">21</span>ef-time-after-pentecost-sunday-24</td><td class="red"><span class="dom">22</span>cecilia</td><td class="red"><span class="dom">23</span>clement-i</td><td class="white"><span class="dom">24</span>john-of-the-cross</td><td class="red"><span class="dom">25</span>catherine-of-alexandria</td><td class="white"><span class="dom">26</span>sylvester</td><td class="white"><span class="dom">27</span>Officium sanctae Mariae in sabbato</td> + </tr> + <tr> + <td class="violet"><span class="dom">28</span>ef-advent-sunday-1</td><td class="violet"><span class="dom">29</span>ef-advent-1-monday</td><td class="red"><span class="dom">30</span>andrew</td><td class="pad"></td><td class="pad"></td><td class="pad"></td><td class="pad"></td> + </tr> + +</table> + +<table> + <caption>December</caption> + <tr><th>Dom</th><th>Lun</th><th>Mar</th><th>Mer</th><th>Iov</th><th>Ven</th><th>Sab</th></tr> + <tr> + <td class="pad"></td><td class="pad"></td><td class="pad"></td><td class="violet"><span class="dom">1</span>ef-advent-1-wednesday</td><td class="red"><span class="dom">2</span>vivian</td><td class="white"><span class="dom">3</span>francis-xavier</td><td class="white"><span class="dom">4</span>peter-chrysologus</td> + </tr> + <tr> + <td class="violet"><span class="dom">5</span>ef-advent-sunday-2</td><td class="white"><span class="dom">6</span>nicholas</td><td class="white"><span class="dom">7</span>ambrose</td><td class="white"><span class="dom">8</span>immaculate-conception-of-the-blessed-virgin-mary</td><td class="violet"><span class="dom">9</span>ef-advent-2-thursday</td><td class="violet"><span class="dom">10</span>ef-advent-2-friday</td><td class="white"><span class="dom">11</span>damasus-i</td> + </tr> + <tr> + <td class="rose"><span class="dom">12</span>ef-advent-sunday-3</td><td class="red"><span class="dom">13</span>lucy</td><td class="violet"><span class="dom">14</span>ef-advent-3-tuesday</td><td class="violet"><span class="dom">15</span>ef-advent-ember-wed</td><td class="red"><span class="dom">16</span>eusebius</td><td class="violet"><span class="dom">17</span>ef-advent-ember-fri</td><td class="violet"><span class="dom">18</span>ef-advent-ember-sat</td> + </tr> + <tr> + <td class="violet"><span class="dom">19</span>ef-advent-sunday-4</td><td class="violet"><span class="dom">20</span>ef-advent-4-monday</td><td class="red"><span class="dom">21</span>thomas</td><td class="violet"><span class="dom">22</span>ef-advent-4-wednesday</td><td class="violet"><span class="dom">23</span>ef-advent-4-thursday</td><td class="violet"><span class="dom">24</span>ef-nativity-vigil</td><td class="white"><span class="dom">25</span>ef-nativity</td> + </tr> + <tr> + <td class="white"><span class="dom">26</span>ef-christmas-sunday-0</td><td class="white"><span class="dom">27</span>john-the-evangelist</td><td class="red"><span class="dom">28</span>holy-innocents</td><td class="white"><span class="dom">29</span>ef-nativity-octave-day-5</td><td class="white"><span class="dom">30</span>ef-nativity-octave-day-6</td><td class="white"><span class="dom">31</span>ef-nativity-octave-day-7</td><td class="pad"></td> + </tr> + +</table> + +</body></html> diff --git a/test/golden/grid-2027.ms b/test/golden/grid-2027.ms new file mode 100644 index 0000000..5668b86 --- /dev/null +++ b/test/golden/grid-2027.ms @@ -0,0 +1,1136 @@ +.\" colitur wall calendar -- groff ms with tbl. flavour: groff +.\" Build: colitur table --year 2027 --template grid.ms | groff -ms -t -Tpdf -P-pa4l > grid.pdf +.\" +.\" LANDSCAPE, not the ms default portrait: with allbox cells and Latin-less +.\" days falling back to the raw slug (some fallback slugs run past 40 +.\" characters, e.g. "commemoration-of-the-baptism-of-the-lord"), seven +.\" columns of real content do not fit a portrait line length at any +.\" reasonable point size. "-P-pa4l" is gropdf's own landscape papersize +.\" (groff_font(5): a trailing "l" on a papersize name swaps width/height at +.\" the OUTPUT DEVICE level) -- it must be a command-line flag, not a request +.\" inside this file: an in-document "\X'papersize=a4l'" escape was tried and +.\" rejected (it does not actually rotate gropdf's page in this groff, and +.\" throws diagnostics doing it). ".pl"/".po"/".ll" below independently widen +.\" TROFF's OWN idea of the page to match -- ".pl"/".ll" are requests, unlike +.\" the device's own physical page size, and are not implied by "-P-pa4l" -- +.\" so both halves are needed, or one side clips the other. +.\" +.\" ".TL" (the ms title macro, s.tmac) ITSELF narrows the line length to +.\" 5/6 of register "LL" for the title text, and never widens it back +.\" afterward -- there is no third place in s.tmac that ever does. Setting +.\" only the primitive ".ll" before ".TL" is therefore not enough: ".TL" +.\" overwrites it and every table for the rest of the document inherits +.\" the NARROWED value, silently, which is a second, independent way the +.\" original template lost its width (found by reading s.tmac itself, not +.\" guessed). Fixed by setting register "LL" (what ".TL" actually reads) +.\" and re-asserting ".ll" once more, explicitly, right after the title. +.\" +.\" Every column is a FIXED-WIDTH, WRAPPING tbl "w()" block, not a plain "l": +.\" without "w()" tbl sizes a column to its single widest entry and does NOT +.\" wrap, so a 40-character slug forces every column that wide -- seven of +.\" them together run far past any line length, tbl warns "table wider than +.\" line length", and whatever falls past the physical page edge is not a +.\" rendering nicety missing, it is GONE: `pdftotext -layout` (and a printed +.\" page) show only however many columns fit, not all seven. "w()" makes +.\" each column wrap its own text block instead, the same fix grid.tex +.\" already uses via LaTeX's "p{2.6cm}" (see that file's own comment) -- +.\" this is the tbl-native equivalent, not a different design. +.\" +.\" "w()" alone is NOT sufficient, and this is the part that actually cost +.\" the time: tbl only wraps a cell as a text block when its content is +.\" delimited by "T{"/"T}" on their own lines. A PLAIN cell entry in a +.\" "w()" column (what the first attempt at this fix used) is never +.\" wrapped at all -- tbl just widens the column past the requested "w()" +.\" to fit the single longest unbroken entry, exactly reproducing the +.\" original bug. Confirmed directly against tbl's own generated troff +.\" code (`tbl grid.ms`, grep "3w0 .*>?"): every column width register is +.\" `max(w(), \w'cell text')`, so an un-delimited 40-character cell always +.\" wins that max. Every day cell below is therefore its own "T{"/"T}" +.\" block; the closing "T}" and the following column's opening "T{" share +.\" one line with the tab between them (the standard tbl idiom: "T}<TAB> +.\" T{"). The template writes that as "T} +.\" <TAB>" rather than "T}<TAB>T{" so that no +.\" literal "T{" ever sits directly against a "" delimiter in the +.\" source -- three braces in a row there parses as a malformed tag, not +.\" as literal text followed by a tag. +.\" +.\" ".na" (no-adjust, ragged right) is required alongside the wrap, not +.\" cosmetic: a hyphenated slug like "commemoration-of-the-baptism-of-the- +.\" lord" DOES break at its own hyphens once wrapping is active (verified: +.\" troff's filler treats an ASCII hyphen as a break point), but adjusted +.\" (justified) fill in a column this narrow cannot always stretch such a +.\" line to the full measure and troff warns "cannot adjust line" for +.\" every such row -- another warning `make check-templates` must fail on. +.\" Ragged-right removes the stretching, not the wrapping. +.\" +.\" Day label falls back to the slug when the day carries no Latin name (most +.\" temporal days, and most sanctoral entries, which are Latin-less in the +.\" shipped data) -- see ordo.tex's own comment for why the fallback is +.\" written as a name-section wrapping a plain var and its inverse, rather +.\" than a single dotted lookup and its inverse. +.\" +.\" Every cell also carries a last flag, true on the seventh of its row: tbl +.\" needs the tab separator BETWEEN columns, not after the last one, and the +.\" engine has no unless-last construct, so the flag comes from data. +.pl 8.27i +.po 0.3i +.nr LL 10.9i +.ll \n[LL]u +.TL +Calendarium 2027 \(bu ef +.ll \n[LL]u +.na + +.SH +Ianuarius +.TS +allbox; +cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) +lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i). +Dom Lun Mar Mer Iov Ven Sab +T{ + +T} T{ + +T} T{ + +T} T{ + +T} T{ + +T} T{ +\fB1\fP \s-2ef-circumcision\s+2 +T} T{ +\fB2\fP \s-2Officium sanctae Mariae in sabbato\s+2 +T} +T{ +\fB3\fP \s-2Sanctissimi Nominis Iesu\s+2 +T} T{ +\fB4\fP \s-2ef-christmas-1-monday\s+2 +T} T{ +\fB5\fP \s-2ef-christmas-1-tuesday\s+2 +T} T{ +\fB6\fP \s-2ef-epiphany\s+2 +T} T{ +\fB7\fP \s-2ef-christmas-2-thursday\s+2 +T} T{ +\fB8\fP \s-2ef-christmas-2-friday\s+2 +T} T{ +\fB9\fP \s-2Officium sanctae Mariae in sabbato\s+2 +T} +T{ +\fB10\fP \s-2Sanctae Familiae Iesu, Mariae, Ioseph\s+2 +T} T{ +\fB11\fP \s-2ef-time-after-epiphany-1-monday\s+2 +T} T{ +\fB12\fP \s-2ef-time-after-epiphany-1-tuesday\s+2 +T} T{ +\fB13\fP \s-2commemoration-of-the-baptism-of-the-lord\s+2 +T} T{ +\fB14\fP \s-2hilary\s+2 +T} T{ +\fB15\fP \s-2paul-the-first-hermit\s+2 +T} T{ +\fB16\fP \s-2marcellus-i\s+2 +T} +T{ +\fB17\fP \s-2ef-time-after-epiphany-sunday-2\s+2 +T} T{ +\fB18\fP \s-2ef-time-after-epiphany-2-monday\s+2 +T} T{ +\fB19\fP \s-2ef-time-after-epiphany-2-tuesday\s+2 +T} T{ +\fB20\fP \s-2sts-fabian-sebastian\s+2 +T} T{ +\fB21\fP \s-2agnes\s+2 +T} T{ +\fB22\fP \s-2sts-vincent-anastasius\s+2 +T} T{ +\fB23\fP \s-2raymond-of-pe-afort\s+2 +T} +T{ +\fB24\fP \s-2ef-septuagesima-sunday-1\s+2 +T} T{ +\fB25\fP \s-2conversion-of-st-paul\s+2 +T} T{ +\fB26\fP \s-2polycarp\s+2 +T} T{ +\fB27\fP \s-2john-chrysostom\s+2 +T} T{ +\fB28\fP \s-2peter-nolasco\s+2 +T} T{ +\fB29\fP \s-2francis-de-sales\s+2 +T} T{ +\fB30\fP \s-2martina\s+2 +T} +T{ +\fB31\fP \s-2ef-septuagesima-sunday-2\s+2 +T} T{ + +T} T{ + +T} T{ + +T} T{ + +T} T{ + +T} T{ + +T} +.TE + +.SH +Februarius +.TS +allbox; +cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) +lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i). +Dom Lun Mar Mer Iov Ven Sab +T{ + +T} T{ +\fB1\fP \s-2ignatius-of-antioch\s+2 +T} T{ +\fB2\fP \s-2purification-of-the-blessed-virgin-mary\s+2 +T} T{ +\fB3\fP \s-2ef-septuagesima-2-wednesday\s+2 +T} T{ +\fB4\fP \s-2andrew-corsini\s+2 +T} T{ +\fB5\fP \s-2agatha\s+2 +T} T{ +\fB6\fP \s-2titus\s+2 +T} +T{ +\fB7\fP \s-2ef-septuagesima-sunday-3\s+2 +T} T{ +\fB8\fP \s-2john-of-matha\s+2 +T} T{ +\fB9\fP \s-2cyril-of-alexandria\s+2 +T} T{ +\fB10\fP \s-2ef-ash-wednesday\s+2 +T} T{ +\fB11\fP \s-2ef-lent-after-ashes-thursday\s+2 +T} T{ +\fB12\fP \s-2ef-lent-after-ashes-friday\s+2 +T} T{ +\fB13\fP \s-2ef-lent-after-ashes-saturday\s+2 +T} +T{ +\fB14\fP \s-2ef-lent-sunday-1\s+2 +T} T{ +\fB15\fP \s-2ef-lent-1-monday\s+2 +T} T{ +\fB16\fP \s-2ef-lent-1-tuesday\s+2 +T} T{ +\fB17\fP \s-2ef-lent-ember-wed\s+2 +T} T{ +\fB18\fP \s-2ef-lent-1-thursday\s+2 +T} T{ +\fB19\fP \s-2ef-lent-ember-fri\s+2 +T} T{ +\fB20\fP \s-2ef-lent-ember-sat\s+2 +T} +T{ +\fB21\fP \s-2ef-lent-sunday-2\s+2 +T} T{ +\fB22\fP \s-2chair-of-st-peter\s+2 +T} T{ +\fB23\fP \s-2ef-lent-2-tuesday\s+2 +T} T{ +\fB24\fP \s-2matthias\s+2 +T} T{ +\fB25\fP \s-2ef-lent-2-thursday\s+2 +T} T{ +\fB26\fP \s-2ef-lent-2-friday\s+2 +T} T{ +\fB27\fP \s-2ef-lent-2-saturday\s+2 +T} +T{ +\fB28\fP \s-2ef-lent-sunday-3\s+2 +T} T{ + +T} T{ + +T} T{ + +T} T{ + +T} T{ + +T} T{ + +T} +.TE + +.SH +Martius +.TS +allbox; +cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) +lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i). +Dom Lun Mar Mer Iov Ven Sab +T{ + +T} T{ +\fB1\fP \s-2ef-lent-3-monday\s+2 +T} T{ +\fB2\fP \s-2ef-lent-3-tuesday\s+2 +T} T{ +\fB3\fP \s-2ef-lent-3-wednesday\s+2 +T} T{ +\fB4\fP \s-2ef-lent-3-thursday\s+2 +T} T{ +\fB5\fP \s-2ef-lent-3-friday\s+2 +T} T{ +\fB6\fP \s-2ef-lent-3-saturday\s+2 +T} +T{ +\fB7\fP \s-2ef-lent-sunday-4\s+2 +T} T{ +\fB8\fP \s-2ef-lent-4-monday\s+2 +T} T{ +\fB9\fP \s-2ef-lent-4-tuesday\s+2 +T} T{ +\fB10\fP \s-2ef-lent-4-wednesday\s+2 +T} T{ +\fB11\fP \s-2ef-lent-4-thursday\s+2 +T} T{ +\fB12\fP \s-2ef-lent-4-friday\s+2 +T} T{ +\fB13\fP \s-2ef-lent-4-saturday\s+2 +T} +T{ +\fB14\fP \s-2ef-passion-sunday\s+2 +T} T{ +\fB15\fP \s-2ef-passiontide-1-monday\s+2 +T} T{ +\fB16\fP \s-2ef-passiontide-1-tuesday\s+2 +T} T{ +\fB17\fP \s-2ef-passiontide-1-wednesday\s+2 +T} T{ +\fB18\fP \s-2ef-passiontide-1-thursday\s+2 +T} T{ +\fB19\fP \s-2joseph-spouse-of-the-bl-virgin-mary\s+2 +T} T{ +\fB20\fP \s-2ef-passiontide-1-saturday\s+2 +T} +T{ +\fB21\fP \s-2ef-palm-sunday\s+2 +T} T{ +\fB22\fP \s-2ef-passiontide-2-monday\s+2 +T} T{ +\fB23\fP \s-2ef-passiontide-2-tuesday\s+2 +T} T{ +\fB24\fP \s-2ef-passiontide-2-wednesday\s+2 +T} T{ +\fB25\fP \s-2Feria V in Cena Domini\s+2 +T} T{ +\fB26\fP \s-2Feria VI in Passione et Morte Domini\s+2 +T} T{ +\fB27\fP \s-2Sabbato sancto\s+2 +T} +T{ +\fB28\fP \s-2ef-easter-sunday\s+2 +T} T{ +\fB29\fP \s-2ef-easter-1-monday\s+2 +T} T{ +\fB30\fP \s-2ef-easter-1-tuesday\s+2 +T} T{ +\fB31\fP \s-2ef-easter-1-wednesday\s+2 +T} T{ + +T} T{ + +T} T{ + +T} +.TE + +.SH +Aprilis +.TS +allbox; +cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) +lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i). +Dom Lun Mar Mer Iov Ven Sab +T{ + +T} T{ + +T} T{ + +T} T{ + +T} T{ +\fB1\fP \s-2ef-easter-1-thursday\s+2 +T} T{ +\fB2\fP \s-2ef-easter-1-friday\s+2 +T} T{ +\fB3\fP \s-2ef-easter-1-saturday\s+2 +T} +T{ +\fB4\fP \s-2ef-low-sunday\s+2 +T} T{ +\fB5\fP \s-2annunciation-of-the-blessed-virgin-mary\s+2 +T} T{ +\fB6\fP \s-2ef-easter-2-tuesday\s+2 +T} T{ +\fB7\fP \s-2ef-easter-2-wednesday\s+2 +T} T{ +\fB8\fP \s-2ef-easter-2-thursday\s+2 +T} T{ +\fB9\fP \s-2ef-easter-2-friday\s+2 +T} T{ +\fB10\fP \s-2Officium sanctae Mariae in sabbato\s+2 +T} +T{ +\fB11\fP \s-2ef-easter-sunday-3\s+2 +T} T{ +\fB12\fP \s-2ef-easter-3-monday\s+2 +T} T{ +\fB13\fP \s-2hermenegild\s+2 +T} T{ +\fB14\fP \s-2justin\s+2 +T} T{ +\fB15\fP \s-2ef-easter-3-thursday\s+2 +T} T{ +\fB16\fP \s-2ef-easter-3-friday\s+2 +T} T{ +\fB17\fP \s-2Officium sanctae Mariae in sabbato\s+2 +T} +T{ +\fB18\fP \s-2ef-easter-sunday-4\s+2 +T} T{ +\fB19\fP \s-2ef-easter-4-monday\s+2 +T} T{ +\fB20\fP \s-2ef-easter-4-tuesday\s+2 +T} T{ +\fB21\fP \s-2anselm\s+2 +T} T{ +\fB22\fP \s-2sts-soter-caius\s+2 +T} T{ +\fB23\fP \s-2ef-easter-4-friday\s+2 +T} T{ +\fB24\fP \s-2fidelis-of-sigmaringen\s+2 +T} +T{ +\fB25\fP \s-2ef-easter-sunday-5\s+2 +T} T{ +\fB26\fP \s-2sts-cletus-marcellinus\s+2 +T} T{ +\fB27\fP \s-2peter-canisius\s+2 +T} T{ +\fB28\fP \s-2paul-of-the-cross\s+2 +T} T{ +\fB29\fP \s-2peter-of-verona\s+2 +T} T{ +\fB30\fP \s-2catherine-of-siena\s+2 +T} T{ + +T} +.TE + +.SH +Maius +.TS +allbox; +cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) +lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i). +Dom Lun Mar Mer Iov Ven Sab +T{ + +T} T{ + +T} T{ + +T} T{ + +T} T{ + +T} T{ + +T} T{ +\fB1\fP \s-2joseph-the-workman\s+2 +T} +T{ +\fB2\fP \s-2ef-easter-sunday-6\s+2 +T} T{ +\fB3\fP \s-2ef-rogation-monday\s+2 +T} T{ +\fB4\fP \s-2monica\s+2 +T} T{ +\fB5\fP \s-2ef-ascension-vigil\s+2 +T} T{ +\fB6\fP \s-2ef-ascension\s+2 +T} T{ +\fB7\fP \s-2stanislaus\s+2 +T} T{ +\fB8\fP \s-2Officium sanctae Mariae in sabbato\s+2 +T} +T{ +\fB9\fP \s-2ef-easter-sunday-7\s+2 +T} T{ +\fB10\fP \s-2antoninus\s+2 +T} T{ +\fB11\fP \s-2sts-philip-james\s+2 +T} T{ +\fB12\fP \s-2sts-nereus-achilleus-domitilla-pancras\s+2 +T} T{ +\fB13\fP \s-2robert-bellarmine\s+2 +T} T{ +\fB14\fP \s-2ef-easter-7-friday\s+2 +T} T{ +\fB15\fP \s-2ef-pentecost-vigil\s+2 +T} +T{ +\fB16\fP \s-2ef-pentecost\s+2 +T} T{ +\fB17\fP \s-2ef-easter-8-monday\s+2 +T} T{ +\fB18\fP \s-2ef-easter-8-tuesday\s+2 +T} T{ +\fB19\fP \s-2ef-pentecost-ember-wed\s+2 +T} T{ +\fB20\fP \s-2ef-easter-8-thursday\s+2 +T} T{ +\fB21\fP \s-2ef-pentecost-ember-fri\s+2 +T} T{ +\fB22\fP \s-2ef-pentecost-ember-sat\s+2 +T} +T{ +\fB23\fP \s-2ef-trinity\s+2 +T} T{ +\fB24\fP \s-2ef-time-after-pentecost-1-monday\s+2 +T} T{ +\fB25\fP \s-2gregory-vii\s+2 +T} T{ +\fB26\fP \s-2philip-neri\s+2 +T} T{ +\fB27\fP \s-2ef-corpus-christi\s+2 +T} T{ +\fB28\fP \s-2augustine-of-canterbury\s+2 +T} T{ +\fB29\fP \s-2mary-magdalene-de-pazzi\s+2 +T} +T{ +\fB30\fP \s-2ef-time-after-pentecost-sunday-2\s+2 +T} T{ +\fB31\fP \s-2queenship-of-the-blessed-virgin-mary\s+2 +T} T{ + +T} T{ + +T} T{ + +T} T{ + +T} T{ + +T} +.TE + +.SH +Iunius +.TS +allbox; +cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) +lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i). +Dom Lun Mar Mer Iov Ven Sab +T{ + +T} T{ + +T} T{ +\fB1\fP \s-2angela-merici\s+2 +T} T{ +\fB2\fP \s-2ef-time-after-pentecost-2-wednesday\s+2 +T} T{ +\fB3\fP \s-2ef-time-after-pentecost-2-thursday\s+2 +T} T{ +\fB4\fP \s-2ef-sacred-heart\s+2 +T} T{ +\fB5\fP \s-2boniface\s+2 +T} +T{ +\fB6\fP \s-2ef-time-after-pentecost-sunday-3\s+2 +T} T{ +\fB7\fP \s-2ef-time-after-pentecost-3-monday\s+2 +T} T{ +\fB8\fP \s-2ef-time-after-pentecost-3-tuesday\s+2 +T} T{ +\fB9\fP \s-2ef-time-after-pentecost-3-wednesday\s+2 +T} T{ +\fB10\fP \s-2margaret-of-scotland\s+2 +T} T{ +\fB11\fP \s-2barnabas\s+2 +T} T{ +\fB12\fP \s-2john-of-san-fecundo\s+2 +T} +T{ +\fB13\fP \s-2ef-time-after-pentecost-sunday-4\s+2 +T} T{ +\fB14\fP \s-2basil-the-great\s+2 +T} T{ +\fB15\fP \s-2ef-time-after-pentecost-4-tuesday\s+2 +T} T{ +\fB16\fP \s-2ef-time-after-pentecost-4-wednesday\s+2 +T} T{ +\fB17\fP \s-2gregory-barbarigo\s+2 +T} T{ +\fB18\fP \s-2ephrem-of-syria\s+2 +T} T{ +\fB19\fP \s-2julia-of-falconieri\s+2 +T} +T{ +\fB20\fP \s-2ef-time-after-pentecost-sunday-5\s+2 +T} T{ +\fB21\fP \s-2aloysius-gongzaga\s+2 +T} T{ +\fB22\fP \s-2paulinus-of-nola\s+2 +T} T{ +\fB23\fP \s-2vigil-of-the-nativity-of-st-john-the-baptist\s+2 +T} T{ +\fB24\fP \s-2nativity-of-st-john-the-baptist\s+2 +T} T{ +\fB25\fP \s-2william\s+2 +T} T{ +\fB26\fP \s-2sts-john-paul\s+2 +T} +T{ +\fB27\fP \s-2ef-time-after-pentecost-sunday-6\s+2 +T} T{ +\fB28\fP \s-2vigil-of-sts-peter-paul\s+2 +T} T{ +\fB29\fP \s-2sts-peter-paul\s+2 +T} T{ +\fB30\fP \s-2in-commemoratione-sancti-pauli-apostoli\s+2 +T} T{ + +T} T{ + +T} T{ + +T} +.TE + +.SH +Iulius +.TS +allbox; +cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) +lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i). +Dom Lun Mar Mer Iov Ven Sab +T{ + +T} T{ + +T} T{ + +T} T{ + +T} T{ +\fB1\fP \s-2precious-blood-of-our-lord-jesus-christ\s+2 +T} T{ +\fB2\fP \s-2visitation-of-the-blessed-virgin-mary\s+2 +T} T{ +\fB3\fP \s-2irenaeus\s+2 +T} +T{ +\fB4\fP \s-2ef-time-after-pentecost-sunday-7\s+2 +T} T{ +\fB5\fP \s-2anthony-mary-zaccariah\s+2 +T} T{ +\fB6\fP \s-2ef-time-after-pentecost-7-tuesday\s+2 +T} T{ +\fB7\fP \s-2sts-cyril-methodius\s+2 +T} T{ +\fB8\fP \s-2elizabeth-of-portugal\s+2 +T} T{ +\fB9\fP \s-2ef-time-after-pentecost-7-friday\s+2 +T} T{ +\fB10\fP \s-2seven-holy-brothers-and-sts-rufina-secunda\s+2 +T} +T{ +\fB11\fP \s-2ef-time-after-pentecost-sunday-8\s+2 +T} T{ +\fB12\fP \s-2john-gualbert\s+2 +T} T{ +\fB13\fP \s-2ef-time-after-pentecost-8-tuesday\s+2 +T} T{ +\fB14\fP \s-2bonaventure\s+2 +T} T{ +\fB15\fP \s-2henry-the-emperor\s+2 +T} T{ +\fB16\fP \s-2ef-time-after-pentecost-8-friday\s+2 +T} T{ +\fB17\fP \s-2Officium sanctae Mariae in sabbato\s+2 +T} +T{ +\fB18\fP \s-2ef-time-after-pentecost-sunday-9\s+2 +T} T{ +\fB19\fP \s-2vincent-de-paul\s+2 +T} T{ +\fB20\fP \s-2jerome-emiliani\s+2 +T} T{ +\fB21\fP \s-2laurence-of-brindisi\s+2 +T} T{ +\fB22\fP \s-2mary-magdalene\s+2 +T} T{ +\fB23\fP \s-2apollinaris\s+2 +T} T{ +\fB24\fP \s-2Officium sanctae Mariae in sabbato\s+2 +T} +T{ +\fB25\fP \s-2ef-time-after-pentecost-sunday-10\s+2 +T} T{ +\fB26\fP \s-2anne-mother-of-the-blessed-virgin\s+2 +T} T{ +\fB27\fP \s-2ef-time-after-pentecost-10-tuesday\s+2 +T} T{ +\fB28\fP \s-2sts-nazarius-celsus-st-victor-i-st-innocent-i\s+2 +T} T{ +\fB29\fP \s-2martha\s+2 +T} T{ +\fB30\fP \s-2ef-time-after-pentecost-10-friday\s+2 +T} T{ +\fB31\fP \s-2ignatius-loyola\s+2 +T} +.TE + +.SH +Augustus +.TS +allbox; +cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) +lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i). +Dom Lun Mar Mer Iov Ven Sab +T{ +\fB1\fP \s-2ef-time-after-pentecost-sunday-11\s+2 +T} T{ +\fB2\fP \s-2alphonsus-liguori\s+2 +T} T{ +\fB3\fP \s-2ef-time-after-pentecost-11-tuesday\s+2 +T} T{ +\fB4\fP \s-2dominic\s+2 +T} T{ +\fB5\fP \s-2dedication-of-the-basilica-of-st-mary-major\s+2 +T} T{ +\fB6\fP \s-2transfiguration-of-our-lord\s+2 +T} T{ +\fB7\fP \s-2cajetan\s+2 +T} +T{ +\fB8\fP \s-2ef-time-after-pentecost-sunday-12\s+2 +T} T{ +\fB9\fP \s-2vigil-of-st-lawrence\s+2 +T} T{ +\fB10\fP \s-2lawrence\s+2 +T} T{ +\fB11\fP \s-2ef-time-after-pentecost-12-wednesday\s+2 +T} T{ +\fB12\fP \s-2clare\s+2 +T} T{ +\fB13\fP \s-2ef-time-after-pentecost-12-friday\s+2 +T} T{ +\fB14\fP \s-2vigil-of-the-assumption\s+2 +T} +T{ +\fB15\fP \s-2assumption-of-the-blessed-virgin-mary\s+2 +T} T{ +\fB16\fP \s-2joachim-father-of-the-blessed-virgin\s+2 +T} T{ +\fB17\fP \s-2hyacinth\s+2 +T} T{ +\fB18\fP \s-2ef-time-after-pentecost-13-wednesday\s+2 +T} T{ +\fB19\fP \s-2john-eudes\s+2 +T} T{ +\fB20\fP \s-2bernard-of-clairvaux\s+2 +T} T{ +\fB21\fP \s-2jane-frances-de-chantal\s+2 +T} +T{ +\fB22\fP \s-2ef-time-after-pentecost-sunday-14\s+2 +T} T{ +\fB23\fP \s-2philip-benizi\s+2 +T} T{ +\fB24\fP \s-2bartholomew\s+2 +T} T{ +\fB25\fP \s-2louis-ix\s+2 +T} T{ +\fB26\fP \s-2ef-time-after-pentecost-14-thursday\s+2 +T} T{ +\fB27\fP \s-2joseph-calasance\s+2 +T} T{ +\fB28\fP \s-2augustine\s+2 +T} +T{ +\fB29\fP \s-2ef-time-after-pentecost-sunday-15\s+2 +T} T{ +\fB30\fP \s-2rose-of-lima\s+2 +T} T{ +\fB31\fP \s-2raymond-nonnatus\s+2 +T} T{ + +T} T{ + +T} T{ + +T} T{ + +T} +.TE + +.SH +September +.TS +allbox; +cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) +lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i). +Dom Lun Mar Mer Iov Ven Sab +T{ + +T} T{ + +T} T{ + +T} T{ +\fB1\fP \s-2ef-time-after-pentecost-15-wednesday\s+2 +T} T{ +\fB2\fP \s-2stephen-of-hungary\s+2 +T} T{ +\fB3\fP \s-2pius-x\s+2 +T} T{ +\fB4\fP \s-2Officium sanctae Mariae in sabbato\s+2 +T} +T{ +\fB5\fP \s-2ef-time-after-pentecost-sunday-16\s+2 +T} T{ +\fB6\fP \s-2ef-time-after-pentecost-16-monday\s+2 +T} T{ +\fB7\fP \s-2ef-time-after-pentecost-16-tuesday\s+2 +T} T{ +\fB8\fP \s-2nativity-of-the-blessed-virgin-mary\s+2 +T} T{ +\fB9\fP \s-2ef-time-after-pentecost-16-thursday\s+2 +T} T{ +\fB10\fP \s-2nicholas-of-tolentino\s+2 +T} T{ +\fB11\fP \s-2Officium sanctae Mariae in sabbato\s+2 +T} +T{ +\fB12\fP \s-2ef-time-after-pentecost-sunday-17\s+2 +T} T{ +\fB13\fP \s-2ef-time-after-pentecost-17-monday\s+2 +T} T{ +\fB14\fP \s-2exaltation-of-the-holy-cross\s+2 +T} T{ +\fB15\fP \s-2seven-sorrows-of-the-blessed-virgin-mary\s+2 +T} T{ +\fB16\fP \s-2sts-cornelius-cyprian\s+2 +T} T{ +\fB17\fP \s-2ef-time-after-pentecost-17-friday\s+2 +T} T{ +\fB18\fP \s-2joseph-of-cupertino\s+2 +T} +T{ +\fB19\fP \s-2ef-time-after-pentecost-sunday-18\s+2 +T} T{ +\fB20\fP \s-2ef-time-after-pentecost-18-monday\s+2 +T} T{ +\fB21\fP \s-2matthew\s+2 +T} T{ +\fB22\fP \s-2ef-september-ember-wed\s+2 +T} T{ +\fB23\fP \s-2linus\s+2 +T} T{ +\fB24\fP \s-2ef-september-ember-fri\s+2 +T} T{ +\fB25\fP \s-2ef-september-ember-sat\s+2 +T} +T{ +\fB26\fP \s-2ef-time-after-pentecost-sunday-19\s+2 +T} T{ +\fB27\fP \s-2sts-cosmas-damian\s+2 +T} T{ +\fB28\fP \s-2wenceslaus\s+2 +T} T{ +\fB29\fP \s-2dedication-of-st-michael-the-archangel\s+2 +T} T{ +\fB30\fP \s-2jerome\s+2 +T} T{ + +T} T{ + +T} +.TE + +.SH +October +.TS +allbox; +cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) +lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i). +Dom Lun Mar Mer Iov Ven Sab +T{ + +T} T{ + +T} T{ + +T} T{ + +T} T{ + +T} T{ +\fB1\fP \s-2ef-time-after-pentecost-19-friday\s+2 +T} T{ +\fB2\fP \s-2holy-guardian-angels\s+2 +T} +T{ +\fB3\fP \s-2ef-time-after-pentecost-sunday-20\s+2 +T} T{ +\fB4\fP \s-2francis-of-assisi\s+2 +T} T{ +\fB5\fP \s-2ef-time-after-pentecost-20-tuesday\s+2 +T} T{ +\fB6\fP \s-2bruno\s+2 +T} T{ +\fB7\fP \s-2our-lady-of-the-rosary\s+2 +T} T{ +\fB8\fP \s-2bridget-of-sweden\s+2 +T} T{ +\fB9\fP \s-2john-leonardi\s+2 +T} +T{ +\fB10\fP \s-2ef-time-after-pentecost-sunday-21\s+2 +T} T{ +\fB11\fP \s-2maternity-of-the-blessed-virgin-mary\s+2 +T} T{ +\fB12\fP \s-2ef-time-after-pentecost-21-tuesday\s+2 +T} T{ +\fB13\fP \s-2edward\s+2 +T} T{ +\fB14\fP \s-2callistus-i\s+2 +T} T{ +\fB15\fP \s-2teresa-of-avila\s+2 +T} T{ +\fB16\fP \s-2hedwig\s+2 +T} +T{ +\fB17\fP \s-2ef-time-after-pentecost-sunday-22\s+2 +T} T{ +\fB18\fP \s-2luke-the-evangelist\s+2 +T} T{ +\fB19\fP \s-2peter-of-alcantara\s+2 +T} T{ +\fB20\fP \s-2john-cantius\s+2 +T} T{ +\fB21\fP \s-2ef-time-after-pentecost-22-thursday\s+2 +T} T{ +\fB22\fP \s-2ef-time-after-pentecost-22-friday\s+2 +T} T{ +\fB23\fP \s-2anthony-mary-claret\s+2 +T} +T{ +\fB24\fP \s-2ef-time-after-pentecost-sunday-23\s+2 +T} T{ +\fB25\fP \s-2ef-time-after-pentecost-23-monday\s+2 +T} T{ +\fB26\fP \s-2ef-time-after-pentecost-23-tuesday\s+2 +T} T{ +\fB27\fP \s-2ef-time-after-pentecost-23-wednesday\s+2 +T} T{ +\fB28\fP \s-2sts-simon-jude\s+2 +T} T{ +\fB29\fP \s-2ef-time-after-pentecost-23-friday\s+2 +T} T{ +\fB30\fP \s-2Officium sanctae Mariae in sabbato\s+2 +T} +T{ +\fB31\fP \s-2ef-christ-the-king\s+2 +T} T{ + +T} T{ + +T} T{ + +T} T{ + +T} T{ + +T} T{ + +T} +.TE + +.SH +November +.TS +allbox; +cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) +lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i). +Dom Lun Mar Mer Iov Ven Sab +T{ + +T} T{ +\fB1\fP \s-2all-saints\s+2 +T} T{ +\fB2\fP \s-2commemoration-of-all-souls\s+2 +T} T{ +\fB3\fP \s-2ef-time-after-pentecost-24-wednesday\s+2 +T} T{ +\fB4\fP \s-2charles-borromeo\s+2 +T} T{ +\fB5\fP \s-2ef-time-after-pentecost-24-friday\s+2 +T} T{ +\fB6\fP \s-2Officium sanctae Mariae in sabbato\s+2 +T} +T{ +\fB7\fP \s-2ef-time-after-epiphany-sunday-5\s+2 +T} T{ +\fB8\fP \s-2ef-time-after-pentecost-25-monday\s+2 +T} T{ +\fB9\fP \s-2dedication-of-the-archbasilica-of-our-holy-savior\s+2 +T} T{ +\fB10\fP \s-2andrew-avellino\s+2 +T} T{ +\fB11\fP \s-2martin-of-tours\s+2 +T} T{ +\fB12\fP \s-2martin-i\s+2 +T} T{ +\fB13\fP \s-2didacus\s+2 +T} +T{ +\fB14\fP \s-2ef-time-after-epiphany-sunday-6\s+2 +T} T{ +\fB15\fP \s-2albert-the-great\s+2 +T} T{ +\fB16\fP \s-2gertrude-the-great\s+2 +T} T{ +\fB17\fP \s-2gregory-the-wonderworker\s+2 +T} T{ +\fB18\fP \s-2dedication-of-the-basilicas-of-sts-peter-paul\s+2 +T} T{ +\fB19\fP \s-2elizabeth-of-hungary\s+2 +T} T{ +\fB20\fP \s-2felix-of-valois\s+2 +T} +T{ +\fB21\fP \s-2ef-time-after-pentecost-sunday-24\s+2 +T} T{ +\fB22\fP \s-2cecilia\s+2 +T} T{ +\fB23\fP \s-2clement-i\s+2 +T} T{ +\fB24\fP \s-2john-of-the-cross\s+2 +T} T{ +\fB25\fP \s-2catherine-of-alexandria\s+2 +T} T{ +\fB26\fP \s-2sylvester\s+2 +T} T{ +\fB27\fP \s-2Officium sanctae Mariae in sabbato\s+2 +T} +T{ +\fB28\fP \s-2ef-advent-sunday-1\s+2 +T} T{ +\fB29\fP \s-2ef-advent-1-monday\s+2 +T} T{ +\fB30\fP \s-2andrew\s+2 +T} T{ + +T} T{ + +T} T{ + +T} T{ + +T} +.TE + +.SH +December +.TS +allbox; +cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) cw(1.3i) +lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i) lw(1.3i). +Dom Lun Mar Mer Iov Ven Sab +T{ + +T} T{ + +T} T{ + +T} T{ +\fB1\fP \s-2ef-advent-1-wednesday\s+2 +T} T{ +\fB2\fP \s-2vivian\s+2 +T} T{ +\fB3\fP \s-2francis-xavier\s+2 +T} T{ +\fB4\fP \s-2peter-chrysologus\s+2 +T} +T{ +\fB5\fP \s-2ef-advent-sunday-2\s+2 +T} T{ +\fB6\fP \s-2nicholas\s+2 +T} T{ +\fB7\fP \s-2ambrose\s+2 +T} T{ +\fB8\fP \s-2immaculate-conception-of-the-blessed-virgin-mary\s+2 +T} T{ +\fB9\fP \s-2ef-advent-2-thursday\s+2 +T} T{ +\fB10\fP \s-2ef-advent-2-friday\s+2 +T} T{ +\fB11\fP \s-2damasus-i\s+2 +T} +T{ +\fB12\fP \s-2ef-advent-sunday-3\s+2 +T} T{ +\fB13\fP \s-2lucy\s+2 +T} T{ +\fB14\fP \s-2ef-advent-3-tuesday\s+2 +T} T{ +\fB15\fP \s-2ef-advent-ember-wed\s+2 +T} T{ +\fB16\fP \s-2eusebius\s+2 +T} T{ +\fB17\fP \s-2ef-advent-ember-fri\s+2 +T} T{ +\fB18\fP \s-2ef-advent-ember-sat\s+2 +T} +T{ +\fB19\fP \s-2ef-advent-sunday-4\s+2 +T} T{ +\fB20\fP \s-2ef-advent-4-monday\s+2 +T} T{ +\fB21\fP \s-2thomas\s+2 +T} T{ +\fB22\fP \s-2ef-advent-4-wednesday\s+2 +T} T{ +\fB23\fP \s-2ef-advent-4-thursday\s+2 +T} T{ +\fB24\fP \s-2ef-nativity-vigil\s+2 +T} T{ +\fB25\fP \s-2ef-nativity\s+2 +T} +T{ +\fB26\fP \s-2ef-christmas-sunday-0\s+2 +T} T{ +\fB27\fP \s-2john-the-evangelist\s+2 +T} T{ +\fB28\fP \s-2holy-innocents\s+2 +T} T{ +\fB29\fP \s-2ef-nativity-octave-day-5\s+2 +T} T{ +\fB30\fP \s-2ef-nativity-octave-day-6\s+2 +T} T{ +\fB31\fP \s-2ef-nativity-octave-day-7\s+2 +T} T{ + +T} +.TE + diff --git a/test/golden/grid-2027.tex b/test/golden/grid-2027.tex new file mode 100644 index 0000000..9a50ddd --- /dev/null +++ b/test/golden/grid-2027.tex @@ -0,0 +1,174 @@ +% colitur wall calendar -- LaTeX. flavour: latex +% Build: colitur table --year 2027 --template grid.tex > grid.tex && pdflatex grid.tex +% +% Day label falls back to the slug when the day carries no Latin name (most +% temporal days, and most sanctoral entries, which are Latin-less in the +% shipped data). The fallback is written as a name-section wrapping a plain +% var and its inverse, deliberately NOT as a single dotted-path lookup +% followed by its own inverse: a dotted lookup that misses climbs to the +% enclosing scope for the WHOLE path, and the month object also carries a +% same-named key one level up, so the naive form would render the month's +% own Latin name on every day lacking one, and never fall back at all. +% +% Every cell also carries a last flag, true on the seventh of its row: the +% engine has no unless-last construct, so the separator BETWEEN cells comes +% from data, not the template. A trailing separator on every cell would give +% eight columns for seven and pdflatex would reject the file outright. +\documentclass[10pt,landscape]{article} +\usepackage[a4paper,margin=10mm]{geometry} +\usepackage[T1]{fontenc} +\usepackage[utf8]{inputenc} +\usepackage[table]{xcolor} +\definecolor{lwhite}{HTML}{FFFFFF}\definecolor{lred}{HTML}{FFDDDD} +\definecolor{lgreen}{HTML}{DDFFDD}\definecolor{lviolet}{HTML}{EEAAEE} +\definecolor{lrose}{HTML}{FFDDEE}\definecolor{lblack}{HTML}{DDDDDD} +\begin{document} + +\section*{ Ianuarius 2027 } +\begin{tabular}{|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|} +\hline Dom & Lun & Mar & Mer & Iov & Ven & Sab \\ \hline + & & & & & \cellcolor{lwhite}\textbf{ 1 } \footnotesize ef-circumcision & \cellcolor{lwhite}\textbf{ 2 } \footnotesize Officium sanctae Mariae in sabbato \\ \hline +\cellcolor{lwhite}\textbf{ 3 } \footnotesize Sanctissimi Nominis Iesu & \cellcolor{lwhite}\textbf{ 4 } \footnotesize ef-christmas-1-monday & \cellcolor{lwhite}\textbf{ 5 } \footnotesize ef-christmas-1-tuesday & \cellcolor{lwhite}\textbf{ 6 } \footnotesize ef-epiphany & \cellcolor{lwhite}\textbf{ 7 } \footnotesize ef-christmas-2-thursday & \cellcolor{lwhite}\textbf{ 8 } \footnotesize ef-christmas-2-friday & \cellcolor{lwhite}\textbf{ 9 } \footnotesize Officium sanctae Mariae in sabbato \\ \hline +\cellcolor{lwhite}\textbf{ 10 } \footnotesize Sanctae Familiae Iesu, Mariae, Ioseph & \cellcolor{lwhite}\textbf{ 11 } \footnotesize ef-time-after-epiphany-1-monday & \cellcolor{lwhite}\textbf{ 12 } \footnotesize ef-time-after-epiphany-1-tuesday & \cellcolor{lwhite}\textbf{ 13 } \footnotesize commemoration-of-the-baptism-of-the-lord & \cellcolor{lwhite}\textbf{ 14 } \footnotesize hilary & \cellcolor{lwhite}\textbf{ 15 } \footnotesize paul-the-first-hermit & \cellcolor{lred}\textbf{ 16 } \footnotesize marcellus-i \\ \hline +\cellcolor{lgreen}\textbf{ 17 } \footnotesize ef-time-after-epiphany-sunday-2 & \cellcolor{lgreen}\textbf{ 18 } \footnotesize ef-time-after-epiphany-2-monday & \cellcolor{lgreen}\textbf{ 19 } \footnotesize ef-time-after-epiphany-2-tuesday & \cellcolor{lred}\textbf{ 20 } \footnotesize sts-fabian-sebastian & \cellcolor{lred}\textbf{ 21 } \footnotesize agnes & \cellcolor{lred}\textbf{ 22 } \footnotesize sts-vincent-anastasius & \cellcolor{lwhite}\textbf{ 23 } \footnotesize raymond-of-pe-afort \\ \hline +\cellcolor{lviolet}\textbf{ 24 } \footnotesize ef-septuagesima-sunday-1 & \cellcolor{lwhite}\textbf{ 25 } \footnotesize conversion-of-st-paul & \cellcolor{lred}\textbf{ 26 } \footnotesize polycarp & \cellcolor{lwhite}\textbf{ 27 } \footnotesize john-chrysostom & \cellcolor{lwhite}\textbf{ 28 } \footnotesize peter-nolasco & \cellcolor{lwhite}\textbf{ 29 } \footnotesize francis-de-sales & \cellcolor{lred}\textbf{ 30 } \footnotesize martina \\ \hline +\cellcolor{lviolet}\textbf{ 31 } \footnotesize ef-septuagesima-sunday-2 & & & & & & \\ \hline + +\end{tabular} +\newpage + +\section*{ Februarius 2027 } +\begin{tabular}{|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|} +\hline Dom & Lun & Mar & Mer & Iov & Ven & Sab \\ \hline + & \cellcolor{lred}\textbf{ 1 } \footnotesize ignatius-of-antioch & \cellcolor{lwhite}\textbf{ 2 } \footnotesize purification-of-the-blessed-virgin-mary & \cellcolor{lviolet}\textbf{ 3 } \footnotesize ef-septuagesima-2-wednesday & \cellcolor{lwhite}\textbf{ 4 } \footnotesize andrew-corsini & \cellcolor{lred}\textbf{ 5 } \footnotesize agatha & \cellcolor{lwhite}\textbf{ 6 } \footnotesize titus \\ \hline +\cellcolor{lviolet}\textbf{ 7 } \footnotesize ef-septuagesima-sunday-3 & \cellcolor{lwhite}\textbf{ 8 } \footnotesize john-of-matha & \cellcolor{lwhite}\textbf{ 9 } \footnotesize cyril-of-alexandria & \cellcolor{lviolet}\textbf{ 10 } \footnotesize ef-ash-wednesday & \cellcolor{lviolet}\textbf{ 11 } \footnotesize ef-lent-after-ashes-thursday & \cellcolor{lviolet}\textbf{ 12 } \footnotesize ef-lent-after-ashes-friday & \cellcolor{lviolet}\textbf{ 13 } \footnotesize ef-lent-after-ashes-saturday \\ \hline +\cellcolor{lviolet}\textbf{ 14 } \footnotesize ef-lent-sunday-1 & \cellcolor{lviolet}\textbf{ 15 } \footnotesize ef-lent-1-monday & \cellcolor{lviolet}\textbf{ 16 } \footnotesize ef-lent-1-tuesday & \cellcolor{lviolet}\textbf{ 17 } \footnotesize ef-lent-ember-wed & \cellcolor{lviolet}\textbf{ 18 } \footnotesize ef-lent-1-thursday & \cellcolor{lviolet}\textbf{ 19 } \footnotesize ef-lent-ember-fri & \cellcolor{lviolet}\textbf{ 20 } \footnotesize ef-lent-ember-sat \\ \hline +\cellcolor{lviolet}\textbf{ 21 } \footnotesize ef-lent-sunday-2 & \cellcolor{lwhite}\textbf{ 22 } \footnotesize chair-of-st-peter & \cellcolor{lviolet}\textbf{ 23 } \footnotesize ef-lent-2-tuesday & \cellcolor{lred}\textbf{ 24 } \footnotesize matthias & \cellcolor{lviolet}\textbf{ 25 } \footnotesize ef-lent-2-thursday & \cellcolor{lviolet}\textbf{ 26 } \footnotesize ef-lent-2-friday & \cellcolor{lviolet}\textbf{ 27 } \footnotesize ef-lent-2-saturday \\ \hline +\cellcolor{lviolet}\textbf{ 28 } \footnotesize ef-lent-sunday-3 & & & & & & \\ \hline + +\end{tabular} +\newpage + +\section*{ Martius 2027 } +\begin{tabular}{|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|} +\hline Dom & Lun & Mar & Mer & Iov & Ven & Sab \\ \hline + & \cellcolor{lviolet}\textbf{ 1 } \footnotesize ef-lent-3-monday & \cellcolor{lviolet}\textbf{ 2 } \footnotesize ef-lent-3-tuesday & \cellcolor{lviolet}\textbf{ 3 } \footnotesize ef-lent-3-wednesday & \cellcolor{lviolet}\textbf{ 4 } \footnotesize ef-lent-3-thursday & \cellcolor{lviolet}\textbf{ 5 } \footnotesize ef-lent-3-friday & \cellcolor{lviolet}\textbf{ 6 } \footnotesize ef-lent-3-saturday \\ \hline +\cellcolor{lrose}\textbf{ 7 } \footnotesize ef-lent-sunday-4 & \cellcolor{lviolet}\textbf{ 8 } \footnotesize ef-lent-4-monday & \cellcolor{lviolet}\textbf{ 9 } \footnotesize ef-lent-4-tuesday & \cellcolor{lviolet}\textbf{ 10 } \footnotesize ef-lent-4-wednesday & \cellcolor{lviolet}\textbf{ 11 } \footnotesize ef-lent-4-thursday & \cellcolor{lviolet}\textbf{ 12 } \footnotesize ef-lent-4-friday & \cellcolor{lviolet}\textbf{ 13 } \footnotesize ef-lent-4-saturday \\ \hline +\cellcolor{lviolet}\textbf{ 14 } \footnotesize ef-passion-sunday & \cellcolor{lviolet}\textbf{ 15 } \footnotesize ef-passiontide-1-monday & \cellcolor{lviolet}\textbf{ 16 } \footnotesize ef-passiontide-1-tuesday & \cellcolor{lviolet}\textbf{ 17 } \footnotesize ef-passiontide-1-wednesday & \cellcolor{lviolet}\textbf{ 18 } \footnotesize ef-passiontide-1-thursday & \cellcolor{lwhite}\textbf{ 19 } \footnotesize joseph-spouse-of-the-bl-virgin-mary & \cellcolor{lviolet}\textbf{ 20 } \footnotesize ef-passiontide-1-saturday \\ \hline +\cellcolor{lviolet}\textbf{ 21 } \footnotesize ef-palm-sunday & \cellcolor{lviolet}\textbf{ 22 } \footnotesize ef-passiontide-2-monday & \cellcolor{lviolet}\textbf{ 23 } \footnotesize ef-passiontide-2-tuesday & \cellcolor{lviolet}\textbf{ 24 } \footnotesize ef-passiontide-2-wednesday & \cellcolor{lwhite}\textbf{ 25 } \footnotesize Feria V in Cena Domini & \cellcolor{lblack}\textbf{ 26 } \footnotesize Feria VI in Passione et Morte Domini & \cellcolor{lviolet}\textbf{ 27 } \footnotesize Sabbato sancto \\ \hline +\cellcolor{lwhite}\textbf{ 28 } \footnotesize ef-easter-sunday & \cellcolor{lwhite}\textbf{ 29 } \footnotesize ef-easter-1-monday & \cellcolor{lwhite}\textbf{ 30 } \footnotesize ef-easter-1-tuesday & \cellcolor{lwhite}\textbf{ 31 } \footnotesize ef-easter-1-wednesday & & & \\ \hline + +\end{tabular} +\newpage + +\section*{ Aprilis 2027 } +\begin{tabular}{|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|} +\hline Dom & Lun & Mar & Mer & Iov & Ven & Sab \\ \hline + & & & & \cellcolor{lwhite}\textbf{ 1 } \footnotesize ef-easter-1-thursday & \cellcolor{lwhite}\textbf{ 2 } \footnotesize ef-easter-1-friday & \cellcolor{lwhite}\textbf{ 3 } \footnotesize ef-easter-1-saturday \\ \hline +\cellcolor{lwhite}\textbf{ 4 } \footnotesize ef-low-sunday & \cellcolor{lwhite}\textbf{ 5 } \footnotesize annunciation-of-the-blessed-virgin-mary & \cellcolor{lwhite}\textbf{ 6 } \footnotesize ef-easter-2-tuesday & \cellcolor{lwhite}\textbf{ 7 } \footnotesize ef-easter-2-wednesday & \cellcolor{lwhite}\textbf{ 8 } \footnotesize ef-easter-2-thursday & \cellcolor{lwhite}\textbf{ 9 } \footnotesize ef-easter-2-friday & \cellcolor{lwhite}\textbf{ 10 } \footnotesize Officium sanctae Mariae in sabbato \\ \hline +\cellcolor{lwhite}\textbf{ 11 } \footnotesize ef-easter-sunday-3 & \cellcolor{lwhite}\textbf{ 12 } \footnotesize ef-easter-3-monday & \cellcolor{lred}\textbf{ 13 } \footnotesize hermenegild & \cellcolor{lred}\textbf{ 14 } \footnotesize justin & \cellcolor{lwhite}\textbf{ 15 } \footnotesize ef-easter-3-thursday & \cellcolor{lwhite}\textbf{ 16 } \footnotesize ef-easter-3-friday & \cellcolor{lwhite}\textbf{ 17 } \footnotesize Officium sanctae Mariae in sabbato \\ \hline +\cellcolor{lwhite}\textbf{ 18 } \footnotesize ef-easter-sunday-4 & \cellcolor{lwhite}\textbf{ 19 } \footnotesize ef-easter-4-monday & \cellcolor{lwhite}\textbf{ 20 } \footnotesize ef-easter-4-tuesday & \cellcolor{lwhite}\textbf{ 21 } \footnotesize anselm & \cellcolor{lred}\textbf{ 22 } \footnotesize sts-soter-caius & \cellcolor{lwhite}\textbf{ 23 } \footnotesize ef-easter-4-friday & \cellcolor{lred}\textbf{ 24 } \footnotesize fidelis-of-sigmaringen \\ \hline +\cellcolor{lwhite}\textbf{ 25 } \footnotesize ef-easter-sunday-5 & \cellcolor{lred}\textbf{ 26 } \footnotesize sts-cletus-marcellinus & \cellcolor{lwhite}\textbf{ 27 } \footnotesize peter-canisius & \cellcolor{lwhite}\textbf{ 28 } \footnotesize paul-of-the-cross & \cellcolor{lred}\textbf{ 29 } \footnotesize peter-of-verona & \cellcolor{lwhite}\textbf{ 30 } \footnotesize catherine-of-siena & \\ \hline + +\end{tabular} +\newpage + +\section*{ Maius 2027 } +\begin{tabular}{|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|} +\hline Dom & Lun & Mar & Mer & Iov & Ven & Sab \\ \hline + & & & & & & \cellcolor{lwhite}\textbf{ 1 } \footnotesize joseph-the-workman \\ \hline +\cellcolor{lwhite}\textbf{ 2 } \footnotesize ef-easter-sunday-6 & \cellcolor{lviolet}\textbf{ 3 } \footnotesize ef-rogation-monday & \cellcolor{lwhite}\textbf{ 4 } \footnotesize monica & \cellcolor{lwhite}\textbf{ 5 } \footnotesize ef-ascension-vigil & \cellcolor{lwhite}\textbf{ 6 } \footnotesize ef-ascension & \cellcolor{lred}\textbf{ 7 } \footnotesize stanislaus & \cellcolor{lwhite}\textbf{ 8 } \footnotesize Officium sanctae Mariae in sabbato \\ \hline +\cellcolor{lwhite}\textbf{ 9 } \footnotesize ef-easter-sunday-7 & \cellcolor{lwhite}\textbf{ 10 } \footnotesize antoninus & \cellcolor{lred}\textbf{ 11 } \footnotesize sts-philip-james & \cellcolor{lred}\textbf{ 12 } \footnotesize sts-nereus-achilleus-domitilla-pancras & \cellcolor{lwhite}\textbf{ 13 } \footnotesize robert-bellarmine & \cellcolor{lwhite}\textbf{ 14 } \footnotesize ef-easter-7-friday & \cellcolor{lred}\textbf{ 15 } \footnotesize ef-pentecost-vigil \\ \hline +\cellcolor{lred}\textbf{ 16 } \footnotesize ef-pentecost & \cellcolor{lred}\textbf{ 17 } \footnotesize ef-easter-8-monday & \cellcolor{lred}\textbf{ 18 } \footnotesize ef-easter-8-tuesday & \cellcolor{lred}\textbf{ 19 } \footnotesize ef-pentecost-ember-wed & \cellcolor{lred}\textbf{ 20 } \footnotesize ef-easter-8-thursday & \cellcolor{lred}\textbf{ 21 } \footnotesize ef-pentecost-ember-fri & \cellcolor{lred}\textbf{ 22 } \footnotesize ef-pentecost-ember-sat \\ \hline +\cellcolor{lwhite}\textbf{ 23 } \footnotesize ef-trinity & \cellcolor{lgreen}\textbf{ 24 } \footnotesize ef-time-after-pentecost-1-monday & \cellcolor{lwhite}\textbf{ 25 } \footnotesize gregory-vii & \cellcolor{lwhite}\textbf{ 26 } \footnotesize philip-neri & \cellcolor{lwhite}\textbf{ 27 } \footnotesize ef-corpus-christi & \cellcolor{lwhite}\textbf{ 28 } \footnotesize augustine-of-canterbury & \cellcolor{lwhite}\textbf{ 29 } \footnotesize mary-magdalene-de-pazzi \\ \hline +\cellcolor{lgreen}\textbf{ 30 } \footnotesize ef-time-after-pentecost-sunday-2 & \cellcolor{lwhite}\textbf{ 31 } \footnotesize queenship-of-the-blessed-virgin-mary & & & & & \\ \hline + +\end{tabular} +\newpage + +\section*{ Iunius 2027 } +\begin{tabular}{|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|} +\hline Dom & Lun & Mar & Mer & Iov & Ven & Sab \\ \hline + & & \cellcolor{lwhite}\textbf{ 1 } \footnotesize angela-merici & \cellcolor{lgreen}\textbf{ 2 } \footnotesize ef-time-after-pentecost-2-wednesday & \cellcolor{lgreen}\textbf{ 3 } \footnotesize ef-time-after-pentecost-2-thursday & \cellcolor{lwhite}\textbf{ 4 } \footnotesize ef-sacred-heart & \cellcolor{lred}\textbf{ 5 } \footnotesize boniface \\ \hline +\cellcolor{lgreen}\textbf{ 6 } \footnotesize ef-time-after-pentecost-sunday-3 & \cellcolor{lgreen}\textbf{ 7 } \footnotesize ef-time-after-pentecost-3-monday & \cellcolor{lgreen}\textbf{ 8 } \footnotesize ef-time-after-pentecost-3-tuesday & \cellcolor{lgreen}\textbf{ 9 } \footnotesize ef-time-after-pentecost-3-wednesday & \cellcolor{lwhite}\textbf{ 10 } \footnotesize margaret-of-scotland & \cellcolor{lred}\textbf{ 11 } \footnotesize barnabas & \cellcolor{lwhite}\textbf{ 12 } \footnotesize john-of-san-fecundo \\ \hline +\cellcolor{lgreen}\textbf{ 13 } \footnotesize ef-time-after-pentecost-sunday-4 & \cellcolor{lwhite}\textbf{ 14 } \footnotesize basil-the-great & \cellcolor{lgreen}\textbf{ 15 } \footnotesize ef-time-after-pentecost-4-tuesday & \cellcolor{lgreen}\textbf{ 16 } \footnotesize ef-time-after-pentecost-4-wednesday & \cellcolor{lwhite}\textbf{ 17 } \footnotesize gregory-barbarigo & \cellcolor{lwhite}\textbf{ 18 } \footnotesize ephrem-of-syria & \cellcolor{lwhite}\textbf{ 19 } \footnotesize julia-of-falconieri \\ \hline +\cellcolor{lgreen}\textbf{ 20 } \footnotesize ef-time-after-pentecost-sunday-5 & \cellcolor{lwhite}\textbf{ 21 } \footnotesize aloysius-gongzaga & \cellcolor{lwhite}\textbf{ 22 } \footnotesize paulinus-of-nola & \cellcolor{lviolet}\textbf{ 23 } \footnotesize vigil-of-the-nativity-of-st-john-the-baptist & \cellcolor{lwhite}\textbf{ 24 } \footnotesize nativity-of-st-john-the-baptist & \cellcolor{lwhite}\textbf{ 25 } \footnotesize william & \cellcolor{lred}\textbf{ 26 } \footnotesize sts-john-paul \\ \hline +\cellcolor{lgreen}\textbf{ 27 } \footnotesize ef-time-after-pentecost-sunday-6 & \cellcolor{lviolet}\textbf{ 28 } \footnotesize vigil-of-sts-peter-paul & \cellcolor{lred}\textbf{ 29 } \footnotesize sts-peter-paul & \cellcolor{lred}\textbf{ 30 } \footnotesize in-commemoratione-sancti-pauli-apostoli & & & \\ \hline + +\end{tabular} +\newpage + +\section*{ Iulius 2027 } +\begin{tabular}{|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|} +\hline Dom & Lun & Mar & Mer & Iov & Ven & Sab \\ \hline + & & & & \cellcolor{lred}\textbf{ 1 } \footnotesize precious-blood-of-our-lord-jesus-christ & \cellcolor{lwhite}\textbf{ 2 } \footnotesize visitation-of-the-blessed-virgin-mary & \cellcolor{lred}\textbf{ 3 } \footnotesize irenaeus \\ \hline +\cellcolor{lgreen}\textbf{ 4 } \footnotesize ef-time-after-pentecost-sunday-7 & \cellcolor{lwhite}\textbf{ 5 } \footnotesize anthony-mary-zaccariah & \cellcolor{lgreen}\textbf{ 6 } \footnotesize ef-time-after-pentecost-7-tuesday & \cellcolor{lwhite}\textbf{ 7 } \footnotesize sts-cyril-methodius & \cellcolor{lwhite}\textbf{ 8 } \footnotesize elizabeth-of-portugal & \cellcolor{lgreen}\textbf{ 9 } \footnotesize ef-time-after-pentecost-7-friday & \cellcolor{lred}\textbf{ 10 } \footnotesize seven-holy-brothers-and-sts-rufina-secunda \\ \hline +\cellcolor{lgreen}\textbf{ 11 } \footnotesize ef-time-after-pentecost-sunday-8 & \cellcolor{lwhite}\textbf{ 12 } \footnotesize john-gualbert & \cellcolor{lgreen}\textbf{ 13 } \footnotesize ef-time-after-pentecost-8-tuesday & \cellcolor{lwhite}\textbf{ 14 } \footnotesize bonaventure & \cellcolor{lwhite}\textbf{ 15 } \footnotesize henry-the-emperor & \cellcolor{lgreen}\textbf{ 16 } \footnotesize ef-time-after-pentecost-8-friday & \cellcolor{lwhite}\textbf{ 17 } \footnotesize Officium sanctae Mariae in sabbato \\ \hline +\cellcolor{lgreen}\textbf{ 18 } \footnotesize ef-time-after-pentecost-sunday-9 & \cellcolor{lwhite}\textbf{ 19 } \footnotesize vincent-de-paul & \cellcolor{lwhite}\textbf{ 20 } \footnotesize jerome-emiliani & \cellcolor{lwhite}\textbf{ 21 } \footnotesize laurence-of-brindisi & \cellcolor{lwhite}\textbf{ 22 } \footnotesize mary-magdalene & \cellcolor{lred}\textbf{ 23 } \footnotesize apollinaris & \cellcolor{lwhite}\textbf{ 24 } \footnotesize Officium sanctae Mariae in sabbato \\ \hline +\cellcolor{lgreen}\textbf{ 25 } \footnotesize ef-time-after-pentecost-sunday-10 & \cellcolor{lwhite}\textbf{ 26 } \footnotesize anne-mother-of-the-blessed-virgin & \cellcolor{lgreen}\textbf{ 27 } \footnotesize ef-time-after-pentecost-10-tuesday & \cellcolor{lred}\textbf{ 28 } \footnotesize sts-nazarius-celsus-st-victor-i-st-innocent-i & \cellcolor{lwhite}\textbf{ 29 } \footnotesize martha & \cellcolor{lgreen}\textbf{ 30 } \footnotesize ef-time-after-pentecost-10-friday & \cellcolor{lwhite}\textbf{ 31 } \footnotesize ignatius-loyola \\ \hline + +\end{tabular} +\newpage + +\section*{ Augustus 2027 } +\begin{tabular}{|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|} +\hline Dom & Lun & Mar & Mer & Iov & Ven & Sab \\ \hline +\cellcolor{lgreen}\textbf{ 1 } \footnotesize ef-time-after-pentecost-sunday-11 & \cellcolor{lwhite}\textbf{ 2 } \footnotesize alphonsus-liguori & \cellcolor{lgreen}\textbf{ 3 } \footnotesize ef-time-after-pentecost-11-tuesday & \cellcolor{lwhite}\textbf{ 4 } \footnotesize dominic & \cellcolor{lwhite}\textbf{ 5 } \footnotesize dedication-of-the-basilica-of-st-mary-major & \cellcolor{lwhite}\textbf{ 6 } \footnotesize transfiguration-of-our-lord & \cellcolor{lwhite}\textbf{ 7 } \footnotesize cajetan \\ \hline +\cellcolor{lgreen}\textbf{ 8 } \footnotesize ef-time-after-pentecost-sunday-12 & \cellcolor{lviolet}\textbf{ 9 } \footnotesize vigil-of-st-lawrence & \cellcolor{lred}\textbf{ 10 } \footnotesize lawrence & \cellcolor{lgreen}\textbf{ 11 } \footnotesize ef-time-after-pentecost-12-wednesday & \cellcolor{lwhite}\textbf{ 12 } \footnotesize clare & \cellcolor{lgreen}\textbf{ 13 } \footnotesize ef-time-after-pentecost-12-friday & \cellcolor{lviolet}\textbf{ 14 } \footnotesize vigil-of-the-assumption \\ \hline +\cellcolor{lwhite}\textbf{ 15 } \footnotesize assumption-of-the-blessed-virgin-mary & \cellcolor{lwhite}\textbf{ 16 } \footnotesize joachim-father-of-the-blessed-virgin & \cellcolor{lwhite}\textbf{ 17 } \footnotesize hyacinth & \cellcolor{lgreen}\textbf{ 18 } \footnotesize ef-time-after-pentecost-13-wednesday & \cellcolor{lwhite}\textbf{ 19 } \footnotesize john-eudes & \cellcolor{lwhite}\textbf{ 20 } \footnotesize bernard-of-clairvaux & \cellcolor{lwhite}\textbf{ 21 } \footnotesize jane-frances-de-chantal \\ \hline +\cellcolor{lgreen}\textbf{ 22 } \footnotesize ef-time-after-pentecost-sunday-14 & \cellcolor{lwhite}\textbf{ 23 } \footnotesize philip-benizi & \cellcolor{lred}\textbf{ 24 } \footnotesize bartholomew & \cellcolor{lwhite}\textbf{ 25 } \footnotesize louis-ix & \cellcolor{lgreen}\textbf{ 26 } \footnotesize ef-time-after-pentecost-14-thursday & \cellcolor{lwhite}\textbf{ 27 } \footnotesize joseph-calasance & \cellcolor{lwhite}\textbf{ 28 } \footnotesize augustine \\ \hline +\cellcolor{lgreen}\textbf{ 29 } \footnotesize ef-time-after-pentecost-sunday-15 & \cellcolor{lwhite}\textbf{ 30 } \footnotesize rose-of-lima & \cellcolor{lwhite}\textbf{ 31 } \footnotesize raymond-nonnatus & & & & \\ \hline + +\end{tabular} +\newpage + +\section*{ September 2027 } +\begin{tabular}{|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|} +\hline Dom & Lun & Mar & Mer & Iov & Ven & Sab \\ \hline + & & & \cellcolor{lgreen}\textbf{ 1 } \footnotesize ef-time-after-pentecost-15-wednesday & \cellcolor{lwhite}\textbf{ 2 } \footnotesize stephen-of-hungary & \cellcolor{lwhite}\textbf{ 3 } \footnotesize pius-x & \cellcolor{lwhite}\textbf{ 4 } \footnotesize Officium sanctae Mariae in sabbato \\ \hline +\cellcolor{lgreen}\textbf{ 5 } \footnotesize ef-time-after-pentecost-sunday-16 & \cellcolor{lgreen}\textbf{ 6 } \footnotesize ef-time-after-pentecost-16-monday & \cellcolor{lgreen}\textbf{ 7 } \footnotesize ef-time-after-pentecost-16-tuesday & \cellcolor{lwhite}\textbf{ 8 } \footnotesize nativity-of-the-blessed-virgin-mary & \cellcolor{lgreen}\textbf{ 9 } \footnotesize ef-time-after-pentecost-16-thursday & \cellcolor{lwhite}\textbf{ 10 } \footnotesize nicholas-of-tolentino & \cellcolor{lwhite}\textbf{ 11 } \footnotesize Officium sanctae Mariae in sabbato \\ \hline +\cellcolor{lgreen}\textbf{ 12 } \footnotesize ef-time-after-pentecost-sunday-17 & \cellcolor{lgreen}\textbf{ 13 } \footnotesize ef-time-after-pentecost-17-monday & \cellcolor{lred}\textbf{ 14 } \footnotesize exaltation-of-the-holy-cross & \cellcolor{lwhite}\textbf{ 15 } \footnotesize seven-sorrows-of-the-blessed-virgin-mary & \cellcolor{lred}\textbf{ 16 } \footnotesize sts-cornelius-cyprian & \cellcolor{lgreen}\textbf{ 17 } \footnotesize ef-time-after-pentecost-17-friday & \cellcolor{lwhite}\textbf{ 18 } \footnotesize joseph-of-cupertino \\ \hline +\cellcolor{lgreen}\textbf{ 19 } \footnotesize ef-time-after-pentecost-sunday-18 & \cellcolor{lgreen}\textbf{ 20 } \footnotesize ef-time-after-pentecost-18-monday & \cellcolor{lred}\textbf{ 21 } \footnotesize matthew & \cellcolor{lviolet}\textbf{ 22 } \footnotesize ef-september-ember-wed & \cellcolor{lred}\textbf{ 23 } \footnotesize linus & \cellcolor{lviolet}\textbf{ 24 } \footnotesize ef-september-ember-fri & \cellcolor{lviolet}\textbf{ 25 } \footnotesize ef-september-ember-sat \\ \hline +\cellcolor{lgreen}\textbf{ 26 } \footnotesize ef-time-after-pentecost-sunday-19 & \cellcolor{lred}\textbf{ 27 } \footnotesize sts-cosmas-damian & \cellcolor{lred}\textbf{ 28 } \footnotesize wenceslaus & \cellcolor{lwhite}\textbf{ 29 } \footnotesize dedication-of-st-michael-the-archangel & \cellcolor{lwhite}\textbf{ 30 } \footnotesize jerome & & \\ \hline + +\end{tabular} +\newpage + +\section*{ October 2027 } +\begin{tabular}{|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|} +\hline Dom & Lun & Mar & Mer & Iov & Ven & Sab \\ \hline + & & & & & \cellcolor{lgreen}\textbf{ 1 } \footnotesize ef-time-after-pentecost-19-friday & \cellcolor{lwhite}\textbf{ 2 } \footnotesize holy-guardian-angels \\ \hline +\cellcolor{lgreen}\textbf{ 3 } \footnotesize ef-time-after-pentecost-sunday-20 & \cellcolor{lwhite}\textbf{ 4 } \footnotesize francis-of-assisi & \cellcolor{lgreen}\textbf{ 5 } \footnotesize ef-time-after-pentecost-20-tuesday & \cellcolor{lwhite}\textbf{ 6 } \footnotesize bruno & \cellcolor{lwhite}\textbf{ 7 } \footnotesize our-lady-of-the-rosary & \cellcolor{lwhite}\textbf{ 8 } \footnotesize bridget-of-sweden & \cellcolor{lwhite}\textbf{ 9 } \footnotesize john-leonardi \\ \hline +\cellcolor{lgreen}\textbf{ 10 } \footnotesize ef-time-after-pentecost-sunday-21 & \cellcolor{lwhite}\textbf{ 11 } \footnotesize maternity-of-the-blessed-virgin-mary & \cellcolor{lgreen}\textbf{ 12 } \footnotesize ef-time-after-pentecost-21-tuesday & \cellcolor{lwhite}\textbf{ 13 } \footnotesize edward & \cellcolor{lred}\textbf{ 14 } \footnotesize callistus-i & \cellcolor{lwhite}\textbf{ 15 } \footnotesize teresa-of-avila & \cellcolor{lwhite}\textbf{ 16 } \footnotesize hedwig \\ \hline +\cellcolor{lgreen}\textbf{ 17 } \footnotesize ef-time-after-pentecost-sunday-22 & \cellcolor{lred}\textbf{ 18 } \footnotesize luke-the-evangelist & \cellcolor{lwhite}\textbf{ 19 } \footnotesize peter-of-alcantara & \cellcolor{lwhite}\textbf{ 20 } \footnotesize john-cantius & \cellcolor{lgreen}\textbf{ 21 } \footnotesize ef-time-after-pentecost-22-thursday & \cellcolor{lgreen}\textbf{ 22 } \footnotesize ef-time-after-pentecost-22-friday & \cellcolor{lwhite}\textbf{ 23 } \footnotesize anthony-mary-claret \\ \hline +\cellcolor{lgreen}\textbf{ 24 } \footnotesize ef-time-after-pentecost-sunday-23 & \cellcolor{lgreen}\textbf{ 25 } \footnotesize ef-time-after-pentecost-23-monday & \cellcolor{lgreen}\textbf{ 26 } \footnotesize ef-time-after-pentecost-23-tuesday & \cellcolor{lgreen}\textbf{ 27 } \footnotesize ef-time-after-pentecost-23-wednesday & \cellcolor{lred}\textbf{ 28 } \footnotesize sts-simon-jude & \cellcolor{lgreen}\textbf{ 29 } \footnotesize ef-time-after-pentecost-23-friday & \cellcolor{lwhite}\textbf{ 30 } \footnotesize Officium sanctae Mariae in sabbato \\ \hline +\cellcolor{lwhite}\textbf{ 31 } \footnotesize ef-christ-the-king & & & & & & \\ \hline + +\end{tabular} +\newpage + +\section*{ November 2027 } +\begin{tabular}{|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|} +\hline Dom & Lun & Mar & Mer & Iov & Ven & Sab \\ \hline + & \cellcolor{lwhite}\textbf{ 1 } \footnotesize all-saints & \cellcolor{lblack}\textbf{ 2 } \footnotesize commemoration-of-all-souls & \cellcolor{lgreen}\textbf{ 3 } \footnotesize ef-time-after-pentecost-24-wednesday & \cellcolor{lwhite}\textbf{ 4 } \footnotesize charles-borromeo & \cellcolor{lgreen}\textbf{ 5 } \footnotesize ef-time-after-pentecost-24-friday & \cellcolor{lwhite}\textbf{ 6 } \footnotesize Officium sanctae Mariae in sabbato \\ \hline +\cellcolor{lgreen}\textbf{ 7 } \footnotesize ef-time-after-epiphany-sunday-5 & \cellcolor{lgreen}\textbf{ 8 } \footnotesize ef-time-after-pentecost-25-monday & \cellcolor{lwhite}\textbf{ 9 } \footnotesize dedication-of-the-archbasilica-of-our-holy-savior & \cellcolor{lwhite}\textbf{ 10 } \footnotesize andrew-avellino & \cellcolor{lwhite}\textbf{ 11 } \footnotesize martin-of-tours & \cellcolor{lred}\textbf{ 12 } \footnotesize martin-i & \cellcolor{lwhite}\textbf{ 13 } \footnotesize didacus \\ \hline +\cellcolor{lgreen}\textbf{ 14 } \footnotesize ef-time-after-epiphany-sunday-6 & \cellcolor{lwhite}\textbf{ 15 } \footnotesize albert-the-great & \cellcolor{lwhite}\textbf{ 16 } \footnotesize gertrude-the-great & \cellcolor{lwhite}\textbf{ 17 } \footnotesize gregory-the-wonderworker & \cellcolor{lwhite}\textbf{ 18 } \footnotesize dedication-of-the-basilicas-of-sts-peter-paul & \cellcolor{lwhite}\textbf{ 19 } \footnotesize elizabeth-of-hungary & \cellcolor{lwhite}\textbf{ 20 } \footnotesize felix-of-valois \\ \hline +\cellcolor{lgreen}\textbf{ 21 } \footnotesize ef-time-after-pentecost-sunday-24 & \cellcolor{lred}\textbf{ 22 } \footnotesize cecilia & \cellcolor{lred}\textbf{ 23 } \footnotesize clement-i & \cellcolor{lwhite}\textbf{ 24 } \footnotesize john-of-the-cross & \cellcolor{lred}\textbf{ 25 } \footnotesize catherine-of-alexandria & \cellcolor{lwhite}\textbf{ 26 } \footnotesize sylvester & \cellcolor{lwhite}\textbf{ 27 } \footnotesize Officium sanctae Mariae in sabbato \\ \hline +\cellcolor{lviolet}\textbf{ 28 } \footnotesize ef-advent-sunday-1 & \cellcolor{lviolet}\textbf{ 29 } \footnotesize ef-advent-1-monday & \cellcolor{lred}\textbf{ 30 } \footnotesize andrew & & & & \\ \hline + +\end{tabular} +\newpage + +\section*{ December 2027 } +\begin{tabular}{|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|p{2.6cm}|} +\hline Dom & Lun & Mar & Mer & Iov & Ven & Sab \\ \hline + & & & \cellcolor{lviolet}\textbf{ 1 } \footnotesize ef-advent-1-wednesday & \cellcolor{lred}\textbf{ 2 } \footnotesize vivian & \cellcolor{lwhite}\textbf{ 3 } \footnotesize francis-xavier & \cellcolor{lwhite}\textbf{ 4 } \footnotesize peter-chrysologus \\ \hline +\cellcolor{lviolet}\textbf{ 5 } \footnotesize ef-advent-sunday-2 & \cellcolor{lwhite}\textbf{ 6 } \footnotesize nicholas & \cellcolor{lwhite}\textbf{ 7 } \footnotesize ambrose & \cellcolor{lwhite}\textbf{ 8 } \footnotesize immaculate-conception-of-the-blessed-virgin-mary & \cellcolor{lviolet}\textbf{ 9 } \footnotesize ef-advent-2-thursday & \cellcolor{lviolet}\textbf{ 10 } \footnotesize ef-advent-2-friday & \cellcolor{lwhite}\textbf{ 11 } \footnotesize damasus-i \\ \hline +\cellcolor{lrose}\textbf{ 12 } \footnotesize ef-advent-sunday-3 & \cellcolor{lred}\textbf{ 13 } \footnotesize lucy & \cellcolor{lviolet}\textbf{ 14 } \footnotesize ef-advent-3-tuesday & \cellcolor{lviolet}\textbf{ 15 } \footnotesize ef-advent-ember-wed & \cellcolor{lred}\textbf{ 16 } \footnotesize eusebius & \cellcolor{lviolet}\textbf{ 17 } \footnotesize ef-advent-ember-fri & \cellcolor{lviolet}\textbf{ 18 } \footnotesize ef-advent-ember-sat \\ \hline +\cellcolor{lviolet}\textbf{ 19 } \footnotesize ef-advent-sunday-4 & \cellcolor{lviolet}\textbf{ 20 } \footnotesize ef-advent-4-monday & \cellcolor{lred}\textbf{ 21 } \footnotesize thomas & \cellcolor{lviolet}\textbf{ 22 } \footnotesize ef-advent-4-wednesday & \cellcolor{lviolet}\textbf{ 23 } \footnotesize ef-advent-4-thursday & \cellcolor{lviolet}\textbf{ 24 } \footnotesize ef-nativity-vigil & \cellcolor{lwhite}\textbf{ 25 } \footnotesize ef-nativity \\ \hline +\cellcolor{lwhite}\textbf{ 26 } \footnotesize ef-christmas-sunday-0 & \cellcolor{lwhite}\textbf{ 27 } \footnotesize john-the-evangelist & \cellcolor{lred}\textbf{ 28 } \footnotesize holy-innocents & \cellcolor{lwhite}\textbf{ 29 } \footnotesize ef-nativity-octave-day-5 & \cellcolor{lwhite}\textbf{ 30 } \footnotesize ef-nativity-octave-day-6 & \cellcolor{lwhite}\textbf{ 31 } \footnotesize ef-nativity-octave-day-7 & \\ \hline + +\end{tabular} +\newpage + +\end{document} diff --git a/test/golden/ordo-2027.adoc b/test/golden/ordo-2027.adoc new file mode 100644 index 0000000..5a8e2f5 --- /dev/null +++ b/test/golden/ordo-2027.adoc @@ -0,0 +1,2365 @@ +// colitur ordo booklet -- AsciiDoc. flavour: none (see man colitur-overlay) +// AsciiDoc's own metacharacters (*, _, +, `, ...) are context-dependent, so +// this template's flavour deliberately does NOT escape interpolated values. +// A feast name containing `*` or `_` will render as emphasis. That is a +// documented limitation, not a bug to fix. +// +// Day label falls back to the slug when the day carries no Latin name (most +// temporal days, and most sanctoral entries, which are Latin-less in the +// shipped data) -- see ordo.tex's own comment for why the fallback is +// written as a name-section wrapping a plain var and its inverse, rather +// than a single dotted lookup and its inverse. += Ordo 2027 · ef +:toc: + + +== Ianuarius + + +*1* ef-circumcision + +class-1 · white + +Ep. Titus 2:11-15 Ev. Luke 2:21 + + + +*2* Officium sanctae Mariae in sabbato + +class-4 · white + +Ep. Titus 3:4-7 Ev. Luke 2:15-20 + + + +*3* Sanctissimi Nominis Iesu + +class-2 · white + +Ep. Acts 4:8-12 Ev. Luke 2:21 + + + +*4* ef-christmas-1-monday + +class-4 · white + +Ep. Titus 2:11-15 Ev. Luke 2:21 + + + +*5* ef-christmas-1-tuesday + +class-4 · white + +Ep. Titus 2:11-15 Ev. Luke 2:21 + + +Com. telesphorus-pope-and-martyr + + +*6* ef-epiphany + +class-1 · white + +Ep. Isa 60:1-6 Ev. Matt 2:1-12 + + + +*7* ef-christmas-2-thursday + +class-4 · white + +Ep. Isa 60:1-6 Ev. Matt 2:1-12 + + + +*8* ef-christmas-2-friday + +class-4 · white + +Ep. Isa 60:1-6 Ev. Matt 2:1-12 + + + +*9* Officium sanctae Mariae in sabbato + +class-4 · white + +Ep. Titus 3:4-7 Ev. Luke 2:15-20 + + + +*10* Sanctae Familiae Iesu, Mariae, Ioseph + +class-2 · white + +Ep. Col 3:12-17 Ev. Luke 2:42-52 + + + +*11* ef-time-after-epiphany-1-monday + +class-4 · white + +Ep. Rom 12:1-5 Ev. Luke 2:42-52 + + +Com. hyginus-pope-and-martyr + + +*12* ef-time-after-epiphany-1-tuesday + +class-4 · white + +Ep. Rom 12:1-5 Ev. Luke 2:42-52 + + + +*13* commemoration-of-the-baptism-of-the-lord + +class-2 · white + +Ep. Isa 60:1-6 Ev. John 1:29-34 + + + +*14* hilary + +class-3 · white + +Ep. 2 Tim 4:1-8 Ev. Matt 5:13-19 + + +Com. felicis + + +*15* paul-the-first-hermit + +class-3 · white + +Ep. Phil 3:7-12 Ev. Matt 11:25-30 + + +Com. maur-abbot + + +*16* marcellus-i + +class-3 · red + +Ep. 1 Pet 5:1-4; 5:10-11. Ev. Matt 16:13-19 + + + +*17* ef-time-after-epiphany-sunday-2 + +class-2 · green + +Ep. Rom 12:6-16 Ev. John 2:1-11 + + + +*18* ef-time-after-epiphany-2-monday + +class-4 · green + +Ep. Rom 12:6-16 Ev. John 2:1-11 + + +Com. prisca + + +*19* ef-time-after-epiphany-2-tuesday + +class-4 · green + +Ep. Rom 12:6-16 Ev. John 2:1-11 + + +Com. canute-martyr + +Com. sts-marius-martha-audifax-abachum + + +*20* sts-fabian-sebastian + +class-3 · red + +Ep. Heb 11:33-39 Ev. Luke 6:17-23 + + + +*21* agnes + +class-3 · red + +Ep. Sir 51:1-8; 51:12 Ev. Matt 25:1-13. + + + +*22* sts-vincent-anastasius + +class-3 · red + +Ep. Wis 3:1-8 Ev. Luke 21:9-19 + + + +*23* raymond-of-pe-afort + +class-3 · white + +Ep. Sir 31:8-11 Ev. Luke 12:35-40 + + +Com. emerentiana + + +*24* ef-septuagesima-sunday-1 + +class-2 · violet + +Ep. 1 Cor. 9:24-27; 10:1-5 Ev. Matt 20:1-16 + + + +*25* conversion-of-st-paul + +class-3 · white + +Ep. Acts 9:1-22 Ev. Matt 19:27-29. + + +Com. peter + + +*26* polycarp + +class-3 · red + +Ep. 1 John 3:10-16 Ev. Matt 10:26-32. + + + +*27* john-chrysostom + +class-3 · white + +Ep. 2 Tim 4:1-8 Ev. Matt 5:13-19 + + + +*28* peter-nolasco + +class-3 · white + +Ep. 1 Cor. 4:9-14 Ev. Luke 12:32-34 + + +Com. agnes-secundo + + +*29* francis-de-sales + +class-3 · white + +Ep. 2 Tim 4:1-8 Ev. Matt 5:13-19 + + + +*30* martina + +class-3 · red + +Ep. Sir 51:1-8; 51:12 Ev. Matt 25:1-13. + + + +*31* ef-septuagesima-sunday-2 + +class-2 · violet + +Ep. 2 Cor. 11:19-33; 12:1-9 Ev. Luke 8:4-15 + + + +== Februarius + + +*1* ignatius-of-antioch + +class-3 · red + +Ep. Rom 8:35-39 Ev. John 12:24-26 + + + +*2* purification-of-the-blessed-virgin-mary + +class-2 · white + +Ep. Mal 3:1-4 Ev. Luke 2:22-32 + + + +*3* ef-septuagesima-2-wednesday + +class-4 · violet + +Ep. 2 Cor. 11:19-33; 12:1-9 Ev. Luke 8:4-15 + + +Com. blaise + + +*4* andrew-corsini + +class-3 · white + +Ep. Sir 44:16-27; 45:3-20 Ev. Matt 25:14-23 + + + +*5* agatha + +class-3 · red + +Ep. 1 Cor. 1:26-31 Ev. Matt 19:3-12. + + + +*6* titus + +class-3 · white + +Ep. Sir 44:16-27; 45:3-20 Ev. Luke 10:1-9 + + +Com. dorothy + + +*7* ef-septuagesima-sunday-3 + +class-2 · violet + +Ep. 1 Cor. 13:1-13 Ev. Luke 18:31-43 + + + +*8* john-of-matha + +class-3 · white + +Ep. Sir 31:8-11 Ev. Luke 12:35-40 + + + +*9* cyril-of-alexandria + +class-3 · white + +Ep. 2 Tim 4:1-8 Ev. Matt 5:13-19 + + +Com. appollonia + + +*10* ef-ash-wednesday + +class-1 · violet + +Ep. Joel 2:12-19 Ev. Matt 6:16-21 + + + +*11* ef-lent-after-ashes-thursday + +class-3 · violet + +Ep. Isa 38:1-6 Ev. Matt 8:5-13 + + +Com. our-lady-of-lourdes + + +*12* ef-lent-after-ashes-friday + +class-3 · violet + +Ep. Isa 58:1-9 Ev. Matt 5:43-48; 6:1-4 + + +Com. seven-holy-servite-founders + + +*13* ef-lent-after-ashes-saturday + +class-3 · violet + +Ep. Isa 58:9-14 Ev. Mark 6:47-56 + + + +*14* ef-lent-sunday-1 + +class-1 · violet + +Ep. 2 Cor. 6:1-10 Ev. Matt 4:1-11 + + + +*15* ef-lent-1-monday + +class-3 · violet + +Ep. Ezech 34:11-16 Ev. Matt 25:31-46 + + +Com. sts-faustinus-jovita + + +*16* ef-lent-1-tuesday + +class-3 · violet + +Ep. Isa 55:6-11 Ev. Matt 21:10-17 + + + +*17* ef-lent-ember-wed + +class-2 · violet + +Ep. 3 Kgs. 19:3-8 Ev. Matt 12:38-50 + + + +*18* ef-lent-1-thursday + +class-3 · violet + +Ep. Ezech 18:1-9 Ev. Matt 15:21-28 + + +Com. simeon + + +*19* ef-lent-ember-fri + +class-2 · violet + +Ep. Ezech 18:20-28 Ev. John 5:1-15 + + + +*20* ef-lent-ember-sat + +class-2 · violet + +Ep. 1 Thess. 5:14-23 Ev. Matt 17:1-9 + + + +*21* ef-lent-sunday-2 + +class-1 · violet + +Ep. 1 Thess. 4:1-7 Ev. Matt 17:1-9 + + + +*22* chair-of-st-peter + +class-2 · white + +Ep. 1 Pet 1:1-7 Ev. Matt 16:13-19 + + +Com. ef-lent-2-monday + +Com. paul + + +*23* ef-lent-2-tuesday + +class-3 · violet + +Ep. 3 Kings 17:8-16 Ev. Matt 23:1-12 + + +Com. peter-damien + + +*24* matthias + +class-2 · red + +Ep. Acts 1:15-26 Ev. Matt 11:25-30 + + +Com. ef-lent-2-wednesday + + +*25* ef-lent-2-thursday + +class-3 · violet + +Ep. Jer 17:5-10 Ev. Luke 16:19-31 + + + +*26* ef-lent-2-friday + +class-3 · violet + +Ep. Gen 37:6-22 Ev. Matt 21:33-46 + + + +*27* ef-lent-2-saturday + +class-3 · violet + +Ep. Gen 27:6-40 Ev. Luke 15:11-32 + + +Com. gabriel-of-our-lady-of-sorrows + + +*28* ef-lent-sunday-3 + +class-1 · violet + +Ep. Eph 5:1-9 Ev. Luke 11:14-28 + + + +== Martius + + +*1* ef-lent-3-monday + +class-3 · violet + +Ep. 4 Kings 5:1-15 Ev. Luke 4:23-30 + + + +*2* ef-lent-3-tuesday + +class-3 · violet + +Ep. 4 Kings 4:1-7 Ev. Matt 18:15-22 + + + +*3* ef-lent-3-wednesday + +class-3 · violet + +Ep. Ex 20:12-24 Ev. Matt 15:1-20 + + + +*4* ef-lent-3-thursday + +class-3 · violet + +Ep. Jer 7:1-7 Ev. Luke 4:38-44. + + +Com. casimir + +Com. lucius + + +*5* ef-lent-3-friday + +class-3 · violet + +Ep. Num 20:1, 3; 6-13. Ev. John 4:5-42 + + + +*6* ef-lent-3-saturday + +class-3 · violet + +Ep. Dan 13:1-9, 15-17, 19-30, 33-62. Ev. John 8:1-11 + + +Com. sts-felicitas-perpetua + + +*7* ef-lent-sunday-4 + +class-1 · rose + +Ep. Gal 4:22-31 Ev. John 6:1-15 + + + +*8* ef-lent-4-monday + +class-3 · violet + +Ep. 3 Kings 3:16-28 Ev. John 2:13-25 + + +Com. john-of-god + + +*9* ef-lent-4-tuesday + +class-3 · violet + +Ep. Ex 32:7-14 Ev. John 7:14-31 + + +Com. frances-rome + + +*10* ef-lent-4-wednesday + +class-3 · violet + +Ep. Isa. 1:16-19 Ev. John 9:1-38 + + +Com. forty-holy-martyrs-of-sebaste + + +*11* ef-lent-4-thursday + +class-3 · violet + +Ep. 4 Kings 4:25-38 Ev. Luke 7:11-16 + + + +*12* ef-lent-4-friday + +class-3 · violet + +Ep. 3 Kings 17:17-24 Ev. John 11:1-45 + + +Com. gregory-the-great + + +*13* ef-lent-4-saturday + +class-3 · violet + +Ep. Isa 49:8-15 Ev. John 8:12-20 + + + +*14* ef-passion-sunday + +class-1 · violet + +Ep. Heb 9:11-15. Ev. John 8:46-59. + + + +*15* ef-passiontide-1-monday + +class-3 · violet + +Ep. Jonas 3:1-10 Ev. John 7:32-39 + + + +*16* ef-passiontide-1-tuesday + +class-3 · violet + +Ep. Dan 14:27, 28-42 Ev. John 7:1-13 + + + +*17* ef-passiontide-1-wednesday + +class-3 · violet + +Ep. Lev 19:1-2, 11-19, 25 Ev. John 10:22-38 + + +Com. patrick + + +*18* ef-passiontide-1-thursday + +class-3 · violet + +Ep. Dan 3:25, 34-45. Ev. Luke 7:36-50 + + +Com. cyril-of-jerusalem + + +*19* joseph-spouse-of-the-bl-virgin-mary + +class-1 · white + +Ep. Ecclus 45:1-6 Ev. Matt 1:18-21 + + +Com. ef-passiontide-1-friday + + +*20* ef-passiontide-1-saturday + +class-3 · violet + +Ep. Jer 18:18-23 Ev. John 12:10-36 + + + +*21* ef-palm-sunday + +class-1 · violet + +Ep. Phil 2:5-11 Ev. Matt. 26:36-75; 27:1-60. + + + +*22* ef-passiontide-2-monday + +class-1 · violet + +Ep. Isa 50:5-10 Ev. John 12:1-9 + + + +*23* ef-passiontide-2-tuesday + +class-1 · violet + +Ep. Jer 11:18-20 Ev. Mark 14:32-72; 15, 1-46 + + + +*24* ef-passiontide-2-wednesday + +class-1 · violet + +Ep. Isa 53:1-12 Ev. Luke 22:39-71; 23:1-53 + + + +*25* Feria V in Cena Domini + +class-1 · white + +Ep. 1 Cor 11:20-32 Ev. John 13:1-15 + + + +*26* Feria VI in Passione et Morte Domini + +class-1 · black + +Ep. Ex 12:1-11 Ev. John 18:1-40; 19:1-42 + + + +*27* Sabbato sancto + +class-1 · violet + +Ep. Col 3:1-4 Ev. Matt 28:1-7 + + + +*28* ef-easter-sunday + +class-1 · white + +Ep. 1 Cor 5:7-8 Ev. Mark 16:1-7 + + + +*29* ef-easter-1-monday + +class-1 · white + +Ep. Acts 10:37-43. Ev. Luke 24:13-35 + + + +*30* ef-easter-1-tuesday + +class-1 · white + +Ep. Acts 13:16; 13:26-33 Ev. Luke 24:36-47 + + + +*31* ef-easter-1-wednesday + +class-1 · white + +Ep. Acts 3:13-15; 3:17-19 Ev. John 21:1-14 + + + +== Aprilis + + +*1* ef-easter-1-thursday + +class-1 · white + +Ep. Acts 8:26-40 Ev. John 20:11-18 + + + +*2* ef-easter-1-friday + +class-1 · white + +Ep. 1 Pet 3:18-22 Ev. Matt 28:16-20 + + + +*3* ef-easter-1-saturday + +class-1 · white + +Ep. 1 Pet 2:1-10 Ev. John 20:1-9 + + + +*4* ef-low-sunday + +class-1 · white + +Ep. 1 John 5:4-10 Ev. John 20:19-31 + + + +*5* annunciation-of-the-blessed-virgin-mary + +class-1 · white + +Ep. Isa 7:10-15 Ev. Luke 1:26-38 + + + +*6* ef-easter-2-tuesday + +class-4 · white + +Ep. 1 John 5:4-10 Ev. John 20:19-31 + + + +*7* ef-easter-2-wednesday + +class-4 · white + +Ep. 1 John 5:4-10 Ev. John 20:19-31 + + + +*8* ef-easter-2-thursday + +class-4 · white + +Ep. 1 John 5:4-10 Ev. John 20:19-31 + + + +*9* ef-easter-2-friday + +class-4 · white + +Ep. 1 John 5:4-10 Ev. John 20:19-31 + + + +*10* Officium sanctae Mariae in sabbato + +class-4 · white + +Ep. Ecclus 24:14-16 Ev. John 19:25-27 + + + +*11* ef-easter-sunday-3 + +class-2 · white + +Ep. 1 Pet 2:21-25 Ev. John 10:11-16 + + + +*12* ef-easter-3-monday + +class-4 · white + +Ep. 1 Pet 2:21-25 Ev. John 10:11-16 + + + +*13* hermenegild + +class-3 · red + +Ep. Wis 10:10-14 Ev. Luke 14:26-33. + + + +*14* justin + +class-3 · red + +Ep. 1 Cor 1:18-25; 1:30; Ev. Luke 12:2-8 + + +Com. sts-tiburtius-valerian-et-maximus-martyrs + + +*15* ef-easter-3-thursday + +class-4 · white + +Ep. 1 Pet 2:21-25 Ev. John 10:11-16 + + + +*16* ef-easter-3-friday + +class-4 · white + +Ep. 1 Pet 2:21-25 Ev. John 10:11-16 + + + +*17* Officium sanctae Mariae in sabbato + +class-4 · white + +Ep. Ecclus 24:14-16 Ev. John 19:25-27 + + +Com. anicetus + + +*18* ef-easter-sunday-4 + +class-2 · white + +Ep. 1 Pet 2:11-19 Ev. John 16:16-22 + + + +*19* ef-easter-4-monday + +class-4 · white + +Ep. 1 Pet 2:11-19 Ev. John 16:16-22 + + + +*20* ef-easter-4-tuesday + +class-4 · white + +Ep. 1 Pet 2:11-19 Ev. John 16:16-22 + + + +*21* anselm + +class-3 · white + +Ep. 2 Tim 4:1-8 Ev. Matt 5:13-19 + + + +*22* sts-soter-caius + +class-3 · red + +Ep. 1 Pet 5:1-4; 5:10-11. Ev. Matt 16:13-19 + + + +*23* ef-easter-4-friday + +class-4 · white + +Ep. 1 Pet 2:11-19 Ev. John 16:16-22 + + +Com. george + + +*24* fidelis-of-sigmaringen + +class-3 · red + +Ep. Wis 5:1-5 Ev. John 15:1-7 + + + +*25* ef-easter-sunday-5 + +class-2 · white + +Ep. Jas 1:17-21 Ev. John 16:5-14 + + +Com. major-litanies + + +*26* sts-cletus-marcellinus + +class-3 · red + +Ep. 1 Pet 5:1-4; 5:10-11. Ev. Matt 16:13-19 + + + +*27* peter-canisius + +class-3 · white + +Ep. 2 Tim 4:1-8 Ev. Matt 5:13-19 + + + +*28* paul-of-the-cross + +class-3 · white + +Ep. 1 Cor 1:17-25. Ev. Luke 10:1-9 + + + +*29* peter-of-verona + +class-3 · red + +Ep. 2 Tim. 2:8-10; 3:10-12. Ev. Matt 10:34-42 + + + +*30* catherine-of-siena + +class-3 · white + +Ep. 2 Cor 10:17-18; 11:1-2 Ev. Matt 25:1-13. + + + +== Maius + + +*1* joseph-the-workman + +class-1 · white + +Ep. Col. 3:14-15, 17, 23-24 Ev. Matt 13:54-58 + + + +*2* ef-easter-sunday-6 + +class-2 · white + +Ep. Jas 1:22-27 Ev. John 16:23-30 + + + +*3* ef-rogation-monday + +class-4 · violet + +Ep. Jas 1:22-27 Ev. John 16:23-30 + + +Com. sts-alexander-companions + + +*4* monica + +class-3 · white + +Ep. 1 Tim. 5:3-10. Ev. Luke 7:11-16 + + + +*5* ef-ascension-vigil + +class-2 · white + +Ep. Eph. 4:7-13. Ev. John 17:1-11. + + +Com. pius-v + + +*6* ef-ascension + +class-1 · white + +Ep. Acts 1:1-11 Ev. Mark 16:14-20 + + + +*7* stanislaus + +class-3 · red + +Ep. Wis 5:1-5 Ev. John 15:1-7 + + + +*8* Officium sanctae Mariae in sabbato + +class-4 · white + +Ep. Ecclus 24:14-16 Ev. John 19:25-27 + + + +*9* ef-easter-sunday-7 + +class-2 · white + +Ep. 1 Pet 4:7-11. Ev. John 15:26-27; 16:1-4. + + + +*10* antoninus + +class-3 · white + +Ep. Sir 44:16-27; 45:3-20 Ev. Matt 25:14-23 + + +Com. gordiano-and-epimacho + + +*11* sts-philip-james + +class-2 · red + +Ep. Wis. 5:1-5 Ev. John 14:1-13 + + + +*12* sts-nereus-achilleus-domitilla-pancras + +class-3 · red + +Ep. Wis. 5:1-5 Ev. John 4:46-53 + + + +*13* robert-bellarmine + +class-3 · white + +Ep. Wis 7:7-14. Ev. Matt 5:13-19 + + + +*14* ef-easter-7-friday + +class-4 · white + +Ep. 1 Pet 4:7-11. Ev. John 15:26-27; 16:1-4. + + +Com. boniface-martyr + + +*15* ef-pentecost-vigil + +class-1 · red + +Ep. Acts 19:1-8. Ev. John 14:15-21. + + + +*16* ef-pentecost + +class-1 · red + +Ep. Acts 2:1-11. Ev. John 14:23-31. + + + +*17* ef-easter-8-monday + +class-1 · red + +Ep. Acts 10:34, 42-48 Ev. John 3:16-21 + + + +*18* ef-easter-8-tuesday + +class-1 · red + +Ep. Acts 8:14-17. Ev. John 10:1-10. + + + +*19* ef-pentecost-ember-wed + +class-1 · red + +Ep. Acts 5:12-16 Ev. John 6:44-52. + + + +*20* ef-easter-8-thursday + +class-1 · red + +Ep. Acts 8:5-8 Ev. Luke 9:1-6 + + + +*21* ef-pentecost-ember-fri + +class-1 · red + +Ep. Joel 2:23-24; 26-27 Ev. Luke 5:17-26 + + + +*22* ef-pentecost-ember-sat + +class-1 · red + +Ep. Rom 5:1-5. Ev. Luke 4:38-44. + + + +*23* ef-trinity + +class-1 · white + +Ep. Rom 11:33-36. Ev. Matt 28:18-20 + + + +*24* ef-time-after-pentecost-1-monday + +class-4 · green + +Ep. 1 John 4:8-21 Ev. Luke 6:36-42 + + + +*25* gregory-vii + +class-3 · white + +Ep. 1 Pet 5:1-4; 5:10-11. Ev. Matt 16:13-19 + + +Com. urban-pope-and-martyr + + +*26* philip-neri + +class-3 · white + +Ep. Wis 7:7-14. Ev. Luke 12:35-40 + + +Com. eleutherius + + +*27* ef-corpus-christi + +class-1 · white + +Ep. 1 Cor 11:23-29 Ev. John 6:56-59 + + + +*28* augustine-of-canterbury + +class-3 · white + +Ep. 1 Thess 2:2-9 Ev. Luke 10:1-9 + + + +*29* mary-magdalene-de-pazzi + +class-3 · white + +Ep. 2 Cor 10:17-18; 11:1-2 Ev. Matt 25:1-13. + + + +*30* ef-time-after-pentecost-sunday-2 + +class-2 · green + +Ep. 1 John 3:13-18. Ev. Luke 14:16-24. + + + +*31* queenship-of-the-blessed-virgin-mary + +class-2 · white + +Ep. Eccli 24:5; 14:7; 14:9-11; 24:30-31 Ev. Luke 1:26-33 + + +Com. petronilla + + +== Iunius + + +*1* angela-merici + +class-3 · white + +Ep. 2 Cor 10:17-18; 11:1-2 Ev. Matt 25:1-13. + + + +*2* ef-time-after-pentecost-2-wednesday + +class-4 · green + +Ep. 1 John 3:13-18. Ev. Luke 14:16-24. + + +Com. sts-marcellinus-peter-erasmus + + +*3* ef-time-after-pentecost-2-thursday + +class-4 · green + +Ep. 1 John 3:13-18. Ev. Luke 14:16-24. + + + +*4* ef-sacred-heart + +class-1 · white + +Ep. Eph 3:8-12, 14-19 Ev. John 19:31-37 + + + +*5* boniface + +class-3 · red + +Ep. Ecclus 44:1-15 Ev. Matt 5:1-12 + + + +*6* ef-time-after-pentecost-sunday-3 + +class-2 · green + +Ep. 1 Pet. 5:6-11 Ev. Luke 15:1-10 + + + +*7* ef-time-after-pentecost-3-monday + +class-4 · green + +Ep. 1 Pet. 5:6-11 Ev. Luke 15:1-10 + + + +*8* ef-time-after-pentecost-3-tuesday + +class-4 · green + +Ep. 1 Pet. 5:6-11 Ev. Luke 15:1-10 + + + +*9* ef-time-after-pentecost-3-wednesday + +class-4 · green + +Ep. 1 Pet. 5:6-11 Ev. Luke 15:1-10 + + +Com. sts-primus-felicianus + + +*10* margaret-of-scotland + +class-3 · white + +Ep. Prov 31:10-31 Ev. Matt 13:44-52. + + + +*11* barnabas + +class-3 · red + +Ep. Acts 11:21-26; 13:1-3 Ev. Matt 10:16-22 + + + +*12* john-of-san-fecundo + +class-3 · white + +Ep. Sir 31:8-11 Ev. Luke 12:35-40 + + +Com. basilidus + + +*13* ef-time-after-pentecost-sunday-4 + +class-2 · green + +Ep. Rom 8:18-23 Ev. Luke 5:1-11 + + + +*14* basil-the-great + +class-3 · white + +Ep. 2 Tim 4:1-8 Ev. Luke 14:26-35 + + + +*15* ef-time-after-pentecost-4-tuesday + +class-4 · green + +Ep. Rom 8:18-23 Ev. Luke 5:1-11 + + +Com. vitus + + +*16* ef-time-after-pentecost-4-wednesday + +class-4 · green + +Ep. Rom 8:18-23 Ev. Luke 5:1-11 + + + +*17* gregory-barbarigo + +class-3 · white + +Ep. Sir 44:16-27; 45:3-20 Ev. Matt 25:14-23 + + + +*18* ephrem-of-syria + +class-3 · white + +Ep. 2 Tim 4:1-8 Ev. Matt 5:13-19 + + +Com. marcus-and-marcellianus + + +*19* julia-of-falconieri + +class-3 · white + +Ep. 2 Cor 10:17-18; 11:1-2 Ev. Matt 25:1-13. + + +Com. sts-gervasius-and-protasius + + +*20* ef-time-after-pentecost-sunday-5 + +class-2 · green + +Ep. 1 Pet 3:8-15. Ev. Matt 5:20-24. + + + +*21* aloysius-gongzaga + +class-3 · white + +Ep. Sir 31:8-11 Ev. Matt 22:29-40 + + + +*22* paulinus-of-nola + +class-3 · white + +Ep. 2 Cor. 8:9-15 Ev. Luke 12:32-34 + + + +*23* vigil-of-the-nativity-of-st-john-the-baptist + +class-2 · violet + +Ep. Jer 1:4-10 Ev. Luke 1:5-17 + + + +*24* nativity-of-st-john-the-baptist + +class-1 · white + +Ep. Isa 49:1-3, 5-7. Ev. Luke 1:57-68 + + + +*25* william + +class-3 · white + +Ep. Ecclus 45:1-6 Ev. Matt 19:27-29. + + + +*26* sts-john-paul + +class-3 · red + +Ep. Eccli 44:10-15 Ev. Luke 12:1-8 + + + +*27* ef-time-after-pentecost-sunday-6 + +class-2 · green + +Ep. Rom 6:3-11. Ev. Mark 8:1-9 + + + +*28* vigil-of-sts-peter-paul + +class-2 · violet + +Ep. Acts 3:1-10 Ev. John 21:15-19 + + + +*29* sts-peter-paul + +class-1 · red + +Ep. Acts 12:1-11 Ev. Matt 16:13-19 + + + +*30* in-commemoratione-sancti-pauli-apostoli + +class-3 · red + +Ep. Gal 1:11-20 Ev. Matt 10:16-22 + + +Com. commemoration-of-st-peter + + +== Iulius + + +*1* precious-blood-of-our-lord-jesus-christ + +class-1 · red + +Ep. Heb 9:11-15. Ev. John 19:30-35 + + + +*2* visitation-of-the-blessed-virgin-mary + +class-2 · white + +Ep. Song 2:8-14 Ev. Luke 1:39-47 + + +Com. processus-and-martinian + + +*3* irenaeus + +class-3 · red + +Ep. 2 Tim. 3:14-17; 4:1-5 Ev. Matt 10:28-33 + + + +*4* ef-time-after-pentecost-sunday-7 + +class-2 · green + +Ep. Rom 6:19-23 Ev. Matt 7:15-21 + + + +*5* anthony-mary-zaccariah + +class-3 · white + +Ep. 1 Tim. 4:8-16 Ev. Mark 10:15-21 + + + +*6* ef-time-after-pentecost-7-tuesday + +class-4 · green + +Ep. Rom 6:19-23 Ev. Matt 7:15-21 + + + +*7* sts-cyril-methodius + +class-3 · white + +Ep. Heb 7:23-27 Ev. Luke 10:1-9 + + + +*8* elizabeth-of-portugal + +class-3 · white + +Ep. Prov 31:10-31 Ev. Matt 13:44-52. + + + +*9* ef-time-after-pentecost-7-friday + +class-4 · green + +Ep. Rom 6:19-23 Ev. Matt 7:15-21 + + + +*10* seven-holy-brothers-and-sts-rufina-secunda + +class-3 · red + +Ep. Prov 31:10-31 Ev. Matt 12:46-50 + + + +*11* ef-time-after-pentecost-sunday-8 + +class-2 · green + +Ep. Rom 8:12-17 Ev. Luke 16:1-9 + + + +*12* john-gualbert + +class-3 · white + +Ep. Ecclus 45:1-6 Ev. Matt 5:43-48 + + +Com. naboris-et-felicis + + +*13* ef-time-after-pentecost-8-tuesday + +class-4 · green + +Ep. Rom 8:12-17 Ev. Luke 16:1-9 + + + +*14* bonaventure + +class-3 · white + +Ep. 2 Tim 4:1-8 Ev. Matt 5:13-19 + + + +*15* henry-the-emperor + +class-3 · white + +Ep. Sir 31:8-11 Ev. Luke 12:35-40 + + + +*16* ef-time-after-pentecost-8-friday + +class-4 · green + +Ep. Rom 8:12-17 Ev. Luke 16:1-9 + + +Com. our-lady-of-mt-carmel + + +*17* Officium sanctae Mariae in sabbato + +class-4 · white + +Ep. Ecclus 24:14-16 Ev. Luke 11:27-28 + + +Com. alexis + + +*18* ef-time-after-pentecost-sunday-9 + +class-2 · green + +Ep. 1 Cor. 10:6-13 Ev. Luke 19:41-47 + + + +*19* vincent-de-paul + +class-3 · white + +Ep. 1 Cor. 4:9-14 Ev. Luke 10:1-9 + + + +*20* jerome-emiliani + +class-3 · white + +Ep. Isa 58:7-11 Ev. Matt 19:13-21 + + +Com. margaret + + +*21* laurence-of-brindisi + +class-3 · white + +Ep. 2 Tim 4:1-8 Ev. Matt 5:13-19 + + +Com. praxedis-virginis + + +*22* mary-magdalene + +class-3 · white + +Ep. Song 3:2-5; 8:6-7 Ev. Luke 7:36-50 + + + +*23* apollinaris + +class-3 · red + +Ep. 1 Pet. 5:1-11 Ev. Luke 22:24-30 + + +Com. liborii + + +*24* Officium sanctae Mariae in sabbato + +class-4 · white + +Ep. Ecclus 24:14-16 Ev. Luke 11:27-28 + + +Com. christina + + +*25* ef-time-after-pentecost-sunday-10 + +class-2 · green + +Ep. 1 Cor. 12:2-11 Ev. Luke 18:9-14 + + +Com. james-the-greater + + +*26* anne-mother-of-the-blessed-virgin + +class-2 · white + +Ep. Prov 31:10-31 Ev. Matt 13:44-52. + + + +*27* ef-time-after-pentecost-10-tuesday + +class-4 · green + +Ep. 1 Cor. 12:2-11 Ev. Luke 18:9-14 + + +Com. pantaleon + + +*28* sts-nazarius-celsus-st-victor-i-st-innocent-i + +class-3 · red + +Ep. Wis 10:17-20 Ev. Luke 21:9-19 + + + +*29* martha + +class-3 · white + +Ep. 2 Cor 10:17-18; 11:1-2 Ev. Luke 10:38-42 + + +Com. felicis-simplicii-faustini-et-beatricis + + +*30* ef-time-after-pentecost-10-friday + +class-4 · green + +Ep. 1 Cor. 12:2-11 Ev. Luke 18:9-14 + + +Com. sts-abdon-sennen + + +*31* ignatius-loyola + +class-3 · white + +Ep. 2 Tim. 2:8-10; 3:10-12. Ev. Luke 10:1-9 + + + +== Augustus + + +*1* ef-time-after-pentecost-sunday-11 + +class-2 · green + +Ep. 1 Cor. 15:1-10 Ev. Mark 7:31-37 + + + +*2* alphonsus-liguori + +class-3 · white + +Ep. 2 Tim. 2:1-7 Ev. Luke 10:1-9 + + +Com. stephen-i-pope-and-martyr + + +*3* ef-time-after-pentecost-11-tuesday + +class-4 · green + +Ep. 1 Cor. 15:1-10 Ev. Mark 7:31-37 + + + +*4* dominic + +class-3 · white + +Ep. 2 Tim. 4:1-8 Ev. Luke 12:35-40 + + + +*5* dedication-of-the-basilica-of-st-mary-major + +class-3 · white + +Ep. Ecclus 24:14-16 Ev. Luke 11:27-28 + + + +*6* transfiguration-of-our-lord + +class-2 · white + +Ep. 2 Pet. 1:16-19 Ev. Matt 17:1-9 + + +Com. pope-sixtus-ii-felicissimus-and-agapitus-martyrs + + +*7* cajetan + +class-3 · white + +Ep. Sir 31:8-11 Ev. Matt 6:24-33 + + +Com. donatus + + +*8* ef-time-after-pentecost-sunday-12 + +class-2 · green + +Ep. 2 Cor. 3:4-9 Ev. Luke 10:23-37 + + + +*9* vigil-of-st-lawrence + +class-3 · violet + +Ep. Ecclus 51:1-8, 12 Ev. Matt 16:24-27 + + +Com. romanus + + +*10* lawrence + +class-2 · red + +Ep. 2 Cor. 9:6-10 Ev. John 12:24-26 + + + +*11* ef-time-after-pentecost-12-wednesday + +class-4 · green + +Ep. 2 Cor. 3:4-9 Ev. Luke 10:23-37 + + +Com. sts-tiburtius-susanna + + +*12* clare + +class-3 · white + +Ep. 2 Cor 10:17-18; 11:1-2 Ev. Matt 25:1-13. + + + +*13* ef-time-after-pentecost-12-friday + +class-4 · green + +Ep. 2 Cor. 3:4-9 Ev. Luke 10:23-37 + + +Com. sts-hippolytus-cassian + + +*14* vigil-of-the-assumption + +class-2 · violet + +Ep. Sir 24:23-31 Ev. Luke 11:27-28 + + +Com. eusebius-confessor + + +*15* assumption-of-the-blessed-virgin-mary + +class-1 · white + +Ep. Judith 13:22-25; 15:10 Ev. Luke 1:41-50 + + +Com. ef-time-after-pentecost-sunday-13 + + +*16* joachim-father-of-the-blessed-virgin + +class-2 · white + +Ep. Sir 31:8-11 Ev. Matt 1:1-16 + + + +*17* hyacinth + +class-3 · white + +Ep. Sir 31:8-11 Ev. Luke 12:35-40 + + + +*18* ef-time-after-pentecost-13-wednesday + +class-4 · green + +Ep. Gal 3:16-22 Ev. Luke 17:11-19 + + +Com. agapitus + + +*19* john-eudes + +class-3 · white + +Ep. Sir 31:8-11 Ev. Luke 12:35-40 + + + +*20* bernard-of-clairvaux + +class-3 · white + +Ep. Ecclus 39:6-14 Ev. Matt 5:13-19 + + + +*21* jane-frances-de-chantal + +class-3 · white + +Ep. Prov 31:10-31 Ev. Matt 13:44-52. + + + +*22* ef-time-after-pentecost-sunday-14 + +class-2 · green + +Ep. Gal 5:16-24 Ev. Matt 6:24-33 + + +Com. immaculate-heart-of-mary + + +*23* philip-benizi + +class-3 · white + +Ep. 1 Cor. 4:9-14 Ev. Luke 12:32-34 + + + +*24* bartholomew + +class-2 · red + +Ep. 1 Cor. 12:27-31 Ev. Luke 6:12-19 + + + +*25* louis-ix + +class-3 · white + +Ep. Wis 10:10-14 Ev. Luke 19:12-26 + + + +*26* ef-time-after-pentecost-14-thursday + +class-4 · green + +Ep. Gal 5:16-24 Ev. Matt 6:24-33 + + +Com. zephyrinus + + +*27* joseph-calasance + +class-3 · white + +Ep. Wis 10:10-14 Ev. Matt 18:1-5 + + + +*28* augustine + +class-3 · white + +Ep. 2 Tim 4:1-8 Ev. Matt 5:13-19 + + +Com. hermes + + +*29* ef-time-after-pentecost-sunday-15 + +class-2 · green + +Ep. Gal 5:25-26; 6:1-10 Ev. Luke 7:11-16 + + + +*30* rose-of-lima + +class-3 · white + +Ep. 2 Cor 10:17-18; 11:1-2 Ev. Matt 25:1-13. + + +Com. sts-felix-and-adauctus + + +*31* raymond-nonnatus + +class-3 · white + +Ep. Sir 31:8-11 Ev. Luke 12:35-40 + + + +== September + + +*1* ef-time-after-pentecost-15-wednesday + +class-4 · green + +Ep. Gal 5:25-26; 6:1-10 Ev. Luke 7:11-16 + + +Com. giles + +Com. twelve-holy-brothers-martyrs + + +*2* stephen-of-hungary + +class-3 · white + +Ep. Sir 31:8-11 Ev. Luke 19:12-26 + + + +*3* pius-x + +class-3 · white + +Ep. 1 Thess. 2:2-8 Ev. John 21:15-17 + + + +*4* Officium sanctae Mariae in sabbato + +class-4 · white + +Ep. Ecclus 24:14-16 Ev. Luke 11:27-28 + + + +*5* ef-time-after-pentecost-sunday-16 + +class-2 · green + +Ep. Eph 3:13-21 Ev. Luke 14:1-11 + + + +*6* ef-time-after-pentecost-16-monday + +class-4 · green + +Ep. Eph 3:13-21 Ev. Luke 14:1-11 + + + +*7* ef-time-after-pentecost-16-tuesday + +class-4 · green + +Ep. Eph 3:13-21 Ev. Luke 14:1-11 + + + +*8* nativity-of-the-blessed-virgin-mary + +class-2 · white + +Ep. Prov 8:22-35 Ev. Matt 1:1-16 + + +Com. hadriani + + +*9* ef-time-after-pentecost-16-thursday + +class-4 · green + +Ep. Eph 3:13-21 Ev. Luke 14:1-11 + + +Com. gorgonius + + +*10* nicholas-of-tolentino + +class-3 · white + +Ep. 1 Cor. 4:9-14 Ev. Luke 12:32-34 + + + +*11* Officium sanctae Mariae in sabbato + +class-4 · white + +Ep. Ecclus 24:14-16 Ev. Luke 11:27-28 + + +Com. sts-protus-hyacinth + + +*12* ef-time-after-pentecost-sunday-17 + +class-2 · green + +Ep. Eph 4:1-6 Ev. Matt 22:34-46 + + + +*13* ef-time-after-pentecost-17-monday + +class-4 · green + +Ep. Eph 4:1-6 Ev. Matt 22:34-46 + + + +*14* exaltation-of-the-holy-cross + +class-2 · red + +Ep. Phil 2:5-11 Ev. John 12:31-36 + + + +*15* seven-sorrows-of-the-blessed-virgin-mary + +class-2 · white + +Ep. Judith 13:22; 13:23-25 Ev. John 19:25-27 + + +Com. nicomedes + + +*16* sts-cornelius-cyprian + +class-3 · red + +Ep. Wis 3:1-8 Ev. Luke 21:9-19 + + +Com. sts-euphemia-lucy-and-geminianus + + +*17* ef-time-after-pentecost-17-friday + +class-4 · green + +Ep. Eph 4:1-6 Ev. Matt 22:34-46 + + +Com. stigmata-of-st-francis + + +*18* joseph-of-cupertino + +class-3 · white + +Ep. 1 Cor 13:1-8 Ev. Matt 22:1-14 + + + +*19* ef-time-after-pentecost-sunday-18 + +class-2 · green + +Ep. 1 Cor. 1:4-8 Ev. Matt 9:1-8 + + + +*20* ef-time-after-pentecost-18-monday + +class-4 · green + +Ep. 1 Cor. 1:4-8 Ev. Matt 9:1-8 + + +Com. sts-eustace-companions + + +*21* matthew + +class-2 · red + +Ep. Ezek 1:10-14 Ev. Matt 9:9-13 + + + +*22* ef-september-ember-wed + +class-2 · violet + +Ep. 2 Esd. 8:1-10 Ev. Mark 9:16-28 + + +Com. thomas-of-villanova + + +*23* linus + +class-3 · red + +Ep. 1 Pet 5:1-4; 5:10-11. Ev. Matt 16:13-19 + + +Com. thecla + + +*24* ef-september-ember-fri + +class-2 · violet + +Ep. Osee 14:2-10 Ev. Luke 7:36-50 + + +Com. our-lady-of-ransom + + +*25* ef-september-ember-sat + +class-2 · violet + +Ep. Heb 9:2-12 Ev. Luke 13:6-17 + + + +*26* ef-time-after-pentecost-sunday-19 + +class-2 · green + +Ep. Eph 4:23-28 Ev. Matt 22:1-14 + + + +*27* sts-cosmas-damian + +class-3 · red + +Ep. Wis 5:16-20 Ev. Luke 6:17-23 + + + +*28* wenceslaus + +class-3 · red + +Ep. Wis 10:10-14 Ev. Matt 10:34-42 + + + +*29* dedication-of-st-michael-the-archangel + +class-1 · white + +Ep. Rev 1:1-5 Ev. Matt 18:1-10 + + + +*30* jerome + +class-3 · white + +Ep. 2 Tim 4:1-8 Ev. Matt 5:13-19 + + + +== October + + +*1* ef-time-after-pentecost-19-friday + +class-4 · green + +Ep. Eph 4:23-28 Ev. Matt 22:1-14 + + +Com. remigius + + +*2* holy-guardian-angels + +class-3 · white + +Ep. Exod 23:20-23 Ev. Matt 18:1-10 + + + +*3* ef-time-after-pentecost-sunday-20 + +class-2 · green + +Ep. Eph 5:15-21 Ev. John 4:46-53 + + + +*4* francis-of-assisi + +class-3 · white + +Ep. Gal 6:14-18 Ev. Matt 11:25-30 + + + +*5* ef-time-after-pentecost-20-tuesday + +class-4 · green + +Ep. Eph 5:15-21 Ev. John 4:46-53 + + +Com. placid-companions + + +*6* bruno + +class-3 · white + +Ep. Sir 31:8-11 Ev. Luke 12:35-40 + + + +*7* our-lady-of-the-rosary + +class-2 · white + +Ep. Prov 8:22-24, 32-35. Ev. Luke 1:26-38 + + +Com. mark-i + + +*8* bridget-of-sweden + +class-3 · white + +Ep. 1 Tim. 5:3-10. Ev. Matt 13:44-52. + + +Com. sergio-baccho-marcello-and-apulejo-martyrs + + +*9* john-leonardi + +class-3 · white + +Ep. 2 Cor 4:1-6; 4:15-18 Ev. Luke 10:1-9 + + +Com. dionysius-and-companions + + +*10* ef-time-after-pentecost-sunday-21 + +class-2 · green + +Ep. Eph 6:10-17 Ev. Matt 18:23-35 + + + +*11* maternity-of-the-blessed-virgin-mary + +class-2 · white + +Ep. Sir 24:23-31 Ev. Luke 2:43-51 + + + +*12* ef-time-after-pentecost-21-tuesday + +class-4 · green + +Ep. Eph 6:10-17 Ev. Matt 18:23-35 + + + +*13* edward + +class-3 · white + +Ep. Sir 31:8-11 Ev. Luke 12:35-40 + + + +*14* callistus-i + +class-3 · red + +Ep. 1 Pet 5:1-4; 5:10-11. Ev. Matt 16:13-19 + + + +*15* teresa-of-avila + +class-3 · white + +Ep. 2 Cor 10:17-18; 11:1-2 Ev. Matt 25:1-13. + + + +*16* hedwig + +class-3 · white + +Ep. Prov 31:10-31 Ev. Matt 13:44-52. + + + +*17* ef-time-after-pentecost-sunday-22 + +class-2 · green + +Ep. Phil 1:6-11 Ev. Matt 22:15-21 + + + +*18* luke-the-evangelist + +class-2 · red + +Ep. 2 Cor. 8:16-24 Ev. Luke 10:1-9 + + + +*19* peter-of-alcantara + +class-3 · white + +Ep. Phil 3:7-12 Ev. Luke 12:32-34 + + + +*20* john-cantius + +class-3 · white + +Ep. James 2:12-17 Ev. Luke 12:35-40 + + + +*21* ef-time-after-pentecost-22-thursday + +class-4 · green + +Ep. Phil 1:6-11 Ev. Matt 22:15-21 + + +Com. hilarion + +Com. ursula-and-companions + + +*22* ef-time-after-pentecost-22-friday + +class-4 · green + +Ep. Phil 1:6-11 Ev. Matt 22:15-21 + + + +*23* anthony-mary-claret + +class-3 · white + +Ep. Heb 7:23-27 Ev. Matt 24:42-47 + + + +*24* ef-time-after-pentecost-sunday-23 + +class-2 · green + +Ep. Phil 3:17-21; 4:1-3 Ev. Matt 9:18-26 + + + +*25* ef-time-after-pentecost-23-monday + +class-4 · green + +Ep. Phil 3:17-21; 4:1-3 Ev. Matt 9:18-26 + + +Com. sts-chrysanthus-daria + + +*26* ef-time-after-pentecost-23-tuesday + +class-4 · green + +Ep. Phil 3:17-21; 4:1-3 Ev. Matt 9:18-26 + + +Com. evaristus + + +*27* ef-time-after-pentecost-23-wednesday + +class-4 · green + +Ep. Phil 3:17-21; 4:1-3 Ev. Matt 9:18-26 + + + +*28* sts-simon-jude + +class-2 · red + +Ep. Eph. 4:7-13. Ev. John 15:17-25 + + + +*29* ef-time-after-pentecost-23-friday + +class-4 · green + +Ep. Phil 3:17-21; 4:1-3 Ev. Matt 9:18-26 + + + +*30* Officium sanctae Mariae in sabbato + +class-4 · white + +Ep. Ecclus 24:14-16 Ev. Luke 11:27-28 + + + +*31* ef-christ-the-king + +class-1 · white + +Ep. Col 1:12-20. Ev. John 18:33-37 + + + +== November + + +*1* all-saints + +class-1 · white + +Ep. Apoc 7:2-12 Ev. Matt 5:1-12 + + + +*2* commemoration-of-all-souls + +class-1 · black + +Ep. 1 Cor. 15:51-57 Ev. John 5:25-29 + + + +*3* ef-time-after-pentecost-24-wednesday + +class-4 · green + +Ep. Col 1:12-20. Ev. John 18:33-37 + + + +*4* charles-borromeo + +class-3 · white + +Ep. Sir 44:16-27; 45:3-20 Ev. Matt 25:14-23 + + +Com. sts-vitalis-and-agricola-martyrs + + +*5* ef-time-after-pentecost-24-friday + +class-4 · green + +Ep. Col 1:12-20. Ev. John 18:33-37 + + + +*6* Officium sanctae Mariae in sabbato + +class-4 · white + +Ep. Ecclus 24:14-16 Ev. Luke 11:27-28 + + + +*7* ef-time-after-epiphany-sunday-5 + +class-2 · green + +Ep. Col 3:12-17 Ev. Matt 13:24-30 + + + +*8* ef-time-after-pentecost-25-monday + +class-4 · green + +Ep. Col 3:12-17 Ev. Matt 13:24-30 + + +Com. four-holy-crowned-martyrs + + +*9* dedication-of-the-archbasilica-of-our-holy-savior + +class-2 · white + +Ep. Rev 21:2-5 Ev. Luke 19:1-10 + + +Com. theodore + + +*10* andrew-avellino + +class-3 · white + +Ep. Sir 31:8-11 Ev. Luke 12:35-40 + + +Com. sts-tryphonis-respicii-et-nymphae + + +*11* martin-of-tours + +class-3 · white + +Ep. Sir 44:16-27; 45:3-20 Ev. Luke 11:33-36 + + +Com. menna + + +*12* martin-i + +class-3 · red + +Ep. 1 Pet 5:1-4; 5:10-11. Ev. Matt 16:13-19 + + + +*13* didacus + +class-3 · white + +Ep. 1 Cor 4:9-14 Ev. Luke 12:32-34 + + + +*14* ef-time-after-epiphany-sunday-6 + +class-2 · green + +Ep. 1 Thess 1:2-10 Ev. Matt 13:31-35 + + + +*15* albert-the-great + +class-3 · white + +Ep. 2 Tim 4:1-8 Ev. Matt 5:13-19 + + + +*16* gertrude-the-great + +class-3 · white + +Ep. 2 Cor 10:17-18; 11:1-2 Ev. Matt 25:1-13. + + + +*17* gregory-the-wonderworker + +class-3 · white + +Ep. Sir 44:16-27; 45:3-20 Ev. Mark 11:22-24 + + + +*18* dedication-of-the-basilicas-of-sts-peter-paul + +class-3 · white + +Ep. Rev 21:2-5 Ev. Luke 19:1-10 + + + +*19* elizabeth-of-hungary + +class-3 · white + +Ep. Prov 31:10-31 Ev. Matt 13:44-52. + + +Com. pontian + + +*20* felix-of-valois + +class-3 · white + +Ep. 1 Cor. 4:9-14 Ev. Luke 12:32-34 + + + +*21* ef-time-after-pentecost-sunday-24 + +class-2 · green + +Ep. Col 1:9-14 Ev. Matt 24:15-35 + + + +*22* cecilia + +class-3 · red + +Ep. Sir 51:13-17. Ev. Matt 25:1-13. + + + +*23* clement-i + +class-3 · red + +Ep. Phil 3:17-21; 4:1-3 Ev. Matt 16:13-19 + + +Com. felicity + + +*24* john-of-the-cross + +class-3 · white + +Ep. 2 Tim 4:1-8 Ev. Matt 5:13-19 + + +Com. chrysogonus + + +*25* catherine-of-alexandria + +class-3 · red + +Ep. Sir 51:1-8; 51:12 Ev. Matt 25:1-13. + + + +*26* sylvester + +class-3 · white + +Ep. Ecclus 45:1-6 Ev. Matt 19:27-29. + + +Com. peter-of-alexandria + + +*27* Officium sanctae Mariae in sabbato + +class-4 · white + +Ep. Ecclus 24:14-16 Ev. Luke 11:27-28 + + + +*28* ef-advent-sunday-1 + +class-1 · violet + +Ep. Rom 13:11-14 Ev. Luke 21:25-33 + + + +*29* ef-advent-1-monday + +class-3 · violet + +Ep. Rom 13:11-14 Ev. Luke 21:25-33 + + +Com. saturninus + + +*30* andrew + +class-2 · red + +Ep. Rom 10:10-18 Ev. Matt 4:18-22 + + +Com. ef-advent-1-tuesday + + +== December + + +*1* ef-advent-1-wednesday + +class-3 · violet + +Ep. Rom 13:11-14 Ev. Luke 21:25-33 + + + +*2* vivian + +class-3 · red + +Ep. Sir 51:13-17. Ev. Matt 13:44-52. + + +Com. ef-advent-1-thursday + + +*3* francis-xavier + +class-3 · white + +Ep. Rom 10:10-18 Ev. Mark 16:15-18 + + +Com. ef-advent-1-friday + + +*4* peter-chrysologus + +class-3 · white + +Ep. 2 Tim 4:1-8 Ev. Matt 5:13-19 + + +Com. ef-advent-1-saturday + +Com. barbara + + +*5* ef-advent-sunday-2 + +class-1 · violet + +Ep. Rom 15:4-13 Ev. Matt 11:2-10 + + + +*6* nicholas + +class-3 · white + +Ep. Heb 13:7-17 Ev. Matt 25:14-23 + + +Com. ef-advent-2-monday + + +*7* ambrose + +class-3 · white + +Ep. 2 Tim 4:1-8 Ev. Matt 5:13-19 + + +Com. ef-advent-2-tuesday + + +*8* immaculate-conception-of-the-blessed-virgin-mary + +class-1 · white + +Ep. Prov 8:22-35 Ev. Luke 1:26-28 + + +Com. ef-advent-2-wednesday + + +*9* ef-advent-2-thursday + +class-3 · violet + +Ep. Rom 15:4-13 Ev. Matt 11:2-10 + + + +*10* ef-advent-2-friday + +class-3 · violet + +Ep. Rom 15:4-13 Ev. Matt 11:2-10 + + +Com. melchiades + + +*11* damasus-i + +class-3 · white + +Ep. 1 Pet 5:1-4; 5:10-11. Ev. Matt 16:13-19 + + +Com. ef-advent-2-saturday + + +*12* ef-advent-sunday-3 + +class-1 · rose + +Ep. Phil 4:4-7 Ev. John 1:19-28 + + + +*13* lucy + +class-3 · red + +Ep. 2 Cor 10:17-18; 11:1-2 Ev. Matt 13:44-52. + + +Com. ef-advent-3-monday + + +*14* ef-advent-3-tuesday + +class-3 · violet + +Ep. Phil 4:4-7 Ev. John 1:19-28 + + + +*15* ef-advent-ember-wed + +class-2 · violet + +Ep. Isa 7:10-15 Ev. Luke 1:26-38 + + + +*16* eusebius + +class-3 · red + +Ep. 2 Cor. 1:3-7 Ev. Matt 16:24-27. + + +Com. ef-advent-3-thursday + + +*17* ef-advent-ember-fri + +class-2 · violet + +Ep. Isa 11:1-5 Ev. Luke 1:39-47 + + + +*18* ef-advent-ember-sat + +class-2 · violet + +Ep. 2 Thess 2:1-8 Ev. Luke 3:1-6 + + + +*19* ef-advent-sunday-4 + +class-1 · violet + +Ep. 1 Cor. 4:1-5 Ev. Luke 3:1-6 + + + +*20* ef-advent-4-monday + +class-2 · violet + +Ep. 1 Cor. 4:1-5 Ev. Luke 3:1-6 + + + +*21* thomas + +class-2 · red + +Ep. Eph 2:19-22 Ev. John 20:24-29 + + +Com. ef-advent-4-tuesday + + +*22* ef-advent-4-wednesday + +class-2 · violet + +Ep. 1 Cor. 4:1-5 Ev. Luke 3:1-6 + + + +*23* ef-advent-4-thursday + +class-2 · violet + +Ep. 1 Cor. 4:1-5 Ev. Luke 3:1-6 + + + +*24* ef-nativity-vigil + +class-1 · violet + +Ep. Rom 1:1-6 Ev. Matt 1:18-21 + + + +*25* ef-nativity + +class-1 · white + +Ep. Heb 1:1-12 Ev. John 1:1-14 + + + +*26* ef-christmas-sunday-0 + +class-2 · white + +Ep. Gal 4:1-7 Ev. Luke 2:33-40 + + +Com. stephen + + +*27* john-the-evangelist + +class-2 · white + +Ep. Ecclus 15:1-6 Ev. John 21:19-24 + + +Com. ef-nativity-octave-day-3 + + +*28* holy-innocents + +class-2 · red + +Ep. Apoc 14:1-5 Ev. Matt 2:13-18 + + +Com. ef-nativity-octave-day-4 + + +*29* ef-nativity-octave-day-5 + +class-2 · white + +Ep. Titus 3:4-7 Ev. Luke 2:15-20 + + +Com. thomas-becket + + +*30* ef-nativity-octave-day-6 + +class-2 · white + +Ep. Titus 3:4-7 Ev. Luke 2:15-20 + + + +*31* ef-nativity-octave-day-7 + +class-2 · white + +Ep. Titus 3:4-7 Ev. Luke 2:15-20 + + +Com. silvester + + diff --git a/test/golden/ordo-2027.html b/test/golden/ordo-2027.html new file mode 100644 index 0000000..2f597c4 --- /dev/null +++ b/test/golden/ordo-2027.html @@ -0,0 +1,1859 @@ +<!-- colitur ordo booklet -- HTML. flavour: html --> +<!-- Day label falls back to the slug when the day carries no Latin name + (most temporal days, and most sanctoral entries, which are Latin-less + in the shipped data) -- see ordo.tex's own comment for why the fallback + is written as a name-section wrapping a plain var and its inverse, + rather than a single dotted lookup and its inverse. --> +<!doctype html> +<html lang="la"><head><meta charset="utf-8"> +<title>Ordo 2027</title> +<style> + body{font-family:serif;max-width:40em;margin:2em auto;line-height:1.4} + .day{margin:.6em 0;padding-left:2.5em;text-indent:-2.5em} + .dom{display:inline-block;width:2em;font-weight:bold} + .meta{font-size:.85em;color:#555} + .white{border-left:4px solid #ccc} .red{border-left:4px solid #b00} + .green{border-left:4px solid #070} .violet{border-left:4px solid #609} + .rose{border-left:4px solid #e7a} .black{border-left:4px solid #000} + @media print{body{margin:0}} +</style></head><body> +<h1>Ordo 2027 · ef</h1> +<h2>Ianuarius</h2> +<div class="day white"> + <span class="dom">1</span>ef-circumcision + <div class="meta">class-1 · white · Ep. Titus 2:11-15 · Ev. Luke 2:21</div> + +</div> +<div class="day white"> + <span class="dom">2</span>Officium sanctae Mariae in sabbato + <div class="meta">class-4 · white · Ep. Titus 3:4-7 · Ev. Luke 2:15-20</div> + +</div> +<div class="day white"> + <span class="dom">3</span>Sanctissimi Nominis Iesu + <div class="meta">class-2 · white · Ep. Acts 4:8-12 · Ev. Luke 2:21</div> + +</div> +<div class="day white"> + <span class="dom">4</span>ef-christmas-1-monday + <div class="meta">class-4 · white · Ep. Titus 2:11-15 · Ev. Luke 2:21</div> + +</div> +<div class="day white"> + <span class="dom">5</span>ef-christmas-1-tuesday + <div class="meta">class-4 · white · Ep. Titus 2:11-15 · Ev. Luke 2:21</div> + <div class="meta">Com. telesphorus-pope-and-martyr</div> +</div> +<div class="day white"> + <span class="dom">6</span>ef-epiphany + <div class="meta">class-1 · white · Ep. Isa 60:1-6 · Ev. Matt 2:1-12</div> + +</div> +<div class="day white"> + <span class="dom">7</span>ef-christmas-2-thursday + <div class="meta">class-4 · white · Ep. Isa 60:1-6 · Ev. Matt 2:1-12</div> + +</div> +<div class="day white"> + <span class="dom">8</span>ef-christmas-2-friday + <div class="meta">class-4 · white · Ep. Isa 60:1-6 · Ev. Matt 2:1-12</div> + +</div> +<div class="day white"> + <span class="dom">9</span>Officium sanctae Mariae in sabbato + <div class="meta">class-4 · white · Ep. Titus 3:4-7 · Ev. Luke 2:15-20</div> + +</div> +<div class="day white"> + <span class="dom">10</span>Sanctae Familiae Iesu, Mariae, Ioseph + <div class="meta">class-2 · white · Ep. Col 3:12-17 · Ev. Luke 2:42-52</div> + +</div> +<div class="day white"> + <span class="dom">11</span>ef-time-after-epiphany-1-monday + <div class="meta">class-4 · white · Ep. Rom 12:1-5 · Ev. Luke 2:42-52</div> + <div class="meta">Com. hyginus-pope-and-martyr</div> +</div> +<div class="day white"> + <span class="dom">12</span>ef-time-after-epiphany-1-tuesday + <div class="meta">class-4 · white · Ep. Rom 12:1-5 · Ev. Luke 2:42-52</div> + +</div> +<div class="day white"> + <span class="dom">13</span>commemoration-of-the-baptism-of-the-lord + <div class="meta">class-2 · white · Ep. Isa 60:1-6 · Ev. John 1:29-34</div> + +</div> +<div class="day white"> + <span class="dom">14</span>hilary + <div class="meta">class-3 · white · Ep. 2 Tim 4:1-8 · Ev. Matt 5:13-19</div> + <div class="meta">Com. felicis</div> +</div> +<div class="day white"> + <span class="dom">15</span>paul-the-first-hermit + <div class="meta">class-3 · white · Ep. Phil 3:7-12 · Ev. Matt 11:25-30</div> + <div class="meta">Com. maur-abbot</div> +</div> +<div class="day red"> + <span class="dom">16</span>marcellus-i + <div class="meta">class-3 · red · Ep. 1 Pet 5:1-4; 5:10-11. · Ev. Matt 16:13-19</div> + +</div> +<div class="day green"> + <span class="dom">17</span>ef-time-after-epiphany-sunday-2 + <div class="meta">class-2 · green · Ep. Rom 12:6-16 · Ev. John 2:1-11</div> + +</div> +<div class="day green"> + <span class="dom">18</span>ef-time-after-epiphany-2-monday + <div class="meta">class-4 · green · Ep. Rom 12:6-16 · Ev. John 2:1-11</div> + <div class="meta">Com. prisca</div> +</div> +<div class="day green"> + <span class="dom">19</span>ef-time-after-epiphany-2-tuesday + <div class="meta">class-4 · green · Ep. Rom 12:6-16 · Ev. John 2:1-11</div> + <div class="meta">Com. canute-martyr</div><div class="meta">Com. sts-marius-martha-audifax-abachum</div> +</div> +<div class="day red"> + <span class="dom">20</span>sts-fabian-sebastian + <div class="meta">class-3 · red · Ep. Heb 11:33-39 · Ev. Luke 6:17-23</div> + +</div> +<div class="day red"> + <span class="dom">21</span>agnes + <div class="meta">class-3 · red · Ep. Sir 51:1-8; 51:12 · Ev. Matt 25:1-13.</div> + +</div> +<div class="day red"> + <span class="dom">22</span>sts-vincent-anastasius + <div class="meta">class-3 · red · Ep. Wis 3:1-8 · Ev. Luke 21:9-19</div> + +</div> +<div class="day white"> + <span class="dom">23</span>raymond-of-pe-afort + <div class="meta">class-3 · white · Ep. Sir 31:8-11 · Ev. Luke 12:35-40</div> + <div class="meta">Com. emerentiana</div> +</div> +<div class="day violet"> + <span class="dom">24</span>ef-septuagesima-sunday-1 + <div class="meta">class-2 · violet · Ep. 1 Cor. 9:24-27; 10:1-5 · Ev. Matt 20:1-16</div> + +</div> +<div class="day white"> + <span class="dom">25</span>conversion-of-st-paul + <div class="meta">class-3 · white · Ep. Acts 9:1-22 · Ev. Matt 19:27-29.</div> + <div class="meta">Com. peter</div> +</div> +<div class="day red"> + <span class="dom">26</span>polycarp + <div class="meta">class-3 · red · Ep. 1 John 3:10-16 · Ev. Matt 10:26-32.</div> + +</div> +<div class="day white"> + <span class="dom">27</span>john-chrysostom + <div class="meta">class-3 · white · Ep. 2 Tim 4:1-8 · Ev. Matt 5:13-19</div> + +</div> +<div class="day white"> + <span class="dom">28</span>peter-nolasco + <div class="meta">class-3 · white · Ep. 1 Cor. 4:9-14 · Ev. Luke 12:32-34</div> + <div class="meta">Com. agnes-secundo</div> +</div> +<div class="day white"> + <span class="dom">29</span>francis-de-sales + <div class="meta">class-3 · white · Ep. 2 Tim 4:1-8 · Ev. Matt 5:13-19</div> + +</div> +<div class="day red"> + <span class="dom">30</span>martina + <div class="meta">class-3 · red · Ep. Sir 51:1-8; 51:12 · Ev. Matt 25:1-13.</div> + +</div> +<div class="day violet"> + <span class="dom">31</span>ef-septuagesima-sunday-2 + <div class="meta">class-2 · violet · Ep. 2 Cor. 11:19-33; 12:1-9 · Ev. Luke 8:4-15</div> + +</div> +<h2>Februarius</h2> +<div class="day red"> + <span class="dom">1</span>ignatius-of-antioch + <div class="meta">class-3 · red · Ep. Rom 8:35-39 · Ev. John 12:24-26</div> + +</div> +<div class="day white"> + <span class="dom">2</span>purification-of-the-blessed-virgin-mary + <div class="meta">class-2 · white · Ep. Mal 3:1-4 · Ev. Luke 2:22-32</div> + +</div> +<div class="day violet"> + <span class="dom">3</span>ef-septuagesima-2-wednesday + <div class="meta">class-4 · violet · Ep. 2 Cor. 11:19-33; 12:1-9 · Ev. Luke 8:4-15</div> + <div class="meta">Com. blaise</div> +</div> +<div class="day white"> + <span class="dom">4</span>andrew-corsini + <div class="meta">class-3 · white · Ep. Sir 44:16-27; 45:3-20 · Ev. Matt 25:14-23</div> + +</div> +<div class="day red"> + <span class="dom">5</span>agatha + <div class="meta">class-3 · red · Ep. 1 Cor. 1:26-31 · Ev. Matt 19:3-12.</div> + +</div> +<div class="day white"> + <span class="dom">6</span>titus + <div class="meta">class-3 · white · Ep. Sir 44:16-27; 45:3-20 · Ev. Luke 10:1-9</div> + <div class="meta">Com. dorothy</div> +</div> +<div class="day violet"> + <span class="dom">7</span>ef-septuagesima-sunday-3 + <div class="meta">class-2 · violet · Ep. 1 Cor. 13:1-13 · Ev. Luke 18:31-43</div> + +</div> +<div class="day white"> + <span class="dom">8</span>john-of-matha + <div class="meta">class-3 · white · Ep. Sir 31:8-11 · Ev. Luke 12:35-40</div> + +</div> +<div class="day white"> + <span class="dom">9</span>cyril-of-alexandria + <div class="meta">class-3 · white · Ep. 2 Tim 4:1-8 · Ev. Matt 5:13-19</div> + <div class="meta">Com. appollonia</div> +</div> +<div class="day violet"> + <span class="dom">10</span>ef-ash-wednesday + <div class="meta">class-1 · violet · Ep. Joel 2:12-19 · Ev. Matt 6:16-21</div> + +</div> +<div class="day violet"> + <span class="dom">11</span>ef-lent-after-ashes-thursday + <div class="meta">class-3 · violet · Ep. Isa 38:1-6 · Ev. Matt 8:5-13</div> + <div class="meta">Com. our-lady-of-lourdes</div> +</div> +<div class="day violet"> + <span class="dom">12</span>ef-lent-after-ashes-friday + <div class="meta">class-3 · violet · Ep. Isa 58:1-9 · Ev. Matt 5:43-48; 6:1-4</div> + <div class="meta">Com. seven-holy-servite-founders</div> +</div> +<div class="day violet"> + <span class="dom">13</span>ef-lent-after-ashes-saturday + <div class="meta">class-3 · violet · Ep. Isa 58:9-14 · Ev. Mark 6:47-56</div> + +</div> +<div class="day violet"> + <span class="dom">14</span>ef-lent-sunday-1 + <div class="meta">class-1 · violet · Ep. 2 Cor. 6:1-10 · Ev. Matt 4:1-11</div> + +</div> +<div class="day violet"> + <span class="dom">15</span>ef-lent-1-monday + <div class="meta">class-3 · violet · Ep. Ezech 34:11-16 · Ev. Matt 25:31-46</div> + <div class="meta">Com. sts-faustinus-jovita</div> +</div> +<div class="day violet"> + <span class="dom">16</span>ef-lent-1-tuesday + <div class="meta">class-3 · violet · Ep. Isa 55:6-11 · Ev. Matt 21:10-17</div> + +</div> +<div class="day violet"> + <span class="dom">17</span>ef-lent-ember-wed + <div class="meta">class-2 · violet · Ep. 3 Kgs. 19:3-8 · Ev. Matt 12:38-50</div> + +</div> +<div class="day violet"> + <span class="dom">18</span>ef-lent-1-thursday + <div class="meta">class-3 · violet · Ep. Ezech 18:1-9 · Ev. Matt 15:21-28</div> + <div class="meta">Com. simeon</div> +</div> +<div class="day violet"> + <span class="dom">19</span>ef-lent-ember-fri + <div class="meta">class-2 · violet · Ep. Ezech 18:20-28 · Ev. John 5:1-15</div> + +</div> +<div class="day violet"> + <span class="dom">20</span>ef-lent-ember-sat + <div class="meta">class-2 · violet · Ep. 1 Thess. 5:14-23 · Ev. Matt 17:1-9</div> + +</div> +<div class="day violet"> + <span class="dom">21</span>ef-lent-sunday-2 + <div class="meta">class-1 · violet · Ep. 1 Thess. 4:1-7 · Ev. Matt 17:1-9</div> + +</div> +<div class="day white"> + <span class="dom">22</span>chair-of-st-peter + <div class="meta">class-2 · white · Ep. 1 Pet 1:1-7 · Ev. Matt 16:13-19</div> + <div class="meta">Com. ef-lent-2-monday</div><div class="meta">Com. paul</div> +</div> +<div class="day violet"> + <span class="dom">23</span>ef-lent-2-tuesday + <div class="meta">class-3 · violet · Ep. 3 Kings 17:8-16 · Ev. Matt 23:1-12</div> + <div class="meta">Com. peter-damien</div> +</div> +<div class="day red"> + <span class="dom">24</span>matthias + <div class="meta">class-2 · red · Ep. Acts 1:15-26 · Ev. Matt 11:25-30</div> + <div class="meta">Com. ef-lent-2-wednesday</div> +</div> +<div class="day violet"> + <span class="dom">25</span>ef-lent-2-thursday + <div class="meta">class-3 · violet · Ep. Jer 17:5-10 · Ev. Luke 16:19-31</div> + +</div> +<div class="day violet"> + <span class="dom">26</span>ef-lent-2-friday + <div class="meta">class-3 · violet · Ep. Gen 37:6-22 · Ev. Matt 21:33-46</div> + +</div> +<div class="day violet"> + <span class="dom">27</span>ef-lent-2-saturday + <div class="meta">class-3 · violet · Ep. Gen 27:6-40 · Ev. Luke 15:11-32</div> + <div class="meta">Com. gabriel-of-our-lady-of-sorrows</div> +</div> +<div class="day violet"> + <span class="dom">28</span>ef-lent-sunday-3 + <div class="meta">class-1 · violet · Ep. Eph 5:1-9 · Ev. Luke 11:14-28</div> + +</div> +<h2>Martius</h2> +<div class="day violet"> + <span class="dom">1</span>ef-lent-3-monday + <div class="meta">class-3 · violet · Ep. 4 Kings 5:1-15 · Ev. Luke 4:23-30</div> + +</div> +<div class="day violet"> + <span class="dom">2</span>ef-lent-3-tuesday + <div class="meta">class-3 · violet · Ep. 4 Kings 4:1-7 · Ev. Matt 18:15-22</div> + +</div> +<div class="day violet"> + <span class="dom">3</span>ef-lent-3-wednesday + <div class="meta">class-3 · violet · Ep. Ex 20:12-24 · Ev. Matt 15:1-20</div> + +</div> +<div class="day violet"> + <span class="dom">4</span>ef-lent-3-thursday + <div class="meta">class-3 · violet · Ep. Jer 7:1-7 · Ev. Luke 4:38-44.</div> + <div class="meta">Com. casimir</div><div class="meta">Com. lucius</div> +</div> +<div class="day violet"> + <span class="dom">5</span>ef-lent-3-friday + <div class="meta">class-3 · violet · Ep. Num 20:1, 3; 6-13. · Ev. John 4:5-42</div> + +</div> +<div class="day violet"> + <span class="dom">6</span>ef-lent-3-saturday + <div class="meta">class-3 · violet · Ep. Dan 13:1-9, 15-17, 19-30, 33-62. · Ev. John 8:1-11</div> + <div class="meta">Com. sts-felicitas-perpetua</div> +</div> +<div class="day rose"> + <span class="dom">7</span>ef-lent-sunday-4 + <div class="meta">class-1 · rose · Ep. Gal 4:22-31 · Ev. John 6:1-15</div> + +</div> +<div class="day violet"> + <span class="dom">8</span>ef-lent-4-monday + <div class="meta">class-3 · violet · Ep. 3 Kings 3:16-28 · Ev. John 2:13-25</div> + <div class="meta">Com. john-of-god</div> +</div> +<div class="day violet"> + <span class="dom">9</span>ef-lent-4-tuesday + <div class="meta">class-3 · violet · Ep. Ex 32:7-14 · Ev. John 7:14-31</div> + <div class="meta">Com. frances-rome</div> +</div> +<div class="day violet"> + <span class="dom">10</span>ef-lent-4-wednesday + <div class="meta">class-3 · violet · Ep. Isa. 1:16-19 · Ev. John 9:1-38</div> + <div class="meta">Com. forty-holy-martyrs-of-sebaste</div> +</div> +<div class="day violet"> + <span class="dom">11</span>ef-lent-4-thursday + <div class="meta">class-3 · violet · Ep. 4 Kings 4:25-38 · Ev. Luke 7:11-16</div> + +</div> +<div class="day violet"> + <span class="dom">12</span>ef-lent-4-friday + <div class="meta">class-3 · violet · Ep. 3 Kings 17:17-24 · Ev. John 11:1-45</div> + <div class="meta">Com. gregory-the-great</div> +</div> +<div class="day violet"> + <span class="dom">13</span>ef-lent-4-saturday + <div class="meta">class-3 · violet · Ep. Isa 49:8-15 · Ev. John 8:12-20</div> + +</div> +<div class="day violet"> + <span class="dom">14</span>ef-passion-sunday + <div class="meta">class-1 · violet · Ep. Heb 9:11-15. · Ev. John 8:46-59.</div> + +</div> +<div class="day violet"> + <span class="dom">15</span>ef-passiontide-1-monday + <div class="meta">class-3 · violet · Ep. Jonas 3:1-10 · Ev. John 7:32-39</div> + +</div> +<div class="day violet"> + <span class="dom">16</span>ef-passiontide-1-tuesday + <div class="meta">class-3 · violet · Ep. Dan 14:27, 28-42 · Ev. John 7:1-13</div> + +</div> +<div class="day violet"> + <span class="dom">17</span>ef-passiontide-1-wednesday + <div class="meta">class-3 · violet · Ep. Lev 19:1-2, 11-19, 25 · Ev. John 10:22-38</div> + <div class="meta">Com. patrick</div> +</div> +<div class="day violet"> + <span class="dom">18</span>ef-passiontide-1-thursday + <div class="meta">class-3 · violet · Ep. Dan 3:25, 34-45. · Ev. Luke 7:36-50</div> + <div class="meta">Com. cyril-of-jerusalem</div> +</div> +<div class="day white"> + <span class="dom">19</span>joseph-spouse-of-the-bl-virgin-mary + <div class="meta">class-1 · white · Ep. Ecclus 45:1-6 · Ev. Matt 1:18-21</div> + <div class="meta">Com. ef-passiontide-1-friday</div> +</div> +<div class="day violet"> + <span class="dom">20</span>ef-passiontide-1-saturday + <div class="meta">class-3 · violet · Ep. Jer 18:18-23 · Ev. John 12:10-36</div> + +</div> +<div class="day violet"> + <span class="dom">21</span>ef-palm-sunday + <div class="meta">class-1 · violet · Ep. Phil 2:5-11 · Ev. Matt. 26:36-75; 27:1-60.</div> + +</div> +<div class="day violet"> + <span class="dom">22</span>ef-passiontide-2-monday + <div class="meta">class-1 · violet · Ep. Isa 50:5-10 · Ev. John 12:1-9</div> + +</div> +<div class="day violet"> + <span class="dom">23</span>ef-passiontide-2-tuesday + <div class="meta">class-1 · violet · Ep. Jer 11:18-20 · Ev. Mark 14:32-72; 15, 1-46</div> + +</div> +<div class="day violet"> + <span class="dom">24</span>ef-passiontide-2-wednesday + <div class="meta">class-1 · violet · Ep. Isa 53:1-12 · Ev. Luke 22:39-71; 23:1-53</div> + +</div> +<div class="day white"> + <span class="dom">25</span>Feria V in Cena Domini + <div class="meta">class-1 · white · Ep. 1 Cor 11:20-32 · Ev. John 13:1-15</div> + +</div> +<div class="day black"> + <span class="dom">26</span>Feria VI in Passione et Morte Domini + <div class="meta">class-1 · black · Ep. Ex 12:1-11 · Ev. John 18:1-40; 19:1-42</div> + +</div> +<div class="day violet"> + <span class="dom">27</span>Sabbato sancto + <div class="meta">class-1 · violet · Ep. Col 3:1-4 · Ev. Matt 28:1-7</div> + +</div> +<div class="day white"> + <span class="dom">28</span>ef-easter-sunday + <div class="meta">class-1 · white · Ep. 1 Cor 5:7-8 · Ev. Mark 16:1-7</div> + +</div> +<div class="day white"> + <span class="dom">29</span>ef-easter-1-monday + <div class="meta">class-1 · white · Ep. Acts 10:37-43. · Ev. Luke 24:13-35</div> + +</div> +<div class="day white"> + <span class="dom">30</span>ef-easter-1-tuesday + <div class="meta">class-1 · white · Ep. Acts 13:16; 13:26-33 · Ev. Luke 24:36-47</div> + +</div> +<div class="day white"> + <span class="dom">31</span>ef-easter-1-wednesday + <div class="meta">class-1 · white · Ep. Acts 3:13-15; 3:17-19 · Ev. John 21:1-14</div> + +</div> +<h2>Aprilis</h2> +<div class="day white"> + <span class="dom">1</span>ef-easter-1-thursday + <div class="meta">class-1 · white · Ep. Acts 8:26-40 · Ev. John 20:11-18</div> + +</div> +<div class="day white"> + <span class="dom">2</span>ef-easter-1-friday + <div class="meta">class-1 · white · Ep. 1 Pet 3:18-22 · Ev. Matt 28:16-20</div> + +</div> +<div class="day white"> + <span class="dom">3</span>ef-easter-1-saturday + <div class="meta">class-1 · white · Ep. 1 Pet 2:1-10 · Ev. John 20:1-9</div> + +</div> +<div class="day white"> + <span class="dom">4</span>ef-low-sunday + <div class="meta">class-1 · white · Ep. 1 John 5:4-10 · Ev. John 20:19-31</div> + +</div> +<div class="day white"> + <span class="dom">5</span>annunciation-of-the-blessed-virgin-mary + <div class="meta">class-1 · white · Ep. Isa 7:10-15 · Ev. Luke 1:26-38</div> + +</div> +<div class="day white"> + <span class="dom">6</span>ef-easter-2-tuesday + <div class="meta">class-4 · white · Ep. 1 John 5:4-10 · Ev. John 20:19-31</div> + +</div> +<div class="day white"> + <span class="dom">7</span>ef-easter-2-wednesday + <div class="meta">class-4 · white · Ep. 1 John 5:4-10 · Ev. John 20:19-31</div> + +</div> +<div class="day white"> + <span class="dom">8</span>ef-easter-2-thursday + <div class="meta">class-4 · white · Ep. 1 John 5:4-10 · Ev. John 20:19-31</div> + +</div> +<div class="day white"> + <span class="dom">9</span>ef-easter-2-friday + <div class="meta">class-4 · white · Ep. 1 John 5:4-10 · Ev. John 20:19-31</div> + +</div> +<div class="day white"> + <span class="dom">10</span>Officium sanctae Mariae in sabbato + <div class="meta">class-4 · white · Ep. Ecclus 24:14-16 · Ev. John 19:25-27</div> + +</div> +<div class="day white"> + <span class="dom">11</span>ef-easter-sunday-3 + <div class="meta">class-2 · white · Ep. 1 Pet 2:21-25 · Ev. John 10:11-16</div> + +</div> +<div class="day white"> + <span class="dom">12</span>ef-easter-3-monday + <div class="meta">class-4 · white · Ep. 1 Pet 2:21-25 · Ev. John 10:11-16</div> + +</div> +<div class="day red"> + <span class="dom">13</span>hermenegild + <div class="meta">class-3 · red · Ep. Wis 10:10-14 · Ev. Luke 14:26-33.</div> + +</div> +<div class="day red"> + <span class="dom">14</span>justin + <div class="meta">class-3 · red · Ep. 1 Cor 1:18-25; 1:30; · Ev. Luke 12:2-8</div> + <div class="meta">Com. sts-tiburtius-valerian-et-maximus-martyrs</div> +</div> +<div class="day white"> + <span class="dom">15</span>ef-easter-3-thursday + <div class="meta">class-4 · white · Ep. 1 Pet 2:21-25 · Ev. John 10:11-16</div> + +</div> +<div class="day white"> + <span class="dom">16</span>ef-easter-3-friday + <div class="meta">class-4 · white · Ep. 1 Pet 2:21-25 · Ev. John 10:11-16</div> + +</div> +<div class="day white"> + <span class="dom">17</span>Officium sanctae Mariae in sabbato + <div class="meta">class-4 · white · Ep. Ecclus 24:14-16 · Ev. John 19:25-27</div> + <div class="meta">Com. anicetus</div> +</div> +<div class="day white"> + <span class="dom">18</span>ef-easter-sunday-4 + <div class="meta">class-2 · white · Ep. 1 Pet 2:11-19 · Ev. John 16:16-22</div> + +</div> +<div class="day white"> + <span class="dom">19</span>ef-easter-4-monday + <div class="meta">class-4 · white · Ep. 1 Pet 2:11-19 · Ev. John 16:16-22</div> + +</div> +<div class="day white"> + <span class="dom">20</span>ef-easter-4-tuesday + <div class="meta">class-4 · white · Ep. 1 Pet 2:11-19 · Ev. John 16:16-22</div> + +</div> +<div class="day white"> + <span class="dom">21</span>anselm + <div class="meta">class-3 · white · Ep. 2 Tim 4:1-8 · Ev. Matt 5:13-19</div> + +</div> +<div class="day red"> + <span class="dom">22</span>sts-soter-caius + <div class="meta">class-3 · red · Ep. 1 Pet 5:1-4; 5:10-11. · Ev. Matt 16:13-19</div> + +</div> +<div class="day white"> + <span class="dom">23</span>ef-easter-4-friday + <div class="meta">class-4 · white · Ep. 1 Pet 2:11-19 · Ev. John 16:16-22</div> + <div class="meta">Com. george</div> +</div> +<div class="day red"> + <span class="dom">24</span>fidelis-of-sigmaringen + <div class="meta">class-3 · red · Ep. Wis 5:1-5 · Ev. John 15:1-7</div> + +</div> +<div class="day white"> + <span class="dom">25</span>ef-easter-sunday-5 + <div class="meta">class-2 · white · Ep. Jas 1:17-21 · Ev. John 16:5-14</div> + <div class="meta">Com. major-litanies</div> +</div> +<div class="day red"> + <span class="dom">26</span>sts-cletus-marcellinus + <div class="meta">class-3 · red · Ep. 1 Pet 5:1-4; 5:10-11. · Ev. Matt 16:13-19</div> + +</div> +<div class="day white"> + <span class="dom">27</span>peter-canisius + <div class="meta">class-3 · white · Ep. 2 Tim 4:1-8 · Ev. Matt 5:13-19</div> + +</div> +<div class="day white"> + <span class="dom">28</span>paul-of-the-cross + <div class="meta">class-3 · white · Ep. 1 Cor 1:17-25. · Ev. Luke 10:1-9</div> + +</div> +<div class="day red"> + <span class="dom">29</span>peter-of-verona + <div class="meta">class-3 · red · Ep. 2 Tim. 2:8-10; 3:10-12. · Ev. Matt 10:34-42</div> + +</div> +<div class="day white"> + <span class="dom">30</span>catherine-of-siena + <div class="meta">class-3 · white · Ep. 2 Cor 10:17-18; 11:1-2 · Ev. Matt 25:1-13.</div> + +</div> +<h2>Maius</h2> +<div class="day white"> + <span class="dom">1</span>joseph-the-workman + <div class="meta">class-1 · white · Ep. Col. 3:14-15, 17, 23-24 · Ev. Matt 13:54-58</div> + +</div> +<div class="day white"> + <span class="dom">2</span>ef-easter-sunday-6 + <div class="meta">class-2 · white · Ep. Jas 1:22-27 · Ev. John 16:23-30</div> + +</div> +<div class="day violet"> + <span class="dom">3</span>ef-rogation-monday + <div class="meta">class-4 · violet · Ep. Jas 1:22-27 · Ev. John 16:23-30</div> + <div class="meta">Com. sts-alexander-companions</div> +</div> +<div class="day white"> + <span class="dom">4</span>monica + <div class="meta">class-3 · white · Ep. 1 Tim. 5:3-10. · Ev. Luke 7:11-16</div> + +</div> +<div class="day white"> + <span class="dom">5</span>ef-ascension-vigil + <div class="meta">class-2 · white · Ep. Eph. 4:7-13. · Ev. John 17:1-11.</div> + <div class="meta">Com. pius-v</div> +</div> +<div class="day white"> + <span class="dom">6</span>ef-ascension + <div class="meta">class-1 · white · Ep. Acts 1:1-11 · Ev. Mark 16:14-20</div> + +</div> +<div class="day red"> + <span class="dom">7</span>stanislaus + <div class="meta">class-3 · red · Ep. Wis 5:1-5 · Ev. John 15:1-7</div> + +</div> +<div class="day white"> + <span class="dom">8</span>Officium sanctae Mariae in sabbato + <div class="meta">class-4 · white · Ep. Ecclus 24:14-16 · Ev. John 19:25-27</div> + +</div> +<div class="day white"> + <span class="dom">9</span>ef-easter-sunday-7 + <div class="meta">class-2 · white · Ep. 1 Pet 4:7-11. · Ev. John 15:26-27; 16:1-4.</div> + +</div> +<div class="day white"> + <span class="dom">10</span>antoninus + <div class="meta">class-3 · white · Ep. Sir 44:16-27; 45:3-20 · Ev. Matt 25:14-23</div> + <div class="meta">Com. gordiano-and-epimacho</div> +</div> +<div class="day red"> + <span class="dom">11</span>sts-philip-james + <div class="meta">class-2 · red · Ep. Wis. 5:1-5 · Ev. John 14:1-13</div> + +</div> +<div class="day red"> + <span class="dom">12</span>sts-nereus-achilleus-domitilla-pancras + <div class="meta">class-3 · red · Ep. Wis. 5:1-5 · Ev. John 4:46-53</div> + +</div> +<div class="day white"> + <span class="dom">13</span>robert-bellarmine + <div class="meta">class-3 · white · Ep. Wis 7:7-14. · Ev. Matt 5:13-19</div> + +</div> +<div class="day white"> + <span class="dom">14</span>ef-easter-7-friday + <div class="meta">class-4 · white · Ep. 1 Pet 4:7-11. · Ev. John 15:26-27; 16:1-4.</div> + <div class="meta">Com. boniface-martyr</div> +</div> +<div class="day red"> + <span class="dom">15</span>ef-pentecost-vigil + <div class="meta">class-1 · red · Ep. Acts 19:1-8. · Ev. John 14:15-21.</div> + +</div> +<div class="day red"> + <span class="dom">16</span>ef-pentecost + <div class="meta">class-1 · red · Ep. Acts 2:1-11. · Ev. John 14:23-31.</div> + +</div> +<div class="day red"> + <span class="dom">17</span>ef-easter-8-monday + <div class="meta">class-1 · red · Ep. Acts 10:34, 42-48 · Ev. John 3:16-21</div> + +</div> +<div class="day red"> + <span class="dom">18</span>ef-easter-8-tuesday + <div class="meta">class-1 · red · Ep. Acts 8:14-17. · Ev. John 10:1-10.</div> + +</div> +<div class="day red"> + <span class="dom">19</span>ef-pentecost-ember-wed + <div class="meta">class-1 · red · Ep. Acts 5:12-16 · Ev. John 6:44-52.</div> + +</div> +<div class="day red"> + <span class="dom">20</span>ef-easter-8-thursday + <div class="meta">class-1 · red · Ep. Acts 8:5-8 · Ev. Luke 9:1-6</div> + +</div> +<div class="day red"> + <span class="dom">21</span>ef-pentecost-ember-fri + <div class="meta">class-1 · red · Ep. Joel 2:23-24; 26-27 · Ev. Luke 5:17-26</div> + +</div> +<div class="day red"> + <span class="dom">22</span>ef-pentecost-ember-sat + <div class="meta">class-1 · red · Ep. Rom 5:1-5. · Ev. Luke 4:38-44.</div> + +</div> +<div class="day white"> + <span class="dom">23</span>ef-trinity + <div class="meta">class-1 · white · Ep. Rom 11:33-36. · Ev. Matt 28:18-20</div> + +</div> +<div class="day green"> + <span class="dom">24</span>ef-time-after-pentecost-1-monday + <div class="meta">class-4 · green · Ep. 1 John 4:8-21 · Ev. Luke 6:36-42</div> + +</div> +<div class="day white"> + <span class="dom">25</span>gregory-vii + <div class="meta">class-3 · white · Ep. 1 Pet 5:1-4; 5:10-11. · Ev. Matt 16:13-19</div> + <div class="meta">Com. urban-pope-and-martyr</div> +</div> +<div class="day white"> + <span class="dom">26</span>philip-neri + <div class="meta">class-3 · white · Ep. Wis 7:7-14. · Ev. Luke 12:35-40</div> + <div class="meta">Com. eleutherius</div> +</div> +<div class="day white"> + <span class="dom">27</span>ef-corpus-christi + <div class="meta">class-1 · white · Ep. 1 Cor 11:23-29 · Ev. John 6:56-59</div> + +</div> +<div class="day white"> + <span class="dom">28</span>augustine-of-canterbury + <div class="meta">class-3 · white · Ep. 1 Thess 2:2-9 · Ev. Luke 10:1-9</div> + +</div> +<div class="day white"> + <span class="dom">29</span>mary-magdalene-de-pazzi + <div class="meta">class-3 · white · Ep. 2 Cor 10:17-18; 11:1-2 · Ev. Matt 25:1-13.</div> + +</div> +<div class="day green"> + <span class="dom">30</span>ef-time-after-pentecost-sunday-2 + <div class="meta">class-2 · green · Ep. 1 John 3:13-18. · Ev. Luke 14:16-24.</div> + +</div> +<div class="day white"> + <span class="dom">31</span>queenship-of-the-blessed-virgin-mary + <div class="meta">class-2 · white · Ep. Eccli 24:5; 14:7; 14:9-11; 24:30-31 · Ev. Luke 1:26-33</div> + <div class="meta">Com. petronilla</div> +</div> +<h2>Iunius</h2> +<div class="day white"> + <span class="dom">1</span>angela-merici + <div class="meta">class-3 · white · Ep. 2 Cor 10:17-18; 11:1-2 · Ev. Matt 25:1-13.</div> + +</div> +<div class="day green"> + <span class="dom">2</span>ef-time-after-pentecost-2-wednesday + <div class="meta">class-4 · green · Ep. 1 John 3:13-18. · Ev. Luke 14:16-24.</div> + <div class="meta">Com. sts-marcellinus-peter-erasmus</div> +</div> +<div class="day green"> + <span class="dom">3</span>ef-time-after-pentecost-2-thursday + <div class="meta">class-4 · green · Ep. 1 John 3:13-18. · Ev. Luke 14:16-24.</div> + +</div> +<div class="day white"> + <span class="dom">4</span>ef-sacred-heart + <div class="meta">class-1 · white · Ep. Eph 3:8-12, 14-19 · Ev. John 19:31-37</div> + +</div> +<div class="day red"> + <span class="dom">5</span>boniface + <div class="meta">class-3 · red · Ep. Ecclus 44:1-15 · Ev. Matt 5:1-12</div> + +</div> +<div class="day green"> + <span class="dom">6</span>ef-time-after-pentecost-sunday-3 + <div class="meta">class-2 · green · Ep. 1 Pet. 5:6-11 · Ev. Luke 15:1-10</div> + +</div> +<div class="day green"> + <span class="dom">7</span>ef-time-after-pentecost-3-monday + <div class="meta">class-4 · green · Ep. 1 Pet. 5:6-11 · Ev. Luke 15:1-10</div> + +</div> +<div class="day green"> + <span class="dom">8</span>ef-time-after-pentecost-3-tuesday + <div class="meta">class-4 · green · Ep. 1 Pet. 5:6-11 · Ev. Luke 15:1-10</div> + +</div> +<div class="day green"> + <span class="dom">9</span>ef-time-after-pentecost-3-wednesday + <div class="meta">class-4 · green · Ep. 1 Pet. 5:6-11 · Ev. Luke 15:1-10</div> + <div class="meta">Com. sts-primus-felicianus</div> +</div> +<div class="day white"> + <span class="dom">10</span>margaret-of-scotland + <div class="meta">class-3 · white · Ep. Prov 31:10-31 · Ev. Matt 13:44-52.</div> + +</div> +<div class="day red"> + <span class="dom">11</span>barnabas + <div class="meta">class-3 · red · Ep. Acts 11:21-26; 13:1-3 · Ev. Matt 10:16-22</div> + +</div> +<div class="day white"> + <span class="dom">12</span>john-of-san-fecundo + <div class="meta">class-3 · white · Ep. Sir 31:8-11 · Ev. Luke 12:35-40</div> + <div class="meta">Com. basilidus</div> +</div> +<div class="day green"> + <span class="dom">13</span>ef-time-after-pentecost-sunday-4 + <div class="meta">class-2 · green · Ep. Rom 8:18-23 · Ev. Luke 5:1-11</div> + +</div> +<div class="day white"> + <span class="dom">14</span>basil-the-great + <div class="meta">class-3 · white · Ep. 2 Tim 4:1-8 · Ev. Luke 14:26-35</div> + +</div> +<div class="day green"> + <span class="dom">15</span>ef-time-after-pentecost-4-tuesday + <div class="meta">class-4 · green · Ep. Rom 8:18-23 · Ev. Luke 5:1-11</div> + <div class="meta">Com. vitus</div> +</div> +<div class="day green"> + <span class="dom">16</span>ef-time-after-pentecost-4-wednesday + <div class="meta">class-4 · green · Ep. Rom 8:18-23 · Ev. Luke 5:1-11</div> + +</div> +<div class="day white"> + <span class="dom">17</span>gregory-barbarigo + <div class="meta">class-3 · white · Ep. Sir 44:16-27; 45:3-20 · Ev. Matt 25:14-23</div> + +</div> +<div class="day white"> + <span class="dom">18</span>ephrem-of-syria + <div class="meta">class-3 · white · Ep. 2 Tim 4:1-8 · Ev. Matt 5:13-19</div> + <div class="meta">Com. marcus-and-marcellianus</div> +</div> +<div class="day white"> + <span class="dom">19</span>julia-of-falconieri + <div class="meta">class-3 · white · Ep. 2 Cor 10:17-18; 11:1-2 · Ev. Matt 25:1-13.</div> + <div class="meta">Com. sts-gervasius-and-protasius</div> +</div> +<div class="day green"> + <span class="dom">20</span>ef-time-after-pentecost-sunday-5 + <div class="meta">class-2 · green · Ep. 1 Pet 3:8-15. · Ev. Matt 5:20-24.</div> + +</div> +<div class="day white"> + <span class="dom">21</span>aloysius-gongzaga + <div class="meta">class-3 · white · Ep. Sir 31:8-11 · Ev. Matt 22:29-40</div> + +</div> +<div class="day white"> + <span class="dom">22</span>paulinus-of-nola + <div class="meta">class-3 · white · Ep. 2 Cor. 8:9-15 · Ev. Luke 12:32-34</div> + +</div> +<div class="day violet"> + <span class="dom">23</span>vigil-of-the-nativity-of-st-john-the-baptist + <div class="meta">class-2 · violet · Ep. Jer 1:4-10 · Ev. Luke 1:5-17</div> + +</div> +<div class="day white"> + <span class="dom">24</span>nativity-of-st-john-the-baptist + <div class="meta">class-1 · white · Ep. Isa 49:1-3, 5-7. · Ev. Luke 1:57-68</div> + +</div> +<div class="day white"> + <span class="dom">25</span>william + <div class="meta">class-3 · white · Ep. Ecclus 45:1-6 · Ev. Matt 19:27-29.</div> + +</div> +<div class="day red"> + <span class="dom">26</span>sts-john-paul + <div class="meta">class-3 · red · Ep. Eccli 44:10-15 · Ev. Luke 12:1-8</div> + +</div> +<div class="day green"> + <span class="dom">27</span>ef-time-after-pentecost-sunday-6 + <div class="meta">class-2 · green · Ep. Rom 6:3-11. · Ev. Mark 8:1-9</div> + +</div> +<div class="day violet"> + <span class="dom">28</span>vigil-of-sts-peter-paul + <div class="meta">class-2 · violet · Ep. Acts 3:1-10 · Ev. John 21:15-19</div> + +</div> +<div class="day red"> + <span class="dom">29</span>sts-peter-paul + <div class="meta">class-1 · red · Ep. Acts 12:1-11 · Ev. Matt 16:13-19</div> + +</div> +<div class="day red"> + <span class="dom">30</span>in-commemoratione-sancti-pauli-apostoli + <div class="meta">class-3 · red · Ep. Gal 1:11-20 · Ev. Matt 10:16-22</div> + <div class="meta">Com. commemoration-of-st-peter</div> +</div> +<h2>Iulius</h2> +<div class="day red"> + <span class="dom">1</span>precious-blood-of-our-lord-jesus-christ + <div class="meta">class-1 · red · Ep. Heb 9:11-15. · Ev. John 19:30-35</div> + +</div> +<div class="day white"> + <span class="dom">2</span>visitation-of-the-blessed-virgin-mary + <div class="meta">class-2 · white · Ep. Song 2:8-14 · Ev. Luke 1:39-47</div> + <div class="meta">Com. processus-and-martinian</div> +</div> +<div class="day red"> + <span class="dom">3</span>irenaeus + <div class="meta">class-3 · red · Ep. 2 Tim. 3:14-17; 4:1-5 · Ev. Matt 10:28-33</div> + +</div> +<div class="day green"> + <span class="dom">4</span>ef-time-after-pentecost-sunday-7 + <div class="meta">class-2 · green · Ep. Rom 6:19-23 · Ev. Matt 7:15-21</div> + +</div> +<div class="day white"> + <span class="dom">5</span>anthony-mary-zaccariah + <div class="meta">class-3 · white · Ep. 1 Tim. 4:8-16 · Ev. Mark 10:15-21</div> + +</div> +<div class="day green"> + <span class="dom">6</span>ef-time-after-pentecost-7-tuesday + <div class="meta">class-4 · green · Ep. Rom 6:19-23 · Ev. Matt 7:15-21</div> + +</div> +<div class="day white"> + <span class="dom">7</span>sts-cyril-methodius + <div class="meta">class-3 · white · Ep. Heb 7:23-27 · Ev. Luke 10:1-9</div> + +</div> +<div class="day white"> + <span class="dom">8</span>elizabeth-of-portugal + <div class="meta">class-3 · white · Ep. Prov 31:10-31 · Ev. Matt 13:44-52.</div> + +</div> +<div class="day green"> + <span class="dom">9</span>ef-time-after-pentecost-7-friday + <div class="meta">class-4 · green · Ep. Rom 6:19-23 · Ev. Matt 7:15-21</div> + +</div> +<div class="day red"> + <span class="dom">10</span>seven-holy-brothers-and-sts-rufina-secunda + <div class="meta">class-3 · red · Ep. Prov 31:10-31 · Ev. Matt 12:46-50</div> + +</div> +<div class="day green"> + <span class="dom">11</span>ef-time-after-pentecost-sunday-8 + <div class="meta">class-2 · green · Ep. Rom 8:12-17 · Ev. Luke 16:1-9</div> + +</div> +<div class="day white"> + <span class="dom">12</span>john-gualbert + <div class="meta">class-3 · white · Ep. Ecclus 45:1-6 · Ev. Matt 5:43-48</div> + <div class="meta">Com. naboris-et-felicis</div> +</div> +<div class="day green"> + <span class="dom">13</span>ef-time-after-pentecost-8-tuesday + <div class="meta">class-4 · green · Ep. Rom 8:12-17 · Ev. Luke 16:1-9</div> + +</div> +<div class="day white"> + <span class="dom">14</span>bonaventure + <div class="meta">class-3 · white · Ep. 2 Tim 4:1-8 · Ev. Matt 5:13-19</div> + +</div> +<div class="day white"> + <span class="dom">15</span>henry-the-emperor + <div class="meta">class-3 · white · Ep. Sir 31:8-11 · Ev. Luke 12:35-40</div> + +</div> +<div class="day green"> + <span class="dom">16</span>ef-time-after-pentecost-8-friday + <div class="meta">class-4 · green · Ep. Rom 8:12-17 · Ev. Luke 16:1-9</div> + <div class="meta">Com. our-lady-of-mt-carmel</div> +</div> +<div class="day white"> + <span class="dom">17</span>Officium sanctae Mariae in sabbato + <div class="meta">class-4 · white · Ep. Ecclus 24:14-16 · Ev. Luke 11:27-28</div> + <div class="meta">Com. alexis</div> +</div> +<div class="day green"> + <span class="dom">18</span>ef-time-after-pentecost-sunday-9 + <div class="meta">class-2 · green · Ep. 1 Cor. 10:6-13 · Ev. Luke 19:41-47</div> + +</div> +<div class="day white"> + <span class="dom">19</span>vincent-de-paul + <div class="meta">class-3 · white · Ep. 1 Cor. 4:9-14 · Ev. Luke 10:1-9</div> + +</div> +<div class="day white"> + <span class="dom">20</span>jerome-emiliani + <div class="meta">class-3 · white · Ep. Isa 58:7-11 · Ev. Matt 19:13-21</div> + <div class="meta">Com. margaret</div> +</div> +<div class="day white"> + <span class="dom">21</span>laurence-of-brindisi + <div class="meta">class-3 · white · Ep. 2 Tim 4:1-8 · Ev. Matt 5:13-19</div> + <div class="meta">Com. praxedis-virginis</div> +</div> +<div class="day white"> + <span class="dom">22</span>mary-magdalene + <div class="meta">class-3 · white · Ep. Song 3:2-5; 8:6-7 · Ev. Luke 7:36-50</div> + +</div> +<div class="day red"> + <span class="dom">23</span>apollinaris + <div class="meta">class-3 · red · Ep. 1 Pet. 5:1-11 · Ev. Luke 22:24-30</div> + <div class="meta">Com. liborii</div> +</div> +<div class="day white"> + <span class="dom">24</span>Officium sanctae Mariae in sabbato + <div class="meta">class-4 · white · Ep. Ecclus 24:14-16 · Ev. Luke 11:27-28</div> + <div class="meta">Com. christina</div> +</div> +<div class="day green"> + <span class="dom">25</span>ef-time-after-pentecost-sunday-10 + <div class="meta">class-2 · green · Ep. 1 Cor. 12:2-11 · Ev. Luke 18:9-14</div> + <div class="meta">Com. james-the-greater</div> +</div> +<div class="day white"> + <span class="dom">26</span>anne-mother-of-the-blessed-virgin + <div class="meta">class-2 · white · Ep. Prov 31:10-31 · Ev. Matt 13:44-52.</div> + +</div> +<div class="day green"> + <span class="dom">27</span>ef-time-after-pentecost-10-tuesday + <div class="meta">class-4 · green · Ep. 1 Cor. 12:2-11 · Ev. Luke 18:9-14</div> + <div class="meta">Com. pantaleon</div> +</div> +<div class="day red"> + <span class="dom">28</span>sts-nazarius-celsus-st-victor-i-st-innocent-i + <div class="meta">class-3 · red · Ep. Wis 10:17-20 · Ev. Luke 21:9-19</div> + +</div> +<div class="day white"> + <span class="dom">29</span>martha + <div class="meta">class-3 · white · Ep. 2 Cor 10:17-18; 11:1-2 · Ev. Luke 10:38-42</div> + <div class="meta">Com. felicis-simplicii-faustini-et-beatricis</div> +</div> +<div class="day green"> + <span class="dom">30</span>ef-time-after-pentecost-10-friday + <div class="meta">class-4 · green · Ep. 1 Cor. 12:2-11 · Ev. Luke 18:9-14</div> + <div class="meta">Com. sts-abdon-sennen</div> +</div> +<div class="day white"> + <span class="dom">31</span>ignatius-loyola + <div class="meta">class-3 · white · Ep. 2 Tim. 2:8-10; 3:10-12. · Ev. Luke 10:1-9</div> + +</div> +<h2>Augustus</h2> +<div class="day green"> + <span class="dom">1</span>ef-time-after-pentecost-sunday-11 + <div class="meta">class-2 · green · Ep. 1 Cor. 15:1-10 · Ev. Mark 7:31-37</div> + +</div> +<div class="day white"> + <span class="dom">2</span>alphonsus-liguori + <div class="meta">class-3 · white · Ep. 2 Tim. 2:1-7 · Ev. Luke 10:1-9</div> + <div class="meta">Com. stephen-i-pope-and-martyr</div> +</div> +<div class="day green"> + <span class="dom">3</span>ef-time-after-pentecost-11-tuesday + <div class="meta">class-4 · green · Ep. 1 Cor. 15:1-10 · Ev. Mark 7:31-37</div> + +</div> +<div class="day white"> + <span class="dom">4</span>dominic + <div class="meta">class-3 · white · Ep. 2 Tim. 4:1-8 · Ev. Luke 12:35-40</div> + +</div> +<div class="day white"> + <span class="dom">5</span>dedication-of-the-basilica-of-st-mary-major + <div class="meta">class-3 · white · Ep. Ecclus 24:14-16 · Ev. Luke 11:27-28</div> + +</div> +<div class="day white"> + <span class="dom">6</span>transfiguration-of-our-lord + <div class="meta">class-2 · white · Ep. 2 Pet. 1:16-19 · Ev. Matt 17:1-9</div> + <div class="meta">Com. pope-sixtus-ii-felicissimus-and-agapitus-martyrs</div> +</div> +<div class="day white"> + <span class="dom">7</span>cajetan + <div class="meta">class-3 · white · Ep. Sir 31:8-11 · Ev. Matt 6:24-33</div> + <div class="meta">Com. donatus</div> +</div> +<div class="day green"> + <span class="dom">8</span>ef-time-after-pentecost-sunday-12 + <div class="meta">class-2 · green · Ep. 2 Cor. 3:4-9 · Ev. Luke 10:23-37</div> + +</div> +<div class="day violet"> + <span class="dom">9</span>vigil-of-st-lawrence + <div class="meta">class-3 · violet · Ep. Ecclus 51:1-8, 12 · Ev. Matt 16:24-27</div> + <div class="meta">Com. romanus</div> +</div> +<div class="day red"> + <span class="dom">10</span>lawrence + <div class="meta">class-2 · red · Ep. 2 Cor. 9:6-10 · Ev. John 12:24-26</div> + +</div> +<div class="day green"> + <span class="dom">11</span>ef-time-after-pentecost-12-wednesday + <div class="meta">class-4 · green · Ep. 2 Cor. 3:4-9 · Ev. Luke 10:23-37</div> + <div class="meta">Com. sts-tiburtius-susanna</div> +</div> +<div class="day white"> + <span class="dom">12</span>clare + <div class="meta">class-3 · white · Ep. 2 Cor 10:17-18; 11:1-2 · Ev. Matt 25:1-13.</div> + +</div> +<div class="day green"> + <span class="dom">13</span>ef-time-after-pentecost-12-friday + <div class="meta">class-4 · green · Ep. 2 Cor. 3:4-9 · Ev. Luke 10:23-37</div> + <div class="meta">Com. sts-hippolytus-cassian</div> +</div> +<div class="day violet"> + <span class="dom">14</span>vigil-of-the-assumption + <div class="meta">class-2 · violet · Ep. Sir 24:23-31 · Ev. Luke 11:27-28</div> + <div class="meta">Com. eusebius-confessor</div> +</div> +<div class="day white"> + <span class="dom">15</span>assumption-of-the-blessed-virgin-mary + <div class="meta">class-1 · white · Ep. Judith 13:22-25; 15:10 · Ev. Luke 1:41-50</div> + <div class="meta">Com. ef-time-after-pentecost-sunday-13</div> +</div> +<div class="day white"> + <span class="dom">16</span>joachim-father-of-the-blessed-virgin + <div class="meta">class-2 · white · Ep. Sir 31:8-11 · Ev. Matt 1:1-16</div> + +</div> +<div class="day white"> + <span class="dom">17</span>hyacinth + <div class="meta">class-3 · white · Ep. Sir 31:8-11 · Ev. Luke 12:35-40</div> + +</div> +<div class="day green"> + <span class="dom">18</span>ef-time-after-pentecost-13-wednesday + <div class="meta">class-4 · green · Ep. Gal 3:16-22 · Ev. Luke 17:11-19</div> + <div class="meta">Com. agapitus</div> +</div> +<div class="day white"> + <span class="dom">19</span>john-eudes + <div class="meta">class-3 · white · Ep. Sir 31:8-11 · Ev. Luke 12:35-40</div> + +</div> +<div class="day white"> + <span class="dom">20</span>bernard-of-clairvaux + <div class="meta">class-3 · white · Ep. Ecclus 39:6-14 · Ev. Matt 5:13-19</div> + +</div> +<div class="day white"> + <span class="dom">21</span>jane-frances-de-chantal + <div class="meta">class-3 · white · Ep. Prov 31:10-31 · Ev. Matt 13:44-52.</div> + +</div> +<div class="day green"> + <span class="dom">22</span>ef-time-after-pentecost-sunday-14 + <div class="meta">class-2 · green · Ep. Gal 5:16-24 · Ev. Matt 6:24-33</div> + <div class="meta">Com. immaculate-heart-of-mary</div> +</div> +<div class="day white"> + <span class="dom">23</span>philip-benizi + <div class="meta">class-3 · white · Ep. 1 Cor. 4:9-14 · Ev. Luke 12:32-34</div> + +</div> +<div class="day red"> + <span class="dom">24</span>bartholomew + <div class="meta">class-2 · red · Ep. 1 Cor. 12:27-31 · Ev. Luke 6:12-19</div> + +</div> +<div class="day white"> + <span class="dom">25</span>louis-ix + <div class="meta">class-3 · white · Ep. Wis 10:10-14 · Ev. Luke 19:12-26</div> + +</div> +<div class="day green"> + <span class="dom">26</span>ef-time-after-pentecost-14-thursday + <div class="meta">class-4 · green · Ep. Gal 5:16-24 · Ev. Matt 6:24-33</div> + <div class="meta">Com. zephyrinus</div> +</div> +<div class="day white"> + <span class="dom">27</span>joseph-calasance + <div class="meta">class-3 · white · Ep. Wis 10:10-14 · Ev. Matt 18:1-5</div> + +</div> +<div class="day white"> + <span class="dom">28</span>augustine + <div class="meta">class-3 · white · Ep. 2 Tim 4:1-8 · Ev. Matt 5:13-19</div> + <div class="meta">Com. hermes</div> +</div> +<div class="day green"> + <span class="dom">29</span>ef-time-after-pentecost-sunday-15 + <div class="meta">class-2 · green · Ep. Gal 5:25-26; 6:1-10 · Ev. Luke 7:11-16</div> + +</div> +<div class="day white"> + <span class="dom">30</span>rose-of-lima + <div class="meta">class-3 · white · Ep. 2 Cor 10:17-18; 11:1-2 · Ev. Matt 25:1-13.</div> + <div class="meta">Com. sts-felix-and-adauctus</div> +</div> +<div class="day white"> + <span class="dom">31</span>raymond-nonnatus + <div class="meta">class-3 · white · Ep. Sir 31:8-11 · Ev. Luke 12:35-40</div> + +</div> +<h2>September</h2> +<div class="day green"> + <span class="dom">1</span>ef-time-after-pentecost-15-wednesday + <div class="meta">class-4 · green · Ep. Gal 5:25-26; 6:1-10 · Ev. Luke 7:11-16</div> + <div class="meta">Com. giles</div><div class="meta">Com. twelve-holy-brothers-martyrs</div> +</div> +<div class="day white"> + <span class="dom">2</span>stephen-of-hungary + <div class="meta">class-3 · white · Ep. Sir 31:8-11 · Ev. Luke 19:12-26</div> + +</div> +<div class="day white"> + <span class="dom">3</span>pius-x + <div class="meta">class-3 · white · Ep. 1 Thess. 2:2-8 · Ev. John 21:15-17</div> + +</div> +<div class="day white"> + <span class="dom">4</span>Officium sanctae Mariae in sabbato + <div class="meta">class-4 · white · Ep. Ecclus 24:14-16 · Ev. Luke 11:27-28</div> + +</div> +<div class="day green"> + <span class="dom">5</span>ef-time-after-pentecost-sunday-16 + <div class="meta">class-2 · green · Ep. Eph 3:13-21 · Ev. Luke 14:1-11</div> + +</div> +<div class="day green"> + <span class="dom">6</span>ef-time-after-pentecost-16-monday + <div class="meta">class-4 · green · Ep. Eph 3:13-21 · Ev. Luke 14:1-11</div> + +</div> +<div class="day green"> + <span class="dom">7</span>ef-time-after-pentecost-16-tuesday + <div class="meta">class-4 · green · Ep. Eph 3:13-21 · Ev. Luke 14:1-11</div> + +</div> +<div class="day white"> + <span class="dom">8</span>nativity-of-the-blessed-virgin-mary + <div class="meta">class-2 · white · Ep. Prov 8:22-35 · Ev. Matt 1:1-16</div> + <div class="meta">Com. hadriani</div> +</div> +<div class="day green"> + <span class="dom">9</span>ef-time-after-pentecost-16-thursday + <div class="meta">class-4 · green · Ep. Eph 3:13-21 · Ev. Luke 14:1-11</div> + <div class="meta">Com. gorgonius</div> +</div> +<div class="day white"> + <span class="dom">10</span>nicholas-of-tolentino + <div class="meta">class-3 · white · Ep. 1 Cor. 4:9-14 · Ev. Luke 12:32-34</div> + +</div> +<div class="day white"> + <span class="dom">11</span>Officium sanctae Mariae in sabbato + <div class="meta">class-4 · white · Ep. Ecclus 24:14-16 · Ev. Luke 11:27-28</div> + <div class="meta">Com. sts-protus-hyacinth</div> +</div> +<div class="day green"> + <span class="dom">12</span>ef-time-after-pentecost-sunday-17 + <div class="meta">class-2 · green · Ep. Eph 4:1-6 · Ev. Matt 22:34-46</div> + +</div> +<div class="day green"> + <span class="dom">13</span>ef-time-after-pentecost-17-monday + <div class="meta">class-4 · green · Ep. Eph 4:1-6 · Ev. Matt 22:34-46</div> + +</div> +<div class="day red"> + <span class="dom">14</span>exaltation-of-the-holy-cross + <div class="meta">class-2 · red · Ep. Phil 2:5-11 · Ev. John 12:31-36</div> + +</div> +<div class="day white"> + <span class="dom">15</span>seven-sorrows-of-the-blessed-virgin-mary + <div class="meta">class-2 · white · Ep. Judith 13:22; 13:23-25 · Ev. John 19:25-27</div> + <div class="meta">Com. nicomedes</div> +</div> +<div class="day red"> + <span class="dom">16</span>sts-cornelius-cyprian + <div class="meta">class-3 · red · Ep. Wis 3:1-8 · Ev. Luke 21:9-19</div> + <div class="meta">Com. sts-euphemia-lucy-and-geminianus</div> +</div> +<div class="day green"> + <span class="dom">17</span>ef-time-after-pentecost-17-friday + <div class="meta">class-4 · green · Ep. Eph 4:1-6 · Ev. Matt 22:34-46</div> + <div class="meta">Com. stigmata-of-st-francis</div> +</div> +<div class="day white"> + <span class="dom">18</span>joseph-of-cupertino + <div class="meta">class-3 · white · Ep. 1 Cor 13:1-8 · Ev. Matt 22:1-14</div> + +</div> +<div class="day green"> + <span class="dom">19</span>ef-time-after-pentecost-sunday-18 + <div class="meta">class-2 · green · Ep. 1 Cor. 1:4-8 · Ev. Matt 9:1-8</div> + +</div> +<div class="day green"> + <span class="dom">20</span>ef-time-after-pentecost-18-monday + <div class="meta">class-4 · green · Ep. 1 Cor. 1:4-8 · Ev. Matt 9:1-8</div> + <div class="meta">Com. sts-eustace-companions</div> +</div> +<div class="day red"> + <span class="dom">21</span>matthew + <div class="meta">class-2 · red · Ep. Ezek 1:10-14 · Ev. Matt 9:9-13</div> + +</div> +<div class="day violet"> + <span class="dom">22</span>ef-september-ember-wed + <div class="meta">class-2 · violet · Ep. 2 Esd. 8:1-10 · Ev. Mark 9:16-28</div> + <div class="meta">Com. thomas-of-villanova</div> +</div> +<div class="day red"> + <span class="dom">23</span>linus + <div class="meta">class-3 · red · Ep. 1 Pet 5:1-4; 5:10-11. · Ev. Matt 16:13-19</div> + <div class="meta">Com. thecla</div> +</div> +<div class="day violet"> + <span class="dom">24</span>ef-september-ember-fri + <div class="meta">class-2 · violet · Ep. Osee 14:2-10 · Ev. Luke 7:36-50</div> + <div class="meta">Com. our-lady-of-ransom</div> +</div> +<div class="day violet"> + <span class="dom">25</span>ef-september-ember-sat + <div class="meta">class-2 · violet · Ep. Heb 9:2-12 · Ev. Luke 13:6-17</div> + +</div> +<div class="day green"> + <span class="dom">26</span>ef-time-after-pentecost-sunday-19 + <div class="meta">class-2 · green · Ep. Eph 4:23-28 · Ev. Matt 22:1-14</div> + +</div> +<div class="day red"> + <span class="dom">27</span>sts-cosmas-damian + <div class="meta">class-3 · red · Ep. Wis 5:16-20 · Ev. Luke 6:17-23</div> + +</div> +<div class="day red"> + <span class="dom">28</span>wenceslaus + <div class="meta">class-3 · red · Ep. Wis 10:10-14 · Ev. Matt 10:34-42</div> + +</div> +<div class="day white"> + <span class="dom">29</span>dedication-of-st-michael-the-archangel + <div class="meta">class-1 · white · Ep. Rev 1:1-5 · Ev. Matt 18:1-10</div> + +</div> +<div class="day white"> + <span class="dom">30</span>jerome + <div class="meta">class-3 · white · Ep. 2 Tim 4:1-8 · Ev. Matt 5:13-19</div> + +</div> +<h2>October</h2> +<div class="day green"> + <span class="dom">1</span>ef-time-after-pentecost-19-friday + <div class="meta">class-4 · green · Ep. Eph 4:23-28 · Ev. Matt 22:1-14</div> + <div class="meta">Com. remigius</div> +</div> +<div class="day white"> + <span class="dom">2</span>holy-guardian-angels + <div class="meta">class-3 · white · Ep. Exod 23:20-23 · Ev. Matt 18:1-10</div> + +</div> +<div class="day green"> + <span class="dom">3</span>ef-time-after-pentecost-sunday-20 + <div class="meta">class-2 · green · Ep. Eph 5:15-21 · Ev. John 4:46-53</div> + +</div> +<div class="day white"> + <span class="dom">4</span>francis-of-assisi + <div class="meta">class-3 · white · Ep. Gal 6:14-18 · Ev. Matt 11:25-30</div> + +</div> +<div class="day green"> + <span class="dom">5</span>ef-time-after-pentecost-20-tuesday + <div class="meta">class-4 · green · Ep. Eph 5:15-21 · Ev. John 4:46-53</div> + <div class="meta">Com. placid-companions</div> +</div> +<div class="day white"> + <span class="dom">6</span>bruno + <div class="meta">class-3 · white · Ep. Sir 31:8-11 · Ev. Luke 12:35-40</div> + +</div> +<div class="day white"> + <span class="dom">7</span>our-lady-of-the-rosary + <div class="meta">class-2 · white · Ep. Prov 8:22-24, 32-35. · Ev. Luke 1:26-38</div> + <div class="meta">Com. mark-i</div> +</div> +<div class="day white"> + <span class="dom">8</span>bridget-of-sweden + <div class="meta">class-3 · white · Ep. 1 Tim. 5:3-10. · Ev. Matt 13:44-52.</div> + <div class="meta">Com. sergio-baccho-marcello-and-apulejo-martyrs</div> +</div> +<div class="day white"> + <span class="dom">9</span>john-leonardi + <div class="meta">class-3 · white · Ep. 2 Cor 4:1-6; 4:15-18 · Ev. Luke 10:1-9</div> + <div class="meta">Com. dionysius-and-companions</div> +</div> +<div class="day green"> + <span class="dom">10</span>ef-time-after-pentecost-sunday-21 + <div class="meta">class-2 · green · Ep. Eph 6:10-17 · Ev. Matt 18:23-35</div> + +</div> +<div class="day white"> + <span class="dom">11</span>maternity-of-the-blessed-virgin-mary + <div class="meta">class-2 · white · Ep. Sir 24:23-31 · Ev. Luke 2:43-51</div> + +</div> +<div class="day green"> + <span class="dom">12</span>ef-time-after-pentecost-21-tuesday + <div class="meta">class-4 · green · Ep. Eph 6:10-17 · Ev. Matt 18:23-35</div> + +</div> +<div class="day white"> + <span class="dom">13</span>edward + <div class="meta">class-3 · white · Ep. Sir 31:8-11 · Ev. Luke 12:35-40</div> + +</div> +<div class="day red"> + <span class="dom">14</span>callistus-i + <div class="meta">class-3 · red · Ep. 1 Pet 5:1-4; 5:10-11. · Ev. Matt 16:13-19</div> + +</div> +<div class="day white"> + <span class="dom">15</span>teresa-of-avila + <div class="meta">class-3 · white · Ep. 2 Cor 10:17-18; 11:1-2 · Ev. Matt 25:1-13.</div> + +</div> +<div class="day white"> + <span class="dom">16</span>hedwig + <div class="meta">class-3 · white · Ep. Prov 31:10-31 · Ev. Matt 13:44-52.</div> + +</div> +<div class="day green"> + <span class="dom">17</span>ef-time-after-pentecost-sunday-22 + <div class="meta">class-2 · green · Ep. Phil 1:6-11 · Ev. Matt 22:15-21</div> + +</div> +<div class="day red"> + <span class="dom">18</span>luke-the-evangelist + <div class="meta">class-2 · red · Ep. 2 Cor. 8:16-24 · Ev. Luke 10:1-9</div> + +</div> +<div class="day white"> + <span class="dom">19</span>peter-of-alcantara + <div class="meta">class-3 · white · Ep. Phil 3:7-12 · Ev. Luke 12:32-34</div> + +</div> +<div class="day white"> + <span class="dom">20</span>john-cantius + <div class="meta">class-3 · white · Ep. James 2:12-17 · Ev. Luke 12:35-40</div> + +</div> +<div class="day green"> + <span class="dom">21</span>ef-time-after-pentecost-22-thursday + <div class="meta">class-4 · green · Ep. Phil 1:6-11 · Ev. Matt 22:15-21</div> + <div class="meta">Com. hilarion</div><div class="meta">Com. ursula-and-companions</div> +</div> +<div class="day green"> + <span class="dom">22</span>ef-time-after-pentecost-22-friday + <div class="meta">class-4 · green · Ep. Phil 1:6-11 · Ev. Matt 22:15-21</div> + +</div> +<div class="day white"> + <span class="dom">23</span>anthony-mary-claret + <div class="meta">class-3 · white · Ep. Heb 7:23-27 · Ev. Matt 24:42-47</div> + +</div> +<div class="day green"> + <span class="dom">24</span>ef-time-after-pentecost-sunday-23 + <div class="meta">class-2 · green · Ep. Phil 3:17-21; 4:1-3 · Ev. Matt 9:18-26</div> + +</div> +<div class="day green"> + <span class="dom">25</span>ef-time-after-pentecost-23-monday + <div class="meta">class-4 · green · Ep. Phil 3:17-21; 4:1-3 · Ev. Matt 9:18-26</div> + <div class="meta">Com. sts-chrysanthus-daria</div> +</div> +<div class="day green"> + <span class="dom">26</span>ef-time-after-pentecost-23-tuesday + <div class="meta">class-4 · green · Ep. Phil 3:17-21; 4:1-3 · Ev. Matt 9:18-26</div> + <div class="meta">Com. evaristus</div> +</div> +<div class="day green"> + <span class="dom">27</span>ef-time-after-pentecost-23-wednesday + <div class="meta">class-4 · green · Ep. Phil 3:17-21; 4:1-3 · Ev. Matt 9:18-26</div> + +</div> +<div class="day red"> + <span class="dom">28</span>sts-simon-jude + <div class="meta">class-2 · red · Ep. Eph. 4:7-13. · Ev. John 15:17-25</div> + +</div> +<div class="day green"> + <span class="dom">29</span>ef-time-after-pentecost-23-friday + <div class="meta">class-4 · green · Ep. Phil 3:17-21; 4:1-3 · Ev. Matt 9:18-26</div> + +</div> +<div class="day white"> + <span class="dom">30</span>Officium sanctae Mariae in sabbato + <div class="meta">class-4 · white · Ep. Ecclus 24:14-16 · Ev. Luke 11:27-28</div> + +</div> +<div class="day white"> + <span class="dom">31</span>ef-christ-the-king + <div class="meta">class-1 · white · Ep. Col 1:12-20. · Ev. John 18:33-37</div> + +</div> +<h2>November</h2> +<div class="day white"> + <span class="dom">1</span>all-saints + <div class="meta">class-1 · white · Ep. Apoc 7:2-12 · Ev. Matt 5:1-12</div> + +</div> +<div class="day black"> + <span class="dom">2</span>commemoration-of-all-souls + <div class="meta">class-1 · black · Ep. 1 Cor. 15:51-57 · Ev. John 5:25-29</div> + +</div> +<div class="day green"> + <span class="dom">3</span>ef-time-after-pentecost-24-wednesday + <div class="meta">class-4 · green · Ep. Col 1:12-20. · Ev. John 18:33-37</div> + +</div> +<div class="day white"> + <span class="dom">4</span>charles-borromeo + <div class="meta">class-3 · white · Ep. Sir 44:16-27; 45:3-20 · Ev. Matt 25:14-23</div> + <div class="meta">Com. sts-vitalis-and-agricola-martyrs</div> +</div> +<div class="day green"> + <span class="dom">5</span>ef-time-after-pentecost-24-friday + <div class="meta">class-4 · green · Ep. Col 1:12-20. · Ev. John 18:33-37</div> + +</div> +<div class="day white"> + <span class="dom">6</span>Officium sanctae Mariae in sabbato + <div class="meta">class-4 · white · Ep. Ecclus 24:14-16 · Ev. Luke 11:27-28</div> + +</div> +<div class="day green"> + <span class="dom">7</span>ef-time-after-epiphany-sunday-5 + <div class="meta">class-2 · green · Ep. Col 3:12-17 · Ev. Matt 13:24-30</div> + +</div> +<div class="day green"> + <span class="dom">8</span>ef-time-after-pentecost-25-monday + <div class="meta">class-4 · green · Ep. Col 3:12-17 · Ev. Matt 13:24-30</div> + <div class="meta">Com. four-holy-crowned-martyrs</div> +</div> +<div class="day white"> + <span class="dom">9</span>dedication-of-the-archbasilica-of-our-holy-savior + <div class="meta">class-2 · white · Ep. Rev 21:2-5 · Ev. Luke 19:1-10</div> + <div class="meta">Com. theodore</div> +</div> +<div class="day white"> + <span class="dom">10</span>andrew-avellino + <div class="meta">class-3 · white · Ep. Sir 31:8-11 · Ev. Luke 12:35-40</div> + <div class="meta">Com. sts-tryphonis-respicii-et-nymphae</div> +</div> +<div class="day white"> + <span class="dom">11</span>martin-of-tours + <div class="meta">class-3 · white · Ep. Sir 44:16-27; 45:3-20 · Ev. Luke 11:33-36</div> + <div class="meta">Com. menna</div> +</div> +<div class="day red"> + <span class="dom">12</span>martin-i + <div class="meta">class-3 · red · Ep. 1 Pet 5:1-4; 5:10-11. · Ev. Matt 16:13-19</div> + +</div> +<div class="day white"> + <span class="dom">13</span>didacus + <div class="meta">class-3 · white · Ep. 1 Cor 4:9-14 · Ev. Luke 12:32-34</div> + +</div> +<div class="day green"> + <span class="dom">14</span>ef-time-after-epiphany-sunday-6 + <div class="meta">class-2 · green · Ep. 1 Thess 1:2-10 · Ev. Matt 13:31-35</div> + +</div> +<div class="day white"> + <span class="dom">15</span>albert-the-great + <div class="meta">class-3 · white · Ep. 2 Tim 4:1-8 · Ev. Matt 5:13-19</div> + +</div> +<div class="day white"> + <span class="dom">16</span>gertrude-the-great + <div class="meta">class-3 · white · Ep. 2 Cor 10:17-18; 11:1-2 · Ev. Matt 25:1-13.</div> + +</div> +<div class="day white"> + <span class="dom">17</span>gregory-the-wonderworker + <div class="meta">class-3 · white · Ep. Sir 44:16-27; 45:3-20 · Ev. Mark 11:22-24</div> + +</div> +<div class="day white"> + <span class="dom">18</span>dedication-of-the-basilicas-of-sts-peter-paul + <div class="meta">class-3 · white · Ep. Rev 21:2-5 · Ev. Luke 19:1-10</div> + +</div> +<div class="day white"> + <span class="dom">19</span>elizabeth-of-hungary + <div class="meta">class-3 · white · Ep. Prov 31:10-31 · Ev. Matt 13:44-52.</div> + <div class="meta">Com. pontian</div> +</div> +<div class="day white"> + <span class="dom">20</span>felix-of-valois + <div class="meta">class-3 · white · Ep. 1 Cor. 4:9-14 · Ev. Luke 12:32-34</div> + +</div> +<div class="day green"> + <span class="dom">21</span>ef-time-after-pentecost-sunday-24 + <div class="meta">class-2 · green · Ep. Col 1:9-14 · Ev. Matt 24:15-35</div> + +</div> +<div class="day red"> + <span class="dom">22</span>cecilia + <div class="meta">class-3 · red · Ep. Sir 51:13-17. · Ev. Matt 25:1-13.</div> + +</div> +<div class="day red"> + <span class="dom">23</span>clement-i + <div class="meta">class-3 · red · Ep. Phil 3:17-21; 4:1-3 · Ev. Matt 16:13-19</div> + <div class="meta">Com. felicity</div> +</div> +<div class="day white"> + <span class="dom">24</span>john-of-the-cross + <div class="meta">class-3 · white · Ep. 2 Tim 4:1-8 · Ev. Matt 5:13-19</div> + <div class="meta">Com. chrysogonus</div> +</div> +<div class="day red"> + <span class="dom">25</span>catherine-of-alexandria + <div class="meta">class-3 · red · Ep. Sir 51:1-8; 51:12 · Ev. Matt 25:1-13.</div> + +</div> +<div class="day white"> + <span class="dom">26</span>sylvester + <div class="meta">class-3 · white · Ep. Ecclus 45:1-6 · Ev. Matt 19:27-29.</div> + <div class="meta">Com. peter-of-alexandria</div> +</div> +<div class="day white"> + <span class="dom">27</span>Officium sanctae Mariae in sabbato + <div class="meta">class-4 · white · Ep. Ecclus 24:14-16 · Ev. Luke 11:27-28</div> + +</div> +<div class="day violet"> + <span class="dom">28</span>ef-advent-sunday-1 + <div class="meta">class-1 · violet · Ep. Rom 13:11-14 · Ev. Luke 21:25-33</div> + +</div> +<div class="day violet"> + <span class="dom">29</span>ef-advent-1-monday + <div class="meta">class-3 · violet · Ep. Rom 13:11-14 · Ev. Luke 21:25-33</div> + <div class="meta">Com. saturninus</div> +</div> +<div class="day red"> + <span class="dom">30</span>andrew + <div class="meta">class-2 · red · Ep. Rom 10:10-18 · Ev. Matt 4:18-22</div> + <div class="meta">Com. ef-advent-1-tuesday</div> +</div> +<h2>December</h2> +<div class="day violet"> + <span class="dom">1</span>ef-advent-1-wednesday + <div class="meta">class-3 · violet · Ep. Rom 13:11-14 · Ev. Luke 21:25-33</div> + +</div> +<div class="day red"> + <span class="dom">2</span>vivian + <div class="meta">class-3 · red · Ep. Sir 51:13-17. · Ev. Matt 13:44-52.</div> + <div class="meta">Com. ef-advent-1-thursday</div> +</div> +<div class="day white"> + <span class="dom">3</span>francis-xavier + <div class="meta">class-3 · white · Ep. Rom 10:10-18 · Ev. Mark 16:15-18</div> + <div class="meta">Com. ef-advent-1-friday</div> +</div> +<div class="day white"> + <span class="dom">4</span>peter-chrysologus + <div class="meta">class-3 · white · Ep. 2 Tim 4:1-8 · Ev. Matt 5:13-19</div> + <div class="meta">Com. ef-advent-1-saturday</div><div class="meta">Com. barbara</div> +</div> +<div class="day violet"> + <span class="dom">5</span>ef-advent-sunday-2 + <div class="meta">class-1 · violet · Ep. Rom 15:4-13 · Ev. Matt 11:2-10</div> + +</div> +<div class="day white"> + <span class="dom">6</span>nicholas + <div class="meta">class-3 · white · Ep. Heb 13:7-17 · Ev. Matt 25:14-23</div> + <div class="meta">Com. ef-advent-2-monday</div> +</div> +<div class="day white"> + <span class="dom">7</span>ambrose + <div class="meta">class-3 · white · Ep. 2 Tim 4:1-8 · Ev. Matt 5:13-19</div> + <div class="meta">Com. ef-advent-2-tuesday</div> +</div> +<div class="day white"> + <span class="dom">8</span>immaculate-conception-of-the-blessed-virgin-mary + <div class="meta">class-1 · white · Ep. Prov 8:22-35 · Ev. Luke 1:26-28</div> + <div class="meta">Com. ef-advent-2-wednesday</div> +</div> +<div class="day violet"> + <span class="dom">9</span>ef-advent-2-thursday + <div class="meta">class-3 · violet · Ep. Rom 15:4-13 · Ev. Matt 11:2-10</div> + +</div> +<div class="day violet"> + <span class="dom">10</span>ef-advent-2-friday + <div class="meta">class-3 · violet · Ep. Rom 15:4-13 · Ev. Matt 11:2-10</div> + <div class="meta">Com. melchiades</div> +</div> +<div class="day white"> + <span class="dom">11</span>damasus-i + <div class="meta">class-3 · white · Ep. 1 Pet 5:1-4; 5:10-11. · Ev. Matt 16:13-19</div> + <div class="meta">Com. ef-advent-2-saturday</div> +</div> +<div class="day rose"> + <span class="dom">12</span>ef-advent-sunday-3 + <div class="meta">class-1 · rose · Ep. Phil 4:4-7 · Ev. John 1:19-28</div> + +</div> +<div class="day red"> + <span class="dom">13</span>lucy + <div class="meta">class-3 · red · Ep. 2 Cor 10:17-18; 11:1-2 · Ev. Matt 13:44-52.</div> + <div class="meta">Com. ef-advent-3-monday</div> +</div> +<div class="day violet"> + <span class="dom">14</span>ef-advent-3-tuesday + <div class="meta">class-3 · violet · Ep. Phil 4:4-7 · Ev. John 1:19-28</div> + +</div> +<div class="day violet"> + <span class="dom">15</span>ef-advent-ember-wed + <div class="meta">class-2 · violet · Ep. Isa 7:10-15 · Ev. Luke 1:26-38</div> + +</div> +<div class="day red"> + <span class="dom">16</span>eusebius + <div class="meta">class-3 · red · Ep. 2 Cor. 1:3-7 · Ev. Matt 16:24-27.</div> + <div class="meta">Com. ef-advent-3-thursday</div> +</div> +<div class="day violet"> + <span class="dom">17</span>ef-advent-ember-fri + <div class="meta">class-2 · violet · Ep. Isa 11:1-5 · Ev. Luke 1:39-47</div> + +</div> +<div class="day violet"> + <span class="dom">18</span>ef-advent-ember-sat + <div class="meta">class-2 · violet · Ep. 2 Thess 2:1-8 · Ev. Luke 3:1-6</div> + +</div> +<div class="day violet"> + <span class="dom">19</span>ef-advent-sunday-4 + <div class="meta">class-1 · violet · Ep. 1 Cor. 4:1-5 · Ev. Luke 3:1-6</div> + +</div> +<div class="day violet"> + <span class="dom">20</span>ef-advent-4-monday + <div class="meta">class-2 · violet · Ep. 1 Cor. 4:1-5 · Ev. Luke 3:1-6</div> + +</div> +<div class="day red"> + <span class="dom">21</span>thomas + <div class="meta">class-2 · red · Ep. Eph 2:19-22 · Ev. John 20:24-29</div> + <div class="meta">Com. ef-advent-4-tuesday</div> +</div> +<div class="day violet"> + <span class="dom">22</span>ef-advent-4-wednesday + <div class="meta">class-2 · violet · Ep. 1 Cor. 4:1-5 · Ev. Luke 3:1-6</div> + +</div> +<div class="day violet"> + <span class="dom">23</span>ef-advent-4-thursday + <div class="meta">class-2 · violet · Ep. 1 Cor. 4:1-5 · Ev. Luke 3:1-6</div> + +</div> +<div class="day violet"> + <span class="dom">24</span>ef-nativity-vigil + <div class="meta">class-1 · violet · Ep. Rom 1:1-6 · Ev. Matt 1:18-21</div> + +</div> +<div class="day white"> + <span class="dom">25</span>ef-nativity + <div class="meta">class-1 · white · Ep. Heb 1:1-12 · Ev. John 1:1-14</div> + +</div> +<div class="day white"> + <span class="dom">26</span>ef-christmas-sunday-0 + <div class="meta">class-2 · white · Ep. Gal 4:1-7 · Ev. Luke 2:33-40</div> + <div class="meta">Com. stephen</div> +</div> +<div class="day white"> + <span class="dom">27</span>john-the-evangelist + <div class="meta">class-2 · white · Ep. Ecclus 15:1-6 · Ev. John 21:19-24</div> + <div class="meta">Com. ef-nativity-octave-day-3</div> +</div> +<div class="day red"> + <span class="dom">28</span>holy-innocents + <div class="meta">class-2 · red · Ep. Apoc 14:1-5 · Ev. Matt 2:13-18</div> + <div class="meta">Com. ef-nativity-octave-day-4</div> +</div> +<div class="day white"> + <span class="dom">29</span>ef-nativity-octave-day-5 + <div class="meta">class-2 · white · Ep. Titus 3:4-7 · Ev. Luke 2:15-20</div> + <div class="meta">Com. thomas-becket</div> +</div> +<div class="day white"> + <span class="dom">30</span>ef-nativity-octave-day-6 + <div class="meta">class-2 · white · Ep. Titus 3:4-7 · Ev. Luke 2:15-20</div> + +</div> +<div class="day white"> + <span class="dom">31</span>ef-nativity-octave-day-7 + <div class="meta">class-2 · white · Ep. Titus 3:4-7 · Ev. Luke 2:15-20</div> + <div class="meta">Com. silvester</div> +</div> + +</body></html> diff --git a/test/golden/ordo-2027.md b/test/golden/ordo-2027.md new file mode 100644 index 0000000..4980cb6 --- /dev/null +++ b/test/golden/ordo-2027.md @@ -0,0 +1,2122 @@ +<!-- colitur ordo booklet -- Markdown. flavour: none --> +<!-- Markdown's own metacharacters (*, _, `, [, ...) are context-dependent, + so this template's flavour deliberately does NOT escape interpolated + values. A feast name containing `*` or `_` will render as emphasis. + That is a documented limitation, not a bug to fix. --> +<!-- Day label falls back to the slug when the day carries no Latin name + (most temporal days, and most sanctoral entries, which are Latin-less + in the shipped data) -- see ordo.tex's own comment for why the fallback + is written as a name-section wrapping a plain var and its inverse, + rather than a single dotted lookup and its inverse. --> +# Ordo 2027 · ef + + +## Ianuarius + + +**1** ef-circumcision +`class-1` · white · Ep. Titus 2:11-15 · Ev. Luke 2:21 + + + +**2** Officium sanctae Mariae in sabbato +`class-4` · white · Ep. Titus 3:4-7 · Ev. Luke 2:15-20 + + + +**3** Sanctissimi Nominis Iesu +`class-2` · white · Ep. Acts 4:8-12 · Ev. Luke 2:21 + + + +**4** ef-christmas-1-monday +`class-4` · white · Ep. Titus 2:11-15 · Ev. Luke 2:21 + + + +**5** ef-christmas-1-tuesday +`class-4` · white · Ep. Titus 2:11-15 · Ev. Luke 2:21 + +- Com. telesphorus-pope-and-martyr + + + +**6** ef-epiphany +`class-1` · white · Ep. Isa 60:1-6 · Ev. Matt 2:1-12 + + + +**7** ef-christmas-2-thursday +`class-4` · white · Ep. Isa 60:1-6 · Ev. Matt 2:1-12 + + + +**8** ef-christmas-2-friday +`class-4` · white · Ep. Isa 60:1-6 · Ev. Matt 2:1-12 + + + +**9** Officium sanctae Mariae in sabbato +`class-4` · white · Ep. Titus 3:4-7 · Ev. Luke 2:15-20 + + + +**10** Sanctae Familiae Iesu, Mariae, Ioseph +`class-2` · white · Ep. Col 3:12-17 · Ev. Luke 2:42-52 + + + +**11** ef-time-after-epiphany-1-monday +`class-4` · white · Ep. Rom 12:1-5 · Ev. Luke 2:42-52 + +- Com. hyginus-pope-and-martyr + + + +**12** ef-time-after-epiphany-1-tuesday +`class-4` · white · Ep. Rom 12:1-5 · Ev. Luke 2:42-52 + + + +**13** commemoration-of-the-baptism-of-the-lord +`class-2` · white · Ep. Isa 60:1-6 · Ev. John 1:29-34 + + + +**14** hilary +`class-3` · white · Ep. 2 Tim 4:1-8 · Ev. Matt 5:13-19 + +- Com. felicis + + + +**15** paul-the-first-hermit +`class-3` · white · Ep. Phil 3:7-12 · Ev. Matt 11:25-30 + +- Com. maur-abbot + + + +**16** marcellus-i +`class-3` · red · Ep. 1 Pet 5:1-4; 5:10-11. · Ev. Matt 16:13-19 + + + +**17** ef-time-after-epiphany-sunday-2 +`class-2` · green · Ep. Rom 12:6-16 · Ev. John 2:1-11 + + + +**18** ef-time-after-epiphany-2-monday +`class-4` · green · Ep. Rom 12:6-16 · Ev. John 2:1-11 + +- Com. prisca + + + +**19** ef-time-after-epiphany-2-tuesday +`class-4` · green · Ep. Rom 12:6-16 · Ev. John 2:1-11 + +- Com. canute-martyr + +- Com. sts-marius-martha-audifax-abachum + + + +**20** sts-fabian-sebastian +`class-3` · red · Ep. Heb 11:33-39 · Ev. Luke 6:17-23 + + + +**21** agnes +`class-3` · red · Ep. Sir 51:1-8; 51:12 · Ev. Matt 25:1-13. + + + +**22** sts-vincent-anastasius +`class-3` · red · Ep. Wis 3:1-8 · Ev. Luke 21:9-19 + + + +**23** raymond-of-pe-afort +`class-3` · white · Ep. Sir 31:8-11 · Ev. Luke 12:35-40 + +- Com. emerentiana + + + +**24** ef-septuagesima-sunday-1 +`class-2` · violet · Ep. 1 Cor. 9:24-27; 10:1-5 · Ev. Matt 20:1-16 + + + +**25** conversion-of-st-paul +`class-3` · white · Ep. Acts 9:1-22 · Ev. Matt 19:27-29. + +- Com. peter + + + +**26** polycarp +`class-3` · red · Ep. 1 John 3:10-16 · Ev. Matt 10:26-32. + + + +**27** john-chrysostom +`class-3` · white · Ep. 2 Tim 4:1-8 · Ev. Matt 5:13-19 + + + +**28** peter-nolasco +`class-3` · white · Ep. 1 Cor. 4:9-14 · Ev. Luke 12:32-34 + +- Com. agnes-secundo + + + +**29** francis-de-sales +`class-3` · white · Ep. 2 Tim 4:1-8 · Ev. Matt 5:13-19 + + + +**30** martina +`class-3` · red · Ep. Sir 51:1-8; 51:12 · Ev. Matt 25:1-13. + + + +**31** ef-septuagesima-sunday-2 +`class-2` · violet · Ep. 2 Cor. 11:19-33; 12:1-9 · Ev. Luke 8:4-15 + + + +## Februarius + + +**1** ignatius-of-antioch +`class-3` · red · Ep. Rom 8:35-39 · Ev. John 12:24-26 + + + +**2** purification-of-the-blessed-virgin-mary +`class-2` · white · Ep. Mal 3:1-4 · Ev. Luke 2:22-32 + + + +**3** ef-septuagesima-2-wednesday +`class-4` · violet · Ep. 2 Cor. 11:19-33; 12:1-9 · Ev. Luke 8:4-15 + +- Com. blaise + + + +**4** andrew-corsini +`class-3` · white · Ep. Sir 44:16-27; 45:3-20 · Ev. Matt 25:14-23 + + + +**5** agatha +`class-3` · red · Ep. 1 Cor. 1:26-31 · Ev. Matt 19:3-12. + + + +**6** titus +`class-3` · white · Ep. Sir 44:16-27; 45:3-20 · Ev. Luke 10:1-9 + +- Com. dorothy + + + +**7** ef-septuagesima-sunday-3 +`class-2` · violet · Ep. 1 Cor. 13:1-13 · Ev. Luke 18:31-43 + + + +**8** john-of-matha +`class-3` · white · Ep. Sir 31:8-11 · Ev. Luke 12:35-40 + + + +**9** cyril-of-alexandria +`class-3` · white · Ep. 2 Tim 4:1-8 · Ev. Matt 5:13-19 + +- Com. appollonia + + + +**10** ef-ash-wednesday +`class-1` · violet · Ep. Joel 2:12-19 · Ev. Matt 6:16-21 + + + +**11** ef-lent-after-ashes-thursday +`class-3` · violet · Ep. Isa 38:1-6 · Ev. Matt 8:5-13 + +- Com. our-lady-of-lourdes + + + +**12** ef-lent-after-ashes-friday +`class-3` · violet · Ep. Isa 58:1-9 · Ev. Matt 5:43-48; 6:1-4 + +- Com. seven-holy-servite-founders + + + +**13** ef-lent-after-ashes-saturday +`class-3` · violet · Ep. Isa 58:9-14 · Ev. Mark 6:47-56 + + + +**14** ef-lent-sunday-1 +`class-1` · violet · Ep. 2 Cor. 6:1-10 · Ev. Matt 4:1-11 + + + +**15** ef-lent-1-monday +`class-3` · violet · Ep. Ezech 34:11-16 · Ev. Matt 25:31-46 + +- Com. sts-faustinus-jovita + + + +**16** ef-lent-1-tuesday +`class-3` · violet · Ep. Isa 55:6-11 · Ev. Matt 21:10-17 + + + +**17** ef-lent-ember-wed +`class-2` · violet · Ep. 3 Kgs. 19:3-8 · Ev. Matt 12:38-50 + + + +**18** ef-lent-1-thursday +`class-3` · violet · Ep. Ezech 18:1-9 · Ev. Matt 15:21-28 + +- Com. simeon + + + +**19** ef-lent-ember-fri +`class-2` · violet · Ep. Ezech 18:20-28 · Ev. John 5:1-15 + + + +**20** ef-lent-ember-sat +`class-2` · violet · Ep. 1 Thess. 5:14-23 · Ev. Matt 17:1-9 + + + +**21** ef-lent-sunday-2 +`class-1` · violet · Ep. 1 Thess. 4:1-7 · Ev. Matt 17:1-9 + + + +**22** chair-of-st-peter +`class-2` · white · Ep. 1 Pet 1:1-7 · Ev. Matt 16:13-19 + +- Com. ef-lent-2-monday + +- Com. paul + + + +**23** ef-lent-2-tuesday +`class-3` · violet · Ep. 3 Kings 17:8-16 · Ev. Matt 23:1-12 + +- Com. peter-damien + + + +**24** matthias +`class-2` · red · Ep. Acts 1:15-26 · Ev. Matt 11:25-30 + +- Com. ef-lent-2-wednesday + + + +**25** ef-lent-2-thursday +`class-3` · violet · Ep. Jer 17:5-10 · Ev. Luke 16:19-31 + + + +**26** ef-lent-2-friday +`class-3` · violet · Ep. Gen 37:6-22 · Ev. Matt 21:33-46 + + + +**27** ef-lent-2-saturday +`class-3` · violet · Ep. Gen 27:6-40 · Ev. Luke 15:11-32 + +- Com. gabriel-of-our-lady-of-sorrows + + + +**28** ef-lent-sunday-3 +`class-1` · violet · Ep. Eph 5:1-9 · Ev. Luke 11:14-28 + + + +## Martius + + +**1** ef-lent-3-monday +`class-3` · violet · Ep. 4 Kings 5:1-15 · Ev. Luke 4:23-30 + + + +**2** ef-lent-3-tuesday +`class-3` · violet · Ep. 4 Kings 4:1-7 · Ev. Matt 18:15-22 + + + +**3** ef-lent-3-wednesday +`class-3` · violet · Ep. Ex 20:12-24 · Ev. Matt 15:1-20 + + + +**4** ef-lent-3-thursday +`class-3` · violet · Ep. Jer 7:1-7 · Ev. Luke 4:38-44. + +- Com. casimir + +- Com. lucius + + + +**5** ef-lent-3-friday +`class-3` · violet · Ep. Num 20:1, 3; 6-13. · Ev. John 4:5-42 + + + +**6** ef-lent-3-saturday +`class-3` · violet · Ep. Dan 13:1-9, 15-17, 19-30, 33-62. · Ev. John 8:1-11 + +- Com. sts-felicitas-perpetua + + + +**7** ef-lent-sunday-4 +`class-1` · rose · Ep. Gal 4:22-31 · Ev. John 6:1-15 + + + +**8** ef-lent-4-monday +`class-3` · violet · Ep. 3 Kings 3:16-28 · Ev. John 2:13-25 + +- Com. john-of-god + + + +**9** ef-lent-4-tuesday +`class-3` · violet · Ep. Ex 32:7-14 · Ev. John 7:14-31 + +- Com. frances-rome + + + +**10** ef-lent-4-wednesday +`class-3` · violet · Ep. Isa. 1:16-19 · Ev. John 9:1-38 + +- Com. forty-holy-martyrs-of-sebaste + + + +**11** ef-lent-4-thursday +`class-3` · violet · Ep. 4 Kings 4:25-38 · Ev. Luke 7:11-16 + + + +**12** ef-lent-4-friday +`class-3` · violet · Ep. 3 Kings 17:17-24 · Ev. John 11:1-45 + +- Com. gregory-the-great + + + +**13** ef-lent-4-saturday +`class-3` · violet · Ep. Isa 49:8-15 · Ev. John 8:12-20 + + + +**14** ef-passion-sunday +`class-1` · violet · Ep. Heb 9:11-15. · Ev. John 8:46-59. + + + +**15** ef-passiontide-1-monday +`class-3` · violet · Ep. Jonas 3:1-10 · Ev. John 7:32-39 + + + +**16** ef-passiontide-1-tuesday +`class-3` · violet · Ep. Dan 14:27, 28-42 · Ev. John 7:1-13 + + + +**17** ef-passiontide-1-wednesday +`class-3` · violet · Ep. Lev 19:1-2, 11-19, 25 · Ev. John 10:22-38 + +- Com. patrick + + + +**18** ef-passiontide-1-thursday +`class-3` · violet · Ep. Dan 3:25, 34-45. · Ev. Luke 7:36-50 + +- Com. cyril-of-jerusalem + + + +**19** joseph-spouse-of-the-bl-virgin-mary +`class-1` · white · Ep. Ecclus 45:1-6 · Ev. Matt 1:18-21 + +- Com. ef-passiontide-1-friday + + + +**20** ef-passiontide-1-saturday +`class-3` · violet · Ep. Jer 18:18-23 · Ev. John 12:10-36 + + + +**21** ef-palm-sunday +`class-1` · violet · Ep. Phil 2:5-11 · Ev. Matt. 26:36-75; 27:1-60. + + + +**22** ef-passiontide-2-monday +`class-1` · violet · Ep. Isa 50:5-10 · Ev. John 12:1-9 + + + +**23** ef-passiontide-2-tuesday +`class-1` · violet · Ep. Jer 11:18-20 · Ev. Mark 14:32-72; 15, 1-46 + + + +**24** ef-passiontide-2-wednesday +`class-1` · violet · Ep. Isa 53:1-12 · Ev. Luke 22:39-71; 23:1-53 + + + +**25** Feria V in Cena Domini +`class-1` · white · Ep. 1 Cor 11:20-32 · Ev. John 13:1-15 + + + +**26** Feria VI in Passione et Morte Domini +`class-1` · black · Ep. Ex 12:1-11 · Ev. John 18:1-40; 19:1-42 + + + +**27** Sabbato sancto +`class-1` · violet · Ep. Col 3:1-4 · Ev. Matt 28:1-7 + + + +**28** ef-easter-sunday +`class-1` · white · Ep. 1 Cor 5:7-8 · Ev. Mark 16:1-7 + + + +**29** ef-easter-1-monday +`class-1` · white · Ep. Acts 10:37-43. · Ev. Luke 24:13-35 + + + +**30** ef-easter-1-tuesday +`class-1` · white · Ep. Acts 13:16; 13:26-33 · Ev. Luke 24:36-47 + + + +**31** ef-easter-1-wednesday +`class-1` · white · Ep. Acts 3:13-15; 3:17-19 · Ev. John 21:1-14 + + + +## Aprilis + + +**1** ef-easter-1-thursday +`class-1` · white · Ep. Acts 8:26-40 · Ev. John 20:11-18 + + + +**2** ef-easter-1-friday +`class-1` · white · Ep. 1 Pet 3:18-22 · Ev. Matt 28:16-20 + + + +**3** ef-easter-1-saturday +`class-1` · white · Ep. 1 Pet 2:1-10 · Ev. John 20:1-9 + + + +**4** ef-low-sunday +`class-1` · white · Ep. 1 John 5:4-10 · Ev. John 20:19-31 + + + +**5** annunciation-of-the-blessed-virgin-mary +`class-1` · white · Ep. Isa 7:10-15 · Ev. Luke 1:26-38 + + + +**6** ef-easter-2-tuesday +`class-4` · white · Ep. 1 John 5:4-10 · Ev. John 20:19-31 + + + +**7** ef-easter-2-wednesday +`class-4` · white · Ep. 1 John 5:4-10 · Ev. John 20:19-31 + + + +**8** ef-easter-2-thursday +`class-4` · white · Ep. 1 John 5:4-10 · Ev. John 20:19-31 + + + +**9** ef-easter-2-friday +`class-4` · white · Ep. 1 John 5:4-10 · Ev. John 20:19-31 + + + +**10** Officium sanctae Mariae in sabbato +`class-4` · white · Ep. Ecclus 24:14-16 · Ev. John 19:25-27 + + + +**11** ef-easter-sunday-3 +`class-2` · white · Ep. 1 Pet 2:21-25 · Ev. John 10:11-16 + + + +**12** ef-easter-3-monday +`class-4` · white · Ep. 1 Pet 2:21-25 · Ev. John 10:11-16 + + + +**13** hermenegild +`class-3` · red · Ep. Wis 10:10-14 · Ev. Luke 14:26-33. + + + +**14** justin +`class-3` · red · Ep. 1 Cor 1:18-25; 1:30; · Ev. Luke 12:2-8 + +- Com. sts-tiburtius-valerian-et-maximus-martyrs + + + +**15** ef-easter-3-thursday +`class-4` · white · Ep. 1 Pet 2:21-25 · Ev. John 10:11-16 + + + +**16** ef-easter-3-friday +`class-4` · white · Ep. 1 Pet 2:21-25 · Ev. John 10:11-16 + + + +**17** Officium sanctae Mariae in sabbato +`class-4` · white · Ep. Ecclus 24:14-16 · Ev. John 19:25-27 + +- Com. anicetus + + + +**18** ef-easter-sunday-4 +`class-2` · white · Ep. 1 Pet 2:11-19 · Ev. John 16:16-22 + + + +**19** ef-easter-4-monday +`class-4` · white · Ep. 1 Pet 2:11-19 · Ev. John 16:16-22 + + + +**20** ef-easter-4-tuesday +`class-4` · white · Ep. 1 Pet 2:11-19 · Ev. John 16:16-22 + + + +**21** anselm +`class-3` · white · Ep. 2 Tim 4:1-8 · Ev. Matt 5:13-19 + + + +**22** sts-soter-caius +`class-3` · red · Ep. 1 Pet 5:1-4; 5:10-11. · Ev. Matt 16:13-19 + + + +**23** ef-easter-4-friday +`class-4` · white · Ep. 1 Pet 2:11-19 · Ev. John 16:16-22 + +- Com. george + + + +**24** fidelis-of-sigmaringen +`class-3` · red · Ep. Wis 5:1-5 · Ev. John 15:1-7 + + + +**25** ef-easter-sunday-5 +`class-2` · white · Ep. Jas 1:17-21 · Ev. John 16:5-14 + +- Com. major-litanies + + + +**26** sts-cletus-marcellinus +`class-3` · red · Ep. 1 Pet 5:1-4; 5:10-11. · Ev. Matt 16:13-19 + + + +**27** peter-canisius +`class-3` · white · Ep. 2 Tim 4:1-8 · Ev. Matt 5:13-19 + + + +**28** paul-of-the-cross +`class-3` · white · Ep. 1 Cor 1:17-25. · Ev. Luke 10:1-9 + + + +**29** peter-of-verona +`class-3` · red · Ep. 2 Tim. 2:8-10; 3:10-12. · Ev. Matt 10:34-42 + + + +**30** catherine-of-siena +`class-3` · white · Ep. 2 Cor 10:17-18; 11:1-2 · Ev. Matt 25:1-13. + + + +## Maius + + +**1** joseph-the-workman +`class-1` · white · Ep. Col. 3:14-15, 17, 23-24 · Ev. Matt 13:54-58 + + + +**2** ef-easter-sunday-6 +`class-2` · white · Ep. Jas 1:22-27 · Ev. John 16:23-30 + + + +**3** ef-rogation-monday +`class-4` · violet · Ep. Jas 1:22-27 · Ev. John 16:23-30 + +- Com. sts-alexander-companions + + + +**4** monica +`class-3` · white · Ep. 1 Tim. 5:3-10. · Ev. Luke 7:11-16 + + + +**5** ef-ascension-vigil +`class-2` · white · Ep. Eph. 4:7-13. · Ev. John 17:1-11. + +- Com. pius-v + + + +**6** ef-ascension +`class-1` · white · Ep. Acts 1:1-11 · Ev. Mark 16:14-20 + + + +**7** stanislaus +`class-3` · red · Ep. Wis 5:1-5 · Ev. John 15:1-7 + + + +**8** Officium sanctae Mariae in sabbato +`class-4` · white · Ep. Ecclus 24:14-16 · Ev. John 19:25-27 + + + +**9** ef-easter-sunday-7 +`class-2` · white · Ep. 1 Pet 4:7-11. · Ev. John 15:26-27; 16:1-4. + + + +**10** antoninus +`class-3` · white · Ep. Sir 44:16-27; 45:3-20 · Ev. Matt 25:14-23 + +- Com. gordiano-and-epimacho + + + +**11** sts-philip-james +`class-2` · red · Ep. Wis. 5:1-5 · Ev. John 14:1-13 + + + +**12** sts-nereus-achilleus-domitilla-pancras +`class-3` · red · Ep. Wis. 5:1-5 · Ev. John 4:46-53 + + + +**13** robert-bellarmine +`class-3` · white · Ep. Wis 7:7-14. · Ev. Matt 5:13-19 + + + +**14** ef-easter-7-friday +`class-4` · white · Ep. 1 Pet 4:7-11. · Ev. John 15:26-27; 16:1-4. + +- Com. boniface-martyr + + + +**15** ef-pentecost-vigil +`class-1` · red · Ep. Acts 19:1-8. · Ev. John 14:15-21. + + + +**16** ef-pentecost +`class-1` · red · Ep. Acts 2:1-11. · Ev. John 14:23-31. + + + +**17** ef-easter-8-monday +`class-1` · red · Ep. Acts 10:34, 42-48 · Ev. John 3:16-21 + + + +**18** ef-easter-8-tuesday +`class-1` · red · Ep. Acts 8:14-17. · Ev. John 10:1-10. + + + +**19** ef-pentecost-ember-wed +`class-1` · red · Ep. Acts 5:12-16 · Ev. John 6:44-52. + + + +**20** ef-easter-8-thursday +`class-1` · red · Ep. Acts 8:5-8 · Ev. Luke 9:1-6 + + + +**21** ef-pentecost-ember-fri +`class-1` · red · Ep. Joel 2:23-24; 26-27 · Ev. Luke 5:17-26 + + + +**22** ef-pentecost-ember-sat +`class-1` · red · Ep. Rom 5:1-5. · Ev. Luke 4:38-44. + + + +**23** ef-trinity +`class-1` · white · Ep. Rom 11:33-36. · Ev. Matt 28:18-20 + + + +**24** ef-time-after-pentecost-1-monday +`class-4` · green · Ep. 1 John 4:8-21 · Ev. Luke 6:36-42 + + + +**25** gregory-vii +`class-3` · white · Ep. 1 Pet 5:1-4; 5:10-11. · Ev. Matt 16:13-19 + +- Com. urban-pope-and-martyr + + + +**26** philip-neri +`class-3` · white · Ep. Wis 7:7-14. · Ev. Luke 12:35-40 + +- Com. eleutherius + + + +**27** ef-corpus-christi +`class-1` · white · Ep. 1 Cor 11:23-29 · Ev. John 6:56-59 + + + +**28** augustine-of-canterbury +`class-3` · white · Ep. 1 Thess 2:2-9 · Ev. Luke 10:1-9 + + + +**29** mary-magdalene-de-pazzi +`class-3` · white · Ep. 2 Cor 10:17-18; 11:1-2 · Ev. Matt 25:1-13. + + + +**30** ef-time-after-pentecost-sunday-2 +`class-2` · green · Ep. 1 John 3:13-18. · Ev. Luke 14:16-24. + + + +**31** queenship-of-the-blessed-virgin-mary +`class-2` · white · Ep. Eccli 24:5; 14:7; 14:9-11; 24:30-31 · Ev. Luke 1:26-33 + +- Com. petronilla + + + +## Iunius + + +**1** angela-merici +`class-3` · white · Ep. 2 Cor 10:17-18; 11:1-2 · Ev. Matt 25:1-13. + + + +**2** ef-time-after-pentecost-2-wednesday +`class-4` · green · Ep. 1 John 3:13-18. · Ev. Luke 14:16-24. + +- Com. sts-marcellinus-peter-erasmus + + + +**3** ef-time-after-pentecost-2-thursday +`class-4` · green · Ep. 1 John 3:13-18. · Ev. Luke 14:16-24. + + + +**4** ef-sacred-heart +`class-1` · white · Ep. Eph 3:8-12, 14-19 · Ev. John 19:31-37 + + + +**5** boniface +`class-3` · red · Ep. Ecclus 44:1-15 · Ev. Matt 5:1-12 + + + +**6** ef-time-after-pentecost-sunday-3 +`class-2` · green · Ep. 1 Pet. 5:6-11 · Ev. Luke 15:1-10 + + + +**7** ef-time-after-pentecost-3-monday +`class-4` · green · Ep. 1 Pet. 5:6-11 · Ev. Luke 15:1-10 + + + +**8** ef-time-after-pentecost-3-tuesday +`class-4` · green · Ep. 1 Pet. 5:6-11 · Ev. Luke 15:1-10 + + + +**9** ef-time-after-pentecost-3-wednesday +`class-4` · green · Ep. 1 Pet. 5:6-11 · Ev. Luke 15:1-10 + +- Com. sts-primus-felicianus + + + +**10** margaret-of-scotland +`class-3` · white · Ep. Prov 31:10-31 · Ev. Matt 13:44-52. + + + +**11** barnabas +`class-3` · red · Ep. Acts 11:21-26; 13:1-3 · Ev. Matt 10:16-22 + + + +**12** john-of-san-fecundo +`class-3` · white · Ep. Sir 31:8-11 · Ev. Luke 12:35-40 + +- Com. basilidus + + + +**13** ef-time-after-pentecost-sunday-4 +`class-2` · green · Ep. Rom 8:18-23 · Ev. Luke 5:1-11 + + + +**14** basil-the-great +`class-3` · white · Ep. 2 Tim 4:1-8 · Ev. Luke 14:26-35 + + + +**15** ef-time-after-pentecost-4-tuesday +`class-4` · green · Ep. Rom 8:18-23 · Ev. Luke 5:1-11 + +- Com. vitus + + + +**16** ef-time-after-pentecost-4-wednesday +`class-4` · green · Ep. Rom 8:18-23 · Ev. Luke 5:1-11 + + + +**17** gregory-barbarigo +`class-3` · white · Ep. Sir 44:16-27; 45:3-20 · Ev. Matt 25:14-23 + + + +**18** ephrem-of-syria +`class-3` · white · Ep. 2 Tim 4:1-8 · Ev. Matt 5:13-19 + +- Com. marcus-and-marcellianus + + + +**19** julia-of-falconieri +`class-3` · white · Ep. 2 Cor 10:17-18; 11:1-2 · Ev. Matt 25:1-13. + +- Com. sts-gervasius-and-protasius + + + +**20** ef-time-after-pentecost-sunday-5 +`class-2` · green · Ep. 1 Pet 3:8-15. · Ev. Matt 5:20-24. + + + +**21** aloysius-gongzaga +`class-3` · white · Ep. Sir 31:8-11 · Ev. Matt 22:29-40 + + + +**22** paulinus-of-nola +`class-3` · white · Ep. 2 Cor. 8:9-15 · Ev. Luke 12:32-34 + + + +**23** vigil-of-the-nativity-of-st-john-the-baptist +`class-2` · violet · Ep. Jer 1:4-10 · Ev. Luke 1:5-17 + + + +**24** nativity-of-st-john-the-baptist +`class-1` · white · Ep. Isa 49:1-3, 5-7. · Ev. Luke 1:57-68 + + + +**25** william +`class-3` · white · Ep. Ecclus 45:1-6 · Ev. Matt 19:27-29. + + + +**26** sts-john-paul +`class-3` · red · Ep. Eccli 44:10-15 · Ev. Luke 12:1-8 + + + +**27** ef-time-after-pentecost-sunday-6 +`class-2` · green · Ep. Rom 6:3-11. · Ev. Mark 8:1-9 + + + +**28** vigil-of-sts-peter-paul +`class-2` · violet · Ep. Acts 3:1-10 · Ev. John 21:15-19 + + + +**29** sts-peter-paul +`class-1` · red · Ep. Acts 12:1-11 · Ev. Matt 16:13-19 + + + +**30** in-commemoratione-sancti-pauli-apostoli +`class-3` · red · Ep. Gal 1:11-20 · Ev. Matt 10:16-22 + +- Com. commemoration-of-st-peter + + + +## Iulius + + +**1** precious-blood-of-our-lord-jesus-christ +`class-1` · red · Ep. Heb 9:11-15. · Ev. John 19:30-35 + + + +**2** visitation-of-the-blessed-virgin-mary +`class-2` · white · Ep. Song 2:8-14 · Ev. Luke 1:39-47 + +- Com. processus-and-martinian + + + +**3** irenaeus +`class-3` · red · Ep. 2 Tim. 3:14-17; 4:1-5 · Ev. Matt 10:28-33 + + + +**4** ef-time-after-pentecost-sunday-7 +`class-2` · green · Ep. Rom 6:19-23 · Ev. Matt 7:15-21 + + + +**5** anthony-mary-zaccariah +`class-3` · white · Ep. 1 Tim. 4:8-16 · Ev. Mark 10:15-21 + + + +**6** ef-time-after-pentecost-7-tuesday +`class-4` · green · Ep. Rom 6:19-23 · Ev. Matt 7:15-21 + + + +**7** sts-cyril-methodius +`class-3` · white · Ep. Heb 7:23-27 · Ev. Luke 10:1-9 + + + +**8** elizabeth-of-portugal +`class-3` · white · Ep. Prov 31:10-31 · Ev. Matt 13:44-52. + + + +**9** ef-time-after-pentecost-7-friday +`class-4` · green · Ep. Rom 6:19-23 · Ev. Matt 7:15-21 + + + +**10** seven-holy-brothers-and-sts-rufina-secunda +`class-3` · red · Ep. Prov 31:10-31 · Ev. Matt 12:46-50 + + + +**11** ef-time-after-pentecost-sunday-8 +`class-2` · green · Ep. Rom 8:12-17 · Ev. Luke 16:1-9 + + + +**12** john-gualbert +`class-3` · white · Ep. Ecclus 45:1-6 · Ev. Matt 5:43-48 + +- Com. naboris-et-felicis + + + +**13** ef-time-after-pentecost-8-tuesday +`class-4` · green · Ep. Rom 8:12-17 · Ev. Luke 16:1-9 + + + +**14** bonaventure +`class-3` · white · Ep. 2 Tim 4:1-8 · Ev. Matt 5:13-19 + + + +**15** henry-the-emperor +`class-3` · white · Ep. Sir 31:8-11 · Ev. Luke 12:35-40 + + + +**16** ef-time-after-pentecost-8-friday +`class-4` · green · Ep. Rom 8:12-17 · Ev. Luke 16:1-9 + +- Com. our-lady-of-mt-carmel + + + +**17** Officium sanctae Mariae in sabbato +`class-4` · white · Ep. Ecclus 24:14-16 · Ev. Luke 11:27-28 + +- Com. alexis + + + +**18** ef-time-after-pentecost-sunday-9 +`class-2` · green · Ep. 1 Cor. 10:6-13 · Ev. Luke 19:41-47 + + + +**19** vincent-de-paul +`class-3` · white · Ep. 1 Cor. 4:9-14 · Ev. Luke 10:1-9 + + + +**20** jerome-emiliani +`class-3` · white · Ep. Isa 58:7-11 · Ev. Matt 19:13-21 + +- Com. margaret + + + +**21** laurence-of-brindisi +`class-3` · white · Ep. 2 Tim 4:1-8 · Ev. Matt 5:13-19 + +- Com. praxedis-virginis + + + +**22** mary-magdalene +`class-3` · white · Ep. Song 3:2-5; 8:6-7 · Ev. Luke 7:36-50 + + + +**23** apollinaris +`class-3` · red · Ep. 1 Pet. 5:1-11 · Ev. Luke 22:24-30 + +- Com. liborii + + + +**24** Officium sanctae Mariae in sabbato +`class-4` · white · Ep. Ecclus 24:14-16 · Ev. Luke 11:27-28 + +- Com. christina + + + +**25** ef-time-after-pentecost-sunday-10 +`class-2` · green · Ep. 1 Cor. 12:2-11 · Ev. Luke 18:9-14 + +- Com. james-the-greater + + + +**26** anne-mother-of-the-blessed-virgin +`class-2` · white · Ep. Prov 31:10-31 · Ev. Matt 13:44-52. + + + +**27** ef-time-after-pentecost-10-tuesday +`class-4` · green · Ep. 1 Cor. 12:2-11 · Ev. Luke 18:9-14 + +- Com. pantaleon + + + +**28** sts-nazarius-celsus-st-victor-i-st-innocent-i +`class-3` · red · Ep. Wis 10:17-20 · Ev. Luke 21:9-19 + + + +**29** martha +`class-3` · white · Ep. 2 Cor 10:17-18; 11:1-2 · Ev. Luke 10:38-42 + +- Com. felicis-simplicii-faustini-et-beatricis + + + +**30** ef-time-after-pentecost-10-friday +`class-4` · green · Ep. 1 Cor. 12:2-11 · Ev. Luke 18:9-14 + +- Com. sts-abdon-sennen + + + +**31** ignatius-loyola +`class-3` · white · Ep. 2 Tim. 2:8-10; 3:10-12. · Ev. Luke 10:1-9 + + + +## Augustus + + +**1** ef-time-after-pentecost-sunday-11 +`class-2` · green · Ep. 1 Cor. 15:1-10 · Ev. Mark 7:31-37 + + + +**2** alphonsus-liguori +`class-3` · white · Ep. 2 Tim. 2:1-7 · Ev. Luke 10:1-9 + +- Com. stephen-i-pope-and-martyr + + + +**3** ef-time-after-pentecost-11-tuesday +`class-4` · green · Ep. 1 Cor. 15:1-10 · Ev. Mark 7:31-37 + + + +**4** dominic +`class-3` · white · Ep. 2 Tim. 4:1-8 · Ev. Luke 12:35-40 + + + +**5** dedication-of-the-basilica-of-st-mary-major +`class-3` · white · Ep. Ecclus 24:14-16 · Ev. Luke 11:27-28 + + + +**6** transfiguration-of-our-lord +`class-2` · white · Ep. 2 Pet. 1:16-19 · Ev. Matt 17:1-9 + +- Com. pope-sixtus-ii-felicissimus-and-agapitus-martyrs + + + +**7** cajetan +`class-3` · white · Ep. Sir 31:8-11 · Ev. Matt 6:24-33 + +- Com. donatus + + + +**8** ef-time-after-pentecost-sunday-12 +`class-2` · green · Ep. 2 Cor. 3:4-9 · Ev. Luke 10:23-37 + + + +**9** vigil-of-st-lawrence +`class-3` · violet · Ep. Ecclus 51:1-8, 12 · Ev. Matt 16:24-27 + +- Com. romanus + + + +**10** lawrence +`class-2` · red · Ep. 2 Cor. 9:6-10 · Ev. John 12:24-26 + + + +**11** ef-time-after-pentecost-12-wednesday +`class-4` · green · Ep. 2 Cor. 3:4-9 · Ev. Luke 10:23-37 + +- Com. sts-tiburtius-susanna + + + +**12** clare +`class-3` · white · Ep. 2 Cor 10:17-18; 11:1-2 · Ev. Matt 25:1-13. + + + +**13** ef-time-after-pentecost-12-friday +`class-4` · green · Ep. 2 Cor. 3:4-9 · Ev. Luke 10:23-37 + +- Com. sts-hippolytus-cassian + + + +**14** vigil-of-the-assumption +`class-2` · violet · Ep. Sir 24:23-31 · Ev. Luke 11:27-28 + +- Com. eusebius-confessor + + + +**15** assumption-of-the-blessed-virgin-mary +`class-1` · white · Ep. Judith 13:22-25; 15:10 · Ev. Luke 1:41-50 + +- Com. ef-time-after-pentecost-sunday-13 + + + +**16** joachim-father-of-the-blessed-virgin +`class-2` · white · Ep. Sir 31:8-11 · Ev. Matt 1:1-16 + + + +**17** hyacinth +`class-3` · white · Ep. Sir 31:8-11 · Ev. Luke 12:35-40 + + + +**18** ef-time-after-pentecost-13-wednesday +`class-4` · green · Ep. Gal 3:16-22 · Ev. Luke 17:11-19 + +- Com. agapitus + + + +**19** john-eudes +`class-3` · white · Ep. Sir 31:8-11 · Ev. Luke 12:35-40 + + + +**20** bernard-of-clairvaux +`class-3` · white · Ep. Ecclus 39:6-14 · Ev. Matt 5:13-19 + + + +**21** jane-frances-de-chantal +`class-3` · white · Ep. Prov 31:10-31 · Ev. Matt 13:44-52. + + + +**22** ef-time-after-pentecost-sunday-14 +`class-2` · green · Ep. Gal 5:16-24 · Ev. Matt 6:24-33 + +- Com. immaculate-heart-of-mary + + + +**23** philip-benizi +`class-3` · white · Ep. 1 Cor. 4:9-14 · Ev. Luke 12:32-34 + + + +**24** bartholomew +`class-2` · red · Ep. 1 Cor. 12:27-31 · Ev. Luke 6:12-19 + + + +**25** louis-ix +`class-3` · white · Ep. Wis 10:10-14 · Ev. Luke 19:12-26 + + + +**26** ef-time-after-pentecost-14-thursday +`class-4` · green · Ep. Gal 5:16-24 · Ev. Matt 6:24-33 + +- Com. zephyrinus + + + +**27** joseph-calasance +`class-3` · white · Ep. Wis 10:10-14 · Ev. Matt 18:1-5 + + + +**28** augustine +`class-3` · white · Ep. 2 Tim 4:1-8 · Ev. Matt 5:13-19 + +- Com. hermes + + + +**29** ef-time-after-pentecost-sunday-15 +`class-2` · green · Ep. Gal 5:25-26; 6:1-10 · Ev. Luke 7:11-16 + + + +**30** rose-of-lima +`class-3` · white · Ep. 2 Cor 10:17-18; 11:1-2 · Ev. Matt 25:1-13. + +- Com. sts-felix-and-adauctus + + + +**31** raymond-nonnatus +`class-3` · white · Ep. Sir 31:8-11 · Ev. Luke 12:35-40 + + + +## September + + +**1** ef-time-after-pentecost-15-wednesday +`class-4` · green · Ep. Gal 5:25-26; 6:1-10 · Ev. Luke 7:11-16 + +- Com. giles + +- Com. twelve-holy-brothers-martyrs + + + +**2** stephen-of-hungary +`class-3` · white · Ep. Sir 31:8-11 · Ev. Luke 19:12-26 + + + +**3** pius-x +`class-3` · white · Ep. 1 Thess. 2:2-8 · Ev. John 21:15-17 + + + +**4** Officium sanctae Mariae in sabbato +`class-4` · white · Ep. Ecclus 24:14-16 · Ev. Luke 11:27-28 + + + +**5** ef-time-after-pentecost-sunday-16 +`class-2` · green · Ep. Eph 3:13-21 · Ev. Luke 14:1-11 + + + +**6** ef-time-after-pentecost-16-monday +`class-4` · green · Ep. Eph 3:13-21 · Ev. Luke 14:1-11 + + + +**7** ef-time-after-pentecost-16-tuesday +`class-4` · green · Ep. Eph 3:13-21 · Ev. Luke 14:1-11 + + + +**8** nativity-of-the-blessed-virgin-mary +`class-2` · white · Ep. Prov 8:22-35 · Ev. Matt 1:1-16 + +- Com. hadriani + + + +**9** ef-time-after-pentecost-16-thursday +`class-4` · green · Ep. Eph 3:13-21 · Ev. Luke 14:1-11 + +- Com. gorgonius + + + +**10** nicholas-of-tolentino +`class-3` · white · Ep. 1 Cor. 4:9-14 · Ev. Luke 12:32-34 + + + +**11** Officium sanctae Mariae in sabbato +`class-4` · white · Ep. Ecclus 24:14-16 · Ev. Luke 11:27-28 + +- Com. sts-protus-hyacinth + + + +**12** ef-time-after-pentecost-sunday-17 +`class-2` · green · Ep. Eph 4:1-6 · Ev. Matt 22:34-46 + + + +**13** ef-time-after-pentecost-17-monday +`class-4` · green · Ep. Eph 4:1-6 · Ev. Matt 22:34-46 + + + +**14** exaltation-of-the-holy-cross +`class-2` · red · Ep. Phil 2:5-11 · Ev. John 12:31-36 + + + +**15** seven-sorrows-of-the-blessed-virgin-mary +`class-2` · white · Ep. Judith 13:22; 13:23-25 · Ev. John 19:25-27 + +- Com. nicomedes + + + +**16** sts-cornelius-cyprian +`class-3` · red · Ep. Wis 3:1-8 · Ev. Luke 21:9-19 + +- Com. sts-euphemia-lucy-and-geminianus + + + +**17** ef-time-after-pentecost-17-friday +`class-4` · green · Ep. Eph 4:1-6 · Ev. Matt 22:34-46 + +- Com. stigmata-of-st-francis + + + +**18** joseph-of-cupertino +`class-3` · white · Ep. 1 Cor 13:1-8 · Ev. Matt 22:1-14 + + + +**19** ef-time-after-pentecost-sunday-18 +`class-2` · green · Ep. 1 Cor. 1:4-8 · Ev. Matt 9:1-8 + + + +**20** ef-time-after-pentecost-18-monday +`class-4` · green · Ep. 1 Cor. 1:4-8 · Ev. Matt 9:1-8 + +- Com. sts-eustace-companions + + + +**21** matthew +`class-2` · red · Ep. Ezek 1:10-14 · Ev. Matt 9:9-13 + + + +**22** ef-september-ember-wed +`class-2` · violet · Ep. 2 Esd. 8:1-10 · Ev. Mark 9:16-28 + +- Com. thomas-of-villanova + + + +**23** linus +`class-3` · red · Ep. 1 Pet 5:1-4; 5:10-11. · Ev. Matt 16:13-19 + +- Com. thecla + + + +**24** ef-september-ember-fri +`class-2` · violet · Ep. Osee 14:2-10 · Ev. Luke 7:36-50 + +- Com. our-lady-of-ransom + + + +**25** ef-september-ember-sat +`class-2` · violet · Ep. Heb 9:2-12 · Ev. Luke 13:6-17 + + + +**26** ef-time-after-pentecost-sunday-19 +`class-2` · green · Ep. Eph 4:23-28 · Ev. Matt 22:1-14 + + + +**27** sts-cosmas-damian +`class-3` · red · Ep. Wis 5:16-20 · Ev. Luke 6:17-23 + + + +**28** wenceslaus +`class-3` · red · Ep. Wis 10:10-14 · Ev. Matt 10:34-42 + + + +**29** dedication-of-st-michael-the-archangel +`class-1` · white · Ep. Rev 1:1-5 · Ev. Matt 18:1-10 + + + +**30** jerome +`class-3` · white · Ep. 2 Tim 4:1-8 · Ev. Matt 5:13-19 + + + +## October + + +**1** ef-time-after-pentecost-19-friday +`class-4` · green · Ep. Eph 4:23-28 · Ev. Matt 22:1-14 + +- Com. remigius + + + +**2** holy-guardian-angels +`class-3` · white · Ep. Exod 23:20-23 · Ev. Matt 18:1-10 + + + +**3** ef-time-after-pentecost-sunday-20 +`class-2` · green · Ep. Eph 5:15-21 · Ev. John 4:46-53 + + + +**4** francis-of-assisi +`class-3` · white · Ep. Gal 6:14-18 · Ev. Matt 11:25-30 + + + +**5** ef-time-after-pentecost-20-tuesday +`class-4` · green · Ep. Eph 5:15-21 · Ev. John 4:46-53 + +- Com. placid-companions + + + +**6** bruno +`class-3` · white · Ep. Sir 31:8-11 · Ev. Luke 12:35-40 + + + +**7** our-lady-of-the-rosary +`class-2` · white · Ep. Prov 8:22-24, 32-35. · Ev. Luke 1:26-38 + +- Com. mark-i + + + +**8** bridget-of-sweden +`class-3` · white · Ep. 1 Tim. 5:3-10. · Ev. Matt 13:44-52. + +- Com. sergio-baccho-marcello-and-apulejo-martyrs + + + +**9** john-leonardi +`class-3` · white · Ep. 2 Cor 4:1-6; 4:15-18 · Ev. Luke 10:1-9 + +- Com. dionysius-and-companions + + + +**10** ef-time-after-pentecost-sunday-21 +`class-2` · green · Ep. Eph 6:10-17 · Ev. Matt 18:23-35 + + + +**11** maternity-of-the-blessed-virgin-mary +`class-2` · white · Ep. Sir 24:23-31 · Ev. Luke 2:43-51 + + + +**12** ef-time-after-pentecost-21-tuesday +`class-4` · green · Ep. Eph 6:10-17 · Ev. Matt 18:23-35 + + + +**13** edward +`class-3` · white · Ep. Sir 31:8-11 · Ev. Luke 12:35-40 + + + +**14** callistus-i +`class-3` · red · Ep. 1 Pet 5:1-4; 5:10-11. · Ev. Matt 16:13-19 + + + +**15** teresa-of-avila +`class-3` · white · Ep. 2 Cor 10:17-18; 11:1-2 · Ev. Matt 25:1-13. + + + +**16** hedwig +`class-3` · white · Ep. Prov 31:10-31 · Ev. Matt 13:44-52. + + + +**17** ef-time-after-pentecost-sunday-22 +`class-2` · green · Ep. Phil 1:6-11 · Ev. Matt 22:15-21 + + + +**18** luke-the-evangelist +`class-2` · red · Ep. 2 Cor. 8:16-24 · Ev. Luke 10:1-9 + + + +**19** peter-of-alcantara +`class-3` · white · Ep. Phil 3:7-12 · Ev. Luke 12:32-34 + + + +**20** john-cantius +`class-3` · white · Ep. James 2:12-17 · Ev. Luke 12:35-40 + + + +**21** ef-time-after-pentecost-22-thursday +`class-4` · green · Ep. Phil 1:6-11 · Ev. Matt 22:15-21 + +- Com. hilarion + +- Com. ursula-and-companions + + + +**22** ef-time-after-pentecost-22-friday +`class-4` · green · Ep. Phil 1:6-11 · Ev. Matt 22:15-21 + + + +**23** anthony-mary-claret +`class-3` · white · Ep. Heb 7:23-27 · Ev. Matt 24:42-47 + + + +**24** ef-time-after-pentecost-sunday-23 +`class-2` · green · Ep. Phil 3:17-21; 4:1-3 · Ev. Matt 9:18-26 + + + +**25** ef-time-after-pentecost-23-monday +`class-4` · green · Ep. Phil 3:17-21; 4:1-3 · Ev. Matt 9:18-26 + +- Com. sts-chrysanthus-daria + + + +**26** ef-time-after-pentecost-23-tuesday +`class-4` · green · Ep. Phil 3:17-21; 4:1-3 · Ev. Matt 9:18-26 + +- Com. evaristus + + + +**27** ef-time-after-pentecost-23-wednesday +`class-4` · green · Ep. Phil 3:17-21; 4:1-3 · Ev. Matt 9:18-26 + + + +**28** sts-simon-jude +`class-2` · red · Ep. Eph. 4:7-13. · Ev. John 15:17-25 + + + +**29** ef-time-after-pentecost-23-friday +`class-4` · green · Ep. Phil 3:17-21; 4:1-3 · Ev. Matt 9:18-26 + + + +**30** Officium sanctae Mariae in sabbato +`class-4` · white · Ep. Ecclus 24:14-16 · Ev. Luke 11:27-28 + + + +**31** ef-christ-the-king +`class-1` · white · Ep. Col 1:12-20. · Ev. John 18:33-37 + + + +## November + + +**1** all-saints +`class-1` · white · Ep. Apoc 7:2-12 · Ev. Matt 5:1-12 + + + +**2** commemoration-of-all-souls +`class-1` · black · Ep. 1 Cor. 15:51-57 · Ev. John 5:25-29 + + + +**3** ef-time-after-pentecost-24-wednesday +`class-4` · green · Ep. Col 1:12-20. · Ev. John 18:33-37 + + + +**4** charles-borromeo +`class-3` · white · Ep. Sir 44:16-27; 45:3-20 · Ev. Matt 25:14-23 + +- Com. sts-vitalis-and-agricola-martyrs + + + +**5** ef-time-after-pentecost-24-friday +`class-4` · green · Ep. Col 1:12-20. · Ev. John 18:33-37 + + + +**6** Officium sanctae Mariae in sabbato +`class-4` · white · Ep. Ecclus 24:14-16 · Ev. Luke 11:27-28 + + + +**7** ef-time-after-epiphany-sunday-5 +`class-2` · green · Ep. Col 3:12-17 · Ev. Matt 13:24-30 + + + +**8** ef-time-after-pentecost-25-monday +`class-4` · green · Ep. Col 3:12-17 · Ev. Matt 13:24-30 + +- Com. four-holy-crowned-martyrs + + + +**9** dedication-of-the-archbasilica-of-our-holy-savior +`class-2` · white · Ep. Rev 21:2-5 · Ev. Luke 19:1-10 + +- Com. theodore + + + +**10** andrew-avellino +`class-3` · white · Ep. Sir 31:8-11 · Ev. Luke 12:35-40 + +- Com. sts-tryphonis-respicii-et-nymphae + + + +**11** martin-of-tours +`class-3` · white · Ep. Sir 44:16-27; 45:3-20 · Ev. Luke 11:33-36 + +- Com. menna + + + +**12** martin-i +`class-3` · red · Ep. 1 Pet 5:1-4; 5:10-11. · Ev. Matt 16:13-19 + + + +**13** didacus +`class-3` · white · Ep. 1 Cor 4:9-14 · Ev. Luke 12:32-34 + + + +**14** ef-time-after-epiphany-sunday-6 +`class-2` · green · Ep. 1 Thess 1:2-10 · Ev. Matt 13:31-35 + + + +**15** albert-the-great +`class-3` · white · Ep. 2 Tim 4:1-8 · Ev. Matt 5:13-19 + + + +**16** gertrude-the-great +`class-3` · white · Ep. 2 Cor 10:17-18; 11:1-2 · Ev. Matt 25:1-13. + + + +**17** gregory-the-wonderworker +`class-3` · white · Ep. Sir 44:16-27; 45:3-20 · Ev. Mark 11:22-24 + + + +**18** dedication-of-the-basilicas-of-sts-peter-paul +`class-3` · white · Ep. Rev 21:2-5 · Ev. Luke 19:1-10 + + + +**19** elizabeth-of-hungary +`class-3` · white · Ep. Prov 31:10-31 · Ev. Matt 13:44-52. + +- Com. pontian + + + +**20** felix-of-valois +`class-3` · white · Ep. 1 Cor. 4:9-14 · Ev. Luke 12:32-34 + + + +**21** ef-time-after-pentecost-sunday-24 +`class-2` · green · Ep. Col 1:9-14 · Ev. Matt 24:15-35 + + + +**22** cecilia +`class-3` · red · Ep. Sir 51:13-17. · Ev. Matt 25:1-13. + + + +**23** clement-i +`class-3` · red · Ep. Phil 3:17-21; 4:1-3 · Ev. Matt 16:13-19 + +- Com. felicity + + + +**24** john-of-the-cross +`class-3` · white · Ep. 2 Tim 4:1-8 · Ev. Matt 5:13-19 + +- Com. chrysogonus + + + +**25** catherine-of-alexandria +`class-3` · red · Ep. Sir 51:1-8; 51:12 · Ev. Matt 25:1-13. + + + +**26** sylvester +`class-3` · white · Ep. Ecclus 45:1-6 · Ev. Matt 19:27-29. + +- Com. peter-of-alexandria + + + +**27** Officium sanctae Mariae in sabbato +`class-4` · white · Ep. Ecclus 24:14-16 · Ev. Luke 11:27-28 + + + +**28** ef-advent-sunday-1 +`class-1` · violet · Ep. Rom 13:11-14 · Ev. Luke 21:25-33 + + + +**29** ef-advent-1-monday +`class-3` · violet · Ep. Rom 13:11-14 · Ev. Luke 21:25-33 + +- Com. saturninus + + + +**30** andrew +`class-2` · red · Ep. Rom 10:10-18 · Ev. Matt 4:18-22 + +- Com. ef-advent-1-tuesday + + + +## December + + +**1** ef-advent-1-wednesday +`class-3` · violet · Ep. Rom 13:11-14 · Ev. Luke 21:25-33 + + + +**2** vivian +`class-3` · red · Ep. Sir 51:13-17. · Ev. Matt 13:44-52. + +- Com. ef-advent-1-thursday + + + +**3** francis-xavier +`class-3` · white · Ep. Rom 10:10-18 · Ev. Mark 16:15-18 + +- Com. ef-advent-1-friday + + + +**4** peter-chrysologus +`class-3` · white · Ep. 2 Tim 4:1-8 · Ev. Matt 5:13-19 + +- Com. ef-advent-1-saturday + +- Com. barbara + + + +**5** ef-advent-sunday-2 +`class-1` · violet · Ep. Rom 15:4-13 · Ev. Matt 11:2-10 + + + +**6** nicholas +`class-3` · white · Ep. Heb 13:7-17 · Ev. Matt 25:14-23 + +- Com. ef-advent-2-monday + + + +**7** ambrose +`class-3` · white · Ep. 2 Tim 4:1-8 · Ev. Matt 5:13-19 + +- Com. ef-advent-2-tuesday + + + +**8** immaculate-conception-of-the-blessed-virgin-mary +`class-1` · white · Ep. Prov 8:22-35 · Ev. Luke 1:26-28 + +- Com. ef-advent-2-wednesday + + + +**9** ef-advent-2-thursday +`class-3` · violet · Ep. Rom 15:4-13 · Ev. Matt 11:2-10 + + + +**10** ef-advent-2-friday +`class-3` · violet · Ep. Rom 15:4-13 · Ev. Matt 11:2-10 + +- Com. melchiades + + + +**11** damasus-i +`class-3` · white · Ep. 1 Pet 5:1-4; 5:10-11. · Ev. Matt 16:13-19 + +- Com. ef-advent-2-saturday + + + +**12** ef-advent-sunday-3 +`class-1` · rose · Ep. Phil 4:4-7 · Ev. John 1:19-28 + + + +**13** lucy +`class-3` · red · Ep. 2 Cor 10:17-18; 11:1-2 · Ev. Matt 13:44-52. + +- Com. ef-advent-3-monday + + + +**14** ef-advent-3-tuesday +`class-3` · violet · Ep. Phil 4:4-7 · Ev. John 1:19-28 + + + +**15** ef-advent-ember-wed +`class-2` · violet · Ep. Isa 7:10-15 · Ev. Luke 1:26-38 + + + +**16** eusebius +`class-3` · red · Ep. 2 Cor. 1:3-7 · Ev. Matt 16:24-27. + +- Com. ef-advent-3-thursday + + + +**17** ef-advent-ember-fri +`class-2` · violet · Ep. Isa 11:1-5 · Ev. Luke 1:39-47 + + + +**18** ef-advent-ember-sat +`class-2` · violet · Ep. 2 Thess 2:1-8 · Ev. Luke 3:1-6 + + + +**19** ef-advent-sunday-4 +`class-1` · violet · Ep. 1 Cor. 4:1-5 · Ev. Luke 3:1-6 + + + +**20** ef-advent-4-monday +`class-2` · violet · Ep. 1 Cor. 4:1-5 · Ev. Luke 3:1-6 + + + +**21** thomas +`class-2` · red · Ep. Eph 2:19-22 · Ev. John 20:24-29 + +- Com. ef-advent-4-tuesday + + + +**22** ef-advent-4-wednesday +`class-2` · violet · Ep. 1 Cor. 4:1-5 · Ev. Luke 3:1-6 + + + +**23** ef-advent-4-thursday +`class-2` · violet · Ep. 1 Cor. 4:1-5 · Ev. Luke 3:1-6 + + + +**24** ef-nativity-vigil +`class-1` · violet · Ep. Rom 1:1-6 · Ev. Matt 1:18-21 + + + +**25** ef-nativity +`class-1` · white · Ep. Heb 1:1-12 · Ev. John 1:1-14 + + + +**26** ef-christmas-sunday-0 +`class-2` · white · Ep. Gal 4:1-7 · Ev. Luke 2:33-40 + +- Com. stephen + + + +**27** john-the-evangelist +`class-2` · white · Ep. Ecclus 15:1-6 · Ev. John 21:19-24 + +- Com. ef-nativity-octave-day-3 + + + +**28** holy-innocents +`class-2` · red · Ep. Apoc 14:1-5 · Ev. Matt 2:13-18 + +- Com. ef-nativity-octave-day-4 + + + +**29** ef-nativity-octave-day-5 +`class-2` · white · Ep. Titus 3:4-7 · Ev. Luke 2:15-20 + +- Com. thomas-becket + + + +**30** ef-nativity-octave-day-6 +`class-2` · white · Ep. Titus 3:4-7 · Ev. Luke 2:15-20 + + + +**31** ef-nativity-octave-day-7 +`class-2` · white · Ep. Titus 3:4-7 · Ev. Luke 2:15-20 + +- Com. silvester + + + diff --git a/test/golden/ordo-2027.ms b/test/golden/ordo-2027.ms new file mode 100644 index 0000000..daeee24 --- /dev/null +++ b/test/golden/ordo-2027.ms @@ -0,0 +1,3604 @@ +.\" colitur ordo booklet -- groff ms. flavour: groff +.\" Build: colitur table --year 2027 --template ordo.ms | groff -ms -Tpdf > ordo.pdf +.\" +.\" Day label falls back to the slug when the day carries no Latin name (most +.\" temporal days, and most sanctoral entries, which are Latin-less in the +.\" shipped data) -- see ordo.tex's own comment for why the fallback is +.\" written as a name-section wrapping a plain var and its inverse, rather +.\" than a single dotted lookup and its inverse. +.TL +ORDO 2027 \(bu ef + +.SH +Ianuarius +.LP + +.IP "1" 4 +ef-circumcision +.br +\s-2class-1 \(bu white\s+2 +.br +\s-2Ep. Titus 2:11-15\s+2 +.br +\s-2Ev. Luke 2:21\s+2 + +.IP "2" 4 +Officium sanctae Mariae in sabbato +.br +\s-2class-4 \(bu white\s+2 +.br +\s-2Ep. Titus 3:4-7\s+2 +.br +\s-2Ev. Luke 2:15-20\s+2 + +.IP "3" 4 +Sanctissimi Nominis Iesu +.br +\s-2class-2 \(bu white\s+2 +.br +\s-2Ep. Acts 4:8-12\s+2 +.br +\s-2Ev. Luke 2:21\s+2 + +.IP "4" 4 +ef-christmas-1-monday +.br +\s-2class-4 \(bu white\s+2 +.br +\s-2Ep. Titus 2:11-15\s+2 +.br +\s-2Ev. Luke 2:21\s+2 + +.IP "5" 4 +ef-christmas-1-tuesday +.br +\s-2class-4 \(bu white\s+2 +.br +\s-2Ep. Titus 2:11-15\s+2 +.br +\s-2Ev. Luke 2:21\s+2 +.br +\s-2Com. telesphorus-pope-and-martyr\s+2 + +.IP "6" 4 +ef-epiphany +.br +\s-2class-1 \(bu white\s+2 +.br +\s-2Ep. Isa 60:1-6\s+2 +.br +\s-2Ev. Matt 2:1-12\s+2 + +.IP "7" 4 +ef-christmas-2-thursday +.br +\s-2class-4 \(bu white\s+2 +.br +\s-2Ep. Isa 60:1-6\s+2 +.br +\s-2Ev. Matt 2:1-12\s+2 + +.IP "8" 4 +ef-christmas-2-friday +.br +\s-2class-4 \(bu white\s+2 +.br +\s-2Ep. Isa 60:1-6\s+2 +.br +\s-2Ev. Matt 2:1-12\s+2 + +.IP "9" 4 +Officium sanctae Mariae in sabbato +.br +\s-2class-4 \(bu white\s+2 +.br +\s-2Ep. Titus 3:4-7\s+2 +.br +\s-2Ev. Luke 2:15-20\s+2 + +.IP "10" 4 +Sanctae Familiae Iesu, Mariae, Ioseph +.br +\s-2class-2 \(bu white\s+2 +.br +\s-2Ep. Col 3:12-17\s+2 +.br +\s-2Ev. Luke 2:42-52\s+2 + +.IP "11" 4 +ef-time-after-epiphany-1-monday +.br +\s-2class-4 \(bu white\s+2 +.br +\s-2Ep. Rom 12:1-5\s+2 +.br +\s-2Ev. Luke 2:42-52\s+2 +.br +\s-2Com. hyginus-pope-and-martyr\s+2 + +.IP "12" 4 +ef-time-after-epiphany-1-tuesday +.br +\s-2class-4 \(bu white\s+2 +.br +\s-2Ep. Rom 12:1-5\s+2 +.br +\s-2Ev. Luke 2:42-52\s+2 + +.IP "13" 4 +commemoration-of-the-baptism-of-the-lord +.br +\s-2class-2 \(bu white\s+2 +.br +\s-2Ep. Isa 60:1-6\s+2 +.br +\s-2Ev. John 1:29-34\s+2 + +.IP "14" 4 +hilary +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. 2 Tim 4:1-8\s+2 +.br +\s-2Ev. Matt 5:13-19\s+2 +.br +\s-2Com. felicis\s+2 + +.IP "15" 4 +paul-the-first-hermit +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. Phil 3:7-12\s+2 +.br +\s-2Ev. Matt 11:25-30\s+2 +.br +\s-2Com. maur-abbot\s+2 + +.IP "16" 4 +marcellus-i +.br +\s-2class-3 \(bu red\s+2 +.br +\s-2Ep. 1 Pet 5:1-4; 5:10-11.\s+2 +.br +\s-2Ev. Matt 16:13-19\s+2 + +.IP "17" 4 +ef-time-after-epiphany-sunday-2 +.br +\s-2class-2 \(bu green\s+2 +.br +\s-2Ep. Rom 12:6-16\s+2 +.br +\s-2Ev. John 2:1-11\s+2 + +.IP "18" 4 +ef-time-after-epiphany-2-monday +.br +\s-2class-4 \(bu green\s+2 +.br +\s-2Ep. Rom 12:6-16\s+2 +.br +\s-2Ev. John 2:1-11\s+2 +.br +\s-2Com. prisca\s+2 + +.IP "19" 4 +ef-time-after-epiphany-2-tuesday +.br +\s-2class-4 \(bu green\s+2 +.br +\s-2Ep. Rom 12:6-16\s+2 +.br +\s-2Ev. John 2:1-11\s+2 +.br +\s-2Com. canute-martyr\s+2 +.br +\s-2Com. sts-marius-martha-audifax-abachum\s+2 + +.IP "20" 4 +sts-fabian-sebastian +.br +\s-2class-3 \(bu red\s+2 +.br +\s-2Ep. Heb 11:33-39\s+2 +.br +\s-2Ev. Luke 6:17-23\s+2 + +.IP "21" 4 +agnes +.br +\s-2class-3 \(bu red\s+2 +.br +\s-2Ep. Sir 51:1-8; 51:12\s+2 +.br +\s-2Ev. Matt 25:1-13.\s+2 + +.IP "22" 4 +sts-vincent-anastasius +.br +\s-2class-3 \(bu red\s+2 +.br +\s-2Ep. Wis 3:1-8\s+2 +.br +\s-2Ev. Luke 21:9-19\s+2 + +.IP "23" 4 +raymond-of-pe-afort +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. Sir 31:8-11\s+2 +.br +\s-2Ev. Luke 12:35-40\s+2 +.br +\s-2Com. emerentiana\s+2 + +.IP "24" 4 +ef-septuagesima-sunday-1 +.br +\s-2class-2 \(bu violet\s+2 +.br +\s-2Ep. 1 Cor. 9:24-27; 10:1-5\s+2 +.br +\s-2Ev. Matt 20:1-16\s+2 + +.IP "25" 4 +conversion-of-st-paul +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. Acts 9:1-22\s+2 +.br +\s-2Ev. Matt 19:27-29.\s+2 +.br +\s-2Com. peter\s+2 + +.IP "26" 4 +polycarp +.br +\s-2class-3 \(bu red\s+2 +.br +\s-2Ep. 1 John 3:10-16\s+2 +.br +\s-2Ev. Matt 10:26-32.\s+2 + +.IP "27" 4 +john-chrysostom +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. 2 Tim 4:1-8\s+2 +.br +\s-2Ev. Matt 5:13-19\s+2 + +.IP "28" 4 +peter-nolasco +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. 1 Cor. 4:9-14\s+2 +.br +\s-2Ev. Luke 12:32-34\s+2 +.br +\s-2Com. agnes-secundo\s+2 + +.IP "29" 4 +francis-de-sales +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. 2 Tim 4:1-8\s+2 +.br +\s-2Ev. Matt 5:13-19\s+2 + +.IP "30" 4 +martina +.br +\s-2class-3 \(bu red\s+2 +.br +\s-2Ep. Sir 51:1-8; 51:12\s+2 +.br +\s-2Ev. Matt 25:1-13.\s+2 + +.IP "31" 4 +ef-septuagesima-sunday-2 +.br +\s-2class-2 \(bu violet\s+2 +.br +\s-2Ep. 2 Cor. 11:19-33; 12:1-9\s+2 +.br +\s-2Ev. Luke 8:4-15\s+2 + + +.SH +Februarius +.LP + +.IP "1" 4 +ignatius-of-antioch +.br +\s-2class-3 \(bu red\s+2 +.br +\s-2Ep. Rom 8:35-39\s+2 +.br +\s-2Ev. John 12:24-26\s+2 + +.IP "2" 4 +purification-of-the-blessed-virgin-mary +.br +\s-2class-2 \(bu white\s+2 +.br +\s-2Ep. Mal 3:1-4\s+2 +.br +\s-2Ev. Luke 2:22-32\s+2 + +.IP "3" 4 +ef-septuagesima-2-wednesday +.br +\s-2class-4 \(bu violet\s+2 +.br +\s-2Ep. 2 Cor. 11:19-33; 12:1-9\s+2 +.br +\s-2Ev. Luke 8:4-15\s+2 +.br +\s-2Com. blaise\s+2 + +.IP "4" 4 +andrew-corsini +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. Sir 44:16-27; 45:3-20\s+2 +.br +\s-2Ev. Matt 25:14-23\s+2 + +.IP "5" 4 +agatha +.br +\s-2class-3 \(bu red\s+2 +.br +\s-2Ep. 1 Cor. 1:26-31\s+2 +.br +\s-2Ev. Matt 19:3-12.\s+2 + +.IP "6" 4 +titus +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. Sir 44:16-27; 45:3-20\s+2 +.br +\s-2Ev. Luke 10:1-9\s+2 +.br +\s-2Com. dorothy\s+2 + +.IP "7" 4 +ef-septuagesima-sunday-3 +.br +\s-2class-2 \(bu violet\s+2 +.br +\s-2Ep. 1 Cor. 13:1-13\s+2 +.br +\s-2Ev. Luke 18:31-43\s+2 + +.IP "8" 4 +john-of-matha +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. Sir 31:8-11\s+2 +.br +\s-2Ev. Luke 12:35-40\s+2 + +.IP "9" 4 +cyril-of-alexandria +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. 2 Tim 4:1-8\s+2 +.br +\s-2Ev. Matt 5:13-19\s+2 +.br +\s-2Com. appollonia\s+2 + +.IP "10" 4 +ef-ash-wednesday +.br +\s-2class-1 \(bu violet\s+2 +.br +\s-2Ep. Joel 2:12-19\s+2 +.br +\s-2Ev. Matt 6:16-21\s+2 + +.IP "11" 4 +ef-lent-after-ashes-thursday +.br +\s-2class-3 \(bu violet\s+2 +.br +\s-2Ep. Isa 38:1-6\s+2 +.br +\s-2Ev. Matt 8:5-13\s+2 +.br +\s-2Com. our-lady-of-lourdes\s+2 + +.IP "12" 4 +ef-lent-after-ashes-friday +.br +\s-2class-3 \(bu violet\s+2 +.br +\s-2Ep. Isa 58:1-9\s+2 +.br +\s-2Ev. Matt 5:43-48; 6:1-4\s+2 +.br +\s-2Com. seven-holy-servite-founders\s+2 + +.IP "13" 4 +ef-lent-after-ashes-saturday +.br +\s-2class-3 \(bu violet\s+2 +.br +\s-2Ep. Isa 58:9-14\s+2 +.br +\s-2Ev. Mark 6:47-56\s+2 + +.IP "14" 4 +ef-lent-sunday-1 +.br +\s-2class-1 \(bu violet\s+2 +.br +\s-2Ep. 2 Cor. 6:1-10\s+2 +.br +\s-2Ev. Matt 4:1-11\s+2 + +.IP "15" 4 +ef-lent-1-monday +.br +\s-2class-3 \(bu violet\s+2 +.br +\s-2Ep. Ezech 34:11-16\s+2 +.br +\s-2Ev. Matt 25:31-46\s+2 +.br +\s-2Com. sts-faustinus-jovita\s+2 + +.IP "16" 4 +ef-lent-1-tuesday +.br +\s-2class-3 \(bu violet\s+2 +.br +\s-2Ep. Isa 55:6-11\s+2 +.br +\s-2Ev. Matt 21:10-17\s+2 + +.IP "17" 4 +ef-lent-ember-wed +.br +\s-2class-2 \(bu violet\s+2 +.br +\s-2Ep. 3 Kgs. 19:3-8\s+2 +.br +\s-2Ev. Matt 12:38-50\s+2 + +.IP "18" 4 +ef-lent-1-thursday +.br +\s-2class-3 \(bu violet\s+2 +.br +\s-2Ep. Ezech 18:1-9\s+2 +.br +\s-2Ev. Matt 15:21-28\s+2 +.br +\s-2Com. simeon\s+2 + +.IP "19" 4 +ef-lent-ember-fri +.br +\s-2class-2 \(bu violet\s+2 +.br +\s-2Ep. Ezech 18:20-28\s+2 +.br +\s-2Ev. John 5:1-15\s+2 + +.IP "20" 4 +ef-lent-ember-sat +.br +\s-2class-2 \(bu violet\s+2 +.br +\s-2Ep. 1 Thess. 5:14-23\s+2 +.br +\s-2Ev. Matt 17:1-9\s+2 + +.IP "21" 4 +ef-lent-sunday-2 +.br +\s-2class-1 \(bu violet\s+2 +.br +\s-2Ep. 1 Thess. 4:1-7\s+2 +.br +\s-2Ev. Matt 17:1-9\s+2 + +.IP "22" 4 +chair-of-st-peter +.br +\s-2class-2 \(bu white\s+2 +.br +\s-2Ep. 1 Pet 1:1-7\s+2 +.br +\s-2Ev. Matt 16:13-19\s+2 +.br +\s-2Com. ef-lent-2-monday\s+2 +.br +\s-2Com. paul\s+2 + +.IP "23" 4 +ef-lent-2-tuesday +.br +\s-2class-3 \(bu violet\s+2 +.br +\s-2Ep. 3 Kings 17:8-16\s+2 +.br +\s-2Ev. Matt 23:1-12\s+2 +.br +\s-2Com. peter-damien\s+2 + +.IP "24" 4 +matthias +.br +\s-2class-2 \(bu red\s+2 +.br +\s-2Ep. Acts 1:15-26\s+2 +.br +\s-2Ev. Matt 11:25-30\s+2 +.br +\s-2Com. ef-lent-2-wednesday\s+2 + +.IP "25" 4 +ef-lent-2-thursday +.br +\s-2class-3 \(bu violet\s+2 +.br +\s-2Ep. Jer 17:5-10\s+2 +.br +\s-2Ev. Luke 16:19-31\s+2 + +.IP "26" 4 +ef-lent-2-friday +.br +\s-2class-3 \(bu violet\s+2 +.br +\s-2Ep. Gen 37:6-22\s+2 +.br +\s-2Ev. Matt 21:33-46\s+2 + +.IP "27" 4 +ef-lent-2-saturday +.br +\s-2class-3 \(bu violet\s+2 +.br +\s-2Ep. Gen 27:6-40\s+2 +.br +\s-2Ev. Luke 15:11-32\s+2 +.br +\s-2Com. gabriel-of-our-lady-of-sorrows\s+2 + +.IP "28" 4 +ef-lent-sunday-3 +.br +\s-2class-1 \(bu violet\s+2 +.br +\s-2Ep. Eph 5:1-9\s+2 +.br +\s-2Ev. Luke 11:14-28\s+2 + + +.SH +Martius +.LP + +.IP "1" 4 +ef-lent-3-monday +.br +\s-2class-3 \(bu violet\s+2 +.br +\s-2Ep. 4 Kings 5:1-15\s+2 +.br +\s-2Ev. Luke 4:23-30\s+2 + +.IP "2" 4 +ef-lent-3-tuesday +.br +\s-2class-3 \(bu violet\s+2 +.br +\s-2Ep. 4 Kings 4:1-7\s+2 +.br +\s-2Ev. Matt 18:15-22\s+2 + +.IP "3" 4 +ef-lent-3-wednesday +.br +\s-2class-3 \(bu violet\s+2 +.br +\s-2Ep. Ex 20:12-24\s+2 +.br +\s-2Ev. Matt 15:1-20\s+2 + +.IP "4" 4 +ef-lent-3-thursday +.br +\s-2class-3 \(bu violet\s+2 +.br +\s-2Ep. Jer 7:1-7\s+2 +.br +\s-2Ev. Luke 4:38-44.\s+2 +.br +\s-2Com. casimir\s+2 +.br +\s-2Com. lucius\s+2 + +.IP "5" 4 +ef-lent-3-friday +.br +\s-2class-3 \(bu violet\s+2 +.br +\s-2Ep. Num 20:1, 3; 6-13.\s+2 +.br +\s-2Ev. John 4:5-42\s+2 + +.IP "6" 4 +ef-lent-3-saturday +.br +\s-2class-3 \(bu violet\s+2 +.br +\s-2Ep. Dan 13:1-9, 15-17, 19-30, 33-62.\s+2 +.br +\s-2Ev. John 8:1-11\s+2 +.br +\s-2Com. sts-felicitas-perpetua\s+2 + +.IP "7" 4 +ef-lent-sunday-4 +.br +\s-2class-1 \(bu rose\s+2 +.br +\s-2Ep. Gal 4:22-31\s+2 +.br +\s-2Ev. John 6:1-15\s+2 + +.IP "8" 4 +ef-lent-4-monday +.br +\s-2class-3 \(bu violet\s+2 +.br +\s-2Ep. 3 Kings 3:16-28\s+2 +.br +\s-2Ev. John 2:13-25\s+2 +.br +\s-2Com. john-of-god\s+2 + +.IP "9" 4 +ef-lent-4-tuesday +.br +\s-2class-3 \(bu violet\s+2 +.br +\s-2Ep. Ex 32:7-14\s+2 +.br +\s-2Ev. John 7:14-31\s+2 +.br +\s-2Com. frances-rome\s+2 + +.IP "10" 4 +ef-lent-4-wednesday +.br +\s-2class-3 \(bu violet\s+2 +.br +\s-2Ep. Isa. 1:16-19\s+2 +.br +\s-2Ev. John 9:1-38\s+2 +.br +\s-2Com. forty-holy-martyrs-of-sebaste\s+2 + +.IP "11" 4 +ef-lent-4-thursday +.br +\s-2class-3 \(bu violet\s+2 +.br +\s-2Ep. 4 Kings 4:25-38\s+2 +.br +\s-2Ev. Luke 7:11-16\s+2 + +.IP "12" 4 +ef-lent-4-friday +.br +\s-2class-3 \(bu violet\s+2 +.br +\s-2Ep. 3 Kings 17:17-24\s+2 +.br +\s-2Ev. John 11:1-45\s+2 +.br +\s-2Com. gregory-the-great\s+2 + +.IP "13" 4 +ef-lent-4-saturday +.br +\s-2class-3 \(bu violet\s+2 +.br +\s-2Ep. Isa 49:8-15\s+2 +.br +\s-2Ev. John 8:12-20\s+2 + +.IP "14" 4 +ef-passion-sunday +.br +\s-2class-1 \(bu violet\s+2 +.br +\s-2Ep. Heb 9:11-15.\s+2 +.br +\s-2Ev. John 8:46-59.\s+2 + +.IP "15" 4 +ef-passiontide-1-monday +.br +\s-2class-3 \(bu violet\s+2 +.br +\s-2Ep. Jonas 3:1-10\s+2 +.br +\s-2Ev. John 7:32-39\s+2 + +.IP "16" 4 +ef-passiontide-1-tuesday +.br +\s-2class-3 \(bu violet\s+2 +.br +\s-2Ep. Dan 14:27, 28-42\s+2 +.br +\s-2Ev. John 7:1-13\s+2 + +.IP "17" 4 +ef-passiontide-1-wednesday +.br +\s-2class-3 \(bu violet\s+2 +.br +\s-2Ep. Lev 19:1-2, 11-19, 25\s+2 +.br +\s-2Ev. John 10:22-38\s+2 +.br +\s-2Com. patrick\s+2 + +.IP "18" 4 +ef-passiontide-1-thursday +.br +\s-2class-3 \(bu violet\s+2 +.br +\s-2Ep. Dan 3:25, 34-45.\s+2 +.br +\s-2Ev. Luke 7:36-50\s+2 +.br +\s-2Com. cyril-of-jerusalem\s+2 + +.IP "19" 4 +joseph-spouse-of-the-bl-virgin-mary +.br +\s-2class-1 \(bu white\s+2 +.br +\s-2Ep. Ecclus 45:1-6\s+2 +.br +\s-2Ev. Matt 1:18-21\s+2 +.br +\s-2Com. ef-passiontide-1-friday\s+2 + +.IP "20" 4 +ef-passiontide-1-saturday +.br +\s-2class-3 \(bu violet\s+2 +.br +\s-2Ep. Jer 18:18-23\s+2 +.br +\s-2Ev. John 12:10-36\s+2 + +.IP "21" 4 +ef-palm-sunday +.br +\s-2class-1 \(bu violet\s+2 +.br +\s-2Ep. Phil 2:5-11\s+2 +.br +\s-2Ev. Matt. 26:36-75; 27:1-60.\s+2 + +.IP "22" 4 +ef-passiontide-2-monday +.br +\s-2class-1 \(bu violet\s+2 +.br +\s-2Ep. Isa 50:5-10\s+2 +.br +\s-2Ev. John 12:1-9\s+2 + +.IP "23" 4 +ef-passiontide-2-tuesday +.br +\s-2class-1 \(bu violet\s+2 +.br +\s-2Ep. Jer 11:18-20\s+2 +.br +\s-2Ev. Mark 14:32-72; 15, 1-46\s+2 + +.IP "24" 4 +ef-passiontide-2-wednesday +.br +\s-2class-1 \(bu violet\s+2 +.br +\s-2Ep. Isa 53:1-12\s+2 +.br +\s-2Ev. Luke 22:39-71; 23:1-53\s+2 + +.IP "25" 4 +Feria V in Cena Domini +.br +\s-2class-1 \(bu white\s+2 +.br +\s-2Ep. 1 Cor 11:20-32\s+2 +.br +\s-2Ev. John 13:1-15\s+2 + +.IP "26" 4 +Feria VI in Passione et Morte Domini +.br +\s-2class-1 \(bu black\s+2 +.br +\s-2Ep. Ex 12:1-11\s+2 +.br +\s-2Ev. John 18:1-40; 19:1-42\s+2 + +.IP "27" 4 +Sabbato sancto +.br +\s-2class-1 \(bu violet\s+2 +.br +\s-2Ep. Col 3:1-4\s+2 +.br +\s-2Ev. Matt 28:1-7\s+2 + +.IP "28" 4 +ef-easter-sunday +.br +\s-2class-1 \(bu white\s+2 +.br +\s-2Ep. 1 Cor 5:7-8\s+2 +.br +\s-2Ev. Mark 16:1-7\s+2 + +.IP "29" 4 +ef-easter-1-monday +.br +\s-2class-1 \(bu white\s+2 +.br +\s-2Ep. Acts 10:37-43.\s+2 +.br +\s-2Ev. Luke 24:13-35\s+2 + +.IP "30" 4 +ef-easter-1-tuesday +.br +\s-2class-1 \(bu white\s+2 +.br +\s-2Ep. Acts 13:16; 13:26-33\s+2 +.br +\s-2Ev. Luke 24:36-47\s+2 + +.IP "31" 4 +ef-easter-1-wednesday +.br +\s-2class-1 \(bu white\s+2 +.br +\s-2Ep. Acts 3:13-15; 3:17-19\s+2 +.br +\s-2Ev. John 21:1-14\s+2 + + +.SH +Aprilis +.LP + +.IP "1" 4 +ef-easter-1-thursday +.br +\s-2class-1 \(bu white\s+2 +.br +\s-2Ep. Acts 8:26-40\s+2 +.br +\s-2Ev. John 20:11-18\s+2 + +.IP "2" 4 +ef-easter-1-friday +.br +\s-2class-1 \(bu white\s+2 +.br +\s-2Ep. 1 Pet 3:18-22\s+2 +.br +\s-2Ev. Matt 28:16-20\s+2 + +.IP "3" 4 +ef-easter-1-saturday +.br +\s-2class-1 \(bu white\s+2 +.br +\s-2Ep. 1 Pet 2:1-10\s+2 +.br +\s-2Ev. John 20:1-9\s+2 + +.IP "4" 4 +ef-low-sunday +.br +\s-2class-1 \(bu white\s+2 +.br +\s-2Ep. 1 John 5:4-10\s+2 +.br +\s-2Ev. John 20:19-31\s+2 + +.IP "5" 4 +annunciation-of-the-blessed-virgin-mary +.br +\s-2class-1 \(bu white\s+2 +.br +\s-2Ep. Isa 7:10-15\s+2 +.br +\s-2Ev. Luke 1:26-38\s+2 + +.IP "6" 4 +ef-easter-2-tuesday +.br +\s-2class-4 \(bu white\s+2 +.br +\s-2Ep. 1 John 5:4-10\s+2 +.br +\s-2Ev. John 20:19-31\s+2 + +.IP "7" 4 +ef-easter-2-wednesday +.br +\s-2class-4 \(bu white\s+2 +.br +\s-2Ep. 1 John 5:4-10\s+2 +.br +\s-2Ev. John 20:19-31\s+2 + +.IP "8" 4 +ef-easter-2-thursday +.br +\s-2class-4 \(bu white\s+2 +.br +\s-2Ep. 1 John 5:4-10\s+2 +.br +\s-2Ev. John 20:19-31\s+2 + +.IP "9" 4 +ef-easter-2-friday +.br +\s-2class-4 \(bu white\s+2 +.br +\s-2Ep. 1 John 5:4-10\s+2 +.br +\s-2Ev. John 20:19-31\s+2 + +.IP "10" 4 +Officium sanctae Mariae in sabbato +.br +\s-2class-4 \(bu white\s+2 +.br +\s-2Ep. Ecclus 24:14-16\s+2 +.br +\s-2Ev. John 19:25-27\s+2 + +.IP "11" 4 +ef-easter-sunday-3 +.br +\s-2class-2 \(bu white\s+2 +.br +\s-2Ep. 1 Pet 2:21-25\s+2 +.br +\s-2Ev. John 10:11-16\s+2 + +.IP "12" 4 +ef-easter-3-monday +.br +\s-2class-4 \(bu white\s+2 +.br +\s-2Ep. 1 Pet 2:21-25\s+2 +.br +\s-2Ev. John 10:11-16\s+2 + +.IP "13" 4 +hermenegild +.br +\s-2class-3 \(bu red\s+2 +.br +\s-2Ep. Wis 10:10-14\s+2 +.br +\s-2Ev. Luke 14:26-33.\s+2 + +.IP "14" 4 +justin +.br +\s-2class-3 \(bu red\s+2 +.br +\s-2Ep. 1 Cor 1:18-25; 1:30;\s+2 +.br +\s-2Ev. Luke 12:2-8\s+2 +.br +\s-2Com. sts-tiburtius-valerian-et-maximus-martyrs\s+2 + +.IP "15" 4 +ef-easter-3-thursday +.br +\s-2class-4 \(bu white\s+2 +.br +\s-2Ep. 1 Pet 2:21-25\s+2 +.br +\s-2Ev. John 10:11-16\s+2 + +.IP "16" 4 +ef-easter-3-friday +.br +\s-2class-4 \(bu white\s+2 +.br +\s-2Ep. 1 Pet 2:21-25\s+2 +.br +\s-2Ev. John 10:11-16\s+2 + +.IP "17" 4 +Officium sanctae Mariae in sabbato +.br +\s-2class-4 \(bu white\s+2 +.br +\s-2Ep. Ecclus 24:14-16\s+2 +.br +\s-2Ev. John 19:25-27\s+2 +.br +\s-2Com. anicetus\s+2 + +.IP "18" 4 +ef-easter-sunday-4 +.br +\s-2class-2 \(bu white\s+2 +.br +\s-2Ep. 1 Pet 2:11-19\s+2 +.br +\s-2Ev. John 16:16-22\s+2 + +.IP "19" 4 +ef-easter-4-monday +.br +\s-2class-4 \(bu white\s+2 +.br +\s-2Ep. 1 Pet 2:11-19\s+2 +.br +\s-2Ev. John 16:16-22\s+2 + +.IP "20" 4 +ef-easter-4-tuesday +.br +\s-2class-4 \(bu white\s+2 +.br +\s-2Ep. 1 Pet 2:11-19\s+2 +.br +\s-2Ev. John 16:16-22\s+2 + +.IP "21" 4 +anselm +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. 2 Tim 4:1-8\s+2 +.br +\s-2Ev. Matt 5:13-19\s+2 + +.IP "22" 4 +sts-soter-caius +.br +\s-2class-3 \(bu red\s+2 +.br +\s-2Ep. 1 Pet 5:1-4; 5:10-11.\s+2 +.br +\s-2Ev. Matt 16:13-19\s+2 + +.IP "23" 4 +ef-easter-4-friday +.br +\s-2class-4 \(bu white\s+2 +.br +\s-2Ep. 1 Pet 2:11-19\s+2 +.br +\s-2Ev. John 16:16-22\s+2 +.br +\s-2Com. george\s+2 + +.IP "24" 4 +fidelis-of-sigmaringen +.br +\s-2class-3 \(bu red\s+2 +.br +\s-2Ep. Wis 5:1-5\s+2 +.br +\s-2Ev. John 15:1-7\s+2 + +.IP "25" 4 +ef-easter-sunday-5 +.br +\s-2class-2 \(bu white\s+2 +.br +\s-2Ep. Jas 1:17-21\s+2 +.br +\s-2Ev. John 16:5-14\s+2 +.br +\s-2Com. major-litanies\s+2 + +.IP "26" 4 +sts-cletus-marcellinus +.br +\s-2class-3 \(bu red\s+2 +.br +\s-2Ep. 1 Pet 5:1-4; 5:10-11.\s+2 +.br +\s-2Ev. Matt 16:13-19\s+2 + +.IP "27" 4 +peter-canisius +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. 2 Tim 4:1-8\s+2 +.br +\s-2Ev. Matt 5:13-19\s+2 + +.IP "28" 4 +paul-of-the-cross +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. 1 Cor 1:17-25.\s+2 +.br +\s-2Ev. Luke 10:1-9\s+2 + +.IP "29" 4 +peter-of-verona +.br +\s-2class-3 \(bu red\s+2 +.br +\s-2Ep. 2 Tim. 2:8-10; 3:10-12.\s+2 +.br +\s-2Ev. Matt 10:34-42\s+2 + +.IP "30" 4 +catherine-of-siena +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. 2 Cor 10:17-18; 11:1-2\s+2 +.br +\s-2Ev. Matt 25:1-13.\s+2 + + +.SH +Maius +.LP + +.IP "1" 4 +joseph-the-workman +.br +\s-2class-1 \(bu white\s+2 +.br +\s-2Ep. Col. 3:14-15, 17, 23-24\s+2 +.br +\s-2Ev. Matt 13:54-58\s+2 + +.IP "2" 4 +ef-easter-sunday-6 +.br +\s-2class-2 \(bu white\s+2 +.br +\s-2Ep. Jas 1:22-27\s+2 +.br +\s-2Ev. John 16:23-30\s+2 + +.IP "3" 4 +ef-rogation-monday +.br +\s-2class-4 \(bu violet\s+2 +.br +\s-2Ep. Jas 1:22-27\s+2 +.br +\s-2Ev. John 16:23-30\s+2 +.br +\s-2Com. sts-alexander-companions\s+2 + +.IP "4" 4 +monica +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. 1 Tim. 5:3-10.\s+2 +.br +\s-2Ev. Luke 7:11-16\s+2 + +.IP "5" 4 +ef-ascension-vigil +.br +\s-2class-2 \(bu white\s+2 +.br +\s-2Ep. Eph. 4:7-13.\s+2 +.br +\s-2Ev. John 17:1-11.\s+2 +.br +\s-2Com. pius-v\s+2 + +.IP "6" 4 +ef-ascension +.br +\s-2class-1 \(bu white\s+2 +.br +\s-2Ep. Acts 1:1-11\s+2 +.br +\s-2Ev. Mark 16:14-20\s+2 + +.IP "7" 4 +stanislaus +.br +\s-2class-3 \(bu red\s+2 +.br +\s-2Ep. Wis 5:1-5\s+2 +.br +\s-2Ev. John 15:1-7\s+2 + +.IP "8" 4 +Officium sanctae Mariae in sabbato +.br +\s-2class-4 \(bu white\s+2 +.br +\s-2Ep. Ecclus 24:14-16\s+2 +.br +\s-2Ev. John 19:25-27\s+2 + +.IP "9" 4 +ef-easter-sunday-7 +.br +\s-2class-2 \(bu white\s+2 +.br +\s-2Ep. 1 Pet 4:7-11.\s+2 +.br +\s-2Ev. John 15:26-27; 16:1-4.\s+2 + +.IP "10" 4 +antoninus +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. Sir 44:16-27; 45:3-20\s+2 +.br +\s-2Ev. Matt 25:14-23\s+2 +.br +\s-2Com. gordiano-and-epimacho\s+2 + +.IP "11" 4 +sts-philip-james +.br +\s-2class-2 \(bu red\s+2 +.br +\s-2Ep. Wis. 5:1-5\s+2 +.br +\s-2Ev. John 14:1-13\s+2 + +.IP "12" 4 +sts-nereus-achilleus-domitilla-pancras +.br +\s-2class-3 \(bu red\s+2 +.br +\s-2Ep. Wis. 5:1-5\s+2 +.br +\s-2Ev. John 4:46-53\s+2 + +.IP "13" 4 +robert-bellarmine +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. Wis 7:7-14.\s+2 +.br +\s-2Ev. Matt 5:13-19\s+2 + +.IP "14" 4 +ef-easter-7-friday +.br +\s-2class-4 \(bu white\s+2 +.br +\s-2Ep. 1 Pet 4:7-11.\s+2 +.br +\s-2Ev. John 15:26-27; 16:1-4.\s+2 +.br +\s-2Com. boniface-martyr\s+2 + +.IP "15" 4 +ef-pentecost-vigil +.br +\s-2class-1 \(bu red\s+2 +.br +\s-2Ep. Acts 19:1-8.\s+2 +.br +\s-2Ev. John 14:15-21.\s+2 + +.IP "16" 4 +ef-pentecost +.br +\s-2class-1 \(bu red\s+2 +.br +\s-2Ep. Acts 2:1-11.\s+2 +.br +\s-2Ev. John 14:23-31.\s+2 + +.IP "17" 4 +ef-easter-8-monday +.br +\s-2class-1 \(bu red\s+2 +.br +\s-2Ep. Acts 10:34, 42-48\s+2 +.br +\s-2Ev. John 3:16-21\s+2 + +.IP "18" 4 +ef-easter-8-tuesday +.br +\s-2class-1 \(bu red\s+2 +.br +\s-2Ep. Acts 8:14-17.\s+2 +.br +\s-2Ev. John 10:1-10.\s+2 + +.IP "19" 4 +ef-pentecost-ember-wed +.br +\s-2class-1 \(bu red\s+2 +.br +\s-2Ep. Acts 5:12-16\s+2 +.br +\s-2Ev. John 6:44-52.\s+2 + +.IP "20" 4 +ef-easter-8-thursday +.br +\s-2class-1 \(bu red\s+2 +.br +\s-2Ep. Acts 8:5-8\s+2 +.br +\s-2Ev. Luke 9:1-6\s+2 + +.IP "21" 4 +ef-pentecost-ember-fri +.br +\s-2class-1 \(bu red\s+2 +.br +\s-2Ep. Joel 2:23-24; 26-27\s+2 +.br +\s-2Ev. Luke 5:17-26\s+2 + +.IP "22" 4 +ef-pentecost-ember-sat +.br +\s-2class-1 \(bu red\s+2 +.br +\s-2Ep. Rom 5:1-5.\s+2 +.br +\s-2Ev. Luke 4:38-44.\s+2 + +.IP "23" 4 +ef-trinity +.br +\s-2class-1 \(bu white\s+2 +.br +\s-2Ep. Rom 11:33-36.\s+2 +.br +\s-2Ev. Matt 28:18-20\s+2 + +.IP "24" 4 +ef-time-after-pentecost-1-monday +.br +\s-2class-4 \(bu green\s+2 +.br +\s-2Ep. 1 John 4:8-21\s+2 +.br +\s-2Ev. Luke 6:36-42\s+2 + +.IP "25" 4 +gregory-vii +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. 1 Pet 5:1-4; 5:10-11.\s+2 +.br +\s-2Ev. Matt 16:13-19\s+2 +.br +\s-2Com. urban-pope-and-martyr\s+2 + +.IP "26" 4 +philip-neri +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. Wis 7:7-14.\s+2 +.br +\s-2Ev. Luke 12:35-40\s+2 +.br +\s-2Com. eleutherius\s+2 + +.IP "27" 4 +ef-corpus-christi +.br +\s-2class-1 \(bu white\s+2 +.br +\s-2Ep. 1 Cor 11:23-29\s+2 +.br +\s-2Ev. John 6:56-59\s+2 + +.IP "28" 4 +augustine-of-canterbury +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. 1 Thess 2:2-9\s+2 +.br +\s-2Ev. Luke 10:1-9\s+2 + +.IP "29" 4 +mary-magdalene-de-pazzi +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. 2 Cor 10:17-18; 11:1-2\s+2 +.br +\s-2Ev. Matt 25:1-13.\s+2 + +.IP "30" 4 +ef-time-after-pentecost-sunday-2 +.br +\s-2class-2 \(bu green\s+2 +.br +\s-2Ep. 1 John 3:13-18.\s+2 +.br +\s-2Ev. Luke 14:16-24.\s+2 + +.IP "31" 4 +queenship-of-the-blessed-virgin-mary +.br +\s-2class-2 \(bu white\s+2 +.br +\s-2Ep. Eccli 24:5; 14:7; 14:9-11; 24:30-31\s+2 +.br +\s-2Ev. Luke 1:26-33\s+2 +.br +\s-2Com. petronilla\s+2 + + +.SH +Iunius +.LP + +.IP "1" 4 +angela-merici +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. 2 Cor 10:17-18; 11:1-2\s+2 +.br +\s-2Ev. Matt 25:1-13.\s+2 + +.IP "2" 4 +ef-time-after-pentecost-2-wednesday +.br +\s-2class-4 \(bu green\s+2 +.br +\s-2Ep. 1 John 3:13-18.\s+2 +.br +\s-2Ev. Luke 14:16-24.\s+2 +.br +\s-2Com. sts-marcellinus-peter-erasmus\s+2 + +.IP "3" 4 +ef-time-after-pentecost-2-thursday +.br +\s-2class-4 \(bu green\s+2 +.br +\s-2Ep. 1 John 3:13-18.\s+2 +.br +\s-2Ev. Luke 14:16-24.\s+2 + +.IP "4" 4 +ef-sacred-heart +.br +\s-2class-1 \(bu white\s+2 +.br +\s-2Ep. Eph 3:8-12, 14-19\s+2 +.br +\s-2Ev. John 19:31-37\s+2 + +.IP "5" 4 +boniface +.br +\s-2class-3 \(bu red\s+2 +.br +\s-2Ep. Ecclus 44:1-15\s+2 +.br +\s-2Ev. Matt 5:1-12\s+2 + +.IP "6" 4 +ef-time-after-pentecost-sunday-3 +.br +\s-2class-2 \(bu green\s+2 +.br +\s-2Ep. 1 Pet. 5:6-11\s+2 +.br +\s-2Ev. Luke 15:1-10\s+2 + +.IP "7" 4 +ef-time-after-pentecost-3-monday +.br +\s-2class-4 \(bu green\s+2 +.br +\s-2Ep. 1 Pet. 5:6-11\s+2 +.br +\s-2Ev. Luke 15:1-10\s+2 + +.IP "8" 4 +ef-time-after-pentecost-3-tuesday +.br +\s-2class-4 \(bu green\s+2 +.br +\s-2Ep. 1 Pet. 5:6-11\s+2 +.br +\s-2Ev. Luke 15:1-10\s+2 + +.IP "9" 4 +ef-time-after-pentecost-3-wednesday +.br +\s-2class-4 \(bu green\s+2 +.br +\s-2Ep. 1 Pet. 5:6-11\s+2 +.br +\s-2Ev. Luke 15:1-10\s+2 +.br +\s-2Com. sts-primus-felicianus\s+2 + +.IP "10" 4 +margaret-of-scotland +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. Prov 31:10-31\s+2 +.br +\s-2Ev. Matt 13:44-52.\s+2 + +.IP "11" 4 +barnabas +.br +\s-2class-3 \(bu red\s+2 +.br +\s-2Ep. Acts 11:21-26; 13:1-3\s+2 +.br +\s-2Ev. Matt 10:16-22\s+2 + +.IP "12" 4 +john-of-san-fecundo +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. Sir 31:8-11\s+2 +.br +\s-2Ev. Luke 12:35-40\s+2 +.br +\s-2Com. basilidus\s+2 + +.IP "13" 4 +ef-time-after-pentecost-sunday-4 +.br +\s-2class-2 \(bu green\s+2 +.br +\s-2Ep. Rom 8:18-23\s+2 +.br +\s-2Ev. Luke 5:1-11\s+2 + +.IP "14" 4 +basil-the-great +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. 2 Tim 4:1-8\s+2 +.br +\s-2Ev. Luke 14:26-35\s+2 + +.IP "15" 4 +ef-time-after-pentecost-4-tuesday +.br +\s-2class-4 \(bu green\s+2 +.br +\s-2Ep. Rom 8:18-23\s+2 +.br +\s-2Ev. Luke 5:1-11\s+2 +.br +\s-2Com. vitus\s+2 + +.IP "16" 4 +ef-time-after-pentecost-4-wednesday +.br +\s-2class-4 \(bu green\s+2 +.br +\s-2Ep. Rom 8:18-23\s+2 +.br +\s-2Ev. Luke 5:1-11\s+2 + +.IP "17" 4 +gregory-barbarigo +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. Sir 44:16-27; 45:3-20\s+2 +.br +\s-2Ev. Matt 25:14-23\s+2 + +.IP "18" 4 +ephrem-of-syria +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. 2 Tim 4:1-8\s+2 +.br +\s-2Ev. Matt 5:13-19\s+2 +.br +\s-2Com. marcus-and-marcellianus\s+2 + +.IP "19" 4 +julia-of-falconieri +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. 2 Cor 10:17-18; 11:1-2\s+2 +.br +\s-2Ev. Matt 25:1-13.\s+2 +.br +\s-2Com. sts-gervasius-and-protasius\s+2 + +.IP "20" 4 +ef-time-after-pentecost-sunday-5 +.br +\s-2class-2 \(bu green\s+2 +.br +\s-2Ep. 1 Pet 3:8-15.\s+2 +.br +\s-2Ev. Matt 5:20-24.\s+2 + +.IP "21" 4 +aloysius-gongzaga +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. Sir 31:8-11\s+2 +.br +\s-2Ev. Matt 22:29-40\s+2 + +.IP "22" 4 +paulinus-of-nola +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. 2 Cor. 8:9-15\s+2 +.br +\s-2Ev. Luke 12:32-34\s+2 + +.IP "23" 4 +vigil-of-the-nativity-of-st-john-the-baptist +.br +\s-2class-2 \(bu violet\s+2 +.br +\s-2Ep. Jer 1:4-10\s+2 +.br +\s-2Ev. Luke 1:5-17\s+2 + +.IP "24" 4 +nativity-of-st-john-the-baptist +.br +\s-2class-1 \(bu white\s+2 +.br +\s-2Ep. Isa 49:1-3, 5-7.\s+2 +.br +\s-2Ev. Luke 1:57-68\s+2 + +.IP "25" 4 +william +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. Ecclus 45:1-6\s+2 +.br +\s-2Ev. Matt 19:27-29.\s+2 + +.IP "26" 4 +sts-john-paul +.br +\s-2class-3 \(bu red\s+2 +.br +\s-2Ep. Eccli 44:10-15\s+2 +.br +\s-2Ev. Luke 12:1-8\s+2 + +.IP "27" 4 +ef-time-after-pentecost-sunday-6 +.br +\s-2class-2 \(bu green\s+2 +.br +\s-2Ep. Rom 6:3-11.\s+2 +.br +\s-2Ev. Mark 8:1-9\s+2 + +.IP "28" 4 +vigil-of-sts-peter-paul +.br +\s-2class-2 \(bu violet\s+2 +.br +\s-2Ep. Acts 3:1-10\s+2 +.br +\s-2Ev. John 21:15-19\s+2 + +.IP "29" 4 +sts-peter-paul +.br +\s-2class-1 \(bu red\s+2 +.br +\s-2Ep. Acts 12:1-11\s+2 +.br +\s-2Ev. Matt 16:13-19\s+2 + +.IP "30" 4 +in-commemoratione-sancti-pauli-apostoli +.br +\s-2class-3 \(bu red\s+2 +.br +\s-2Ep. Gal 1:11-20\s+2 +.br +\s-2Ev. Matt 10:16-22\s+2 +.br +\s-2Com. commemoration-of-st-peter\s+2 + + +.SH +Iulius +.LP + +.IP "1" 4 +precious-blood-of-our-lord-jesus-christ +.br +\s-2class-1 \(bu red\s+2 +.br +\s-2Ep. Heb 9:11-15.\s+2 +.br +\s-2Ev. John 19:30-35\s+2 + +.IP "2" 4 +visitation-of-the-blessed-virgin-mary +.br +\s-2class-2 \(bu white\s+2 +.br +\s-2Ep. Song 2:8-14\s+2 +.br +\s-2Ev. Luke 1:39-47\s+2 +.br +\s-2Com. processus-and-martinian\s+2 + +.IP "3" 4 +irenaeus +.br +\s-2class-3 \(bu red\s+2 +.br +\s-2Ep. 2 Tim. 3:14-17; 4:1-5\s+2 +.br +\s-2Ev. Matt 10:28-33\s+2 + +.IP "4" 4 +ef-time-after-pentecost-sunday-7 +.br +\s-2class-2 \(bu green\s+2 +.br +\s-2Ep. Rom 6:19-23\s+2 +.br +\s-2Ev. Matt 7:15-21\s+2 + +.IP "5" 4 +anthony-mary-zaccariah +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. 1 Tim. 4:8-16\s+2 +.br +\s-2Ev. Mark 10:15-21\s+2 + +.IP "6" 4 +ef-time-after-pentecost-7-tuesday +.br +\s-2class-4 \(bu green\s+2 +.br +\s-2Ep. Rom 6:19-23\s+2 +.br +\s-2Ev. Matt 7:15-21\s+2 + +.IP "7" 4 +sts-cyril-methodius +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. Heb 7:23-27\s+2 +.br +\s-2Ev. Luke 10:1-9\s+2 + +.IP "8" 4 +elizabeth-of-portugal +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. Prov 31:10-31\s+2 +.br +\s-2Ev. Matt 13:44-52.\s+2 + +.IP "9" 4 +ef-time-after-pentecost-7-friday +.br +\s-2class-4 \(bu green\s+2 +.br +\s-2Ep. Rom 6:19-23\s+2 +.br +\s-2Ev. Matt 7:15-21\s+2 + +.IP "10" 4 +seven-holy-brothers-and-sts-rufina-secunda +.br +\s-2class-3 \(bu red\s+2 +.br +\s-2Ep. Prov 31:10-31\s+2 +.br +\s-2Ev. Matt 12:46-50\s+2 + +.IP "11" 4 +ef-time-after-pentecost-sunday-8 +.br +\s-2class-2 \(bu green\s+2 +.br +\s-2Ep. Rom 8:12-17\s+2 +.br +\s-2Ev. Luke 16:1-9\s+2 + +.IP "12" 4 +john-gualbert +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. Ecclus 45:1-6\s+2 +.br +\s-2Ev. Matt 5:43-48\s+2 +.br +\s-2Com. naboris-et-felicis\s+2 + +.IP "13" 4 +ef-time-after-pentecost-8-tuesday +.br +\s-2class-4 \(bu green\s+2 +.br +\s-2Ep. Rom 8:12-17\s+2 +.br +\s-2Ev. Luke 16:1-9\s+2 + +.IP "14" 4 +bonaventure +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. 2 Tim 4:1-8\s+2 +.br +\s-2Ev. Matt 5:13-19\s+2 + +.IP "15" 4 +henry-the-emperor +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. Sir 31:8-11\s+2 +.br +\s-2Ev. Luke 12:35-40\s+2 + +.IP "16" 4 +ef-time-after-pentecost-8-friday +.br +\s-2class-4 \(bu green\s+2 +.br +\s-2Ep. Rom 8:12-17\s+2 +.br +\s-2Ev. Luke 16:1-9\s+2 +.br +\s-2Com. our-lady-of-mt-carmel\s+2 + +.IP "17" 4 +Officium sanctae Mariae in sabbato +.br +\s-2class-4 \(bu white\s+2 +.br +\s-2Ep. Ecclus 24:14-16\s+2 +.br +\s-2Ev. Luke 11:27-28\s+2 +.br +\s-2Com. alexis\s+2 + +.IP "18" 4 +ef-time-after-pentecost-sunday-9 +.br +\s-2class-2 \(bu green\s+2 +.br +\s-2Ep. 1 Cor. 10:6-13\s+2 +.br +\s-2Ev. Luke 19:41-47\s+2 + +.IP "19" 4 +vincent-de-paul +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. 1 Cor. 4:9-14\s+2 +.br +\s-2Ev. Luke 10:1-9\s+2 + +.IP "20" 4 +jerome-emiliani +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. Isa 58:7-11\s+2 +.br +\s-2Ev. Matt 19:13-21\s+2 +.br +\s-2Com. margaret\s+2 + +.IP "21" 4 +laurence-of-brindisi +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. 2 Tim 4:1-8\s+2 +.br +\s-2Ev. Matt 5:13-19\s+2 +.br +\s-2Com. praxedis-virginis\s+2 + +.IP "22" 4 +mary-magdalene +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. Song 3:2-5; 8:6-7\s+2 +.br +\s-2Ev. Luke 7:36-50\s+2 + +.IP "23" 4 +apollinaris +.br +\s-2class-3 \(bu red\s+2 +.br +\s-2Ep. 1 Pet. 5:1-11\s+2 +.br +\s-2Ev. Luke 22:24-30\s+2 +.br +\s-2Com. liborii\s+2 + +.IP "24" 4 +Officium sanctae Mariae in sabbato +.br +\s-2class-4 \(bu white\s+2 +.br +\s-2Ep. Ecclus 24:14-16\s+2 +.br +\s-2Ev. Luke 11:27-28\s+2 +.br +\s-2Com. christina\s+2 + +.IP "25" 4 +ef-time-after-pentecost-sunday-10 +.br +\s-2class-2 \(bu green\s+2 +.br +\s-2Ep. 1 Cor. 12:2-11\s+2 +.br +\s-2Ev. Luke 18:9-14\s+2 +.br +\s-2Com. james-the-greater\s+2 + +.IP "26" 4 +anne-mother-of-the-blessed-virgin +.br +\s-2class-2 \(bu white\s+2 +.br +\s-2Ep. Prov 31:10-31\s+2 +.br +\s-2Ev. Matt 13:44-52.\s+2 + +.IP "27" 4 +ef-time-after-pentecost-10-tuesday +.br +\s-2class-4 \(bu green\s+2 +.br +\s-2Ep. 1 Cor. 12:2-11\s+2 +.br +\s-2Ev. Luke 18:9-14\s+2 +.br +\s-2Com. pantaleon\s+2 + +.IP "28" 4 +sts-nazarius-celsus-st-victor-i-st-innocent-i +.br +\s-2class-3 \(bu red\s+2 +.br +\s-2Ep. Wis 10:17-20\s+2 +.br +\s-2Ev. Luke 21:9-19\s+2 + +.IP "29" 4 +martha +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. 2 Cor 10:17-18; 11:1-2\s+2 +.br +\s-2Ev. Luke 10:38-42\s+2 +.br +\s-2Com. felicis-simplicii-faustini-et-beatricis\s+2 + +.IP "30" 4 +ef-time-after-pentecost-10-friday +.br +\s-2class-4 \(bu green\s+2 +.br +\s-2Ep. 1 Cor. 12:2-11\s+2 +.br +\s-2Ev. Luke 18:9-14\s+2 +.br +\s-2Com. sts-abdon-sennen\s+2 + +.IP "31" 4 +ignatius-loyola +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. 2 Tim. 2:8-10; 3:10-12.\s+2 +.br +\s-2Ev. Luke 10:1-9\s+2 + + +.SH +Augustus +.LP + +.IP "1" 4 +ef-time-after-pentecost-sunday-11 +.br +\s-2class-2 \(bu green\s+2 +.br +\s-2Ep. 1 Cor. 15:1-10\s+2 +.br +\s-2Ev. Mark 7:31-37\s+2 + +.IP "2" 4 +alphonsus-liguori +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. 2 Tim. 2:1-7\s+2 +.br +\s-2Ev. Luke 10:1-9\s+2 +.br +\s-2Com. stephen-i-pope-and-martyr\s+2 + +.IP "3" 4 +ef-time-after-pentecost-11-tuesday +.br +\s-2class-4 \(bu green\s+2 +.br +\s-2Ep. 1 Cor. 15:1-10\s+2 +.br +\s-2Ev. Mark 7:31-37\s+2 + +.IP "4" 4 +dominic +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. 2 Tim. 4:1-8\s+2 +.br +\s-2Ev. Luke 12:35-40\s+2 + +.IP "5" 4 +dedication-of-the-basilica-of-st-mary-major +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. Ecclus 24:14-16\s+2 +.br +\s-2Ev. Luke 11:27-28\s+2 + +.IP "6" 4 +transfiguration-of-our-lord +.br +\s-2class-2 \(bu white\s+2 +.br +\s-2Ep. 2 Pet. 1:16-19\s+2 +.br +\s-2Ev. Matt 17:1-9\s+2 +.br +\s-2Com. pope-sixtus-ii-felicissimus-and-agapitus-martyrs\s+2 + +.IP "7" 4 +cajetan +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. Sir 31:8-11\s+2 +.br +\s-2Ev. Matt 6:24-33\s+2 +.br +\s-2Com. donatus\s+2 + +.IP "8" 4 +ef-time-after-pentecost-sunday-12 +.br +\s-2class-2 \(bu green\s+2 +.br +\s-2Ep. 2 Cor. 3:4-9\s+2 +.br +\s-2Ev. Luke 10:23-37\s+2 + +.IP "9" 4 +vigil-of-st-lawrence +.br +\s-2class-3 \(bu violet\s+2 +.br +\s-2Ep. Ecclus 51:1-8, 12\s+2 +.br +\s-2Ev. Matt 16:24-27\s+2 +.br +\s-2Com. romanus\s+2 + +.IP "10" 4 +lawrence +.br +\s-2class-2 \(bu red\s+2 +.br +\s-2Ep. 2 Cor. 9:6-10\s+2 +.br +\s-2Ev. John 12:24-26\s+2 + +.IP "11" 4 +ef-time-after-pentecost-12-wednesday +.br +\s-2class-4 \(bu green\s+2 +.br +\s-2Ep. 2 Cor. 3:4-9\s+2 +.br +\s-2Ev. Luke 10:23-37\s+2 +.br +\s-2Com. sts-tiburtius-susanna\s+2 + +.IP "12" 4 +clare +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. 2 Cor 10:17-18; 11:1-2\s+2 +.br +\s-2Ev. Matt 25:1-13.\s+2 + +.IP "13" 4 +ef-time-after-pentecost-12-friday +.br +\s-2class-4 \(bu green\s+2 +.br +\s-2Ep. 2 Cor. 3:4-9\s+2 +.br +\s-2Ev. Luke 10:23-37\s+2 +.br +\s-2Com. sts-hippolytus-cassian\s+2 + +.IP "14" 4 +vigil-of-the-assumption +.br +\s-2class-2 \(bu violet\s+2 +.br +\s-2Ep. Sir 24:23-31\s+2 +.br +\s-2Ev. Luke 11:27-28\s+2 +.br +\s-2Com. eusebius-confessor\s+2 + +.IP "15" 4 +assumption-of-the-blessed-virgin-mary +.br +\s-2class-1 \(bu white\s+2 +.br +\s-2Ep. Judith 13:22-25; 15:10\s+2 +.br +\s-2Ev. Luke 1:41-50\s+2 +.br +\s-2Com. ef-time-after-pentecost-sunday-13\s+2 + +.IP "16" 4 +joachim-father-of-the-blessed-virgin +.br +\s-2class-2 \(bu white\s+2 +.br +\s-2Ep. Sir 31:8-11\s+2 +.br +\s-2Ev. Matt 1:1-16\s+2 + +.IP "17" 4 +hyacinth +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. Sir 31:8-11\s+2 +.br +\s-2Ev. Luke 12:35-40\s+2 + +.IP "18" 4 +ef-time-after-pentecost-13-wednesday +.br +\s-2class-4 \(bu green\s+2 +.br +\s-2Ep. Gal 3:16-22\s+2 +.br +\s-2Ev. Luke 17:11-19\s+2 +.br +\s-2Com. agapitus\s+2 + +.IP "19" 4 +john-eudes +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. Sir 31:8-11\s+2 +.br +\s-2Ev. Luke 12:35-40\s+2 + +.IP "20" 4 +bernard-of-clairvaux +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. Ecclus 39:6-14\s+2 +.br +\s-2Ev. Matt 5:13-19\s+2 + +.IP "21" 4 +jane-frances-de-chantal +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. Prov 31:10-31\s+2 +.br +\s-2Ev. Matt 13:44-52.\s+2 + +.IP "22" 4 +ef-time-after-pentecost-sunday-14 +.br +\s-2class-2 \(bu green\s+2 +.br +\s-2Ep. Gal 5:16-24\s+2 +.br +\s-2Ev. Matt 6:24-33\s+2 +.br +\s-2Com. immaculate-heart-of-mary\s+2 + +.IP "23" 4 +philip-benizi +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. 1 Cor. 4:9-14\s+2 +.br +\s-2Ev. Luke 12:32-34\s+2 + +.IP "24" 4 +bartholomew +.br +\s-2class-2 \(bu red\s+2 +.br +\s-2Ep. 1 Cor. 12:27-31\s+2 +.br +\s-2Ev. Luke 6:12-19\s+2 + +.IP "25" 4 +louis-ix +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. Wis 10:10-14\s+2 +.br +\s-2Ev. Luke 19:12-26\s+2 + +.IP "26" 4 +ef-time-after-pentecost-14-thursday +.br +\s-2class-4 \(bu green\s+2 +.br +\s-2Ep. Gal 5:16-24\s+2 +.br +\s-2Ev. Matt 6:24-33\s+2 +.br +\s-2Com. zephyrinus\s+2 + +.IP "27" 4 +joseph-calasance +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. Wis 10:10-14\s+2 +.br +\s-2Ev. Matt 18:1-5\s+2 + +.IP "28" 4 +augustine +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. 2 Tim 4:1-8\s+2 +.br +\s-2Ev. Matt 5:13-19\s+2 +.br +\s-2Com. hermes\s+2 + +.IP "29" 4 +ef-time-after-pentecost-sunday-15 +.br +\s-2class-2 \(bu green\s+2 +.br +\s-2Ep. Gal 5:25-26; 6:1-10\s+2 +.br +\s-2Ev. Luke 7:11-16\s+2 + +.IP "30" 4 +rose-of-lima +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. 2 Cor 10:17-18; 11:1-2\s+2 +.br +\s-2Ev. Matt 25:1-13.\s+2 +.br +\s-2Com. sts-felix-and-adauctus\s+2 + +.IP "31" 4 +raymond-nonnatus +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. Sir 31:8-11\s+2 +.br +\s-2Ev. Luke 12:35-40\s+2 + + +.SH +September +.LP + +.IP "1" 4 +ef-time-after-pentecost-15-wednesday +.br +\s-2class-4 \(bu green\s+2 +.br +\s-2Ep. Gal 5:25-26; 6:1-10\s+2 +.br +\s-2Ev. Luke 7:11-16\s+2 +.br +\s-2Com. giles\s+2 +.br +\s-2Com. twelve-holy-brothers-martyrs\s+2 + +.IP "2" 4 +stephen-of-hungary +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. Sir 31:8-11\s+2 +.br +\s-2Ev. Luke 19:12-26\s+2 + +.IP "3" 4 +pius-x +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. 1 Thess. 2:2-8\s+2 +.br +\s-2Ev. John 21:15-17\s+2 + +.IP "4" 4 +Officium sanctae Mariae in sabbato +.br +\s-2class-4 \(bu white\s+2 +.br +\s-2Ep. Ecclus 24:14-16\s+2 +.br +\s-2Ev. Luke 11:27-28\s+2 + +.IP "5" 4 +ef-time-after-pentecost-sunday-16 +.br +\s-2class-2 \(bu green\s+2 +.br +\s-2Ep. Eph 3:13-21\s+2 +.br +\s-2Ev. Luke 14:1-11\s+2 + +.IP "6" 4 +ef-time-after-pentecost-16-monday +.br +\s-2class-4 \(bu green\s+2 +.br +\s-2Ep. Eph 3:13-21\s+2 +.br +\s-2Ev. Luke 14:1-11\s+2 + +.IP "7" 4 +ef-time-after-pentecost-16-tuesday +.br +\s-2class-4 \(bu green\s+2 +.br +\s-2Ep. Eph 3:13-21\s+2 +.br +\s-2Ev. Luke 14:1-11\s+2 + +.IP "8" 4 +nativity-of-the-blessed-virgin-mary +.br +\s-2class-2 \(bu white\s+2 +.br +\s-2Ep. Prov 8:22-35\s+2 +.br +\s-2Ev. Matt 1:1-16\s+2 +.br +\s-2Com. hadriani\s+2 + +.IP "9" 4 +ef-time-after-pentecost-16-thursday +.br +\s-2class-4 \(bu green\s+2 +.br +\s-2Ep. Eph 3:13-21\s+2 +.br +\s-2Ev. Luke 14:1-11\s+2 +.br +\s-2Com. gorgonius\s+2 + +.IP "10" 4 +nicholas-of-tolentino +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. 1 Cor. 4:9-14\s+2 +.br +\s-2Ev. Luke 12:32-34\s+2 + +.IP "11" 4 +Officium sanctae Mariae in sabbato +.br +\s-2class-4 \(bu white\s+2 +.br +\s-2Ep. Ecclus 24:14-16\s+2 +.br +\s-2Ev. Luke 11:27-28\s+2 +.br +\s-2Com. sts-protus-hyacinth\s+2 + +.IP "12" 4 +ef-time-after-pentecost-sunday-17 +.br +\s-2class-2 \(bu green\s+2 +.br +\s-2Ep. Eph 4:1-6\s+2 +.br +\s-2Ev. Matt 22:34-46\s+2 + +.IP "13" 4 +ef-time-after-pentecost-17-monday +.br +\s-2class-4 \(bu green\s+2 +.br +\s-2Ep. Eph 4:1-6\s+2 +.br +\s-2Ev. Matt 22:34-46\s+2 + +.IP "14" 4 +exaltation-of-the-holy-cross +.br +\s-2class-2 \(bu red\s+2 +.br +\s-2Ep. Phil 2:5-11\s+2 +.br +\s-2Ev. John 12:31-36\s+2 + +.IP "15" 4 +seven-sorrows-of-the-blessed-virgin-mary +.br +\s-2class-2 \(bu white\s+2 +.br +\s-2Ep. Judith 13:22; 13:23-25\s+2 +.br +\s-2Ev. John 19:25-27\s+2 +.br +\s-2Com. nicomedes\s+2 + +.IP "16" 4 +sts-cornelius-cyprian +.br +\s-2class-3 \(bu red\s+2 +.br +\s-2Ep. Wis 3:1-8\s+2 +.br +\s-2Ev. Luke 21:9-19\s+2 +.br +\s-2Com. sts-euphemia-lucy-and-geminianus\s+2 + +.IP "17" 4 +ef-time-after-pentecost-17-friday +.br +\s-2class-4 \(bu green\s+2 +.br +\s-2Ep. Eph 4:1-6\s+2 +.br +\s-2Ev. Matt 22:34-46\s+2 +.br +\s-2Com. stigmata-of-st-francis\s+2 + +.IP "18" 4 +joseph-of-cupertino +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. 1 Cor 13:1-8\s+2 +.br +\s-2Ev. Matt 22:1-14\s+2 + +.IP "19" 4 +ef-time-after-pentecost-sunday-18 +.br +\s-2class-2 \(bu green\s+2 +.br +\s-2Ep. 1 Cor. 1:4-8\s+2 +.br +\s-2Ev. Matt 9:1-8\s+2 + +.IP "20" 4 +ef-time-after-pentecost-18-monday +.br +\s-2class-4 \(bu green\s+2 +.br +\s-2Ep. 1 Cor. 1:4-8\s+2 +.br +\s-2Ev. Matt 9:1-8\s+2 +.br +\s-2Com. sts-eustace-companions\s+2 + +.IP "21" 4 +matthew +.br +\s-2class-2 \(bu red\s+2 +.br +\s-2Ep. Ezek 1:10-14\s+2 +.br +\s-2Ev. Matt 9:9-13\s+2 + +.IP "22" 4 +ef-september-ember-wed +.br +\s-2class-2 \(bu violet\s+2 +.br +\s-2Ep. 2 Esd. 8:1-10\s+2 +.br +\s-2Ev. Mark 9:16-28\s+2 +.br +\s-2Com. thomas-of-villanova\s+2 + +.IP "23" 4 +linus +.br +\s-2class-3 \(bu red\s+2 +.br +\s-2Ep. 1 Pet 5:1-4; 5:10-11.\s+2 +.br +\s-2Ev. Matt 16:13-19\s+2 +.br +\s-2Com. thecla\s+2 + +.IP "24" 4 +ef-september-ember-fri +.br +\s-2class-2 \(bu violet\s+2 +.br +\s-2Ep. Osee 14:2-10\s+2 +.br +\s-2Ev. Luke 7:36-50\s+2 +.br +\s-2Com. our-lady-of-ransom\s+2 + +.IP "25" 4 +ef-september-ember-sat +.br +\s-2class-2 \(bu violet\s+2 +.br +\s-2Ep. Heb 9:2-12\s+2 +.br +\s-2Ev. Luke 13:6-17\s+2 + +.IP "26" 4 +ef-time-after-pentecost-sunday-19 +.br +\s-2class-2 \(bu green\s+2 +.br +\s-2Ep. Eph 4:23-28\s+2 +.br +\s-2Ev. Matt 22:1-14\s+2 + +.IP "27" 4 +sts-cosmas-damian +.br +\s-2class-3 \(bu red\s+2 +.br +\s-2Ep. Wis 5:16-20\s+2 +.br +\s-2Ev. Luke 6:17-23\s+2 + +.IP "28" 4 +wenceslaus +.br +\s-2class-3 \(bu red\s+2 +.br +\s-2Ep. Wis 10:10-14\s+2 +.br +\s-2Ev. Matt 10:34-42\s+2 + +.IP "29" 4 +dedication-of-st-michael-the-archangel +.br +\s-2class-1 \(bu white\s+2 +.br +\s-2Ep. Rev 1:1-5\s+2 +.br +\s-2Ev. Matt 18:1-10\s+2 + +.IP "30" 4 +jerome +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. 2 Tim 4:1-8\s+2 +.br +\s-2Ev. Matt 5:13-19\s+2 + + +.SH +October +.LP + +.IP "1" 4 +ef-time-after-pentecost-19-friday +.br +\s-2class-4 \(bu green\s+2 +.br +\s-2Ep. Eph 4:23-28\s+2 +.br +\s-2Ev. Matt 22:1-14\s+2 +.br +\s-2Com. remigius\s+2 + +.IP "2" 4 +holy-guardian-angels +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. Exod 23:20-23\s+2 +.br +\s-2Ev. Matt 18:1-10\s+2 + +.IP "3" 4 +ef-time-after-pentecost-sunday-20 +.br +\s-2class-2 \(bu green\s+2 +.br +\s-2Ep. Eph 5:15-21\s+2 +.br +\s-2Ev. John 4:46-53\s+2 + +.IP "4" 4 +francis-of-assisi +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. Gal 6:14-18\s+2 +.br +\s-2Ev. Matt 11:25-30\s+2 + +.IP "5" 4 +ef-time-after-pentecost-20-tuesday +.br +\s-2class-4 \(bu green\s+2 +.br +\s-2Ep. Eph 5:15-21\s+2 +.br +\s-2Ev. John 4:46-53\s+2 +.br +\s-2Com. placid-companions\s+2 + +.IP "6" 4 +bruno +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. Sir 31:8-11\s+2 +.br +\s-2Ev. Luke 12:35-40\s+2 + +.IP "7" 4 +our-lady-of-the-rosary +.br +\s-2class-2 \(bu white\s+2 +.br +\s-2Ep. Prov 8:22-24, 32-35.\s+2 +.br +\s-2Ev. Luke 1:26-38\s+2 +.br +\s-2Com. mark-i\s+2 + +.IP "8" 4 +bridget-of-sweden +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. 1 Tim. 5:3-10.\s+2 +.br +\s-2Ev. Matt 13:44-52.\s+2 +.br +\s-2Com. sergio-baccho-marcello-and-apulejo-martyrs\s+2 + +.IP "9" 4 +john-leonardi +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. 2 Cor 4:1-6; 4:15-18\s+2 +.br +\s-2Ev. Luke 10:1-9\s+2 +.br +\s-2Com. dionysius-and-companions\s+2 + +.IP "10" 4 +ef-time-after-pentecost-sunday-21 +.br +\s-2class-2 \(bu green\s+2 +.br +\s-2Ep. Eph 6:10-17\s+2 +.br +\s-2Ev. Matt 18:23-35\s+2 + +.IP "11" 4 +maternity-of-the-blessed-virgin-mary +.br +\s-2class-2 \(bu white\s+2 +.br +\s-2Ep. Sir 24:23-31\s+2 +.br +\s-2Ev. Luke 2:43-51\s+2 + +.IP "12" 4 +ef-time-after-pentecost-21-tuesday +.br +\s-2class-4 \(bu green\s+2 +.br +\s-2Ep. Eph 6:10-17\s+2 +.br +\s-2Ev. Matt 18:23-35\s+2 + +.IP "13" 4 +edward +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. Sir 31:8-11\s+2 +.br +\s-2Ev. Luke 12:35-40\s+2 + +.IP "14" 4 +callistus-i +.br +\s-2class-3 \(bu red\s+2 +.br +\s-2Ep. 1 Pet 5:1-4; 5:10-11.\s+2 +.br +\s-2Ev. Matt 16:13-19\s+2 + +.IP "15" 4 +teresa-of-avila +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. 2 Cor 10:17-18; 11:1-2\s+2 +.br +\s-2Ev. Matt 25:1-13.\s+2 + +.IP "16" 4 +hedwig +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. Prov 31:10-31\s+2 +.br +\s-2Ev. Matt 13:44-52.\s+2 + +.IP "17" 4 +ef-time-after-pentecost-sunday-22 +.br +\s-2class-2 \(bu green\s+2 +.br +\s-2Ep. Phil 1:6-11\s+2 +.br +\s-2Ev. Matt 22:15-21\s+2 + +.IP "18" 4 +luke-the-evangelist +.br +\s-2class-2 \(bu red\s+2 +.br +\s-2Ep. 2 Cor. 8:16-24\s+2 +.br +\s-2Ev. Luke 10:1-9\s+2 + +.IP "19" 4 +peter-of-alcantara +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. Phil 3:7-12\s+2 +.br +\s-2Ev. Luke 12:32-34\s+2 + +.IP "20" 4 +john-cantius +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. James 2:12-17\s+2 +.br +\s-2Ev. Luke 12:35-40\s+2 + +.IP "21" 4 +ef-time-after-pentecost-22-thursday +.br +\s-2class-4 \(bu green\s+2 +.br +\s-2Ep. Phil 1:6-11\s+2 +.br +\s-2Ev. Matt 22:15-21\s+2 +.br +\s-2Com. hilarion\s+2 +.br +\s-2Com. ursula-and-companions\s+2 + +.IP "22" 4 +ef-time-after-pentecost-22-friday +.br +\s-2class-4 \(bu green\s+2 +.br +\s-2Ep. Phil 1:6-11\s+2 +.br +\s-2Ev. Matt 22:15-21\s+2 + +.IP "23" 4 +anthony-mary-claret +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. Heb 7:23-27\s+2 +.br +\s-2Ev. Matt 24:42-47\s+2 + +.IP "24" 4 +ef-time-after-pentecost-sunday-23 +.br +\s-2class-2 \(bu green\s+2 +.br +\s-2Ep. Phil 3:17-21; 4:1-3\s+2 +.br +\s-2Ev. Matt 9:18-26\s+2 + +.IP "25" 4 +ef-time-after-pentecost-23-monday +.br +\s-2class-4 \(bu green\s+2 +.br +\s-2Ep. Phil 3:17-21; 4:1-3\s+2 +.br +\s-2Ev. Matt 9:18-26\s+2 +.br +\s-2Com. sts-chrysanthus-daria\s+2 + +.IP "26" 4 +ef-time-after-pentecost-23-tuesday +.br +\s-2class-4 \(bu green\s+2 +.br +\s-2Ep. Phil 3:17-21; 4:1-3\s+2 +.br +\s-2Ev. Matt 9:18-26\s+2 +.br +\s-2Com. evaristus\s+2 + +.IP "27" 4 +ef-time-after-pentecost-23-wednesday +.br +\s-2class-4 \(bu green\s+2 +.br +\s-2Ep. Phil 3:17-21; 4:1-3\s+2 +.br +\s-2Ev. Matt 9:18-26\s+2 + +.IP "28" 4 +sts-simon-jude +.br +\s-2class-2 \(bu red\s+2 +.br +\s-2Ep. Eph. 4:7-13.\s+2 +.br +\s-2Ev. John 15:17-25\s+2 + +.IP "29" 4 +ef-time-after-pentecost-23-friday +.br +\s-2class-4 \(bu green\s+2 +.br +\s-2Ep. Phil 3:17-21; 4:1-3\s+2 +.br +\s-2Ev. Matt 9:18-26\s+2 + +.IP "30" 4 +Officium sanctae Mariae in sabbato +.br +\s-2class-4 \(bu white\s+2 +.br +\s-2Ep. Ecclus 24:14-16\s+2 +.br +\s-2Ev. Luke 11:27-28\s+2 + +.IP "31" 4 +ef-christ-the-king +.br +\s-2class-1 \(bu white\s+2 +.br +\s-2Ep. Col 1:12-20.\s+2 +.br +\s-2Ev. John 18:33-37\s+2 + + +.SH +November +.LP + +.IP "1" 4 +all-saints +.br +\s-2class-1 \(bu white\s+2 +.br +\s-2Ep. Apoc 7:2-12\s+2 +.br +\s-2Ev. Matt 5:1-12\s+2 + +.IP "2" 4 +commemoration-of-all-souls +.br +\s-2class-1 \(bu black\s+2 +.br +\s-2Ep. 1 Cor. 15:51-57\s+2 +.br +\s-2Ev. John 5:25-29\s+2 + +.IP "3" 4 +ef-time-after-pentecost-24-wednesday +.br +\s-2class-4 \(bu green\s+2 +.br +\s-2Ep. Col 1:12-20.\s+2 +.br +\s-2Ev. John 18:33-37\s+2 + +.IP "4" 4 +charles-borromeo +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. Sir 44:16-27; 45:3-20\s+2 +.br +\s-2Ev. Matt 25:14-23\s+2 +.br +\s-2Com. sts-vitalis-and-agricola-martyrs\s+2 + +.IP "5" 4 +ef-time-after-pentecost-24-friday +.br +\s-2class-4 \(bu green\s+2 +.br +\s-2Ep. Col 1:12-20.\s+2 +.br +\s-2Ev. John 18:33-37\s+2 + +.IP "6" 4 +Officium sanctae Mariae in sabbato +.br +\s-2class-4 \(bu white\s+2 +.br +\s-2Ep. Ecclus 24:14-16\s+2 +.br +\s-2Ev. Luke 11:27-28\s+2 + +.IP "7" 4 +ef-time-after-epiphany-sunday-5 +.br +\s-2class-2 \(bu green\s+2 +.br +\s-2Ep. Col 3:12-17\s+2 +.br +\s-2Ev. Matt 13:24-30\s+2 + +.IP "8" 4 +ef-time-after-pentecost-25-monday +.br +\s-2class-4 \(bu green\s+2 +.br +\s-2Ep. Col 3:12-17\s+2 +.br +\s-2Ev. Matt 13:24-30\s+2 +.br +\s-2Com. four-holy-crowned-martyrs\s+2 + +.IP "9" 4 +dedication-of-the-archbasilica-of-our-holy-savior +.br +\s-2class-2 \(bu white\s+2 +.br +\s-2Ep. Rev 21:2-5\s+2 +.br +\s-2Ev. Luke 19:1-10\s+2 +.br +\s-2Com. theodore\s+2 + +.IP "10" 4 +andrew-avellino +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. Sir 31:8-11\s+2 +.br +\s-2Ev. Luke 12:35-40\s+2 +.br +\s-2Com. sts-tryphonis-respicii-et-nymphae\s+2 + +.IP "11" 4 +martin-of-tours +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. Sir 44:16-27; 45:3-20\s+2 +.br +\s-2Ev. Luke 11:33-36\s+2 +.br +\s-2Com. menna\s+2 + +.IP "12" 4 +martin-i +.br +\s-2class-3 \(bu red\s+2 +.br +\s-2Ep. 1 Pet 5:1-4; 5:10-11.\s+2 +.br +\s-2Ev. Matt 16:13-19\s+2 + +.IP "13" 4 +didacus +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. 1 Cor 4:9-14\s+2 +.br +\s-2Ev. Luke 12:32-34\s+2 + +.IP "14" 4 +ef-time-after-epiphany-sunday-6 +.br +\s-2class-2 \(bu green\s+2 +.br +\s-2Ep. 1 Thess 1:2-10\s+2 +.br +\s-2Ev. Matt 13:31-35\s+2 + +.IP "15" 4 +albert-the-great +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. 2 Tim 4:1-8\s+2 +.br +\s-2Ev. Matt 5:13-19\s+2 + +.IP "16" 4 +gertrude-the-great +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. 2 Cor 10:17-18; 11:1-2\s+2 +.br +\s-2Ev. Matt 25:1-13.\s+2 + +.IP "17" 4 +gregory-the-wonderworker +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. Sir 44:16-27; 45:3-20\s+2 +.br +\s-2Ev. Mark 11:22-24\s+2 + +.IP "18" 4 +dedication-of-the-basilicas-of-sts-peter-paul +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. Rev 21:2-5\s+2 +.br +\s-2Ev. Luke 19:1-10\s+2 + +.IP "19" 4 +elizabeth-of-hungary +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. Prov 31:10-31\s+2 +.br +\s-2Ev. Matt 13:44-52.\s+2 +.br +\s-2Com. pontian\s+2 + +.IP "20" 4 +felix-of-valois +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. 1 Cor. 4:9-14\s+2 +.br +\s-2Ev. Luke 12:32-34\s+2 + +.IP "21" 4 +ef-time-after-pentecost-sunday-24 +.br +\s-2class-2 \(bu green\s+2 +.br +\s-2Ep. Col 1:9-14\s+2 +.br +\s-2Ev. Matt 24:15-35\s+2 + +.IP "22" 4 +cecilia +.br +\s-2class-3 \(bu red\s+2 +.br +\s-2Ep. Sir 51:13-17.\s+2 +.br +\s-2Ev. Matt 25:1-13.\s+2 + +.IP "23" 4 +clement-i +.br +\s-2class-3 \(bu red\s+2 +.br +\s-2Ep. Phil 3:17-21; 4:1-3\s+2 +.br +\s-2Ev. Matt 16:13-19\s+2 +.br +\s-2Com. felicity\s+2 + +.IP "24" 4 +john-of-the-cross +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. 2 Tim 4:1-8\s+2 +.br +\s-2Ev. Matt 5:13-19\s+2 +.br +\s-2Com. chrysogonus\s+2 + +.IP "25" 4 +catherine-of-alexandria +.br +\s-2class-3 \(bu red\s+2 +.br +\s-2Ep. Sir 51:1-8; 51:12\s+2 +.br +\s-2Ev. Matt 25:1-13.\s+2 + +.IP "26" 4 +sylvester +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. Ecclus 45:1-6\s+2 +.br +\s-2Ev. Matt 19:27-29.\s+2 +.br +\s-2Com. peter-of-alexandria\s+2 + +.IP "27" 4 +Officium sanctae Mariae in sabbato +.br +\s-2class-4 \(bu white\s+2 +.br +\s-2Ep. Ecclus 24:14-16\s+2 +.br +\s-2Ev. Luke 11:27-28\s+2 + +.IP "28" 4 +ef-advent-sunday-1 +.br +\s-2class-1 \(bu violet\s+2 +.br +\s-2Ep. Rom 13:11-14\s+2 +.br +\s-2Ev. Luke 21:25-33\s+2 + +.IP "29" 4 +ef-advent-1-monday +.br +\s-2class-3 \(bu violet\s+2 +.br +\s-2Ep. Rom 13:11-14\s+2 +.br +\s-2Ev. Luke 21:25-33\s+2 +.br +\s-2Com. saturninus\s+2 + +.IP "30" 4 +andrew +.br +\s-2class-2 \(bu red\s+2 +.br +\s-2Ep. Rom 10:10-18\s+2 +.br +\s-2Ev. Matt 4:18-22\s+2 +.br +\s-2Com. ef-advent-1-tuesday\s+2 + + +.SH +December +.LP + +.IP "1" 4 +ef-advent-1-wednesday +.br +\s-2class-3 \(bu violet\s+2 +.br +\s-2Ep. Rom 13:11-14\s+2 +.br +\s-2Ev. Luke 21:25-33\s+2 + +.IP "2" 4 +vivian +.br +\s-2class-3 \(bu red\s+2 +.br +\s-2Ep. Sir 51:13-17.\s+2 +.br +\s-2Ev. Matt 13:44-52.\s+2 +.br +\s-2Com. ef-advent-1-thursday\s+2 + +.IP "3" 4 +francis-xavier +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. Rom 10:10-18\s+2 +.br +\s-2Ev. Mark 16:15-18\s+2 +.br +\s-2Com. ef-advent-1-friday\s+2 + +.IP "4" 4 +peter-chrysologus +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. 2 Tim 4:1-8\s+2 +.br +\s-2Ev. Matt 5:13-19\s+2 +.br +\s-2Com. ef-advent-1-saturday\s+2 +.br +\s-2Com. barbara\s+2 + +.IP "5" 4 +ef-advent-sunday-2 +.br +\s-2class-1 \(bu violet\s+2 +.br +\s-2Ep. Rom 15:4-13\s+2 +.br +\s-2Ev. Matt 11:2-10\s+2 + +.IP "6" 4 +nicholas +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. Heb 13:7-17\s+2 +.br +\s-2Ev. Matt 25:14-23\s+2 +.br +\s-2Com. ef-advent-2-monday\s+2 + +.IP "7" 4 +ambrose +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. 2 Tim 4:1-8\s+2 +.br +\s-2Ev. Matt 5:13-19\s+2 +.br +\s-2Com. ef-advent-2-tuesday\s+2 + +.IP "8" 4 +immaculate-conception-of-the-blessed-virgin-mary +.br +\s-2class-1 \(bu white\s+2 +.br +\s-2Ep. Prov 8:22-35\s+2 +.br +\s-2Ev. Luke 1:26-28\s+2 +.br +\s-2Com. ef-advent-2-wednesday\s+2 + +.IP "9" 4 +ef-advent-2-thursday +.br +\s-2class-3 \(bu violet\s+2 +.br +\s-2Ep. Rom 15:4-13\s+2 +.br +\s-2Ev. Matt 11:2-10\s+2 + +.IP "10" 4 +ef-advent-2-friday +.br +\s-2class-3 \(bu violet\s+2 +.br +\s-2Ep. Rom 15:4-13\s+2 +.br +\s-2Ev. Matt 11:2-10\s+2 +.br +\s-2Com. melchiades\s+2 + +.IP "11" 4 +damasus-i +.br +\s-2class-3 \(bu white\s+2 +.br +\s-2Ep. 1 Pet 5:1-4; 5:10-11.\s+2 +.br +\s-2Ev. Matt 16:13-19\s+2 +.br +\s-2Com. ef-advent-2-saturday\s+2 + +.IP "12" 4 +ef-advent-sunday-3 +.br +\s-2class-1 \(bu rose\s+2 +.br +\s-2Ep. Phil 4:4-7\s+2 +.br +\s-2Ev. John 1:19-28\s+2 + +.IP "13" 4 +lucy +.br +\s-2class-3 \(bu red\s+2 +.br +\s-2Ep. 2 Cor 10:17-18; 11:1-2\s+2 +.br +\s-2Ev. Matt 13:44-52.\s+2 +.br +\s-2Com. ef-advent-3-monday\s+2 + +.IP "14" 4 +ef-advent-3-tuesday +.br +\s-2class-3 \(bu violet\s+2 +.br +\s-2Ep. Phil 4:4-7\s+2 +.br +\s-2Ev. John 1:19-28\s+2 + +.IP "15" 4 +ef-advent-ember-wed +.br +\s-2class-2 \(bu violet\s+2 +.br +\s-2Ep. Isa 7:10-15\s+2 +.br +\s-2Ev. Luke 1:26-38\s+2 + +.IP "16" 4 +eusebius +.br +\s-2class-3 \(bu red\s+2 +.br +\s-2Ep. 2 Cor. 1:3-7\s+2 +.br +\s-2Ev. Matt 16:24-27.\s+2 +.br +\s-2Com. ef-advent-3-thursday\s+2 + +.IP "17" 4 +ef-advent-ember-fri +.br +\s-2class-2 \(bu violet\s+2 +.br +\s-2Ep. Isa 11:1-5\s+2 +.br +\s-2Ev. Luke 1:39-47\s+2 + +.IP "18" 4 +ef-advent-ember-sat +.br +\s-2class-2 \(bu violet\s+2 +.br +\s-2Ep. 2 Thess 2:1-8\s+2 +.br +\s-2Ev. Luke 3:1-6\s+2 + +.IP "19" 4 +ef-advent-sunday-4 +.br +\s-2class-1 \(bu violet\s+2 +.br +\s-2Ep. 1 Cor. 4:1-5\s+2 +.br +\s-2Ev. Luke 3:1-6\s+2 + +.IP "20" 4 +ef-advent-4-monday +.br +\s-2class-2 \(bu violet\s+2 +.br +\s-2Ep. 1 Cor. 4:1-5\s+2 +.br +\s-2Ev. Luke 3:1-6\s+2 + +.IP "21" 4 +thomas +.br +\s-2class-2 \(bu red\s+2 +.br +\s-2Ep. Eph 2:19-22\s+2 +.br +\s-2Ev. John 20:24-29\s+2 +.br +\s-2Com. ef-advent-4-tuesday\s+2 + +.IP "22" 4 +ef-advent-4-wednesday +.br +\s-2class-2 \(bu violet\s+2 +.br +\s-2Ep. 1 Cor. 4:1-5\s+2 +.br +\s-2Ev. Luke 3:1-6\s+2 + +.IP "23" 4 +ef-advent-4-thursday +.br +\s-2class-2 \(bu violet\s+2 +.br +\s-2Ep. 1 Cor. 4:1-5\s+2 +.br +\s-2Ev. Luke 3:1-6\s+2 + +.IP "24" 4 +ef-nativity-vigil +.br +\s-2class-1 \(bu violet\s+2 +.br +\s-2Ep. Rom 1:1-6\s+2 +.br +\s-2Ev. Matt 1:18-21\s+2 + +.IP "25" 4 +ef-nativity +.br +\s-2class-1 \(bu white\s+2 +.br +\s-2Ep. Heb 1:1-12\s+2 +.br +\s-2Ev. John 1:1-14\s+2 + +.IP "26" 4 +ef-christmas-sunday-0 +.br +\s-2class-2 \(bu white\s+2 +.br +\s-2Ep. Gal 4:1-7\s+2 +.br +\s-2Ev. Luke 2:33-40\s+2 +.br +\s-2Com. stephen\s+2 + +.IP "27" 4 +john-the-evangelist +.br +\s-2class-2 \(bu white\s+2 +.br +\s-2Ep. Ecclus 15:1-6\s+2 +.br +\s-2Ev. John 21:19-24\s+2 +.br +\s-2Com. ef-nativity-octave-day-3\s+2 + +.IP "28" 4 +holy-innocents +.br +\s-2class-2 \(bu red\s+2 +.br +\s-2Ep. Apoc 14:1-5\s+2 +.br +\s-2Ev. Matt 2:13-18\s+2 +.br +\s-2Com. ef-nativity-octave-day-4\s+2 + +.IP "29" 4 +ef-nativity-octave-day-5 +.br +\s-2class-2 \(bu white\s+2 +.br +\s-2Ep. Titus 3:4-7\s+2 +.br +\s-2Ev. Luke 2:15-20\s+2 +.br +\s-2Com. thomas-becket\s+2 + +.IP "30" 4 +ef-nativity-octave-day-6 +.br +\s-2class-2 \(bu white\s+2 +.br +\s-2Ep. Titus 3:4-7\s+2 +.br +\s-2Ev. Luke 2:15-20\s+2 + +.IP "31" 4 +ef-nativity-octave-day-7 +.br +\s-2class-2 \(bu white\s+2 +.br +\s-2Ep. Titus 3:4-7\s+2 +.br +\s-2Ev. Luke 2:15-20\s+2 +.br +\s-2Com. silvester\s+2 + + diff --git a/test/golden/ordo-2027.tex b/test/golden/ordo-2027.tex new file mode 100644 index 0000000..f5faa3d --- /dev/null +++ b/test/golden/ordo-2027.tex @@ -0,0 +1,2737 @@ +% colitur ordo booklet -- LaTeX. flavour: latex +% Build: colitur table --year 2027 --template ordo.tex > ordo.tex && pdflatex ordo.tex +% +% Day label falls back to the slug when the day carries no Latin name (most +% temporal days, and most sanctoral entries, which are Latin-less in the +% shipped data). The fallback is written as a name-section wrapping a plain +% var and its inverse, deliberately NOT as a single dotted-path lookup +% followed by its own inverse: a dotted lookup that misses climbs to the +% enclosing scope for the WHOLE path, and the month object also carries a +% same-named key one level up, so the naive form would render the month's +% own Latin name on every day lacking one, and never fall back at all. +\documentclass[10pt,twoside]{article} +\usepackage[a5paper,margin=15mm]{geometry} +\usepackage[T1]{fontenc} +\usepackage[utf8]{inputenc} +\usepackage{fancyhdr} +\pagestyle{fancy} +\fancyhead[C]{ORDO 2027 \textperiodcentered\ ef} +\setlength{\parindent}{0pt} +\begin{document} + +\section*{ Ianuarius } + +\textbf{ 1 } \quad ef-circumcision\\ +\small class-1 \textperiodcentered\ white\\ +\small Ep. Titus 2:11-15\quad\small Ev. Luke 2:21\\ + +\medskip + + +\textbf{ 2 } \quad Officium sanctae Mariae in sabbato\\ +\small class-4 \textperiodcentered\ white\\ +\small Ep. Titus 3:4-7\quad\small Ev. Luke 2:15-20\\ + +\medskip + + +\textbf{ 3 } \quad Sanctissimi Nominis Iesu\\ +\small class-2 \textperiodcentered\ white\\ +\small Ep. Acts 4:8-12\quad\small Ev. Luke 2:21\\ + +\medskip + + +\textbf{ 4 } \quad ef-christmas-1-monday\\ +\small class-4 \textperiodcentered\ white\\ +\small Ep. Titus 2:11-15\quad\small Ev. Luke 2:21\\ + +\medskip + + +\textbf{ 5 } \quad ef-christmas-1-tuesday\\ +\small class-4 \textperiodcentered\ white\\ +\small Ep. Titus 2:11-15\quad\small Ev. Luke 2:21\\ +\small Com. telesphorus-pope-and-martyr\\ + +\medskip + + +\textbf{ 6 } \quad ef-epiphany\\ +\small class-1 \textperiodcentered\ white\\ +\small Ep. Isa 60:1-6\quad\small Ev. Matt 2:1-12\\ + +\medskip + + +\textbf{ 7 } \quad ef-christmas-2-thursday\\ +\small class-4 \textperiodcentered\ white\\ +\small Ep. Isa 60:1-6\quad\small Ev. Matt 2:1-12\\ + +\medskip + + +\textbf{ 8 } \quad ef-christmas-2-friday\\ +\small class-4 \textperiodcentered\ white\\ +\small Ep. Isa 60:1-6\quad\small Ev. Matt 2:1-12\\ + +\medskip + + +\textbf{ 9 } \quad Officium sanctae Mariae in sabbato\\ +\small class-4 \textperiodcentered\ white\\ +\small Ep. Titus 3:4-7\quad\small Ev. Luke 2:15-20\\ + +\medskip + + +\textbf{ 10 } \quad Sanctae Familiae Iesu, Mariae, Ioseph\\ +\small class-2 \textperiodcentered\ white\\ +\small Ep. Col 3:12-17\quad\small Ev. Luke 2:42-52\\ + +\medskip + + +\textbf{ 11 } \quad ef-time-after-epiphany-1-monday\\ +\small class-4 \textperiodcentered\ white\\ +\small Ep. Rom 12:1-5\quad\small Ev. Luke 2:42-52\\ +\small Com. hyginus-pope-and-martyr\\ + +\medskip + + +\textbf{ 12 } \quad ef-time-after-epiphany-1-tuesday\\ +\small class-4 \textperiodcentered\ white\\ +\small Ep. Rom 12:1-5\quad\small Ev. Luke 2:42-52\\ + +\medskip + + +\textbf{ 13 } \quad commemoration-of-the-baptism-of-the-lord\\ +\small class-2 \textperiodcentered\ white\\ +\small Ep. Isa 60:1-6\quad\small Ev. John 1:29-34\\ + +\medskip + + +\textbf{ 14 } \quad hilary\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. 2 Tim 4:1-8\quad\small Ev. Matt 5:13-19\\ +\small Com. felicis\\ + +\medskip + + +\textbf{ 15 } \quad paul-the-first-hermit\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. Phil 3:7-12\quad\small Ev. Matt 11:25-30\\ +\small Com. maur-abbot\\ + +\medskip + + +\textbf{ 16 } \quad marcellus-i\\ +\small class-3 \textperiodcentered\ red\\ +\small Ep. 1 Pet 5:1-4; 5:10-11.\quad\small Ev. Matt 16:13-19\\ + +\medskip + + +\textbf{ 17 } \quad ef-time-after-epiphany-sunday-2\\ +\small class-2 \textperiodcentered\ green\\ +\small Ep. Rom 12:6-16\quad\small Ev. John 2:1-11\\ + +\medskip + + +\textbf{ 18 } \quad ef-time-after-epiphany-2-monday\\ +\small class-4 \textperiodcentered\ green\\ +\small Ep. Rom 12:6-16\quad\small Ev. John 2:1-11\\ +\small Com. prisca\\ + +\medskip + + +\textbf{ 19 } \quad ef-time-after-epiphany-2-tuesday\\ +\small class-4 \textperiodcentered\ green\\ +\small Ep. Rom 12:6-16\quad\small Ev. John 2:1-11\\ +\small Com. canute-martyr\\ +\small Com. sts-marius-martha-audifax-abachum\\ + +\medskip + + +\textbf{ 20 } \quad sts-fabian-sebastian\\ +\small class-3 \textperiodcentered\ red\\ +\small Ep. Heb 11:33-39\quad\small Ev. Luke 6:17-23\\ + +\medskip + + +\textbf{ 21 } \quad agnes\\ +\small class-3 \textperiodcentered\ red\\ +\small Ep. Sir 51:1-8; 51:12\quad\small Ev. Matt 25:1-13.\\ + +\medskip + + +\textbf{ 22 } \quad sts-vincent-anastasius\\ +\small class-3 \textperiodcentered\ red\\ +\small Ep. Wis 3:1-8\quad\small Ev. Luke 21:9-19\\ + +\medskip + + +\textbf{ 23 } \quad raymond-of-pe-afort\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. Sir 31:8-11\quad\small Ev. Luke 12:35-40\\ +\small Com. emerentiana\\ + +\medskip + + +\textbf{ 24 } \quad ef-septuagesima-sunday-1\\ +\small class-2 \textperiodcentered\ violet\\ +\small Ep. 1 Cor. 9:24-27; 10:1-5\quad\small Ev. Matt 20:1-16\\ + +\medskip + + +\textbf{ 25 } \quad conversion-of-st-paul\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. Acts 9:1-22\quad\small Ev. Matt 19:27-29.\\ +\small Com. peter\\ + +\medskip + + +\textbf{ 26 } \quad polycarp\\ +\small class-3 \textperiodcentered\ red\\ +\small Ep. 1 John 3:10-16\quad\small Ev. Matt 10:26-32.\\ + +\medskip + + +\textbf{ 27 } \quad john-chrysostom\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. 2 Tim 4:1-8\quad\small Ev. Matt 5:13-19\\ + +\medskip + + +\textbf{ 28 } \quad peter-nolasco\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. 1 Cor. 4:9-14\quad\small Ev. Luke 12:32-34\\ +\small Com. agnes-secundo\\ + +\medskip + + +\textbf{ 29 } \quad francis-de-sales\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. 2 Tim 4:1-8\quad\small Ev. Matt 5:13-19\\ + +\medskip + + +\textbf{ 30 } \quad martina\\ +\small class-3 \textperiodcentered\ red\\ +\small Ep. Sir 51:1-8; 51:12\quad\small Ev. Matt 25:1-13.\\ + +\medskip + + +\textbf{ 31 } \quad ef-septuagesima-sunday-2\\ +\small class-2 \textperiodcentered\ violet\\ +\small Ep. 2 Cor. 11:19-33; 12:1-9\quad\small Ev. Luke 8:4-15\\ + +\medskip + + + +\section*{ Februarius } + +\textbf{ 1 } \quad ignatius-of-antioch\\ +\small class-3 \textperiodcentered\ red\\ +\small Ep. Rom 8:35-39\quad\small Ev. John 12:24-26\\ + +\medskip + + +\textbf{ 2 } \quad purification-of-the-blessed-virgin-mary\\ +\small class-2 \textperiodcentered\ white\\ +\small Ep. Mal 3:1-4\quad\small Ev. Luke 2:22-32\\ + +\medskip + + +\textbf{ 3 } \quad ef-septuagesima-2-wednesday\\ +\small class-4 \textperiodcentered\ violet\\ +\small Ep. 2 Cor. 11:19-33; 12:1-9\quad\small Ev. Luke 8:4-15\\ +\small Com. blaise\\ + +\medskip + + +\textbf{ 4 } \quad andrew-corsini\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. Sir 44:16-27; 45:3-20\quad\small Ev. Matt 25:14-23\\ + +\medskip + + +\textbf{ 5 } \quad agatha\\ +\small class-3 \textperiodcentered\ red\\ +\small Ep. 1 Cor. 1:26-31\quad\small Ev. Matt 19:3-12.\\ + +\medskip + + +\textbf{ 6 } \quad titus\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. Sir 44:16-27; 45:3-20\quad\small Ev. Luke 10:1-9\\ +\small Com. dorothy\\ + +\medskip + + +\textbf{ 7 } \quad ef-septuagesima-sunday-3\\ +\small class-2 \textperiodcentered\ violet\\ +\small Ep. 1 Cor. 13:1-13\quad\small Ev. Luke 18:31-43\\ + +\medskip + + +\textbf{ 8 } \quad john-of-matha\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. Sir 31:8-11\quad\small Ev. Luke 12:35-40\\ + +\medskip + + +\textbf{ 9 } \quad cyril-of-alexandria\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. 2 Tim 4:1-8\quad\small Ev. Matt 5:13-19\\ +\small Com. appollonia\\ + +\medskip + + +\textbf{ 10 } \quad ef-ash-wednesday\\ +\small class-1 \textperiodcentered\ violet\\ +\small Ep. Joel 2:12-19\quad\small Ev. Matt 6:16-21\\ + +\medskip + + +\textbf{ 11 } \quad ef-lent-after-ashes-thursday\\ +\small class-3 \textperiodcentered\ violet\\ +\small Ep. Isa 38:1-6\quad\small Ev. Matt 8:5-13\\ +\small Com. our-lady-of-lourdes\\ + +\medskip + + +\textbf{ 12 } \quad ef-lent-after-ashes-friday\\ +\small class-3 \textperiodcentered\ violet\\ +\small Ep. Isa 58:1-9\quad\small Ev. Matt 5:43-48; 6:1-4\\ +\small Com. seven-holy-servite-founders\\ + +\medskip + + +\textbf{ 13 } \quad ef-lent-after-ashes-saturday\\ +\small class-3 \textperiodcentered\ violet\\ +\small Ep. Isa 58:9-14\quad\small Ev. Mark 6:47-56\\ + +\medskip + + +\textbf{ 14 } \quad ef-lent-sunday-1\\ +\small class-1 \textperiodcentered\ violet\\ +\small Ep. 2 Cor. 6:1-10\quad\small Ev. Matt 4:1-11\\ + +\medskip + + +\textbf{ 15 } \quad ef-lent-1-monday\\ +\small class-3 \textperiodcentered\ violet\\ +\small Ep. Ezech 34:11-16\quad\small Ev. Matt 25:31-46\\ +\small Com. sts-faustinus-jovita\\ + +\medskip + + +\textbf{ 16 } \quad ef-lent-1-tuesday\\ +\small class-3 \textperiodcentered\ violet\\ +\small Ep. Isa 55:6-11\quad\small Ev. Matt 21:10-17\\ + +\medskip + + +\textbf{ 17 } \quad ef-lent-ember-wed\\ +\small class-2 \textperiodcentered\ violet\\ +\small Ep. 3 Kgs. 19:3-8\quad\small Ev. Matt 12:38-50\\ + +\medskip + + +\textbf{ 18 } \quad ef-lent-1-thursday\\ +\small class-3 \textperiodcentered\ violet\\ +\small Ep. Ezech 18:1-9\quad\small Ev. Matt 15:21-28\\ +\small Com. simeon\\ + +\medskip + + +\textbf{ 19 } \quad ef-lent-ember-fri\\ +\small class-2 \textperiodcentered\ violet\\ +\small Ep. Ezech 18:20-28\quad\small Ev. John 5:1-15\\ + +\medskip + + +\textbf{ 20 } \quad ef-lent-ember-sat\\ +\small class-2 \textperiodcentered\ violet\\ +\small Ep. 1 Thess. 5:14-23\quad\small Ev. Matt 17:1-9\\ + +\medskip + + +\textbf{ 21 } \quad ef-lent-sunday-2\\ +\small class-1 \textperiodcentered\ violet\\ +\small Ep. 1 Thess. 4:1-7\quad\small Ev. Matt 17:1-9\\ + +\medskip + + +\textbf{ 22 } \quad chair-of-st-peter\\ +\small class-2 \textperiodcentered\ white\\ +\small Ep. 1 Pet 1:1-7\quad\small Ev. Matt 16:13-19\\ +\small Com. ef-lent-2-monday\\ +\small Com. paul\\ + +\medskip + + +\textbf{ 23 } \quad ef-lent-2-tuesday\\ +\small class-3 \textperiodcentered\ violet\\ +\small Ep. 3 Kings 17:8-16\quad\small Ev. Matt 23:1-12\\ +\small Com. peter-damien\\ + +\medskip + + +\textbf{ 24 } \quad matthias\\ +\small class-2 \textperiodcentered\ red\\ +\small Ep. Acts 1:15-26\quad\small Ev. Matt 11:25-30\\ +\small Com. ef-lent-2-wednesday\\ + +\medskip + + +\textbf{ 25 } \quad ef-lent-2-thursday\\ +\small class-3 \textperiodcentered\ violet\\ +\small Ep. Jer 17:5-10\quad\small Ev. Luke 16:19-31\\ + +\medskip + + +\textbf{ 26 } \quad ef-lent-2-friday\\ +\small class-3 \textperiodcentered\ violet\\ +\small Ep. Gen 37:6-22\quad\small Ev. Matt 21:33-46\\ + +\medskip + + +\textbf{ 27 } \quad ef-lent-2-saturday\\ +\small class-3 \textperiodcentered\ violet\\ +\small Ep. Gen 27:6-40\quad\small Ev. Luke 15:11-32\\ +\small Com. gabriel-of-our-lady-of-sorrows\\ + +\medskip + + +\textbf{ 28 } \quad ef-lent-sunday-3\\ +\small class-1 \textperiodcentered\ violet\\ +\small Ep. Eph 5:1-9\quad\small Ev. Luke 11:14-28\\ + +\medskip + + + +\section*{ Martius } + +\textbf{ 1 } \quad ef-lent-3-monday\\ +\small class-3 \textperiodcentered\ violet\\ +\small Ep. 4 Kings 5:1-15\quad\small Ev. Luke 4:23-30\\ + +\medskip + + +\textbf{ 2 } \quad ef-lent-3-tuesday\\ +\small class-3 \textperiodcentered\ violet\\ +\small Ep. 4 Kings 4:1-7\quad\small Ev. Matt 18:15-22\\ + +\medskip + + +\textbf{ 3 } \quad ef-lent-3-wednesday\\ +\small class-3 \textperiodcentered\ violet\\ +\small Ep. Ex 20:12-24\quad\small Ev. Matt 15:1-20\\ + +\medskip + + +\textbf{ 4 } \quad ef-lent-3-thursday\\ +\small class-3 \textperiodcentered\ violet\\ +\small Ep. Jer 7:1-7\quad\small Ev. Luke 4:38-44.\\ +\small Com. casimir\\ +\small Com. lucius\\ + +\medskip + + +\textbf{ 5 } \quad ef-lent-3-friday\\ +\small class-3 \textperiodcentered\ violet\\ +\small Ep. Num 20:1, 3; 6-13.\quad\small Ev. John 4:5-42\\ + +\medskip + + +\textbf{ 6 } \quad ef-lent-3-saturday\\ +\small class-3 \textperiodcentered\ violet\\ +\small Ep. Dan 13:1-9, 15-17, 19-30, 33-62.\quad\small Ev. John 8:1-11\\ +\small Com. sts-felicitas-perpetua\\ + +\medskip + + +\textbf{ 7 } \quad ef-lent-sunday-4\\ +\small class-1 \textperiodcentered\ rose\\ +\small Ep. Gal 4:22-31\quad\small Ev. John 6:1-15\\ + +\medskip + + +\textbf{ 8 } \quad ef-lent-4-monday\\ +\small class-3 \textperiodcentered\ violet\\ +\small Ep. 3 Kings 3:16-28\quad\small Ev. John 2:13-25\\ +\small Com. john-of-god\\ + +\medskip + + +\textbf{ 9 } \quad ef-lent-4-tuesday\\ +\small class-3 \textperiodcentered\ violet\\ +\small Ep. Ex 32:7-14\quad\small Ev. John 7:14-31\\ +\small Com. frances-rome\\ + +\medskip + + +\textbf{ 10 } \quad ef-lent-4-wednesday\\ +\small class-3 \textperiodcentered\ violet\\ +\small Ep. Isa. 1:16-19\quad\small Ev. John 9:1-38\\ +\small Com. forty-holy-martyrs-of-sebaste\\ + +\medskip + + +\textbf{ 11 } \quad ef-lent-4-thursday\\ +\small class-3 \textperiodcentered\ violet\\ +\small Ep. 4 Kings 4:25-38\quad\small Ev. Luke 7:11-16\\ + +\medskip + + +\textbf{ 12 } \quad ef-lent-4-friday\\ +\small class-3 \textperiodcentered\ violet\\ +\small Ep. 3 Kings 17:17-24\quad\small Ev. John 11:1-45\\ +\small Com. gregory-the-great\\ + +\medskip + + +\textbf{ 13 } \quad ef-lent-4-saturday\\ +\small class-3 \textperiodcentered\ violet\\ +\small Ep. Isa 49:8-15\quad\small Ev. John 8:12-20\\ + +\medskip + + +\textbf{ 14 } \quad ef-passion-sunday\\ +\small class-1 \textperiodcentered\ violet\\ +\small Ep. Heb 9:11-15.\quad\small Ev. John 8:46-59.\\ + +\medskip + + +\textbf{ 15 } \quad ef-passiontide-1-monday\\ +\small class-3 \textperiodcentered\ violet\\ +\small Ep. Jonas 3:1-10\quad\small Ev. John 7:32-39\\ + +\medskip + + +\textbf{ 16 } \quad ef-passiontide-1-tuesday\\ +\small class-3 \textperiodcentered\ violet\\ +\small Ep. Dan 14:27, 28-42\quad\small Ev. John 7:1-13\\ + +\medskip + + +\textbf{ 17 } \quad ef-passiontide-1-wednesday\\ +\small class-3 \textperiodcentered\ violet\\ +\small Ep. Lev 19:1-2, 11-19, 25\quad\small Ev. John 10:22-38\\ +\small Com. patrick\\ + +\medskip + + +\textbf{ 18 } \quad ef-passiontide-1-thursday\\ +\small class-3 \textperiodcentered\ violet\\ +\small Ep. Dan 3:25, 34-45.\quad\small Ev. Luke 7:36-50\\ +\small Com. cyril-of-jerusalem\\ + +\medskip + + +\textbf{ 19 } \quad joseph-spouse-of-the-bl-virgin-mary\\ +\small class-1 \textperiodcentered\ white\\ +\small Ep. Ecclus 45:1-6\quad\small Ev. Matt 1:18-21\\ +\small Com. ef-passiontide-1-friday\\ + +\medskip + + +\textbf{ 20 } \quad ef-passiontide-1-saturday\\ +\small class-3 \textperiodcentered\ violet\\ +\small Ep. Jer 18:18-23\quad\small Ev. John 12:10-36\\ + +\medskip + + +\textbf{ 21 } \quad ef-palm-sunday\\ +\small class-1 \textperiodcentered\ violet\\ +\small Ep. Phil 2:5-11\quad\small Ev. Matt. 26:36-75; 27:1-60.\\ + +\medskip + + +\textbf{ 22 } \quad ef-passiontide-2-monday\\ +\small class-1 \textperiodcentered\ violet\\ +\small Ep. Isa 50:5-10\quad\small Ev. John 12:1-9\\ + +\medskip + + +\textbf{ 23 } \quad ef-passiontide-2-tuesday\\ +\small class-1 \textperiodcentered\ violet\\ +\small Ep. Jer 11:18-20\quad\small Ev. Mark 14:32-72; 15, 1-46\\ + +\medskip + + +\textbf{ 24 } \quad ef-passiontide-2-wednesday\\ +\small class-1 \textperiodcentered\ violet\\ +\small Ep. Isa 53:1-12\quad\small Ev. Luke 22:39-71; 23:1-53\\ + +\medskip + + +\textbf{ 25 } \quad Feria V in Cena Domini\\ +\small class-1 \textperiodcentered\ white\\ +\small Ep. 1 Cor 11:20-32\quad\small Ev. John 13:1-15\\ + +\medskip + + +\textbf{ 26 } \quad Feria VI in Passione et Morte Domini\\ +\small class-1 \textperiodcentered\ black\\ +\small Ep. Ex 12:1-11\quad\small Ev. John 18:1-40; 19:1-42\\ + +\medskip + + +\textbf{ 27 } \quad Sabbato sancto\\ +\small class-1 \textperiodcentered\ violet\\ +\small Ep. Col 3:1-4\quad\small Ev. Matt 28:1-7\\ + +\medskip + + +\textbf{ 28 } \quad ef-easter-sunday\\ +\small class-1 \textperiodcentered\ white\\ +\small Ep. 1 Cor 5:7-8\quad\small Ev. Mark 16:1-7\\ + +\medskip + + +\textbf{ 29 } \quad ef-easter-1-monday\\ +\small class-1 \textperiodcentered\ white\\ +\small Ep. Acts 10:37-43.\quad\small Ev. Luke 24:13-35\\ + +\medskip + + +\textbf{ 30 } \quad ef-easter-1-tuesday\\ +\small class-1 \textperiodcentered\ white\\ +\small Ep. Acts 13:16; 13:26-33\quad\small Ev. Luke 24:36-47\\ + +\medskip + + +\textbf{ 31 } \quad ef-easter-1-wednesday\\ +\small class-1 \textperiodcentered\ white\\ +\small Ep. Acts 3:13-15; 3:17-19\quad\small Ev. John 21:1-14\\ + +\medskip + + + +\section*{ Aprilis } + +\textbf{ 1 } \quad ef-easter-1-thursday\\ +\small class-1 \textperiodcentered\ white\\ +\small Ep. Acts 8:26-40\quad\small Ev. John 20:11-18\\ + +\medskip + + +\textbf{ 2 } \quad ef-easter-1-friday\\ +\small class-1 \textperiodcentered\ white\\ +\small Ep. 1 Pet 3:18-22\quad\small Ev. Matt 28:16-20\\ + +\medskip + + +\textbf{ 3 } \quad ef-easter-1-saturday\\ +\small class-1 \textperiodcentered\ white\\ +\small Ep. 1 Pet 2:1-10\quad\small Ev. John 20:1-9\\ + +\medskip + + +\textbf{ 4 } \quad ef-low-sunday\\ +\small class-1 \textperiodcentered\ white\\ +\small Ep. 1 John 5:4-10\quad\small Ev. John 20:19-31\\ + +\medskip + + +\textbf{ 5 } \quad annunciation-of-the-blessed-virgin-mary\\ +\small class-1 \textperiodcentered\ white\\ +\small Ep. Isa 7:10-15\quad\small Ev. Luke 1:26-38\\ + +\medskip + + +\textbf{ 6 } \quad ef-easter-2-tuesday\\ +\small class-4 \textperiodcentered\ white\\ +\small Ep. 1 John 5:4-10\quad\small Ev. John 20:19-31\\ + +\medskip + + +\textbf{ 7 } \quad ef-easter-2-wednesday\\ +\small class-4 \textperiodcentered\ white\\ +\small Ep. 1 John 5:4-10\quad\small Ev. John 20:19-31\\ + +\medskip + + +\textbf{ 8 } \quad ef-easter-2-thursday\\ +\small class-4 \textperiodcentered\ white\\ +\small Ep. 1 John 5:4-10\quad\small Ev. John 20:19-31\\ + +\medskip + + +\textbf{ 9 } \quad ef-easter-2-friday\\ +\small class-4 \textperiodcentered\ white\\ +\small Ep. 1 John 5:4-10\quad\small Ev. John 20:19-31\\ + +\medskip + + +\textbf{ 10 } \quad Officium sanctae Mariae in sabbato\\ +\small class-4 \textperiodcentered\ white\\ +\small Ep. Ecclus 24:14-16\quad\small Ev. John 19:25-27\\ + +\medskip + + +\textbf{ 11 } \quad ef-easter-sunday-3\\ +\small class-2 \textperiodcentered\ white\\ +\small Ep. 1 Pet 2:21-25\quad\small Ev. John 10:11-16\\ + +\medskip + + +\textbf{ 12 } \quad ef-easter-3-monday\\ +\small class-4 \textperiodcentered\ white\\ +\small Ep. 1 Pet 2:21-25\quad\small Ev. John 10:11-16\\ + +\medskip + + +\textbf{ 13 } \quad hermenegild\\ +\small class-3 \textperiodcentered\ red\\ +\small Ep. Wis 10:10-14\quad\small Ev. Luke 14:26-33.\\ + +\medskip + + +\textbf{ 14 } \quad justin\\ +\small class-3 \textperiodcentered\ red\\ +\small Ep. 1 Cor 1:18-25; 1:30;\quad\small Ev. Luke 12:2-8\\ +\small Com. sts-tiburtius-valerian-et-maximus-martyrs\\ + +\medskip + + +\textbf{ 15 } \quad ef-easter-3-thursday\\ +\small class-4 \textperiodcentered\ white\\ +\small Ep. 1 Pet 2:21-25\quad\small Ev. John 10:11-16\\ + +\medskip + + +\textbf{ 16 } \quad ef-easter-3-friday\\ +\small class-4 \textperiodcentered\ white\\ +\small Ep. 1 Pet 2:21-25\quad\small Ev. John 10:11-16\\ + +\medskip + + +\textbf{ 17 } \quad Officium sanctae Mariae in sabbato\\ +\small class-4 \textperiodcentered\ white\\ +\small Ep. Ecclus 24:14-16\quad\small Ev. John 19:25-27\\ +\small Com. anicetus\\ + +\medskip + + +\textbf{ 18 } \quad ef-easter-sunday-4\\ +\small class-2 \textperiodcentered\ white\\ +\small Ep. 1 Pet 2:11-19\quad\small Ev. John 16:16-22\\ + +\medskip + + +\textbf{ 19 } \quad ef-easter-4-monday\\ +\small class-4 \textperiodcentered\ white\\ +\small Ep. 1 Pet 2:11-19\quad\small Ev. John 16:16-22\\ + +\medskip + + +\textbf{ 20 } \quad ef-easter-4-tuesday\\ +\small class-4 \textperiodcentered\ white\\ +\small Ep. 1 Pet 2:11-19\quad\small Ev. John 16:16-22\\ + +\medskip + + +\textbf{ 21 } \quad anselm\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. 2 Tim 4:1-8\quad\small Ev. Matt 5:13-19\\ + +\medskip + + +\textbf{ 22 } \quad sts-soter-caius\\ +\small class-3 \textperiodcentered\ red\\ +\small Ep. 1 Pet 5:1-4; 5:10-11.\quad\small Ev. Matt 16:13-19\\ + +\medskip + + +\textbf{ 23 } \quad ef-easter-4-friday\\ +\small class-4 \textperiodcentered\ white\\ +\small Ep. 1 Pet 2:11-19\quad\small Ev. John 16:16-22\\ +\small Com. george\\ + +\medskip + + +\textbf{ 24 } \quad fidelis-of-sigmaringen\\ +\small class-3 \textperiodcentered\ red\\ +\small Ep. Wis 5:1-5\quad\small Ev. John 15:1-7\\ + +\medskip + + +\textbf{ 25 } \quad ef-easter-sunday-5\\ +\small class-2 \textperiodcentered\ white\\ +\small Ep. Jas 1:17-21\quad\small Ev. John 16:5-14\\ +\small Com. major-litanies\\ + +\medskip + + +\textbf{ 26 } \quad sts-cletus-marcellinus\\ +\small class-3 \textperiodcentered\ red\\ +\small Ep. 1 Pet 5:1-4; 5:10-11.\quad\small Ev. Matt 16:13-19\\ + +\medskip + + +\textbf{ 27 } \quad peter-canisius\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. 2 Tim 4:1-8\quad\small Ev. Matt 5:13-19\\ + +\medskip + + +\textbf{ 28 } \quad paul-of-the-cross\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. 1 Cor 1:17-25.\quad\small Ev. Luke 10:1-9\\ + +\medskip + + +\textbf{ 29 } \quad peter-of-verona\\ +\small class-3 \textperiodcentered\ red\\ +\small Ep. 2 Tim. 2:8-10; 3:10-12.\quad\small Ev. Matt 10:34-42\\ + +\medskip + + +\textbf{ 30 } \quad catherine-of-siena\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. 2 Cor 10:17-18; 11:1-2\quad\small Ev. Matt 25:1-13.\\ + +\medskip + + + +\section*{ Maius } + +\textbf{ 1 } \quad joseph-the-workman\\ +\small class-1 \textperiodcentered\ white\\ +\small Ep. Col. 3:14-15, 17, 23-24\quad\small Ev. Matt 13:54-58\\ + +\medskip + + +\textbf{ 2 } \quad ef-easter-sunday-6\\ +\small class-2 \textperiodcentered\ white\\ +\small Ep. Jas 1:22-27\quad\small Ev. John 16:23-30\\ + +\medskip + + +\textbf{ 3 } \quad ef-rogation-monday\\ +\small class-4 \textperiodcentered\ violet\\ +\small Ep. Jas 1:22-27\quad\small Ev. John 16:23-30\\ +\small Com. sts-alexander-companions\\ + +\medskip + + +\textbf{ 4 } \quad monica\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. 1 Tim. 5:3-10.\quad\small Ev. Luke 7:11-16\\ + +\medskip + + +\textbf{ 5 } \quad ef-ascension-vigil\\ +\small class-2 \textperiodcentered\ white\\ +\small Ep. Eph. 4:7-13.\quad\small Ev. John 17:1-11.\\ +\small Com. pius-v\\ + +\medskip + + +\textbf{ 6 } \quad ef-ascension\\ +\small class-1 \textperiodcentered\ white\\ +\small Ep. Acts 1:1-11\quad\small Ev. Mark 16:14-20\\ + +\medskip + + +\textbf{ 7 } \quad stanislaus\\ +\small class-3 \textperiodcentered\ red\\ +\small Ep. Wis 5:1-5\quad\small Ev. John 15:1-7\\ + +\medskip + + +\textbf{ 8 } \quad Officium sanctae Mariae in sabbato\\ +\small class-4 \textperiodcentered\ white\\ +\small Ep. Ecclus 24:14-16\quad\small Ev. John 19:25-27\\ + +\medskip + + +\textbf{ 9 } \quad ef-easter-sunday-7\\ +\small class-2 \textperiodcentered\ white\\ +\small Ep. 1 Pet 4:7-11.\quad\small Ev. John 15:26-27; 16:1-4.\\ + +\medskip + + +\textbf{ 10 } \quad antoninus\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. Sir 44:16-27; 45:3-20\quad\small Ev. Matt 25:14-23\\ +\small Com. gordiano-and-epimacho\\ + +\medskip + + +\textbf{ 11 } \quad sts-philip-james\\ +\small class-2 \textperiodcentered\ red\\ +\small Ep. Wis. 5:1-5\quad\small Ev. John 14:1-13\\ + +\medskip + + +\textbf{ 12 } \quad sts-nereus-achilleus-domitilla-pancras\\ +\small class-3 \textperiodcentered\ red\\ +\small Ep. Wis. 5:1-5\quad\small Ev. John 4:46-53\\ + +\medskip + + +\textbf{ 13 } \quad robert-bellarmine\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. Wis 7:7-14.\quad\small Ev. Matt 5:13-19\\ + +\medskip + + +\textbf{ 14 } \quad ef-easter-7-friday\\ +\small class-4 \textperiodcentered\ white\\ +\small Ep. 1 Pet 4:7-11.\quad\small Ev. John 15:26-27; 16:1-4.\\ +\small Com. boniface-martyr\\ + +\medskip + + +\textbf{ 15 } \quad ef-pentecost-vigil\\ +\small class-1 \textperiodcentered\ red\\ +\small Ep. Acts 19:1-8.\quad\small Ev. John 14:15-21.\\ + +\medskip + + +\textbf{ 16 } \quad ef-pentecost\\ +\small class-1 \textperiodcentered\ red\\ +\small Ep. Acts 2:1-11.\quad\small Ev. John 14:23-31.\\ + +\medskip + + +\textbf{ 17 } \quad ef-easter-8-monday\\ +\small class-1 \textperiodcentered\ red\\ +\small Ep. Acts 10:34, 42-48\quad\small Ev. John 3:16-21\\ + +\medskip + + +\textbf{ 18 } \quad ef-easter-8-tuesday\\ +\small class-1 \textperiodcentered\ red\\ +\small Ep. Acts 8:14-17.\quad\small Ev. John 10:1-10.\\ + +\medskip + + +\textbf{ 19 } \quad ef-pentecost-ember-wed\\ +\small class-1 \textperiodcentered\ red\\ +\small Ep. Acts 5:12-16\quad\small Ev. John 6:44-52.\\ + +\medskip + + +\textbf{ 20 } \quad ef-easter-8-thursday\\ +\small class-1 \textperiodcentered\ red\\ +\small Ep. Acts 8:5-8\quad\small Ev. Luke 9:1-6\\ + +\medskip + + +\textbf{ 21 } \quad ef-pentecost-ember-fri\\ +\small class-1 \textperiodcentered\ red\\ +\small Ep. Joel 2:23-24; 26-27\quad\small Ev. Luke 5:17-26\\ + +\medskip + + +\textbf{ 22 } \quad ef-pentecost-ember-sat\\ +\small class-1 \textperiodcentered\ red\\ +\small Ep. Rom 5:1-5.\quad\small Ev. Luke 4:38-44.\\ + +\medskip + + +\textbf{ 23 } \quad ef-trinity\\ +\small class-1 \textperiodcentered\ white\\ +\small Ep. Rom 11:33-36.\quad\small Ev. Matt 28:18-20\\ + +\medskip + + +\textbf{ 24 } \quad ef-time-after-pentecost-1-monday\\ +\small class-4 \textperiodcentered\ green\\ +\small Ep. 1 John 4:8-21\quad\small Ev. Luke 6:36-42\\ + +\medskip + + +\textbf{ 25 } \quad gregory-vii\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. 1 Pet 5:1-4; 5:10-11.\quad\small Ev. Matt 16:13-19\\ +\small Com. urban-pope-and-martyr\\ + +\medskip + + +\textbf{ 26 } \quad philip-neri\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. Wis 7:7-14.\quad\small Ev. Luke 12:35-40\\ +\small Com. eleutherius\\ + +\medskip + + +\textbf{ 27 } \quad ef-corpus-christi\\ +\small class-1 \textperiodcentered\ white\\ +\small Ep. 1 Cor 11:23-29\quad\small Ev. John 6:56-59\\ + +\medskip + + +\textbf{ 28 } \quad augustine-of-canterbury\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. 1 Thess 2:2-9\quad\small Ev. Luke 10:1-9\\ + +\medskip + + +\textbf{ 29 } \quad mary-magdalene-de-pazzi\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. 2 Cor 10:17-18; 11:1-2\quad\small Ev. Matt 25:1-13.\\ + +\medskip + + +\textbf{ 30 } \quad ef-time-after-pentecost-sunday-2\\ +\small class-2 \textperiodcentered\ green\\ +\small Ep. 1 John 3:13-18.\quad\small Ev. Luke 14:16-24.\\ + +\medskip + + +\textbf{ 31 } \quad queenship-of-the-blessed-virgin-mary\\ +\small class-2 \textperiodcentered\ white\\ +\small Ep. Eccli 24:5; 14:7; 14:9-11; 24:30-31\quad\small Ev. Luke 1:26-33\\ +\small Com. petronilla\\ + +\medskip + + + +\section*{ Iunius } + +\textbf{ 1 } \quad angela-merici\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. 2 Cor 10:17-18; 11:1-2\quad\small Ev. Matt 25:1-13.\\ + +\medskip + + +\textbf{ 2 } \quad ef-time-after-pentecost-2-wednesday\\ +\small class-4 \textperiodcentered\ green\\ +\small Ep. 1 John 3:13-18.\quad\small Ev. Luke 14:16-24.\\ +\small Com. sts-marcellinus-peter-erasmus\\ + +\medskip + + +\textbf{ 3 } \quad ef-time-after-pentecost-2-thursday\\ +\small class-4 \textperiodcentered\ green\\ +\small Ep. 1 John 3:13-18.\quad\small Ev. Luke 14:16-24.\\ + +\medskip + + +\textbf{ 4 } \quad ef-sacred-heart\\ +\small class-1 \textperiodcentered\ white\\ +\small Ep. Eph 3:8-12, 14-19\quad\small Ev. John 19:31-37\\ + +\medskip + + +\textbf{ 5 } \quad boniface\\ +\small class-3 \textperiodcentered\ red\\ +\small Ep. Ecclus 44:1-15\quad\small Ev. Matt 5:1-12\\ + +\medskip + + +\textbf{ 6 } \quad ef-time-after-pentecost-sunday-3\\ +\small class-2 \textperiodcentered\ green\\ +\small Ep. 1 Pet. 5:6-11\quad\small Ev. Luke 15:1-10\\ + +\medskip + + +\textbf{ 7 } \quad ef-time-after-pentecost-3-monday\\ +\small class-4 \textperiodcentered\ green\\ +\small Ep. 1 Pet. 5:6-11\quad\small Ev. Luke 15:1-10\\ + +\medskip + + +\textbf{ 8 } \quad ef-time-after-pentecost-3-tuesday\\ +\small class-4 \textperiodcentered\ green\\ +\small Ep. 1 Pet. 5:6-11\quad\small Ev. Luke 15:1-10\\ + +\medskip + + +\textbf{ 9 } \quad ef-time-after-pentecost-3-wednesday\\ +\small class-4 \textperiodcentered\ green\\ +\small Ep. 1 Pet. 5:6-11\quad\small Ev. Luke 15:1-10\\ +\small Com. sts-primus-felicianus\\ + +\medskip + + +\textbf{ 10 } \quad margaret-of-scotland\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. Prov 31:10-31\quad\small Ev. Matt 13:44-52.\\ + +\medskip + + +\textbf{ 11 } \quad barnabas\\ +\small class-3 \textperiodcentered\ red\\ +\small Ep. Acts 11:21-26; 13:1-3\quad\small Ev. Matt 10:16-22\\ + +\medskip + + +\textbf{ 12 } \quad john-of-san-fecundo\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. Sir 31:8-11\quad\small Ev. Luke 12:35-40\\ +\small Com. basilidus\\ + +\medskip + + +\textbf{ 13 } \quad ef-time-after-pentecost-sunday-4\\ +\small class-2 \textperiodcentered\ green\\ +\small Ep. Rom 8:18-23\quad\small Ev. Luke 5:1-11\\ + +\medskip + + +\textbf{ 14 } \quad basil-the-great\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. 2 Tim 4:1-8\quad\small Ev. Luke 14:26-35\\ + +\medskip + + +\textbf{ 15 } \quad ef-time-after-pentecost-4-tuesday\\ +\small class-4 \textperiodcentered\ green\\ +\small Ep. Rom 8:18-23\quad\small Ev. Luke 5:1-11\\ +\small Com. vitus\\ + +\medskip + + +\textbf{ 16 } \quad ef-time-after-pentecost-4-wednesday\\ +\small class-4 \textperiodcentered\ green\\ +\small Ep. Rom 8:18-23\quad\small Ev. Luke 5:1-11\\ + +\medskip + + +\textbf{ 17 } \quad gregory-barbarigo\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. Sir 44:16-27; 45:3-20\quad\small Ev. Matt 25:14-23\\ + +\medskip + + +\textbf{ 18 } \quad ephrem-of-syria\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. 2 Tim 4:1-8\quad\small Ev. Matt 5:13-19\\ +\small Com. marcus-and-marcellianus\\ + +\medskip + + +\textbf{ 19 } \quad julia-of-falconieri\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. 2 Cor 10:17-18; 11:1-2\quad\small Ev. Matt 25:1-13.\\ +\small Com. sts-gervasius-and-protasius\\ + +\medskip + + +\textbf{ 20 } \quad ef-time-after-pentecost-sunday-5\\ +\small class-2 \textperiodcentered\ green\\ +\small Ep. 1 Pet 3:8-15.\quad\small Ev. Matt 5:20-24.\\ + +\medskip + + +\textbf{ 21 } \quad aloysius-gongzaga\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. Sir 31:8-11\quad\small Ev. Matt 22:29-40\\ + +\medskip + + +\textbf{ 22 } \quad paulinus-of-nola\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. 2 Cor. 8:9-15\quad\small Ev. Luke 12:32-34\\ + +\medskip + + +\textbf{ 23 } \quad vigil-of-the-nativity-of-st-john-the-baptist\\ +\small class-2 \textperiodcentered\ violet\\ +\small Ep. Jer 1:4-10\quad\small Ev. Luke 1:5-17\\ + +\medskip + + +\textbf{ 24 } \quad nativity-of-st-john-the-baptist\\ +\small class-1 \textperiodcentered\ white\\ +\small Ep. Isa 49:1-3, 5-7.\quad\small Ev. Luke 1:57-68\\ + +\medskip + + +\textbf{ 25 } \quad william\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. Ecclus 45:1-6\quad\small Ev. Matt 19:27-29.\\ + +\medskip + + +\textbf{ 26 } \quad sts-john-paul\\ +\small class-3 \textperiodcentered\ red\\ +\small Ep. Eccli 44:10-15\quad\small Ev. Luke 12:1-8\\ + +\medskip + + +\textbf{ 27 } \quad ef-time-after-pentecost-sunday-6\\ +\small class-2 \textperiodcentered\ green\\ +\small Ep. Rom 6:3-11.\quad\small Ev. Mark 8:1-9\\ + +\medskip + + +\textbf{ 28 } \quad vigil-of-sts-peter-paul\\ +\small class-2 \textperiodcentered\ violet\\ +\small Ep. Acts 3:1-10\quad\small Ev. John 21:15-19\\ + +\medskip + + +\textbf{ 29 } \quad sts-peter-paul\\ +\small class-1 \textperiodcentered\ red\\ +\small Ep. Acts 12:1-11\quad\small Ev. Matt 16:13-19\\ + +\medskip + + +\textbf{ 30 } \quad in-commemoratione-sancti-pauli-apostoli\\ +\small class-3 \textperiodcentered\ red\\ +\small Ep. Gal 1:11-20\quad\small Ev. Matt 10:16-22\\ +\small Com. commemoration-of-st-peter\\ + +\medskip + + + +\section*{ Iulius } + +\textbf{ 1 } \quad precious-blood-of-our-lord-jesus-christ\\ +\small class-1 \textperiodcentered\ red\\ +\small Ep. Heb 9:11-15.\quad\small Ev. John 19:30-35\\ + +\medskip + + +\textbf{ 2 } \quad visitation-of-the-blessed-virgin-mary\\ +\small class-2 \textperiodcentered\ white\\ +\small Ep. Song 2:8-14\quad\small Ev. Luke 1:39-47\\ +\small Com. processus-and-martinian\\ + +\medskip + + +\textbf{ 3 } \quad irenaeus\\ +\small class-3 \textperiodcentered\ red\\ +\small Ep. 2 Tim. 3:14-17; 4:1-5\quad\small Ev. Matt 10:28-33\\ + +\medskip + + +\textbf{ 4 } \quad ef-time-after-pentecost-sunday-7\\ +\small class-2 \textperiodcentered\ green\\ +\small Ep. Rom 6:19-23\quad\small Ev. Matt 7:15-21\\ + +\medskip + + +\textbf{ 5 } \quad anthony-mary-zaccariah\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. 1 Tim. 4:8-16\quad\small Ev. Mark 10:15-21\\ + +\medskip + + +\textbf{ 6 } \quad ef-time-after-pentecost-7-tuesday\\ +\small class-4 \textperiodcentered\ green\\ +\small Ep. Rom 6:19-23\quad\small Ev. Matt 7:15-21\\ + +\medskip + + +\textbf{ 7 } \quad sts-cyril-methodius\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. Heb 7:23-27\quad\small Ev. Luke 10:1-9\\ + +\medskip + + +\textbf{ 8 } \quad elizabeth-of-portugal\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. Prov 31:10-31\quad\small Ev. Matt 13:44-52.\\ + +\medskip + + +\textbf{ 9 } \quad ef-time-after-pentecost-7-friday\\ +\small class-4 \textperiodcentered\ green\\ +\small Ep. Rom 6:19-23\quad\small Ev. Matt 7:15-21\\ + +\medskip + + +\textbf{ 10 } \quad seven-holy-brothers-and-sts-rufina-secunda\\ +\small class-3 \textperiodcentered\ red\\ +\small Ep. Prov 31:10-31\quad\small Ev. Matt 12:46-50\\ + +\medskip + + +\textbf{ 11 } \quad ef-time-after-pentecost-sunday-8\\ +\small class-2 \textperiodcentered\ green\\ +\small Ep. Rom 8:12-17\quad\small Ev. Luke 16:1-9\\ + +\medskip + + +\textbf{ 12 } \quad john-gualbert\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. Ecclus 45:1-6\quad\small Ev. Matt 5:43-48\\ +\small Com. naboris-et-felicis\\ + +\medskip + + +\textbf{ 13 } \quad ef-time-after-pentecost-8-tuesday\\ +\small class-4 \textperiodcentered\ green\\ +\small Ep. Rom 8:12-17\quad\small Ev. Luke 16:1-9\\ + +\medskip + + +\textbf{ 14 } \quad bonaventure\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. 2 Tim 4:1-8\quad\small Ev. Matt 5:13-19\\ + +\medskip + + +\textbf{ 15 } \quad henry-the-emperor\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. Sir 31:8-11\quad\small Ev. Luke 12:35-40\\ + +\medskip + + +\textbf{ 16 } \quad ef-time-after-pentecost-8-friday\\ +\small class-4 \textperiodcentered\ green\\ +\small Ep. Rom 8:12-17\quad\small Ev. Luke 16:1-9\\ +\small Com. our-lady-of-mt-carmel\\ + +\medskip + + +\textbf{ 17 } \quad Officium sanctae Mariae in sabbato\\ +\small class-4 \textperiodcentered\ white\\ +\small Ep. Ecclus 24:14-16\quad\small Ev. Luke 11:27-28\\ +\small Com. alexis\\ + +\medskip + + +\textbf{ 18 } \quad ef-time-after-pentecost-sunday-9\\ +\small class-2 \textperiodcentered\ green\\ +\small Ep. 1 Cor. 10:6-13\quad\small Ev. Luke 19:41-47\\ + +\medskip + + +\textbf{ 19 } \quad vincent-de-paul\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. 1 Cor. 4:9-14\quad\small Ev. Luke 10:1-9\\ + +\medskip + + +\textbf{ 20 } \quad jerome-emiliani\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. Isa 58:7-11\quad\small Ev. Matt 19:13-21\\ +\small Com. margaret\\ + +\medskip + + +\textbf{ 21 } \quad laurence-of-brindisi\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. 2 Tim 4:1-8\quad\small Ev. Matt 5:13-19\\ +\small Com. praxedis-virginis\\ + +\medskip + + +\textbf{ 22 } \quad mary-magdalene\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. Song 3:2-5; 8:6-7\quad\small Ev. Luke 7:36-50\\ + +\medskip + + +\textbf{ 23 } \quad apollinaris\\ +\small class-3 \textperiodcentered\ red\\ +\small Ep. 1 Pet. 5:1-11\quad\small Ev. Luke 22:24-30\\ +\small Com. liborii\\ + +\medskip + + +\textbf{ 24 } \quad Officium sanctae Mariae in sabbato\\ +\small class-4 \textperiodcentered\ white\\ +\small Ep. Ecclus 24:14-16\quad\small Ev. Luke 11:27-28\\ +\small Com. christina\\ + +\medskip + + +\textbf{ 25 } \quad ef-time-after-pentecost-sunday-10\\ +\small class-2 \textperiodcentered\ green\\ +\small Ep. 1 Cor. 12:2-11\quad\small Ev. Luke 18:9-14\\ +\small Com. james-the-greater\\ + +\medskip + + +\textbf{ 26 } \quad anne-mother-of-the-blessed-virgin\\ +\small class-2 \textperiodcentered\ white\\ +\small Ep. Prov 31:10-31\quad\small Ev. Matt 13:44-52.\\ + +\medskip + + +\textbf{ 27 } \quad ef-time-after-pentecost-10-tuesday\\ +\small class-4 \textperiodcentered\ green\\ +\small Ep. 1 Cor. 12:2-11\quad\small Ev. Luke 18:9-14\\ +\small Com. pantaleon\\ + +\medskip + + +\textbf{ 28 } \quad sts-nazarius-celsus-st-victor-i-st-innocent-i\\ +\small class-3 \textperiodcentered\ red\\ +\small Ep. Wis 10:17-20\quad\small Ev. Luke 21:9-19\\ + +\medskip + + +\textbf{ 29 } \quad martha\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. 2 Cor 10:17-18; 11:1-2\quad\small Ev. Luke 10:38-42\\ +\small Com. felicis-simplicii-faustini-et-beatricis\\ + +\medskip + + +\textbf{ 30 } \quad ef-time-after-pentecost-10-friday\\ +\small class-4 \textperiodcentered\ green\\ +\small Ep. 1 Cor. 12:2-11\quad\small Ev. Luke 18:9-14\\ +\small Com. sts-abdon-sennen\\ + +\medskip + + +\textbf{ 31 } \quad ignatius-loyola\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. 2 Tim. 2:8-10; 3:10-12.\quad\small Ev. Luke 10:1-9\\ + +\medskip + + + +\section*{ Augustus } + +\textbf{ 1 } \quad ef-time-after-pentecost-sunday-11\\ +\small class-2 \textperiodcentered\ green\\ +\small Ep. 1 Cor. 15:1-10\quad\small Ev. Mark 7:31-37\\ + +\medskip + + +\textbf{ 2 } \quad alphonsus-liguori\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. 2 Tim. 2:1-7\quad\small Ev. Luke 10:1-9\\ +\small Com. stephen-i-pope-and-martyr\\ + +\medskip + + +\textbf{ 3 } \quad ef-time-after-pentecost-11-tuesday\\ +\small class-4 \textperiodcentered\ green\\ +\small Ep. 1 Cor. 15:1-10\quad\small Ev. Mark 7:31-37\\ + +\medskip + + +\textbf{ 4 } \quad dominic\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. 2 Tim. 4:1-8\quad\small Ev. Luke 12:35-40\\ + +\medskip + + +\textbf{ 5 } \quad dedication-of-the-basilica-of-st-mary-major\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. Ecclus 24:14-16\quad\small Ev. Luke 11:27-28\\ + +\medskip + + +\textbf{ 6 } \quad transfiguration-of-our-lord\\ +\small class-2 \textperiodcentered\ white\\ +\small Ep. 2 Pet. 1:16-19\quad\small Ev. Matt 17:1-9\\ +\small Com. pope-sixtus-ii-felicissimus-and-agapitus-martyrs\\ + +\medskip + + +\textbf{ 7 } \quad cajetan\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. Sir 31:8-11\quad\small Ev. Matt 6:24-33\\ +\small Com. donatus\\ + +\medskip + + +\textbf{ 8 } \quad ef-time-after-pentecost-sunday-12\\ +\small class-2 \textperiodcentered\ green\\ +\small Ep. 2 Cor. 3:4-9\quad\small Ev. Luke 10:23-37\\ + +\medskip + + +\textbf{ 9 } \quad vigil-of-st-lawrence\\ +\small class-3 \textperiodcentered\ violet\\ +\small Ep. Ecclus 51:1-8, 12\quad\small Ev. Matt 16:24-27\\ +\small Com. romanus\\ + +\medskip + + +\textbf{ 10 } \quad lawrence\\ +\small class-2 \textperiodcentered\ red\\ +\small Ep. 2 Cor. 9:6-10\quad\small Ev. John 12:24-26\\ + +\medskip + + +\textbf{ 11 } \quad ef-time-after-pentecost-12-wednesday\\ +\small class-4 \textperiodcentered\ green\\ +\small Ep. 2 Cor. 3:4-9\quad\small Ev. Luke 10:23-37\\ +\small Com. sts-tiburtius-susanna\\ + +\medskip + + +\textbf{ 12 } \quad clare\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. 2 Cor 10:17-18; 11:1-2\quad\small Ev. Matt 25:1-13.\\ + +\medskip + + +\textbf{ 13 } \quad ef-time-after-pentecost-12-friday\\ +\small class-4 \textperiodcentered\ green\\ +\small Ep. 2 Cor. 3:4-9\quad\small Ev. Luke 10:23-37\\ +\small Com. sts-hippolytus-cassian\\ + +\medskip + + +\textbf{ 14 } \quad vigil-of-the-assumption\\ +\small class-2 \textperiodcentered\ violet\\ +\small Ep. Sir 24:23-31\quad\small Ev. Luke 11:27-28\\ +\small Com. eusebius-confessor\\ + +\medskip + + +\textbf{ 15 } \quad assumption-of-the-blessed-virgin-mary\\ +\small class-1 \textperiodcentered\ white\\ +\small Ep. Judith 13:22-25; 15:10\quad\small Ev. Luke 1:41-50\\ +\small Com. ef-time-after-pentecost-sunday-13\\ + +\medskip + + +\textbf{ 16 } \quad joachim-father-of-the-blessed-virgin\\ +\small class-2 \textperiodcentered\ white\\ +\small Ep. Sir 31:8-11\quad\small Ev. Matt 1:1-16\\ + +\medskip + + +\textbf{ 17 } \quad hyacinth\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. Sir 31:8-11\quad\small Ev. Luke 12:35-40\\ + +\medskip + + +\textbf{ 18 } \quad ef-time-after-pentecost-13-wednesday\\ +\small class-4 \textperiodcentered\ green\\ +\small Ep. Gal 3:16-22\quad\small Ev. Luke 17:11-19\\ +\small Com. agapitus\\ + +\medskip + + +\textbf{ 19 } \quad john-eudes\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. Sir 31:8-11\quad\small Ev. Luke 12:35-40\\ + +\medskip + + +\textbf{ 20 } \quad bernard-of-clairvaux\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. Ecclus 39:6-14\quad\small Ev. Matt 5:13-19\\ + +\medskip + + +\textbf{ 21 } \quad jane-frances-de-chantal\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. Prov 31:10-31\quad\small Ev. Matt 13:44-52.\\ + +\medskip + + +\textbf{ 22 } \quad ef-time-after-pentecost-sunday-14\\ +\small class-2 \textperiodcentered\ green\\ +\small Ep. Gal 5:16-24\quad\small Ev. Matt 6:24-33\\ +\small Com. immaculate-heart-of-mary\\ + +\medskip + + +\textbf{ 23 } \quad philip-benizi\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. 1 Cor. 4:9-14\quad\small Ev. Luke 12:32-34\\ + +\medskip + + +\textbf{ 24 } \quad bartholomew\\ +\small class-2 \textperiodcentered\ red\\ +\small Ep. 1 Cor. 12:27-31\quad\small Ev. Luke 6:12-19\\ + +\medskip + + +\textbf{ 25 } \quad louis-ix\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. Wis 10:10-14\quad\small Ev. Luke 19:12-26\\ + +\medskip + + +\textbf{ 26 } \quad ef-time-after-pentecost-14-thursday\\ +\small class-4 \textperiodcentered\ green\\ +\small Ep. Gal 5:16-24\quad\small Ev. Matt 6:24-33\\ +\small Com. zephyrinus\\ + +\medskip + + +\textbf{ 27 } \quad joseph-calasance\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. Wis 10:10-14\quad\small Ev. Matt 18:1-5\\ + +\medskip + + +\textbf{ 28 } \quad augustine\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. 2 Tim 4:1-8\quad\small Ev. Matt 5:13-19\\ +\small Com. hermes\\ + +\medskip + + +\textbf{ 29 } \quad ef-time-after-pentecost-sunday-15\\ +\small class-2 \textperiodcentered\ green\\ +\small Ep. Gal 5:25-26; 6:1-10\quad\small Ev. Luke 7:11-16\\ + +\medskip + + +\textbf{ 30 } \quad rose-of-lima\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. 2 Cor 10:17-18; 11:1-2\quad\small Ev. Matt 25:1-13.\\ +\small Com. sts-felix-and-adauctus\\ + +\medskip + + +\textbf{ 31 } \quad raymond-nonnatus\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. Sir 31:8-11\quad\small Ev. Luke 12:35-40\\ + +\medskip + + + +\section*{ September } + +\textbf{ 1 } \quad ef-time-after-pentecost-15-wednesday\\ +\small class-4 \textperiodcentered\ green\\ +\small Ep. Gal 5:25-26; 6:1-10\quad\small Ev. Luke 7:11-16\\ +\small Com. giles\\ +\small Com. twelve-holy-brothers-martyrs\\ + +\medskip + + +\textbf{ 2 } \quad stephen-of-hungary\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. Sir 31:8-11\quad\small Ev. Luke 19:12-26\\ + +\medskip + + +\textbf{ 3 } \quad pius-x\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. 1 Thess. 2:2-8\quad\small Ev. John 21:15-17\\ + +\medskip + + +\textbf{ 4 } \quad Officium sanctae Mariae in sabbato\\ +\small class-4 \textperiodcentered\ white\\ +\small Ep. Ecclus 24:14-16\quad\small Ev. Luke 11:27-28\\ + +\medskip + + +\textbf{ 5 } \quad ef-time-after-pentecost-sunday-16\\ +\small class-2 \textperiodcentered\ green\\ +\small Ep. Eph 3:13-21\quad\small Ev. Luke 14:1-11\\ + +\medskip + + +\textbf{ 6 } \quad ef-time-after-pentecost-16-monday\\ +\small class-4 \textperiodcentered\ green\\ +\small Ep. Eph 3:13-21\quad\small Ev. Luke 14:1-11\\ + +\medskip + + +\textbf{ 7 } \quad ef-time-after-pentecost-16-tuesday\\ +\small class-4 \textperiodcentered\ green\\ +\small Ep. Eph 3:13-21\quad\small Ev. Luke 14:1-11\\ + +\medskip + + +\textbf{ 8 } \quad nativity-of-the-blessed-virgin-mary\\ +\small class-2 \textperiodcentered\ white\\ +\small Ep. Prov 8:22-35\quad\small Ev. Matt 1:1-16\\ +\small Com. hadriani\\ + +\medskip + + +\textbf{ 9 } \quad ef-time-after-pentecost-16-thursday\\ +\small class-4 \textperiodcentered\ green\\ +\small Ep. Eph 3:13-21\quad\small Ev. Luke 14:1-11\\ +\small Com. gorgonius\\ + +\medskip + + +\textbf{ 10 } \quad nicholas-of-tolentino\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. 1 Cor. 4:9-14\quad\small Ev. Luke 12:32-34\\ + +\medskip + + +\textbf{ 11 } \quad Officium sanctae Mariae in sabbato\\ +\small class-4 \textperiodcentered\ white\\ +\small Ep. Ecclus 24:14-16\quad\small Ev. Luke 11:27-28\\ +\small Com. sts-protus-hyacinth\\ + +\medskip + + +\textbf{ 12 } \quad ef-time-after-pentecost-sunday-17\\ +\small class-2 \textperiodcentered\ green\\ +\small Ep. Eph 4:1-6\quad\small Ev. Matt 22:34-46\\ + +\medskip + + +\textbf{ 13 } \quad ef-time-after-pentecost-17-monday\\ +\small class-4 \textperiodcentered\ green\\ +\small Ep. Eph 4:1-6\quad\small Ev. Matt 22:34-46\\ + +\medskip + + +\textbf{ 14 } \quad exaltation-of-the-holy-cross\\ +\small class-2 \textperiodcentered\ red\\ +\small Ep. Phil 2:5-11\quad\small Ev. John 12:31-36\\ + +\medskip + + +\textbf{ 15 } \quad seven-sorrows-of-the-blessed-virgin-mary\\ +\small class-2 \textperiodcentered\ white\\ +\small Ep. Judith 13:22; 13:23-25\quad\small Ev. John 19:25-27\\ +\small Com. nicomedes\\ + +\medskip + + +\textbf{ 16 } \quad sts-cornelius-cyprian\\ +\small class-3 \textperiodcentered\ red\\ +\small Ep. Wis 3:1-8\quad\small Ev. Luke 21:9-19\\ +\small Com. sts-euphemia-lucy-and-geminianus\\ + +\medskip + + +\textbf{ 17 } \quad ef-time-after-pentecost-17-friday\\ +\small class-4 \textperiodcentered\ green\\ +\small Ep. Eph 4:1-6\quad\small Ev. Matt 22:34-46\\ +\small Com. stigmata-of-st-francis\\ + +\medskip + + +\textbf{ 18 } \quad joseph-of-cupertino\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. 1 Cor 13:1-8\quad\small Ev. Matt 22:1-14\\ + +\medskip + + +\textbf{ 19 } \quad ef-time-after-pentecost-sunday-18\\ +\small class-2 \textperiodcentered\ green\\ +\small Ep. 1 Cor. 1:4-8\quad\small Ev. Matt 9:1-8\\ + +\medskip + + +\textbf{ 20 } \quad ef-time-after-pentecost-18-monday\\ +\small class-4 \textperiodcentered\ green\\ +\small Ep. 1 Cor. 1:4-8\quad\small Ev. Matt 9:1-8\\ +\small Com. sts-eustace-companions\\ + +\medskip + + +\textbf{ 21 } \quad matthew\\ +\small class-2 \textperiodcentered\ red\\ +\small Ep. Ezek 1:10-14\quad\small Ev. Matt 9:9-13\\ + +\medskip + + +\textbf{ 22 } \quad ef-september-ember-wed\\ +\small class-2 \textperiodcentered\ violet\\ +\small Ep. 2 Esd. 8:1-10\quad\small Ev. Mark 9:16-28\\ +\small Com. thomas-of-villanova\\ + +\medskip + + +\textbf{ 23 } \quad linus\\ +\small class-3 \textperiodcentered\ red\\ +\small Ep. 1 Pet 5:1-4; 5:10-11.\quad\small Ev. Matt 16:13-19\\ +\small Com. thecla\\ + +\medskip + + +\textbf{ 24 } \quad ef-september-ember-fri\\ +\small class-2 \textperiodcentered\ violet\\ +\small Ep. Osee 14:2-10\quad\small Ev. Luke 7:36-50\\ +\small Com. our-lady-of-ransom\\ + +\medskip + + +\textbf{ 25 } \quad ef-september-ember-sat\\ +\small class-2 \textperiodcentered\ violet\\ +\small Ep. Heb 9:2-12\quad\small Ev. Luke 13:6-17\\ + +\medskip + + +\textbf{ 26 } \quad ef-time-after-pentecost-sunday-19\\ +\small class-2 \textperiodcentered\ green\\ +\small Ep. Eph 4:23-28\quad\small Ev. Matt 22:1-14\\ + +\medskip + + +\textbf{ 27 } \quad sts-cosmas-damian\\ +\small class-3 \textperiodcentered\ red\\ +\small Ep. Wis 5:16-20\quad\small Ev. Luke 6:17-23\\ + +\medskip + + +\textbf{ 28 } \quad wenceslaus\\ +\small class-3 \textperiodcentered\ red\\ +\small Ep. Wis 10:10-14\quad\small Ev. Matt 10:34-42\\ + +\medskip + + +\textbf{ 29 } \quad dedication-of-st-michael-the-archangel\\ +\small class-1 \textperiodcentered\ white\\ +\small Ep. Rev 1:1-5\quad\small Ev. Matt 18:1-10\\ + +\medskip + + +\textbf{ 30 } \quad jerome\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. 2 Tim 4:1-8\quad\small Ev. Matt 5:13-19\\ + +\medskip + + + +\section*{ October } + +\textbf{ 1 } \quad ef-time-after-pentecost-19-friday\\ +\small class-4 \textperiodcentered\ green\\ +\small Ep. Eph 4:23-28\quad\small Ev. Matt 22:1-14\\ +\small Com. remigius\\ + +\medskip + + +\textbf{ 2 } \quad holy-guardian-angels\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. Exod 23:20-23\quad\small Ev. Matt 18:1-10\\ + +\medskip + + +\textbf{ 3 } \quad ef-time-after-pentecost-sunday-20\\ +\small class-2 \textperiodcentered\ green\\ +\small Ep. Eph 5:15-21\quad\small Ev. John 4:46-53\\ + +\medskip + + +\textbf{ 4 } \quad francis-of-assisi\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. Gal 6:14-18\quad\small Ev. Matt 11:25-30\\ + +\medskip + + +\textbf{ 5 } \quad ef-time-after-pentecost-20-tuesday\\ +\small class-4 \textperiodcentered\ green\\ +\small Ep. Eph 5:15-21\quad\small Ev. John 4:46-53\\ +\small Com. placid-companions\\ + +\medskip + + +\textbf{ 6 } \quad bruno\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. Sir 31:8-11\quad\small Ev. Luke 12:35-40\\ + +\medskip + + +\textbf{ 7 } \quad our-lady-of-the-rosary\\ +\small class-2 \textperiodcentered\ white\\ +\small Ep. Prov 8:22-24, 32-35.\quad\small Ev. Luke 1:26-38\\ +\small Com. mark-i\\ + +\medskip + + +\textbf{ 8 } \quad bridget-of-sweden\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. 1 Tim. 5:3-10.\quad\small Ev. Matt 13:44-52.\\ +\small Com. sergio-baccho-marcello-and-apulejo-martyrs\\ + +\medskip + + +\textbf{ 9 } \quad john-leonardi\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. 2 Cor 4:1-6; 4:15-18\quad\small Ev. Luke 10:1-9\\ +\small Com. dionysius-and-companions\\ + +\medskip + + +\textbf{ 10 } \quad ef-time-after-pentecost-sunday-21\\ +\small class-2 \textperiodcentered\ green\\ +\small Ep. Eph 6:10-17\quad\small Ev. Matt 18:23-35\\ + +\medskip + + +\textbf{ 11 } \quad maternity-of-the-blessed-virgin-mary\\ +\small class-2 \textperiodcentered\ white\\ +\small Ep. Sir 24:23-31\quad\small Ev. Luke 2:43-51\\ + +\medskip + + +\textbf{ 12 } \quad ef-time-after-pentecost-21-tuesday\\ +\small class-4 \textperiodcentered\ green\\ +\small Ep. Eph 6:10-17\quad\small Ev. Matt 18:23-35\\ + +\medskip + + +\textbf{ 13 } \quad edward\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. Sir 31:8-11\quad\small Ev. Luke 12:35-40\\ + +\medskip + + +\textbf{ 14 } \quad callistus-i\\ +\small class-3 \textperiodcentered\ red\\ +\small Ep. 1 Pet 5:1-4; 5:10-11.\quad\small Ev. Matt 16:13-19\\ + +\medskip + + +\textbf{ 15 } \quad teresa-of-avila\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. 2 Cor 10:17-18; 11:1-2\quad\small Ev. Matt 25:1-13.\\ + +\medskip + + +\textbf{ 16 } \quad hedwig\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. Prov 31:10-31\quad\small Ev. Matt 13:44-52.\\ + +\medskip + + +\textbf{ 17 } \quad ef-time-after-pentecost-sunday-22\\ +\small class-2 \textperiodcentered\ green\\ +\small Ep. Phil 1:6-11\quad\small Ev. Matt 22:15-21\\ + +\medskip + + +\textbf{ 18 } \quad luke-the-evangelist\\ +\small class-2 \textperiodcentered\ red\\ +\small Ep. 2 Cor. 8:16-24\quad\small Ev. Luke 10:1-9\\ + +\medskip + + +\textbf{ 19 } \quad peter-of-alcantara\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. Phil 3:7-12\quad\small Ev. Luke 12:32-34\\ + +\medskip + + +\textbf{ 20 } \quad john-cantius\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. James 2:12-17\quad\small Ev. Luke 12:35-40\\ + +\medskip + + +\textbf{ 21 } \quad ef-time-after-pentecost-22-thursday\\ +\small class-4 \textperiodcentered\ green\\ +\small Ep. Phil 1:6-11\quad\small Ev. Matt 22:15-21\\ +\small Com. hilarion\\ +\small Com. ursula-and-companions\\ + +\medskip + + +\textbf{ 22 } \quad ef-time-after-pentecost-22-friday\\ +\small class-4 \textperiodcentered\ green\\ +\small Ep. Phil 1:6-11\quad\small Ev. Matt 22:15-21\\ + +\medskip + + +\textbf{ 23 } \quad anthony-mary-claret\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. Heb 7:23-27\quad\small Ev. Matt 24:42-47\\ + +\medskip + + +\textbf{ 24 } \quad ef-time-after-pentecost-sunday-23\\ +\small class-2 \textperiodcentered\ green\\ +\small Ep. Phil 3:17-21; 4:1-3\quad\small Ev. Matt 9:18-26\\ + +\medskip + + +\textbf{ 25 } \quad ef-time-after-pentecost-23-monday\\ +\small class-4 \textperiodcentered\ green\\ +\small Ep. Phil 3:17-21; 4:1-3\quad\small Ev. Matt 9:18-26\\ +\small Com. sts-chrysanthus-daria\\ + +\medskip + + +\textbf{ 26 } \quad ef-time-after-pentecost-23-tuesday\\ +\small class-4 \textperiodcentered\ green\\ +\small Ep. Phil 3:17-21; 4:1-3\quad\small Ev. Matt 9:18-26\\ +\small Com. evaristus\\ + +\medskip + + +\textbf{ 27 } \quad ef-time-after-pentecost-23-wednesday\\ +\small class-4 \textperiodcentered\ green\\ +\small Ep. Phil 3:17-21; 4:1-3\quad\small Ev. Matt 9:18-26\\ + +\medskip + + +\textbf{ 28 } \quad sts-simon-jude\\ +\small class-2 \textperiodcentered\ red\\ +\small Ep. Eph. 4:7-13.\quad\small Ev. John 15:17-25\\ + +\medskip + + +\textbf{ 29 } \quad ef-time-after-pentecost-23-friday\\ +\small class-4 \textperiodcentered\ green\\ +\small Ep. Phil 3:17-21; 4:1-3\quad\small Ev. Matt 9:18-26\\ + +\medskip + + +\textbf{ 30 } \quad Officium sanctae Mariae in sabbato\\ +\small class-4 \textperiodcentered\ white\\ +\small Ep. Ecclus 24:14-16\quad\small Ev. Luke 11:27-28\\ + +\medskip + + +\textbf{ 31 } \quad ef-christ-the-king\\ +\small class-1 \textperiodcentered\ white\\ +\small Ep. Col 1:12-20.\quad\small Ev. John 18:33-37\\ + +\medskip + + + +\section*{ November } + +\textbf{ 1 } \quad all-saints\\ +\small class-1 \textperiodcentered\ white\\ +\small Ep. Apoc 7:2-12\quad\small Ev. Matt 5:1-12\\ + +\medskip + + +\textbf{ 2 } \quad commemoration-of-all-souls\\ +\small class-1 \textperiodcentered\ black\\ +\small Ep. 1 Cor. 15:51-57\quad\small Ev. John 5:25-29\\ + +\medskip + + +\textbf{ 3 } \quad ef-time-after-pentecost-24-wednesday\\ +\small class-4 \textperiodcentered\ green\\ +\small Ep. Col 1:12-20.\quad\small Ev. John 18:33-37\\ + +\medskip + + +\textbf{ 4 } \quad charles-borromeo\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. Sir 44:16-27; 45:3-20\quad\small Ev. Matt 25:14-23\\ +\small Com. sts-vitalis-and-agricola-martyrs\\ + +\medskip + + +\textbf{ 5 } \quad ef-time-after-pentecost-24-friday\\ +\small class-4 \textperiodcentered\ green\\ +\small Ep. Col 1:12-20.\quad\small Ev. John 18:33-37\\ + +\medskip + + +\textbf{ 6 } \quad Officium sanctae Mariae in sabbato\\ +\small class-4 \textperiodcentered\ white\\ +\small Ep. Ecclus 24:14-16\quad\small Ev. Luke 11:27-28\\ + +\medskip + + +\textbf{ 7 } \quad ef-time-after-epiphany-sunday-5\\ +\small class-2 \textperiodcentered\ green\\ +\small Ep. Col 3:12-17\quad\small Ev. Matt 13:24-30\\ + +\medskip + + +\textbf{ 8 } \quad ef-time-after-pentecost-25-monday\\ +\small class-4 \textperiodcentered\ green\\ +\small Ep. Col 3:12-17\quad\small Ev. Matt 13:24-30\\ +\small Com. four-holy-crowned-martyrs\\ + +\medskip + + +\textbf{ 9 } \quad dedication-of-the-archbasilica-of-our-holy-savior\\ +\small class-2 \textperiodcentered\ white\\ +\small Ep. Rev 21:2-5\quad\small Ev. Luke 19:1-10\\ +\small Com. theodore\\ + +\medskip + + +\textbf{ 10 } \quad andrew-avellino\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. Sir 31:8-11\quad\small Ev. Luke 12:35-40\\ +\small Com. sts-tryphonis-respicii-et-nymphae\\ + +\medskip + + +\textbf{ 11 } \quad martin-of-tours\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. Sir 44:16-27; 45:3-20\quad\small Ev. Luke 11:33-36\\ +\small Com. menna\\ + +\medskip + + +\textbf{ 12 } \quad martin-i\\ +\small class-3 \textperiodcentered\ red\\ +\small Ep. 1 Pet 5:1-4; 5:10-11.\quad\small Ev. Matt 16:13-19\\ + +\medskip + + +\textbf{ 13 } \quad didacus\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. 1 Cor 4:9-14\quad\small Ev. Luke 12:32-34\\ + +\medskip + + +\textbf{ 14 } \quad ef-time-after-epiphany-sunday-6\\ +\small class-2 \textperiodcentered\ green\\ +\small Ep. 1 Thess 1:2-10\quad\small Ev. Matt 13:31-35\\ + +\medskip + + +\textbf{ 15 } \quad albert-the-great\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. 2 Tim 4:1-8\quad\small Ev. Matt 5:13-19\\ + +\medskip + + +\textbf{ 16 } \quad gertrude-the-great\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. 2 Cor 10:17-18; 11:1-2\quad\small Ev. Matt 25:1-13.\\ + +\medskip + + +\textbf{ 17 } \quad gregory-the-wonderworker\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. Sir 44:16-27; 45:3-20\quad\small Ev. Mark 11:22-24\\ + +\medskip + + +\textbf{ 18 } \quad dedication-of-the-basilicas-of-sts-peter-paul\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. Rev 21:2-5\quad\small Ev. Luke 19:1-10\\ + +\medskip + + +\textbf{ 19 } \quad elizabeth-of-hungary\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. Prov 31:10-31\quad\small Ev. Matt 13:44-52.\\ +\small Com. pontian\\ + +\medskip + + +\textbf{ 20 } \quad felix-of-valois\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. 1 Cor. 4:9-14\quad\small Ev. Luke 12:32-34\\ + +\medskip + + +\textbf{ 21 } \quad ef-time-after-pentecost-sunday-24\\ +\small class-2 \textperiodcentered\ green\\ +\small Ep. Col 1:9-14\quad\small Ev. Matt 24:15-35\\ + +\medskip + + +\textbf{ 22 } \quad cecilia\\ +\small class-3 \textperiodcentered\ red\\ +\small Ep. Sir 51:13-17.\quad\small Ev. Matt 25:1-13.\\ + +\medskip + + +\textbf{ 23 } \quad clement-i\\ +\small class-3 \textperiodcentered\ red\\ +\small Ep. Phil 3:17-21; 4:1-3\quad\small Ev. Matt 16:13-19\\ +\small Com. felicity\\ + +\medskip + + +\textbf{ 24 } \quad john-of-the-cross\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. 2 Tim 4:1-8\quad\small Ev. Matt 5:13-19\\ +\small Com. chrysogonus\\ + +\medskip + + +\textbf{ 25 } \quad catherine-of-alexandria\\ +\small class-3 \textperiodcentered\ red\\ +\small Ep. Sir 51:1-8; 51:12\quad\small Ev. Matt 25:1-13.\\ + +\medskip + + +\textbf{ 26 } \quad sylvester\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. Ecclus 45:1-6\quad\small Ev. Matt 19:27-29.\\ +\small Com. peter-of-alexandria\\ + +\medskip + + +\textbf{ 27 } \quad Officium sanctae Mariae in sabbato\\ +\small class-4 \textperiodcentered\ white\\ +\small Ep. Ecclus 24:14-16\quad\small Ev. Luke 11:27-28\\ + +\medskip + + +\textbf{ 28 } \quad ef-advent-sunday-1\\ +\small class-1 \textperiodcentered\ violet\\ +\small Ep. Rom 13:11-14\quad\small Ev. Luke 21:25-33\\ + +\medskip + + +\textbf{ 29 } \quad ef-advent-1-monday\\ +\small class-3 \textperiodcentered\ violet\\ +\small Ep. Rom 13:11-14\quad\small Ev. Luke 21:25-33\\ +\small Com. saturninus\\ + +\medskip + + +\textbf{ 30 } \quad andrew\\ +\small class-2 \textperiodcentered\ red\\ +\small Ep. Rom 10:10-18\quad\small Ev. Matt 4:18-22\\ +\small Com. ef-advent-1-tuesday\\ + +\medskip + + + +\section*{ December } + +\textbf{ 1 } \quad ef-advent-1-wednesday\\ +\small class-3 \textperiodcentered\ violet\\ +\small Ep. Rom 13:11-14\quad\small Ev. Luke 21:25-33\\ + +\medskip + + +\textbf{ 2 } \quad vivian\\ +\small class-3 \textperiodcentered\ red\\ +\small Ep. Sir 51:13-17.\quad\small Ev. Matt 13:44-52.\\ +\small Com. ef-advent-1-thursday\\ + +\medskip + + +\textbf{ 3 } \quad francis-xavier\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. Rom 10:10-18\quad\small Ev. Mark 16:15-18\\ +\small Com. ef-advent-1-friday\\ + +\medskip + + +\textbf{ 4 } \quad peter-chrysologus\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. 2 Tim 4:1-8\quad\small Ev. Matt 5:13-19\\ +\small Com. ef-advent-1-saturday\\ +\small Com. barbara\\ + +\medskip + + +\textbf{ 5 } \quad ef-advent-sunday-2\\ +\small class-1 \textperiodcentered\ violet\\ +\small Ep. Rom 15:4-13\quad\small Ev. Matt 11:2-10\\ + +\medskip + + +\textbf{ 6 } \quad nicholas\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. Heb 13:7-17\quad\small Ev. Matt 25:14-23\\ +\small Com. ef-advent-2-monday\\ + +\medskip + + +\textbf{ 7 } \quad ambrose\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. 2 Tim 4:1-8\quad\small Ev. Matt 5:13-19\\ +\small Com. ef-advent-2-tuesday\\ + +\medskip + + +\textbf{ 8 } \quad immaculate-conception-of-the-blessed-virgin-mary\\ +\small class-1 \textperiodcentered\ white\\ +\small Ep. Prov 8:22-35\quad\small Ev. Luke 1:26-28\\ +\small Com. ef-advent-2-wednesday\\ + +\medskip + + +\textbf{ 9 } \quad ef-advent-2-thursday\\ +\small class-3 \textperiodcentered\ violet\\ +\small Ep. Rom 15:4-13\quad\small Ev. Matt 11:2-10\\ + +\medskip + + +\textbf{ 10 } \quad ef-advent-2-friday\\ +\small class-3 \textperiodcentered\ violet\\ +\small Ep. Rom 15:4-13\quad\small Ev. Matt 11:2-10\\ +\small Com. melchiades\\ + +\medskip + + +\textbf{ 11 } \quad damasus-i\\ +\small class-3 \textperiodcentered\ white\\ +\small Ep. 1 Pet 5:1-4; 5:10-11.\quad\small Ev. Matt 16:13-19\\ +\small Com. ef-advent-2-saturday\\ + +\medskip + + +\textbf{ 12 } \quad ef-advent-sunday-3\\ +\small class-1 \textperiodcentered\ rose\\ +\small Ep. Phil 4:4-7\quad\small Ev. John 1:19-28\\ + +\medskip + + +\textbf{ 13 } \quad lucy\\ +\small class-3 \textperiodcentered\ red\\ +\small Ep. 2 Cor 10:17-18; 11:1-2\quad\small Ev. Matt 13:44-52.\\ +\small Com. ef-advent-3-monday\\ + +\medskip + + +\textbf{ 14 } \quad ef-advent-3-tuesday\\ +\small class-3 \textperiodcentered\ violet\\ +\small Ep. Phil 4:4-7\quad\small Ev. John 1:19-28\\ + +\medskip + + +\textbf{ 15 } \quad ef-advent-ember-wed\\ +\small class-2 \textperiodcentered\ violet\\ +\small Ep. Isa 7:10-15\quad\small Ev. Luke 1:26-38\\ + +\medskip + + +\textbf{ 16 } \quad eusebius\\ +\small class-3 \textperiodcentered\ red\\ +\small Ep. 2 Cor. 1:3-7\quad\small Ev. Matt 16:24-27.\\ +\small Com. ef-advent-3-thursday\\ + +\medskip + + +\textbf{ 17 } \quad ef-advent-ember-fri\\ +\small class-2 \textperiodcentered\ violet\\ +\small Ep. Isa 11:1-5\quad\small Ev. Luke 1:39-47\\ + +\medskip + + +\textbf{ 18 } \quad ef-advent-ember-sat\\ +\small class-2 \textperiodcentered\ violet\\ +\small Ep. 2 Thess 2:1-8\quad\small Ev. Luke 3:1-6\\ + +\medskip + + +\textbf{ 19 } \quad ef-advent-sunday-4\\ +\small class-1 \textperiodcentered\ violet\\ +\small Ep. 1 Cor. 4:1-5\quad\small Ev. Luke 3:1-6\\ + +\medskip + + +\textbf{ 20 } \quad ef-advent-4-monday\\ +\small class-2 \textperiodcentered\ violet\\ +\small Ep. 1 Cor. 4:1-5\quad\small Ev. Luke 3:1-6\\ + +\medskip + + +\textbf{ 21 } \quad thomas\\ +\small class-2 \textperiodcentered\ red\\ +\small Ep. Eph 2:19-22\quad\small Ev. John 20:24-29\\ +\small Com. ef-advent-4-tuesday\\ + +\medskip + + +\textbf{ 22 } \quad ef-advent-4-wednesday\\ +\small class-2 \textperiodcentered\ violet\\ +\small Ep. 1 Cor. 4:1-5\quad\small Ev. Luke 3:1-6\\ + +\medskip + + +\textbf{ 23 } \quad ef-advent-4-thursday\\ +\small class-2 \textperiodcentered\ violet\\ +\small Ep. 1 Cor. 4:1-5\quad\small Ev. Luke 3:1-6\\ + +\medskip + + +\textbf{ 24 } \quad ef-nativity-vigil\\ +\small class-1 \textperiodcentered\ violet\\ +\small Ep. Rom 1:1-6\quad\small Ev. Matt 1:18-21\\ + +\medskip + + +\textbf{ 25 } \quad ef-nativity\\ +\small class-1 \textperiodcentered\ white\\ +\small Ep. Heb 1:1-12\quad\small Ev. John 1:1-14\\ + +\medskip + + +\textbf{ 26 } \quad ef-christmas-sunday-0\\ +\small class-2 \textperiodcentered\ white\\ +\small Ep. Gal 4:1-7\quad\small Ev. Luke 2:33-40\\ +\small Com. stephen\\ + +\medskip + + +\textbf{ 27 } \quad john-the-evangelist\\ +\small class-2 \textperiodcentered\ white\\ +\small Ep. Ecclus 15:1-6\quad\small Ev. John 21:19-24\\ +\small Com. ef-nativity-octave-day-3\\ + +\medskip + + +\textbf{ 28 } \quad holy-innocents\\ +\small class-2 \textperiodcentered\ red\\ +\small Ep. Apoc 14:1-5\quad\small Ev. Matt 2:13-18\\ +\small Com. ef-nativity-octave-day-4\\ + +\medskip + + +\textbf{ 29 } \quad ef-nativity-octave-day-5\\ +\small class-2 \textperiodcentered\ white\\ +\small Ep. Titus 3:4-7\quad\small Ev. Luke 2:15-20\\ +\small Com. thomas-becket\\ + +\medskip + + +\textbf{ 30 } \quad ef-nativity-octave-day-6\\ +\small class-2 \textperiodcentered\ white\\ +\small Ep. Titus 3:4-7\quad\small Ev. Luke 2:15-20\\ + +\medskip + + +\textbf{ 31 } \quad ef-nativity-octave-day-7\\ +\small class-2 \textperiodcentered\ white\\ +\small Ep. Titus 3:4-7\quad\small Ev. Luke 2:15-20\\ +\small Com. silvester\\ + +\medskip + + + +\end{document} diff --git a/test/golden/ordo-2027.txt b/test/golden/ordo-2027.txt new file mode 100644 index 0000000..daf66e3 --- /dev/null +++ b/test/golden/ordo-2027.txt @@ -0,0 +1,1986 @@ + +Ianuarius 2027 + +1 ef-circumcision + class-1 · white + Ep. Titus 2:11-15 + Ev. Luke 2:21 + +2 ef-christmas-1-saturday + class-4 · white + Ep. Titus 3:4-7 + Ev. Luke 2:15-20 + +3 ef-holy-name-sunday + class-2 · white + Ep. Acts 4:8-12 + Ev. Luke 2:21 + +4 ef-christmas-1-monday + class-4 · white + Ep. Titus 2:11-15 + Ev. Luke 2:21 + +5 ef-christmas-1-tuesday + class-4 · white + Ep. Titus 2:11-15 + Ev. Luke 2:21 + Com. telesphorus-pope-and-martyr + +6 ef-epiphany + class-1 · white + Ep. Isa 60:1-6 + Ev. Matt 2:1-12 + +7 ef-christmas-2-thursday + class-4 · white + Ep. Isa 60:1-6 + Ev. Matt 2:1-12 + +8 ef-christmas-2-friday + class-4 · white + Ep. Isa 60:1-6 + Ev. Matt 2:1-12 + +9 ef-christmas-2-saturday + class-4 · white + Ep. Titus 3:4-7 + Ev. Luke 2:15-20 + +10 ef-time-after-epiphany-sunday-1 + class-2 · white + Ep. Col 3:12-17 + Ev. Luke 2:42-52 + +11 ef-time-after-epiphany-1-monday + class-4 · white + Ep. Rom 12:1-5 + Ev. Luke 2:42-52 + Com. hyginus-pope-and-martyr + +12 ef-time-after-epiphany-1-tuesday + class-4 · white + Ep. Rom 12:1-5 + Ev. Luke 2:42-52 + +13 commemoration-of-the-baptism-of-the-lord + class-2 · white + Ep. Isa 60:1-6 + Ev. John 1:29-34 + +14 hilary + class-3 · white + Ep. 2 Tim 4:1-8 + Ev. Matt 5:13-19 + Com. felicis + +15 paul-the-first-hermit + class-3 · white + Ep. Phil 3:7-12 + Ev. Matt 11:25-30 + Com. maur-abbot + +16 marcellus-i + class-3 · red + Ep. 1 Pet 5:1-4; 5:10-11. + Ev. Matt 16:13-19 + +17 ef-time-after-epiphany-sunday-2 + class-2 · green + Ep. Rom 12:6-16 + Ev. John 2:1-11 + +18 ef-time-after-epiphany-2-monday + class-4 · green + Ep. Rom 12:6-16 + Ev. John 2:1-11 + Com. prisca + +19 ef-time-after-epiphany-2-tuesday + class-4 · green + Ep. Rom 12:6-16 + Ev. John 2:1-11 + Com. canute-martyr + Com. sts-marius-martha-audifax-abachum + +20 sts-fabian-sebastian + class-3 · red + Ep. Heb 11:33-39 + Ev. Luke 6:17-23 + +21 agnes + class-3 · red + Ep. Sir 51:1-8; 51:12 + Ev. Matt 25:1-13. + +22 sts-vincent-anastasius + class-3 · red + Ep. Wis 3:1-8 + Ev. Luke 21:9-19 + +23 raymond-of-pe-afort + class-3 · white + Ep. Sir 31:8-11 + Ev. Luke 12:35-40 + Com. emerentiana + +24 ef-septuagesima-sunday-1 + class-2 · violet + Ep. 1 Cor. 9:24-27; 10:1-5 + Ev. Matt 20:1-16 + +25 conversion-of-st-paul + class-3 · white + Ep. Acts 9:1-22 + Ev. Matt 19:27-29. + Com. peter + +26 polycarp + class-3 · red + Ep. 1 John 3:10-16 + Ev. Matt 10:26-32. + +27 john-chrysostom + class-3 · white + Ep. 2 Tim 4:1-8 + Ev. Matt 5:13-19 + +28 peter-nolasco + class-3 · white + Ep. 1 Cor. 4:9-14 + Ev. Luke 12:32-34 + Com. agnes-secundo + +29 francis-de-sales + class-3 · white + Ep. 2 Tim 4:1-8 + Ev. Matt 5:13-19 + +30 martina + class-3 · red + Ep. Sir 51:1-8; 51:12 + Ev. Matt 25:1-13. + +31 ef-septuagesima-sunday-2 + class-2 · violet + Ep. 2 Cor. 11:19-33; 12:1-9 + Ev. Luke 8:4-15 + + +Februarius 2027 + +1 ignatius-of-antioch + class-3 · red + Ep. Rom 8:35-39 + Ev. John 12:24-26 + +2 purification-of-the-blessed-virgin-mary + class-2 · white + Ep. Mal 3:1-4 + Ev. Luke 2:22-32 + +3 ef-septuagesima-2-wednesday + class-4 · violet + Ep. 2 Cor. 11:19-33; 12:1-9 + Ev. Luke 8:4-15 + Com. blaise + +4 andrew-corsini + class-3 · white + Ep. Sir 44:16-27; 45:3-20 + Ev. Matt 25:14-23 + +5 agatha + class-3 · red + Ep. 1 Cor. 1:26-31 + Ev. Matt 19:3-12. + +6 titus + class-3 · white + Ep. Sir 44:16-27; 45:3-20 + Ev. Luke 10:1-9 + Com. dorothy + +7 ef-septuagesima-sunday-3 + class-2 · violet + Ep. 1 Cor. 13:1-13 + Ev. Luke 18:31-43 + +8 john-of-matha + class-3 · white + Ep. Sir 31:8-11 + Ev. Luke 12:35-40 + +9 cyril-of-alexandria + class-3 · white + Ep. 2 Tim 4:1-8 + Ev. Matt 5:13-19 + Com. appollonia + +10 ef-ash-wednesday + class-1 · violet + Ep. Joel 2:12-19 + Ev. Matt 6:16-21 + +11 ef-lent-after-ashes-thursday + class-3 · violet + Ep. Isa 38:1-6 + Ev. Matt 8:5-13 + Com. our-lady-of-lourdes + +12 ef-lent-after-ashes-friday + class-3 · violet + Ep. Isa 58:1-9 + Ev. Matt 5:43-48; 6:1-4 + Com. seven-holy-servite-founders + +13 ef-lent-after-ashes-saturday + class-3 · violet + Ep. Isa 58:9-14 + Ev. Mark 6:47-56 + +14 ef-lent-sunday-1 + class-1 · violet + Ep. 2 Cor. 6:1-10 + Ev. Matt 4:1-11 + +15 ef-lent-1-monday + class-3 · violet + Ep. Ezech 34:11-16 + Ev. Matt 25:31-46 + Com. sts-faustinus-jovita + +16 ef-lent-1-tuesday + class-3 · violet + Ep. Isa 55:6-11 + Ev. Matt 21:10-17 + +17 ef-lent-ember-wed + class-2 · violet + Ep. 3 Kgs. 19:3-8 + Ev. Matt 12:38-50 + +18 ef-lent-1-thursday + class-3 · violet + Ep. Ezech 18:1-9 + Ev. Matt 15:21-28 + Com. simeon + +19 ef-lent-ember-fri + class-2 · violet + Ep. Ezech 18:20-28 + Ev. John 5:1-15 + +20 ef-lent-ember-sat + class-2 · violet + Ep. 1 Thess. 5:14-23 + Ev. Matt 17:1-9 + +21 ef-lent-sunday-2 + class-1 · violet + Ep. 1 Thess. 4:1-7 + Ev. Matt 17:1-9 + +22 chair-of-st-peter + class-2 · white + Ep. 1 Pet 1:1-7 + Ev. Matt 16:13-19 + Com. ef-lent-2-monday + Com. paul + +23 ef-lent-2-tuesday + class-3 · violet + Ep. 3 Kings 17:8-16 + Ev. Matt 23:1-12 + Com. peter-damien + +24 matthias + class-2 · red + Ep. Acts 1:15-26 + Ev. Matt 11:25-30 + Com. ef-lent-2-wednesday + +25 ef-lent-2-thursday + class-3 · violet + Ep. Jer 17:5-10 + Ev. Luke 16:19-31 + +26 ef-lent-2-friday + class-3 · violet + Ep. Gen 37:6-22 + Ev. Matt 21:33-46 + +27 ef-lent-2-saturday + class-3 · violet + Ep. Gen 27:6-40 + Ev. Luke 15:11-32 + Com. gabriel-of-our-lady-of-sorrows + +28 ef-lent-sunday-3 + class-1 · violet + Ep. Eph 5:1-9 + Ev. Luke 11:14-28 + + +Martius 2027 + +1 ef-lent-3-monday + class-3 · violet + Ep. 4 Kings 5:1-15 + Ev. Luke 4:23-30 + +2 ef-lent-3-tuesday + class-3 · violet + Ep. 4 Kings 4:1-7 + Ev. Matt 18:15-22 + +3 ef-lent-3-wednesday + class-3 · violet + Ep. Ex 20:12-24 + Ev. Matt 15:1-20 + +4 ef-lent-3-thursday + class-3 · violet + Ep. Jer 7:1-7 + Ev. Luke 4:38-44. + Com. casimir + Com. lucius + +5 ef-lent-3-friday + class-3 · violet + Ep. Num 20:1, 3; 6-13. + Ev. John 4:5-42 + +6 ef-lent-3-saturday + class-3 · violet + Ep. Dan 13:1-9, 15-17, 19-30, 33-62. + Ev. John 8:1-11 + Com. sts-felicitas-perpetua + +7 ef-lent-sunday-4 + class-1 · rose + Ep. Gal 4:22-31 + Ev. John 6:1-15 + +8 ef-lent-4-monday + class-3 · violet + Ep. 3 Kings 3:16-28 + Ev. John 2:13-25 + Com. john-of-god + +9 ef-lent-4-tuesday + class-3 · violet + Ep. Ex 32:7-14 + Ev. John 7:14-31 + Com. frances-rome + +10 ef-lent-4-wednesday + class-3 · violet + Ep. Isa. 1:16-19 + Ev. John 9:1-38 + Com. forty-holy-martyrs-of-sebaste + +11 ef-lent-4-thursday + class-3 · violet + Ep. 4 Kings 4:25-38 + Ev. Luke 7:11-16 + +12 ef-lent-4-friday + class-3 · violet + Ep. 3 Kings 17:17-24 + Ev. John 11:1-45 + Com. gregory-the-great + +13 ef-lent-4-saturday + class-3 · violet + Ep. Isa 49:8-15 + Ev. John 8:12-20 + +14 ef-passion-sunday + class-1 · violet + Ep. Heb 9:11-15. + Ev. John 8:46-59. + +15 ef-passiontide-1-monday + class-3 · violet + Ep. Jonas 3:1-10 + Ev. John 7:32-39 + +16 ef-passiontide-1-tuesday + class-3 · violet + Ep. Dan 14:27, 28-42 + Ev. John 7:1-13 + +17 ef-passiontide-1-wednesday + class-3 · violet + Ep. Lev 19:1-2, 11-19, 25 + Ev. John 10:22-38 + Com. patrick + +18 ef-passiontide-1-thursday + class-3 · violet + Ep. Dan 3:25, 34-45. + Ev. Luke 7:36-50 + Com. cyril-of-jerusalem + +19 joseph-spouse-of-the-bl-virgin-mary + class-1 · white + Ep. Ecclus 45:1-6 + Ev. Matt 1:18-21 + Com. ef-passiontide-1-friday + +20 ef-passiontide-1-saturday + class-3 · violet + Ep. Jer 18:18-23 + Ev. John 12:10-36 + +21 ef-palm-sunday + class-1 · violet + Ep. Phil 2:5-11 + Ev. Matt. 26:36-75; 27:1-60. + +22 ef-passiontide-2-monday + class-1 · violet + Ep. Isa 50:5-10 + Ev. John 12:1-9 + +23 ef-passiontide-2-tuesday + class-1 · violet + Ep. Jer 11:18-20 + Ev. Mark 14:32-72; 15, 1-46 + +24 ef-passiontide-2-wednesday + class-1 · violet + Ep. Isa 53:1-12 + Ev. Luke 22:39-71; 23:1-53 + +25 ef-passiontide-2-thursday + class-1 · white + Ep. 1 Cor 11:20-32 + Ev. John 13:1-15 + +26 ef-passiontide-2-friday + class-1 · black + Ep. Ex 12:1-11 + Ev. John 18:1-40; 19:1-42 + +27 ef-passiontide-2-saturday + class-1 · violet + Ep. Col 3:1-4 + Ev. Matt 28:1-7 + +28 ef-easter-sunday + class-1 · white + Ep. 1 Cor 5:7-8 + Ev. Mark 16:1-7 + +29 ef-easter-1-monday + class-1 · white + Ep. Acts 10:37-43. + Ev. Luke 24:13-35 + +30 ef-easter-1-tuesday + class-1 · white + Ep. Acts 13:16; 13:26-33 + Ev. Luke 24:36-47 + +31 ef-easter-1-wednesday + class-1 · white + Ep. Acts 3:13-15; 3:17-19 + Ev. John 21:1-14 + + +Aprilis 2027 + +1 ef-easter-1-thursday + class-1 · white + Ep. Acts 8:26-40 + Ev. John 20:11-18 + +2 ef-easter-1-friday + class-1 · white + Ep. 1 Pet 3:18-22 + Ev. Matt 28:16-20 + +3 ef-easter-1-saturday + class-1 · white + Ep. 1 Pet 2:1-10 + Ev. John 20:1-9 + +4 ef-low-sunday + class-1 · white + Ep. 1 John 5:4-10 + Ev. John 20:19-31 + +5 annunciation-of-the-blessed-virgin-mary + class-1 · white + Ep. Isa 7:10-15 + Ev. Luke 1:26-38 + +6 ef-easter-2-tuesday + class-4 · white + Ep. 1 John 5:4-10 + Ev. John 20:19-31 + +7 ef-easter-2-wednesday + class-4 · white + Ep. 1 John 5:4-10 + Ev. John 20:19-31 + +8 ef-easter-2-thursday + class-4 · white + Ep. 1 John 5:4-10 + Ev. John 20:19-31 + +9 ef-easter-2-friday + class-4 · white + Ep. 1 John 5:4-10 + Ev. John 20:19-31 + +10 ef-easter-2-saturday + class-4 · white + Ep. Ecclus 24:14-16 + Ev. John 19:25-27 + +11 ef-easter-sunday-3 + class-2 · white + Ep. 1 Pet 2:21-25 + Ev. John 10:11-16 + +12 ef-easter-3-monday + class-4 · white + Ep. 1 Pet 2:21-25 + Ev. John 10:11-16 + +13 hermenegild + class-3 · red + Ep. Wis 10:10-14 + Ev. Luke 14:26-33. + +14 justin + class-3 · red + Ep. 1 Cor 1:18-25; 1:30; + Ev. Luke 12:2-8 + Com. sts-tiburtius-valerian-et-maximus-martyrs + +15 ef-easter-3-thursday + class-4 · white + Ep. 1 Pet 2:21-25 + Ev. John 10:11-16 + +16 ef-easter-3-friday + class-4 · white + Ep. 1 Pet 2:21-25 + Ev. John 10:11-16 + +17 ef-easter-3-saturday + class-4 · white + Ep. Ecclus 24:14-16 + Ev. John 19:25-27 + Com. anicetus + +18 ef-easter-sunday-4 + class-2 · white + Ep. 1 Pet 2:11-19 + Ev. John 16:16-22 + +19 ef-easter-4-monday + class-4 · white + Ep. 1 Pet 2:11-19 + Ev. John 16:16-22 + +20 ef-easter-4-tuesday + class-4 · white + Ep. 1 Pet 2:11-19 + Ev. John 16:16-22 + +21 anselm + class-3 · white + Ep. 2 Tim 4:1-8 + Ev. Matt 5:13-19 + +22 sts-soter-caius + class-3 · red + Ep. 1 Pet 5:1-4; 5:10-11. + Ev. Matt 16:13-19 + +23 ef-easter-4-friday + class-4 · white + Ep. 1 Pet 2:11-19 + Ev. John 16:16-22 + Com. george + +24 fidelis-of-sigmaringen + class-3 · red + Ep. Wis 5:1-5 + Ev. John 15:1-7 + +25 ef-easter-sunday-5 + class-2 · white + Ep. Jas 1:17-21 + Ev. John 16:5-14 + Com. major-litanies + +26 sts-cletus-marcellinus + class-3 · red + Ep. 1 Pet 5:1-4; 5:10-11. + Ev. Matt 16:13-19 + +27 peter-canisius + class-3 · white + Ep. 2 Tim 4:1-8 + Ev. Matt 5:13-19 + +28 paul-of-the-cross + class-3 · white + Ep. 1 Cor 1:17-25. + Ev. Luke 10:1-9 + +29 peter-of-verona + class-3 · red + Ep. 2 Tim. 2:8-10; 3:10-12. + Ev. Matt 10:34-42 + +30 catherine-of-siena + class-3 · white + Ep. 2 Cor 10:17-18; 11:1-2 + Ev. Matt 25:1-13. + + +Maius 2027 + +1 joseph-the-workman + class-1 · white + Ep. Col. 3:14-15, 17, 23-24 + Ev. Matt 13:54-58 + +2 ef-easter-sunday-6 + class-2 · white + Ep. Jas 1:22-27 + Ev. John 16:23-30 + +3 ef-rogation-monday + class-4 · violet + Ep. Jas 1:22-27 + Ev. John 16:23-30 + Com. sts-alexander-companions + +4 monica + class-3 · white + Ep. 1 Tim. 5:3-10. + Ev. Luke 7:11-16 + +5 ef-ascension-vigil + class-2 · white + Ep. Eph. 4:7-13. + Ev. John 17:1-11. + Com. pius-v + +6 ef-ascension + class-1 · white + Ep. Acts 1:1-11 + Ev. Mark 16:14-20 + +7 stanislaus + class-3 · red + Ep. Wis 5:1-5 + Ev. John 15:1-7 + +8 ef-easter-6-saturday + class-4 · white + Ep. Ecclus 24:14-16 + Ev. John 19:25-27 + +9 ef-easter-sunday-7 + class-2 · white + Ep. 1 Pet 4:7-11. + Ev. John 15:26-27; 16:1-4. + +10 antoninus + class-3 · white + Ep. Sir 44:16-27; 45:3-20 + Ev. Matt 25:14-23 + Com. gordiano-and-epimacho + +11 sts-philip-james + class-2 · red + Ep. Wis. 5:1-5 + Ev. John 14:1-13 + +12 sts-nereus-achilleus-domitilla-pancras + class-3 · red + Ep. Wis. 5:1-5 + Ev. John 4:46-53 + +13 robert-bellarmine + class-3 · white + Ep. Wis 7:7-14. + Ev. Matt 5:13-19 + +14 ef-easter-7-friday + class-4 · white + Ep. 1 Pet 4:7-11. + Ev. John 15:26-27; 16:1-4. + Com. boniface-martyr + +15 ef-pentecost-vigil + class-1 · red + Ep. Acts 19:1-8. + Ev. John 14:15-21. + +16 ef-pentecost + class-1 · red + Ep. Acts 2:1-11. + Ev. John 14:23-31. + +17 ef-easter-8-monday + class-1 · red + Ep. Acts 10:34, 42-48 + Ev. John 3:16-21 + +18 ef-easter-8-tuesday + class-1 · red + Ep. Acts 8:14-17. + Ev. John 10:1-10. + +19 ef-pentecost-ember-wed + class-1 · red + Ep. Acts 5:12-16 + Ev. John 6:44-52. + +20 ef-easter-8-thursday + class-1 · red + Ep. Acts 8:5-8 + Ev. Luke 9:1-6 + +21 ef-pentecost-ember-fri + class-1 · red + Ep. Joel 2:23-24; 26-27 + Ev. Luke 5:17-26 + +22 ef-pentecost-ember-sat + class-1 · red + Ep. Rom 5:1-5. + Ev. Luke 4:38-44. + +23 ef-trinity + class-1 · white + Ep. Rom 11:33-36. + Ev. Matt 28:18-20 + +24 ef-time-after-pentecost-1-monday + class-4 · green + Ep. 1 John 4:8-21 + Ev. Luke 6:36-42 + +25 gregory-vii + class-3 · white + Ep. 1 Pet 5:1-4; 5:10-11. + Ev. Matt 16:13-19 + Com. urban-pope-and-martyr + +26 philip-neri + class-3 · white + Ep. Wis 7:7-14. + Ev. Luke 12:35-40 + Com. eleutherius + +27 ef-corpus-christi + class-1 · white + Ep. 1 Cor 11:23-29 + Ev. John 6:56-59 + +28 augustine-of-canterbury + class-3 · white + Ep. 1 Thess 2:2-9 + Ev. Luke 10:1-9 + +29 mary-magdalene-de-pazzi + class-3 · white + Ep. 2 Cor 10:17-18; 11:1-2 + Ev. Matt 25:1-13. + +30 ef-time-after-pentecost-sunday-2 + class-2 · green + Ep. 1 John 3:13-18. + Ev. Luke 14:16-24. + +31 queenship-of-the-blessed-virgin-mary + class-2 · white + Ep. Eccli 24:5; 14:7; 14:9-11; 24:30-31 + Ev. Luke 1:26-33 + Com. petronilla + + +Iunius 2027 + +1 angela-merici + class-3 · white + Ep. 2 Cor 10:17-18; 11:1-2 + Ev. Matt 25:1-13. + +2 ef-time-after-pentecost-2-wednesday + class-4 · green + Ep. 1 John 3:13-18. + Ev. Luke 14:16-24. + Com. sts-marcellinus-peter-erasmus + +3 ef-time-after-pentecost-2-thursday + class-4 · green + Ep. 1 John 3:13-18. + Ev. Luke 14:16-24. + +4 ef-sacred-heart + class-1 · white + Ep. Eph 3:8-12, 14-19 + Ev. John 19:31-37 + +5 boniface + class-3 · red + Ep. Ecclus 44:1-15 + Ev. Matt 5:1-12 + +6 ef-time-after-pentecost-sunday-3 + class-2 · green + Ep. 1 Pet. 5:6-11 + Ev. Luke 15:1-10 + +7 ef-time-after-pentecost-3-monday + class-4 · green + Ep. 1 Pet. 5:6-11 + Ev. Luke 15:1-10 + +8 ef-time-after-pentecost-3-tuesday + class-4 · green + Ep. 1 Pet. 5:6-11 + Ev. Luke 15:1-10 + +9 ef-time-after-pentecost-3-wednesday + class-4 · green + Ep. 1 Pet. 5:6-11 + Ev. Luke 15:1-10 + Com. sts-primus-felicianus + +10 margaret-of-scotland + class-3 · white + Ep. Prov 31:10-31 + Ev. Matt 13:44-52. + +11 barnabas + class-3 · red + Ep. Acts 11:21-26; 13:1-3 + Ev. Matt 10:16-22 + +12 john-of-san-fecundo + class-3 · white + Ep. Sir 31:8-11 + Ev. Luke 12:35-40 + Com. basilidus + +13 ef-time-after-pentecost-sunday-4 + class-2 · green + Ep. Rom 8:18-23 + Ev. Luke 5:1-11 + +14 basil-the-great + class-3 · white + Ep. 2 Tim 4:1-8 + Ev. Luke 14:26-35 + +15 ef-time-after-pentecost-4-tuesday + class-4 · green + Ep. Rom 8:18-23 + Ev. Luke 5:1-11 + Com. vitus + +16 ef-time-after-pentecost-4-wednesday + class-4 · green + Ep. Rom 8:18-23 + Ev. Luke 5:1-11 + +17 gregory-barbarigo + class-3 · white + Ep. Sir 44:16-27; 45:3-20 + Ev. Matt 25:14-23 + +18 ephrem-of-syria + class-3 · white + Ep. 2 Tim 4:1-8 + Ev. Matt 5:13-19 + Com. marcus-and-marcellianus + +19 julia-of-falconieri + class-3 · white + Ep. 2 Cor 10:17-18; 11:1-2 + Ev. Matt 25:1-13. + Com. sts-gervasius-and-protasius + +20 ef-time-after-pentecost-sunday-5 + class-2 · green + Ep. 1 Pet 3:8-15. + Ev. Matt 5:20-24. + +21 aloysius-gongzaga + class-3 · white + Ep. Sir 31:8-11 + Ev. Matt 22:29-40 + +22 paulinus-of-nola + class-3 · white + Ep. 2 Cor. 8:9-15 + Ev. Luke 12:32-34 + +23 vigil-of-the-nativity-of-st-john-the-baptist + class-2 · violet + Ep. Jer 1:4-10 + Ev. Luke 1:5-17 + +24 nativity-of-st-john-the-baptist + class-1 · white + Ep. Isa 49:1-3, 5-7. + Ev. Luke 1:57-68 + +25 william + class-3 · white + Ep. Ecclus 45:1-6 + Ev. Matt 19:27-29. + +26 sts-john-paul + class-3 · red + Ep. Eccli 44:10-15 + Ev. Luke 12:1-8 + +27 ef-time-after-pentecost-sunday-6 + class-2 · green + Ep. Rom 6:3-11. + Ev. Mark 8:1-9 + +28 vigil-of-sts-peter-paul + class-2 · violet + Ep. Acts 3:1-10 + Ev. John 21:15-19 + +29 sts-peter-paul + class-1 · red + Ep. Acts 12:1-11 + Ev. Matt 16:13-19 + +30 in-commemoratione-sancti-pauli-apostoli + class-3 · red + Ep. Gal 1:11-20 + Ev. Matt 10:16-22 + Com. commemoration-of-st-peter + + +Iulius 2027 + +1 precious-blood-of-our-lord-jesus-christ + class-1 · red + Ep. Heb 9:11-15. + Ev. John 19:30-35 + +2 visitation-of-the-blessed-virgin-mary + class-2 · white + Ep. Song 2:8-14 + Ev. Luke 1:39-47 + Com. processus-and-martinian + +3 irenaeus + class-3 · red + Ep. 2 Tim. 3:14-17; 4:1-5 + Ev. Matt 10:28-33 + +4 ef-time-after-pentecost-sunday-7 + class-2 · green + Ep. Rom 6:19-23 + Ev. Matt 7:15-21 + +5 anthony-mary-zaccariah + class-3 · white + Ep. 1 Tim. 4:8-16 + Ev. Mark 10:15-21 + +6 ef-time-after-pentecost-7-tuesday + class-4 · green + Ep. Rom 6:19-23 + Ev. Matt 7:15-21 + +7 sts-cyril-methodius + class-3 · white + Ep. Heb 7:23-27 + Ev. Luke 10:1-9 + +8 elizabeth-of-portugal + class-3 · white + Ep. Prov 31:10-31 + Ev. Matt 13:44-52. + +9 ef-time-after-pentecost-7-friday + class-4 · green + Ep. Rom 6:19-23 + Ev. Matt 7:15-21 + +10 seven-holy-brothers-and-sts-rufina-secunda + class-3 · red + Ep. Prov 31:10-31 + Ev. Matt 12:46-50 + +11 ef-time-after-pentecost-sunday-8 + class-2 · green + Ep. Rom 8:12-17 + Ev. Luke 16:1-9 + +12 john-gualbert + class-3 · white + Ep. Ecclus 45:1-6 + Ev. Matt 5:43-48 + Com. naboris-et-felicis + +13 ef-time-after-pentecost-8-tuesday + class-4 · green + Ep. Rom 8:12-17 + Ev. Luke 16:1-9 + +14 bonaventure + class-3 · white + Ep. 2 Tim 4:1-8 + Ev. Matt 5:13-19 + +15 henry-the-emperor + class-3 · white + Ep. Sir 31:8-11 + Ev. Luke 12:35-40 + +16 ef-time-after-pentecost-8-friday + class-4 · green + Ep. Rom 8:12-17 + Ev. Luke 16:1-9 + Com. our-lady-of-mt-carmel + +17 ef-time-after-pentecost-8-saturday + class-4 · white + Ep. Ecclus 24:14-16 + Ev. Luke 11:27-28 + Com. alexis + +18 ef-time-after-pentecost-sunday-9 + class-2 · green + Ep. 1 Cor. 10:6-13 + Ev. Luke 19:41-47 + +19 vincent-de-paul + class-3 · white + Ep. 1 Cor. 4:9-14 + Ev. Luke 10:1-9 + +20 jerome-emiliani + class-3 · white + Ep. Isa 58:7-11 + Ev. Matt 19:13-21 + Com. margaret + +21 laurence-of-brindisi + class-3 · white + Ep. 2 Tim 4:1-8 + Ev. Matt 5:13-19 + Com. praxedis-virginis + +22 mary-magdalene + class-3 · white + Ep. Song 3:2-5; 8:6-7 + Ev. Luke 7:36-50 + +23 apollinaris + class-3 · red + Ep. 1 Pet. 5:1-11 + Ev. Luke 22:24-30 + Com. liborii + +24 ef-time-after-pentecost-9-saturday + class-4 · white + Ep. Ecclus 24:14-16 + Ev. Luke 11:27-28 + Com. christina + +25 ef-time-after-pentecost-sunday-10 + class-2 · green + Ep. 1 Cor. 12:2-11 + Ev. Luke 18:9-14 + Com. james-the-greater + +26 anne-mother-of-the-blessed-virgin + class-2 · white + Ep. Prov 31:10-31 + Ev. Matt 13:44-52. + +27 ef-time-after-pentecost-10-tuesday + class-4 · green + Ep. 1 Cor. 12:2-11 + Ev. Luke 18:9-14 + Com. pantaleon + +28 sts-nazarius-celsus-st-victor-i-st-innocent-i + class-3 · red + Ep. Wis 10:17-20 + Ev. Luke 21:9-19 + +29 martha + class-3 · white + Ep. 2 Cor 10:17-18; 11:1-2 + Ev. Luke 10:38-42 + Com. felicis-simplicii-faustini-et-beatricis + +30 ef-time-after-pentecost-10-friday + class-4 · green + Ep. 1 Cor. 12:2-11 + Ev. Luke 18:9-14 + Com. sts-abdon-sennen + +31 ignatius-loyola + class-3 · white + Ep. 2 Tim. 2:8-10; 3:10-12. + Ev. Luke 10:1-9 + + +Augustus 2027 + +1 ef-time-after-pentecost-sunday-11 + class-2 · green + Ep. 1 Cor. 15:1-10 + Ev. Mark 7:31-37 + +2 alphonsus-liguori + class-3 · white + Ep. 2 Tim. 2:1-7 + Ev. Luke 10:1-9 + Com. stephen-i-pope-and-martyr + +3 ef-time-after-pentecost-11-tuesday + class-4 · green + Ep. 1 Cor. 15:1-10 + Ev. Mark 7:31-37 + +4 dominic + class-3 · white + Ep. 2 Tim. 4:1-8 + Ev. Luke 12:35-40 + +5 dedication-of-the-basilica-of-st-mary-major + class-3 · white + Ep. Ecclus 24:14-16 + Ev. Luke 11:27-28 + +6 transfiguration-of-our-lord + class-2 · white + Ep. 2 Pet. 1:16-19 + Ev. Matt 17:1-9 + Com. pope-sixtus-ii-felicissimus-and-agapitus-martyrs + +7 cajetan + class-3 · white + Ep. Sir 31:8-11 + Ev. Matt 6:24-33 + Com. donatus + +8 ef-time-after-pentecost-sunday-12 + class-2 · green + Ep. 2 Cor. 3:4-9 + Ev. Luke 10:23-37 + +9 vigil-of-st-lawrence + class-3 · violet + Ep. Ecclus 51:1-8, 12 + Ev. Matt 16:24-27 + Com. romanus + +10 lawrence + class-2 · red + Ep. 2 Cor. 9:6-10 + Ev. John 12:24-26 + +11 ef-time-after-pentecost-12-wednesday + class-4 · green + Ep. 2 Cor. 3:4-9 + Ev. Luke 10:23-37 + Com. sts-tiburtius-susanna + +12 clare + class-3 · white + Ep. 2 Cor 10:17-18; 11:1-2 + Ev. Matt 25:1-13. + +13 ef-time-after-pentecost-12-friday + class-4 · green + Ep. 2 Cor. 3:4-9 + Ev. Luke 10:23-37 + Com. sts-hippolytus-cassian + +14 vigil-of-the-assumption + class-2 · violet + Ep. Sir 24:23-31 + Ev. Luke 11:27-28 + Com. eusebius-confessor + +15 assumption-of-the-blessed-virgin-mary + class-1 · white + Ep. Judith 13:22-25; 15:10 + Ev. Luke 1:41-50 + Com. ef-time-after-pentecost-sunday-13 + +16 joachim-father-of-the-blessed-virgin + class-2 · white + Ep. Sir 31:8-11 + Ev. Matt 1:1-16 + +17 hyacinth + class-3 · white + Ep. Sir 31:8-11 + Ev. Luke 12:35-40 + +18 ef-time-after-pentecost-13-wednesday + class-4 · green + Ep. Gal 3:16-22 + Ev. Luke 17:11-19 + Com. agapitus + +19 john-eudes + class-3 · white + Ep. Sir 31:8-11 + Ev. Luke 12:35-40 + +20 bernard-of-clairvaux + class-3 · white + Ep. Ecclus 39:6-14 + Ev. Matt 5:13-19 + +21 jane-frances-de-chantal + class-3 · white + Ep. Prov 31:10-31 + Ev. Matt 13:44-52. + +22 ef-time-after-pentecost-sunday-14 + class-2 · green + Ep. Gal 5:16-24 + Ev. Matt 6:24-33 + Com. immaculate-heart-of-mary + +23 philip-benizi + class-3 · white + Ep. 1 Cor. 4:9-14 + Ev. Luke 12:32-34 + +24 bartholomew + class-2 · red + Ep. 1 Cor. 12:27-31 + Ev. Luke 6:12-19 + +25 louis-ix + class-3 · white + Ep. Wis 10:10-14 + Ev. Luke 19:12-26 + +26 ef-time-after-pentecost-14-thursday + class-4 · green + Ep. Gal 5:16-24 + Ev. Matt 6:24-33 + Com. zephyrinus + +27 joseph-calasance + class-3 · white + Ep. Wis 10:10-14 + Ev. Matt 18:1-5 + +28 augustine + class-3 · white + Ep. 2 Tim 4:1-8 + Ev. Matt 5:13-19 + Com. hermes + +29 ef-time-after-pentecost-sunday-15 + class-2 · green + Ep. Gal 5:25-26; 6:1-10 + Ev. Luke 7:11-16 + +30 rose-of-lima + class-3 · white + Ep. 2 Cor 10:17-18; 11:1-2 + Ev. Matt 25:1-13. + Com. sts-felix-and-adauctus + +31 raymond-nonnatus + class-3 · white + Ep. Sir 31:8-11 + Ev. Luke 12:35-40 + + +September 2027 + +1 ef-time-after-pentecost-15-wednesday + class-4 · green + Ep. Gal 5:25-26; 6:1-10 + Ev. Luke 7:11-16 + Com. giles + Com. twelve-holy-brothers-martyrs + +2 stephen-of-hungary + class-3 · white + Ep. Sir 31:8-11 + Ev. Luke 19:12-26 + +3 pius-x + class-3 · white + Ep. 1 Thess. 2:2-8 + Ev. John 21:15-17 + +4 ef-time-after-pentecost-15-saturday + class-4 · white + Ep. Ecclus 24:14-16 + Ev. Luke 11:27-28 + +5 ef-time-after-pentecost-sunday-16 + class-2 · green + Ep. Eph 3:13-21 + Ev. Luke 14:1-11 + +6 ef-time-after-pentecost-16-monday + class-4 · green + Ep. Eph 3:13-21 + Ev. Luke 14:1-11 + +7 ef-time-after-pentecost-16-tuesday + class-4 · green + Ep. Eph 3:13-21 + Ev. Luke 14:1-11 + +8 nativity-of-the-blessed-virgin-mary + class-2 · white + Ep. Prov 8:22-35 + Ev. Matt 1:1-16 + Com. hadriani + +9 ef-time-after-pentecost-16-thursday + class-4 · green + Ep. Eph 3:13-21 + Ev. Luke 14:1-11 + Com. gorgonius + +10 nicholas-of-tolentino + class-3 · white + Ep. 1 Cor. 4:9-14 + Ev. Luke 12:32-34 + +11 ef-time-after-pentecost-16-saturday + class-4 · white + Ep. Ecclus 24:14-16 + Ev. Luke 11:27-28 + Com. sts-protus-hyacinth + +12 ef-time-after-pentecost-sunday-17 + class-2 · green + Ep. Eph 4:1-6 + Ev. Matt 22:34-46 + +13 ef-time-after-pentecost-17-monday + class-4 · green + Ep. Eph 4:1-6 + Ev. Matt 22:34-46 + +14 exaltation-of-the-holy-cross + class-2 · red + Ep. Phil 2:5-11 + Ev. John 12:31-36 + +15 seven-sorrows-of-the-blessed-virgin-mary + class-2 · white + Ep. Judith 13:22; 13:23-25 + Ev. John 19:25-27 + Com. nicomedes + +16 sts-cornelius-cyprian + class-3 · red + Ep. Wis 3:1-8 + Ev. Luke 21:9-19 + Com. sts-euphemia-lucy-and-geminianus + +17 ef-time-after-pentecost-17-friday + class-4 · green + Ep. Eph 4:1-6 + Ev. Matt 22:34-46 + Com. stigmata-of-st-francis + +18 joseph-of-cupertino + class-3 · white + Ep. 1 Cor 13:1-8 + Ev. Matt 22:1-14 + +19 ef-time-after-pentecost-sunday-18 + class-2 · green + Ep. 1 Cor. 1:4-8 + Ev. Matt 9:1-8 + +20 ef-time-after-pentecost-18-monday + class-4 · green + Ep. 1 Cor. 1:4-8 + Ev. Matt 9:1-8 + Com. sts-eustace-companions + +21 matthew + class-2 · red + Ep. Ezek 1:10-14 + Ev. Matt 9:9-13 + +22 ef-september-ember-wed + class-2 · violet + Ep. 2 Esd. 8:1-10 + Ev. Mark 9:16-28 + Com. thomas-of-villanova + +23 linus + class-3 · red + Ep. 1 Pet 5:1-4; 5:10-11. + Ev. Matt 16:13-19 + Com. thecla + +24 ef-september-ember-fri + class-2 · violet + Ep. Osee 14:2-10 + Ev. Luke 7:36-50 + Com. our-lady-of-ransom + +25 ef-september-ember-sat + class-2 · violet + Ep. Heb 9:2-12 + Ev. Luke 13:6-17 + +26 ef-time-after-pentecost-sunday-19 + class-2 · green + Ep. Eph 4:23-28 + Ev. Matt 22:1-14 + +27 sts-cosmas-damian + class-3 · red + Ep. Wis 5:16-20 + Ev. Luke 6:17-23 + +28 wenceslaus + class-3 · red + Ep. Wis 10:10-14 + Ev. Matt 10:34-42 + +29 dedication-of-st-michael-the-archangel + class-1 · white + Ep. Rev 1:1-5 + Ev. Matt 18:1-10 + +30 jerome + class-3 · white + Ep. 2 Tim 4:1-8 + Ev. Matt 5:13-19 + + +October 2027 + +1 ef-time-after-pentecost-19-friday + class-4 · green + Ep. Eph 4:23-28 + Ev. Matt 22:1-14 + Com. remigius + +2 holy-guardian-angels + class-3 · white + Ep. Exod 23:20-23 + Ev. Matt 18:1-10 + +3 ef-time-after-pentecost-sunday-20 + class-2 · green + Ep. Eph 5:15-21 + Ev. John 4:46-53 + +4 francis-of-assisi + class-3 · white + Ep. Gal 6:14-18 + Ev. Matt 11:25-30 + +5 ef-time-after-pentecost-20-tuesday + class-4 · green + Ep. Eph 5:15-21 + Ev. John 4:46-53 + Com. placid-companions + +6 bruno + class-3 · white + Ep. Sir 31:8-11 + Ev. Luke 12:35-40 + +7 our-lady-of-the-rosary + class-2 · white + Ep. Prov 8:22-24, 32-35. + Ev. Luke 1:26-38 + Com. mark-i + +8 bridget-of-sweden + class-3 · white + Ep. 1 Tim. 5:3-10. + Ev. Matt 13:44-52. + Com. sergio-baccho-marcello-and-apulejo-martyrs + +9 john-leonardi + class-3 · white + Ep. 2 Cor 4:1-6; 4:15-18 + Ev. Luke 10:1-9 + Com. dionysius-and-companions + +10 ef-time-after-pentecost-sunday-21 + class-2 · green + Ep. Eph 6:10-17 + Ev. Matt 18:23-35 + +11 maternity-of-the-blessed-virgin-mary + class-2 · white + Ep. Sir 24:23-31 + Ev. Luke 2:43-51 + +12 ef-time-after-pentecost-21-tuesday + class-4 · green + Ep. Eph 6:10-17 + Ev. Matt 18:23-35 + +13 edward + class-3 · white + Ep. Sir 31:8-11 + Ev. Luke 12:35-40 + +14 callistus-i + class-3 · red + Ep. 1 Pet 5:1-4; 5:10-11. + Ev. Matt 16:13-19 + +15 teresa-of-avila + class-3 · white + Ep. 2 Cor 10:17-18; 11:1-2 + Ev. Matt 25:1-13. + +16 hedwig + class-3 · white + Ep. Prov 31:10-31 + Ev. Matt 13:44-52. + +17 ef-time-after-pentecost-sunday-22 + class-2 · green + Ep. Phil 1:6-11 + Ev. Matt 22:15-21 + +18 luke-the-evangelist + class-2 · red + Ep. 2 Cor. 8:16-24 + Ev. Luke 10:1-9 + +19 peter-of-alcantara + class-3 · white + Ep. Phil 3:7-12 + Ev. Luke 12:32-34 + +20 john-cantius + class-3 · white + Ep. James 2:12-17 + Ev. Luke 12:35-40 + +21 ef-time-after-pentecost-22-thursday + class-4 · green + Ep. Phil 1:6-11 + Ev. Matt 22:15-21 + Com. hilarion + Com. ursula-and-companions + +22 ef-time-after-pentecost-22-friday + class-4 · green + Ep. Phil 1:6-11 + Ev. Matt 22:15-21 + +23 anthony-mary-claret + class-3 · white + Ep. Heb 7:23-27 + Ev. Matt 24:42-47 + +24 ef-time-after-pentecost-sunday-23 + class-2 · green + Ep. Phil 3:17-21; 4:1-3 + Ev. Matt 9:18-26 + +25 ef-time-after-pentecost-23-monday + class-4 · green + Ep. Phil 3:17-21; 4:1-3 + Ev. Matt 9:18-26 + Com. sts-chrysanthus-daria + +26 ef-time-after-pentecost-23-tuesday + class-4 · green + Ep. Phil 3:17-21; 4:1-3 + Ev. Matt 9:18-26 + Com. evaristus + +27 ef-time-after-pentecost-23-wednesday + class-4 · green + Ep. Phil 3:17-21; 4:1-3 + Ev. Matt 9:18-26 + +28 sts-simon-jude + class-2 · red + Ep. Eph. 4:7-13. + Ev. John 15:17-25 + +29 ef-time-after-pentecost-23-friday + class-4 · green + Ep. Phil 3:17-21; 4:1-3 + Ev. Matt 9:18-26 + +30 ef-time-after-pentecost-23-saturday + class-4 · white + Ep. Ecclus 24:14-16 + Ev. Luke 11:27-28 + +31 ef-christ-the-king + class-1 · white + Ep. Col 1:12-20. + Ev. John 18:33-37 + + +November 2027 + +1 all-saints + class-1 · white + Ep. Apoc 7:2-12 + Ev. Matt 5:1-12 + +2 commemoration-of-all-souls + class-1 · black + Ep. 1 Cor. 15:51-57 + Ev. John 5:25-29 + +3 ef-time-after-pentecost-24-wednesday + class-4 · green + Ep. Col 1:12-20. + Ev. John 18:33-37 + +4 charles-borromeo + class-3 · white + Ep. Sir 44:16-27; 45:3-20 + Ev. Matt 25:14-23 + Com. sts-vitalis-and-agricola-martyrs + +5 ef-time-after-pentecost-24-friday + class-4 · green + Ep. Col 1:12-20. + Ev. John 18:33-37 + +6 ef-time-after-pentecost-24-saturday + class-4 · white + Ep. Ecclus 24:14-16 + Ev. Luke 11:27-28 + +7 ef-time-after-epiphany-sunday-5 + class-2 · green + Ep. Col 3:12-17 + Ev. Matt 13:24-30 + +8 ef-time-after-pentecost-25-monday + class-4 · green + Ep. Col 3:12-17 + Ev. Matt 13:24-30 + Com. four-holy-crowned-martyrs + +9 dedication-of-the-archbasilica-of-our-holy-savior + class-2 · white + Ep. Rev 21:2-5 + Ev. Luke 19:1-10 + Com. theodore + +10 andrew-avellino + class-3 · white + Ep. Sir 31:8-11 + Ev. Luke 12:35-40 + Com. sts-tryphonis-respicii-et-nymphae + +11 martin-of-tours + class-3 · white + Ep. Sir 44:16-27; 45:3-20 + Ev. Luke 11:33-36 + Com. menna + +12 martin-i + class-3 · red + Ep. 1 Pet 5:1-4; 5:10-11. + Ev. Matt 16:13-19 + +13 didacus + class-3 · white + Ep. 1 Cor 4:9-14 + Ev. Luke 12:32-34 + +14 ef-time-after-epiphany-sunday-6 + class-2 · green + Ep. 1 Thess 1:2-10 + Ev. Matt 13:31-35 + +15 albert-the-great + class-3 · white + Ep. 2 Tim 4:1-8 + Ev. Matt 5:13-19 + +16 gertrude-the-great + class-3 · white + Ep. 2 Cor 10:17-18; 11:1-2 + Ev. Matt 25:1-13. + +17 gregory-the-wonderworker + class-3 · white + Ep. Sir 44:16-27; 45:3-20 + Ev. Mark 11:22-24 + +18 dedication-of-the-basilicas-of-sts-peter-paul + class-3 · white + Ep. Rev 21:2-5 + Ev. Luke 19:1-10 + +19 elizabeth-of-hungary + class-3 · white + Ep. Prov 31:10-31 + Ev. Matt 13:44-52. + Com. pontian + +20 felix-of-valois + class-3 · white + Ep. 1 Cor. 4:9-14 + Ev. Luke 12:32-34 + +21 ef-time-after-pentecost-sunday-24 + class-2 · green + Ep. Col 1:9-14 + Ev. Matt 24:15-35 + +22 cecilia + class-3 · red + Ep. Sir 51:13-17. + Ev. Matt 25:1-13. + +23 clement-i + class-3 · red + Ep. Phil 3:17-21; 4:1-3 + Ev. Matt 16:13-19 + Com. felicity + +24 john-of-the-cross + class-3 · white + Ep. 2 Tim 4:1-8 + Ev. Matt 5:13-19 + Com. chrysogonus + +25 catherine-of-alexandria + class-3 · red + Ep. Sir 51:1-8; 51:12 + Ev. Matt 25:1-13. + +26 sylvester + class-3 · white + Ep. Ecclus 45:1-6 + Ev. Matt 19:27-29. + Com. peter-of-alexandria + +27 ef-time-after-pentecost-27-saturday + class-4 · white + Ep. Ecclus 24:14-16 + Ev. Luke 11:27-28 + +28 ef-advent-sunday-1 + class-1 · violet + Ep. Rom 13:11-14 + Ev. Luke 21:25-33 + +29 ef-advent-1-monday + class-3 · violet + Ep. Rom 13:11-14 + Ev. Luke 21:25-33 + Com. saturninus + +30 andrew + class-2 · red + Ep. Rom 10:10-18 + Ev. Matt 4:18-22 + Com. ef-advent-1-tuesday + + +December 2027 + +1 ef-advent-1-wednesday + class-3 · violet + Ep. Rom 13:11-14 + Ev. Luke 21:25-33 + +2 vivian + class-3 · red + Ep. Sir 51:13-17. + Ev. Matt 13:44-52. + Com. ef-advent-1-thursday + +3 francis-xavier + class-3 · white + Ep. Rom 10:10-18 + Ev. Mark 16:15-18 + Com. ef-advent-1-friday + +4 peter-chrysologus + class-3 · white + Ep. 2 Tim 4:1-8 + Ev. Matt 5:13-19 + Com. ef-advent-1-saturday + Com. barbara + +5 ef-advent-sunday-2 + class-1 · violet + Ep. Rom 15:4-13 + Ev. Matt 11:2-10 + +6 nicholas + class-3 · white + Ep. Heb 13:7-17 + Ev. Matt 25:14-23 + Com. ef-advent-2-monday + +7 ambrose + class-3 · white + Ep. 2 Tim 4:1-8 + Ev. Matt 5:13-19 + Com. ef-advent-2-tuesday + +8 immaculate-conception-of-the-blessed-virgin-mary + class-1 · white + Ep. Prov 8:22-35 + Ev. Luke 1:26-28 + Com. ef-advent-2-wednesday + +9 ef-advent-2-thursday + class-3 · violet + Ep. Rom 15:4-13 + Ev. Matt 11:2-10 + +10 ef-advent-2-friday + class-3 · violet + Ep. Rom 15:4-13 + Ev. Matt 11:2-10 + Com. melchiades + +11 damasus-i + class-3 · white + Ep. 1 Pet 5:1-4; 5:10-11. + Ev. Matt 16:13-19 + Com. ef-advent-2-saturday + +12 ef-advent-sunday-3 + class-1 · rose + Ep. Phil 4:4-7 + Ev. John 1:19-28 + +13 lucy + class-3 · red + Ep. 2 Cor 10:17-18; 11:1-2 + Ev. Matt 13:44-52. + Com. ef-advent-3-monday + +14 ef-advent-3-tuesday + class-3 · violet + Ep. Phil 4:4-7 + Ev. John 1:19-28 + +15 ef-advent-ember-wed + class-2 · violet + Ep. Isa 7:10-15 + Ev. Luke 1:26-38 + +16 eusebius + class-3 · red + Ep. 2 Cor. 1:3-7 + Ev. Matt 16:24-27. + Com. ef-advent-3-thursday + +17 ef-advent-ember-fri + class-2 · violet + Ep. Isa 11:1-5 + Ev. Luke 1:39-47 + +18 ef-advent-ember-sat + class-2 · violet + Ep. 2 Thess 2:1-8 + Ev. Luke 3:1-6 + +19 ef-advent-sunday-4 + class-1 · violet + Ep. 1 Cor. 4:1-5 + Ev. Luke 3:1-6 + +20 ef-advent-4-monday + class-2 · violet + Ep. 1 Cor. 4:1-5 + Ev. Luke 3:1-6 + +21 thomas + class-2 · red + Ep. Eph 2:19-22 + Ev. John 20:24-29 + Com. ef-advent-4-tuesday + +22 ef-advent-4-wednesday + class-2 · violet + Ep. 1 Cor. 4:1-5 + Ev. Luke 3:1-6 + +23 ef-advent-4-thursday + class-2 · violet + Ep. 1 Cor. 4:1-5 + Ev. Luke 3:1-6 + +24 ef-nativity-vigil + class-1 · violet + Ep. Rom 1:1-6 + Ev. Matt 1:18-21 + +25 ef-nativity + class-1 · white + Ep. Heb 1:1-12 + Ev. John 1:1-14 + +26 ef-christmas-sunday-0 + class-2 · white + Ep. Gal 4:1-7 + Ev. Luke 2:33-40 + Com. stephen + +27 john-the-evangelist + class-2 · white + Ep. Ecclus 15:1-6 + Ev. John 21:19-24 + Com. ef-nativity-octave-day-3 + +28 holy-innocents + class-2 · red + Ep. Apoc 14:1-5 + Ev. Matt 2:13-18 + Com. ef-nativity-octave-day-4 + +29 ef-nativity-octave-day-5 + class-2 · white + Ep. Titus 3:4-7 + Ev. Luke 2:15-20 + Com. thomas-becket + +30 ef-nativity-octave-day-6 + class-2 · white + Ep. Titus 3:4-7 + Ev. Luke 2:15-20 + +31 ef-nativity-octave-day-7 + class-2 · white + Ep. Titus 3:4-7 + Ev. Luke 2:15-20 + Com. silvester + + diff --git a/test/test_colitur.ml b/test/test_colitur.ml index 76ff685..04bbdee 100644 --- a/test/test_colitur.ml +++ b/test/test_colitur.ml @@ -6,4 +6,12 @@ let () = Test_calendar.suite; Test_precedence_ef.suite; Test_sanctoral_ef.suite; Test_rite_ef.suite; Test_differential.suite; Test_oracle.suite; Test_oracle.suite_2038; Test_oracle.suite_2035; Test_golden.suite; ("lectionary", Test_lectionary.suite); - ("lectionary-ef", Test_lectionary_ef.suite) ] + ("lectionary-ef", Test_lectionary_ef.suite); + Test_escape.suite; + Test_template.suite; + Test_template.render_suite; + Test_view.suite; + Test_emit.suite; + Test_emit.xml_suite; + Test_ics.suite; + Test_render_golden.suite ] diff --git a/test/test_emit.ml b/test/test_emit.ml new file mode 100644 index 0000000..a22eaaf --- /dev/null +++ b/test/test_emit.ml @@ -0,0 +1,203 @@ +module V = Colitur_render.View +module Csv = Colitur_render.Emit_csv +module Json = Colitur_render.Emit_json +module Xml = Colitur_render.Emit_xml + +let view_2027 () = Test_view.view_of 2027 + +(* Substring search shared by several live-data checks below (CSV, XML), in + place of a repeated inline recursive finder. *) +let contains ~needle hay = + let n = String.length needle and h = String.length hay in + let rec go i = i + n <= h && (String.sub hay i n = needle || go (i + 1)) in + go 0 + +(* A byte-accurate RFC 4180 field splitter. [String.split_on_char ','] cannot + be trusted to count fields: a correctly QUOTED field is legally allowed to + contain a comma (exactly what Joseph's own name field does below), so a + naive split over-counts by the number of internal commas whether or not + they are correctly quoted -- it cannot tell the difference, which is + precisely why the test this replaced was vacuous. *) +let parse_csv_row line = + let n = String.length line in + let fields = ref [] in + let buf = Buffer.create 32 in + let i = ref 0 in + while !i < n do + if line.[!i] = '"' then begin + incr i; + let closed = ref false in + while (not !closed) && !i < n do + if line.[!i] = '"' then + if !i + 1 < n && line.[!i + 1] = '"' then begin + Buffer.add_char buf '"'; + i := !i + 2 + end + else begin + incr i; + closed := true + end + else begin + Buffer.add_char buf line.[!i]; + incr i + end + done + end + else if line.[!i] = ',' then begin + fields := Buffer.contents buf :: !fields; + Buffer.clear buf; + incr i + end + else begin + Buffer.add_char buf line.[!i]; + incr i + end + done; + fields := Buffer.contents buf :: !fields; + List.rev !fields + +let test_csv_header_and_rows () = + let out = Csv.year (view_2027 ()) in + let lines = String.split_on_char '\n' out |> List.filter (fun l -> l <> "") in + Alcotest.(check int) "366 lines: header + 365 days" 366 (List.length lines); + Alcotest.(check string) "header" + "date,rite,season,week,slug,rank,colour,subject,name_la,name_en,first,gospel,comms" + (List.hd lines); + Alcotest.(check bool) "first row is 1 January" true + (String.length (List.nth lines 1) > 10 && String.sub (List.nth lines 1) 0 10 = "2027-01-01") + +(* RFC 4180: a field containing a comma, quote or newline is quoted, and an + embedded quote is doubled. Feast names contain commas ("St. Joseph, Spouse + of the Bl. Virgin Mary"), so this is live on real data, not hypothetical. *) +let test_csv_quotes_commas () = + Alcotest.(check string) "comma quoted" "\"a,b\"" (Csv.escape_field "a,b"); + Alcotest.(check string) "quote doubled" "\"a\"\"b\"" (Csv.escape_field "a\"b"); + Alcotest.(check string) "plain unquoted" "ab" (Csv.escape_field "ab"); + let out = Csv.year (view_2027 ()) in + let joseph = + List.find + (fun l -> String.length l > 10 && String.sub l 0 10 = "2027-03-19") + (String.split_on_char '\n' out) + in + (* The check this replaced inspected the length of the FIRST field only -- + always the 10-char ISO date, which can never contain a comma, so it + could never fail. Parse the row as RFC 4180 actually requires + (quote-aware) and check the FIELD COUNT against the header: a comma + that escapes its quoting produces 14 fields, not 13. Also assert the + quoted substring appears literally, byte for byte -- belt and braces, + and closer to what a human reviewing the CSV would actually look for. *) + Alcotest.(check int) "the row has exactly 13 fields, same as the header" + 13 (List.length (parse_csv_row joseph)); + Alcotest.(check bool) "Joseph's comma-bearing name is quoted whole, not split" true + (contains ~needle:"\"St. Joseph, Spouse of the Bl. Virgin Mary\"" joseph) + +let test_json_parses_back () = + let out = Json.year (view_2027 ()) in + Alcotest.(check bool) "starts as an object" true (out.[0] = '{'); + let count sub = + let n = String.length sub in + let rec go i acc = + if i + n > String.length out then acc + else go (i + 1) (if String.sub out i n = sub then acc + 1 else acc) + in + go 0 0 + in + Alcotest.(check bool) "has a days array" true (count "\"days\":[" >= 1); + (* Every ISO date the view produced appears in the JSON -- that is the + property under test, not a specific occurrence count. The count is NOT + 1: the view deliberately offers both artefacts at every level (view.mli) + -- the flat top-level [days], each month's own [days], and that month's + [weeks] grid cell -- so an ordinary date's "iso" field appears 3 times. + Verified against the real 2027 engine output (all 365 dates checked); + the one exception is legitimate, not a bug: 2027-04-05 appears 6 times + because the Annunciation (25 March, impeded by Holy Week) transfers to + it under RG 96/98, and its own "to" target string is the identical + literal, tripled by the same structural redundancy. *) + Alcotest.(check int) "1 January appears (flat days + month days + week grid)" 3 + (count "\"2027-01-01\""); + Alcotest.(check int) "31 December appears (flat days + month days + week grid)" 3 + (count "\"2027-12-31\"") + +let test_json_escapes () = + Alcotest.(check string) "quote" "\"a\\\"b\"" (Json.escape_string "a\"b"); + Alcotest.(check string) "backslash" "\"a\\\\b\"" (Json.escape_string "a\\b"); + Alcotest.(check string) "newline" "\"a\\nb\"" (Json.escape_string "a\nb"); + Alcotest.(check string) "tab" "\"a\\tb\"" (Json.escape_string "a\tb"); + (* Control characters below 0x20 must be \u-escaped (RFC 8259 section 7). *) + Alcotest.(check string) "control" "\"a\\u0001b\"" (Json.escape_string "a\001b") + +let test_utf8_passes_through_json () = + Alcotest.(check string) "polish" "\"\xc5\x9awi\xc4\x99tej\"" (Json.escape_string "\xc5\x9awi\xc4\x99tej") + +let suite = + ( "Emit/csv+json", + [ Alcotest.test_case "csv header and rows" `Quick test_csv_header_and_rows; + Alcotest.test_case "csv quotes commas" `Quick test_csv_quotes_commas; + Alcotest.test_case "json parses back" `Quick test_json_parses_back; + Alcotest.test_case "json escapes" `Quick test_json_escapes; + Alcotest.test_case "json passes utf8 through" `Quick test_utf8_passes_through_json ] ) + +let test_xml_shape () = + let out = Xml.year (view_2027 ()) in + Alcotest.(check bool) "declaration" true + (String.length out > 5 && String.sub out 0 5 = "<?xml"); + Alcotest.(check bool) "root element" true + (contains ~needle:"<calendar rite=\"ef\" year=\"2027\">" out) + +(* Every '<' in the output must open a tag: an unescaped '<' inside a feast + name is the failure that makes a whole feed unparseable. *) +let test_xml_tags_balance () = + let out = Xml.year (view_2027 ()) in + let opens = ref 0 and closes = ref 0 in + String.iter (fun c -> if c = '<' then incr opens else if c = '>' then incr closes) out; + Alcotest.(check int) "every < has a >" !opens !closes + +let test_xml_escapes_data () = + Alcotest.(check string) "amp" "a & b" (Xml.escape "a & b"); + Alcotest.(check string) "angle" "<x>" (Xml.escape "<x>") + +(* [is_entity_at s i] recognises the five predefined XML entities and a + numeric character reference starting at [s.[i]] = '&'. Anything else + starting at a '&' is a bare, illegal ampersand -- exactly what + [xmllint --noout] refuses a document over. *) +let is_entity_at s i = + let n = String.length s in + let starts_with prefix = + let pn = String.length prefix in + i + pn <= n && String.sub s i pn = prefix + in + starts_with "&" || starts_with "<" || starts_with ">" + || starts_with """ || starts_with "'" + || + (* &#NNN; -- one or more digits then ';'. *) + (i + 2 < n && s.[i + 1] = '#' + && + let j = ref (i + 2) in + while !j < n && s.[!j] >= '0' && s.[!j] <= '9' do + incr j + done; + !j > i + 2 && !j < n && s.[!j] = ';') + +(* Live-data check. [test_xml_escapes_data] above proves [Escape.Xml] is + correct in isolation; it proves nothing about whether [Emit_xml.year] + actually CALLS it on every interpolated value -- bypassing that call + while leaving [Escape.Xml] itself untouched left every test in this suite + green (mutation-proven; see the branch review that found this). Real 2035 + output carries "Sts. Fabian & Sebastian" (20 January) unescaped in the + source data, which is exactly the case that must come out as "&", and + the whole document must then contain no OTHER bare '&' anywhere. *) +let test_xml_escapes_live_data () = + let out = Xml.year (Test_view.view_of 2035) in + Alcotest.(check bool) "Fabian & Sebastian's ampersand is escaped" true + (contains ~needle:"&" out); + let bare = ref 0 in + String.iteri (fun i c -> if c = '&' && not (is_entity_at out i) then incr bare) out; + Alcotest.(check int) "no bare, unescaped '&' anywhere in the document" 0 !bare + +let xml_suite = + ( "Emit/xml", + [ Alcotest.test_case "shape" `Quick test_xml_shape; + Alcotest.test_case "tags balance" `Quick test_xml_tags_balance; + Alcotest.test_case "escapes data" `Quick test_xml_escapes_data; + Alcotest.test_case "escapes live data (2035, Fabian & Sebastian)" `Quick + test_xml_escapes_live_data ] ) diff --git a/test/test_escape.ml b/test/test_escape.ml new file mode 100644 index 0000000..35a9b9d --- /dev/null +++ b/test/test_escape.ml @@ -0,0 +1,119 @@ +module E = Colitur_render.Escape + +let check = Alcotest.(check string) + +let test_latex () = + check "ampersand" "\\&" (E.apply E.Latex "&"); + check "percent" "\\%" (E.apply E.Latex "%"); + check "underscore" "\\_" (E.apply E.Latex "_"); + check "braces" "\\{\\}" (E.apply E.Latex "{}"); + check "backslash first" "\\textbackslash{}" (E.apply E.Latex "\\"); + (* A real feast name that would otherwise break a .tex build. *) + check "real name" "Ss.mi Nominis Iesu \\& Mari\xc3\xa6" + (E.apply E.Latex "Ss.mi Nominis Iesu & Mari\xc3\xa6") + +let test_groff () = + check "backslash" "\\e" (E.apply E.Groff "\\"); + (* RG-irrelevant but groff-critical: a leading dot starts a request. *) + check "leading dot" "\\&.Ss" (E.apply E.Groff ".Ss"); + check "leading quote" "\\&'tis" (E.apply E.Groff "'tis"); + check "interior dot untouched" "Ss.mi" (E.apply E.Groff "Ss.mi") + +let test_html_xml () = + check "amp first" "&lt;" (E.apply E.Html "<"); + check "angles" "<b>" (E.apply E.Html "<b>"); + check "quote" """ (E.apply E.Html "\""); + check "xml same" "<b>" (E.apply E.Xml "<b>") + +let test_ics () = + check "comma" "\\," (E.apply E.Ics ","); + check "semicolon" "\\;" (E.apply E.Ics ";"); + check "backslash" "\\\\" (E.apply E.Ics "\\"); + check "newline" "\\n" (E.apply E.Ics "\n") + +let test_none_is_identity () = + check "none" "& < > \\ % {}" (E.apply E.None_ "& < > \\ % {}") + +let test_flavour_names () = + List.iter + (fun f -> Alcotest.(check bool) "roundtrip" true (E.of_string (E.to_string f) = Some f)) + [ E.Latex; E.Groff; E.Html; E.Xml; E.Ics; E.None_ ]; + Alcotest.(check bool) "tex" true (E.of_extension ".tex" = Some E.Latex); + Alcotest.(check bool) "ms" true (E.of_extension ".ms" = Some E.Groff); + Alcotest.(check bool) "mom" true (E.of_extension ".mom" = Some E.Groff); + Alcotest.(check bool) "html" true (E.of_extension ".html" = Some E.Html); + Alcotest.(check bool) "md is none" true (E.of_extension ".md" = Some E.None_); + Alcotest.(check bool) "adoc is none" true (E.of_extension ".adoc" = Some E.None_); + Alcotest.(check bool) "txt is none" true (E.of_extension ".txt" = Some E.None_); + (* Spec section 5: an unknown extension is an ERROR, never a silent fallback. *) + Alcotest.(check bool) "unknown is None" true (E.of_extension ".wat" = None) + +let test_fold_short_line_unchanged () = + check "short" "SUMMARY:Feast\r\n" (E.fold_ics "SUMMARY:Feast") + +let test_fold_long_line () = + let long = "DESCRIPTION:" ^ String.make 200 'x' in + let out = E.fold_ics long in + let lines = String.split_on_char '\n' out in + List.iter + (fun l -> + let l = if l <> "" && l.[String.length l - 1] = '\r' then String.sub l 0 (String.length l - 1) else l in + if String.length l > 75 then Alcotest.failf "line of %d octets exceeds 75" (String.length l)) + (List.filter (fun l -> l <> "") lines); + (* Continuation lines begin with exactly one space (RFC 5545 section 3.1). *) + match lines with + | _ :: second :: _ -> Alcotest.(check bool) "continuation starts with space" true (second.[0] = ' ') + | _ -> Alcotest.fail "expected the line to fold" + +(* RFC 5545 section 3.1 folds on OCTET boundaries; splitting mid-UTF-8 corrupts + Polish and Latin names, which is the whole reason this is not a template job. *) +let test_fold_never_splits_utf8 () = + let long = "SUMMARY:" ^ String.concat "" (List.init 40 (fun _ -> "\xc4\x99\xc5\x9b\xc4\x87")) in + let out = E.fold_ics long in + let chunks = + List.filter_map + (fun l -> + let l = if l <> "" && l.[String.length l - 1] = '\r' then String.sub l 0 (String.length l - 1) else l in + if l = "" then None else if l.[0] = ' ' then Some (String.sub l 1 (String.length l - 1)) else Some l) + (String.split_on_char '\n' out) + in + (* The named property: no chunk may START with a UTF-8 continuation byte + (0x80-0xBF) -- that would mean the previous fold cut mid-character. + Unfolding losslessly (below) cannot detect this on its own: concatenation + is insensitive to where the cuts fell, so a fold at ANY position still + round-trips. *) + List.iter + (fun c -> + if String.length c > 0 then + Alcotest.(check bool) "chunk does not start mid-UTF-8" true (Char.code c.[0] land 0xC0 <> 0x80)) + chunks; + let stripped = String.concat "" chunks in + check "unfolds to the original" long stripped + +(* B1 regression: 100 consecutive UTF-8 continuation bytes (0x80-0xBF) is not + producible by valid UTF-8 (whose longest continuation run is 3), but + fold_ics must stay TOTAL on arbitrary octet strings. A backoff loop with no + hard-cut fallback backs `cut` all the way down to `pos`, yielding a + zero-length chunk and recursing on the identical position forever. *) +let test_fold_pathological_input_terminates () = + let pathological = String.make 100 '\x80' in + let out = E.fold_ics pathological in + let lines = String.split_on_char '\n' out in + List.iter + (fun l -> + let l = if l <> "" && l.[String.length l - 1] = '\r' then String.sub l 0 (String.length l - 1) else l in + if String.length l > 75 then Alcotest.failf "line of %d octets exceeds 75" (String.length l)) + (List.filter (fun l -> l <> "") lines) + +let suite = + ( "Escape", + [ Alcotest.test_case "latex" `Quick test_latex; + Alcotest.test_case "groff" `Quick test_groff; + Alcotest.test_case "html/xml" `Quick test_html_xml; + Alcotest.test_case "ics" `Quick test_ics; + Alcotest.test_case "none is identity" `Quick test_none_is_identity; + Alcotest.test_case "flavour names" `Quick test_flavour_names; + Alcotest.test_case "fold: short unchanged" `Quick test_fold_short_line_unchanged; + Alcotest.test_case "fold: long line" `Quick test_fold_long_line; + Alcotest.test_case "fold: never splits utf8" `Quick test_fold_never_splits_utf8; + Alcotest.test_case "fold: pathological input terminates" `Quick test_fold_pathological_input_terminates ] ) diff --git a/test/test_ics.ml b/test/test_ics.ml new file mode 100644 index 0000000..7d1ca37 --- /dev/null +++ b/test/test_ics.ml @@ -0,0 +1,143 @@ +module Ics = Colitur_render.Emit_ics + +let out_2027 () = Ics.year (Test_view.view_of 2027) + +let lines s = + String.split_on_char '\n' s + |> List.map (fun l -> if l <> "" && l.[String.length l - 1] = '\r' then String.sub l 0 (String.length l - 1) else l) + |> List.filter (fun l -> l <> "") + +let count_prefix p ls = + List.length (List.filter (fun l -> String.length l >= String.length p && String.sub l 0 (String.length p) = p) ls) + +let test_envelope () = + let ls = lines (out_2027 ()) in + Alcotest.(check string) "first line" "BEGIN:VCALENDAR" (List.hd ls); + Alcotest.(check string) "last line" "END:VCALENDAR" (List.nth ls (List.length ls - 1)); + Alcotest.(check int) "version" 1 (count_prefix "VERSION:2.0" ls); + Alcotest.(check int) "prodid" 1 (count_prefix "PRODID:" ls); + Alcotest.(check int) "365 events" 365 (count_prefix "BEGIN:VEVENT" ls) + +(* RFC 5545 section 3.6.1: for an all-day event DTEND is EXCLUSIVE. Getting + this wrong shows every event a day short in every client. *) +let test_dtend_is_exclusive () = + let ls = lines (out_2027 ()) in + let starts = List.filter_map (fun l -> + if count_prefix "DTSTART;VALUE=DATE:" [l] = 1 then + Some (String.sub l (String.length "DTSTART;VALUE=DATE:") 8) else None) ls in + let ends = List.filter_map (fun l -> + if count_prefix "DTEND;VALUE=DATE:" [l] = 1 then + Some (String.sub l (String.length "DTEND;VALUE=DATE:") 8) else None) ls in + Alcotest.(check int) "same count" (List.length starts) (List.length ends); + Alcotest.(check string) "1 Jan starts" "20270101" (List.hd starts); + Alcotest.(check string) "1 Jan ends on the 2nd" "20270102" (List.hd ends); + Alcotest.(check string) "31 Dec ends on 1 Jan next" "20280101" + (List.nth ends (List.length ends - 1)) + +let test_uids_unique_and_shaped () = + let ls = lines (out_2027 ()) in + let uids = List.filter_map (fun l -> + if count_prefix "UID:" [l] = 1 then Some (String.sub l 4 (String.length l - 4)) else None) ls in + Alcotest.(check int) "365 uids" 365 (List.length uids); + let sorted = List.sort_uniq String.compare uids in + Alcotest.(check int) "all unique" 365 (List.length sorted); + Alcotest.(check string) "shape" "20270101-ef@colitur" (List.hd uids) + +(* The rule that punishes silently, months later, in someone else's phone: + regenerating a feed must not duplicate every event. *) +let test_output_is_byte_stable_across_runs () = + Alcotest.(check string) "two runs identical" (out_2027 ()) (out_2027 ()) + +let test_every_line_folded_and_crlf () = + let raw = out_2027 () in + List.iter + (fun l -> + if String.length l > 75 then Alcotest.failf "line of %d octets: %s" (String.length l) l) + (lines raw); + (* Every physical line ends CRLF (RFC 5545 section 3.1). *) + let n = String.length raw in + let rec check i = + if i >= n then () + else if raw.[i] = '\n' then ( + if i = 0 || raw.[i - 1] <> '\r' then Alcotest.failf "bare LF at offset %d" i; + check (i + 1)) + else check (i + 1) + in + check 0 + +let test_no_rrule () = + Alcotest.(check int) "no RRULE" 0 (count_prefix "RRULE" (lines (out_2027 ()))) + +let test_text_escaped () = + let ls = lines (Ics.year (Test_view.view_of 2035)) in + (* 2035-04-03 is St Joseph, whose English name contains a comma. *) + let joseph = List.find (fun l -> count_prefix "SUMMARY:St. Joseph" [l] = 1) ls in + Alcotest.(check bool) "comma escaped" true + (let re = "\\," in + let n = String.length re in + let rec f i = i + n <= String.length joseph && (String.sub joseph i n = re || f (i + 1)) in + f 0) + +let test_dtstamp_is_a_parameter () = + let a = Ics.year ~dtstamp:"20200101T000000Z" (Test_view.view_of 2027) in + let b = Ics.year ~dtstamp:"20210101T000000Z" (Test_view.view_of 2027) in + Alcotest.(check bool) "differs with the parameter" true (a <> b); + (* DTSTAMP is a per-VEVENT property (RFC 5545 section 3.8.7.2), not a + calendar-level one -- every one of the 365 events carries the same + default value, not just one line in the whole feed. *) + Alcotest.(check int) "default is deterministic" 365 + (count_prefix "DTSTAMP:20270101T000000Z" (lines (out_2027 ()))) + +(* F1 (fix round 1, 2026-08-19): 9999 is the domain's own last civil year. + Its last VEVENT's successor date (10000-01-01) falls outside the + 1583..9999 domain [Date.make] enforces (date.mli) -- [Date.add_days] is + itself unbounded, and [to_iso8601] pads but never truncates, so the naive + successor string would be 9 digits, not 8. RFC 5545 section 3.6.1 makes a + DATE-valued DTSTART with neither DTEND nor DURATION mean exactly one day, + so [dtend_of] omits the DTEND line entirely for that one event rather than + emit it malformed. *) +let out_9999 () = Ics.year (Test_view.view_of 9999) + +let test_dtend_omitted_at_domain_end () = + let ls = Array.of_list (lines (out_9999 ())) in + let n = Array.length ls in + let idx = ref (-1) in + Array.iteri (fun i l -> if l = "DTSTART;VALUE=DATE:99991231" then idx := i) ls; + if !idx < 0 then Alcotest.fail "DTSTART;VALUE=DATE:99991231 not found"; + let next_line = if !idx + 1 < n then ls.(!idx + 1) else "" in + Alcotest.(check bool) "no DTEND line follows DTSTART 99991231" true + (count_prefix "DTEND;VALUE=DATE:" [ next_line ] = 0); + Alcotest.(check bool) "SUMMARY follows DTSTART directly instead" true + (count_prefix "SUMMARY:" [ next_line ] = 1) + +(* The general form of F1's bug class: every DTEND value anywhere in the + feed must be an 8-digit YYYYMMDD, never 9 (a future domain-boundary + regression anywhere else in 1583..9999 would show up here too). *) +let test_all_9999_dtends_are_eight_digits () = + let ls = lines (out_9999 ()) in + let prefix = "DTEND;VALUE=DATE:" in + let ends = + List.filter_map + (fun l -> + if count_prefix prefix [ l ] = 1 then + Some (String.sub l (String.length prefix) (String.length l - String.length prefix)) + else None) + ls + in + Alcotest.(check bool) "at least one DTEND present in 9999" true (List.length ends > 0); + List.iter + (fun v -> if String.length v <> 8 then Alcotest.failf "DTEND value %S is %d digits, not 8" v (String.length v)) + ends + +let suite = + ( "Emit/ics", + [ Alcotest.test_case "envelope" `Quick test_envelope; + Alcotest.test_case "DTEND exclusive" `Quick test_dtend_is_exclusive; + Alcotest.test_case "uids unique and shaped" `Quick test_uids_unique_and_shaped; + Alcotest.test_case "byte-stable across runs" `Quick test_output_is_byte_stable_across_runs; + Alcotest.test_case "folded and CRLF" `Quick test_every_line_folded_and_crlf; + Alcotest.test_case "no RRULE" `Quick test_no_rrule; + Alcotest.test_case "text escaped" `Quick test_text_escaped; + Alcotest.test_case "DTSTAMP is a parameter" `Quick test_dtstamp_is_a_parameter; + Alcotest.test_case "DTEND omitted at domain end" `Quick test_dtend_omitted_at_domain_end; + Alcotest.test_case "all 9999 DTENDs are eight digits" `Quick test_all_9999_dtends_are_eight_digits ] ) diff --git a/test/test_render_golden.ml b/test/test_render_golden.ml new file mode 100644 index 0000000..6340109 --- /dev/null +++ b/test/test_render_golden.ml @@ -0,0 +1,42 @@ +(* Pins the six shipped ordo booklet templates, one per flavour, under + templates/ef/, against a byte-for-byte golden render of 2027. These are + the templates a real user ships with colitur, rendered through the same + Template.render_string / View.of_days path colitur table uses -- so a + change to the view shape, the escaping rules, or the templates themselves + that alters output is caught here, not only in test_view.ml's shape + assertions. *) + +module T = Colitur_render.Template +module E = Colitur_render.Escape + +let render_template path year = + let ic = open_in_bin path in + let src = really_input_string ic (in_channel_length ic) in + close_in ic; + let ext = + match String.rindex_opt path '.' with + | Some i -> String.sub path i (String.length path - i) + | None -> "" + in + let flavour = match E.of_extension ext with Some f -> f | None -> Alcotest.failf "flavour for %s" ext in + let v = Test_view.view_of year in + match T.render_string ~flavour src v with Ok s -> s | Error e -> Alcotest.failf "%s: %s" path e + +let read path = + let ic = open_in_bin path in + let s = really_input_string ic (in_channel_length ic) in + close_in ic; + s + +let check_golden name = + let got = render_template ("../templates/ef/" ^ name) 2027 in + let want = read ("golden/" ^ Filename.remove_extension name ^ "-2027" ^ Filename.extension name) in + Alcotest.(check string) name want got + +let cases = + [ "ordo.tex"; "ordo.ms"; "ordo.html"; "ordo.adoc"; "ordo.md"; "ordo.txt"; + "grid.tex"; "grid.ms"; "grid.html" ] + +let suite = + ( "Render/golden", + List.map (fun n -> Alcotest.test_case n `Quick (fun () -> check_golden n)) cases ) diff --git a/test/test_support.ml b/test/test_support.ml new file mode 100644 index 0000000..7d7662f --- /dev/null +++ b/test/test_support.ml @@ -0,0 +1,65 @@ +(* Loaders for the real EF data (data/ef/*.sexp), extracted from + bin/main.ml's [load_ef_layer]/[load_ef_lectionary]/[load_ef_commons] + (bin/main.ml:154, :193, :206) and simplified to what the test suite + needs: no [~user_overlays], no COLITUR_DATA_DIR/installed-prefix + indirection (that machinery exists so the CLI finds its data next to + wherever it was installed or built -- tests always run from test/, where + test/dune already declares the four data/ef/*.sexp paths as [deps]). + Reading them via the same "../data/ef/..." relative paths test_calendar.ml, + test_rite_ef.ml and test_lectionary_ef.ml already use, not [bin/]'s own + [data_dir ()]. + + Deliberately NOT shared as a library with bin/main.ml: [bin/] and [test/] + are separate dune stanzas, and three small loaders duplicated here is + cheaper than a new library built just to serve them. bin/main.ml is not + changed to use this module -- the CLI keeps its own copy, already pinned + by test/cli.t. *) + +let sanctoral_path = "../data/ef/sanctoral.sexp" +let adjustments_path = "../data/ef/adjustments.sexp" +let lectionary_path = "../data/ef/lectionary.sexp" +let commons_path = "../data/ef/commons.sexp" + +(* Mirrors bin/main.ml's [load_ef_layer]: the shipped sanctoral layer with + the shipped adjustments overlay merged on top (RG 110's 30 June + companion, the Major Litanies, Barbara, Rogation Wednesday -- see + adjustments.sexp's own header). No user overlays: the test suite always + wants the plain shipped calendar. Diagnostics are discarded rather than + surfaced -- the shipped overlay is asserted elsewhere (test_overlay.ml, + the "check" path) to merge clean; a test that wants to see them can + still call {!Colitur_kernel.Overlay.merge} directly. *) +let load_ef_layer () = + match Colitur_kernel.Layer.load Rite_ef.Vocab_ef.rank_of_sexp sanctoral_path with + | Error e -> Error (Printf.sprintf "failed to load %s: %s" sanctoral_path e) + | Ok layer -> ( + match Colitur_kernel.Overlay.load Rite_ef.Vocab_ef.rank_of_sexp adjustments_path with + | Error e -> Error (Printf.sprintf "failed to load %s: %s" adjustments_path e) + | Ok overlay -> + let layer, _diagnostics = Colitur_kernel.Overlay.merge layer [ overlay ] in + Ok layer) + +(* Mirrors bin/main.ml's [load_ef_lectionary]. *) +let load_ef_lectionary () = + match Colitur_kernel.Lectionary.load lectionary_path with + | Error e -> Error (Printf.sprintf "failed to load %s: %s" lectionary_path e) + | Ok l -> Ok l + +(* Mirrors bin/main.ml's [load_ef_commons]. *) +let load_ef_commons () = + match Rite_ef.Lectionary_ef.Commons.load commons_path with + | Error e -> Error (Printf.sprintf "failed to load %s: %s" commons_path e) + | Ok c -> Ok c + +(* Assembles [Rite_ef.context] the way bin/main.ml:328 does, over the real + shipped lectionary and Commons. Raises on a load failure rather than + returning a [result]: the four data files are declared [deps] in + test/dune, so a failure here means the test tree itself is broken, the + same condition test_calendar.ml's and test_rite_ef.ml's own + module-level loaders already treat as fatal. *) +let ef_context () = + match load_ef_lectionary () with + | Error e -> failwith e + | Ok lectionary -> ( + match load_ef_commons () with + | Error e -> failwith e + | Ok commons -> Rite_ef.context ~lectionary ~commons) diff --git a/test/test_template.ml b/test/test_template.ml new file mode 100644 index 0000000..b83c378 --- /dev/null +++ b/test/test_template.ml @@ -0,0 +1,165 @@ +module T = Colitur_render.Template + +let parse_ok s = match T.parse s with Ok ns -> ns | Error e -> Alcotest.failf "parse: %s" e + +let test_plain_text () = + Alcotest.(check bool) "text only" true (parse_ok "hello" = [ T.Text "hello" ]) + +let test_var () = + Alcotest.(check bool) "var" true (parse_ok "{{name}}" = [ T.Var [ "name" ] ]); + Alcotest.(check bool) "dotted" true (parse_ok "{{name.la}}" = [ T.Var [ "name"; "la" ] ]); + Alcotest.(check bool) "spaces trimmed" true (parse_ok "{{ name.la }}" = [ T.Var [ "name"; "la" ] ]) + +let test_section () = + Alcotest.(check bool) "section" true + (parse_ok "{{#days}}x{{/days}}" = [ T.Section ([ "days" ], [ T.Text "x" ]) ]); + Alcotest.(check bool) "inverted" true + (parse_ok "{{^days}}x{{/days}}" = [ T.Inverted ([ "days" ], [ T.Text "x" ]) ]) + +let test_nested_sections () = + Alcotest.(check bool) "nested" true + (parse_ok "{{#months}}{{#weeks}}w{{/weeks}}{{/months}}" + = [ T.Section ([ "months" ], [ T.Section ([ "weeks" ], [ T.Text "w" ]) ]) ]) + +let test_comment_is_dropped () = + Alcotest.(check bool) "comment" true (parse_ok "a{{! note }}b" = [ T.Text "a"; T.Text "b" ]) + +let test_unclosed_section_is_an_error () = + match T.parse "{{#days}}x" with + | Error _ -> () + | Ok _ -> Alcotest.fail "an unclosed section must be a parse error, not silently accepted" + +let test_mismatched_close_is_an_error () = + match T.parse "{{#days}}x{{/weeks}}" with + | Error _ -> () + | Ok _ -> Alcotest.fail "a mismatched close tag must be a parse error" + +let test_unterminated_tag_is_an_error () = + match T.parse "{{name" with + | Error _ -> () + | Ok _ -> Alcotest.fail "an unterminated tag must be a parse error" + +(* The safety promise (spec section 5): a template is data, never a program. + There is no raw/triple-brace form to opt out of escaping, and no partial. *) +let test_no_raw_or_partial_form () = + (* {{{name}}} is not a triple-brace "unescaped" form -- there is no such + form in this engine, so this assertion states what parsing it ACTUALLY + produces rather than gesturing at a guarantee it cannot check: the + lexer only recognises double braces, so it reads an ordinary var whose + path is the literal string "{name", then a leftover "}" as text. The + real guarantee against a raw form is structural, not this assertion: + [node] has exactly four constructors -- Text, Var, Section, Inverted -- + and none of them is raw/unescaped. If [node] ever grows a fifth, raw + constructor, this test is not what will catch it. *) + Alcotest.(check bool) "triple brace parses as var + stray text" true + (parse_ok "{{{name}}}" = [ T.Var [ "{name" ]; T.Text "}" ]); + match T.parse "{{>partial}}" with + | Error _ -> () + | Ok _ -> Alcotest.fail "partials must not parse: a template may not pull in another file" + +(* No "current context" concept exists in this engine (sections push an + object; lookup falls back outward), so a bare-dot or empty-sigil path has + no meaning. Reject at parse time rather than inventing behaviour Task 3's + renderer would otherwise have to define for a case nobody designed. *) +let test_empty_path_is_an_error () = + let expect_error label s = + match T.parse s with + | Error _ -> () + | Ok _ -> Alcotest.failf "%s: an empty tag path must be a parse error" label + in + expect_error "{{.}}" "{{.}}"; + expect_error "{{ . }}" "{{ . }}"; + expect_error "{{#}}{{/}}" "{{#}}{{/}}"; + expect_error "{{^}}{{/}}" "{{^}}{{/}}" + +let suite = + ( "Template/parse", + [ Alcotest.test_case "plain text" `Quick test_plain_text; + Alcotest.test_case "vars" `Quick test_var; + Alcotest.test_case "sections" `Quick test_section; + Alcotest.test_case "nested sections" `Quick test_nested_sections; + Alcotest.test_case "comments dropped" `Quick test_comment_is_dropped; + Alcotest.test_case "unclosed section errors" `Quick test_unclosed_section_is_an_error; + Alcotest.test_case "mismatched close errors" `Quick test_mismatched_close_is_an_error; + Alcotest.test_case "unterminated tag errors" `Quick test_unterminated_tag_is_an_error; + Alcotest.test_case "no raw or partial form" `Quick test_no_raw_or_partial_form; + Alcotest.test_case "empty path errors" `Quick test_empty_path_is_an_error ] ) + +module E = Colitur_render.Escape + +let render ?(flavour = E.None_) tpl v = + match T.render_string ~flavour tpl v with Ok s -> s | Error e -> Alcotest.failf "render: %s" e + +let obj kvs = T.Obj kvs + +let test_render_var () = + Alcotest.(check string) "var" "Hilary" (render "{{name}}" (obj [ ("name", T.Str "Hilary") ])); + Alcotest.(check string) "dotted" "Hilarii" + (render "{{name.la}}" (obj [ ("name", obj [ ("la", T.Str "Hilarii") ]) ])) + +(* A missing key renders empty. This is the ONE silent case, and it is + deliberate: a template written for a rite that does not set every optional + field must still render (spec section 5). *) +let test_missing_key_is_empty () = + Alcotest.(check string) "missing" "[]" (render "[{{nope}}]" (obj [ ("name", T.Str "x") ])) + +let test_section_iterates () = + let v = obj [ ("days", T.List [ obj [ ("dom", T.Str "1") ]; obj [ ("dom", T.Str "2") ] ]) ] in + Alcotest.(check string) "iterate" "1|2|" (render "{{#days}}{{dom}}|{{/days}}" v) + +let test_bool_section () = + Alcotest.(check string) "true" "yes" (render "{{#f}}yes{{/f}}" (obj [ ("f", T.Bool true) ])); + Alcotest.(check string) "false" "" (render "{{#f}}yes{{/f}}" (obj [ ("f", T.Bool false) ])); + Alcotest.(check string) "inverted true" "" (render "{{^f}}no{{/f}}" (obj [ ("f", T.Bool true) ])); + Alcotest.(check string) "inverted false" "no" (render "{{^f}}no{{/f}}" (obj [ ("f", T.Bool false) ])) + +let test_empty_list_section_is_skipped () = + Alcotest.(check string) "empty list" "" (render "{{#days}}x{{/days}}" (obj [ ("days", T.List []) ])); + Alcotest.(check string) "inverted empty list" "none" + (render "{{^days}}none{{/days}}" (obj [ ("days", T.List []) ])) + +let test_outer_scope_visible_inside_section () = + let v = obj [ ("year", T.Str "2027"); ("days", T.List [ obj [ ("dom", T.Str "1") ] ]) ] in + Alcotest.(check string) "outer visible" "2027-1" + (render "{{#days}}{{year}}-{{dom}}{{/days}}" v) + +(* THE safety property (spec section 9.2): a data value can never escape its + flavour. This is the test that must redden if any escape rule is broken. *) +let test_data_cannot_escape_flavour () = + let nasty = obj [ ("name", T.Str "A & B \\ 50% {x} $y_z") ] in + let out = render ~flavour:E.Latex "{{name}}" nasty in + Alcotest.(check string) "fully escaped" "A \\& B \\textbackslash{} 50\\% \\{x\\} \\$y\\_z" out; + let hout = render ~flavour:E.Html "{{name}}" (obj [ ("name", T.Str "<script>") ]) in + Alcotest.(check string) "html escaped" "<script>" hout + +(* Literal template text is NOT escaped -- it is the author's own markup. Only + interpolated DATA is escaped. Getting this backwards would make every + template render as visible source. *) +(* NOTE: the brief's own example here was "\textbf{{{name}}}", i.e. a literal + "{" immediately followed by "{{name}}". That does not parse the way the + brief assumes: this engine's lexer (Task 2, frozen) is greedy left-to-right + and has no triple-brace special case (by design -- there is no raw form), + so three consecutive "{" are read as an ordinary tag opener "{{" followed + by a path that literally starts with "{" ("{name"), which resolves to + nothing and renders empty, plus a stray literal "}" -- exactly what + test_no_raw_or_partial_form above already documents for "{{{name}}}" on + its own. Verified live: the brief's original line reddens with "\textbf}", + not "\textbf{Hilary}". Rewritten below to put a character between the + literal "{" and the tag's own "{{", which sidesteps the ambiguity while + still proving the same property: literal backslash/braces from Text survive + unescaped, where a wrongly-escaped Text node would turn "\textbf{" into + "\textbackslash{}\{". *) +let test_literal_markup_is_not_escaped () = + Alcotest.(check string) "literal kept" "\\textbf{Name: Hilary}" + (render ~flavour:E.Latex "\\textbf{Name: {{name}}}" (obj [ ("name", T.Str "Hilary") ])) + +let render_suite = + ( "Template/render", + [ Alcotest.test_case "vars" `Quick test_render_var; + Alcotest.test_case "missing key is empty" `Quick test_missing_key_is_empty; + Alcotest.test_case "section iterates" `Quick test_section_iterates; + Alcotest.test_case "bool sections" `Quick test_bool_section; + Alcotest.test_case "empty list sections" `Quick test_empty_list_section_is_skipped; + Alcotest.test_case "outer scope visible" `Quick test_outer_scope_visible_inside_section; + Alcotest.test_case "data cannot escape flavour" `Quick test_data_cannot_escape_flavour; + Alcotest.test_case "literal markup unescaped" `Quick test_literal_markup_is_not_escaped ] ) diff --git a/test/test_view.ml b/test/test_view.ml new file mode 100644 index 0000000..e595357 --- /dev/null +++ b/test/test_view.ml @@ -0,0 +1,119 @@ +module V = Colitur_render.View +module T = Colitur_render.Template + +(* Build one civil year of resolved days exactly as the CLI does. *) +let days_of_year y = + let layer = + match Test_support.load_ef_layer () with Ok l -> l | Error e -> Alcotest.failf "layer: %s" e + in + let context = Test_support.ef_context () in + let module Cal = Colitur_kernel.Calendar in + let module D = Colitur_kernel.Date in + let tbl = Hashtbl.create 400 in + let index days = + Array.iter (fun d -> Hashtbl.replace tbl (D.to_rata d.Colitur_kernel.Liturgical_day.date) d) days + in + index (Cal.year context layer (y - 1)); + index (Cal.year context layer y); + let jan1 = Result.get_ok (D.make ~year:y ~month:1 ~day:1) in + let dec31 = Result.get_ok (D.make ~year:y ~month:12 ~day:31) in + let out = ref [] and d = ref jan1 in + while D.compare !d dec31 <= 0 do + (match Hashtbl.find_opt tbl (D.to_rata !d) with Some x -> out := x :: !out | None -> ()); + d := D.add_days !d 1 + done; + List.rev !out + +let view_of y = + V.of_days ~vocab:Rite_ef.Vocab_ef.vocab ~rite:"ef" ~year:y (days_of_year y) + +let get path v = + let rec go v = function + | [] -> v + | k :: tl -> ( + match v with + | T.Obj kvs -> ( + match List.assoc_opt k kvs with Some v' -> go v' tl | None -> Alcotest.failf "no key %s" k) + | _ -> Alcotest.failf "not an object at %s" k) + in + go v path + +let as_list = function T.List l -> l | _ -> Alcotest.fail "expected a list" +let as_str = function T.Str s -> s | _ -> Alcotest.fail "expected a string" +let as_bool = function T.Bool b -> b | _ -> Alcotest.fail "expected a bool" + +let test_year_shape () = + let v = view_of 2027 in + Alcotest.(check string) "rite" "ef" (as_str (get [ "rite" ] v)); + Alcotest.(check string) "year" "2027" (as_str (get [ "year" ] v)); + Alcotest.(check int) "twelve months" 12 (List.length (as_list (get [ "months" ] v))); + Alcotest.(check int) "365 days" 365 (List.length (as_list (get [ "days" ] v))) + +(* THE property the grid depends on: weeks flatten to the month's days plus + padding, and every real day appears exactly once (spec section 9.3). *) +let test_weeks_flatten_to_days () = + let v = view_of 2027 in + List.iter + (fun m -> + let weeks = as_list (get [ "weeks" ] m) in + let cells = List.concat_map (fun w -> as_list (get [ "days" ] w)) weeks in + List.iter + (fun w -> Alcotest.(check int) "seven cells per week" 7 (List.length (as_list (get [ "days" ] w)))) + weeks; + let real = List.filter (fun c -> as_bool (get [ "in_month" ] c)) cells in + let own = as_list (get [ "days" ] m) in + Alcotest.(check int) "real cells = month days" (List.length own) (List.length real); + List.iter2 + (fun a b -> Alcotest.(check string) "same day, same order" (as_str (get [ "iso" ] a)) (as_str (get [ "iso" ] b))) + own real) + (as_list (get [ "months" ] v)) + +let test_padding_cells_are_flagged () = + let v = view_of 2027 in + let jan = List.hd (as_list (get [ "months" ] v)) in + let first_week = List.hd (as_list (get [ "weeks" ] jan)) in + let cells = as_list (get [ "days" ] first_week) in + (* 1 January 2027 is a Friday, so the first week has five padding cells. *) + Alcotest.(check int) "five padding cells" 5 + (List.length (List.filter (fun c -> not (as_bool (get [ "in_month" ] c))) cells)); + List.iter + (fun c -> + if not (as_bool (get [ "in_month" ] c)) then + Alcotest.(check string) "padding has empty iso" "" (as_str (get [ "iso" ] c))) + cells + +let test_day_fields () = + let v = view_of 2027 in + let d = + List.find (fun d -> as_str (get [ "iso" ] d) = "2027-01-13") (as_list (get [ "days" ] v)) + in + Alcotest.(check string) "slug" "commemoration-of-the-baptism-of-the-lord" (as_str (get [ "slug" ] d)); + Alcotest.(check string) "colour" "white" (as_str (get [ "colour" ] d)); + Alcotest.(check bool) "is_white" true (as_bool (get [ "is_white" ] d)); + Alcotest.(check bool) "is_violet" false (as_bool (get [ "is_violet" ] d)); + Alcotest.(check int) "dow friday" 3 (int_of_string (as_str (get [ "dow" ] d))); + Alcotest.(check bool) "first citation present" true (as_str (get [ "first" ] d) <> ""); + Alcotest.(check bool) "gospel citation present" true (as_str (get [ "gospel" ] d) <> "") + +(* Exactly one of the six colour booleans is true on every day of a whole year: + a template that keys a cell colour off them can never get no colour or two. *) +let test_exactly_one_colour_flag () = + let v = view_of 2027 in + List.iter + (fun d -> + let n = + List.length + (List.filter + (fun k -> as_bool (get [ k ] d)) + [ "is_white"; "is_red"; "is_green"; "is_violet"; "is_rose"; "is_black" ]) + in + if n <> 1 then Alcotest.failf "%s has %d colour flags set" (as_str (get [ "iso" ] d)) n) + (as_list (get [ "days" ] v)) + +let suite = + ( "View", + [ Alcotest.test_case "year shape" `Quick test_year_shape; + Alcotest.test_case "weeks flatten to days" `Quick test_weeks_flatten_to_days; + Alcotest.test_case "padding cells flagged" `Quick test_padding_cells_are_flagged; + Alcotest.test_case "day fields" `Quick test_day_fields; + Alcotest.test_case "exactly one colour flag" `Quick test_exactly_one_colour_flag ] ) |
