diff --git a/README.md b/README.md index 66bcca5..99282da 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,8 @@ Everything derives from the paschalion and the fixed calendar, so it needs no network, cannot go stale, and answers for any year you ask about. No API key, no service that might be gone next year, no cache to invalidate. +![typikon on the command line](docs/cli.png) + ```console $ typikon Wednesday 18 March 2026 — 5 March in the church calendar @@ -178,7 +180,9 @@ prints, your parish is right. Please open an issue. ## Front ends [`horologion`](https://git.pumpin.online/funkpower/horologion) — desktop -widgets for Hyprland (Quickshell), waybar and eww. +widgets for Hyprland (Quickshell), waybar and eww, all reading the JSON above. + +![The horologion widget](https://git.pumpin.online/funkpower/horologion/raw/branch/main/docs/nativity-fast.png) ## Licence diff --git a/docs/cli.png b/docs/cli.png new file mode 100644 index 0000000..f339f5d Binary files /dev/null and b/docs/cli.png differ diff --git a/typikon/cli.py b/typikon/cli.py index 2bb2393..ad07158 100644 --- a/typikon/cli.py +++ b/typikon/cli.py @@ -2,6 +2,7 @@ import argparse import datetime as dt +import shutil import sys from . import config @@ -33,6 +34,16 @@ def _list_jurisdictions(): print() +def _elide(text, width): + """Cut on a word boundary and say so, rather than stopping mid-word.""" + if len(text) <= width: + return text + cut = text[:width - 1] + if " " in cut[width // 2:]: + cut = cut[:cut.rstrip().rfind(" ")] + return cut.rstrip(" ,;") + "\u2026" + + def _wrap(text, width): words, line, out = text.split(), "", [] for w in words: @@ -81,10 +92,14 @@ def _print_days(days, jur, rule, source, verbose): return print(f"\n {jur.name} · {rule['title']}\n") + # The glyph is two columns wide in a terminal and one character to Python, + # which is why the arithmetic below looks off by one. + fixed = 2 + 2 + 10 + 1 + 1 + 32 + room = max(24, shutil.get_terminal_size((100, 24)).columns - fixed - 1) for d in days: mark = "*" if d.obligation == OBLIGATORY else " " when = d.date.strftime("%a %-d %b") - print(f" {d.emoji} {when:>10}{mark} {d.fast_label:<32}{d.title[:44]}") + print(f" {d.emoji} {when:>10}{mark} {d.fast_label:<32}{_elide(d.title, room)}") if any(d.obligation == OBLIGATORY for d in days): print("\n * obligatory. Everything unmarked is customary and does not bind.") print()