1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
package cli
import (
"fmt"
"io"
"regexp"
"strconv"
"strings"
"time"
"github.com/lukaszkasprzak/lectio/internal/caldata"
"github.com/lukaszkasprzak/lectio/internal/calendar"
"github.com/lukaszkasprzak/lectio/internal/config"
)
// reNumberedSunday matches the generic seasonal Sundays ("ordinary-sunday-11",
// "lent-sunday-1"), which carry solemnity rank but are not what a "key dates"
// list wants -- the season boundary already marks them.
var reNumberedSunday = regexp.MustCompile(`-sunday-\d+$`)
// seasonalSunday reports whether a slug is a generic numbered Sunday or an
// Octave-of-Easter weekday, which the overview omits from the solemnity list.
func seasonalSunday(slug string) bool {
s := strings.TrimPrefix(slug, "ef-")
return reNumberedSunday.MatchString(s) || strings.HasPrefix(s, "easter-octave-")
}
// seasonName renders a season slug as a display phrase for the year overview.
func seasonName(s calendar.Season) string {
switch s {
case calendar.Advent:
return "Advent"
case calendar.Christmas:
return "Christmas"
case calendar.Lent:
return "Lent"
case calendar.Triduum:
return "the Paschal Triduum"
case calendar.Easter_:
return "Eastertide"
case calendar.Ordinary:
return "Ordinary Time"
}
switch string(s) {
case "septuagesima":
return "Septuagesima"
case "passiontide":
return "Passiontide"
case "time-after-epiphany":
return "Time after Epiphany"
case "time-after-pentecost":
return "Time after Pentecost"
}
return string(s)
}
// topRank reports whether a rank is the year's headline tier: a solemnity
// (Ordinary Form) or a class-1 feast (Extraordinary Form).
func topRank(r calendar.Rank) bool {
return r == calendar.RankSolemnity || r == calendar.RankClass1
}
// runYearOverview prints the key liturgical dates of a civil year -- season
// boundaries, solemnities and feasts of the Lord -- computed from the engine
// for the configured form (and custom-calendar layers). It is what `--year N`
// does on its own (with --format it emits the machine calendar instead). Output
// goes through the pager when one is configured and stdout is a terminal.
func runYearOverview(cfg config.Config, yearStr, formFlag string, pagerFlag, noPager bool, stdout, stderr io.Writer) int {
year, err := strconv.Atoi(strings.TrimSpace(yearStr))
if err != nil || year < 1583 || year > 9999 {
fmt.Fprintf(stderr, "lectio: invalid --year %q (want 1583-9999)\n", yearStr)
return 2
}
sel := cfg.Selection()
if formFlag != "" {
if formFlag != "old" && formFlag != "new" {
fmt.Fprintf(stderr, "lectio: invalid --form %q (want old|new)\n", formFlag)
return 2
}
sel.Form = formFlag
}
dir, _ := config.CalendarsDir()
layers, errs := caldata.Stack(sel.Form, dir, cfg.Use)
for _, e := range errs {
fmt.Fprintln(stderr, "lectio: warning:", e)
}
out := stdout
if pagerRequested(pagerFlag, noPager, cfg) && isTerminalWriter(stdout) {
if o, finish, ok := startPager(pagerCommand(cfg), stdout, stderr); ok {
out = o
defer finish()
}
}
formName := "Ordinary Form"
if sel.Form == "old" {
formName = "Extraordinary Form (1962)"
}
title := fmt.Sprintf("Key liturgical dates %d — %s", year, formName)
fmt.Fprintf(out, "%s\n%s\n\n", title, strings.Repeat("=", len([]rune(title))))
prev := calendar.Season("")
for d := time.Date(year, 1, 1, 0, 0, 0, 0, time.UTC); d.Year() == year; d = d.AddDate(0, 0, 1) {
day := calendar.Compute(d, sel, layers)
var tags []string
if day.Season != prev && prev != "" {
tags = append(tags, seasonName(day.Season)+" begins")
}
prev = day.Season
if topRank(day.Observed.Rank) && !seasonalSunday(day.Observed.Slug) {
tags = append(tags, "solemnity")
} else if day.Observed.Class == calendar.ClassLord && day.Observed.Rank == calendar.RankFeast {
tags = append(tags, "feast of the Lord")
}
if len(tags) == 0 {
continue
}
name := celebrationName(cfg, day.Observed)
fmt.Fprintf(out, " %s %s %-46s %s\n",
d.Format("2006-01-02"), d.Weekday().String()[:3], name, strings.Join(tags, " · "))
}
return 0
}
|