unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* 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

* bug#6766: [PATCH] icalendar.el: Handle multiple BYDAY values in a WEEKLY RRULE.
  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
  0 siblings, 2 replies; 4+ messages in thread
From: Ulf Jasper @ 2010-08-08 18:01 UTC (permalink / raw)
  To: Stephen Peters; +Cc: 6766

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

Thanks!
Ulf





^ permalink raw reply	[flat|nested] 4+ messages in thread

* bug#6766: please close bug#6766
  2010-08-08 18:01 ` Ulf Jasper
@ 2010-08-09 18:15   ` Ulf Jasper
  2010-08-10  0:05   ` bug#6766: [PATCH] icalendar.el: Handle multiple BYDAY values in a WEEKLY RRULE Glenn Morris
  1 sibling, 0 replies; 4+ messages in thread
From: Ulf Jasper @ 2010-08-09 18:15 UTC (permalink / raw)
  To: 6766-done

thanks





^ permalink raw reply	[flat|nested] 4+ messages in thread

* bug#6766: [PATCH] icalendar.el: Handle multiple BYDAY values in a WEEKLY RRULE.
  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   ` Glenn Morris
  1 sibling, 0 replies; 4+ messages in thread
From: Glenn Morris @ 2010-08-10  0:05 UTC (permalink / raw)
  To: Ulf Jasper; +Cc: 6766, Stephen Peters

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.





^ permalink raw reply	[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).