/[emacs]/emacs/lisp/calendar/icalendar.el
ViewVC logotype

Diff of /emacs/lisp/calendar/icalendar.el

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.4.2.1 by miles, Mon Oct 25 04:19:45 2004 UTC revision 1.4.2.2 by miles, Mon Oct 25 04:22:30 2004 UTC
# Line 1  Line 1 
1  ;;; icalendar.el --- iCalendar implementation  ;;; icalendar.el --- iCalendar implementation -*-coding: utf-8 -*-
2    
3  ;; Copyright (C) 2002, 2003, 2004  Free Software Foundation, Inc.  ;; Copyright (C) 2002, 2003, 2004  Free Software Foundation, Inc.
4    
5  ;; Author:   Ulf Jasper <ulf.jasper@web.de>  ;; Author:         Ulf Jasper <ulf.jasper@web.de>
6  ;; Created:  August 2002  ;; Created:        August 2002
7  ;; Keywords: calendar  ;; Keywords:       calendar
8  ;; Human-Keywords: calendar, diary, iCalendar, vCalendar  ;; Human-Keywords: calendar, diary, iCalendar, vCalendar
9    
10  ;; This file is part of GNU Emacs.  ;; This file is part of GNU Emacs.
# Line 31  Line 31 
31    
32  ;;; History:  ;;; History:
33    
34  ;;  0.06  Bugfixes regarding icalendar-import-format-*.  ;;  0.07: Renamed commands!
35  ;;        Fix in icalendar-convert-diary-to-ical -- thanks to Philipp Grau.  ;;        icalendar-extract-ical-from-buffer -> icalendar-import-buffer
36    ;;        icalendar-convert-diary-to-ical    -> icalendar-export-file
37    ;;        Naming scheme: icalendar-.* = user command; icalendar--.* =
38    ;;        internal.
39    ;;        Added icalendar-export-region.
40    ;;        The import and export commands do not clear their target file,
41    ;;        but append their results to the target file.
42    ;;        I18n-problems fixed -- use calendar-(month|day)-name-array.
43    ;;        Fixed problems with export of multi-line diary entries.
44    
45    ;;  0.06: Bugfixes regarding icalendar-import-format-*.
46    ;;        Fix in icalendar-convert-diary-to-ical -- thanks to Philipp
47    ;;        Grau.
48    
49  ;;  0.05: New import format scheme: Replaced icalendar-import-prefix-*,  ;;  0.05: New import format scheme: Replaced icalendar-import-prefix-*,
50  ;;        icalendar-import-ignored-properties, and  ;;        icalendar-import-ignored-properties, and
# Line 61  Line 73 
73  ;; ======================================================================  ;; ======================================================================
74  ;; To Do:  ;; To Do:
75    
76  ;;  * Import from ical:  ;;  * Import from ical to diary:
77  ;;    + Need more properties for icalendar-import-format  ;;    + Need more properties for icalendar-import-format
78  ;;    + check vcalendar version  ;;    + check vcalendar version
79  ;;    + check (unknown) elements  ;;    + check (unknown) elements
# Line 73  Line 85 
85  ;;    + error log is incomplete  ;;    + error log is incomplete
86  ;;    + nice to have: #include "webcal://foo.com/some-calendar.ics"  ;;    + nice to have: #include "webcal://foo.com/some-calendar.ics"
87    
88  ;;  * Export into ical  ;;  * Export from diary to ical
89  ;;    + diary-date, diary-float, and self-made sexp entries are not  ;;    + diary-date, diary-float, and self-made sexp entries are not
90  ;;      understood  ;;      understood
91  ;;    + timezones, currently all times are local!  ;;    + timezones, currently all times are local!
92    
93  ;;  * Other things  ;;  * Other things
 ;;    + defcustom icalendar-import-ignored-properties does not work with  
 ;;      XEmacs.  
94  ;;    + clean up all those date/time parsing functions  ;;    + clean up all those date/time parsing functions
95  ;;    + Handle todo items?  ;;    + Handle todo items?
96  ;;    + Check iso 8601 for datetime and period  ;;    + Check iso 8601 for datetime and period
97  ;;    + Which chars to (un)escape?  ;;    + Which chars to (un)escape?
 ;;    + Time to find out how the profiler works?  
98    
99    
100  ;;; Code:  ;;; Code:
101    
102  (defconst icalendar-version 0.06  (defconst icalendar-version 0.07
103    "Version number of icalendar.el.")    "Version number of icalendar.el.")
104    
105  ;; ======================================================================  ;; ======================================================================
# Line 160  longer than they are." Line 169  longer than they are."
169  ;; NO USER SERVICABLE PARTS BELOW THIS LINE  ;; NO USER SERVICABLE PARTS BELOW THIS LINE
170  ;; ======================================================================  ;; ======================================================================
171    
172  (defconst icalendar-weekdayabbrev-table  (defconst icalendar--weekday-array ["SU" "MO" "TU" "WE" "TH" "FR" "SA"])
   '(("mon\\(day\\)?"    . "MO")  
     ("tue\\(sday\\)?"   . "TU")  
     ("wed\\(nesday\\)?" . "WE")  
     ("thu\\(rsday\\)?"  . "TH")  
     ("fri\\(day\\)?"    . "FR")  
     ("sat\\(urday\\)?"  . "SA")  
     ("sun\\(day\\)?"    . "SU"))  
   "Translation table for weekdays.")  
   
 (defconst icalendar-monthnumber-table  
   '(("^jan\\(uar\\)?y?$"       . 1)  
     ("^feb\\(ruar\\)?y?$"      . 2)  
     ("^mar\\(ch\\)?\\|märz?$" . 3)  
     ("^apr\\(il\\)?$"          . 4)  
     ("^ma[iy]$"                . 5)  
     ("^jun[ie]?$"              . 6)  
     ("^jul[iy]?$"              . 7)  
     ("^aug\\(ust\\)?$"         . 8)  
     ("^sep\\(tember\\)?$"      . 9)  
     ("^o[ck]t\\(ober\\)?$"     . 10)  
     ("^nov\\(ember\\)?$"       . 11)  
     ("^de[cz]\\(ember\\)?$"    . 12))  
   "Regular expressions for month names.  
 Currently this matches only German and English.")  
173    
174  (defvar icalendar-debug nil ".")  (defvar icalendar-debug nil ".")
175    
# Line 195  Currently this matches only German and E Line 180  Currently this matches only German and E
180  (require 'appt)  (require 'appt)
181    
182  ;; ======================================================================  ;; ======================================================================
183    ;; misc
184    ;; ======================================================================
185    (defun icalendar--dmsg (&rest args)
186      "Print message ARGS if `icalendar-debug' is non-nil."
187      (if icalendar-debug
188          (apply 'message args)))
189    
190    ;; ======================================================================
191  ;; Core functionality  ;; Core functionality
192  ;; Functions for parsing icalendars, importing and so on  ;; Functions for parsing icalendars, importing and so on
193  ;; ======================================================================  ;; ======================================================================
194    
195  (defun icalendar-get-unfolded-buffer (folded-ical-buffer)  (defun icalendar--get-unfolded-buffer (folded-ical-buffer)
196    "Return a new buffer containing the unfolded contents of a buffer.    "Return a new buffer containing the unfolded contents of a buffer.
197  Folding is the iCalendar way of wrapping long lines.  In the  Folding is the iCalendar way of wrapping long lines.  In the
198  created buffer all occurrences of CR LF BLANK are replaced by the  created buffer all occurrences of CR LF BLANK are replaced by the
# Line 211  buffer." Line 204  buffer."
204        (erase-buffer)        (erase-buffer)
205        (insert-buffer folded-ical-buffer)        (insert-buffer folded-ical-buffer)
206        (while (re-search-forward "\r?\n[ \t]" nil t)        (while (re-search-forward "\r?\n[ \t]" nil t)
207          (replace-match "" nil nil))          (replace-match "" nil nil)))
       )  
208      unfolded-buffer))      unfolded-buffer))
209    
210  ;; Replace regexp RE with RP in string ST and return the new string.  (defsubst icalendar--rris (re rp st)
211  ;; This is here for compatibility with XEmacs.    "Replace regexp RE with RP in string ST and return the new string.
212  (defsubst icalendar-rris (re rp st)  This is here for compatibility with XEmacs."
213    ;; XEmacs:    ;; XEmacs:
214    (if (fboundp 'replace-in-string)    (if (fboundp 'replace-in-string)
215        (save-match-data ;; apparently XEmacs needs save-match-data        (save-match-data ;; apparently XEmacs needs save-match-data
# Line 225  buffer." Line 217  buffer."
217      ;; Emacs:      ;; Emacs:
218      (replace-regexp-in-string re rp st)))      (replace-regexp-in-string re rp st)))
219    
220  (defun icalendar-read-element (invalue inparams)  (defun icalendar--read-element (invalue inparams)
221    "Recursively read the next iCalendar element in the current buffer.    "Recursively read the next iCalendar element in the current buffer.
222  INVALUE gives the current iCalendar element we are reading.  INVALUE gives the current iCalendar element we are reading.
223  INPARAMS gives the current parameters.....  INPARAMS gives the current parameters.....
# Line 233  This function calls itself recursively f Line 225  This function calls itself recursively f
225  it finds"  it finds"
226    (let (element children line name params param param-name param-value    (let (element children line name params param param-name param-value
227                  value                  value
228          (continue t))                  (continue t))
229      (setq children '())      (setq children '())
230      (while (and continue      (while (and continue
231                  (re-search-forward "^\\([A-Za-z0-9-]+\\)[;:]" nil t))                  (re-search-forward "^\\([A-Za-z0-9-]+\\)[;:]" nil t))
# Line 261  it finds" Line 253  it finds"
253          (error "Oops"))          (error "Oops"))
254        (forward-char 1)        (forward-char 1)
255        (re-search-forward  "\\(.*\\)\\(\r?\n[ \t].*\\)*" nil t)        (re-search-forward  "\\(.*\\)\\(\r?\n[ \t].*\\)*" nil t)
256        (setq value (icalendar-rris "\r?\n[ \t]" "" (match-string 0)))        (setq value (icalendar--rris "\r?\n[ \t]" "" (match-string 0)))
257        (setq line (list name params value))        (setq line (list name params value))
258        (cond ((eq name 'BEGIN)        (cond ((eq name 'BEGIN)
259               (setq children               (setq children
260                     (append children                     (append children
261                             (list (icalendar-read-element (intern value)                             (list (icalendar--read-element (intern value)
262                                                           params)))))                                                            params)))))
263              ((eq name 'END)              ((eq name 'END)
264               (setq continue nil))               (setq continue nil))
265              (t              (t
# Line 280  it finds" Line 272  it finds"
272  ;; helper functions for examining events  ;; helper functions for examining events
273  ;; ======================================================================  ;; ======================================================================
274    
275  (defsubst icalendar-get-all-event-properties (event)  ;;(defsubst icalendar--get-all-event-properties (event)
276    "Return the list of properties in this EVENT."  ;;  "Return the list of properties in this EVENT."
277    (car (cddr event)))  ;;  (car (cddr event)))
278    
279  (defun icalendar-get-event-property (event prop)  (defun icalendar--get-event-property (event prop)
280    "For the given EVENT return the value of the property PROP."    "For the given EVENT return the value of the property PROP."
281    (catch 'found    (catch 'found
282      (let ((props (car (cddr event))) pp)      (let ((props (car (cddr event))) pp)
# Line 295  it finds" Line 287  it finds"
287          (setq props (cdr props))))          (setq props (cdr props))))
288      nil))      nil))
289    
290  (defun icalendar-set-event-property (event prop new-value)  ;; (defun icalendar--set-event-property (event prop new-value)
291    "For the given EVENT set the property PROP to the value NEW-VALUE."  ;;   "For the given EVENT set the property PROP to the value NEW-VALUE."
292    (catch 'found  ;;   (catch 'found
293      (let ((props (car (cddr event))) pp)  ;;     (let ((props (car (cddr event))) pp)
294        (while props  ;;       (while props
295          (setq pp (car props))  ;;         (setq pp (car props))
296          (when (eq (car pp) prop)  ;;         (when (eq (car pp) prop)
297            (setcdr (cdr pp) new-value)  ;;           (setcdr (cdr pp) new-value)
298            (throw 'found (car (cddr pp))))  ;;           (throw 'found (car (cddr pp))))
299          (setq props (cdr props)))  ;;         (setq props (cdr props)))
300        (setq props (car (cddr event)))  ;;       (setq props (car (cddr event)))
301        (setcar (cddr event)  ;;       (setcar (cddr event)
302                (append props (list (list prop nil new-value)))))))  ;;               (append props (list (list prop nil new-value)))))))
303    
304  (defun icalendar-get-children (node name)  (defun icalendar--get-children (node name)
305    "Return all children of the given NODE which have a name NAME.    "Return all children of the given NODE which have a name NAME.
306  For instance the VCALENDAR node can have VEVENT children as well as VTODO  For instance the VCALENDAR node can have VEVENT children as well as VTODO
307  children."  children."
# Line 321  children." Line 313  children."
313      (when children      (when children
314        (let ((subresult        (let ((subresult
315               (delq nil               (delq nil
316                     (mapcar (lambda (n)                     (mapcar (lambda (n)
317                               (icalendar-get-children n name))                               (icalendar--get-children n name))
318                             children))))                             children))))
319          (if subresult          (if subresult
320              (if result              (if result
321                  (setq result (append result subresult))                  (setq result (append result subresult))
322                (setq result subresult)))))                (setq result subresult)))))
323      result))      result))
324    
325  ; private                                          ; private
326  (defun icalendar-all-events (icalendar)  (defun icalendar--all-events (icalendar)
327    "Return the list of all existing events in the given ICALENDAR."    "Return the list of all existing events in the given ICALENDAR."
328    (interactive "")    (icalendar--get-children (car icalendar) 'VEVENT))
   (icalendar-get-children (car icalendar) 'VEVENT))  
329    
330  (defun icalendar-split-value (value-string)  (defun icalendar--split-value (value-string)
331    "Splits VALUE-STRING at ';='."    "Splits VALUE-STRING at ';='."
332    (let ((result '())    (let ((result '())
333          param-name param-value)          param-name param-value)
# Line 348  children." Line 339  children."
339          (insert value-string)          (insert value-string)
340          (goto-char (point-min))          (goto-char (point-min))
341          (while          (while
342              (re-search-forward              (re-search-forward
343               "\\([A-Za-z0-9-]+\\)=\\(\\([^;,:]+\\)\\|\"\\([^\"]+\\)\"\\);?"               "\\([A-Za-z0-9-]+\\)=\\(\\([^;,:]+\\)\\|\"\\([^\"]+\\)\"\\);?"
344               nil t)               nil t)
345            (setq param-name (intern (match-string 1)))            (setq param-name (intern (match-string 1)))
346            (setq param-value (match-string 2))            (setq param-value (match-string 2))
347            (setq result            (setq result
348                  (append result (list (list param-name param-value)))))))                  (append result (list (list param-name param-value)))))))
349      result))      result))
350    
351  (defun icalendar-decode-isodatetime (isodatetimestring)  (defun icalendar--decode-isodatetime (isodatetimestring)
352    "Return ISODATETIMESTRING in format like `decode-time'.    "Return ISODATETIMESTRING in format like `decode-time'.
353  Converts from ISO-8601 to Emacs representation.  If ISODATETIMESTRING  Converts from ISO-8601 to Emacs representation.  If ISODATETIMESTRING
354  specifies UTC time (trailing letter Z) the decoded time is given in  specifies UTC time (trailing letter Z) the decoded time is given in
355  the local time zone! FIXME: TZID-attributes are ignored....! FIXME:  the local time zone! FIXME: TZID-attributes are ignored....! FIXME:
356  multiple comma-separated values should be allowed!"  multiple comma-separated values should be allowed!"
357    (icalendar-dmsg isodatetimestring)    (icalendar--dmsg isodatetimestring)
358    (if isodatetimestring    (if isodatetimestring
359        ;; day/month/year must be present        ;; day/month/year must be present
360        (let ((year  (read (substring isodatetimestring 0 4)))        (let ((year  (read (substring isodatetimestring 0 4)))
# Line 373  multiple comma-separated values should b Line 364  multiple comma-separated values should b
364              (minute 0)              (minute 0)
365              (second 0))              (second 0))
366          (when (> (length isodatetimestring) 12)          (when (> (length isodatetimestring) 12)
367            ;; hour/minute present            ;; hour/minute present
368            (setq hour (read (substring isodatetimestring 9 11)))            (setq hour (read (substring isodatetimestring 9 11)))
369            (setq minute (read (substring isodatetimestring 11 13))))            (setq minute (read (substring isodatetimestring 11 13))))
370          (when (> (length isodatetimestring) 14)          (when (> (length isodatetimestring) 14)
371            ;; seconds present            ;; seconds present
372            (setq second (read (substring isodatetimestring 13 15))))            (setq second (read (substring isodatetimestring 13 15))))
373          (when (and (> (length isodatetimestring) 15)          (when (and (> (length isodatetimestring) 15)
374                     ;; UTC specifier present                     ;; UTC specifier present
375                     (char-equal ?Z (aref isodatetimestring 15)))                     (char-equal ?Z (aref isodatetimestring 15)))
376            ;; if not UTC add current-time-zone offset            ;; if not UTC add current-time-zone offset
377            (setq second (+ (car (current-time-zone)) second)))            (setq second (+ (car (current-time-zone)) second)))
# Line 395  multiple comma-separated values should b Line 386  multiple comma-separated values should b
386      ;; isodatetimestring == nil      ;; isodatetimestring == nil
387      nil))      nil))
388    
389  (defun icalendar-decode-isoduration (isodurationstring)  (defun icalendar--decode-isoduration (isodurationstring)
390    "Return ISODURATIONSTRING in format like `decode-time'.    "Return ISODURATIONSTRING in format like `decode-time'.
391  Converts from ISO-8601 to Emacs representation.  If ISODURATIONSTRING  Converts from ISO-8601 to Emacs representation.  If ISODURATIONSTRING
392  specifies UTC time (trailing letter Z) the decoded time is given in  specifies UTC time (trailing letter Z) the decoded time is given in
# Line 409  multiple comma-separated values should b Line 400  multiple comma-separated values should b
400            "\\(\\([0-9]+\\)D\\)"         ; days only            "\\(\\([0-9]+\\)D\\)"         ; days only
401            "\\|"            "\\|"
402            "\\(\\(\\([0-9]+\\)D\\)?T\\(\\([0-9]+\\)H\\)?" ; opt days            "\\(\\(\\([0-9]+\\)D\\)?T\\(\\([0-9]+\\)H\\)?" ; opt days
403            "\\(\\([0-9]+\\)M\\)?\\(\\([0-9]+\\)S\\)?\\)" ; mand. time            "\\(\\([0-9]+\\)M\\)?\\(\\([0-9]+\\)S\\)?\\)"  ; mand. time
404            "\\|"            "\\|"
405            "\\(\\([0-9]+\\)W\\)"         ; weeks only            "\\(\\([0-9]+\\)W\\)"         ; weeks only
406            "\\)$") isodurationstring)            "\\)$") isodurationstring)
# Line 419  multiple comma-separated values should b Line 410  multiple comma-separated values should b
410                (days 0)                (days 0)
411                (months 0)                (months 0)
412                (years 0))                (years 0))
413          (cond            (cond
414           ((match-beginning 2)           ;days only             ((match-beginning 2)         ;days only
415            (setq days (read (substring isodurationstring              (setq days (read (substring isodurationstring
416                                        (match-beginning 3)                                          (match-beginning 3)
417                                        (match-end 3))))                                          (match-end 3))))
418            (when icalendar-duration-correction              (when icalendar-duration-correction
419              (setq days (1- days))))                (setq days (1- days))))
420           ((match-beginning 4)           ;days and time             ((match-beginning 4)         ;days and time
421            (if (match-beginning 5)              (if (match-beginning 5)
422                (setq days (* 7 (read (substring isodurationstring                  (setq days (* 7 (read (substring isodurationstring
423                                                 (match-beginning 6)                                                   (match-beginning 6)
424                                                 (match-end 6))))))                                                   (match-end 6))))))
425            (if (match-beginning 7)              (if (match-beginning 7)
426                (setq hours (read (substring isodurationstring                  (setq hours (read (substring isodurationstring
427                                             (match-beginning 8)                                               (match-beginning 8)
428                                             (match-end 8)))))                                               (match-end 8)))))
429            (if (match-beginning 9)              (if (match-beginning 9)
430                (setq minutes (read (substring isodurationstring                  (setq minutes (read (substring isodurationstring
431                                               (match-beginning 10)                                                 (match-beginning 10)
432                                               (match-end 10)))))                                                 (match-end 10)))))
433            (if (match-beginning 11)              (if (match-beginning 11)
434                (setq seconds (read (substring isodurationstring                  (setq seconds (read (substring isodurationstring
435                                               (match-beginning 12)                                                 (match-beginning 12)
436                                               (match-end 12)))))                                                 (match-end 12)))))
437            )              )
438           ((match-beginning 13)          ;weeks only             ((match-beginning 13)        ;weeks only
439            (setq days (* 7 (read (substring isodurationstring              (setq days (* 7 (read (substring isodurationstring
440                                             (match-beginning 14)                                               (match-beginning 14)
441                                             (match-end 14))))))                                               (match-end 14))))))
442           )             )
443          (list seconds minutes hours days months years)))            (list seconds minutes hours days months years)))
444      ;; isodatetimestring == nil      ;; isodatetimestring == nil
445      nil))      nil))
446    
447  (defun icalendar-add-decoded-times (time1 time2)  (defun icalendar--add-decoded-times (time1 time2)
448    "Add TIME1 to TIME2.    "Add TIME1 to TIME2.
449  Both times must be given in decoded form.  One of these times must be  Both times must be given in decoded form.  One of these times must be
450  valid (year > 1900 or something)."  valid (year > 1900 or something)."
# Line 470  valid (year > 1900 or something)." Line 461  valid (year > 1900 or something)."
461                  ;;(or (nth 6 time1) (nth 6 time2)) ;; FIXME?                  ;;(or (nth 6 time1) (nth 6 time2)) ;; FIXME?
462                  )))                  )))
463    
464  (defun icalendar-datetime-to-noneuropean-date (datetime)  (defun icalendar--datetime-to-noneuropean-date (datetime)
465    "Convert the decoded DATETIME to non-european-style format.    "Convert the decoded DATETIME to non-european-style format.
466  Non-European format: (month day year)."  Non-European format: (month day year)."
467    (if datetime    (if datetime
468        (list (nth 4 datetime) ;month        (list (nth 4 datetime)            ;month
469              (nth 3 datetime) ;day              (nth 3 datetime)            ;day
470              (nth 5 datetime));year              (nth 5 datetime))           ;year
471      ;; datetime == nil      ;; datetime == nil
472      nil))      nil))
473    
474  (defun icalendar-datetime-to-european-date (datetime)  (defun icalendar--datetime-to-european-date (datetime)
475    "Convert the decoded DATETIME to European format.    "Convert the decoded DATETIME to European format.
476  European format: (day month year).  European format: (day month year).
477  FIXME"  FIXME"
478    (if datetime    (if datetime
479        (format "%d %d %d" (nth 3 datetime); day        (format "%d %d %d" (nth 3 datetime) ; day
480                (nth 4 datetime) ;month                (nth 4 datetime)            ;month
481                (nth 5 datetime));year                (nth 5 datetime))           ;year
482      ;; datetime == nil      ;; datetime == nil
483      nil))      nil))
484    
485  (defun icalendar-datetime-to-colontime (datetime)  (defun icalendar--datetime-to-colontime (datetime)
486    "Extract the time part of a decoded DATETIME into 24-hour format.    "Extract the time part of a decoded DATETIME into 24-hour format.
487  Note that this silently ignores seconds."  Note that this silently ignores seconds."
488    (format "%02d:%02d" (nth 2 datetime) (nth 1 datetime)))    (format "%02d:%02d" (nth 2 datetime) (nth 1 datetime)))
489    
490  (defun icalendar-get-month-number (monthname)  (defun icalendar--get-month-number (monthname)
491    "Return the month number for the given MONTHNAME."    "Return the month number for the given MONTHNAME."
492    (save-match-data    (catch 'found
493      (let ((case-fold-search t))      (let ((num 1)
494        (assoc-default monthname icalendar-monthnumber-table            (m (downcase monthname)))
495                       'string-match))))        (mapc (lambda (month)
496                  (let ((mm (downcase month)))
497                    (if (or (string-equal mm m)
498                            (string-equal (substring mm 0 3) m))
499                        (throw 'found num))
500                    (setq num (1+ num))))
501                calendar-month-name-array))
502        ;; Error:
503        -1))
504    
505  (defun icalendar-get-weekday-abbrev (weekday)  (defun icalendar--get-weekday-number (abbrevweekday)
506      "Return the number for the ABBREVWEEKDAY."
507      (catch 'found
508        (let ((num 0)
509              (aw (downcase abbrevweekday)))
510          (mapc (lambda (day)
511                  (let ((d (downcase day)))
512                    (if (string-equal d aw)
513                        (throw 'found num))
514                    (setq num (1+ num))))
515                icalendar--weekday-array))
516        ;; Error:
517        -1))
518    
519    (defun icalendar--get-weekday-abbrev (weekday)
520    "Return the abbreviated WEEKDAY."    "Return the abbreviated WEEKDAY."
521    ;;FIXME: ISO-like(?).    (catch 'found
522    (save-match-data      (let ((num 0)
523      (let ((case-fold-search t))            (w (downcase weekday)))
524        (assoc-default weekday icalendar-weekdayabbrev-table        (mapc (lambda (day)
525                       'string-match))))                (let ((d (downcase day)))
526                    (if (or (string-equal d w)
527                            (string-equal (substring d 0 3) w))
528                        (throw 'found (aref icalendar--weekday-array num)))
529                    (setq num (1+ num))))
530                calendar-day-name-array))
531        ;; Error:
532        "??"))
533    
534  (defun icalendar-datestring-to-isodate (datestring &optional day-shift)  (defun icalendar--datestring-to-isodate (datestring &optional day-shift)
535    "Convert diary-style DATESTRING to iso-style date.    "Convert diary-style DATESTRING to iso-style date.
536  If DAY-SHIFT is non-nil, the result is shifted by DAY-SHIFT days  If DAY-SHIFT is non-nil, the result is shifted by DAY-SHIFT days
537  -- DAY-SHIFT must be either nil or an integer.  This function  -- DAY-SHIFT must be either nil or an integer.  This function
538  takes care of european-style."  takes care of european-style."
539    (let ((day -1) month year)    (let ((day -1) month year)
540      (save-match-data      (save-match-data
541        (cond (;; numeric date        (cond ( ;; numeric date
542               (string-match (concat "\\s-*"               (string-match (concat "\\s-*"
543                                     "0?\\([1-9][0-9]?\\)[ \t/]\\s-*"                                     "0?\\([1-9][0-9]?\\)[ \t/]\\s-*"
544                                     "0?\\([1-9][0-9]?\\),?[ \t/]\\s-*"                                     "0?\\([1-9][0-9]?\\),?[ \t/]\\s-*"
545                                     "\\([0-9]\\{4\\}\\)")                                     "\\([0-9]\\{4\\}\\)")
546                             datestring)                             datestring)
547               (setq day (read (substring datestring (match-beginning 1)               (setq day (read (substring datestring (match-beginning 1)
548                                          (match-end 1))))                                          (match-end 1))))
549               (setq month (read (substring datestring (match-beginning 2)               (setq month (read (substring datestring (match-beginning 2)
550                                            (match-end 2))))                                            (match-end 2))))
551               (setq year (read (substring datestring (match-beginning 3)               (setq year (read (substring datestring (match-beginning 3)
552                                           (match-end 3))))                                           (match-end 3))))
553               (unless european-calendar-style               (unless european-calendar-style
554                 (let ((x month))                 (let ((x month))
555                   (setq month day)                   (setq month day)
556                   (setq day x))))                   (setq day x))))
557              (;; date contains month names -- european-style              ( ;; date contains month names -- european-style
558               (and european-calendar-style               (and european-calendar-style
559                    (string-match (concat "\\s-*"                    (string-match (concat "\\s-*"
560                                          "0?\\([123]?[0-9]\\)[ \t/]\\s-*"                                          "0?\\([123]?[0-9]\\)[ \t/]\\s-*"
561                                          "\\([A-Za-z][^ ]+\\)[ \t/]\\s-*"                                          "\\([A-Za-z][^ ]+\\)[ \t/]\\s-*"
562                                          "\\([0-9]\\{4\\}\\)")                                          "\\([0-9]\\{4\\}\\)")
563                                  datestring))                                  datestring))
564                   (setq day (read (substring datestring (match-beginning 1)               (setq day (read (substring datestring (match-beginning 1)
565                                              (match-end 1))))                                          (match-end 1))))
566                   (setq month (icalendar-get-month-number               (setq month (icalendar--get-month-number
567                                (substring datestring (match-beginning 2)                            (substring datestring (match-beginning 2)
568                                           (match-end 2))))                                       (match-end 2))))
569                   (setq year (read (substring datestring (match-beginning 3)               (setq year (read (substring datestring (match-beginning 3)
570                                               (match-end 3)))))                                           (match-end 3)))))
571              (;; date contains month names -- non-european-style              ( ;; date contains month names -- non-european-style
572               (and (not european-calendar-style)               (and (not european-calendar-style)
573                    (string-match (concat "\\s-*"                    (string-match (concat "\\s-*"
574                                          "\\([A-Za-z][^ ]+\\)[ \t/]\\s-*"                                          "\\([A-Za-z][^ ]+\\)[ \t/]\\s-*"
575                                          "0?\\([123]?[0-9]\\),?[ \t/]\\s-*"                                          "0?\\([123]?[0-9]\\),?[ \t/]\\s-*"
576                                          "\\([0-9]\\{4\\}\\)")                                          "\\([0-9]\\{4\\}\\)")
577                                  datestring))                                  datestring))
578               (setq day (read (substring datestring (match-beginning 2)               (setq day (read (substring datestring (match-beginning 2)
579                                          (match-end 2))))                                          (match-end 2))))
580               (setq month (icalendar-get-month-number               (setq month (icalendar--get-month-number
581                            (substring datestring (match-beginning 1)                            (substring datestring (match-beginning 1)
582                                       (match-end 1))))                                       (match-end 1))))
583               (setq year (read (substring datestring (match-beginning 3)               (setq year (read (substring datestring (match-beginning 3)
584                                           (match-end 3)))))                                           (match-end 3)))))
585              (t              (t
586               nil)))               nil)))
587      (if (> day 0)      (if (> day 0)
588          (let ((mdy (calendar-gregorian-from-absolute          (let ((mdy (calendar-gregorian-from-absolute
589                      (+ (calendar-absolute-from-gregorian (list month day year))                      (+ (calendar-absolute-from-gregorian (list month day
590                         (or day-shift 0)))))                                                                 year))
591            (format "%04d%02d%02d" (nth 2 mdy) (nth 0 mdy) (nth 1 mdy)))                         (or day-shift 0)))))
592              (format "%04d%02d%02d" (nth 2 mdy) (nth 0 mdy) (nth 1 mdy)))
593        nil)))        nil)))
594    
595  (defun icalendar-dmsg (&rest args)  (defun icalendar--diarytime-to-isotime (timestring ampmstring)
   "Print message ARGS if `icalendar-debug' is non-nil."  
   (if icalendar-debug  
       (apply 'message args)))  
   
 (defun icalendar-diarytime-to-isotime (timestring ampmstring)  
596    "Convert a a time like 9:30pm to an iso-conform string like T213000.    "Convert a a time like 9:30pm to an iso-conform string like T213000.
597  In this example the TIMESTRING would be \"9:30\" and the AMPMSTRING  In this example the TIMESTRING would be \"9:30\" and the AMPMSTRING
598  would be \"pm\"."  would be \"pm\"."
599    (if timestring    (if timestring
600        (let ((starttimenum (read (icalendar-rris ":" "" timestring))))        (let ((starttimenum (read (icalendar--rris ":" "" timestring))))
601          ;; take care of am/pm style          ;; take care of am/pm style
602          (if (and ampmstring (string= "pm" ampmstring))          (if (and ampmstring (string= "pm" ampmstring))
603              (setq starttimenum (+ starttimenum 1200)))              (setq starttimenum (+ starttimenum 1200)))
604          (format "T%04d00" starttimenum))          (format "T%04d00" starttimenum))
605      nil))      nil))
606    
607  (defun icalendar-convert-string-for-export (s)  (defun icalendar--convert-string-for-export (s)
608    "Escape comma and other critical characters in string S."    "Escape comma and other critical characters in string S."
609    (icalendar-rris "," "\\\\," s))    (icalendar--rris "," "\\\\," s))
610    
611  (defun icalendar-convert-for-import (string)  (defun icalendar--convert-string-for-import (string)
612    "Remove escape chars for comma, semicolon etc. from STRING."    "Remove escape chars for comma, semicolon etc. from STRING."
613    (icalendar-rris    (icalendar--rris
614     "\\\\n" "\n " (icalendar-rris     "\\\\n" "\n " (icalendar--rris
615                 "\\\\\"" "\"" (icalendar-rris                    "\\\\\"" "\"" (icalendar--rris
616                                "\\\\;" ";" (icalendar-rris                                   "\\\\;" ";" (icalendar--rris
617                                             "\\\\," "," string)))))                                                "\\\\," "," string)))))
618    
619  ;; ======================================================================  ;; ======================================================================
620  ;; export -- convert emacs-diary to icalendar  ;; Export -- convert emacs-diary to icalendar
621  ;; ======================================================================  ;; ======================================================================
622    
623  (defun icalendar-convert-diary-to-ical (diary-filename ical-filename  ;; User function
624                                          &optional do-not-clear-diary-file)  (defun icalendar-export-file (diary-filename ical-filename)
625    "Export diary file to iCalendar format -- erases ical-filename!!!.    "Export diary file to iCalendar format.
626  Argument DIARY-FILENAME is the input `diary-file'.  All diary entries in the file DIARY-FILENAME are converted to iCalendar
627  Argument ICAL-FILENAME is the output iCalendar file.  format.  The result is appended to the file ICAL-FILENAME."
 If DO-NOT-CLEAR-DIARY-FILE is not nil the target iCalendar file  
 is not erased."  
628    (interactive "FExport diary data from file:    (interactive "FExport diary data from file:
629  Finto iCalendar file: ")  Finto iCalendar file: ")
630      (save-current-buffer
631        (set-buffer (find-file diary-filename))
632        (icalendar-export-region (point-min) (point-max) ical-filename)))
633    
634    (defalias 'icalendar-convert-diary-to-ical 'icalendar-export-file)
635    (make-obsolete 'icalendar-convert-diary-to-ical 'icalendar-export-file
636                   "icalendar 0.07")
637    
638    ;; User function
639    (defun icalendar-export-region (min max ical-filename)
640      "Export region in diary file to iCalendar format.
641    All diary entries in the region from MIN to MAX in the current buffer are
642    converted to iCalendar format.  The result is appended to the file
643    ICAL-FILENAME."
644      (interactive "r
645    FExport diary data into iCalendar file: ")
646    (let ((result "")    (let ((result "")
647          (start 0)          (start 0)
648          (entry-main "")          (entry-main "")
# Line 621  Finto iCalendar file: ") Line 651  Finto iCalendar file: ")
651          (contents)          (contents)
652          (oops nil)          (oops nil)
653          (nonmarker (concat "^" (regexp-quote diary-nonmarking-symbol)          (nonmarker (concat "^" (regexp-quote diary-nonmarking-symbol)
654                             "?")))                             "?")))
655      (save-current-buffer      (save-excursion
656        (set-buffer (find-file diary-filename))        (goto-char min)
       (goto-char (point-min))  
657        (while (re-search-forward        (while (re-search-forward
658                "^\\([^ \t\n].*\\)\\(\n[ \t].*\\)*" nil t)                "^\\([^ \t\n].*\\)\\(\\(\n[ \t].*\\)*\\)" max t)
659          (setq entry-main (match-string 1))          (setq entry-main (match-string 1))
660          (if (match-beginning 2)          (if (match-beginning 2)
661              (setq entry-rest (match-string 2))              (setq entry-rest (match-string 2))
# Line 642  Finto iCalendar file: ") Line 671  Finto iCalendar file: ")
671             (concat nonmarker             (concat nonmarker
672                     "%%(diary-anniversary \\([^)]+\\))\\s-*\\(.*\\)")                     "%%(diary-anniversary \\([^)]+\\))\\s-*\\(.*\\)")
673             entry-main)             entry-main)
674            (icalendar-dmsg "diary-anniversary %s" entry-main)            (icalendar--dmsg "diary-anniversary %s" entry-main)
675            (let* ((datetime (substring entry-main (match-beginning 1)            (let* ((datetime (substring entry-main (match-beginning 1)
676                                        (match-end 1)))                                        (match-end 1)))
677                   (summary (icalendar-convert-string-for-export                   (summary (icalendar--convert-string-for-export
678                             (substring entry-main (match-beginning 2)                             (substring entry-main (match-beginning 2)
679                                        (match-end 2))))                                        (match-end 2))))
680                   (startisostring (icalendar-datestring-to-isodate                   (startisostring (icalendar--datestring-to-isodate
681                                    datetime))                                    datetime))
682                   (endisostring (icalendar-datestring-to-isodate                   (endisostring (icalendar--datestring-to-isodate
683                                  datetime 1)))                                  datetime 1)))
684              (setq contents              (setq contents
685                    (concat "\nDTSTART;VALUE=DATE:" startisostring                    (concat "\nDTSTART;VALUE=DATE:" startisostring
686                            "\nDTEND;VALUE=DATE:" endisostring                            "\nDTEND;VALUE=DATE:" endisostring
# Line 666  Finto iCalendar file: ") Line 695  Finto iCalendar file: ")
695                            )))                            )))
696            (unless (string= entry-rest "")            (unless (string= entry-rest "")
697              (setq contents (concat contents "\nDESCRIPTION:"              (setq contents (concat contents "\nDESCRIPTION:"
698                                     (icalendar-convert-string-for-export                                     (icalendar--convert-string-for-export
699                                      entry-rest)))))                                      entry-rest)))))
700           ;; cyclic events           ;; cyclic events
701           ;; %%(diary-cyclic )           ;; %%(diary-cyclic )
# Line 675  Finto iCalendar file: ") Line 704  Finto iCalendar file: ")
704                     "%%(diary-cyclic \\([^ ]+\\) +"                     "%%(diary-cyclic \\([^ ]+\\) +"
705                     "\\([^ /]+[ /]+[^ /]+[ /]+[^ ]+\\))\\s-*\\(.*\\)")                     "\\([^ /]+[ /]+[^ /]+[ /]+[^ ]+\\))\\s-*\\(.*\\)")
706             entry-main)             entry-main)
707            (icalendar-dmsg "diary-cyclic %s" entry-main)            (icalendar--dmsg "diary-cyclic %s" entry-main)
708            (let* ((frequency (substring entry-main (match-beginning 1)            (let* ((frequency (substring entry-main (match-beginning 1)
709                                         (match-end 1)))                                         (match-end 1)))
710                   (datetime (substring entry-main (match-beginning 2)                   (datetime (substring entry-main (match-beginning 2)
711                                        (match-end 2)))                                        (match-end 2)))
712                   (summary (icalendar-convert-string-for-export                   (summary (icalendar--convert-string-for-export
713                             (substring entry-main (match-beginning 3)                             (substring entry-main (match-beginning 3)
714                                        (match-end 3))))                                        (match-end 3))))
715                   (startisostring (icalendar-datestring-to-isodate                   (startisostring (icalendar--datestring-to-isodate
716                                    datetime))                                    datetime))
717                   (endisostring (icalendar-datestring-to-isodate                   (endisostring (icalendar--datestring-to-isodate
718                                  datetime 1)))                                  datetime 1)))
719              (setq contents              (setq contents
720                    (concat "\nDTSTART;VALUE=DATE:" startisostring                    (concat "\nDTSTART;VALUE=DATE:" startisostring
721                            "\nDTEND;VALUE=DATE:" endisostring                            "\nDTEND;VALUE=DATE:" endisostring
# Line 697  Finto iCalendar file: ") Line 726  Finto iCalendar file: ")
726                            )))                            )))
727            (unless (string= entry-rest "")            (unless (string= entry-rest "")
728              (setq contents (concat contents "\nDESCRIPTION:"              (setq contents (concat contents "\nDESCRIPTION:"
729                                     (icalendar-convert-string-for-export                                     (icalendar--convert-string-for-export
730                                      entry-rest)))))                                      entry-rest)))))
731           ;; diary-date -- FIXME           ;; diary-date -- FIXME
732           ((string-match           ((string-match
733             (concat nonmarker             (concat nonmarker
734                     "%%(diary-date \\([^)]+\\))\\s-*\\(.*\\)")                     "%%(diary-date \\([^)]+\\))\\s-*\\(.*\\)")
735             entry-main)             entry-main)
736            (icalendar-dmsg "diary-date %s" entry-main)            (icalendar--dmsg "diary-date %s" entry-main)
737            (setq oops t))            (setq oops t))
738           ;; float events -- FIXME           ;; float events -- FIXME
739           ((string-match           ((string-match
740             (concat nonmarker             (concat nonmarker
741                     "%%(diary-float \\([^)]+\\))\\s-*\\(.*\\)")                     "%%(diary-float \\([^)]+\\))\\s-*\\(.*\\)")
742             entry-main)             entry-main)
743            (icalendar-dmsg "diary-float %s" entry-main)            (icalendar--dmsg "diary-float %s" entry-main)
744            (setq oops t))            (setq oops t))
745           ;; block events           ;; block events
746           ((string-match           ((string-match
# Line 719  Finto iCalendar file: ") Line 748  Finto iCalendar file: ")
748                     "%%(diary-block \\([^ /]+[ /]+[^ /]+[ /]+[^ ]+\\) +"                     "%%(diary-block \\([^ /]+[ /]+[^ /]+[ /]+[^ ]+\\) +"
749                     "\\([^ /]+[ /]+[^ /]+[ /]+[^ ]+\\))\\s-*\\(.*\\)")                     "\\([^ /]+[ /]+[^ /]+[ /]+[^ ]+\\))\\s-*\\(.*\\)")
750             entry-main)             entry-main)
751            (icalendar-dmsg "diary-block %s" entry-main)            (icalendar--dmsg "diary-block %s" entry-main)
752            (let* ((startstring (substring entry-main (match-beginning 1)            (let* ((startstring (substring entry-main (match-beginning 1)
753                                           (match-end 1)))                                           (match-end 1)))
754                   (endstring (substring entry-main (match-beginning 2)                   (endstring (substring entry-main (match-beginning 2)
755                                         (match-end 2)))                                         (match-end 2)))
756                   (summary (icalendar-convert-string-for-export                   (summary (icalendar--convert-string-for-export
757                             (substring entry-main (match-beginning 3)                             (substring entry-main (match-beginning 3)
758                                        (match-end 3))))                                        (match-end 3))))
759                   (startisostring (icalendar-datestring-to-isodate                   (startisostring (icalendar--datestring-to-isodate
760                                    startstring))                                    startstring))
761                   (endisostring (icalendar-datestring-to-isodate                   (endisostring (icalendar--datestring-to-isodate
762                                  endstring 1)))                                  endstring 1)))
763              (setq contents              (setq contents
764                    (concat "\nDTSTART;VALUE=DATE:" startisostring                    (concat "\nDTSTART;VALUE=DATE:" startisostring
765                            "\nDTEND;VALUE=DATE:" endisostring                            "\nDTEND;VALUE=DATE:" endisostring
# Line 738  Finto iCalendar file: ") Line 767  Finto iCalendar file: ")
767                            ))                            ))
768              (unless (string= entry-rest "")              (unless (string= entry-rest "")
769                (setq contents (concat contents "\nDESCRIPTION:"                (setq contents (concat contents "\nDESCRIPTION:"
770                                       (icalendar-convert-string-for-export                                       (icalendar--convert-string-for-export
771                                        entry-rest))))))                                        entry-rest))))))
772           ;; other sexp diary entries -- FIXME           ;; other sexp diary entries -- FIXME
773           ((string-match           ((string-match
774             (concat nonmarker             (concat nonmarker
775                     "%%(\\([^)]+\\))\\s-*\\(.*\\)")                     "%%(\\([^)]+\\))\\s-*\\(.*\\)")
776             entry-main)             entry-main)
777            (icalendar-dmsg "diary-sexp %s" entry-main)            (icalendar--dmsg "diary-sexp %s" entry-main)
778            (setq oops t))            (setq oops t))
779           ;; weekly by day           ;; weekly by day
780           ;; Monday 8:30 Team meeting           ;; Monday 8:30 Team meeting
# Line 758  Finto iCalendar file: ") Line 787  Finto iCalendar file: ")
787                          "\\)?"                          "\\)?"
788                          "\\s-*\\(.*\\)$")                          "\\s-*\\(.*\\)$")
789                  entry-main)                  entry-main)
790                 (icalendar-get-weekday-abbrev                 (icalendar--get-weekday-abbrev
791                  (substring entry-main (match-beginning 1) (match-end 1))))                  (substring entry-main (match-beginning 1) (match-end 1))))
792            (icalendar-dmsg "weekly %s" entry-main)            (icalendar--dmsg "weekly %s" entry-main)
793            (let* ((day (icalendar-get-weekday-abbrev            (let* ((day (icalendar--get-weekday-abbrev
794                         (substring entry-main (match-beginning 1)                         (substring entry-main (match-beginning 1)
795                                    (match-end 1))))                                    (match-end 1))))
796                   (starttimestring (icalendar-diarytime-to-isotime                   (starttimestring (icalendar--diarytime-to-isotime
797                                     (if (match-beginning 3)                                     (if (match-beginning 3)
798                                         (substring entry-main                                         (substring entry-main
799                                                    (match-beginning 3)                                                    (match-beginning 3)
# Line 775  Finto iCalendar file: ") Line 804  Finto iCalendar file: ")
804                                                    (match-beginning 4)                                                    (match-beginning 4)
805                                                    (match-end 4))                                                    (match-end 4))
806                                       nil)))                                       nil)))
807                   (endtimestring (icalendar-diarytime-to-isotime                   (endtimestring (icalendar--diarytime-to-isotime
808                                   (if (match-beginning 6)                                   (if (match-beginning 6)
809                                       (substring entry-main                                       (substring entry-main
810                                                  (match-beginning 6)                                                  (match-beginning 6)
811                                                  (match-end 6))                                                  (match-end 6))
812                                     nil)                                     nil)
813                                   (if (match-beginning 7)                                   (if (match-beginning 7)
814                                       (substring entry-main                                       (substring entry-main
815                                                  (match-beginning 7)                                                  (match-beginning 7)
816                                                  (match-end 7))                                                  (match-end 7))
817                                     nil)))                                     nil)))
818                   (summary (icalendar-convert-string-for-export                   (summary (icalendar--convert-string-for-export
819                             (substring entry-main (match-beginning 8)                             (substring entry-main (match-beginning 8)
820                                        (match-end 8)))))                                        (match-end 8)))))
821              (when starttimestring              (when starttimestring
822                (unless endtimestring                (unless endtimestring
823                  (let ((time (read (icalendar-rris "^T0?" ""                  (let ((time (read (icalendar--rris "^T0?" ""
824                                                    starttimestring))))                                                     starttimestring))))
825                    (setq endtimestring (format "T%06d" (+ 10000 time))))))                    (setq endtimestring (format "T%06d" (+ 10000 time))))))
826              (setq contents              (setq contents
827                    (concat "\nDTSTART"                    (concat "\nDTSTART"
# Line 809  Finto iCalendar file: ") Line 838  Finto iCalendar file: ")
838                            )))                            )))
839            (unless (string= entry-rest "")            (unless (string= entry-rest "")
840              (setq contents (concat contents "\nDESCRIPTION:"              (setq contents (concat contents "\nDESCRIPTION:"
841                                     (icalendar-convert-string-for-export                                     (icalendar--convert-string-for-export
842                                      entry-rest)))))                                      entry-rest)))))
843           ;; yearly by day           ;; yearly by day
844           ;; 1 May Tag der Arbeit           ;; 1 May Tag der Arbeit
# Line 821  Finto iCalendar file: ") Line 850  Finto iCalendar file: ")
850                     "\\*?\\s-*"                     "\\*?\\s-*"
851                     "\\(0?\\([1-9][0-9]?:[0-9][0-9]\\)\\([ap]m\\)?"                     "\\(0?\\([1-9][0-9]?:[0-9][0-9]\\)\\([ap]m\\)?"
852                     "\\("                     "\\("
853                     "-0?\\([1-9][0-9]?:[0-9][0-9]\\)\\([ap]m\\)?\\)?"                     "-0?\\([1-9][0-9]?:[0-9][0-9]\\)\\([ap]m\\)?\\)?"
854                     "\\)?"                     "\\)?"
855                     "\\s-*\\([^0-9]+.*\\)$"; must not match years                     "\\s-*\\([^0-9]+.*\\)$" ; must not match years
856                     )                     )
857             entry-main)             entry-main)
858            (icalendar-dmsg "yearly %s" entry-main)            (icalendar--dmsg "yearly %s" entry-main)
859            (let* ((daypos (if european-calendar-style 1 2))            (let* ((daypos (if european-calendar-style 1 2))
860                   (monpos (if european-calendar-style 2 1))                   (monpos (if european-calendar-style 2 1))
861                   (day (read (substring entry-main (match-beginning daypos)                   (day (read (substring entry-main (match-beginning daypos)
862                                         (match-end daypos))))                                         (match-end daypos))))
863                   (month (icalendar-get-month-number                   (month (icalendar--get-month-number
864                           (substring entry-main (match-beginning monpos)                           (substring entry-main (match-beginning monpos)
865                                      (match-end monpos))))                                      (match-end monpos))))
866                   (starttimestring (icalendar-diarytime-to-isotime                   (starttimestring (icalendar--diarytime-to-isotime
867                                     (if (match-beginning 4)                                     (if (match-beginning 4)
868                                         (substring entry-main                                         (substring entry-main
869                                                    (match-beginning 4)                                                    (match-beginning 4)
# Line 845  Finto iCalendar file: ") Line 874  Finto iCalendar file: ")
874                                                    (match-beginning 5)                                                    (match-beginning 5)
875                                                    (match-end 5))                                                    (match-end 5))
876                                       nil)))                                       nil)))
877                   (endtimestring (icalendar-diarytime-to-isotime                   (endtimestring (icalendar--diarytime-to-isotime
878                                   (if (match-beginning 7)                                   (if (match-beginning 7)
879                                       (substring entry-main                                       (substring entry-main
880                                                  (match-beginning 7)                                                  (match-beginning 7)
881                                                  (match-end 7))                                                  (match-end 7))
882                                     nil)                                     nil)
883                                   (if (match-beginning 8)                                   (if (match-beginning 8)
884                                       (substring entry-main                                       (substring entry-main
885                                                  (match-beginning 8)                                                  (match-beginning 8)
886                                                  (match-end 8))                                                  (match-end 8))
887                                     nil)))                                     nil)))
888                   (summary (icalendar-convert-string-for-export                   (summary (icalendar--convert-string-for-export
889                             (substring entry-main (match-beginning 9)                             (substring entry-main (match-beginning 9)
890                                        (match-end 9)))))                                        (match-end 9)))))
891              (when starttimestring              (when starttimestring
892                (unless endtimestring                (unless endtimestring
893                  (let ((time (read (icalendar-rris "^T0?" ""                  (let ((time (read (icalendar--rris "^T0?" ""
894                                                    starttimestring))))                                                     starttimestring))))
895                    (setq endtimestring (format "T%06d" (+ 10000 time))))))                    (setq endtimestring (format "T%06d" (+ 10000 time))))))
896              (setq contents              (setq contents
897                    (concat "\nDTSTART"                    (concat "\nDTSTART"
# Line 881  Finto iCalendar file: ") Line 910  Finto iCalendar file: ")
910                            )))                            )))
911            (unless (string= entry-rest "")            (unless (string= entry-rest "")
912              (setq contents (concat contents "\nDESCRIPTION:"              (setq contents (concat contents "\nDESCRIPTION:"
913                                     (icalendar-convert-string-for-export                                     (icalendar--convert-string-for-export
914                                      entry-rest)))))                                      entry-rest)))))
915           ;; "ordinary" events, start and end time given           ;; "ordinary" events, start and end time given
916           ;; 1 Feb 2003 Hs Hochzeitsfeier, Dreieich           ;; 1 Feb 2003 Hs Hochzeitsfeier, Dreieich
# Line 890  Finto iCalendar file: ") Line 919  Finto iCalendar file: ")
919                     "\\([^ /]+[ /]+[^ /]+[ /]+[^ ]+\\)\\s-+"                     "\\([^ /]+[ /]+[^ /]+[ /]+[^ ]+\\)\\s-+"
920                     "\\(0?\\([1-9][0-9]?:[0-9][0-9]\\)\\([ap]m\\)?"                     "\\(0?\\([1-9][0-9]?:[0-9][0-9]\\)\\([ap]m\\)?"
921                     "\\("                     "\\("
922                     "-0?\\([1-9][0-9]?:[0-9][0-9]\\)\\([ap]m\\)?\\)?"                     "-0?\\([1-9][0-9]?:[0-9][0-9]\\)\\([ap]m\\)?\\)?"
923                     "\\)?"                     "\\)?"
924                     "\\s-*\\(.*\\)")                     "\\s-*\\(.*\\)")
925             entry-main)             entry-main)
926            (icalendar-dmsg "ordinary %s" entry-main)            (icalendar--dmsg "ordinary %s" entry-main)
927            (let* ((datestring (icalendar-datestring-to-isodate            (let* ((datestring (icalendar--datestring-to-isodate
928                                (substring entry-main (match-beginning 1)                                (substring entry-main (match-beginning 1)
929                                           (match-end 1))))                                           (match-end 1))))
930                   (starttimestring (icalendar-diarytime-to-isotime                   (starttimestring (icalendar--diarytime-to-isotime
931                                     (if (match-beginning 3)                                     (if (match-beginning 3)
932                                         (substring entry-main                                         (substring entry-main
933                                                    (match-beginning 3)                                                    (match-beginning 3)
# Line 909  Finto iCalendar file: ") Line 938  Finto iCalendar file: ")
938                                                    (match-beginning 4)                                                    (match-beginning 4)
939                                                    (match-end 4))                                                    (match-end 4))
940                                       nil)))                                       nil)))
941                   (endtimestring (icalendar-diarytime-to-isotime                   (endtimestring (icalendar--diarytime-to-isotime
942                                   (if (match-beginning 6)                                   (if (match-beginning 6)
943                                       (substring entry-main                                       (substring entry-main
944                                                  (match-beginning 6)                                                  (match-beginning 6)
945                                                  (match-end 6))                                                  (match-end 6))
946                                     nil)                                     nil)
947                                   (if (match-beginning 7)                                   (if (match-beginning 7)
948                                       (substring entry-main                                       (substring entry-main
949                                                  (match-beginning 7)                                                  (match-beginning 7)
950                                                  (match-end 7))                                                  (match-end 7))
951                                     nil)))                                     nil)))
952                   (summary (icalendar-convert-string-for-export                   (summary (icalendar--convert-string-for-export
953                             (substring entry-main (match-beginning 8)                             (substring entry-main (match-beginning 8)
954                                        (match-end 8)))))                                        (match-end 8)))))
955              (when starttimestring              (when starttimestring
956                (unless endtimestring                (unless endtimestring
957                  (let ((time (read (icalendar-rris "^T0?" ""                  (let ((time (read (icalendar--rris "^T0?" ""
958                                                    starttimestring))))                                                     starttimestring))))
959                    (setq endtimestring (format "T%06d" (+ 10000 time))))))                    (setq endtimestring (format "T%06d" (+ 10000 time))))))
960              (setq contents (format              (setq contents (format
961                              "\nDTSTART%s:%s%s\nDTEND%s:%s%s\nSUMMARY:%s"                              "\nDTSTART%s:%s%s\nDTEND%s:%s%s\nSUMMARY:%s"
962                              (if starttimestring "" ";VALUE=DATE")                              (if starttimestring "" ";VALUE=DATE")
963                              datestring                              datestring
964                              (or starttimestring "")                              (or starttimestring "")
965                              (if endtimestring ""                              (if endtimestring ""
966                                ";VALUE=DATE")                                ";VALUE=DATE")
967                              datestring                              datestring
968                              (or endtimestring "")                              (or endtimestring "")
969                              summary))                              summary))
970              (unless (string= entry-rest "")              (unless (string= entry-rest "")
971                (setq contents (concat contents "\nDESCRIPTION:"                (setq contents (concat contents "\nDESCRIPTION:"
972                                       (icalendar-convert-string-for-export                                       (icalendar--convert-string-for-export
973                                        entry-rest))))))                                        entry-rest))))))
974           ;; everything else           ;; everything else
975           (t           (t
# Line 948  Finto iCalendar file: ") Line 977  Finto iCalendar file: ")
977            (setq oops t)))            (setq oops t)))
978          (if oops          (if oops
979              (message "Cannot export entry on line %d"              (message "Cannot export entry on line %d"
980                       (count-lines (point-min) (point)))                       (count-lines (point-min) (point)))
981            (setq result (concat result header contents "\nEND:VEVENT"))))            (setq result (concat result header contents "\nEND:VEVENT"))))
982        ;; we're done, insert everything into the file        ;; we're done, insert everything into the file
983        (let ((coding-system-for-write 'utf8))        (let ((coding-system-for-write 'utf8))
984          (set-buffer (find-file ical-filename))          (set-buffer (find-file ical-filename))
985          (unless do-not-clear-diary-file          (goto-char (point-max))
986            (erase-buffer))          (insert "BEGIN:VCALENDAR")
987          (insert          (insert "\nPRODID:-//Emacs//NONSGML icalendar.el//EN")
          "BEGIN:VCALENDAR\nPRODID:-//Emacs//NONSGML icalendar.el//EN")  
988          (insert "\nVERSION:2.0")          (insert "\nVERSION:2.0")
989          (insert result)          (insert result)
990          (insert "\nEND:VCALENDAR\n")))))          (insert "\nEND:VCALENDAR\n")))))
991    
   
992  ;; ======================================================================  ;; ======================================================================
993  ;; import -- convert icalendar to emacs-diary  ;; Import -- convert icalendar to emacs-diary
994  ;; ======================================================================  ;; ======================================================================
995    
996  ;; user function  ;; User function
997  (defun icalendar-import-file (ical-filename diary-filename  (defun icalendar-import-file (ical-filename diary-filename
998                                              &optional non-marking                                              &optional non-marking)
999                                              do-not-clear-diary-file)    "Import a iCalendar file and append to a diary file.
   "Import a iCalendar file and save to a diary file -- erases diary-file!  
1000  Argument ICAL-FILENAME output iCalendar file.  Argument ICAL-FILENAME output iCalendar file.
1001  Argument DIARY-FILENAME input `diary-file'.  Argument DIARY-FILENAME input `diary-file'.
1002  Optional argument NON-MARKING determines whether events are created as  Optional argument NON-MARKING determines whether events are created as
1003  non-marking or not.  non-marking or not."
 If DO-NOT-CLEAR-DIARY-FILE is not nil the target diary file is  
 not erased."  
1004    (interactive "fImport iCalendar data from file:    (interactive "fImport iCalendar data from file:
1005  Finto diary file (will be erased!):  Finto diary file:
1006  p")  p")
1007    ;; clean up the diary file    ;; clean up the diary file
1008    (save-current-buffer    (save-current-buffer
     (unless do-not-clear-diary-file  
       ;; clear the target diary file  
       (set-buffer (find-file diary-filename))  
       (erase-buffer))  
1009      ;; now load and convert from the ical file      ;; now load and convert from the ical file
1010      (set-buffer (find-file ical-filename))      (set-buffer (find-file ical-filename))
1011      (icalendar-extract-ical-from-buffer diary-filename t non-marking)))      (icalendar-import-buffer diary-filename t non-marking)))
1012    
1013  ; user function  ;; User function
1014  (defun icalendar-extract-ical-from-buffer (&optional  (defun icalendar-import-buffer (&optional diary-file do-not-ask
1015                                             diary-file do-not-ask                                            non-marking)
                                            non-marking)  
1016    "Extract iCalendar events from current buffer.    "Extract iCalendar events from current buffer.
1017    
1018  This function searches the current buffer for the first iCalendar  This function searches the current buffer for the first iCalendar
# Line 1013  reading, parsing, or converting iCalenda Line 1032  reading, parsing, or converting iCalenda
1032    (save-current-buffer    (save-current-buffer
1033      ;; prepare ical      ;; prepare ical
1034      (message "Preparing icalendar...")      (message "Preparing icalendar...")
1035      (set-buffer (icalendar-get-unfolded-buffer (current-buffer)))      (set-buffer (icalendar--get-unfolded-buffer (current-buffer)))
1036      (goto-char (point-min))      (goto-char (point-min))
1037      (message "Preparing icalendar...done")      (message "Preparing icalendar...done")
1038      (if (re-search-forward "^BEGIN:VCALENDAR\\s-*$" nil t)      (if (re-search-forward "^BEGIN:VCALENDAR\\s-*$" nil t)
# Line 1021  reading, parsing, or converting iCalenda Line 1040  reading, parsing, or converting iCalenda
1040            ;; read ical            ;; read ical
1041            (message "Reading icalendar...")            (message "Reading icalendar...")
1042            (beginning-of-line)            (beginning-of-line)
1043            (setq ical-contents (icalendar-read-element nil nil))            (setq ical-contents (icalendar--read-element nil nil))
1044            (message "Reading icalendar...done")            (message "Reading icalendar...done")
1045            ;; convert ical            ;; convert ical
1046            (message "Converting icalendar...")            (message "Converting icalendar...")
1047            (setq ical-errors (icalendar-convert-ical-to-diary            (setq ical-errors (icalendar--convert-ical-to-diary
1048                               ical-contents                               ical-contents
1049                               diary-file do-not-ask non-marking))                               diary-file do-not-ask non-marking))
1050            (when diary-file            (when diary-file
# Line 1035  reading, parsing, or converting iCalenda Line 1054  reading, parsing, or converting iCalenda
1054                (save-buffer)))                (save-buffer)))
1055            (message "Converting icalendar...done")            (message "Converting icalendar...done")
1056            (if (and ical-errors (y-or-n-p            (if (and ical-errors (y-or-n-p
1057                                  (concat "Something went wrong -- "                                  (concat "Something went wrong -- "
1058                                          "do you want to see the "                                          "do you want to see the "
1059                                          "error log? ")))                                          "error log? ")))
1060                (switch-to-buffer " *icalendar-errors*")))                (switch-to-buffer " *icalendar-errors*")))
1061        (message        (message
1062         "Current buffer does not contain icalendar contents!"))))         "Current buffer does not contain icalendar contents!"))))
1063    
1064  ;; ----------------------------------------------------------------------  (defalias 'icalendar-extract-ical-from-buffer 'icalendar-import-buffer)
1065    
1066    (make-obsolete 'icalendar-extract-ical-from-buffer 'icalendar-import-buffer
1067                   "icalendar 0.07")
1068    
1069    ;; ======================================================================
1070  ;; private area  ;; private area
1071  ;; ----------------------------------------------------------------------  ;; ======================================================================
1072  (defun icalendar-format-ical-event (event)  
1073    (defun icalendar--format-ical-event (event)
1074    "Create a string representation of an iCalendar EVENT."    "Create a string representation of an iCalendar EVENT."
1075    (let ((string icalendar-import-format)    (let ((string icalendar-import-format)
1076          (conversion-list          (conversion-list
# Line 1058  reading, parsing, or converting iCalenda Line 1083  reading, parsing, or converting iCalenda
1083                (let* ((spec (car i))                (let* ((spec (car i))
1084                       (prop (cadr i))                       (prop (cadr i))
1085                       (format (car (cddr i)))                       (format (car (cddr i)))
1086                       (contents (icalendar-get-event-property event prop))                       (contents (icalendar--get-event-property event prop))
1087                       (formatted-contents ""))                       (formatted-contents ""))
                 ;;(message "%s" event)  
                 ;;(message "contents%s = %s" prop contents)  
1088                  (when (and contents (> (length contents) 0))                  (when (and contents (> (length contents) 0))
1089                    (setq formatted-contents                    (setq formatted-contents
1090                          (icalendar-rris "%s"                          (icalendar--rris "%s"
1091                                          (icalendar-convert-for-import                                           (icalendar--convert-string-for-import
1092                                           contents)                                            contents)
1093                                          (symbol-value format))))                                           (symbol-value format))))
1094                  (setq string (icalendar-rris spec                  (setq string (icalendar--rris spec
1095                                               formatted-contents                                                formatted-contents
1096                                               string))))                                                string))))
1097              conversion-list)              conversion-list)
1098      string))      string))
1099    
1100  (defun icalendar-convert-ical-to-diary (ical-list diary-file  (defun icalendar--convert-ical-to-diary (ical-list diary-file
1101                                                    &optional do-not-ask                                                     &optional do-not-ask
1102                                                    non-marking)                                                     non-marking)
1103    "Convert an iCalendar file to an Emacs diary file.    "Convert an iCalendar file to an Emacs diary file.
1104  Import VEVENTS from the iCalendar object ICAL-LIST and saves them to a  Import VEVENTS from the iCalendar object ICAL-LIST and saves them to a
1105  DIARY-FILE.  If DO-NOT-ASK is nil the user is asked for each event  DIARY-FILE.  If DO-NOT-ASK is nil the user is asked for each event
# Line 1085  events are created as non-marking. Line 1108  events are created as non-marking.
1108  This function attempts to return t if something goes wrong.  In this  This function attempts to return t if something goes wrong.  In this
1109  case an error string which describes all the errors and problems is  case an error string which describes all the errors and problems is
1110  written into the buffer ` *icalendar-errors*'."  written into the buffer ` *icalendar-errors*'."
1111    (let* ((ev (icalendar-all-events ical-list))    (let* ((ev (icalendar--all-events ical-list))
1112           (error-string "")           (error-string "")
1113           (event-ok t)           (event-ok t)
1114           (found-error nil)           (found-error nil)
# Line 1096  written into the buffer ` *icalendar-err Line 1119  written into the buffer ` *icalendar-err
1119        (setq ev (cdr ev))        (setq ev (cdr ev))
1120        (setq event-ok nil)        (setq event-ok nil)
1121        (condition-case error-val        (condition-case error-val
1122            (let* ((dtstart (icalendar-decode-isodatetime            (let* ((dtstart (icalendar--decode-isodatetime
1123                             (icalendar-get-event-property e 'DTSTART)))                             (icalendar--get-event-property e 'DTSTART)))
1124                   (start-d (calendar-date-string                   (start-d (calendar-date-string
1125                             (icalendar-datetime-to-noneuropean-date                             (icalendar--datetime-to-noneuropean-date
1126                              dtstart)                              dtstart)
1127                             t t))                             t t))
1128                   (start-t (icalendar-datetime-to-colontime dtstart))                   (start-t (icalendar--datetime-to-colontime dtstart))
1129                   (dtend (icalendar-decode-isodatetime                   (dtend (icalendar--decode-isodatetime
1130                           (icalendar-get-event-property e 'DTEND)))                           (icalendar--get-event-property e 'DTEND)))
1131                   end-d                   end-d
1132                   end-t                   end-t
1133                   (subject (icalendar-convert-for-import                   (subject (icalendar--convert-string-for-import
1134                             (or (icalendar-get-event-property e 'SUMMARY)                             (or (icalendar--get-event-property e 'SUMMARY)
1135                                 "No Subject")))                                 "No Subject")))
1136                   (rrule (icalendar-get-event-property e 'RRULE))                   (rrule (icalendar--get-event-property e 'RRULE))
1137                   (rdate (icalendar-get-event-property e 'RDATE))                   (rdate (icalendar--get-event-property e 'RDATE))
1138                   (duration (icalendar-get-event-property e 'DURATION)))                   (duration (icalendar--get-event-property e 'DURATION)))
1139              (icalendar-dmsg "%s: %s" start-d subject)              (icalendar--dmsg "%s: %s" start-d subject)
1140              (when duration              (when duration
1141                (let ((dtend2 (icalendar-add-decoded-times                (let ((dtend2 (icalendar--add-decoded-times
1142                               dtstart                               dtstart
1143                               (icalendar-decode-isoduration duration))))                               (icalendar--decode-isoduration duration))))
1144                  (if (and dtend (not (eq dtend dtend2)))                  (if (and dtend (not (eq dtend dtend2)))
1145                      (message "Inconsistent endtime and duration for %s"                      (message "Inconsistent endtime and duration for %s"
1146                               subject))                               subject))
1147                  (setq dtend dtend2)))                  (setq dtend dtend2)))
1148              (setq end-d (if dtend              (setq end-d (if dtend
1149                              (calendar-date-string                              (calendar-date-string
1150                               (icalendar-datetime-to-noneuropean-date                               (icalendar--datetime-to-noneuropean-date
1151                                dtend)                                dtend)
1152                               t t)                               t t)
1153                            start-d))                            start-d))
1154              (setq end-t (if dtend              (setq end-t (if dtend
1155                              (icalendar-datetime-to-colontime dtend)                              (icalendar--datetime-to-colontime dtend)
1156                            start-t))                            start-t))
1157              (icalendar-dmsg "start-d: %s, end-d: %s" start-d end-d)              (icalendar--dmsg "start-d: %s, end-d: %s" start-d end-d)
1158              (cond              (cond
1159               ;; recurring event               ;; recurring event
1160               (rrule               (rrule
1161                (icalendar-dmsg "recurring event")                (icalendar--dmsg "recurring event")
1162                (let* ((rrule-props (icalendar-split-value rrule))                (let* ((rrule-props (icalendar--split-value rrule))
1163                       (frequency (car (cdr (assoc 'FREQ rrule-props))))                       (frequency (car (cdr (assoc 'FREQ rrule-props))))
1164                       (until (car (cdr (assoc 'UNTIL rrule-props))))                       (until (car (cdr (assoc 'UNTIL rrule-props))))
1165                       (interval  (read (car (cdr (assoc 'INTERVAL                       (interval  (read (car (cdr (assoc 'INTERVAL
1166                                                         rrule-props))))))                                                         rrule-props))))))
1167                  (cond ((string-equal frequency "WEEKLY")                  (cond ((string-equal frequency "WEEKLY")
1168                         (if (not start-t)                         (if (not start-t)
1169                             (progn                             (progn
1170                               ;; weekly and all-day                               ;; weekly and all-day
1171                               (icalendar-dmsg "weekly all-day")                               (icalendar--dmsg "weekly all-day")
1172                               (setq diary-string                               (setq diary-string
1173                                     (format                                     (format
1174                                      "%%%%(diary-cyclic %d %s)"                                      "%%%%(diary-cyclic %d %s)"
1175                                      (* interval 7)                                      (* interval 7)
1176                                      (icalendar-datetime-to-european-date                                      (icalendar--datetime-to-european-date
1177                                       dtstart))))                                       dtstart))))
1178                           ;; weekly and not all-day                           ;; weekly and not all-day
1179                           (let* ((byday (cadr (assoc 'BYDAY rrule-props)))                           (let* ((byday (cadr (assoc 'BYDAY rrule-props)))
1180                                  (weekday                                  (weekday
1181                                   (cdr (rassoc                                   (icalendar--get-weekday-number byday)))
1182                                         byday                             (icalendar--dmsg "weekly not-all-day")
1183                                         icalendar-weekdayabbrev-table))))                             (if (> weekday -1)
                            (icalendar-dmsg "weekly not-all-day")  
                            (if weekday  
1184                                 (setq diary-string                                 (setq diary-string
1185                                       (format "%s %s%s%s" weekday                                       (format "%s %s%s%s"
1186                                                 (aref calendar-day-name-array
1187                                                       weekday)
1188                                               start-t (if end-t "-" "")                                               start-t (if end-t "-" "")
1189                                               (or end-t "")))                                               (or end-t "")))
1190                               ;; FIXME!!!!                               ;; FIXME!!!!
# Line 1169  written into the buffer ` *icalendar-err Line 1192  written into the buffer ` *icalendar-err
1192                               ;; DTEND;VALUE=DATE-TIME:20030919T113000                               ;; DTEND;VALUE=DATE-TIME:20030919T113000
1193                               (setq diary-string                               (setq diary-string
1194                                     (format                                     (format
1195                                      "%%%%(diary-cyclic %s %s) %s%s%s"                                      "%%%%(diary-cyclic %s %s) %s%s%s"
1196                                      (* interval 7)                                      (* interval 7)
1197                                      (icalendar-datetime-to-european-date                                      (icalendar--datetime-to-european-date
1198                                       dtstart)                                       dtstart)
1199                                      start-t (if end-t "-" "") (or end-t ""))))                                      start-t (if end-t "-" "") (or end-t ""))))
1200                             (setq event-ok t))))                             (setq event-ok t))))
1201                        ;; yearly                        ;; yearly
1202                        ((string-equal frequency "YEARLY")                        ((string-equal frequency "YEARLY")
1203                         (icalendar-dmsg "yearly")                         (icalendar--dmsg "yearly")
1204                         (setq diary-string                         (setq diary-string
1205                               (format                               (format
1206                                "%%%%(diary-anniversary %s)"                                "%%%%(diary-anniversary %s)"
1207                                (icalendar-datetime-to-european-date dtstart)))                                (icalendar--datetime-to-european-date dtstart)))
1208                         (setq event-ok t))                         (setq event-ok t))
1209                        ;; FIXME: war auskommentiert:                        ;; FIXME: war auskommentiert:
1210                        ((and (string-equal frequency "DAILY")                        ((and (string-equal frequency "DAILY")
# Line 1189  written into the buffer ` *icalendar-err Line 1212  written into the buffer ` *icalendar-err
1212                              ;;(not start-t)                              ;;(not start-t)
1213                              ;;(not end-t)                              ;;(not end-t)
1214                              )                              )
1215                         (let ((ds (icalendar-datetime-to-noneuropean-date                         (let ((ds (icalendar--datetime-to-noneuropean-date
1216                                    (icalendar-decode-isodatetime                                    (icalendar--decode-isodatetime
1217                                     (icalendar-get-event-property e                                     (icalendar--get-event-property e
1218                                                                   'DTSTART))))                                                                    'DTSTART))))
1219                               (de (icalendar-datetime-to-noneuropean-date                               (de (icalendar--datetime-to-noneuropean-date
1220                                    (icalendar-decode-isodatetime                                    (icalendar--decode-isodatetime
1221                                     until))))                                     until))))
1222                           (setq diary-string                           (setq diary-string
1223                                 (format                                 (format
1224                                  "%%%%(diary-block %d %d %d  %d %d %d)"                                  "%%%%(diary-block %d %d %d  %d %d %d)"
1225                                  (nth 1 ds) (nth 0 ds) (nth 2 ds)                                  (nth 1 ds) (nth 0 ds) (nth 2 ds)
1226                                  (nth 1 de) (nth 0 de) (nth 2 de))))                                  (nth 1 de) (nth 0 de) (nth 2 de))))
1227                         (setq event-ok t)))                         (setq event-ok t)))
1228                  ))                  ))
1229               (rdate               (rdate
1230                (icalendar-dmsg "rdate event")                (icalendar--dmsg "rdate event")
1231                (setq diary-string "")                (setq diary-string "")
1232                (mapcar (lambda (datestring)                (mapcar (lambda (datestring)
1233                          (setq diary-string                          (setq diary-string
1234                                (concat diary-string                                (concat diary-string
1235                                        (format "......"))))                                        (format "......"))))
1236                        (icalendar-split-value rdate)))                        (icalendar--split-value rdate)))
1237               ;; non-recurring event               ;; non-recurring event
1238               ;; long event               ;; long event
1239               ((not (string= start-d end-d))               ((not (string= start-d end-d))
1240                (icalendar-dmsg "non-recurring event")                (icalendar--dmsg "non-recurring event")
1241                (let ((ds (icalendar-datetime-to-noneuropean-date dtstart))                (let ((ds (icalendar--datetime-to-noneuropean-date dtstart))
1242                      (de (icalendar-datetime-to-noneuropean-date dtend)))                      (de (icalendar--datetime-to-noneuropean-date dtend)))
1243                  (setq diary-string                  (setq diary-string
1244                        (format "%%%%(diary-block %d %d %d   %d %d %d)"                        (format "%%%%(diary-block %d %d %d   %d %d %d)"
1245                                (nth 1 ds) (nth 0 ds) (nth 2 ds)                                (nth 1 ds) (nth 0 ds) (nth 2 ds)
# Line 1225  written into the buffer ` *icalendar-err Line 1248  written into the buffer ` *icalendar-err
1248               ;; not all-day               ;; not all-day
1249               ((and start-t (or (not end-t)               ((and start-t (or (not end-t)
1250                                 (not (string= start-t end-t))))                                 (not (string= start-t end-t))))
1251                (icalendar-dmsg "not all day event")                (icalendar--dmsg "not all day event")
1252                (cond (end-t                (cond (end-t
1253                       (setq diary-string (format "%s %s-%s" start-d                       (setq diary-string (format "%s %s-%s" start-d
1254                                                  start-t end-t)))                                                  start-t end-t)))
1255                      (t                      (t
1256                       (setq diary-string (format "%s %s" start-d                       (setq diary-string (format "%s %s" start-d
1257                                                  start-t))))                                                  start-t))))
1258                (setq event-ok t))                (setq event-ok t))
1259               ;; all-day event               ;; all-day event
1260               (t               (t
1261                (icalendar-dmsg "all day event")                (icalendar--dmsg "all day event")
1262                (setq diary-string start-d)                (setq diary-string start-d)
1263                (setq event-ok t)))                (setq event-ok t)))
1264              ;; add all other elements unless the user doesn't want to have              ;; add all other elements unless the user doesn't want to have
# Line 1243  written into the buffer ` *icalendar-err Line 1266  written into the buffer ` *icalendar-err
1266              (if event-ok              (if event-ok
1267                  (progn                  (progn
1268                    (setq diary-string                    (setq diary-string
1269                          (concat diary-string " "                          (concat diary-string " "
1270                                  (icalendar-format-ical-event e)))                                  (icalendar--format-ical-event e)))
1271                    (if do-not-ask (setq subject nil))                    (if do-not-ask (setq subject nil))
1272                    (icalendar-add-diary-entry diary-string diary-file                    (icalendar--add-diary-entry diary-string diary-file
1273                                               non-marking subject))                                                non-marking subject))
1274                ;; event was not ok                ;; event was not ok
1275                (setq found-error t)                (setq found-error t)
1276                (setq error-string                (setq error-string
1277                      (format "%s\nCannot handle this event:%s"                      (format "%s\nCannot handle this event:%s"
1278                              error-string e))))                              error-string e))))
1279          ;; handle errors          ;; handle errors
1280          (error          (error
1281           (message "Ignoring event \"%s\"" e)           (message "Ignoring event \"%s\"" e)
# Line 1267  written into the buffer ` *icalendar-err Line 1290  written into the buffer ` *icalendar-err
1290      (message "Converting icalendar...done")      (message "Converting icalendar...done")
1291      found-error))      found-error))
1292    
1293  (defun icalendar-add-diary-entry (string diary-file non-marking  (defun icalendar--add-diary-entry (string diary-file non-marking
1294                                           &optional subject)                                            &optional subject)
1295    "Add STRING to the diary file DIARY-FILE.    "Add STRING to the diary file DIARY-FILE.
1296  STRING must be a properly formatted valid diary entry.  NON-MARKING  STRING must be a properly formatted valid diary entry.  NON-MARKING
1297  determines whether diary events are created as non-marking.  If  determines whether diary events are created as non-marking.  If
1298  SUBJECT is not nil it must be a string that gives the subject of the  SUBJECT is not nil it must be a string that gives the subject of the
1299  entry.  In this case the user will be asked whether he wants to insert  entry.  In this case the user will be asked whether he wants to insert
1300  the entry."  the entry."
1301    (when (or (not subject)                       ;    (when (or (not subject)               ;
1302              (y-or-n-p (format "Add appointment for `%s' to diary? "              (y-or-n-p (format "Add appointment for `%s' to diary? "
1303                                subject)))                                subject)))
1304      (when subject      (when subject
1305        (setq non-marking        (setq non-marking
1306              (y-or-n-p (format "Make appointment non-marking? "))))              (y-or-n-p (format "Make appointment non-marking? "))))
# Line 1287  the entry." Line 1310  the entry."
1310                (read-file-name "Add appointment to this diary file: ")))                (read-file-name "Add appointment to this diary file: ")))
1311        (make-diary-entry string non-marking diary-file))))        (make-diary-entry string non-marking diary-file))))
1312    
 ;; ======================================================================  
 ;; (add-hook 'list-diary-entries-hook 'include-icalendar-files)  
 ;; ======================================================================  
 (defun include-icalendar-files ()  
   "Not yet implemented.")  
   
1313  (provide 'icalendar)  (provide 'icalendar)
1314    
1315  ;; arch-tag: 74fdbe8e-0451-4e38-bb61-4416e822f4fc  ;; arch-tag: 74fdbe8e-0451-4e38-bb61-4416e822f4fc

Legend:
Removed from v.1.4.2.1  
changed lines
  Added in v.1.4.2.2

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26