aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGlenn Morris2008-03-16 01:21:25 +0000
committerGlenn Morris2008-03-16 01:21:25 +0000
commitf8e9107c532cd857b2e5ca471d94e1bf5dc3fb35 (patch)
tree5feb52f1ffda266301480b3fc87d9bc41e9dfa2f
parent30864d5f804c54bd1537d07a8e1aabf8e707f73e (diff)
downloademacs-f8e9107c532cd857b2e5ca471d94e1bf5dc3fb35.tar.gz
emacs-f8e9107c532cd857b2e5ca471d94e1bf5dc3fb35.zip
Craig Markwardt <Craig.Markwardt at nasa.gov>
(icalendar-recurring-start-year): New variable. (icalendar--diarytime-to-isotime): Fix treatment of 12:00pm - 12:59pm. (icalendar-export-region): Ignore hidden diary entries. (icalendar--convert-ordinary-to-ical): Fix case where event spans across midnight boundary. (icalendar-first-weekday-of-year): New function. (icalendar--convert-weekly-to-ical): Allow user-selectable start year for recurring events (Mozilla calendars do not propagate recurring events forever, so year 2000 start date was not working). (icalendar--convert-yearly-to-ical): Remove extra spaces in formatting of BYMONTH and BYMONTHDAY (not allowed by ical spec).
-rw-r--r--lisp/calendar/icalendar.el72
1 files changed, 55 insertions, 17 deletions
diff --git a/lisp/calendar/icalendar.el b/lisp/calendar/icalendar.el
index 62cc247e8de..e202d957f08 100644
--- a/lisp/calendar/icalendar.el
+++ b/lisp/calendar/icalendar.el
@@ -195,6 +195,15 @@ the class."
195 :type 'string 195 :type 'string
196 :group 'icalendar) 196 :group 'icalendar)
197 197
198(defcustom icalendar-recurring-start-year
199 2005
200 "Start year for recurring events.
201Some calendar browsers only propagate recurring events for
202several years beyond the start time. Set this string to a year
203just before the start of your personal calendar."
204 :type 'integer
205 :group 'icalendar)
206
198(defvar icalendar-debug nil 207(defvar icalendar-debug nil
199 "Enable icalendar debug messages.") 208 "Enable icalendar debug messages.")
200 209
@@ -771,7 +780,8 @@ would be \"pm\"."
771 (if timestring 780 (if timestring
772 (let ((starttimenum (read (icalendar--rris ":" "" timestring)))) 781 (let ((starttimenum (read (icalendar--rris ":" "" timestring))))
773 ;; take care of am/pm style 782 ;; take care of am/pm style
774 (if (and ampmstring (string= "pm" ampmstring)) 783 ;; Be sure *not* to convert 12:00pm - 12:59pm to 2400-2459
784 (if (and ampmstring (string= "pm" ampmstring) (< starttimenum 1200))
775 (setq starttimenum (+ starttimenum 1200))) 785 (setq starttimenum (+ starttimenum 1200)))
776 (format "T%04d00" starttimenum)) 786 (format "T%04d00" starttimenum))
777 nil)) 787 nil))
@@ -837,7 +847,8 @@ FExport diary data into iCalendar file: ")
837 (save-excursion 847 (save-excursion
838 (goto-char min) 848 (goto-char min)
839 (while (re-search-forward 849 (while (re-search-forward
840 "^\\([^ \t\n].+\\)\\(\\(\n[ \t].*\\)*\\)" max t) 850 ;; ignores hidden entries beginning with "&"
851 "^\\([^ \t\n&#].+\\)\\(\\(\n[ \t].*\\)*\\)" max t)
841 (setq entry-main (match-string 1)) 852 (setq entry-main (match-string 1))
842 (if (match-beginning 2) 853 (if (match-beginning 2)
843 (setq entry-rest (match-string 2)) 854 (setq entry-rest (match-string 2))
@@ -1040,6 +1051,7 @@ entries. ENTRY-MAIN is the first line of the diary entry."
1040 datetime)) 1051 datetime))
1041 (endisostring (icalendar--datestring-to-isodate 1052 (endisostring (icalendar--datestring-to-isodate
1042 datetime 1)) 1053 datetime 1))
1054 (endisostring1)
1043 (starttimestring (icalendar--diarytime-to-isotime 1055 (starttimestring (icalendar--diarytime-to-isotime
1044 (if (match-beginning 3) 1056 (if (match-beginning 3)
1045 (substring entry-main 1057 (substring entry-main
@@ -1069,13 +1081,27 @@ entries. ENTRY-MAIN is the first line of the diary entry."
1069 1081
1070 (unless startisostring 1082 (unless startisostring
1071 (error "Could not parse date")) 1083 (error "Could not parse date"))
1084
1085 ;; If only start-date is specified, then end-date is next day,
1086 ;; otherwise it is same day.
1087 (setq endisostring1 (if starttimestring
1088 startisostring
1089 endisostring))
1090
1072 (when starttimestring 1091 (when starttimestring
1073 (unless endtimestring 1092 (unless endtimestring
1074 (let ((time 1093 (let ((time
1075 (read (icalendar--rris "^T0?" "" 1094 (read (icalendar--rris "^T0?" ""
1076 starttimestring)))) 1095 starttimestring))))
1096 (if (< time 230000)
1097 ;; Case: ends on same day
1077 (setq endtimestring (format "T%06d" 1098 (setq endtimestring (format "T%06d"
1078 (+ 10000 time)))))) 1099 (+ 10000 time)))
1100 ;; Case: ends on next day
1101 (setq endtimestring (format "T%06d"
1102 (- time 230000)))
1103 (setq endisostring1 endisostring)) )))
1104
1079 (list (concat "\nDTSTART;" 1105 (list (concat "\nDTSTART;"
1080 (if starttimestring "VALUE=DATE-TIME:" 1106 (if starttimestring "VALUE=DATE-TIME:"
1081 "VALUE=DATE:") 1107 "VALUE=DATE:")
@@ -1084,14 +1110,22 @@ entries. ENTRY-MAIN is the first line of the diary entry."
1084 "\nDTEND;" 1110 "\nDTEND;"
1085 (if endtimestring "VALUE=DATE-TIME:" 1111 (if endtimestring "VALUE=DATE-TIME:"
1086 "VALUE=DATE:") 1112 "VALUE=DATE:")
1087 (if starttimestring 1113 endisostring1
1088 startisostring
1089 endisostring)
1090 (or endtimestring "")) 1114 (or endtimestring ""))
1091 summary)) 1115 summary))
1092 ;; no match 1116 ;; no match
1093 nil)) 1117 nil))
1094 1118
1119(defun icalendar-first-weekday-of-year (abbrevweekday year &optional offset)
1120 "Find the first WEEKDAY in a given YEAR."
1121 (let* ((j2000 (calendar-absolute-from-gregorian '(1 2 2000)))
1122 (juser (calendar-absolute-from-gregorian (list 1 1 year)))
1123 (wdayjan1 (mod (- juser j2000) 7))
1124 (wdayuser (icalendar--get-weekday-number abbrevweekday))
1125 (dayoff (+ wdayuser 1 (- wdayjan1) (or offset 0))))
1126 (if (<= dayoff 0) (setq dayoff (+ dayoff 7)))
1127 (list year 1 dayoff)))
1128
1095(defun icalendar--convert-weekly-to-ical (nonmarker entry-main) 1129(defun icalendar--convert-weekly-to-ical (nonmarker entry-main)
1096 "Convert weekly diary entry to icalendar format. 1130 "Convert weekly diary entry to icalendar format.
1097NONMARKER is a regular expression matching the start of non-marking 1131NONMARKER is a regular expression matching the start of non-marking
@@ -1150,21 +1184,23 @@ entries. ENTRY-MAIN is the first line of the diary entry."
1150 (if starttimestring 1184 (if starttimestring
1151 "VALUE=DATE-TIME:" 1185 "VALUE=DATE-TIME:"
1152 "VALUE=DATE:") 1186 "VALUE=DATE:")
1153 ;; find the correct week day, 1187 ;; Find the first requested weekday of the
1154 ;; 1st january 2000 was a saturday 1188 ;; start year
1155 (format 1189 (apply 'format
1156 "200001%02d" 1190 "%04d%02d%02d"
1157 (+ (icalendar--get-weekday-number day) 2)) 1191 (icalendar-first-weekday-of-year day
1192 icalendar-recurring-start-year))
1158 (or starttimestring "") 1193 (or starttimestring "")
1159 "\nDTEND;" 1194 "\nDTEND;"
1160 (if endtimestring 1195 (if endtimestring
1161 "VALUE=DATE-TIME:" 1196 "VALUE=DATE-TIME:"
1162 "VALUE=DATE:") 1197 "VALUE=DATE:")
1163 (format 1198 (apply 'format
1164 "200001%02d" 1199 "%04d%02d%02d"
1165 ;; end is non-inclusive! 1200 ;; end is non-inclusive!
1166 (+ (icalendar--get-weekday-number day) 1201 (icalendar-first-weekday-of-year day
1167 (if endtimestring 2 3))) 1202 icalendar-recurring-start-year
1203 (if endtimestring 0 1)))
1168 (or endtimestring "") 1204 (or endtimestring "")
1169 "\nRRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=" 1205 "\nRRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY="
1170 day) 1206 day)
@@ -1245,9 +1281,11 @@ entries. ENTRY-MAIN is the first line of the diary entry."
1245 (if endtimestring 0 1)) 1281 (if endtimestring 0 1))
1246 (or endtimestring "") 1282 (or endtimestring "")
1247 "\nRRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH=" 1283 "\nRRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH="
1248 (format "%2d" month) 1284 ;; Removed %2d formatting string since spaces
1285 ;; are not allowed
1286 (format "%d" month)
1249 ";BYMONTHDAY=" 1287 ";BYMONTHDAY="
1250 (format "%2d" day)) 1288 (format "%d" day))
1251 summary)) 1289 summary))
1252 ;; no match 1290 ;; no match
1253 nil)) 1291 nil))