From 8bb075153d15fc14f946dd1e159e00eacc266b89 Mon Sep 17 00:00:00 2001 From: Paolo Donadeo Date: Sun, 24 May 2026 18:15:38 +0200 Subject: [PATCH] docs: fix yearly recurrence format and clarify sort/limitations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix `REM Mon DD` → `REM MMM DD` in yearly recurrence table - Clarify `--sort original` preserves processing order in CLI reference - Update `RELATED=END` trigger behaviour (treated as `RELATED=START`) - Remove unsupported EXDATE/RDATE+override limitation (now handled) - Fix `--sort none` → `--sort original` in CLI help text - Remove EXDATE/RDATE/override guard from `simple_recurrence` --- README.md | 7 +++--- bin/commandLine.ml | 2 +- bin/eventPredicates.ml | 53 +++++++++++++++++++----------------------- 3 files changed, 28 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index de57c72..ff04a70 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ Full RFC 5545 coverage is intentionally out of scope — see [Limitations](#limi | All-day single | `REM YYYY-MM-DD MSG …` | | All-day multi-day | `REM date THROUGH date MSG …` | | Timed event (UTC, local, TZID) | `REM date AT HH:MM DURATION HH:MM MSG …` | -| Yearly recurrence (`FREQ=YEARLY`) | `REM Mon DD MSG …` | +| Yearly recurrence (`FREQ=YEARLY`) | `REM MMM DD MSG …` | | Weekly recurrence (`FREQ=WEEKLY`) | `REM Mon Wed FROM … UNTIL … MSG …` | | Daily recurrence (`FREQ=DAILY`) | `REM date *N UNTIL … MSG …` | | Monthly by day-of-month (`BYMONTHDAY`) | `REM N FROM … UNTIL … MSG …` | @@ -115,7 +115,7 @@ ical2rem --verbose personal.ics > personal.rem |---|---| | `FILE…` | One or more `.ics` files to convert | | `-z`, `--timezone TZ` | Target timezone for output (default: local) | -| `--sort asc\|desc\|original` | Sort order by date (default: `desc`) | +| `--sort asc\|desc\|original` | Sort order by date (default: `desc`); `original` preserves processing order (sorted by UID within each file, last file first) | | `--source NAME` | Override calendar name (single file only) | | `-v`, `--verbose` | Print diagnostic messages on stderr | | `--no-uuid` | Omit `INFO "UID: …"` lines | @@ -184,14 +184,13 @@ REM \ - `BYSETPOS`: **not supported**. - `FREQ=YEARLY` with `BYMONTH`/`BYDAY` variants: **not supported**, only simple yearly (same day every year). - `RDATE` (additional isolated dates): **not supported**, warning emitted. -- Recurring events that have both EXDATE/RDATE and override occurrences (`RECURRENCE-ID`): **not supported**, event skipped with warning. ### Alarms (`VALARM`) - `ACTION:EMAIL`: ignored silently. - `TRIGGER;VALUE=DATE-TIME` (absolute datetime trigger): ignored silently. - Positive triggers (after the event): ignored silently. -- `RELATED=END` triggers: **not implemented**. +- `RELATED=END` triggers: the offset is applied as if it were `RELATED=START` (no warning emitted). - `REPEAT`/`DURATION` (repeating alarms) on all-day events: ignored. ### Other diff --git a/bin/commandLine.ml b/bin/commandLine.ml index e69e438..6827619 100644 --- a/bin/commandLine.ml +++ b/bin/commandLine.ml @@ -43,7 +43,7 @@ type sort_order = Asc | Desc | Original let sort_order_enum = [ ("asc", Asc); ("desc", Desc); ("original", Original) ] let sort = - let doc = "Output sort order by date: $(b,desc) (default), $(b,asc), or $(b,none) (file order)." in + let doc = "Output sort order by date: $(b,desc) (default), $(b,asc), or $(b,original) (processing order)." in Arg.(value & opt (enum sort_order_enum) Desc & info [ "sort" ] ~docv:"ORDER" ~doc) let source = diff --git a/bin/eventPredicates.ml b/bin/eventPredicates.ml index 049c05d..ea53607 100644 --- a/bin/eventPredicates.ml +++ b/bin/eventPredicates.ml @@ -126,35 +126,30 @@ let simple_recurrence rem ev : (Remind.rem, error) result = match ev.rrule with | Some (_, (`Yearly, None, None, [])) -> Ok rem (* handled in yearly_simple_date *) | Some (_, ((`Weekly as freq), count_or_until, interval, recurs)) - | Some (_, ((`Daily as freq), count_or_until, interval, recurs)) -> - begin if List.length rem.recurring > 0 then ( - Utils.warn "Warning: complex recurrence with EXDATE/RDATE/overrides not supported, skipping (UID: %s)\n" - (Utils.get_uid ev); - skip) - else - let days = - ListLabels.filter_map recurs ~f:(function - | `Byday days -> begin List.map (fun (_n, weekday) -> weekday) days |> Option.some end - | _ -> None) - |> List.flatten - in - let week_start = - ListLabels.find_map recurs ~f:(function - | `Weekday `Sunday -> Some `Sunday - | `Weekday `Monday -> Some `Monday - | _ -> None) - in - match freq with - | `Daily -> Ok { rem with Remind.weekly = None; Remind.daily = Some { count_or_until; interval; week_start } } - | `Weekly -> - let days = if days = [] then [ timedesc_wd_to_ical (Timedesc.Date.weekday rem.date) ] else days in - Ok - { - rem with - Remind.daily = None; - Remind.weekly = Some { count_or_until; interval; byday = days; week_start }; - } - end + | Some (_, ((`Daily as freq), count_or_until, interval, recurs)) -> begin + let days = + ListLabels.filter_map recurs ~f:(function + | `Byday days -> begin List.map (fun (_n, weekday) -> weekday) days |> Option.some end + | _ -> None) + |> List.flatten + in + let week_start = + ListLabels.find_map recurs ~f:(function + | `Weekday `Sunday -> Some `Sunday + | `Weekday `Monday -> Some `Monday + | _ -> None) + in + match freq with + | `Daily -> Ok { rem with Remind.weekly = None; Remind.daily = Some { count_or_until; interval; week_start } } + | `Weekly -> + let days = if days = [] then [ timedesc_wd_to_ical (Timedesc.Date.weekday rem.date) ] else days in + Ok + { + rem with + Remind.daily = None; + Remind.weekly = Some { count_or_until; interval; byday = days; week_start }; + } + end | Some (_, (`Monthly, count_or_until, interval, recurs)) -> begin match interval with | Some n when n > 1 ->