/[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.5 by gm, Tue Nov 2 01:05:27 2004 UTC revision 1.6 by gm, Fri Feb 11 01:02:56 2005 UTC
# Line 1  Line 1 
1  ;;; icalendar.el --- iCalendar implementation -*-coding: utf-8 -*-  ;;; icalendar.el --- iCalendar implementation -*-coding: utf-8 -*-
2    
3  ;; Copyright (C) 2002, 2003, 2004  Free Software Foundation, Inc.  ;; Copyright (C) 2002, 2003, 2004, 2005  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
# Line 90  Line 90 
90    
91  ;;; Code:  ;;; Code:
92    
93  (defconst icalendar-version 0.08  (defconst icalendar-version 0.09
94    "Version number of icalendar.el.")    "Version number of icalendar.el.")
95    
96  ;; ======================================================================  ;; ======================================================================
# Line 268  it finds" Line 268  it finds"
268  ;;  (car (cddr event)))  ;;  (car (cddr event)))
269    
270  (defun icalendar--get-event-property (event prop)  (defun icalendar--get-event-property (event prop)
271    "For the given EVENT return the value of the property PROP."    "For the given EVENT return the value of the first occurence of PROP."
272    (catch 'found    (catch 'found
273      (let ((props (car (cddr event))) pp)      (let ((props (car (cddr event))) pp)
274        (while props        (while props
# Line 278  it finds" Line 278  it finds"
278          (setq props (cdr props))))          (setq props (cdr props))))
279      nil))      nil))
280    
281    (defun icalendar--get-event-property-attributes (event prop)
282      "For the given EVENT return attributes of the first occurence of PROP."
283      (catch 'found
284        (let ((props (car (cddr event))) pp)
285          (while props
286            (setq pp (car props))
287            (if (eq (car pp) prop)
288                (throw 'found (cadr pp)))
289            (setq props (cdr props))))
290        nil))
291    
292    (defun icalendar--get-event-properties (event prop)
293      "For the given EVENT return a list of all values of the property PROP."
294      (let ((props (car (cddr event))) pp result)
295        (while props
296          (setq pp (car props))
297          (if (eq (car pp) prop)
298              (setq result (cons (car (cddr pp)) result)))
299          (setq props (cdr props)))
300        result))
301    
302  ;; (defun icalendar--set-event-property (event prop new-value)  ;; (defun icalendar--set-event-property (event prop new-value)
303  ;;   "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."
304  ;;   (catch 'found  ;;   (catch 'found
# Line 319  children." Line 340  children."
340    (icalendar--get-children (car icalendar) 'VEVENT))    (icalendar--get-children (car icalendar) 'VEVENT))
341    
342  (defun icalendar--split-value (value-string)  (defun icalendar--split-value (value-string)
343    "Splits VALUE-STRING at ';='."    "Split VALUE-STRING at ';='."
344    (let ((result '())    (let ((result '())
345          param-name param-value)          param-name param-value)
346      (when value-string      (when value-string
# Line 424  multiple comma-separated values should b Line 445  multiple comma-separated values should b
445              (if (match-beginning 11)              (if (match-beginning 11)
446                  (setq seconds (read (substring isodurationstring                  (setq seconds (read (substring isodurationstring
447                                                 (match-beginning 12)                                                 (match-beginning 12)
448                                                 (match-end 12)))))                                                 (match-end 12))))))
             )  
449             ((match-beginning 13)        ;weeks only             ((match-beginning 13)        ;weeks only
450              (setq days (* 7 (read (substring isodurationstring              (setq days (* 7 (read (substring isodurationstring
451                                               (match-beginning 14)                                               (match-beginning 14)
452                                               (match-end 14))))))                                               (match-end 14)))))))
            )  
453            (list seconds minutes hours days months years)))            (list seconds minutes hours days months years)))
454      ;; isodatetimestring == nil      ;; isodatetimestring == nil
455      nil))      nil))
# Line 452  valid (year > 1900 or something)." Line 471  valid (year > 1900 or something)."
471                  ;;(or (nth 6 time1) (nth 6 time2)) ;; FIXME?                  ;;(or (nth 6 time1) (nth 6 time2)) ;; FIXME?
472                  )))                  )))
473    
474  (defun icalendar--datetime-to-noneuropean-date (datetime)  (defun icalendar--datetime-to-noneuropean-date (datetime &optional separator)
475    "Convert the decoded DATETIME to non-european-style format.    "Convert the decoded DATETIME to non-european-style format.
476  Non-European format: (month day year)."  Optional argument SEPARATOR gives the separator between month,
477    day, and year.  If nil a blank character is used as separator.
478    Non-European format: \"month day year\"."
479    (if datetime    (if datetime
480        (list (nth 4 datetime)            ;month        (format "%d%s%d%s%d" (nth 4 datetime) ;month
481              (nth 3 datetime)            ;day                (or separator " ")
482              (nth 5 datetime))           ;year                (nth 3 datetime)          ;day
483                  (or separator " ")
484                  (nth 5 datetime))         ;year
485      ;; datetime == nil      ;; datetime == nil
486      nil))      nil))
487    
488  (defun icalendar--datetime-to-european-date (datetime)  (defun icalendar--datetime-to-european-date (datetime &optional separator)
489    "Convert the decoded DATETIME to European format.    "Convert the decoded DATETIME to European format.
490    Optional argument SEPARATOR gives the separator between month,
491    day, and year.  If nil a blank character is used as separator.
492  European format: (day month year).  European format: (day month year).
493  FIXME"  FIXME"
494    (if datetime    (if datetime
495        (format "%d %d %d" (nth 3 datetime) ; day        (format "%d%s%d%s%d" (nth 3 datetime) ;day
496                  (or separator " ")
497                (nth 4 datetime)            ;month                (nth 4 datetime)            ;month
498                  (or separator " ")
499                (nth 5 datetime))           ;year                (nth 5 datetime))           ;year
500      ;; datetime == nil      ;; datetime == nil
501      nil))      nil))
502    
503    (defun icalendar--datetime-to-diary-date (datetime &optional separator)
504      "Convert the decoded DATETIME to diary format.
505    Optional argument SEPARATOR gives the separator between month,
506    day, and year.  If nil a blank character is used as separator.
507    Call icalendar--datetime-to-(non)-european-date according to
508    value of `european-calendar-style'."
509      (if european-calendar-style
510          (icalendar--datetime-to-european-date datetime separator)
511        (icalendar--datetime-to-noneuropean-date datetime separator)))
512    
513  (defun icalendar--datetime-to-colontime (datetime)  (defun icalendar--datetime-to-colontime (datetime)
514    "Extract the time part of a decoded DATETIME into 24-hour format.    "Extract the time part of a decoded DATETIME into 24-hour format.
515  Note that this silently ignores seconds."  Note that this silently ignores seconds."
# Line 495  Note that this silently ignores seconds. Line 532  Note that this silently ignores seconds.
532    
533  (defun icalendar--get-weekday-number (abbrevweekday)  (defun icalendar--get-weekday-number (abbrevweekday)
534    "Return the number for the ABBREVWEEKDAY."    "Return the number for the ABBREVWEEKDAY."
535    (catch 'found    (if abbrevweekday
536      (let ((num 0)        (catch 'found
537            (aw (downcase abbrevweekday)))          (let ((num 0)
538        (mapc (lambda (day)                (aw (downcase abbrevweekday)))
539                (let ((d (downcase day)))            (mapc (lambda (day)
540                  (if (string-equal d aw)                    (let ((d (downcase day)))
541                      (throw 'found num))                      (if (string-equal d aw)
542                  (setq num (1+ num))))                          (throw 'found num))
543              icalendar--weekday-array))                      (setq num (1+ num))))
544                    icalendar--weekday-array)))
545      ;; Error:      ;; Error:
546      -1))      -1))
547    
# Line 605  would be \"pm\"." Line 643  would be \"pm\"."
643          (format "T%04d00" starttimenum))          (format "T%04d00" starttimenum))
644      nil))      nil))
645    
646  (defun icalendar--convert-string-for-export (s)  (defun icalendar--convert-string-for-export (string)
647    "Escape comma and other critical characters in string S."    "Escape comma and other critical characters in STRING."
648    (icalendar--rris "," "\\\\," s))    (icalendar--rris "," "\\\\," string))
649    
650  (defun icalendar--convert-string-for-import (string)  (defun icalendar--convert-string-for-import (string)
651    "Remove escape chars for comma, semicolon etc. from STRING."    "Remove escape chars for comma, semicolon etc. from STRING."
# Line 641  Finto iCalendar file: ") Line 679  Finto iCalendar file: ")
679  All diary entries in the region from MIN to MAX in the current buffer are  All diary entries in the region from MIN to MAX in the current buffer are
680  converted to iCalendar format.  The result is appended to the file  converted to iCalendar format.  The result is appended to the file
681  ICAL-FILENAME.  ICAL-FILENAME.
682    This function attempts to return t if something goes wrong.  In this
683  Returns non-nil if an error occurred.  In this case an error message is  case an error string which describes all the errors and problems is
684  written to the buffer ` *icalendar-errors*'."  written into the buffer `*icalendar-errors*'."
685    (interactive "r    (interactive "r
686  FExport diary data into iCalendar file: ")  FExport diary data into iCalendar file: ")
687    (let ((result "")    (let ((result "")
# Line 659  FExport diary data into iCalendar file: Line 697  FExport diary data into iCalendar file:
697      (save-current-buffer      (save-current-buffer
698        (set-buffer (get-buffer-create " *icalendar-errors*"))        (set-buffer (get-buffer-create " *icalendar-errors*"))
699        (erase-buffer))        (erase-buffer))
700    
701      ;; here we go      ;; here we go
702      (save-excursion      (save-excursion
703        (goto-char min)        (goto-char min)
# Line 699  FExport diary data into iCalendar file: Line 738  FExport diary data into iCalendar file:
738                                  ;; but korganizer seems to expect this... ;(                                  ;; but korganizer seems to expect this... ;(
739                                  ;; and evolution doesn't understand it... :(                                  ;; and evolution doesn't understand it... :(
740                                  ;; so... who is wrong?!                                  ;; so... who is wrong?!
741                                  ";BYMONTH=" (substring startisostring 4 6)                                  ";BYMONTH="
742                                  ";BYMONTHDAY=" (substring startisostring 6 8)                                  (substring startisostring 4 6)
743                                  )))                                  ";BYMONTHDAY="
744                                    (substring startisostring 6 8))))
745                  (unless (string= entry-rest "")                  (unless (string= entry-rest "")
746                    (setq contents (concat contents "\nDESCRIPTION:"                    (setq contents
747                                           (icalendar--convert-string-for-export                          (concat contents "\nDESCRIPTION:"
748                                            entry-rest)))))                                  (icalendar--convert-string-for-export
749                                     entry-rest)))))
750                 ;; cyclic events                 ;; cyclic events
751                 ;; %%(diary-cyclic )                 ;; %%(diary-cyclic )
752                 ((string-match                 ((string-match
# Line 734  FExport diary data into iCalendar file: Line 775  FExport diary data into iCalendar file:
775                                  ;; BYSOMETHING here...                                  ;; BYSOMETHING here...
776                                  )))                                  )))
777                  (unless (string= entry-rest "")                  (unless (string= entry-rest "")
778                    (setq contents (concat contents "\nDESCRIPTION:"                    (setq contents
779                                           (icalendar--convert-string-for-export                          (concat contents "\nDESCRIPTION:"
780                                            entry-rest)))))                                  (icalendar--convert-string-for-export
781                                     entry-rest)))))
782                 ;; diary-date -- FIXME                 ;; diary-date -- FIXME
783                 ((string-match                 ((string-match
784                   (concat nonmarker                   (concat nonmarker
# Line 754  FExport diary data into iCalendar file: Line 796  FExport diary data into iCalendar file:
796                 ;; block events                 ;; block events
797                 ((string-match                 ((string-match
798                   (concat nonmarker                   (concat nonmarker
799                           "%%(diary-block \\([^ /]+[ /]+[^ /]+[ /]+[^ ]+\\) +"                           "%%(diary-block \\([^ /]+[ /]+[^ /]+[ /]+[^ ]+\\)"
800                           "\\([^ /]+[ /]+[^ /]+[ /]+[^ ]+\\))\\s-*\\(.*\\)")                           " +\\([^ /]+[ /]+[^ /]+[ /]+[^ ]+\\))\\s-*"
801                             "\\(.*\\)")
802                   entry-main)                   entry-main)
803                  (icalendar--dmsg "diary-block %s" entry-main)                  (icalendar--dmsg "diary-block %s" entry-main)
804                  (let* ((startstring (substring entry-main (match-beginning 1)                  (let* ((startstring (substring entry-main
805                                                   (match-beginning 1)
806                                                 (match-end 1)))                                                 (match-end 1)))
807                         (endstring (substring entry-main (match-beginning 2)                         (endstring (substring entry-main
808                                                 (match-beginning 2)
809                                               (match-end 2)))                                               (match-end 2)))
810                         (summary (icalendar--convert-string-for-export                         (summary (icalendar--convert-string-for-export
811                                   (substring entry-main (match-beginning 3)                                   (substring entry-main (match-beginning 3)
# Line 772  FExport diary data into iCalendar file: Line 817  FExport diary data into iCalendar file:
817                    (setq contents                    (setq contents
818                          (concat "\nDTSTART;VALUE=DATE:" startisostring                          (concat "\nDTSTART;VALUE=DATE:" startisostring
819                                  "\nDTEND;VALUE=DATE:" endisostring                                  "\nDTEND;VALUE=DATE:" endisostring
820                                  "\nSUMMARY:" summary                                  "\nSUMMARY:" summary))
                                 ))  
821                    (unless (string= entry-rest "")                    (unless (string= entry-rest "")
822                      (setq contents (concat contents "\nDESCRIPTION:"                      (setq contents
823                                             (icalendar--convert-string-for-export                            (concat contents "\nDESCRIPTION:"
824                                              entry-rest))))))                                    (icalendar--convert-string-for-export
825                                       entry-rest))))))
826                 ;; other sexp diary entries -- FIXME                 ;; other sexp diary entries -- FIXME
827                 ((string-match                 ((string-match
828                   (concat nonmarker                   (concat nonmarker
# Line 790  FExport diary data into iCalendar file: Line 835  FExport diary data into iCalendar file:
835                 ((and (string-match                 ((and (string-match
836                        (concat nonmarker                        (concat nonmarker
837                                "\\([a-z]+\\)\\s-+"                                "\\([a-z]+\\)\\s-+"
838                                "\\(0?\\([1-9][0-9]?:[0-9][0-9]\\)\\([ap]m\\)?"                                "\\(0?\\([1-9][0-9]?:[0-9][0-9]\\)"
839                                  "\\([ap]m\\)?"
840                                "\\(-0?"                                "\\(-0?"
841                                "\\([1-9][0-9]?:[0-9][0-9]\\)\\([ap]m\\)?\\)?"                                "\\([1-9][0-9]?:[0-9][0-9]\\)"
842                                  "\\([ap]m\\)?\\)?"
843                                "\\)?"                                "\\)?"
844                                "\\s-*\\(.*\\)$")                                "\\s-*\\(.*\\)$")
845                        entry-main)                        entry-main)
846                       (icalendar--get-weekday-abbrev                       (icalendar--get-weekday-abbrev
847                        (substring entry-main (match-beginning 1) (match-end 1))))                        (substring entry-main (match-beginning 1)
848                                     (match-end 1))))
849                  (icalendar--dmsg "weekly %s" entry-main)                  (icalendar--dmsg "weekly %s" entry-main)
850                  (let* ((day (icalendar--get-weekday-abbrev                  (let* ((day (icalendar--get-weekday-abbrev
851                               (substring entry-main (match-beginning 1)                               (substring entry-main (match-beginning 1)
# Line 829  FExport diary data into iCalendar file: Line 877  FExport diary data into iCalendar file:
877                                              (match-end 8)))))                                              (match-end 8)))))
878                    (when starttimestring                    (when starttimestring
879                      (unless endtimestring                      (unless endtimestring
880                        (let ((time (read (icalendar--rris "^T0?" ""                        (let ((time (read
881                                                           starttimestring))))                                     (icalendar--rris "^T0?" ""
882                          (setq endtimestring (format "T%06d" (+ 10000 time))))))                                                      starttimestring))))
883                            (setq endtimestring (format "T%06d"
884                                                        (+ 10000 time))))))
885                    (setq contents                    (setq contents
886                          (concat "\nDTSTART;"                          (concat "\nDTSTART;"
887                                  (if starttimestring                                  (if starttimestring
# Line 854  FExport diary data into iCalendar file: Line 904  FExport diary data into iCalendar file:
904                                      (if endtimestring 2 3)))                                      (if endtimestring 2 3)))
905                                  (or endtimestring "")                                  (or endtimestring "")
906                                  "\nSUMMARY:" summary                                  "\nSUMMARY:" summary
907                                  "\nRRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=" day                                  "\nRRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY="
908                                  )))                                  day)))
909                  (unless (string= entry-rest "")                  (unless (string= entry-rest "")
910                    (setq contents (concat contents "\nDESCRIPTION:"                    (setq contents
911                                           (icalendar--convert-string-for-export                          (concat contents "\nDESCRIPTION:"
912                                            entry-rest)))))                                  (icalendar--convert-string-for-export
913                                     entry-rest)))))
914                 ;; yearly by day                 ;; yearly by day
915                 ;; 1 May Tag der Arbeit                 ;; 1 May Tag der Arbeit
916                 ((string-match                 ((string-match
# Line 878  FExport diary data into iCalendar file: Line 929  FExport diary data into iCalendar file:
929                  (icalendar--dmsg "yearly %s" entry-main)                  (icalendar--dmsg "yearly %s" entry-main)
930                  (let* ((daypos (if european-calendar-style 1 2))                  (let* ((daypos (if european-calendar-style 1 2))
931                         (monpos (if european-calendar-style 2 1))                         (monpos (if european-calendar-style 2 1))
932                         (day (read (substring entry-main (match-beginning daypos)                         (day (read (substring entry-main
933                                                 (match-beginning daypos)
934                                               (match-end daypos))))                                               (match-end daypos))))
935                         (month (icalendar--get-month-number                         (month (icalendar--get-month-number
936                                 (substring entry-main (match-beginning monpos)                                 (substring entry-main
937                                              (match-beginning monpos)
938                                            (match-end monpos))))                                            (match-end monpos))))
939                         (starttimestring (icalendar--diarytime-to-isotime                         (starttimestring (icalendar--diarytime-to-isotime
940                                           (if (match-beginning 4)                                           (if (match-beginning 4)
# Line 910  FExport diary data into iCalendar file: Line 963  FExport diary data into iCalendar file:
963                                              (match-end 9)))))                                              (match-end 9)))))
964                    (when starttimestring                    (when starttimestring
965                      (unless endtimestring                      (unless endtimestring
966                        (let ((time (read (icalendar--rris "^T0?" ""                        (let ((time (read
967                                                           starttimestring))))                                     (icalendar--rris "^T0?" ""
968                          (setq endtimestring (format "T%06d" (+ 10000 time))))))                                                      starttimestring))))
969                            (setq endtimestring (format "T%06d"
970                                                        (+ 10000 time))))))
971                    (setq contents                    (setq contents
972                          (concat "\nDTSTART;"                          (concat "\nDTSTART;"
973                                  (if starttimestring "VALUE=DATE-TIME:"                                  (if starttimestring "VALUE=DATE-TIME:"
# Line 924  FExport diary data into iCalendar file: Line 979  FExport diary data into iCalendar file:
979                                    "VALUE=DATE:")                                    "VALUE=DATE:")
980                                  ;; end is not included! shift by one day                                  ;; end is not included! shift by one day
981                                  (icalendar--date-to-isodate                                  (icalendar--date-to-isodate
982                                   (list month day 1900) (if endtimestring 0 1))                                   (list month day 1900)
983                                     (if endtimestring 0 1))
984                                  (or endtimestring "")                                  (or endtimestring "")
985                                  "\nSUMMARY:"                                  "\nSUMMARY:"
986                                  summary                                  summary
987                                  "\nRRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH="                                  "\nRRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH="
988                                  (format "%2d" month)                                  (format "%2d" month)
989                                  ";BYMONTHDAY="                                  ";BYMONTHDAY="
990                                  (format "%2d" day)                                  (format "%2d" day))))
                                 )))  
991                  (unless (string= entry-rest "")                  (unless (string= entry-rest "")
992                    (setq contents (concat contents "\nDESCRIPTION:"                    (setq contents
993                                           (icalendar--convert-string-for-export                          (concat contents "\nDESCRIPTION:"
994                                            entry-rest)))))                                  (icalendar--convert-string-for-export
995                                     entry-rest)))))
996                 ;; "ordinary" events, start and end time given                 ;; "ordinary" events, start and end time given
997                 ;; 1 Feb 2003 Hs Hochzeitsfeier, Dreieich                 ;; 1 Feb 2003 Hs Hochzeitsfeier, Dreieich
998                 ((string-match                 ((string-match
# Line 982  FExport diary data into iCalendar file: Line 1038  FExport diary data into iCalendar file:
1038                      (error "Could not parse date"))                      (error "Could not parse date"))
1039                    (when starttimestring                    (when starttimestring
1040                      (unless endtimestring                      (unless endtimestring
1041                        (let ((time (read (icalendar--rris "^T0?" ""                        (let ((time
1042                                                           starttimestring))))                               (read (icalendar--rris "^T0?" ""
1043                          (setq endtimestring (format "T%06d" (+ 10000 time))))))                                                      starttimestring))))
1044                            (setq endtimestring (format "T%06d"
1045                                                        (+ 10000 time))))))
1046                    (setq contents (concat                    (setq contents (concat
1047                                    "\nDTSTART;"                                    "\nDTSTART;"
1048                                    (if starttimestring "VALUE=DATE-TIME:"                                    (if starttimestring "VALUE=DATE-TIME:"
# Line 1004  FExport diary data into iCalendar file: Line 1062  FExport diary data into iCalendar file:
1062                                    summary))                                    summary))
1063                    ;; could not parse the date                    ;; could not parse the date
1064                    (unless (string= entry-rest "")                    (unless (string= entry-rest "")
1065                      (setq contents (concat contents "\nDESCRIPTION:"                      (setq contents
1066                                             (icalendar--convert-string-for-export                            (concat contents "\nDESCRIPTION:"
1067                                              entry-rest))))))                                    (icalendar--convert-string-for-export
1068                                       entry-rest))))))
1069                 ;; everything else                 ;; everything else
1070                 (t                 (t
1071                  ;; Oops! what's that?                  ;; Oops! what's that?
# Line 1023  FExport diary data into iCalendar file: Line 1082  FExport diary data into iCalendar file:
1082                               entry-main))))))                               entry-main))))))
1083    
1084        ;; we're done, insert everything into the file        ;; we're done, insert everything into the file
1085        (let ((coding-system-for-write 'utf8))        (save-current-buffer
1086          (set-buffer (find-file ical-filename))          (let ((coding-system-for-write 'utf8))
1087          (goto-char (point-max))            (set-buffer (find-file ical-filename))
1088          (insert "BEGIN:VCALENDAR")            (goto-char (point-max))
1089          (insert "\nPRODID:-//Emacs//NONSGML icalendar.el//EN")            (insert "BEGIN:VCALENDAR")
1090          (insert "\nVERSION:2.0")            (insert "\nPRODID:-//Emacs//NONSGML icalendar.el//EN")
1091          (insert result)            (insert "\nVERSION:2.0")
1092          (insert "\nEND:VCALENDAR\n")))            (insert result)
1093              (insert "\nEND:VCALENDAR\n")
1094              ;; save the diary file
1095              (save-buffer))))
1096      found-error))      found-error))
1097    
1098  ;; ======================================================================  ;; ======================================================================
# Line 1046  Argument DIARY-FILENAME input `diary-fil Line 1108  Argument DIARY-FILENAME input `diary-fil
1108  Optional argument NON-MARKING determines whether events are created as  Optional argument NON-MARKING determines whether events are created as
1109  non-marking or not."  non-marking or not."
1110    (interactive "fImport iCalendar data from file:    (interactive "fImport iCalendar data from file:
1111  Finto diary file:  Finto diary file:
1112  p")  p")
1113    ;; clean up the diary file    ;; clean up the diary file
1114    (save-current-buffer    (save-current-buffer
# Line 1070  DO-NOT-ASK is set to t, so that you are Line 1132  DO-NOT-ASK is set to t, so that you are
1132  NON-MARKING determines whether diary events are created as  NON-MARKING determines whether diary events are created as
1133  non-marking.  non-marking.
1134    
1135  This function attempts to notify about problems that occur when  Return code t means that importing worked well, return code nil
1136  reading, parsing, or converting iCalendar data!"  means that an error has occured.  Error messages will be in the
1137    buffer `*icalendar-errors*'."
1138    (interactive)    (interactive)
1139    (save-current-buffer    (save-current-buffer
1140      ;; prepare ical      ;; prepare ical
# Line 1097  reading, parsing, or converting iCalenda Line 1160  reading, parsing, or converting iCalenda
1160                (set-buffer (find-buffer-visiting diary-file))                (set-buffer (find-buffer-visiting diary-file))
1161                (save-buffer)))                (save-buffer)))
1162            (message "Converting icalendar...done")            (message "Converting icalendar...done")
1163            (if (and ical-errors (y-or-n-p            ;; return t if no error occured
1164                                  (concat "Something went wrong -- "            (not ical-errors))
                                         "do you want to see the "  
                                         "error log? ")))  
               (switch-to-buffer " *icalendar-errors*")))  
1165        (message        (message
1166         "Current buffer does not contain icalendar contents!"))))         "Current buffer does not contain icalendar contents!")
1167          ;; return nil, i.e. import did not work
1168          nil)))
1169    
1170  (defalias 'icalendar-extract-ical-from-buffer 'icalendar-import-buffer)  (defalias 'icalendar-extract-ical-from-buffer 'icalendar-import-buffer)
1171  (make-obsolete 'icalendar-extract-ical-from-buffer 'icalendar-import-buffer)  (make-obsolete 'icalendar-extract-ical-from-buffer 'icalendar-import-buffer)
# Line 1163  written into the buffer ` *icalendar-err Line 1225  written into the buffer ` *icalendar-err
1225        (condition-case error-val        (condition-case error-val
1226            (let* ((dtstart (icalendar--decode-isodatetime            (let* ((dtstart (icalendar--decode-isodatetime
1227                             (icalendar--get-event-property e 'DTSTART)))                             (icalendar--get-event-property e 'DTSTART)))
1228                   (start-d (calendar-date-string                   (start-d (icalendar--datetime-to-diary-date
1229                             (icalendar--datetime-to-noneuropean-date                             dtstart))
                             dtstart)  
                            t t))  
1230                   (start-t (icalendar--datetime-to-colontime dtstart))                   (start-t (icalendar--datetime-to-colontime dtstart))
1231                   (dtend (icalendar--decode-isodatetime                   (dtend (icalendar--decode-isodatetime
1232                           (icalendar--get-event-property e 'DTEND)))                           (icalendar--get-event-property e 'DTEND)))
# Line 1179  written into the buffer ` *icalendar-err Line 1239  written into the buffer ` *icalendar-err
1239                   (rdate (icalendar--get-event-property e 'RDATE))                   (rdate (icalendar--get-event-property e 'RDATE))
1240                   (duration (icalendar--get-event-property e 'DURATION)))                   (duration (icalendar--get-event-property e 'DURATION)))
1241              (icalendar--dmsg "%s: %s" start-d subject)              (icalendar--dmsg "%s: %s" start-d subject)
1242                ;; check whether start-time is missing
1243                (if  (and (icalendar--get-event-property-attributes
1244                           e 'DTSTART)
1245                          (string= (cadr (icalendar--get-event-property-attributes
1246                                          e 'DTSTART))
1247                                   "DATE"))
1248                    (setq start-t nil))
1249              (when duration              (when duration
1250                (let ((dtend2 (icalendar--add-decoded-times                (let ((dtend2 (icalendar--add-decoded-times
1251                               dtstart                               dtstart
# Line 1188  written into the buffer ` *icalendar-err Line 1255  written into the buffer ` *icalendar-err
1255                               subject))                               subject))
1256                  (setq dtend dtend2)))                  (setq dtend dtend2)))
1257              (setq end-d (if dtend              (setq end-d (if dtend
1258                              (calendar-date-string                              (icalendar--datetime-to-diary-date dtend)
                              (icalendar--datetime-to-noneuropean-date  
                               dtend)  
                              t t)  
1259                            start-d))                            start-d))
1260              (setq end-t (if dtend              (setq end-t (if dtend
1261                              (icalendar--datetime-to-colontime dtend)                              (icalendar--datetime-to-colontime dtend)
# Line 1202  written into the buffer ` *icalendar-err Line 1266  written into the buffer ` *icalendar-err
1266               (rrule               (rrule
1267                (icalendar--dmsg "recurring event")                (icalendar--dmsg "recurring event")
1268                (let* ((rrule-props (icalendar--split-value rrule))                (let* ((rrule-props (icalendar--split-value rrule))
1269                       (frequency (car (cdr (assoc 'FREQ rrule-props))))                       (frequency (cadr (assoc 'FREQ rrule-props)))
1270                       (until (car (cdr (assoc 'UNTIL rrule-props))))                       (until (cadr (assoc 'UNTIL rrule-props)))
1271                       (interval  (read (car (cdr (assoc 'INTERVAL                       (interval (read (cadr (assoc 'INTERVAL rrule-props)))))
                                                        rrule-props))))))  
1272                  (cond ((string-equal frequency "WEEKLY")                  (cond ((string-equal frequency "WEEKLY")
1273                         (if (not start-t)                         (if (not start-t)
1274                             (progn                             (progn
1275                               ;; weekly and all-day                               ;; weekly and all-day
1276                               (icalendar--dmsg "weekly all-day")                               (icalendar--dmsg "weekly all-day")
1277                                 (if until
1278                                     (let ((fro
1279                                            (icalendar--datetime-to-diary-date
1280                                             (icalendar--decode-isodatetime
1281                                              (icalendar--get-event-property
1282                                               e
1283                                               'DTSTART))))
1284                                           (unt
1285                                            (icalendar--datetime-to-diary-date
1286                                             (icalendar--decode-isodatetime
1287                                              until))))
1288                               (setq diary-string                               (setq diary-string
1289                                     (format                                     (format
1290                                      "%%%%(diary-cyclic %d %s)"                                      (concat "%%%%(and "
1291                                                "(diary-cyclic %d %s) "
1292                                                "(diary-block %s %s))")
1293                                      (* interval 7)                                      (* interval 7)
1294                                      (icalendar--datetime-to-european-date                                      (icalendar--datetime-to-diary-date
1295                                       dtstart))))                                       dtstart)
1296                                        (icalendar--datetime-to-diary-date
1297                                         dtstart)
1298                                        (icalendar--datetime-to-diary-date
1299                                         (icalendar--decode-isodatetime
1300                                          until)))))
1301                                   (setq diary-string
1302                                         (format "%%%%(and (diary-cyclic %d %s))"
1303                                                 (* interval 7)
1304                                                 (icalendar--datetime-to-diary-date
1305                                                  dtstart))))
1306                                 (setq event-ok t))
1307                           ;; weekly and not all-day                           ;; weekly and not all-day
1308                           (let* ((byday (cadr (assoc 'BYDAY rrule-props)))                           (let* ((byday (cadr (assoc 'BYDAY rrule-props)))
1309                                  (weekday                                  (weekday
1310                                   (icalendar--get-weekday-number byday)))                                   (icalendar--get-weekday-number byday)))
1311                             (icalendar--dmsg "weekly not-all-day")                             (icalendar--dmsg "weekly not-all-day")
1312                             (if (> weekday -1)                             (if until
1313                                 (setq diary-string                                 (let ((fro
1314                                       (format "%s %s%s%s"                                        (icalendar--datetime-to-diary-date
1315                                               (aref calendar-day-name-array                                         (icalendar--decode-isodatetime
1316                                                     weekday)                                          (icalendar--get-event-property
1317                                               start-t (if end-t "-" "")                                           e
1318                                               (or end-t "")))                                           'DTSTART))))
1319                                         (unt
1320                                          (icalendar--datetime-to-diary-date
1321                                           (icalendar--decode-isodatetime
1322                                            until))))
1323                                     (setq diary-string
1324                                           (format
1325                                            (concat "%%%%(and "
1326                                                    "(diary-cyclic %d %s) "
1327                                                    "(diary-block %s %s)) "
1328                                                    "%s%s%s")
1329                                            (* interval 7)
1330                                            (icalendar--datetime-to-diary-date
1331                                             dtstart)
1332                                            (icalendar--datetime-to-diary-date
1333                                             dtstart)
1334                                            (icalendar--datetime-to-diary-date
1335                                             (icalendar--decode-isodatetime
1336                                              until))
1337                                            start-t
1338                                            (if end-t "-" "") (or end-t ""))))
1339                                 ;; no limit
1340                               ;; FIXME!!!!                               ;; FIXME!!!!
1341                               ;; DTSTART;VALUE=DATE-TIME:20030919T090000                               ;; DTSTART;VALUE=DATE-TIME:20030919T090000
1342                               ;; DTEND;VALUE=DATE-TIME:20030919T113000                               ;; DTEND;VALUE=DATE-TIME:20030919T113000
1343                               (setq diary-string                               (setq diary-string
1344                                     (format                                     (format
1345                                      "%%%%(diary-cyclic %s %s) %s%s%s"                                      "%%%%(and (diary-cyclic %s %s)) %s%s%s"
1346                                      (* interval 7)                                      (* interval 7)
1347                                      (icalendar--datetime-to-european-date                                      (icalendar--datetime-to-diary-date
1348                                       dtstart)                                       dtstart)
1349                                      start-t (if end-t "-" "") (or end-t ""))))                                      start-t
1350                                        (if end-t "-" "") (or end-t ""))))
1351                             (setq event-ok t))))                             (setq event-ok t))))
1352                        ;; yearly                        ;; yearly
1353                        ((string-equal frequency "YEARLY")                        ((string-equal frequency "YEARLY")
1354                         (icalendar--dmsg "yearly")                         (icalendar--dmsg "yearly")
1355                         (setq diary-string                         (setq diary-string
1356                               (format                               (format
1357                                "%%%%(diary-anniversary %s)"                                "%%%%(and (diary-anniversary %s))"
1358                                (icalendar--datetime-to-european-date dtstart)))                                (icalendar--datetime-to-diary-date dtstart)))
1359                         (setq event-ok t))                         (setq event-ok t))
1360                        ;; FIXME: war auskommentiert:                        ;; FIXME: war auskommentiert:
1361                        ((and (string-equal frequency "DAILY")                        ((and (string-equal frequency "DAILY")
# Line 1254  written into the buffer ` *icalendar-err Line 1363  written into the buffer ` *icalendar-err
1363                              ;;(not start-t)                              ;;(not start-t)
1364                              ;;(not end-t)                              ;;(not end-t)
1365                              )                              )
1366                         (let ((ds (icalendar--datetime-to-noneuropean-date                         (let ((ds (icalendar--datetime-to-diary-date
1367                                    (icalendar--decode-isodatetime                                    (icalendar--decode-isodatetime
1368                                     (icalendar--get-event-property e                                     (icalendar--get-event-property
1369                                                                    'DTSTART))))                                      e 'DTSTART))))
1370                               (de (icalendar--datetime-to-noneuropean-date                               (de (icalendar--datetime-to-diary-date
1371                                    (icalendar--decode-isodatetime                                    (icalendar--decode-isodatetime
1372                                     until))))                                     until))))
1373                           (setq diary-string                           (setq diary-string
1374                                 (format                                 (format
1375                                  "%%%%(diary-block %d %d %d  %d %d %d)"                                  "%%%%(and (diary-block %s %s))"
1376                                  (nth 1 ds) (nth 0 ds) (nth 2 ds)                                  ds de)))
1377                                  (nth 1 de) (nth 0 de) (nth 2 de))))                         (setq event-ok t))))
1378                         (setq event-ok t)))                ;; Handle exceptions from recurrence rules
1379                  ))                (let ((ex-dates (icalendar--get-event-properties e
1380                                                                   'EXDATE)))
1381                    (while ex-dates
1382                      (let* ((ex-start (icalendar--decode-isodatetime
1383                      (car ex-dates)))
1384                             (ex-d (icalendar--datetime-to-diary-date
1385                             ex-start)))
1386                        (setq diary-string
1387                              (icalendar--rris "^%%(\\(and \\)?"
1388                                               (format
1389                                               "%%%%(and (not (diary-date %s)) "
1390                                               ex-d)
1391                                               diary-string)))
1392                      (setq ex-dates (cdr ex-dates))))
1393                  ;; FIXME: exception rules are not recognized
1394                  (if (icalendar--get-event-property e 'EXRULE)
1395                      (setq diary-string
1396                            (concat diary-string
1397                                    "\n Exception rules: "
1398                                    (icalendar--get-event-properties
1399                                     e 'EXRULE)))))
1400               (rdate               (rdate
1401                (icalendar--dmsg "rdate event")                (icalendar--dmsg "rdate event")
1402                (setq diary-string "")                (setq diary-string "")
# Line 1280  written into the buffer ` *icalendar-err Line 1409  written into the buffer ` *icalendar-err
1409               ;; long event               ;; long event
1410               ((not (string= start-d end-d))               ((not (string= start-d end-d))
1411                (icalendar--dmsg "non-recurring event")                (icalendar--dmsg "non-recurring event")
1412                (let ((ds (icalendar--datetime-to-noneuropean-date dtstart))                (let ((ds (icalendar--datetime-to-diary-date dtstart))
1413                      (de (icalendar--datetime-to-noneuropean-date dtend)))                      (de (icalendar--datetime-to-diary-date dtend)))
1414                  (setq diary-string                  (setq diary-string
1415                        (format "%%%%(diary-block %d %d %d   %d %d %d)"                        (format "%%%%(and (diary-block %s %s))"
1416                                (nth 1 ds) (nth 0 ds) (nth 2 ds)                                ds de)))
                               (nth 1 de) (nth 0 de) (nth 2 de))))  
1417                (setq event-ok t))                (setq event-ok t))
1418               ;; not all-day               ;; not all-day
1419               ((and start-t (or (not end-t)               ((and start-t (or (not end-t)
1420                                 (not (string= start-t end-t))))                                 (not (string= start-t end-t))))
1421                (icalendar--dmsg "not all day event")                (icalendar--dmsg "not all day event")
1422                (cond (end-t                (cond (end-t
1423                       (setq diary-string (format "%s %s-%s" start-d                       (setq diary-string
1424                                                  start-t end-t)))                             (format "%s %s-%s"
1425                                       (icalendar--datetime-to-diary-date
1426                                        dtstart "/")
1427                                       start-t end-t)))
1428                      (t                      (t
1429                       (setq diary-string (format "%s %s" start-d                       (setq diary-string
1430                                                  start-t))))                             (format "%s %s"
1431                                       (icalendar--datetime-to-diary-date
1432                                        dtstart "/")
1433                                       start-t))))
1434                (setq event-ok t))                (setq event-ok t))
1435               ;; all-day event               ;; all-day event
1436               (t               (t
1437                (icalendar--dmsg "all day event")                (icalendar--dmsg "all day event")
1438                (setq diary-string start-d)                (setq diary-string (icalendar--datetime-to-diary-date
1439                                      dtstart "/"))
1440                (setq event-ok t)))                (setq event-ok t)))
1441              ;; add all other elements unless the user doesn't want to have              ;; add all other elements unless the user doesn't want to have
1442              ;; them              ;; them
# Line 1318  written into the buffer ` *icalendar-err Line 1453  written into the buffer ` *icalendar-err
1453                (setq error-string                (setq error-string
1454                      (format "%s\nCannot handle this event:%s"                      (format "%s\nCannot handle this event:%s"
1455                              error-string e))))                              error-string e))))
1456            ;; FIXME: inform user about ignored event properties
1457          ;; handle errors          ;; handle errors
1458          (error          (error
1459           (message "Ignoring event \"%s\"" e)           (message "Ignoring event \"%s\"" e)
1460           (setq found-error t)           (setq found-error t)
1461           (setq error-string (format "%s\nCannot handle this event: %s"           (setq error-string (format "%s\n%s\nCannot handle this event: %s"
1462                                      error-string e)))))                                      error-val error-string e))
1463             (message error-string))))
1464      (if found-error      (if found-error
1465          (save-current-buffer          (save-current-buffer
1466            (set-buffer (get-buffer-create " *icalendar-errors*"))            (set-buffer (get-buffer-create " *icalendar-errors*"))
# Line 1340  determines whether diary events are crea Line 1477  determines whether diary events are crea
1477  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
1478  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
1479  the entry."  the entry."
1480    (when (or (not subject)               ;    (when (or (not subject)
1481              (y-or-n-p (format "Add appointment for `%s' to diary? "              (y-or-n-p (format "Add appointment for `%s' to diary? "
1482                                subject)))                                subject)))
1483      (when subject      (when subject

Legend:
Removed from v.1.5  
changed lines
  Added in v.1.6

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