From a675a983424f1f8d103fc12d55ef4f7129a92d62 Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Fri, 24 Jul 2026 13:07:37 +0200 Subject: qol: tui jump-to-date (d) + lectio --citation/--week + hide bt for traditional web; v0.10.0 --- internal/cli/cli.go | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 93 insertions(+), 1 deletion(-) (limited to 'internal/cli/cli.go') diff --git a/internal/cli/cli.go b/internal/cli/cli.go index 76ebd5b..611ce52 100644 --- a/internal/cli/cli.go +++ b/internal/cli/cli.go @@ -43,6 +43,8 @@ Flags: -P, --pager page reading output (like git); default from config --no-pager never page, even if config sets one --list list all books + abbreviations (dialect from sigla_style) + --citation print the day's gospel reference (scripts/cron) and exit + --week list the coming week's gospel references and exit -v, --version print the version and exit -h, --help this help @@ -59,6 +61,8 @@ Examples: lectio -p "Jn 3:16" -b vul look up a passage (English sigla) lectio -p "J 3,16" -c wuj,drb Polish sigla when sigla_style=polish/auto+pl UI lectio --list list every book + abbreviations + lectio --citation today's gospel reference + lectio --week 2026-07-22 a week of gospel references from a date Flags override config. Exit codes: 0 ok, 1 runtime error (fetch/parse), 2 usage error (bad flag, bad date, bad version, bad --lectionary/--lang). @@ -96,7 +100,7 @@ func Run(args []string, stdin io.Reader, stdout, stderr io.Writer) int { return 2 } - var all, raw, refresh, offline, update, clean, pagerFlag, noPager bool + var all, raw, refresh, offline, update, clean, pagerFlag, noPager, citation, week bool var bibleVer, compareList, lectionary, lang string var width int var list bool @@ -134,6 +138,8 @@ func Run(args []string, stdin io.Reader, stdout, stderr io.Writer) int { fs.StringVar(&ref, "p", "", "look up a passage, e.g. \"J 3:16\" (with -b/-c)") fs.StringVar(&ref, "ref", "", "look up a passage, e.g. \"J 3:16\" (with -b/-c)") fs.BoolVar(&list, "list", false, "list all books + abbreviations (in your sigla_style)") + fs.BoolVar(&citation, "citation", false, "print the day's gospel reference and exit") + fs.BoolVar(&week, "week", false, "list the coming week's gospel references and exit") if err := fs.Parse(rest); err != nil { return 2 @@ -175,6 +181,13 @@ func Run(args []string, stdin io.Reader, stdout, stderr io.Writer) int { cfg.TraditionalLang = lang } + if citation { + return runCitation(cfg, date, refresh, stdout, stderr) + } + if week { + return runWeek(cfg, date, refresh, stdout, stderr) + } + effAll := all || cfg.All effWidth := width if effWidth == 0 { @@ -250,6 +263,85 @@ func Run(args []string, stdin io.Reader, stdout, stderr io.Writer) int { return code } +// gospelSection returns the gospel section from a (gospel-only, All=false) +// load: the section tagged "ewangelia" (modern) or "evangelium" (traditional), +// else the first section present. ok is false only when secs is empty. +func gospelSection(secs []liturgy.Section) (liturgy.Section, bool) { + for _, s := range secs { + if s.PartID == "ewangelia" || s.PartID == "evangelium" { + return s, true + } + } + if len(secs) > 0 { + return secs[0], true + } + return liturgy.Section{}, false +} + +// gospelCitation returns a section's scripture reference: its Citation field if +// set, else the reference parsed out of its Heading (e.g. "Ewangelia (Mt 7, +// 1-5)" -> "Mt 7, 1-5"), else "" (source-form, never translated). +func gospelCitation(sec liturgy.Section) string { + if sec.Citation != "" { + return sec.Citation + } + if c, err := liturgy.ExtractCitation(sec.Heading); err == nil { + return c + } + return "" +} + +// runCitation handles --citation: fetch the day's gospel (gospel-only) and +// print just its scripture reference, for scripts/cron/prompt use. Honors the +// resolved cfg (lectionary/lang/offline) and date. Exit 1 if the day has no +// gospel reference (unpublished date, no network while offline, ...). +func runCitation(cfg config.Config, date string, refresh bool, stdout, stderr io.Writer) int { + secs, _, err := readings.Load(cfg, readings.Options{Date: date, Refresh: refresh, Offline: cfg.Offline, All: false}) + if err != nil { + fmt.Fprintln(stderr, "lectio:", err) + return 1 + } + sec, ok := gospelSection(secs) + if !ok { + fmt.Fprintln(stderr, "lectio: no gospel for", date) + return 1 + } + cit := gospelCitation(sec) + if cit == "" { + fmt.Fprintln(stderr, "lectio: no gospel reference for", date) + return 1 + } + fmt.Fprintln(stdout, cit) + return 0 +} + +// runWeek handles --week: print the gospel reference for each of the seven days +// starting at date, one "YYYY-MM-DD " line per day. A day that +// can't be loaded (unpublished, offline gap, no gospel) shows "—" rather than +// aborting the run, so the list is always seven lines. Honors cfg +// (lectionary/lang/offline). +func runWeek(cfg config.Config, date string, refresh bool, stdout, stderr io.Writer) int { + start, err := time.Parse("2006-01-02", date) + if err != nil { + fmt.Fprintln(stderr, "lectio:", err) + return 2 + } + for i := 0; i < 7; i++ { + d := start.AddDate(0, 0, i).Format("2006-01-02") + cit := "—" + secs, _, err := readings.Load(cfg, readings.Options{Date: d, Refresh: refresh, Offline: cfg.Offline, All: false}) + if err == nil { + if sec, ok := gospelSection(secs); ok { + if c := gospelCitation(sec); c != "" { + cit = c + } + } + } + fmt.Fprintf(stdout, "%s %s\n", d, cit) + } + return 0 +} + // userBooksTOML returns the bytes of the optional user books.toml, or nil if // it is absent/unreadable (built-in defaults are used). func userBooksTOML() []byte { -- cgit v1.3