diff options
Diffstat (limited to 'internal/liturgy/parse.go')
| -rw-r--r-- | internal/liturgy/parse.go | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/internal/liturgy/parse.go b/internal/liturgy/parse.go index 64e6928..4c1a935 100644 --- a/internal/liturgy/parse.go +++ b/internal/liturgy/parse.go @@ -23,8 +23,32 @@ var ( h4Re = regexp.MustCompile(`(?s)<h4>(.*?)</h4>`) pRe = regexp.MustCompile(`(?s)<p>(.*?)</p>`) citationRe = regexp.MustCompile(`\((.+)\)\s*$`) + + // dayNamePRe matches every classed <p><em>...</em></p> on the page; only + // the one whose class carries both "fw-bold" and a "color-" role (see + // dayNameParaMatches) is the day's celebration name -- the page also + // carries a plain fw-bold (no color-) lookalike higher up that must not + // win instead. + dayNamePRe = regexp.MustCompile(`(?s)<p class="([^"]*)">\s*<em>(.*?)</em>\s*</p>`) + + // dayColourRe matches niedziela.pl's "Kolor szat: <word>" vestment-colour + // line, tolerating the <span>/<strong> markup wrapped around the colour + // word on the page (see internal/liturgy/testdata/2026-07-22.html). + dayColourRe = regexp.MustCompile(`Kolor szat:\s*(?:<[^>]+>\s*)*([\p{L}]+)`) ) +// modernColours maps niedziela.pl's Polish vestment-colour words to +// DayInfo's normalized colour names; anything not listed here (including a +// multi-option line like "zielony albo biały albo czerwony", which matches +// only its first word) is left for the caller to treat as "" if absent. +var modernColours = map[string]string{ + "biały": "white", + "zielony": "green", + "fioletowy": "violet", + "czerwony": "red", + "różowy": "rose", +} + // panePattern matches the opening tag of the tab-pane div carrying the given // tab id, e.g. `<div class="tab-pane fade " id="tabnowy0all">`. func panePattern(tab string) *regexp.Regexp { @@ -122,6 +146,35 @@ func Parse(pageHTML string) ([]Section, error) { return sections, nil } +// ParseDayInfo extracts the day's celebration name and liturgical colour +// from a niedziela.pl page: Name is the inner text of the <p class="... +// fw-bold color-XXX"><em>NAME</em></p> paragraph (there is also an earlier, +// plain fw-bold-but-no-color- lookalike on the page -- see dayNamePRe -- +// which must not match instead), and Colour comes from the page's "Kolor +// szat: <word>" line, mapped via modernColours (case-insensitive; unknown +// word -> ""). Season is always "" -- the modern lectionary folds its +// temporal context into Name on temporal days rather than carrying it +// separately. A page whose markup doesn't match either pattern (a layout +// change, or a fixture with neither) yields a zero DayInfo, never an error: +// the readings are the load-bearing content, the header is a nice-to-have. +func ParseDayInfo(pageHTML string) DayInfo { + var info DayInfo + + for _, m := range dayNamePRe.FindAllStringSubmatch(pageHTML, -1) { + class := m[1] + if strings.Contains(class, "fw-bold") && strings.Contains(class, "color-") { + info.Name = strings.Join(htmlToLines(m[2]), " ") + break + } + } + + if m := dayColourRe.FindStringSubmatch(pageHTML); m != nil { + info.Colour = modernColours[strings.ToLower(m[1])] + } + + return info +} + // partID assigns the stable liturgical-part identifier for a section heading. // A second "1. czytanie" heading on the same day (a split feast offering two // alternative first readings) becomes "drugie_czytanie" instead of colliding |
