GNU bug report logs - #6766
[PATCH] icalendar.el: Handle multiple BYDAY values in a WEEKLY RRULE.

Previous Next

Package: emacs;

Reported by: speters <at> itasoftware.com (Stephen Peters)

Date: Fri, 30 Jul 2010 20:41:01 UTC

Severity: normal

Tags: patch

Done: Ulf Jasper <ulf.jasper <at> web.de>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 6766 in the body.
You can then email your comments to 6766 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to owner <at> debbugs.gnu.org, bug-gnu-emacs <at> gnu.org:
bug#6766; Package emacs. (Fri, 30 Jul 2010 20:41:01 GMT) Full text and rfc822 format available.

Acknowledgement sent to speters <at> itasoftware.com (Stephen Peters):
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Fri, 30 Jul 2010 20:41:01 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: speters <at> itasoftware.com (Stephen Peters)
To: bug-gnu-emacs <at> gnu.org
Subject: [PATCH] icalendar.el: Handle multiple BYDAY values in a WEEKLY RRULE.
Date: Thu, 29 Jul 2010 15:13:10 -0400 (EDT)
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")




Information forwarded to owner <at> debbugs.gnu.org, bug-gnu-emacs <at> gnu.org:
bug#6766; Package emacs. (Sun, 08 Aug 2010 18:01:01 GMT) Full text and rfc822 format available.

Message #8 received at 6766 <at> debbugs.gnu.org (full text, mbox):

From: Ulf Jasper <ulf.jasper <at> web.de>
To: speters <at> itasoftware.com (Stephen Peters)
Cc: 6766 <at> debbugs.gnu.org
Subject: Re: [PATCH] icalendar.el: Handle multiple BYDAY values in a WEEKLY
	RRULE.
Date: Sun, 08 Aug 2010 20:01:23 +0200
Applied your patch and added unit test using your ics data.

Thanks!
Ulf




Reply sent to Ulf Jasper <ulf.jasper <at> web.de>:
You have taken responsibility. (Mon, 09 Aug 2010 18:16:02 GMT) Full text and rfc822 format available.

Notification sent to speters <at> itasoftware.com (Stephen Peters):
bug acknowledged by developer. (Mon, 09 Aug 2010 18:16:02 GMT) Full text and rfc822 format available.

Message #13 received at 6766-done <at> debbugs.gnu.org (full text, mbox):

From: Ulf Jasper <ulf.jasper <at> web.de>
To: 6766-done <at> debbugs.gnu.org
Subject: please close bug#6766
Date: Mon, 09 Aug 2010 20:15:42 +0200
thanks




Information forwarded to owner <at> debbugs.gnu.org, bug-gnu-emacs <at> gnu.org:
bug#6766; Package emacs. (Tue, 10 Aug 2010 00:05:02 GMT) Full text and rfc822 format available.

Message #16 received at 6766 <at> debbugs.gnu.org (full text, mbox):

From: Glenn Morris <rgm <at> gnu.org>
To: Ulf Jasper <ulf.jasper <at> web.de>
Cc: 6766 <at> debbugs.gnu.org, Stephen Peters <speters <at> itasoftware.com>
Subject: Re: bug#6766: [PATCH] icalendar.el: Handle multiple BYDAY values in a
	WEEKLY RRULE.
Date: Mon, 09 Aug 2010 20:05:02 -0400
Ulf Jasper wrote:

> Applied your patch and added unit test using your ics data.

When applying changes written by other people, please make the
ChangeLog entry in their name, not yours. Also, at first glance this
is not a tiny change and so would need some copyright paperwork.




bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Tue, 07 Sep 2010 11:24:04 GMT) Full text and rfc822 format available.

This bug report was last modified 15 years and 6 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.