* bug#6766: [PATCH] icalendar.el: Handle multiple BYDAY values in a WEEKLY RRULE.
@ 2010-07-29 19:13 Stephen Peters
2010-08-08 18:01 ` Ulf Jasper
0 siblings, 1 reply; 4+ messages in thread
From: Stephen Peters @ 2010-07-29 19:13 UTC (permalink / raw)
To: 6766
When trying to use icalendar-import-file to create a diary file from my
work calendar, I noticed that recurring events for multiple days in a
week were not properly handled. Here's an example .ics file,
including both timed and all-day events:
----------z.ics----------
BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VTIMEZONE
TZID:America/New_York
BEGIN:STANDARD
DTSTART:19710101T020000
RRULE:FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=11;BYDAY=1SU
TZNAME:EST
TZOFFSETFROM:-0400
TZOFFSETTO:-0500
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:19710101T020000
RRULE:FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=3;BYDAY=2SU
TZNAME:EDT
TZOFFSETFROM:-0500
TZOFFSETTO:-0400
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VEVENT
CLASS:PUBLIC
DTEND;TZID=America/New_York:20100421T120000
DTSTAMP:20100525T141214Z
DTSTART;TZID=America/New_York:20100421T113000
RRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=MO,WE,TH,FR
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:Scrum
TRANSP:OPAQUE
UID:8814e3f9-7482-408f-996c-3bfe486a1262
END:VEVENT
BEGIN:VEVENT
CLASS:PUBLIC
DTSTAMP:20100525T141214Z
DTSTART;VALUE=DATE:20100422
DTEND;VALUE=DATE:20100423
RRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=TU,TH
SEQUENCE:1
SUMMARY:Tues + Thurs thinking
TRANSP:OPAQUE
UID:8814e3f9-7482-408f-996c-3bfe486a1263
END:VEVENT
END:VCALENDAR
==========z.ics==========
Using icalendar-import-file on this .ics file will create diary
entries that only repeat once a week, not the multiple days per week
that are indicated.
To fix this, I'm submitting a patch to icalendar.el which will parse
multiple days from the BYDAY property and use it to create a diary
entry based on the calendar-day-of-week value.
Please note that this also changes the icalendar--split-value function
so that it doesn't stop at the first comma in VALUE-STRING.
diff --git a/lisp/calendar/icalendar.el b/lisp/calendar/icalendar.el
index a07402a..f7ae466 100644
--- a/lisp/calendar/icalendar.el
+++ b/lisp/calendar/icalendar.el
@@ -427,7 +427,7 @@ children."
(goto-char (point-min))
(while
(re-search-forward
- "\\([A-Za-z0-9-]+\\)=\\(\\([^;,:]+\\)\\|\"\\([^\"]+\\)\"\\);?"
+ "\\([A-Za-z0-9-]+\\)=\\(\\([^;:]+\\)\\|\"\\([^\"]+\\)\"\\);?"
nil t)
(setq param-name (intern (match-string 1)))
(setq param-value (match-string 2))
@@ -744,6 +744,19 @@ Note that this silently ignores seconds."
;; Error:
-1))
+(defun icalendar--get-weekday-numbers (abbrevweekdays)
+ "Return the list of numbers for the comma-separated ABBREVWEEKDAYS."
+ (let* ((num -1)
+ (weekday-alist (mapcar (lambda (day)
+ (progn
+ (setq num (1+ num))
+ (cons (downcase day) num)))
+ icalendar--weekday-array)))
+ (delq nil
+ (mapcar (lambda (abbrevday)
+ (cdr (assoc abbrevday weekday-alist)))
+ (split-string (downcase abbrevweekdays) ",")))))
+
(defun icalendar--get-weekday-abbrev (weekday)
"Return the abbreviated WEEKDAY."
(catch 'found
@@ -2057,39 +2070,47 @@ END-T is the event's end time in diary format."
))
)
(cond ((string-equal frequency "WEEKLY")
- (if (not start-t)
- (progn
- ;; weekly and all-day
- (icalendar--dmsg "weekly all-day")
- (if until
- (setq result
- (format
- (concat "%%%%(and "
- "(diary-cyclic %d %s) "
- "(diary-block %s %s))")
- (* interval 7)
- dtstart-conv
- dtstart-conv
- (if count until-1-conv until-conv)
- ))
- (setq result
- (format "%%%%(and (diary-cyclic %d %s))"
- (* interval 7)
- dtstart-conv))))
- ;; weekly and not all-day
- (let* ((byday (cadr (assoc 'BYDAY rrule-props)))
- (weekday
- (icalendar--get-weekday-number byday)))
+ (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))
+ (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 "
- "(diary-cyclic %d %s) "
+ "%s"
"(diary-block %s %s)) "
"%s%s%s")
- (* interval 7)
- dtstart-conv
+ (or weekday-clause
+ (format "(diary-cyclic %d %s) "
+ (* interval 7)
+ dtstart-conv))
dtstart-conv
until-conv
(or start-t "")
@@ -2100,10 +2121,11 @@ END-T is the event's end time in diary format."
;; DTEND;VALUE=DATE-TIME:20030919T113000
(setq result
(format
- "%%%%(and (diary-cyclic %s %s)) %s%s%s"
- (* interval 7)
- dtstart-conv
- (or start-t "")
+ "%%%%(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")
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2010-08-10 0:05 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-07-29 19:13 bug#6766: [PATCH] icalendar.el: Handle multiple BYDAY values in a WEEKLY RRULE Stephen Peters
2010-08-08 18:01 ` Ulf Jasper
2010-08-09 18:15 ` bug#6766: please close bug#6766 Ulf Jasper
2010-08-10 0:05 ` bug#6766: [PATCH] icalendar.el: Handle multiple BYDAY values in a WEEKLY RRULE Glenn Morris
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).