From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: speters@itasoftware.com (Stephen Peters) Newsgroups: gmane.emacs.bugs Subject: bug#6766: [PATCH] icalendar.el: Handle multiple BYDAY values in a WEEKLY RRULE. Date: Thu, 29 Jul 2010 15:13:10 -0400 (EDT) Message-ID: <20100729191310.AFCA45D038C@leng-speters> NNTP-Posting-Host: lo.gmane.org X-Trace: dough.gmane.org 1280528558 19329 80.91.229.12 (30 Jul 2010 22:22:38 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Fri, 30 Jul 2010 22:22:38 +0000 (UTC) To: 6766@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Sat Jul 31 00:22:37 2010 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1OexyM-0006Bo-Tf for geb-bug-gnu-emacs@m.gmane.org; Sat, 31 Jul 2010 00:22:35 +0200 Original-Received: from localhost ([127.0.0.1]:35505 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OexyM-0007SV-Ap for geb-bug-gnu-emacs@m.gmane.org; Fri, 30 Jul 2010 18:22:34 -0400 Original-Received: from [140.186.70.92] (port=42401 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Oewo5-0006ON-LL for bug-gnu-emacs@gnu.org; Fri, 30 Jul 2010 17:07:55 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1Oewo3-0006FA-Kq for bug-gnu-emacs@gnu.org; Fri, 30 Jul 2010 17:07:52 -0400 Original-Received: from debbugs.gnu.org ([140.186.70.43]:53102) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Oewo3-0006F6-JS for bug-gnu-emacs@gnu.org; Fri, 30 Jul 2010 17:07:51 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.69) (envelope-from ) id 1OewO5-00010x-TC; Fri, 30 Jul 2010 16:41:01 -0400 X-Loop: help-debbugs@gnu.org Resent-From: speters@itasoftware.com (Stephen Peters) Original-Sender: debbugs-submit-bounces@debbugs.gnu.org Resent-To: owner@debbugs.gnu.org Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Fri, 30 Jul 2010 20:41:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 6766 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch X-Debbugs-Original-To: bug-gnu-emacs@gnu.org Original-Received: via spool by submit@debbugs.gnu.org id=B.12805224253889 (code B ref -1); Fri, 30 Jul 2010 20:41:01 +0000 Original-Received: (at submit) by debbugs.gnu.org; 30 Jul 2010 20:40:25 +0000 Original-Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1OewNT-00010g-S2 for submit@debbugs.gnu.org; Fri, 30 Jul 2010 16:40:24 -0400 Original-Received: from mail.gnu.org ([199.232.76.166] helo=mx10.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1OerRQ-0007IK-OX for submit@debbugs.gnu.org; Fri, 30 Jul 2010 11:24:10 -0400 Original-Received: from lists.gnu.org ([199.232.76.165]:51395) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1OerRg-000555-C1 for submit@debbugs.gnu.org; Fri, 30 Jul 2010 11:24:24 -0400 Original-Received: from [140.186.70.92] (port=37329 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OerRJ-0007b4-Ir for bug-gnu-emacs@gnu.org; Fri, 30 Jul 2010 11:24:24 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1OerR0-0003Zb-9K for bug-gnu-emacs@gnu.org; Fri, 30 Jul 2010 11:23:56 -0400 Original-Received: from ita4fw1.itasoftware.com ([63.107.91.99]:10494 helo=ita4mta2.internal.itasoftware.com) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1OerR0-0003Yw-4I for bug-gnu-emacs@gnu.org; Fri, 30 Jul 2010 11:23:42 -0400 Original-Received: from leng-speters (lb1.dc4nat177.dc4.internal.itasoftware.com [10.4.199.177]) by ita4mta2.internal.itasoftware.com (Postfix) with ESMTP id E0B2519D805F for ; Fri, 30 Jul 2010 11:23:40 -0400 (EDT) Original-Received: by leng-speters (Postfix, from userid 1000) id AFCA45D038C; Thu, 29 Jul 2010 15:13:10 -0400 (EDT) Sent-via: bug-gnu-emacs@gnu.org X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6, seldom 2.4 (older, 4) X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.6, seldom 2.4 (older, 4) X-Mailman-Approved-At: Fri, 30 Jul 2010 16:40:22 -0400 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list Resent-Date: Fri, 30 Jul 2010 16:41:01 -0400 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-Mailman-Approved-At: Fri, 30 Jul 2010 18:22:27 -0400 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.bugs:39084 Archived-At: 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")