aboutsummaryrefslogtreecommitdiff
path: root/module/vcomponent/xcal/parse.scm
diff options
context:
space:
mode:
Diffstat (limited to 'module/vcomponent/xcal/parse.scm')
-rw-r--r--module/vcomponent/xcal/parse.scm139
1 files changed, 98 insertions, 41 deletions
diff --git a/module/vcomponent/xcal/parse.scm b/module/vcomponent/xcal/parse.scm
index 124a91f4..c6a2122f 100644
--- a/module/vcomponent/xcal/parse.scm
+++ b/module/vcomponent/xcal/parse.scm
@@ -49,40 +49,68 @@
((@ (vcomponent duration) parse-duration) duration))])]
[(recur)
- (apply (@ (vcomponent recurrence internal) make-recur-rule)
- (concatenate
- (for (k v) in value
- (list (symbol->keyword k)
- (case k
- ((wkst)
- ((@ (vcomponent recurrence parse)
- rfc->datetime-weekday)
- (string->symbol v)))
- ((freq) (string->symbol v))
- ((until)
- ;; RFC 6321 (xcal), p. 30 specifies type-until as
- ;; type-until = element until {
- ;; type-date |
- ;; type-date-time
- ;; }
- ;; but doesn't bother defining type-date[-time]...
- ;; This is acknowledged in errata 3315 [1], but
- ;; it lacks a solution...
- ;; Seeing as RFC 7265 (jcal) in Example 2 (p. 16)
- ;; show the date as a direct string we will roll
- ;; with that here to.
- ;; [1]: https://www.rfc-editor.org/errata/eid3315
- (string->date/-time v))
- ((byday) #|TODO|#
- (throw 'not-yet-implemented))
- ((count interval bysecond bymunite byhour
- bymonthday byyearday byweekno
- bymonth bysetpos)
- (string->number v))
- (else (throw
- 'key-error
- "Invalid key ~a, with value ~a"
- k v)))))))]
+ ;; RFC6221 (xcal) Appendix A 3.3.10 specifies that all components should
+ ;; come in a specified order, and by extension that all components of the
+ ;; same type should follow each other. Actually checking that is harder
+ ;; than to just accept anything in any order. It would also make us less
+ ;; robust for other implementations with other ideas.
+ (let ((parse-value-of-that-type
+ (lambda (type value)
+ (case type
+ ((wkst)
+ ((@ (vcomponent recurrence parse)
+ rfc->datetime-weekday)
+ (string->symbol value)))
+ ((freq) (string->symbol value))
+ ((until)
+ ;; RFC 6321 (xcal), p. 30 specifies type-until as
+ ;; type-until = element until {
+ ;; type-date |
+ ;; type-date-time
+ ;; }
+ ;; but doesn't bother defining type-date[-time]...
+ ;; This is acknowledged in errata 3315 [1], but
+ ;; it lacks a solution...
+ ;; Seeing as RFC 7265 (jcal) in Example 2 (p. 16)
+ ;; show the date as a direct string we will roll
+ ;; with that here to.
+ ;; [1]: https://www.rfc-editor.org/errata/eid3315
+ (string->date/-time value))
+ ((byday) ((@@ (vcomponent recurrence parse) parse-day-spec) value))
+ ((count interval bysecond bymunite byhour
+ bymonthday byyearday byweekno
+ bymonth bysetpos)
+ (string->number value))
+ (else (throw
+ 'key-error
+ "Invalid type ~a, with value ~a"
+ type value))))))
+
+ ;; freq until count interval wkst
+
+ (apply (@ (vcomponent recurrence internal) make-recur-rule)
+ (concatenate
+ (filter identity
+ (for key in '(bysecond byminute byhour byday bymonthday
+ byyearday byweekno bymonth bysetpos
+ freq until count interval wkst)
+ (define values (assoc-ref-all value key))
+ (if (null? values)
+ #f
+ (case key
+ ;; These fields all have zero or one value
+ ((freq until count interval wkst)
+ (list (symbol->keyword key)
+ (parse-value-of-that-type
+ key (car (map car values)))))
+ ;; these fields take lists
+ ((bysecond byminute byhour byday bymonthday
+ byyearday byweekno bymonth bysetpos)
+ (list (symbol->keyword key)
+ (map (lambda (v) (parse-value-of-that-type key v))
+ (map car values)))
+ )
+ (else (throw 'error)))))))))]
[(time) (parse-iso-time (car value))]
@@ -171,11 +199,25 @@
;; ignore empty fields
;; mostly for <text/>
(unless (null? value)
- (set! (prop* component tag*)
- (make-vline tag*
- (handle-tag
- tag (handle-value type params value))
- params)))))]
+ (let ()
+ (define vline
+ (make-vline tag*
+ (handle-tag
+ tag (handle-value type params value))
+ params))
+ (if (memv tag* '(ATTACH ATTENDEE CATEGORIES
+ COMMENT CONTACT EXDATE
+ REQUEST-STATUS RELATED-TO
+ RESOURCES RDATE
+ ;; x-prop
+ ;; iana-prop
+ ))
+ (aif (prop* component tag*)
+ (set! (prop* component tag*) (cons vline it))
+ (set! (prop* component tag*) (list vline)))
+ ;; else
+ (set! (prop* component tag*) vline))
+ ))))]
[(tag (type value ...) ...)
(for (type value) in (zip type value)
@@ -184,7 +226,7 @@
(unless (null? value)
(let ((params (make-hash-table))
(tag* (symbol-upcase tag)))
- (set! (prop* component tag*)
+ (define vline
(make-vline tag*
(handle-tag
tag (let ((v (handle-value type params value)))
@@ -192,7 +234,22 @@
(if (eq? tag 'categories)
(string-split v #\,)
v)))
- params)))))])))
+ params))
+ ;;
+
+ (if (memv tag* '(ATTACH ATTENDEE CATEGORIES
+ COMMENT CONTACT EXDATE
+ REQUEST-STATUS RELATED-TO
+ RESOURCES RDATE
+ ;; x-prop
+ ;; iana-prop
+ ))
+ (aif (prop* component tag*)
+ (set! (prop* component tag*) (cons vline it))
+ (set! (prop* component tag*) (list vline)))
+ ;; else
+ (set! (prop* component tag*) vline))
+ )))])))
;; children
(awhen (assoc-ref sxcal 'components)