aboutsummaryrefslogtreecommitdiff
path: root/module/vcomponent/recurrence/generate-alt.scm
diff options
context:
space:
mode:
authorHugo Hörnquist <hugo@lysator.liu.se>2020-05-13 00:41:08 +0200
committerHugo Hörnquist <hugo@lysator.liu.se>2020-05-13 00:41:08 +0200
commit76de8e988f64056eb03de2e02033e5f0f41a4931 (patch)
treef27dd11d22dec416b0c2f49138e1ad9fe79aed32 /module/vcomponent/recurrence/generate-alt.scm
parentAdd values-map. (diff)
downloadcalp-76de8e988f64056eb03de2e02033e5f0f41a4931.tar.gz
calp-76de8e988f64056eb03de2e02033e5f0f41a4931.tar.xz
RRULES with FREQ=MONTHLY and BYDAY now works in the extension case.
Diffstat (limited to '')
-rw-r--r--module/vcomponent/recurrence/generate-alt.scm51
1 files changed, 37 insertions, 14 deletions
diff --git a/module/vcomponent/recurrence/generate-alt.scm b/module/vcomponent/recurrence/generate-alt.scm
index c48a6c82..25aed205 100644
--- a/module/vcomponent/recurrence/generate-alt.scm
+++ b/module/vcomponent/recurrence/generate-alt.scm
@@ -75,11 +75,12 @@
(make-single-extender rr cc ...)] ...)]))
;; TODO compliacted fields
+;; rrule → (list extension-rule)
(define (all-extenders rrule)
(make-extenders
rrule
[YEARLY || month weekno yearday monthday #| day |# hour minute second]
- [MONTHLY || monthday #| day |# hour minute second]
+ [MONTHLY || monthday day hour minute second]
[WEEKLY || day hour minute second]
[DAILY || hour minute second]
[HOURLY || minute second]
@@ -105,10 +106,12 @@
(define (branching-fold proc init collection)
(if (null? collection)
init
- (let ((v (proc (car collection) init)))
- (if (list? v)
- (map (lambda (c) (branching-fold proc c (cdr collection))) v)
- (branching-fold proc v (cdr collection))))))
+ (call-with-values
+ (lambda () (proc (car collection) init))
+ (case-lambda
+ [(value) (branching-fold proc value (cdr collection))]
+ [values (map (lambda (c) (branching-fold proc c (cdr collection)))
+ values)]))))
;; TODO more special expands (p. 44)
;; (a := (date|datetime)), rrule, extension-rule → a
@@ -137,12 +140,13 @@
(byday rrule)
(not (or (byyearday rrule)
(bymonthday rrule))))
- (map to-dt
- (concatenate
- (map (lambda (wday)
- (all-wday-in-month
- wday (set (month d) value)))
- (map cdr (byday rrule)))))
+ (values-map
+ to-dt
+ (concatenate
+ (map (lambda (wday)
+ (all-wday-in-month
+ wday (set (month d) value)))
+ (map cdr (byday rrule)))))
;; else
(to-dt (set (month d) value)))]
@@ -156,10 +160,29 @@
;; TODO check that this actually is the correct calculation
(date day: (modulo (- value (wkst rrule))
7))))]
+
[(MONTHLY)
- ;; TODO
- dt
- ]
+ ;; if bymonthday is present byday turns into a limiter
+ (unless (bymonthday rrule)
+ (let* ((instances (all-wday-in-month value d)))
+ (catch 'out-of-range
+ (lambda ()
+ (cond [(eqv? #f offset)
+ ;; every of that day in this month
+ (values-map to-dt instances)]
+
+ [(positive? offset)
+ (to-dt (list-ref instances (1- offset)))]
+
+ [(negative? offset)
+ (to-dt (list-ref (reverse instances)
+ (1- (- offset))))]))
+
+ (lambda (err proc fmt args . rest)
+ (warning "BYDAY out of range for MONTHLY.
+ Possibly stuck in infinite loop")
+ dt))))]
+
[(YEARLY)
;; TODO
dt