diff options
| -rw-r--r-- | README.md | 12 | ||||
| -rw-r--r-- | clectio.c | 67 |
2 files changed, 74 insertions, 5 deletions
@@ -18,14 +18,18 @@ the Go engine that computes and generates clectio's data. ./clectio 2026-12-25 # a given date ./clectio -g 2026-12-25 # the Gospel only ./clectio -a # all readings (override a Gospel-only build) + ./clectio --month # this month at a glance (day, colour, celebration) + ./clectio --month 2026-04 > apr.txt # a month to a file for reference make install # into $PREFIX/bin (default /usr/local) Needs only a C99 compiler and libc. It builds in about a second. -The only run-time options are `-a`/`--all`, `-g`/`--gospel` (which reading set -to print, overriding the compiled default) and `-h`/`--help`; everything else is -compile-time. Reading text wraps to the terminal width by default (see `WRAP`); -piped output is left one line per verse. +The run-time options are `-a`/`--all`, `-g`/`--gospel` (which reading set to +print, overriding the compiled default), `--month [YYYY-MM | N]` (one line per +day of a month — weekday, colour and celebration, no readings; defaults to the +current month) and `-h`/`--help`. Everything else is compile-time. Reading text +wraps to the terminal width by default (see `WRAP`); piped output is left one +line per verse. ## Configure (suckless style) @@ -107,6 +107,64 @@ static void putwrapped(const char *s, int w) { } } +/* One line per day of month `mon` in year `y`: weekday, day, colour, celebration. + * Needs no scripture text, so it never touches the text blob. Returns an exit + * code (1 if the month falls outside the compiled range). */ +static int print_month(int y, int mon) { + static const char *const wd[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; + long base = days_from_civil(EPOCH_Y, EPOCH_M, EPOCH_D); + long civ1 = days_from_civil(y, (unsigned)mon, 1); + long nextfirst = days_from_civil(mon == 12 ? y + 1 : y, (unsigned)(mon == 12 ? 1 : mon + 1), 1); + int dim = (int)(nextfirst - civ1); /* days in the month (leap-correct) */ + long off1 = civ1 - base; + int day, n; + + if (off1 < 0 || off1 + dim - 1 >= NDAYS) { + fprintf(stderr, "clectio: %04d-%02d is outside the compiled range %d..%d\n", + y, mon, EPOCH_Y, EPOCH_Y + (NDAYS / 366)); + return 1; + } + n = printf("%04d-%02d %s\n", y, mon, FORMNAME) - 1; /* underline that line */ + while (n-- > 0) + putchar('='); + putchar('\n'); + for (day = 1; day <= dim; day++) { + long civ = civ1 + (day - 1); + const Day *d = &days[cal[off1 + (day - 1)]]; + int w = (int)((civ + 4) % 7); /* 1970-01-01 was Thursday; 0 = Sunday */ + printf("%s %02d %-6s ", wd[w], day, colname[d->colour]); + if (usecolor) + printf("%s%s\033[0m\n", colansi[d->colour], names[d->name]); + else + printf("%s\n", names[d->name]); + } + return 0; +} + +/* Parse a --month spec ("YYYY-MM", or "N" for month N of the current year, or + * NULL for the current month) and print it. Returns an exit code. */ +static int run_month(const char *spec) { + struct tm tm; + time_t t = time(NULL); + int y, mon; + localtime_r(&t, &tm); + y = tm.tm_year + 1900; + mon = tm.tm_mon + 1; + if (spec) { + int ok = strchr(spec, '-') ? sscanf(spec, "%d-%d", &y, &mon) == 2 + : sscanf(spec, "%d", &mon) == 1; + if (!ok) { + fprintf(stderr, "clectio: bad month %s (want YYYY-MM or 1-12)\n", spec); + return 2; + } + } + if (mon < 1 || mon > 12) { + fprintf(stderr, "clectio: bad month %s (want YYYY-MM or 1-12)\n", spec ? spec : ""); + return 2; + } + return print_month(y, mon); +} + static void print_day(long off, const char *datestr, int gospel, int wrap) { const Day *d = &days[cal[off]]; unsigned ri; @@ -137,7 +195,7 @@ int main(int argc, char **argv) { int y, m, dd, i; int gospel = GOSPEL_ONLY; /* compiled default, overridable per run */ int istty = isatty(1); - int wrap; + int wrap, monthmode = 0; const char *datearg = NULL; usecolor = COLOR && istty; @@ -146,8 +204,10 @@ int main(int argc, char **argv) { if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { fprintf(stderr, "usage: clectio [-a|--all | -g|--gospel] [YYYY-MM-DD]\n" + " clectio --month [YYYY-MM | N]\n" " -a, --all print all readings\n" " -g, --gospel print the Gospel only\n" + " --month list a whole month (default: current month)\n" " (default: today, %s)\n" " compiled: %s, %s, wrap %s, range %d-%d\n", READMODE, FORMNAME, SIGLANAME, WRAPNAME, EPOCH_Y, EPOCH_Y + (NDAYS / 366)); @@ -156,6 +216,8 @@ int main(int argc, char **argv) { gospel = 0; } else if (!strcmp(argv[i], "-g") || !strcmp(argv[i], "--gospel")) { gospel = 1; + } else if (!strcmp(argv[i], "--month")) { + monthmode = 1; } else if (argv[i][0] == '-' && argv[i][1]) { fprintf(stderr, "clectio: unknown option %s (try -h)\n", argv[i]); return 2; @@ -167,6 +229,9 @@ int main(int argc, char **argv) { } } + if (monthmode) + return run_month(datearg); /* month overview: no readings, no text loaded */ + if (datearg) { if (sscanf(datearg, "%d-%d-%d", &y, &m, &dd) != 3) { fprintf(stderr, "clectio: bad date %s (want YYYY-MM-DD)\n", datearg); |
