diff --git a/calendarium/tests/test_antiochian_readings.py b/calendarium/tests/test_antiochian_readings.py index 97e01d3..f3672e8 100644 --- a/calendarium/tests/test_antiochian_readings.py +++ b/calendarium/tests/test_antiochian_readings.py @@ -1,5 +1,5 @@ import itertools -from datetime import date +from datetime import date, timedelta from pathlib import Path from django.test import TestCase @@ -47,6 +47,20 @@ async def verse_set(reference): displays = [r.pericope.sdisplay for r in await day.aget_readings()] served = [(d, await verse_set(d)) for d in displays] + # The sources list the Lamentations (Matins of Holy Saturday, sung on + # Friday evening) under Holy Friday; orthocal carries them on Holy + # Saturday. Its Matins Epistle adds Gal 3:13-14, which the sources + # leave out, so containment is enough. + anticipated = [] + if day.pdist == -2: + next_day = day_date + timedelta(days=1) + saturday = liturgics.Day(next_day.year, next_day.month, next_day.day, + tradition=Tradition.Greek) + await saturday.ainitialize() + anticipated = [await verse_set(r.pericope.sdisplay) + for r in await saturday.aget_readings() + if r.source.startswith('Matins')] + for _, title in group: overlapping = '-' try: @@ -57,6 +71,8 @@ async def verse_set(reference): status = 'unresolved' elif any(found == wanted for _, found in served): status = 'exact' + elif any(wanted <= found for found in anticipated): + status = 'exact' elif overlaps := [d for d, found in served if found & wanted]: status = 'boundary' overlapping = ' | '.join(overlaps) @@ -113,7 +129,8 @@ class TestExactGreekReadingBoundaries(TestCase): (2, 9, 'Epistle', '1 John 2.18-29; 3.1-8'), (2, 16, 'Epistle', '3 John 1.1-15'), (3, 1, 'Epistle', 'Heb 11.24-26, 32-40'), - # 4/10, Holy Friday, is left alone; see load_exact_boundaries.py. + # Not 4/10: Holy Friday's listing is the Lamentations, which the app + # carries as Holy Saturday Matins; see load_exact_boundaries.py. (4, 15, 'Epistle', 'Acts 2.22-38'), (5, 7, 'Epistle', 'Acts 26.1, 12-20'), (5, 8, 'Gospel', 'John 19.25-28, 21.24-25'), diff --git a/docs/greek-commons.md b/docs/greek-commons.md index fcfea00..9b5e74e 100644 --- a/docs/greek-commons.md +++ b/docs/greek-commons.md @@ -318,6 +318,11 @@ Of the 4: - **Holy Friday**: `1 Cor 5:6-8` (Greek) vs. our existing Vespers Epistle `1 Cor 1.18-2.2` (Slavic) — confirmed 2/2 years (2021, 2026). Added as a `greek` override on the `Vespers`-desc Epistle slot (new Pericope). + **Reverted 2026-10-14**: this was a misreading. The sources list the + Lamentations (Matins of Holy Saturday, sung on Friday evening) under Friday; + `1 Cor 5:6-8` is that service's Epistle, which the app already carries on + Holy Saturday. Greek Vespers on Holy Friday reads `1 Cor 1:18-2:2` like + Slavic. See `docs/greek-lectionary.md`, "Accuracy, measured". - **Holy Thursday's compound Gospel reading**: our version and antiochian's differ by a few verses within an already-massive 6-part compound citation (`Matt 26:2-20;...` vs `Matt 26:1-20;...`, etc.) — diff --git a/docs/greek-lectionary.md b/docs/greek-lectionary.md index 1497171..6202402 100644 --- a/docs/greek-lectionary.md +++ b/docs/greek-lectionary.md @@ -10,8 +10,8 @@ investigation history, kept because it records *why* decisions were made and which hypotheses are already dead; some of its early sections are superseded and are marked as such. -Last measured 2026-10-14, by verse set against goarch.org: **6,626 of 6,696 -Epistle and Gospel fields (99.0%) over 2018-2027**, and 670 of 672 in 2026. +Last measured 2026-10-14, by verse set against goarch.org: **6,636 of 6,696 +Epistle and Gospel fields (99.1%) over 2018-2027**, and 671 of 672 in 2026. An earlier "99.1%" compared only each citation's opening verse and is not comparable; see "Accuracy, measured". @@ -158,28 +158,36 @@ only if some app reading of the same kind covers exactly goarch.org's verses. | year | Epistle/Gospel fields | exact | |---|---|---| -| 2018 | 668 | 661 (99.0%) | -| 2019 | 668 | 659 (98.7%) | -| 2020 | 672 | 667 (99.3%) | -| 2021 | 668 | 661 (99.0%) | -| 2022 | 670 | 660 (98.5%) | -| 2023 | 670 | 659 (98.4%) | -| 2024 | 672 | 663 (98.7%) | -| 2025 | 668 | 665 (99.6%) | -| 2026 | 672 | 670 (99.7%) | -| 2027 | 668 | 661 (99.0%) | -| **all** | **6,696** | **6,626 (99.0%)** | +| 2018 | 668 | 662 (99.1%) | +| 2019 | 668 | 660 (98.8%) | +| 2020 | 672 | 668 (99.4%) | +| 2021 | 668 | 662 (99.1%) | +| 2022 | 670 | 661 (98.7%) | +| 2023 | 670 | 660 (98.5%) | +| 2024 | 672 | 664 (98.8%) | +| 2025 | 668 | 666 (99.7%) | +| 2026 | 672 | 671 (99.9%) | +| 2027 | 668 | 662 (99.1%) | +| **all** | **6,696** | **6,636 (99.1%)** | Before the exact-boundary work (PR #252) the same measure gave 90.8%; after it, 98.6%. Five more rows found with `--recurring` and corroborated by -antiochian.org brought it to 99.0%. Run the +antiochian.org brought it to 99.0%, and reading Holy Friday correctly (below) +to 99.1%. + +**Holy Friday.** goarch.org lists `1 Corinthians 5:6-8` and `Matthew 27:62-66` +as Holy Friday's Epistle and Gospel. Those are the Lamentations readings -- +Matins of Holy Saturday, sung on Friday evening -- which this app already +carries as Holy Saturday's Matins readings, exactly as oca.org does. Holy +Friday's own Vespers reads `1 Corinthians 1:18-2:2` and the composite Gospel in +the Greek tradition too (johnsanidopoulos.com's Holy Friday readings and Holy +Cross, Pittsburgh's service list both print them). The audit therefore also +accepts Holy Saturday's Matins readings on Holy Friday. A `greek` row added in +July from that Friday listing, putting `1 Cor 5:6-8` in the Vespers Epistle +slot, was removed. Run the script with `--recurring` for the current list of differences; what remains is mostly: -- **Holy Friday**, every year: both sources print `Matthew 27:62-66`, the - Lamentations Gospel (Matins of Holy Saturday, served on Friday evening), where - this slot carries the Vespers composite Gospel. Fixing it means modelling the - Lamentations as its own service, not swapping one Gospel for the other. - **Apostles' feasts moved out of Holy or Bright Week** (`Luke 10:16-21` for St Mark, `Acts 12:1-11` for St James, `Hebrews 13:7-16`): transfer logic, not missing rows. diff --git a/fixtures/calendarium.json b/fixtures/calendarium.json index 97b8293..c195e44 100644 --- a/fixtures/calendarium.json +++ b/fixtures/calendarium.json @@ -45865,21 +45865,6 @@ "tradition": "greek" } }, -{ - "model": "calendarium.reading", - "pk": 1794, - "fields": { - "month": 0, - "day": 0, - "pdist": -2, - "source": "Epistle", - "desc": "Vespers", - "pericope": 1012, - "ordering": 521, - "flag": 0, - "tradition": "greek" - } -}, { "model": "calendarium.reading", "pk": 1795, @@ -63292,23 +63277,6 @@ "flag": 0 } }, -{ - "model": "calendarium.pericope", - "pk": 1012, - "fields": { - "pericope": "308grk", - "book": "Apostol", - "display": "1 Corinthians 5.6-8", - "sdisplay": "1 Cor 5.6-8", - "desc": "Holy Friday Vespers (Greek)", - "preverse": "", - "prefix": "Brethren, your glorying", - "prefixb": "", - "verses": "1Cor_5006_5008", - "suffix": "", - "flag": 0 - } -}, { "model": "calendarium.pericope", "pk": 1013, diff --git a/tools/greek/goa_verse_audit.py b/tools/greek/goa_verse_audit.py index 2b8314c..039daca 100644 --- a/tools/greek/goa_verse_audit.py +++ b/tools/greek/goa_verse_audit.py @@ -131,7 +131,16 @@ def verse_set(citation): async def app_readings(date): day = Day(date.year, date.month, date.day, tradition=Tradition.Greek) await day.ainitialize() - return [(r.source, r.pericope.sdisplay) for r in await day.aget_readings()] + return day.pdist, [(r.source, r.pericope.sdisplay) for r in await day.aget_readings()] + + +# goarch.org lists the Lamentations -- Matins of Holy Saturday, sung on Friday +# evening -- as Holy Friday's Epistle and Gospel. This app keeps them where they +# belong liturgically, as Holy Saturday's Matins readings, so on Holy Friday +# those count too. goarch.org prints only 1 Cor 5:6-8 of the Matins Epistle, +# which also includes Gal 3:13-14, so containment is enough there. +HOLY_FRIDAY = -2 +ANTICIPATED = {'Epistle': 'Matins Epistle', 'Gospel': 'Matins Gospel'} async def audit(years): @@ -142,7 +151,9 @@ async def audit(years): continue label, readings = value date = datetime.date.fromisoformat(key) - ours = await app_readings(date) + pdist, ours = await app_readings(date) + if pdist == HOLY_FRIDAY: + _, saturday = await app_readings(date + datetime.timedelta(days=1)) for kind, citation in readings: if kind not in SOURCES: continue @@ -153,6 +164,10 @@ async def audit(years): result = 'unparsed' elif want in got: result = 'exact' + elif pdist == HOLY_FRIDAY and any( + want <= (verse_set(s) or frozenset()) + for source, s in saturday if source == ANTICIPATED[SOURCES[kind]]): + result = 'exact' elif any(g and g & want for g in got): result = 'boundary' else: diff --git a/tools/greek/load_exact_boundaries.py b/tools/greek/load_exact_boundaries.py index 03d40a0..b824c27 100644 --- a/tools/greek/load_exact_boundaries.py +++ b/tools/greek/load_exact_boundaries.py @@ -47,10 +47,9 @@ 'goarch.org 2024, 2026; antiochian.org 2024, 2026'), # Holy Friday is deliberately absent. Both sources print Matthew 27:62-66, # but that is the Gospel of the Lamentations (Matins of Holy Saturday, - # served on Friday evening), not of Vespers, whose composite Gospel this - # slot carries. Replacing it would drop the Vespers Gospel and leave a - # Lamentations reading under a Vespers label; it needs the Lamentations - # modelled as its own service instead. + # sung on Friday evening), which the app already carries as Holy + # Saturday's Matins Gospel. This slot is Holy Friday Vespers, whose + # composite Gospel is the same in both traditions. ('Epistle', 3, 'Acts 2.22-36', 'Acts 2:22-38', 'goarch.org 2024, 2026; antiochian.org 2026'), ('Epistle', (5, 7), 'Acts 26.1-5, 12-20', 'Acts 26:1, 12-20',