31 |
|
|
32 |
;;; History: |
;;; History: |
33 |
|
|
34 |
;; 0.07: Renamed commands! |
;; 0.07 onwards: see lisp/ChangeLog |
|
;; icalendar-extract-ical-from-buffer -> icalendar-import-buffer |
|
|
;; icalendar-convert-diary-to-ical -> icalendar-export-file |
|
|
;; Naming scheme: icalendar-.* = user command; icalendar--.* = |
|
|
;; internal. |
|
|
;; Added icalendar-export-region. |
|
|
;; The import and export commands do not clear their target file, |
|
|
;; but append their results to the target file. |
|
|
;; I18n-problems fixed -- use calendar-(month|day)-name-array. |
|
|
;; Fixed problems with export of multi-line diary entries. |
|
35 |
|
|
36 |
;; 0.06: Bugfixes regarding icalendar-import-format-*. |
;; 0.06: Bugfixes regarding icalendar-import-format-*. |
37 |
;; Fix in icalendar-convert-diary-to-ical -- thanks to Philipp |
;; Fix in icalendar-convert-diary-to-ical -- thanks to Philipp |
90 |
|
|
91 |
;;; Code: |
;;; Code: |
92 |
|
|
93 |
(defconst icalendar-version 0.07 |
(defconst icalendar-version 0.08 |
94 |
"Version number of icalendar.el.") |
"Version number of icalendar.el.") |
95 |
|
|
96 |
;; ====================================================================== |
;; ====================================================================== |
324 |
param-name param-value) |
param-name param-value) |
325 |
(when value-string |
(when value-string |
326 |
(save-current-buffer |
(save-current-buffer |
327 |
(set-buffer (get-buffer-create " *ical-temp*")) |
(set-buffer (get-buffer-create " *icalendar-work*")) |
328 |
(set-buffer-modified-p nil) |
(set-buffer-modified-p nil) |
329 |
(erase-buffer) |
(erase-buffer) |
330 |
(insert value-string) |
(insert value-string) |
520 |
(setq num (1+ num)))) |
(setq num (1+ num)))) |
521 |
calendar-day-name-array)) |
calendar-day-name-array)) |
522 |
;; Error: |
;; Error: |
523 |
"??")) |
nil)) |
524 |
|
|
525 |
|
(defun icalendar--date-to-isodate (date &optional day-shift) |
526 |
|
"Convert DATE to iso-style date. |
527 |
|
DATE must be a list of the form (month day year). |
528 |
|
If DAY-SHIFT is non-nil, the result is shifted by DAY-SHIFT days." |
529 |
|
(let ((mdy (calendar-gregorian-from-absolute |
530 |
|
(+ (calendar-absolute-from-gregorian date) |
531 |
|
(or day-shift 0))))) |
532 |
|
(format "%04d%02d%02d" (nth 2 mdy) (nth 0 mdy) (nth 1 mdy)))) |
533 |
|
|
534 |
|
|
535 |
(defun icalendar--datestring-to-isodate (datestring &optional day-shift) |
(defun icalendar--datestring-to-isodate (datestring &optional day-shift) |
536 |
"Convert diary-style DATESTRING to iso-style date. |
"Convert diary-style DATESTRING to iso-style date. |
588 |
(if (> day 0) |
(if (> day 0) |
589 |
(let ((mdy (calendar-gregorian-from-absolute |
(let ((mdy (calendar-gregorian-from-absolute |
590 |
(+ (calendar-absolute-from-gregorian (list month day |
(+ (calendar-absolute-from-gregorian (list month day |
591 |
year)) |
year)) |
592 |
(or day-shift 0))))) |
(or day-shift 0))))) |
593 |
(format "%04d%02d%02d" (nth 2 mdy) (nth 0 mdy) (nth 1 mdy))) |
(format "%04d%02d%02d" (nth 2 mdy) (nth 0 mdy) (nth 1 mdy))) |
594 |
nil))) |
nil))) |
626 |
"Export diary file to iCalendar format. |
"Export diary file to iCalendar format. |
627 |
All diary entries in the file DIARY-FILENAME are converted to iCalendar |
All diary entries in the file DIARY-FILENAME are converted to iCalendar |
628 |
format. The result is appended to the file ICAL-FILENAME." |
format. The result is appended to the file ICAL-FILENAME." |
629 |
(interactive "FExport diary data from file: |
(interactive "FExport diary data from file: |
630 |
Finto iCalendar file: ") |
Finto iCalendar file: ") |
631 |
(save-current-buffer |
(save-current-buffer |
632 |
(set-buffer (find-file diary-filename)) |
(set-buffer (find-file diary-filename)) |
633 |
(icalendar-export-region (point-min) (point-max) ical-filename))) |
(icalendar-export-region (point-min) (point-max) ical-filename))) |
634 |
|
|
635 |
(defalias 'icalendar-convert-diary-to-ical 'icalendar-export-file) |
(defalias 'icalendar-convert-diary-to-ical 'icalendar-export-file) |
636 |
(make-obsolete 'icalendar-convert-diary-to-ical 'icalendar-export-file |
(make-obsolete 'icalendar-convert-diary-to-ical 'icalendar-export-file) |
|
"icalendar 0.07") |
|
637 |
|
|
638 |
;; User function |
;; User function |
639 |
(defun icalendar-export-region (min max ical-filename) |
(defun icalendar-export-region (min max ical-filename) |
640 |
"Export region in diary file to iCalendar format. |
"Export region in diary file to iCalendar format. |
641 |
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 |
642 |
converted to iCalendar format. The result is appended to the file |
converted to iCalendar format. The result is appended to the file |
643 |
ICAL-FILENAME." |
ICAL-FILENAME. |
644 |
|
|
645 |
|
Returns non-nil if an error occurred. In this case an error message is |
646 |
|
written to the buffer ` *icalendar-errors*'." |
647 |
(interactive "r |
(interactive "r |
648 |
FExport diary data into iCalendar file: ") |
FExport diary data into iCalendar file: ") |
649 |
(let ((result "") |
(let ((result "") |
652 |
(entry-rest "") |
(entry-rest "") |
653 |
(header "") |
(header "") |
654 |
(contents) |
(contents) |
655 |
(oops nil) |
(found-error nil) |
656 |
(nonmarker (concat "^" (regexp-quote diary-nonmarking-symbol) |
(nonmarker (concat "^" (regexp-quote diary-nonmarking-symbol) |
657 |
"?"))) |
"?"))) |
658 |
|
;; prepare buffer with error messages |
659 |
|
(save-current-buffer |
660 |
|
(set-buffer (get-buffer-create " *icalendar-errors*")) |
661 |
|
(erase-buffer)) |
662 |
|
;; here we go |
663 |
(save-excursion |
(save-excursion |
664 |
(goto-char min) |
(goto-char min) |
665 |
(while (re-search-forward |
(while (re-search-forward |
672 |
(car (current-time)) |
(car (current-time)) |
673 |
(cadr (current-time)) |
(cadr (current-time)) |
674 |
(car (cddr (current-time))))) |
(car (cddr (current-time))))) |
675 |
(setq oops nil) |
(condition-case error-val |
676 |
(cond |
(progn |
677 |
;; anniversaries |
(cond |
678 |
((string-match |
;; anniversaries |
679 |
(concat nonmarker |
((string-match |
680 |
"%%(diary-anniversary \\([^)]+\\))\\s-*\\(.*\\)") |
(concat nonmarker |
681 |
entry-main) |
"%%(diary-anniversary \\([^)]+\\))\\s-*\\(.*\\)") |
682 |
(icalendar--dmsg "diary-anniversary %s" entry-main) |
entry-main) |
683 |
(let* ((datetime (substring entry-main (match-beginning 1) |
(icalendar--dmsg "diary-anniversary %s" entry-main) |
684 |
(match-end 1))) |
(let* ((datetime (substring entry-main (match-beginning 1) |
685 |
(summary (icalendar--convert-string-for-export |
(match-end 1))) |
686 |
(substring entry-main (match-beginning 2) |
(summary (icalendar--convert-string-for-export |
687 |
(match-end 2)))) |
(substring entry-main (match-beginning 2) |
688 |
(startisostring (icalendar--datestring-to-isodate |
(match-end 2)))) |
689 |
datetime)) |
(startisostring (icalendar--datestring-to-isodate |
690 |
(endisostring (icalendar--datestring-to-isodate |
datetime)) |
691 |
datetime 1))) |
(endisostring (icalendar--datestring-to-isodate |
692 |
(setq contents |
datetime 1))) |
693 |
(concat "\nDTSTART;VALUE=DATE:" startisostring |
(setq contents |
694 |
"\nDTEND;VALUE=DATE:" endisostring |
(concat "\nDTSTART;VALUE=DATE:" startisostring |
695 |
"\nSUMMARY:" summary |
"\nDTEND;VALUE=DATE:" endisostring |
696 |
"\nRRULE:FREQ=YEARLY;INTERVAL=1" |
"\nSUMMARY:" summary |
697 |
;; the following is redundant, |
"\nRRULE:FREQ=YEARLY;INTERVAL=1" |
698 |
;; but korganizer seems to expect this... ;( |
;; the following is redundant, |
699 |
;; and evolution doesn't understand it... :( |
;; but korganizer seems to expect this... ;( |
700 |
;; so... who is wrong?! |
;; and evolution doesn't understand it... :( |
701 |
";BYMONTH=" (substring startisostring 4 6) |
;; so... who is wrong?! |
702 |
";BYMONTHDAY=" (substring startisostring 6 8) |
";BYMONTH=" (substring startisostring 4 6) |
703 |
))) |
";BYMONTHDAY=" (substring startisostring 6 8) |
704 |
(unless (string= entry-rest "") |
))) |
705 |
(setq contents (concat contents "\nDESCRIPTION:" |
(unless (string= entry-rest "") |
706 |
(icalendar--convert-string-for-export |
(setq contents (concat contents "\nDESCRIPTION:" |
707 |
entry-rest))))) |
(icalendar--convert-string-for-export |
708 |
;; cyclic events |
entry-rest))))) |
709 |
;; %%(diary-cyclic ) |
;; cyclic events |
710 |
((string-match |
;; %%(diary-cyclic ) |
711 |
(concat nonmarker |
((string-match |
712 |
"%%(diary-cyclic \\([^ ]+\\) +" |
(concat nonmarker |
713 |
"\\([^ /]+[ /]+[^ /]+[ /]+[^ ]+\\))\\s-*\\(.*\\)") |
"%%(diary-cyclic \\([^ ]+\\) +" |
714 |
entry-main) |
"\\([^ /]+[ /]+[^ /]+[ /]+[^ ]+\\))\\s-*\\(.*\\)") |
715 |
(icalendar--dmsg "diary-cyclic %s" entry-main) |
entry-main) |
716 |
(let* ((frequency (substring entry-main (match-beginning 1) |
(icalendar--dmsg "diary-cyclic %s" entry-main) |
717 |
(match-end 1))) |
(let* ((frequency (substring entry-main (match-beginning 1) |
718 |
(datetime (substring entry-main (match-beginning 2) |
(match-end 1))) |
719 |
(match-end 2))) |
(datetime (substring entry-main (match-beginning 2) |
720 |
(summary (icalendar--convert-string-for-export |
(match-end 2))) |
721 |
(substring entry-main (match-beginning 3) |
(summary (icalendar--convert-string-for-export |
722 |
(match-end 3)))) |
(substring entry-main (match-beginning 3) |
723 |
(startisostring (icalendar--datestring-to-isodate |
(match-end 3)))) |
724 |
datetime)) |
(startisostring (icalendar--datestring-to-isodate |
725 |
(endisostring (icalendar--datestring-to-isodate |
datetime)) |
726 |
datetime 1))) |
(endisostring (icalendar--datestring-to-isodate |
727 |
(setq contents |
datetime 1))) |
728 |
(concat "\nDTSTART;VALUE=DATE:" startisostring |
(setq contents |
729 |
"\nDTEND;VALUE=DATE:" endisostring |
(concat "\nDTSTART;VALUE=DATE:" startisostring |
730 |
"\nSUMMARY:" summary |
"\nDTEND;VALUE=DATE:" endisostring |
731 |
"\nRRULE:FREQ=DAILY;INTERVAL=" frequency |
"\nSUMMARY:" summary |
732 |
;; strange: korganizer does not expect |
"\nRRULE:FREQ=DAILY;INTERVAL=" frequency |
733 |
;; BYSOMETHING here... |
;; strange: korganizer does not expect |
734 |
))) |
;; BYSOMETHING here... |
735 |
(unless (string= entry-rest "") |
))) |
736 |
(setq contents (concat contents "\nDESCRIPTION:" |
(unless (string= entry-rest "") |
737 |
(icalendar--convert-string-for-export |
(setq contents (concat contents "\nDESCRIPTION:" |
738 |
entry-rest))))) |
(icalendar--convert-string-for-export |
739 |
;; diary-date -- FIXME |
entry-rest))))) |
740 |
((string-match |
;; diary-date -- FIXME |
741 |
(concat nonmarker |
((string-match |
742 |
"%%(diary-date \\([^)]+\\))\\s-*\\(.*\\)") |
(concat nonmarker |
743 |
entry-main) |
"%%(diary-date \\([^)]+\\))\\s-*\\(.*\\)") |
744 |
(icalendar--dmsg "diary-date %s" entry-main) |
entry-main) |
745 |
(setq oops t)) |
(icalendar--dmsg "diary-date %s" entry-main) |
746 |
;; float events -- FIXME |
(error "`diary-date' is not supported yet")) |
747 |
((string-match |
;; float events -- FIXME |
748 |
(concat nonmarker |
((string-match |
749 |
"%%(diary-float \\([^)]+\\))\\s-*\\(.*\\)") |
(concat nonmarker |
750 |
entry-main) |
"%%(diary-float \\([^)]+\\))\\s-*\\(.*\\)") |
751 |
(icalendar--dmsg "diary-float %s" entry-main) |
entry-main) |
752 |
(setq oops t)) |
(icalendar--dmsg "diary-float %s" entry-main) |
753 |
;; block events |
(error "`diary-float' is not supported yet")) |
754 |
((string-match |
;; block events |
755 |
(concat nonmarker |
((string-match |
756 |
"%%(diary-block \\([^ /]+[ /]+[^ /]+[ /]+[^ ]+\\) +" |
(concat nonmarker |
757 |
"\\([^ /]+[ /]+[^ /]+[ /]+[^ ]+\\))\\s-*\\(.*\\)") |
"%%(diary-block \\([^ /]+[ /]+[^ /]+[ /]+[^ ]+\\) +" |
758 |
entry-main) |
"\\([^ /]+[ /]+[^ /]+[ /]+[^ ]+\\))\\s-*\\(.*\\)") |
759 |
(icalendar--dmsg "diary-block %s" entry-main) |
entry-main) |
760 |
(let* ((startstring (substring entry-main (match-beginning 1) |
(icalendar--dmsg "diary-block %s" entry-main) |
761 |
(match-end 1))) |
(let* ((startstring (substring entry-main (match-beginning 1) |
762 |
(endstring (substring entry-main (match-beginning 2) |
(match-end 1))) |
763 |
(match-end 2))) |
(endstring (substring entry-main (match-beginning 2) |
764 |
(summary (icalendar--convert-string-for-export |
(match-end 2))) |
765 |
(substring entry-main (match-beginning 3) |
(summary (icalendar--convert-string-for-export |
766 |
(match-end 3)))) |
(substring entry-main (match-beginning 3) |
767 |
(startisostring (icalendar--datestring-to-isodate |
(match-end 3)))) |
768 |
startstring)) |
(startisostring (icalendar--datestring-to-isodate |
769 |
(endisostring (icalendar--datestring-to-isodate |
startstring)) |
770 |
endstring 1))) |
(endisostring (icalendar--datestring-to-isodate |
771 |
(setq contents |
endstring 1))) |
772 |
(concat "\nDTSTART;VALUE=DATE:" startisostring |
(setq contents |
773 |
"\nDTEND;VALUE=DATE:" endisostring |
(concat "\nDTSTART;VALUE=DATE:" startisostring |
774 |
"\nSUMMARY:" summary |
"\nDTEND;VALUE=DATE:" endisostring |
775 |
)) |
"\nSUMMARY:" summary |
776 |
(unless (string= entry-rest "") |
)) |
777 |
(setq contents (concat contents "\nDESCRIPTION:" |
(unless (string= entry-rest "") |
778 |
(icalendar--convert-string-for-export |
(setq contents (concat contents "\nDESCRIPTION:" |
779 |
entry-rest)))))) |
(icalendar--convert-string-for-export |
780 |
;; other sexp diary entries -- FIXME |
entry-rest)))))) |
781 |
((string-match |
;; other sexp diary entries -- FIXME |
782 |
(concat nonmarker |
((string-match |
783 |
"%%(\\([^)]+\\))\\s-*\\(.*\\)") |
(concat nonmarker |
784 |
entry-main) |
"%%(\\([^)]+\\))\\s-*\\(.*\\)") |
785 |
(icalendar--dmsg "diary-sexp %s" entry-main) |
entry-main) |
786 |
(setq oops t)) |
(icalendar--dmsg "diary-sexp %s" entry-main) |
787 |
;; weekly by day |
(error "sexp-entries are not supported yet")) |
788 |
;; Monday 8:30 Team meeting |
;; weekly by day |
789 |
((and (string-match |
;; Monday 8:30 Team meeting |
790 |
(concat nonmarker |
((and (string-match |
791 |
"\\([a-z]+\\)\\s-+" |
(concat nonmarker |
792 |
"\\(0?\\([1-9][0-9]?:[0-9][0-9]\\)\\([ap]m\\)?" |
"\\([a-z]+\\)\\s-+" |
793 |
"\\(-0?" |
"\\(0?\\([1-9][0-9]?:[0-9][0-9]\\)\\([ap]m\\)?" |
794 |
"\\([1-9][0-9]?:[0-9][0-9]\\)\\([ap]m\\)?\\)?" |
"\\(-0?" |
795 |
"\\)?" |
"\\([1-9][0-9]?:[0-9][0-9]\\)\\([ap]m\\)?\\)?" |
796 |
"\\s-*\\(.*\\)$") |
"\\)?" |
797 |
entry-main) |
"\\s-*\\(.*\\)$") |
798 |
(icalendar--get-weekday-abbrev |
entry-main) |
799 |
(substring entry-main (match-beginning 1) (match-end 1)))) |
(icalendar--get-weekday-abbrev |
800 |
(icalendar--dmsg "weekly %s" entry-main) |
(substring entry-main (match-beginning 1) (match-end 1)))) |
801 |
(let* ((day (icalendar--get-weekday-abbrev |
(icalendar--dmsg "weekly %s" entry-main) |
802 |
(substring entry-main (match-beginning 1) |
(let* ((day (icalendar--get-weekday-abbrev |
803 |
(match-end 1)))) |
(substring entry-main (match-beginning 1) |
804 |
(starttimestring (icalendar--diarytime-to-isotime |
(match-end 1)))) |
805 |
(if (match-beginning 3) |
(starttimestring (icalendar--diarytime-to-isotime |
806 |
(substring entry-main |
(if (match-beginning 3) |
807 |
(match-beginning 3) |
(substring entry-main |
808 |
(match-end 3)) |
(match-beginning 3) |
809 |
nil) |
(match-end 3)) |
810 |
(if (match-beginning 4) |
nil) |
811 |
(substring entry-main |
(if (match-beginning 4) |
812 |
(match-beginning 4) |
(substring entry-main |
813 |
(match-end 4)) |
(match-beginning 4) |
814 |
nil))) |
(match-end 4)) |
815 |
(endtimestring (icalendar--diarytime-to-isotime |
nil))) |
816 |
(if (match-beginning 6) |
(endtimestring (icalendar--diarytime-to-isotime |
817 |
(substring entry-main |
(if (match-beginning 6) |
818 |
(match-beginning 6) |
(substring entry-main |
819 |
(match-end 6)) |
(match-beginning 6) |
820 |
nil) |
(match-end 6)) |
821 |
(if (match-beginning 7) |
nil) |
822 |
(substring entry-main |
(if (match-beginning 7) |
823 |
(match-beginning 7) |
(substring entry-main |
824 |
(match-end 7)) |
(match-beginning 7) |
825 |
nil))) |
(match-end 7)) |
826 |
(summary (icalendar--convert-string-for-export |
nil))) |
827 |
(substring entry-main (match-beginning 8) |
(summary (icalendar--convert-string-for-export |
828 |
(match-end 8))))) |
(substring entry-main (match-beginning 8) |
829 |
(when starttimestring |
(match-end 8))))) |
830 |
(unless endtimestring |
(when starttimestring |
831 |
(let ((time (read (icalendar--rris "^T0?" "" |
(unless endtimestring |
832 |
starttimestring)))) |
(let ((time (read (icalendar--rris "^T0?" "" |
833 |
(setq endtimestring (format "T%06d" (+ 10000 time)))))) |
starttimestring)))) |
834 |
(setq contents |
(setq endtimestring (format "T%06d" (+ 10000 time)))))) |
835 |
(concat "\nDTSTART" |
(setq contents |
836 |
(if starttimestring "" ";VALUE=DATE") |
(concat "\nDTSTART;" |
837 |
":19000101" ;; FIXME? Probability that this |
(if starttimestring |
838 |
;; is the right day is 1/7 |
"VALUE=DATE-TIME:" |
839 |
(or starttimestring "") |
"VALUE=DATE:") |
840 |
"\nDTEND" |
;; find the correct week day, |
841 |
(if endtimestring "" ";VALUE=DATE") |
;; 1st january 2000 was a saturday |
842 |
":19000101" ;; FIXME? |
(format |
843 |
(or endtimestring "") |
"200001%02d" |
844 |
"\nSUMMARY:" summary |
(+ (icalendar--get-weekday-number day) 2)) |
845 |
"\nRRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=" day |
(or starttimestring "") |
846 |
))) |
"\nDTEND;" |
847 |
(unless (string= entry-rest "") |
(if endtimestring |
848 |
(setq contents (concat contents "\nDESCRIPTION:" |
"VALUE=DATE-TIME:" |
849 |
(icalendar--convert-string-for-export |
"VALUE=DATE:") |
850 |
entry-rest))))) |
(format |
851 |
;; yearly by day |
"200001%02d" |
852 |
;; 1 May Tag der Arbeit |
;; end is non-inclusive! |
853 |
((string-match |
(+ (icalendar--get-weekday-number day) |
854 |
(concat nonmarker |
(if endtimestring 2 3))) |
855 |
(if european-calendar-style |
(or endtimestring "") |
856 |
"0?\\([1-9]+[0-9]?\\)\\s-+\\([a-z]+\\)\\s-+" |
"\nSUMMARY:" summary |
857 |
"\\([a-z]+\\)\\s-+0?\\([1-9]+[0-9]?\\)\\s-+") |
"\nRRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=" day |
858 |
"\\*?\\s-*" |
))) |
859 |
"\\(0?\\([1-9][0-9]?:[0-9][0-9]\\)\\([ap]m\\)?" |
(unless (string= entry-rest "") |
860 |
"\\(" |
(setq contents (concat contents "\nDESCRIPTION:" |
861 |
"-0?\\([1-9][0-9]?:[0-9][0-9]\\)\\([ap]m\\)?\\)?" |
(icalendar--convert-string-for-export |
862 |
"\\)?" |
entry-rest))))) |
863 |
"\\s-*\\([^0-9]+.*\\)$" ; must not match years |
;; yearly by day |
864 |
) |
;; 1 May Tag der Arbeit |
865 |
entry-main) |
((string-match |
866 |
(icalendar--dmsg "yearly %s" entry-main) |
(concat nonmarker |
867 |
(let* ((daypos (if european-calendar-style 1 2)) |
(if european-calendar-style |
868 |
(monpos (if european-calendar-style 2 1)) |
"0?\\([1-9]+[0-9]?\\)\\s-+\\([a-z]+\\)\\s-+" |
869 |
(day (read (substring entry-main (match-beginning daypos) |
"\\([a-z]+\\)\\s-+0?\\([1-9]+[0-9]?\\)\\s-+") |
870 |
(match-end daypos)))) |
"\\*?\\s-*" |
871 |
(month (icalendar--get-month-number |
"\\(0?\\([1-9][0-9]?:[0-9][0-9]\\)\\([ap]m\\)?" |
872 |
(substring entry-main (match-beginning monpos) |
"\\(" |
873 |
(match-end monpos)))) |
"-0?\\([1-9][0-9]?:[0-9][0-9]\\)\\([ap]m\\)?\\)?" |
874 |
(starttimestring (icalendar--diarytime-to-isotime |
"\\)?" |
875 |
(if (match-beginning 4) |
"\\s-*\\([^0-9]+.*\\)$" ; must not match years |
876 |
(substring entry-main |
) |
877 |
(match-beginning 4) |
entry-main) |
878 |
(match-end 4)) |
(icalendar--dmsg "yearly %s" entry-main) |
879 |
nil) |
(let* ((daypos (if european-calendar-style 1 2)) |
880 |
(if (match-beginning 5) |
(monpos (if european-calendar-style 2 1)) |
881 |
(substring entry-main |
(day (read (substring entry-main (match-beginning daypos) |
882 |
(match-beginning 5) |
(match-end daypos)))) |
883 |
(match-end 5)) |
(month (icalendar--get-month-number |
884 |
nil))) |
(substring entry-main (match-beginning monpos) |
885 |
(endtimestring (icalendar--diarytime-to-isotime |
(match-end monpos)))) |
886 |
(if (match-beginning 7) |
(starttimestring (icalendar--diarytime-to-isotime |
887 |
(substring entry-main |
(if (match-beginning 4) |
888 |
(match-beginning 7) |
(substring entry-main |
889 |
(match-end 7)) |
(match-beginning 4) |
890 |
nil) |
(match-end 4)) |
891 |
(if (match-beginning 8) |
nil) |
892 |
(substring entry-main |
(if (match-beginning 5) |
893 |
(match-beginning 8) |
(substring entry-main |
894 |
(match-end 8)) |
(match-beginning 5) |
895 |
nil))) |
(match-end 5)) |
896 |
(summary (icalendar--convert-string-for-export |
nil))) |
897 |
(substring entry-main (match-beginning 9) |
(endtimestring (icalendar--diarytime-to-isotime |
898 |
(match-end 9))))) |
(if (match-beginning 7) |
899 |
(when starttimestring |
(substring entry-main |
900 |
(unless endtimestring |
(match-beginning 7) |
901 |
(let ((time (read (icalendar--rris "^T0?" "" |
(match-end 7)) |
902 |
starttimestring)))) |
nil) |
903 |
(setq endtimestring (format "T%06d" (+ 10000 time)))))) |
(if (match-beginning 8) |
904 |
(setq contents |
(substring entry-main |
905 |
(concat "\nDTSTART" |
(match-beginning 8) |
906 |
(if starttimestring "" ";VALUE=DATE") |
(match-end 8)) |
907 |
(format ":1900%02d%02d" month day) |
nil))) |
908 |
(or starttimestring "") |
(summary (icalendar--convert-string-for-export |
909 |
"\nDTEND" |
(substring entry-main (match-beginning 9) |
910 |
(if endtimestring "" ";VALUE=DATE") |
(match-end 9))))) |
911 |
(format ":1900%02d%02d" month day) |
(when starttimestring |
912 |
(or endtimestring "") |
(unless endtimestring |
913 |
"\nSUMMARY:" summary |
(let ((time (read (icalendar--rris "^T0?" "" |
914 |
"\nRRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH=" |
starttimestring)))) |
915 |
(format "%2d" month) |
(setq endtimestring (format "T%06d" (+ 10000 time)))))) |
916 |
";BYMONTHDAY=" |
(setq contents |
917 |
(format "%2d" day) |
(concat "\nDTSTART;" |
918 |
))) |
(if starttimestring "VALUE=DATE-TIME:" |
919 |
(unless (string= entry-rest "") |
"VALUE=DATE:") |
920 |
(setq contents (concat contents "\nDESCRIPTION:" |
(format "1900%02d%02d" month day) |
921 |
(icalendar--convert-string-for-export |
(or starttimestring "") |
922 |
entry-rest))))) |
"\nDTEND;" |
923 |
;; "ordinary" events, start and end time given |
(if endtimestring "VALUE=DATE-TIME:" |
924 |
;; 1 Feb 2003 Hs Hochzeitsfeier, Dreieich |
"VALUE=DATE:") |
925 |
((string-match |
;; end is not included! shift by one day |
926 |
(concat nonmarker |
(icalendar--date-to-isodate |
927 |
"\\([^ /]+[ /]+[^ /]+[ /]+[^ ]+\\)\\s-+" |
(list month day 1900) (if endtimestring 0 1)) |
928 |
"\\(0?\\([1-9][0-9]?:[0-9][0-9]\\)\\([ap]m\\)?" |
(or endtimestring "") |
929 |
"\\(" |
"\nSUMMARY:" |
930 |
"-0?\\([1-9][0-9]?:[0-9][0-9]\\)\\([ap]m\\)?\\)?" |
summary |
931 |
"\\)?" |
"\nRRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH=" |
932 |
"\\s-*\\(.*\\)") |
(format "%2d" month) |
933 |
entry-main) |
";BYMONTHDAY=" |
934 |
(icalendar--dmsg "ordinary %s" entry-main) |
(format "%2d" day) |
935 |
(let* ((datestring (icalendar--datestring-to-isodate |
))) |
936 |
(substring entry-main (match-beginning 1) |
(unless (string= entry-rest "") |
937 |
(match-end 1)))) |
(setq contents (concat contents "\nDESCRIPTION:" |
938 |
(starttimestring (icalendar--diarytime-to-isotime |
(icalendar--convert-string-for-export |
939 |
(if (match-beginning 3) |
entry-rest))))) |
940 |
(substring entry-main |
;; "ordinary" events, start and end time given |
941 |
(match-beginning 3) |
;; 1 Feb 2003 Hs Hochzeitsfeier, Dreieich |
942 |
(match-end 3)) |
((string-match |
943 |
nil) |
(concat nonmarker |
944 |
(if (match-beginning 4) |
"\\([^ /]+[ /]+[^ /]+[ /]+[^ ]+\\)\\s-+" |
945 |
(substring entry-main |
"\\(0?\\([1-9][0-9]?:[0-9][0-9]\\)\\([ap]m\\)?" |
946 |
(match-beginning 4) |
"\\(" |
947 |
(match-end 4)) |
"-0?\\([1-9][0-9]?:[0-9][0-9]\\)\\([ap]m\\)?\\)?" |
948 |
nil))) |
"\\)?" |
949 |
(endtimestring (icalendar--diarytime-to-isotime |
"\\s-*\\(.*\\)") |
950 |
(if (match-beginning 6) |
entry-main) |
951 |
(substring entry-main |
(icalendar--dmsg "ordinary %s" entry-main) |
952 |
(match-beginning 6) |
(let* ((startdatestring (icalendar--datestring-to-isodate |
953 |
(match-end 6)) |
(substring entry-main |
954 |
nil) |
(match-beginning 1) |
955 |
(if (match-beginning 7) |
(match-end 1)))) |
956 |
(substring entry-main |
(starttimestring (icalendar--diarytime-to-isotime |
957 |
(match-beginning 7) |
(if (match-beginning 3) |
958 |
(match-end 7)) |
(substring entry-main |
959 |
nil))) |
(match-beginning 3) |
960 |
(summary (icalendar--convert-string-for-export |
(match-end 3)) |
961 |
(substring entry-main (match-beginning 8) |
nil) |
962 |
(match-end 8))))) |
(if (match-beginning 4) |
963 |
(when starttimestring |
(substring entry-main |
964 |
(unless endtimestring |
(match-beginning 4) |
965 |
(let ((time (read (icalendar--rris "^T0?" "" |
(match-end 4)) |
966 |
starttimestring)))) |
nil))) |
967 |
(setq endtimestring (format "T%06d" (+ 10000 time)))))) |
(endtimestring (icalendar--diarytime-to-isotime |
968 |
(setq contents (format |
(if (match-beginning 6) |
969 |
"\nDTSTART%s:%s%s\nDTEND%s:%s%s\nSUMMARY:%s" |
(substring entry-main |
970 |
(if starttimestring "" ";VALUE=DATE") |
(match-beginning 6) |
971 |
datestring |
(match-end 6)) |
972 |
(or starttimestring "") |
nil) |
973 |
(if endtimestring "" |
(if (match-beginning 7) |
974 |
";VALUE=DATE") |
(substring entry-main |
975 |
datestring |
(match-beginning 7) |
976 |
(or endtimestring "") |
(match-end 7)) |
977 |
summary)) |
nil))) |
978 |
(unless (string= entry-rest "") |
(summary (icalendar--convert-string-for-export |
979 |
(setq contents (concat contents "\nDESCRIPTION:" |
(substring entry-main (match-beginning 8) |
980 |
(icalendar--convert-string-for-export |
(match-end 8))))) |
981 |
entry-rest)))))) |
(unless startdatestring |
982 |
;; everything else |
(error "Could not parse date")) |
983 |
(t |
(when starttimestring |
984 |
;; Oops! what's that? |
(unless endtimestring |
985 |
(setq oops t))) |
(let ((time (read (icalendar--rris "^T0?" "" |
986 |
(if oops |
starttimestring)))) |
987 |
(message "Cannot export entry on line %d" |
(setq endtimestring (format "T%06d" (+ 10000 time)))))) |
988 |
(count-lines (point-min) (point))) |
(setq contents (concat |
989 |
(setq result (concat result header contents "\nEND:VEVENT")))) |
"\nDTSTART;" |
990 |
|
(if starttimestring "VALUE=DATE-TIME:" |
991 |
|
"VALUE=DATE:") |
992 |
|
startdatestring |
993 |
|
(or starttimestring "") |
994 |
|
"\nDTEND;" |
995 |
|
(if endtimestring "VALUE=DATE-TIME:" |
996 |
|
"VALUE=DATE:") |
997 |
|
(icalendar--datestring-to-isodate |
998 |
|
(substring entry-main |
999 |
|
(match-beginning 1) |
1000 |
|
(match-end 1)) |
1001 |
|
(if endtimestring 0 1)) |
1002 |
|
(or endtimestring "") |
1003 |
|
"\nSUMMARY:" |
1004 |
|
summary)) |
1005 |
|
;; could not parse the date |
1006 |
|
(unless (string= entry-rest "") |
1007 |
|
(setq contents (concat contents "\nDESCRIPTION:" |
1008 |
|
(icalendar--convert-string-for-export |
1009 |
|
entry-rest)))))) |
1010 |
|
;; everything else |
1011 |
|
(t |
1012 |
|
;; Oops! what's that? |
1013 |
|
(error "Could not parse entry"))) |
1014 |
|
(setq result (concat result header contents "\nEND:VEVENT"))) |
1015 |
|
;; handle errors |
1016 |
|
(error |
1017 |
|
(setq found-error t) |
1018 |
|
(save-current-buffer |
1019 |
|
(set-buffer (get-buffer-create " *icalendar-errors*")) |
1020 |
|
(insert (format "Error in line %d -- %s: `%s'\n" |
1021 |
|
(count-lines (point-min) (point)) |
1022 |
|
(cadr error-val) |
1023 |
|
entry-main)))))) |
1024 |
|
|
1025 |
;; we're done, insert everything into the file |
;; we're done, insert everything into the file |
1026 |
(let ((coding-system-for-write 'utf8)) |
(let ((coding-system-for-write 'utf8)) |
1027 |
(set-buffer (find-file ical-filename)) |
(set-buffer (find-file ical-filename)) |
1028 |
(goto-char (point-max)) |
(goto-char (point-max)) |
1029 |
(insert "BEGIN:VCALENDAR") |
(insert "BEGIN:VCALENDAR") |
1030 |
(insert "\nPRODID:-//Emacs//NONSGML icalendar.el//EN") |
(insert "\nPRODID:-//Emacs//NONSGML icalendar.el//EN") |
1031 |
(insert "\nVERSION:2.0") |
(insert "\nVERSION:2.0") |
1032 |
(insert result) |
(insert result) |
1033 |
(insert "\nEND:VCALENDAR\n"))))) |
(insert "\nEND:VCALENDAR\n"))) |
1034 |
|
found-error)) |
1035 |
|
|
1036 |
;; ====================================================================== |
;; ====================================================================== |
1037 |
;; Import -- convert icalendar to emacs-diary |
;; Import -- convert icalendar to emacs-diary |
1045 |
Argument DIARY-FILENAME input `diary-file'. |
Argument DIARY-FILENAME input `diary-file'. |
1046 |
Optional argument NON-MARKING determines whether events are created as |
Optional argument NON-MARKING determines whether events are created as |
1047 |
non-marking or not." |
non-marking or not." |
1048 |
(interactive "fImport iCalendar data from file: |
(interactive "fImport iCalendar data from file: |
1049 |
Finto diary file: |
Finto diary file: |
1050 |
p") |
p") |
1051 |
;; clean up the diary file |
;; clean up the diary file |
1106 |
"Current buffer does not contain icalendar contents!")))) |
"Current buffer does not contain icalendar contents!")))) |
1107 |
|
|
1108 |
(defalias 'icalendar-extract-ical-from-buffer 'icalendar-import-buffer) |
(defalias 'icalendar-extract-ical-from-buffer 'icalendar-import-buffer) |
1109 |
|
(make-obsolete 'icalendar-extract-ical-from-buffer 'icalendar-import-buffer) |
|
(make-obsolete 'icalendar-extract-ical-from-buffer 'icalendar-import-buffer |
|
|
"icalendar 0.07") |
|
1110 |
|
|
1111 |
;; ====================================================================== |
;; ====================================================================== |
1112 |
;; private area |
;; private area |
1226 |
(setq diary-string |
(setq diary-string |
1227 |
(format "%s %s%s%s" |
(format "%s %s%s%s" |
1228 |
(aref calendar-day-name-array |
(aref calendar-day-name-array |
1229 |
weekday) |
weekday) |
1230 |
start-t (if end-t "-" "") |
start-t (if end-t "-" "") |
1231 |
(or end-t ""))) |
(or end-t ""))) |
1232 |
;; FIXME!!!! |
;; FIXME!!!! |