Function: icalendar--convert-recurring-to-diary
icalendar--convert-recurring-to-diary is a byte-compiled function
defined in icalendar.el.gz.
Signature
(icalendar--convert-recurring-to-diary E DTSTART-DEC START-T END-T)
Documentation
Convert recurring iCalendar event E to diary format.
DTSTART-DEC is the DTSTART property of E. START-T is the event's start time in diary format. END-T is the event's end time in diary format.
Source Code
;; Defined in /usr/src/emacs/lisp/calendar/icalendar.el.gz
;; subroutines for importing
(defun icalendar--convert-recurring-to-diary (e dtstart-dec start-t end-t)
"Convert recurring iCalendar event E to diary format.
DTSTART-DEC is the DTSTART property of E.
START-T is the event's start time in diary format.
END-T is the event's end time in diary format."
(icalendar--dmsg "recurring event")
(let* ((rrule (icalendar--get-event-property e 'RRULE))
(rrule-props (icalendar--split-value rrule))
(frequency (cadr (assoc 'FREQ rrule-props)))
(until (cadr (assoc 'UNTIL rrule-props)))
(count (cadr (assoc 'COUNT rrule-props)))
(interval (read (or (cadr (assoc 'INTERVAL rrule-props)) "1")))
(dtstart-conv (icalendar--datetime-to-diary-date dtstart-dec))
(until-conv (icalendar--datetime-to-diary-date
(icalendar--decode-isodatetime until)))
(until-1-conv (icalendar--datetime-to-diary-date
(icalendar--decode-isodatetime until -1)))
(result ""))
;; FIXME FIXME interval!!!!!!!!!!!!!
(when count
(if until
(message "Must not have UNTIL and COUNT -- ignoring COUNT element!")
(let ((until-1 0))
(cond ((string-equal frequency "DAILY")
(setq until (icalendar--add-decoded-times
dtstart-dec
(list 0 0 0 (* (read count) interval) 0 0)))
(setq until-1 (icalendar--add-decoded-times
dtstart-dec
(list 0 0 0 (* (- (read count) 1) interval)
0 0)))
)
((string-equal frequency "WEEKLY")
(setq until (icalendar--add-decoded-times
dtstart-dec
(list 0 0 0 (* (read count) 7 interval) 0 0)))
(setq until-1 (icalendar--add-decoded-times
dtstart-dec
(list 0 0 0 (* (- (read count) 1) 7
interval) 0 0)))
)
((string-equal frequency "MONTHLY")
(setq until (icalendar--add-decoded-times
dtstart-dec (list 0 0 0 0 (* (- (read count) 1)
interval) 0)))
(setq until-1 (icalendar--add-decoded-times
dtstart-dec (list 0 0 0 0 (* (- (read count) 1)
interval) 0)))
)
((string-equal frequency "YEARLY")
(setq until (icalendar--add-decoded-times
dtstart-dec (list 0 0 0 0 0 (* (- (read count) 1)
interval))))
(setq until-1 (icalendar--add-decoded-times
dtstart-dec
(list 0 0 0 0 0 (* (- (read count) 1)
interval))))
)
(t
(message "Cannot handle COUNT attribute for `%s' events."
frequency)))
(setq until-conv (icalendar--datetime-to-diary-date until))
(setq until-1-conv (icalendar--datetime-to-diary-date until-1))
))
)
(cond ((string-equal frequency "WEEKLY")
(let* ((byday (cadr (assoc 'BYDAY rrule-props)))
(weekdays
(icalendar--get-weekday-numbers byday))
(weekday-clause
(when (> (length weekdays) 1)
(format "(memq (calendar-day-of-week date) '%s) "
weekdays))))
(if (not start-t)
(progn
;; weekly and all-day
(icalendar--dmsg "weekly all-day")
(if until
(setq result
(format
(concat "%%%%(and "
"%s"
"(diary-block %s %s))")
(or weekday-clause
(format "(diary-cyclic %d %s) "
(* interval 7)
dtstart-conv))
dtstart-conv
(if count until-1-conv until-conv)
))
(setq result
(format "%%%%(and %s(diary-cyclic %d %s))"
(or weekday-clause "")
(if weekday-clause 1 (* interval 7))
dtstart-conv))))
;; weekly and not all-day
(icalendar--dmsg "weekly not-all-day")
(if until
(setq result
(format
(concat "%%%%(and "
"%s"
"(diary-block %s %s)) "
"%s%s%s")
(or weekday-clause
(format "(diary-cyclic %d %s) "
(* interval 7)
dtstart-conv))
dtstart-conv
until-conv
(or start-t "")
(if end-t "-" "") (or end-t "")))
;; no limit
;; FIXME!!!!
;; DTSTART;VALUE=DATE-TIME:20030919T090000
;; DTEND;VALUE=DATE-TIME:20030919T113000
(setq result
(format
"%%%%(and %s(diary-cyclic %d %s)) %s%s%s"
(or weekday-clause "")
(if weekday-clause 1 (* interval 7))
dtstart-conv
(or start-t "")
(if end-t "-" "") (or end-t "")))))))
;; yearly
((string-equal frequency "YEARLY")
(icalendar--dmsg "yearly")
(if until
(let ((day (nth 3 dtstart-dec))
(month (nth 4 dtstart-dec)))
(setq result (concat "%%(and (diary-date "
(cond ((eq calendar-date-style 'iso)
(format "t %d %d" month day))
((eq calendar-date-style 'european)
(format "%d %d t" day month))
((eq calendar-date-style 'american)
(format "%d %d t" month day)))
") (diary-block "
dtstart-conv
" "
until-conv
")) "
(or start-t "")
(if end-t "-" "")
(or end-t ""))))
(setq result (format
"%%%%(diary-anniversary %s) %s%s%s"
(let* ((year (nth 5 dtstart-dec))
(dtstart-1y-dec (copy-sequence dtstart-dec)))
(setf (nth 5 dtstart-1y-dec) (1- year))
(icalendar--datetime-to-diary-date dtstart-1y-dec))
(or start-t "")
(if end-t "-" "") (or end-t "")))))
;; monthly
((string-equal frequency "MONTHLY")
(icalendar--dmsg "monthly")
(let* ((byday (cadr (assoc 'BYDAY rrule-props)))
(count-weekday
(and byday
(save-match-data
(when (string-match "\\(-?[0-9]+\\)\\([A-Z][A-Z]\\)"
byday)
(cons (substring byday
(match-beginning 1)
(match-end 1))
(substring byday
(match-beginning 2)
(match-end 2)))))))
(rule-part
(if count-weekday
(let ((count (car count-weekday))
(weekdaynum (icalendar--get-weekday-number
(cdr count-weekday))))
;; FIXME: this is valid only for interval==1
(format "(diary-float t %s %s)" weekdaynum count))
(format "(diary-date %s)"
(let ((day (nth 3 dtstart-dec)))
(cond ((eq calendar-date-style 'iso)
(format "t t %d" day))
((eq calendar-date-style 'european)
(format "%d t t" day))
((eq calendar-date-style 'american)
(format "t %d t" day))))))))
(setq result
(format
"%%%%(and %s (diary-block %s %s)) %s%s%s"
rule-part
dtstart-conv
(if until
until-conv
(if (eq calendar-date-style 'iso) "9999 1 1" "1 1 9999")) ;; FIXME: should be unlimited
(or start-t "")
(if end-t "-" "") (or end-t "")))))
;; daily
((and (string-equal frequency "DAILY"))
(if until
(setq result
(format
(concat "%%%%(and (diary-cyclic %s %s) "
"(diary-block %s %s)) %s%s%s")
interval dtstart-conv dtstart-conv
(if count until-1-conv until-conv)
(or start-t "")
(if end-t "-" "") (or end-t "")))
(setq result
(format
"%%%%(and (diary-cyclic %s %s)) %s%s%s"
interval
dtstart-conv
(or start-t "")
(if end-t "-" "") (or end-t ""))))))
;; Handle exceptions from recurrence rules
(let ((ex-dates (icalendar--get-event-properties e 'EXDATE)))
(while ex-dates
(let* ((ex-start (icalendar--decode-isodatetime
(car ex-dates)))
(ex-d (icalendar--datetime-to-diary-date
ex-start)))
(setq result
(replace-regexp-in-string "^%%(\\(and \\)?"
(format
"%%%%(and (not (diary-date %s)) "
ex-d)
result)))
(setq ex-dates (cdr ex-dates))))
;; FIXME: exception rules are not recognized
(if (icalendar--get-event-property e 'EXRULE)
(setq result
(concat result
"\n Exception rules: "
(icalendar--get-event-properties
e 'EXRULE))))
result))