diff options
| author | Glenn Morris | 2005-10-24 07:27:39 +0000 |
|---|---|---|
| committer | Glenn Morris | 2005-10-24 07:27:39 +0000 |
| commit | d2afe62f2adf8211d61036ed4e8f77d1d7e2926d (patch) | |
| tree | c211096eb77de053bc98e874410a3366148e9bd4 | |
| parent | ad1eff1bc7c4bc8badfc7cbbbc6ed30925519887 (diff) | |
| download | emacs-d2afe62f2adf8211d61036ed4e8f77d1d7e2926d.tar.gz emacs-d2afe62f2adf8211d61036ed4e8f77d1d7e2926d.zip | |
From Ulf Jasper <ulf.jasper@web.de>:
(icalendar-version): Increase to 0.13. Now a string.
(icalendar-import-format): Handle CLASS, STATUS, URL. Rename
`subject' to `summary'.
(icalendar-import-format-summary): Rename from
`icalendar-import-format-subject'.
(icalendar-import-format-url, icalendar-import-format-status)
(icalendar-import-format-class): New variables.
(icalendar--rris): Take variable argument list.
(icalendar--datestring-to-isodate): Remove unnecessary
calendar-style check when converting dates with explicit month
names.
(icalendar-export-region): Change return type of conversion
subroutines. Bury current buffer unless error occurred.
(icalendar--convert-to-ical)
(icalendar--parse-summary-and-rest): New functions.
(icalendar--convert-ordinary-to-ical)
(icalendar--convert-weekly-to-ical)
(icalendar--convert-yearly-to-ical)
(icalendar--convert-block-to-ical)
(icalendar--convert-cyclic-to-ical)
(icalendar--convert-anniversary-to-ical): Change return type.
Strip trailing blanks from subject.
(icalendar--convert-sexp-to-ical): Change return type.
Strip trailing blanks from subject. Handle simple sexp
entries as generated by icalendar.el.
(icalendar--convert-float-to-ical)
(icalendar--convert-date-to-ical): Strip trailing blanks from
subject.
(icalendar-import-file): Doc fix.
(icalendar--format-ical-event): Handle CLASS, STATUS, URL.
Correct call to icalendar--rris.
(icalendar--convert-ical-to-diary): Doc fix. Rename `subject' to
`summary'.
(icalendar--add-diary-entry): Rename `subject' to `summary'.
| -rw-r--r-- | lisp/calendar/icalendar.el | 550 |
1 files changed, 349 insertions, 201 deletions
diff --git a/lisp/calendar/icalendar.el b/lisp/calendar/icalendar.el index 0e0400bd686..33f89474504 100644 --- a/lisp/calendar/icalendar.el +++ b/lisp/calendar/icalendar.el | |||
| @@ -97,7 +97,7 @@ | |||
| 97 | 97 | ||
| 98 | ;;; Code: | 98 | ;;; Code: |
| 99 | 99 | ||
| 100 | (defconst icalendar-version 0.12 | 100 | (defconst icalendar-version "0.13" |
| 101 | "Version number of icalendar.el.") | 101 | "Version number of icalendar.el.") |
| 102 | 102 | ||
| 103 | ;; ====================================================================== | 103 | ;; ====================================================================== |
| @@ -113,18 +113,21 @@ | |||
| 113 | "Format string for importing events from iCalendar into Emacs diary. | 113 | "Format string for importing events from iCalendar into Emacs diary. |
| 114 | This string defines how iCalendar events are inserted into diary | 114 | This string defines how iCalendar events are inserted into diary |
| 115 | file. Meaning of the specifiers: | 115 | file. Meaning of the specifiers: |
| 116 | %c Class, see `icalendar-import-format-class' | ||
| 116 | %d Description, see `icalendar-import-format-description' | 117 | %d Description, see `icalendar-import-format-description' |
| 117 | %l Location, see `icalendar-import-format-location' | 118 | %l Location, see `icalendar-import-format-location' |
| 118 | %o Organizer, see `icalendar-import-format-organizer' | 119 | %o Organizer, see `icalendar-import-format-organizer' |
| 119 | %s Subject, see `icalendar-import-format-subject'" | 120 | %s Summary, see `icalendar-import-format-summary' |
| 121 | %t Status, see `icalendar-import-format-status' | ||
| 122 | %u URL, see `icalendar-import-format-url'" | ||
| 120 | :type 'string | 123 | :type 'string |
| 121 | :group 'icalendar) | 124 | :group 'icalendar) |
| 122 | 125 | ||
| 123 | (defcustom icalendar-import-format-subject | 126 | (defcustom icalendar-import-format-summary |
| 124 | "%s" | 127 | "%s" |
| 125 | "Format string defining how the subject element is formatted. | 128 | "Format string defining how the summary element is formatted. |
| 126 | This applies only if the subject is not empty! `%s' is replaced | 129 | This applies only if the summary is not empty! `%s' is replaced |
| 127 | by the subject." | 130 | by the summary." |
| 128 | :type 'string | 131 | :type 'string |
| 129 | :group 'icalendar) | 132 | :group 'icalendar) |
| 130 | 133 | ||
| @@ -152,6 +155,30 @@ replaced by the organizer." | |||
| 152 | :type 'string | 155 | :type 'string |
| 153 | :group 'icalendar) | 156 | :group 'icalendar) |
| 154 | 157 | ||
| 158 | (defcustom icalendar-import-format-url | ||
| 159 | "\n URL: %s" | ||
| 160 | "Format string defining how the URL element is formatted. | ||
| 161 | This applies only if the URL is not empty! `%s' is replaced by | ||
| 162 | the URL." | ||
| 163 | :type 'string | ||
| 164 | :group 'icalendar) | ||
| 165 | |||
| 166 | (defcustom icalendar-import-format-status | ||
| 167 | "\n Status: %s" | ||
| 168 | "Format string defining how the status element is formatted. | ||
| 169 | This applies only if the status is not empty! `%s' is replaced by | ||
| 170 | the status." | ||
| 171 | :type 'string | ||
| 172 | :group 'icalendar) | ||
| 173 | |||
| 174 | (defcustom icalendar-import-format-class | ||
| 175 | "\n Class: %s" | ||
| 176 | "Format string defining how the class element is formatted. | ||
| 177 | This applies only if the class is not empty! `%s' is replaced by | ||
| 178 | the class." | ||
| 179 | :type 'string | ||
| 180 | :group 'icalendar) | ||
| 181 | |||
| 155 | (defvar icalendar-debug nil | 182 | (defvar icalendar-debug nil |
| 156 | "Enable icalendar debug messages.") | 183 | "Enable icalendar debug messages.") |
| 157 | 184 | ||
| @@ -195,15 +222,16 @@ buffer." | |||
| 195 | (replace-match "" nil nil))) | 222 | (replace-match "" nil nil))) |
| 196 | unfolded-buffer)) | 223 | unfolded-buffer)) |
| 197 | 224 | ||
| 198 | (defsubst icalendar--rris (re rp st) | 225 | (defsubst icalendar--rris (&rest args) |
| 199 | "Replace regexp RE with RP in string ST and return the new string. | 226 | "Replace regular expression in string. |
| 200 | This is here for compatibility with XEmacs." | 227 | Pass ARGS to `replace-regexp-in-string' (Emacs) or to |
| 228 | `replace-in-string' (XEmacs)." | ||
| 201 | ;; XEmacs: | 229 | ;; XEmacs: |
| 202 | (if (fboundp 'replace-in-string) | 230 | (if (fboundp 'replace-in-string) |
| 203 | (save-match-data ;; apparently XEmacs needs save-match-data | 231 | (save-match-data ;; apparently XEmacs needs save-match-data |
| 204 | (replace-in-string st re rp)) | 232 | (apply 'replace-in-string args)) |
| 205 | ;; Emacs: | 233 | ;; Emacs: |
| 206 | (replace-regexp-in-string re rp st))) | 234 | (apply 'replace-regexp-in-string args))) |
| 207 | 235 | ||
| 208 | (defun icalendar--read-element (invalue inparams) | 236 | (defun icalendar--read-element (invalue inparams) |
| 209 | "Recursively read the next iCalendar element in the current buffer. | 237 | "Recursively read the next iCalendar element in the current buffer. |
| @@ -609,12 +637,11 @@ takes care of european-style." | |||
| 609 | (setq month day) | 637 | (setq month day) |
| 610 | (setq day x)))) | 638 | (setq day x)))) |
| 611 | ( ;; date contains month names -- european-style | 639 | ( ;; date contains month names -- european-style |
| 612 | (and european-calendar-style | 640 | (string-match (concat "\\s-*" |
| 613 | (string-match (concat "\\s-*" | 641 | "0?\\([123]?[0-9]\\)[ \t/]\\s-*" |
| 614 | "0?\\([123]?[0-9]\\)[ \t/]\\s-*" | 642 | "\\([A-Za-z][^ ]+\\)[ \t/]\\s-*" |
| 615 | "\\([A-Za-z][^ ]+\\)[ \t/]\\s-*" | 643 | "\\([0-9]\\{4\\}\\)") |
| 616 | "\\([0-9]\\{4\\}\\)") | 644 | datestring) |
| 617 | datestring)) | ||
| 618 | (setq day (read (substring datestring (match-beginning 1) | 645 | (setq day (read (substring datestring (match-beginning 1) |
| 619 | (match-end 1)))) | 646 | (match-end 1)))) |
| 620 | (setq month (icalendar--get-month-number | 647 | (setq month (icalendar--get-month-number |
| @@ -623,12 +650,11 @@ takes care of european-style." | |||
| 623 | (setq year (read (substring datestring (match-beginning 3) | 650 | (setq year (read (substring datestring (match-beginning 3) |
| 624 | (match-end 3))))) | 651 | (match-end 3))))) |
| 625 | ( ;; date contains month names -- non-european-style | 652 | ( ;; date contains month names -- non-european-style |
| 626 | (and (not european-calendar-style) | 653 | (string-match (concat "\\s-*" |
| 627 | (string-match (concat "\\s-*" | 654 | "\\([A-Za-z][^ ]+\\)[ \t/]\\s-*" |
| 628 | "\\([A-Za-z][^ ]+\\)[ \t/]\\s-*" | 655 | "0?\\([123]?[0-9]\\),?[ \t/]\\s-*" |
| 629 | "0?\\([123]?[0-9]\\),?[ \t/]\\s-*" | 656 | "\\([0-9]\\{4\\}\\)") |
| 630 | "\\([0-9]\\{4\\}\\)") | 657 | datestring) |
| 631 | datestring)) | ||
| 632 | (setq day (read (substring datestring (match-beginning 2) | 658 | (setq day (read (substring datestring (match-beginning 2) |
| 633 | (match-end 2)))) | 659 | (match-end 2)))) |
| 634 | (setq month (icalendar--get-month-number | 660 | (setq month (icalendar--get-month-number |
| @@ -704,10 +730,12 @@ FExport diary data into iCalendar file: ") | |||
| 704 | (entry-main "") | 730 | (entry-main "") |
| 705 | (entry-rest "") | 731 | (entry-rest "") |
| 706 | (header "") | 732 | (header "") |
| 733 | (contents-n-summary) | ||
| 707 | (contents) | 734 | (contents) |
| 708 | (found-error nil) | 735 | (found-error nil) |
| 709 | (nonmarker (concat "^" (regexp-quote diary-nonmarking-symbol) | 736 | (nonmarker (concat "^" (regexp-quote diary-nonmarking-symbol) |
| 710 | "?"))) | 737 | "?")) |
| 738 | (other-elements nil)) | ||
| 711 | ;; prepare buffer with error messages | 739 | ;; prepare buffer with error messages |
| 712 | (save-current-buffer | 740 | (save-current-buffer |
| 713 | (set-buffer (get-buffer-create "*icalendar-errors*")) | 741 | (set-buffer (get-buffer-create "*icalendar-errors*")) |
| @@ -728,36 +756,33 @@ FExport diary data into iCalendar file: ") | |||
| 728 | (car (cddr (current-time))))) | 756 | (car (cddr (current-time))))) |
| 729 | (condition-case error-val | 757 | (condition-case error-val |
| 730 | (progn | 758 | (progn |
| 731 | (setq contents | 759 | (setq contents-n-summary |
| 732 | (or | 760 | (icalendar--convert-to-ical nonmarker entry-main)) |
| 733 | ;; anniversaries -- %%(diary-anniversary ...) | 761 | (setq other-elements (icalendar--parse-summary-and-rest |
| 734 | (icalendar--convert-anniversary-to-ical nonmarker | 762 | (concat entry-main entry-rest))) |
| 735 | entry-main) | 763 | (setq contents (concat (car contents-n-summary) |
| 736 | ;; cyclic events -- %%(diary-cyclic ...) | 764 | "\nSUMMARY:" (cadr contents-n-summary))) |
| 737 | (icalendar--convert-cyclic-to-ical nonmarker entry-main) | 765 | (let ((cla (cdr (assoc 'cla other-elements))) |
| 738 | ;; diary-date -- %%(diary-date ...) | 766 | (des (cdr (assoc 'des other-elements))) |
| 739 | (icalendar--convert-date-to-ical nonmarker entry-main) | 767 | (loc (cdr (assoc 'loc other-elements))) |
| 740 | ;; float events -- %%(diary-float ...) | 768 | (org (cdr (assoc 'org other-elements))) |
| 741 | (icalendar--convert-float-to-ical nonmarker entry-main) | 769 | (sta (cdr (assoc 'sta other-elements))) |
| 742 | ;; block events -- %%(diary-block ...) | 770 | (sum (cdr (assoc 'sum other-elements))) |
| 743 | (icalendar--convert-block-to-ical nonmarker entry-main) | 771 | (url (cdr (assoc 'url other-elements)))) |
| 744 | ;; other sexp diary entries | 772 | (if cla |
| 745 | (icalendar--convert-sexp-to-ical nonmarker entry-main) | 773 | (setq contents (concat contents "\nCLASS:" cla))) |
| 746 | ;; weekly by day -- Monday 8:30 Team meeting | 774 | (if des |
| 747 | (icalendar--convert-weekly-to-ical nonmarker entry-main) | 775 | (setq contents (concat contents "\nDESCRIPTION:" des))) |
| 748 | ;; yearly by day -- 1 May Tag der Arbeit | 776 | (if loc |
| 749 | (icalendar--convert-yearly-to-ical nonmarker entry-main) | 777 | (setq contents (concat contents "\nLOCATION:" loc))) |
| 750 | ;; "ordinary" events, start and end time given | 778 | (if org |
| 751 | ;; 1 Feb 2003 blah | 779 | (setq contents (concat contents "\nORGANIZER:" org))) |
| 752 | (icalendar--convert-ordinary-to-ical nonmarker entry-main) | 780 | (if sta |
| 753 | ;; everything else | 781 | (setq contents (concat contents "\nSTATUS:" sta))) |
| 754 | ;; Oops! what's that? | 782 | ;;(if sum |
| 755 | (error "Could not parse entry"))) | 783 | ;; (setq contents (concat contents "\nSUMMARY:" sum))) |
| 756 | (unless (string= entry-rest "") | 784 | (if url |
| 757 | (setq contents | 785 | (setq contents (concat contents "\nURL:" url)))) |
| 758 | (concat contents "\nDESCRIPTION:" | ||
| 759 | (icalendar--convert-string-for-export | ||
| 760 | entry-rest)))) | ||
| 761 | (setq result (concat result header contents "\nEND:VEVENT"))) | 786 | (setq result (concat result header contents "\nEND:VEVENT"))) |
| 762 | ;; handle errors | 787 | ;; handle errors |
| 763 | (error | 788 | (error |
| @@ -780,13 +805,127 @@ FExport diary data into iCalendar file: ") | |||
| 780 | (insert result) | 805 | (insert result) |
| 781 | (insert "\nEND:VCALENDAR\n") | 806 | (insert "\nEND:VCALENDAR\n") |
| 782 | ;; save the diary file | 807 | ;; save the diary file |
| 783 | (save-buffer)))) | 808 | (save-buffer) |
| 809 | (unless found-error | ||
| 810 | (bury-buffer))))) | ||
| 784 | found-error)) | 811 | found-error)) |
| 785 | 812 | ||
| 786 | ;; subroutines | 813 | (defun icalendar--convert-to-ical (nonmarker entry-main) |
| 814 | "Convert a diary entry to icalendar format. | ||
| 815 | NONMARKER is a regular expression matching the start of non-marking | ||
| 816 | entries. ENTRY-MAIN is the first line of the diary entry." | ||
| 817 | (or | ||
| 818 | ;; anniversaries -- %%(diary-anniversary ...) | ||
| 819 | (icalendar--convert-anniversary-to-ical nonmarker entry-main) | ||
| 820 | ;; cyclic events -- %%(diary-cyclic ...) | ||
| 821 | (icalendar--convert-cyclic-to-ical nonmarker entry-main) | ||
| 822 | ;; diary-date -- %%(diary-date ...) | ||
| 823 | (icalendar--convert-date-to-ical nonmarker entry-main) | ||
| 824 | ;; float events -- %%(diary-float ...) | ||
| 825 | (icalendar--convert-float-to-ical nonmarker entry-main) | ||
| 826 | ;; block events -- %%(diary-block ...) | ||
| 827 | (icalendar--convert-block-to-ical nonmarker entry-main) | ||
| 828 | ;; other sexp diary entries | ||
| 829 | (icalendar--convert-sexp-to-ical nonmarker entry-main) | ||
| 830 | ;; weekly by day -- Monday 8:30 Team meeting | ||
| 831 | (icalendar--convert-weekly-to-ical nonmarker entry-main) | ||
| 832 | ;; yearly by day -- 1 May Tag der Arbeit | ||
| 833 | (icalendar--convert-yearly-to-ical nonmarker entry-main) | ||
| 834 | ;; "ordinary" events, start and end time given | ||
| 835 | ;; 1 Feb 2003 blah | ||
| 836 | (icalendar--convert-ordinary-to-ical nonmarker entry-main) | ||
| 837 | ;; everything else | ||
| 838 | ;; Oops! what's that? | ||
| 839 | (error "Could not parse entry"))) | ||
| 840 | |||
| 841 | (defun icalendar--parse-summary-and-rest (summary-and-rest) | ||
| 842 | "Parse SUMMARY-AND-REST from a diary to fill iCalendar properties." | ||
| 843 | (save-match-data | ||
| 844 | (let* ((s icalendar-import-format) | ||
| 845 | (p-cla (or (string-match "%c" icalendar-import-format) -1)) | ||
| 846 | (p-des (or (string-match "%d" icalendar-import-format) -1)) | ||
| 847 | (p-loc (or (string-match "%l" icalendar-import-format) -1)) | ||
| 848 | (p-org (or (string-match "%o" icalendar-import-format) -1)) | ||
| 849 | (p-sum (or (string-match "%s" icalendar-import-format) -1)) | ||
| 850 | (p-sta (or (string-match "%t" icalendar-import-format) -1)) | ||
| 851 | (p-url (or (string-match "%u" icalendar-import-format) -1)) | ||
| 852 | (p-list (sort (list p-cla p-des p-loc p-org p-sta p-sum p-url) '<)) | ||
| 853 | pos-cla pos-des pos-loc pos-org pos-sta pos-sum pos-url) | ||
| 854 | (dotimes (i (length p-list)) | ||
| 855 | (cond ((and (>= p-cla 0) (= (nth i p-list) p-cla)) | ||
| 856 | (setq pos-cla (+ 2 (* 2 i)))) | ||
| 857 | ((and (>= p-des 0) (= (nth i p-list) p-des)) | ||
| 858 | (setq pos-des (+ 2 (* 2 i)))) | ||
| 859 | ((and (>= p-loc 0) (= (nth i p-list) p-loc)) | ||
| 860 | (setq pos-loc (+ 2 (* 2 i)))) | ||
| 861 | ((and (>= p-org 0) (= (nth i p-list) p-org)) | ||
| 862 | (setq pos-org (+ 2 (* 2 i)))) | ||
| 863 | ((and (>= p-sta 0) (= (nth i p-list) p-sta)) | ||
| 864 | (setq pos-sta (+ 2 (* 2 i)))) | ||
| 865 | ((and (>= p-sum 0) (= (nth i p-list) p-sum)) | ||
| 866 | (setq pos-sum (+ 2 (* 2 i)))) | ||
| 867 | ((and (>= p-url 0) (= (nth i p-list) p-url)) | ||
| 868 | (setq pos-url (+ 2 (* 2 i)))))) | ||
| 869 | (mapc (lambda (ij) | ||
| 870 | (setq s (icalendar--rris (car ij) (cadr ij) s t t))) | ||
| 871 | (list | ||
| 872 | ;; summary must be first! because of %s | ||
| 873 | (list "%s" | ||
| 874 | (concat "\\(" icalendar-import-format-summary "\\)?")) | ||
| 875 | (list "%c" | ||
| 876 | (concat "\\(" icalendar-import-format-class "\\)?")) | ||
| 877 | (list "%d" | ||
| 878 | (concat "\\(" icalendar-import-format-description "\\)?")) | ||
| 879 | (list "%l" | ||
| 880 | (concat "\\(" icalendar-import-format-location "\\)?")) | ||
| 881 | (list "%o" | ||
| 882 | (concat "\\(" icalendar-import-format-organizer "\\)?")) | ||
| 883 | (list "%t" | ||
| 884 | (concat "\\(" icalendar-import-format-status "\\)?")) | ||
| 885 | (list "%u" | ||
| 886 | (concat "\\(" icalendar-import-format-url "\\)?")))) | ||
| 887 | (setq s (concat (icalendar--rris "%s" "\\(.*\\)" s nil t) " ")) | ||
| 888 | (if (string-match s summary-and-rest) | ||
| 889 | (let (cla des loc org sta sum url) | ||
| 890 | (if (and pos-sum (match-beginning pos-sum)) | ||
| 891 | (setq sum (substring summary-and-rest | ||
| 892 | (match-beginning pos-sum) | ||
| 893 | (match-end pos-sum)))) | ||
| 894 | (if (and pos-cla (match-beginning pos-cla)) | ||
| 895 | (setq cla (substring summary-and-rest | ||
| 896 | (match-beginning pos-cla) | ||
| 897 | (match-end pos-cla)))) | ||
| 898 | (if (and pos-des (match-beginning pos-des)) | ||
| 899 | (setq des (substring summary-and-rest | ||
| 900 | (match-beginning pos-des) | ||
| 901 | (match-end pos-des)))) | ||
| 902 | (if (and pos-loc (match-beginning pos-loc)) | ||
| 903 | (setq loc (substring summary-and-rest | ||
| 904 | (match-beginning pos-loc) | ||
| 905 | (match-end pos-loc)))) | ||
| 906 | (if (and pos-org (match-beginning pos-org)) | ||
| 907 | (setq org (substring summary-and-rest | ||
| 908 | (match-beginning pos-org) | ||
| 909 | (match-end pos-org)))) | ||
| 910 | (if (and pos-sta (match-beginning pos-sta)) | ||
| 911 | (setq sta (substring summary-and-rest | ||
| 912 | (match-beginning pos-sta) | ||
| 913 | (match-end pos-sta)))) | ||
| 914 | (if (and pos-url (match-beginning pos-url)) | ||
| 915 | (setq url (substring summary-and-rest | ||
| 916 | (match-beginning pos-url) | ||
| 917 | (match-end pos-url)))) | ||
| 918 | (list (if cla (cons 'cla cla) nil) | ||
| 919 | (if des (cons 'des des) nil) | ||
| 920 | (if loc (cons 'loc loc) nil) | ||
| 921 | (if org (cons 'org org) nil) | ||
| 922 | (if sta (cons 'sta sta) nil) | ||
| 923 | ;;(if sum (cons 'sum sum) nil) | ||
| 924 | (if url (cons 'url url) nil))))))) | ||
| 925 | |||
| 926 | ;; subroutines for icalendar-export-region | ||
| 787 | (defun icalendar--convert-ordinary-to-ical (nonmarker entry-main) | 927 | (defun icalendar--convert-ordinary-to-ical (nonmarker entry-main) |
| 788 | "Convert \"ordinary\" diary entry to icalendar format. | 928 | "Convert \"ordinary\" diary entry to icalendar format. |
| 789 | |||
| 790 | NONMARKER is a regular expression matching the start of non-marking | 929 | NONMARKER is a regular expression matching the start of non-marking |
| 791 | entries. ENTRY-MAIN is the first line of the diary entry." | 930 | entries. ENTRY-MAIN is the first line of the diary entry." |
| 792 | (if (string-match (concat nonmarker | 931 | (if (string-match (concat nonmarker |
| @@ -795,7 +934,7 @@ entries. ENTRY-MAIN is the first line of the diary entry." | |||
| 795 | "\\(" | 934 | "\\(" |
| 796 | "-0?\\([1-9][0-9]?:[0-9][0-9]\\)\\([ap]m\\)?\\)?" | 935 | "-0?\\([1-9][0-9]?:[0-9][0-9]\\)\\([ap]m\\)?\\)?" |
| 797 | "\\)?" | 936 | "\\)?" |
| 798 | "\\s-*\\(.*\\)") | 937 | "\\s-*\\(.*?\\) ?$") |
| 799 | entry-main) | 938 | entry-main) |
| 800 | (let* ((datetime (substring entry-main (match-beginning 1) | 939 | (let* ((datetime (substring entry-main (match-beginning 1) |
| 801 | (match-end 1))) | 940 | (match-end 1))) |
| @@ -839,26 +978,24 @@ entries. ENTRY-MAIN is the first line of the diary entry." | |||
| 839 | starttimestring)))) | 978 | starttimestring)))) |
| 840 | (setq endtimestring (format "T%06d" | 979 | (setq endtimestring (format "T%06d" |
| 841 | (+ 10000 time)))))) | 980 | (+ 10000 time)))))) |
| 842 | (concat "\nDTSTART;" | 981 | (list (concat "\nDTSTART;" |
| 843 | (if starttimestring "VALUE=DATE-TIME:" | 982 | (if starttimestring "VALUE=DATE-TIME:" |
| 844 | "VALUE=DATE:") | 983 | "VALUE=DATE:") |
| 845 | startisostring | 984 | startisostring |
| 846 | (or starttimestring "") | 985 | (or starttimestring "") |
| 847 | "\nDTEND;" | 986 | "\nDTEND;" |
| 848 | (if endtimestring "VALUE=DATE-TIME:" | 987 | (if endtimestring "VALUE=DATE-TIME:" |
| 849 | "VALUE=DATE:") | 988 | "VALUE=DATE:") |
| 850 | (if starttimestring | 989 | (if starttimestring |
| 851 | startisostring | 990 | startisostring |
| 852 | endisostring) | 991 | endisostring) |
| 853 | (or endtimestring "") | 992 | (or endtimestring "")) |
| 854 | "\nSUMMARY:" | 993 | summary)) |
| 855 | summary)) | ||
| 856 | ;; no match | 994 | ;; no match |
| 857 | nil)) | 995 | nil)) |
| 858 | 996 | ||
| 859 | (defun icalendar--convert-weekly-to-ical (nonmarker entry-main) | 997 | (defun icalendar--convert-weekly-to-ical (nonmarker entry-main) |
| 860 | "Convert weekly diary entry to icalendar format. | 998 | "Convert weekly diary entry to icalendar format. |
| 861 | |||
| 862 | NONMARKER is a regular expression matching the start of non-marking | 999 | NONMARKER is a regular expression matching the start of non-marking |
| 863 | entries. ENTRY-MAIN is the first line of the diary entry." | 1000 | entries. ENTRY-MAIN is the first line of the diary entry." |
| 864 | (if (and (string-match (concat nonmarker | 1001 | (if (and (string-match (concat nonmarker |
| @@ -869,7 +1006,7 @@ entries. ENTRY-MAIN is the first line of the diary entry." | |||
| 869 | "\\([1-9][0-9]?:[0-9][0-9]\\)" | 1006 | "\\([1-9][0-9]?:[0-9][0-9]\\)" |
| 870 | "\\([ap]m\\)?\\)?" | 1007 | "\\([ap]m\\)?\\)?" |
| 871 | "\\)?" | 1008 | "\\)?" |
| 872 | "\\s-*\\(.*\\)$") | 1009 | "\\s-*\\(.*?\\) ?$") |
| 873 | entry-main) | 1010 | entry-main) |
| 874 | (icalendar--get-weekday-abbrev | 1011 | (icalendar--get-weekday-abbrev |
| 875 | (substring entry-main (match-beginning 1) | 1012 | (substring entry-main (match-beginning 1) |
| @@ -911,35 +1048,34 @@ entries. ENTRY-MAIN is the first line of the diary entry." | |||
| 911 | starttimestring)))) | 1048 | starttimestring)))) |
| 912 | (setq endtimestring (format "T%06d" | 1049 | (setq endtimestring (format "T%06d" |
| 913 | (+ 10000 time)))))) | 1050 | (+ 10000 time)))))) |
| 914 | (concat "\nDTSTART;" | 1051 | (list (concat "\nDTSTART;" |
| 915 | (if starttimestring | 1052 | (if starttimestring |
| 916 | "VALUE=DATE-TIME:" | 1053 | "VALUE=DATE-TIME:" |
| 917 | "VALUE=DATE:") | 1054 | "VALUE=DATE:") |
| 918 | ;; find the correct week day, | 1055 | ;; find the correct week day, |
| 919 | ;; 1st january 2000 was a saturday | 1056 | ;; 1st january 2000 was a saturday |
| 920 | (format | 1057 | (format |
| 921 | "200001%02d" | 1058 | "200001%02d" |
| 922 | (+ (icalendar--get-weekday-number day) 2)) | 1059 | (+ (icalendar--get-weekday-number day) 2)) |
| 923 | (or starttimestring "") | 1060 | (or starttimestring "") |
| 924 | "\nDTEND;" | 1061 | "\nDTEND;" |
| 925 | (if endtimestring | 1062 | (if endtimestring |
| 926 | "VALUE=DATE-TIME:" | 1063 | "VALUE=DATE-TIME:" |
| 927 | "VALUE=DATE:") | 1064 | "VALUE=DATE:") |
| 928 | (format | 1065 | (format |
| 929 | "200001%02d" | 1066 | "200001%02d" |
| 930 | ;; end is non-inclusive! | 1067 | ;; end is non-inclusive! |
| 931 | (+ (icalendar--get-weekday-number day) | 1068 | (+ (icalendar--get-weekday-number day) |
| 932 | (if endtimestring 2 3))) | 1069 | (if endtimestring 2 3))) |
| 933 | (or endtimestring "") | 1070 | (or endtimestring "") |
| 934 | "\nSUMMARY:" summary | 1071 | "\nRRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=" |
| 935 | "\nRRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=" | 1072 | day) |
| 936 | day)) | 1073 | summary)) |
| 937 | ;; no match | 1074 | ;; no match |
| 938 | nil)) | 1075 | nil)) |
| 939 | 1076 | ||
| 940 | (defun icalendar--convert-yearly-to-ical (nonmarker entry-main) | 1077 | (defun icalendar--convert-yearly-to-ical (nonmarker entry-main) |
| 941 | "Convert yearly diary entry to icalendar format. | 1078 | "Convert yearly diary entry to icalendar format. |
| 942 | |||
| 943 | NONMARKER is a regular expression matching the start of non-marking | 1079 | NONMARKER is a regular expression matching the start of non-marking |
| 944 | entries. ENTRY-MAIN is the first line of the diary entry." | 1080 | entries. ENTRY-MAIN is the first line of the diary entry." |
| 945 | (if (string-match (concat nonmarker | 1081 | (if (string-match (concat nonmarker |
| @@ -951,7 +1087,7 @@ entries. ENTRY-MAIN is the first line of the diary entry." | |||
| 951 | "\\(" | 1087 | "\\(" |
| 952 | "-0?\\([1-9][0-9]?:[0-9][0-9]\\)\\([ap]m\\)?\\)?" | 1088 | "-0?\\([1-9][0-9]?:[0-9][0-9]\\)\\([ap]m\\)?\\)?" |
| 953 | "\\)?" | 1089 | "\\)?" |
| 954 | "\\s-*\\([^0-9]+.*\\)$" ; must not match years | 1090 | "\\s-*\\([^0-9]+.*?\\) ?$" ; must not match years |
| 955 | ) | 1091 | ) |
| 956 | entry-main) | 1092 | entry-main) |
| 957 | (let* ((daypos (if european-calendar-style 1 2)) | 1093 | (let* ((daypos (if european-calendar-style 1 2)) |
| @@ -997,25 +1133,24 @@ entries. ENTRY-MAIN is the first line of the diary entry." | |||
| 997 | starttimestring)))) | 1133 | starttimestring)))) |
| 998 | (setq endtimestring (format "T%06d" | 1134 | (setq endtimestring (format "T%06d" |
| 999 | (+ 10000 time)))))) | 1135 | (+ 10000 time)))))) |
| 1000 | (concat "\nDTSTART;" | 1136 | (list (concat "\nDTSTART;" |
| 1001 | (if starttimestring "VALUE=DATE-TIME:" | 1137 | (if starttimestring "VALUE=DATE-TIME:" |
| 1002 | "VALUE=DATE:") | 1138 | "VALUE=DATE:") |
| 1003 | (format "1900%02d%02d" month day) | 1139 | (format "1900%02d%02d" month day) |
| 1004 | (or starttimestring "") | 1140 | (or starttimestring "") |
| 1005 | "\nDTEND;" | 1141 | "\nDTEND;" |
| 1006 | (if endtimestring "VALUE=DATE-TIME:" | 1142 | (if endtimestring "VALUE=DATE-TIME:" |
| 1007 | "VALUE=DATE:") | 1143 | "VALUE=DATE:") |
| 1008 | ;; end is not included! shift by one day | 1144 | ;; end is not included! shift by one day |
| 1009 | (icalendar--date-to-isodate | 1145 | (icalendar--date-to-isodate |
| 1010 | (list month day 1900) | 1146 | (list month day 1900) |
| 1011 | (if endtimestring 0 1)) | 1147 | (if endtimestring 0 1)) |
| 1012 | (or endtimestring "") | 1148 | (or endtimestring "") |
| 1013 | "\nSUMMARY:" | 1149 | "\nRRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH=" |
| 1014 | summary | 1150 | (format "%2d" month) |
| 1015 | "\nRRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH=" | 1151 | ";BYMONTHDAY=" |
| 1016 | (format "%2d" month) | 1152 | (format "%2d" day)) |
| 1017 | ";BYMONTHDAY=" | 1153 | summary)) |
| 1018 | (format "%2d" day))) | ||
| 1019 | ;; no match | 1154 | ;; no match |
| 1020 | nil)) | 1155 | nil)) |
| 1021 | 1156 | ||
| @@ -1026,18 +1161,28 @@ FIXME! | |||
| 1026 | 1161 | ||
| 1027 | NONMARKER is a regular expression matching the start of non-marking | 1162 | NONMARKER is a regular expression matching the start of non-marking |
| 1028 | entries. ENTRY-MAIN is the first line of the diary entry." | 1163 | entries. ENTRY-MAIN is the first line of the diary entry." |
| 1029 | (if (string-match (concat nonmarker | 1164 | (cond ((string-match (concat nonmarker |
| 1030 | "%%(\\([^)]+\\))\\s-*\\(.*\\)") | 1165 | "%%(and \\(([^)]+)\\))\\(\\s-*.*?\\) ?$") |
| 1031 | entry-main) | 1166 | entry-main) |
| 1032 | (progn | 1167 | ;; simple sexp entry as generated by icalendar.el: strip off the |
| 1033 | (icalendar--dmsg "diary-sexp %s" entry-main) | 1168 | ;; unnecessary (and) |
| 1034 | (error "Sexp-entries are not supported yet")) | 1169 | (icalendar--dmsg "diary-sexp from icalendar.el %s" entry-main) |
| 1035 | ;; no match | 1170 | (icalendar--convert-to-ical |
| 1036 | nil)) | 1171 | nonmarker |
| 1172 | (concat "%%" | ||
| 1173 | (substring entry-main (match-beginning 1) (match-end 1)) | ||
| 1174 | (substring entry-main (match-beginning 2) (match-end 2))))) | ||
| 1175 | ((string-match (concat nonmarker | ||
| 1176 | "%%([^)]+)\\s-*.*") | ||
| 1177 | entry-main) | ||
| 1178 | (icalendar--dmsg "diary-sexp %s" entry-main) | ||
| 1179 | (error "Sexp-entries are not supported yet")) | ||
| 1180 | (t | ||
| 1181 | ;; no match | ||
| 1182 | nil))) | ||
| 1037 | 1183 | ||
| 1038 | (defun icalendar--convert-block-to-ical (nonmarker entry-main) | 1184 | (defun icalendar--convert-block-to-ical (nonmarker entry-main) |
| 1039 | "Convert block diary entry to icalendar format. | 1185 | "Convert block diary entry to icalendar format. |
| 1040 | |||
| 1041 | NONMARKER is a regular expression matching the start of non-marking | 1186 | NONMARKER is a regular expression matching the start of non-marking |
| 1042 | entries. ENTRY-MAIN is the first line of the diary entry." | 1187 | entries. ENTRY-MAIN is the first line of the diary entry." |
| 1043 | (if (string-match (concat nonmarker | 1188 | (if (string-match (concat nonmarker |
| @@ -1047,7 +1192,7 @@ entries. ENTRY-MAIN is the first line of the diary entry." | |||
| 1047 | "\\(" | 1192 | "\\(" |
| 1048 | "-0?\\([1-9][0-9]?:[0-9][0-9]\\)\\([ap]m\\)?\\)?" | 1193 | "-0?\\([1-9][0-9]?:[0-9][0-9]\\)\\([ap]m\\)?\\)?" |
| 1049 | "\\)?" | 1194 | "\\)?" |
| 1050 | "\\s-*\\(.*\\)") | 1195 | "\\s-*\\(.*?\\) ?$") |
| 1051 | entry-main) | 1196 | entry-main) |
| 1052 | (let* ((startstring (substring entry-main | 1197 | (let* ((startstring (substring entry-main |
| 1053 | (match-beginning 1) | 1198 | (match-beginning 1) |
| @@ -1096,20 +1241,19 @@ entries. ENTRY-MAIN is the first line of the diary entry." | |||
| 1096 | (+ 10000 time)))))) | 1241 | (+ 10000 time)))))) |
| 1097 | (if starttimestring | 1242 | (if starttimestring |
| 1098 | ;; with time -> write rrule | 1243 | ;; with time -> write rrule |
| 1099 | (concat "\nDTSTART;VALUE=DATE-TIME:" | 1244 | (list (concat "\nDTSTART;VALUE=DATE-TIME:" |
| 1100 | startisostring | 1245 | startisostring |
| 1101 | starttimestring | 1246 | starttimestring |
| 1102 | "\nDTEND;VALUE=DATE-TIME:" | 1247 | "\nDTEND;VALUE=DATE-TIME:" |
| 1103 | startisostring | 1248 | startisostring |
| 1104 | endtimestring | 1249 | endtimestring |
| 1105 | "\nSUMMARY:" | 1250 | "\nRRULE:FREQ=DAILY;INTERVAL=1;UNTIL=" |
| 1106 | summary | 1251 | endisostring) |
| 1107 | "\nRRULE:FREQ=DAILY;INTERVAL=1;UNTIL=" | 1252 | summary) |
| 1108 | endisostring) | ||
| 1109 | ;; no time -> write long event | 1253 | ;; no time -> write long event |
| 1110 | (concat "\nDTSTART;VALUE=DATE:" startisostring | 1254 | (list (concat "\nDTSTART;VALUE=DATE:" startisostring |
| 1111 | "\nDTEND;VALUE=DATE:" endisostring+1 | 1255 | "\nDTEND;VALUE=DATE:" endisostring+1) |
| 1112 | "\nSUMMARY:" summary))) | 1256 | summary))) |
| 1113 | ;; no match | 1257 | ;; no match |
| 1114 | nil)) | 1258 | nil)) |
| 1115 | 1259 | ||
| @@ -1121,7 +1265,7 @@ FIXME! | |||
| 1121 | NONMARKER is a regular expression matching the start of non-marking | 1265 | NONMARKER is a regular expression matching the start of non-marking |
| 1122 | entries. ENTRY-MAIN is the first line of the diary entry." | 1266 | entries. ENTRY-MAIN is the first line of the diary entry." |
| 1123 | (if (string-match (concat nonmarker | 1267 | (if (string-match (concat nonmarker |
| 1124 | "%%(diary-float \\([^)]+\\))\\s-*\\(.*\\)") | 1268 | "%%(diary-float \\([^)]+\\))\\s-*\\(.*?\\) ?$") |
| 1125 | entry-main) | 1269 | entry-main) |
| 1126 | (progn | 1270 | (progn |
| 1127 | (icalendar--dmsg "diary-float %s" entry-main) | 1271 | (icalendar--dmsg "diary-float %s" entry-main) |
| @@ -1137,7 +1281,7 @@ FIXME! | |||
| 1137 | NONMARKER is a regular expression matching the start of non-marking | 1281 | NONMARKER is a regular expression matching the start of non-marking |
| 1138 | entries. ENTRY-MAIN is the first line of the diary entry." | 1282 | entries. ENTRY-MAIN is the first line of the diary entry." |
| 1139 | (if (string-match (concat nonmarker | 1283 | (if (string-match (concat nonmarker |
| 1140 | "%%(diary-date \\([^)]+\\))\\s-*\\(.*\\)") | 1284 | "%%(diary-date \\([^)]+\\))\\s-*\\(.*?\\) ?$") |
| 1141 | entry-main) | 1285 | entry-main) |
| 1142 | (progn | 1286 | (progn |
| 1143 | (icalendar--dmsg "diary-date %s" entry-main) | 1287 | (icalendar--dmsg "diary-date %s" entry-main) |
| @@ -1147,7 +1291,6 @@ entries. ENTRY-MAIN is the first line of the diary entry." | |||
| 1147 | 1291 | ||
| 1148 | (defun icalendar--convert-cyclic-to-ical (nonmarker entry-main) | 1292 | (defun icalendar--convert-cyclic-to-ical (nonmarker entry-main) |
| 1149 | "Convert `diary-cyclic' diary entry to icalendar format. | 1293 | "Convert `diary-cyclic' diary entry to icalendar format. |
| 1150 | |||
| 1151 | NONMARKER is a regular expression matching the start of non-marking | 1294 | NONMARKER is a regular expression matching the start of non-marking |
| 1152 | entries. ENTRY-MAIN is the first line of the diary entry." | 1295 | entries. ENTRY-MAIN is the first line of the diary entry." |
| 1153 | (if (string-match (concat nonmarker | 1296 | (if (string-match (concat nonmarker |
| @@ -1157,7 +1300,7 @@ entries. ENTRY-MAIN is the first line of the diary entry." | |||
| 1157 | "\\(" | 1300 | "\\(" |
| 1158 | "-0?\\([1-9][0-9]?:[0-9][0-9]\\)\\([ap]m\\)?\\)?" | 1301 | "-0?\\([1-9][0-9]?:[0-9][0-9]\\)\\([ap]m\\)?\\)?" |
| 1159 | "\\)?" | 1302 | "\\)?" |
| 1160 | "\\s-*\\(.*\\)") | 1303 | "\\s-*\\(.*?\\) ?$") |
| 1161 | entry-main) | 1304 | entry-main) |
| 1162 | (let* ((frequency (substring entry-main (match-beginning 1) | 1305 | (let* ((frequency (substring entry-main (match-beginning 1) |
| 1163 | (match-end 1))) | 1306 | (match-end 1))) |
| @@ -1202,27 +1345,26 @@ entries. ENTRY-MAIN is the first line of the diary entry." | |||
| 1202 | starttimestring)))) | 1345 | starttimestring)))) |
| 1203 | (setq endtimestring (format "T%06d" | 1346 | (setq endtimestring (format "T%06d" |
| 1204 | (+ 10000 time)))))) | 1347 | (+ 10000 time)))))) |
| 1205 | (concat "\nDTSTART;" | 1348 | (list (concat "\nDTSTART;" |
| 1206 | (if starttimestring "VALUE=DATE-TIME:" | 1349 | (if starttimestring "VALUE=DATE-TIME:" |
| 1207 | "VALUE=DATE:") | 1350 | "VALUE=DATE:") |
| 1208 | startisostring | 1351 | startisostring |
| 1209 | (or starttimestring "") | 1352 | (or starttimestring "") |
| 1210 | "\nDTEND;" | 1353 | "\nDTEND;" |
| 1211 | (if endtimestring "VALUE=DATE-TIME:" | 1354 | (if endtimestring "VALUE=DATE-TIME:" |
| 1212 | "VALUE=DATE:") | 1355 | "VALUE=DATE:") |
| 1213 | (if endtimestring endisostring endisostring+1) | 1356 | (if endtimestring endisostring endisostring+1) |
| 1214 | (or endtimestring "") | 1357 | (or endtimestring "") |
| 1215 | "\nSUMMARY:" summary | 1358 | "\nRRULE:FREQ=DAILY;INTERVAL=" frequency |
| 1216 | "\nRRULE:FREQ=DAILY;INTERVAL=" frequency | 1359 | ;; strange: korganizer does not expect |
| 1217 | ;; strange: korganizer does not expect | 1360 | ;; BYSOMETHING here... |
| 1218 | ;; BYSOMETHING here... | 1361 | ) |
| 1219 | )) | 1362 | summary)) |
| 1220 | ;; no match | 1363 | ;; no match |
| 1221 | nil)) | 1364 | nil)) |
| 1222 | 1365 | ||
| 1223 | (defun icalendar--convert-anniversary-to-ical (nonmarker entry-main) | 1366 | (defun icalendar--convert-anniversary-to-ical (nonmarker entry-main) |
| 1224 | "Convert `diary-anniversary' diary entry to icalendar format. | 1367 | "Convert `diary-anniversary' diary entry to icalendar format. |
| 1225 | |||
| 1226 | NONMARKER is a regular expression matching the start of non-marking | 1368 | NONMARKER is a regular expression matching the start of non-marking |
| 1227 | entries. ENTRY-MAIN is the first line of the diary entry." | 1369 | entries. ENTRY-MAIN is the first line of the diary entry." |
| 1228 | (if (string-match (concat nonmarker | 1370 | (if (string-match (concat nonmarker |
| @@ -1231,7 +1373,7 @@ entries. ENTRY-MAIN is the first line of the diary entry." | |||
| 1231 | "\\(" | 1373 | "\\(" |
| 1232 | "-0?\\([1-9][0-9]?:[0-9][0-9]\\)\\([ap]m\\)?\\)?" | 1374 | "-0?\\([1-9][0-9]?:[0-9][0-9]\\)\\([ap]m\\)?\\)?" |
| 1233 | "\\)?" | 1375 | "\\)?" |
| 1234 | "\\s-*\\(.*\\)") | 1376 | "\\s-*\\(.*?\\) ?$") |
| 1235 | entry-main) | 1377 | entry-main) |
| 1236 | (let* ((datetime (substring entry-main (match-beginning 1) | 1378 | (let* ((datetime (substring entry-main (match-beginning 1) |
| 1237 | (match-end 1))) | 1379 | (match-end 1))) |
| @@ -1272,26 +1414,26 @@ entries. ENTRY-MAIN is the first line of the diary entry." | |||
| 1272 | starttimestring)))) | 1414 | starttimestring)))) |
| 1273 | (setq endtimestring (format "T%06d" | 1415 | (setq endtimestring (format "T%06d" |
| 1274 | (+ 10000 time)))))) | 1416 | (+ 10000 time)))))) |
| 1275 | (concat "\nDTSTART;" | 1417 | (list (concat "\nDTSTART;" |
| 1276 | (if starttimestring "VALUE=DATE-TIME:" | 1418 | (if starttimestring "VALUE=DATE-TIME:" |
| 1277 | "VALUE=DATE:") | 1419 | "VALUE=DATE:") |
| 1278 | startisostring | 1420 | startisostring |
| 1279 | (or starttimestring "") | 1421 | (or starttimestring "") |
| 1280 | "\nDTEND;" | 1422 | "\nDTEND;" |
| 1281 | (if endtimestring "VALUE=DATE-TIME:" | 1423 | (if endtimestring "VALUE=DATE-TIME:" |
| 1282 | "VALUE=DATE:") | 1424 | "VALUE=DATE:") |
| 1283 | endisostring | 1425 | endisostring |
| 1284 | (or endtimestring "") | 1426 | (or endtimestring "") |
| 1285 | "\nSUMMARY:" summary | 1427 | "\nRRULE:FREQ=YEARLY;INTERVAL=1" |
| 1286 | "\nRRULE:FREQ=YEARLY;INTERVAL=1" | 1428 | ;; the following is redundant, |
| 1287 | ;; the following is redundant, | 1429 | ;; but korganizer seems to expect this... ;( |
| 1288 | ;; but korganizer seems to expect this... ;( | 1430 | ;; and evolution doesn't understand it... :( |
| 1289 | ;; and evolution doesn't understand it... :( | 1431 | ;; so... who is wrong?! |
| 1290 | ;; so... who is wrong?! | 1432 | ";BYMONTH=" |
| 1291 | ";BYMONTH=" | 1433 | (substring startisostring 4 6) |
| 1292 | (substring startisostring 4 6) | 1434 | ";BYMONTHDAY=" |
| 1293 | ";BYMONTHDAY=" | 1435 | (substring startisostring 6 8)) |
| 1294 | (substring startisostring 6 8))) | 1436 | summary)) |
| 1295 | ;; no match | 1437 | ;; no match |
| 1296 | nil)) | 1438 | nil)) |
| 1297 | 1439 | ||
| @@ -1302,7 +1444,7 @@ entries. ENTRY-MAIN is the first line of the diary entry." | |||
| 1302 | ;;;###autoload | 1444 | ;;;###autoload |
| 1303 | (defun icalendar-import-file (ical-filename diary-filename | 1445 | (defun icalendar-import-file (ical-filename diary-filename |
| 1304 | &optional non-marking) | 1446 | &optional non-marking) |
| 1305 | "Import a iCalendar file and append to a diary file. | 1447 | "Import an iCalendar file and append to a diary file. |
| 1306 | Argument ICAL-FILENAME output iCalendar file. | 1448 | Argument ICAL-FILENAME output iCalendar file. |
| 1307 | Argument DIARY-FILENAME input `diary-file'. | 1449 | Argument DIARY-FILENAME input `diary-file'. |
| 1308 | Optional argument NON-MARKING determines whether events are created as | 1450 | Optional argument NON-MARKING determines whether events are created as |
| @@ -1376,10 +1518,13 @@ buffer `*icalendar-errors*'." | |||
| 1376 | "Create a string representation of an iCalendar EVENT." | 1518 | "Create a string representation of an iCalendar EVENT." |
| 1377 | (let ((string icalendar-import-format) | 1519 | (let ((string icalendar-import-format) |
| 1378 | (conversion-list | 1520 | (conversion-list |
| 1379 | '(("%d" DESCRIPTION icalendar-import-format-description) | 1521 | '(("%c" CLASS icalendar-import-format-class) |
| 1380 | ("%s" SUMMARY icalendar-import-format-subject) | 1522 | ("%d" DESCRIPTION icalendar-import-format-description) |
| 1381 | ("%l" LOCATION icalendar-import-format-location) | 1523 | ("%l" LOCATION icalendar-import-format-location) |
| 1382 | ("%o" ORGANIZER icalendar-import-format-organizer)))) | 1524 | ("%o" ORGANIZER icalendar-import-format-organizer) |
| 1525 | ("%s" SUMMARY icalendar-import-format-summary) | ||
| 1526 | ("%t" STATUS icalendar-import-format-status) | ||
| 1527 | ("%u" URL icalendar-import-format-url)))) | ||
| 1383 | ;; convert the specifiers in the format string | 1528 | ;; convert the specifiers in the format string |
| 1384 | (mapcar (lambda (i) | 1529 | (mapcar (lambda (i) |
| 1385 | (let* ((spec (car i)) | 1530 | (let* ((spec (car i)) |
| @@ -1392,17 +1537,19 @@ buffer `*icalendar-errors*'." | |||
| 1392 | (icalendar--rris "%s" | 1537 | (icalendar--rris "%s" |
| 1393 | (icalendar--convert-string-for-import | 1538 | (icalendar--convert-string-for-import |
| 1394 | contents) | 1539 | contents) |
| 1395 | (symbol-value format)))) | 1540 | (symbol-value format) |
| 1541 | t t))) | ||
| 1396 | (setq string (icalendar--rris spec | 1542 | (setq string (icalendar--rris spec |
| 1397 | formatted-contents | 1543 | formatted-contents |
| 1398 | string)))) | 1544 | string |
| 1545 | t t)))) | ||
| 1399 | conversion-list) | 1546 | conversion-list) |
| 1400 | string)) | 1547 | string)) |
| 1401 | 1548 | ||
| 1402 | (defun icalendar--convert-ical-to-diary (ical-list diary-file | 1549 | (defun icalendar--convert-ical-to-diary (ical-list diary-file |
| 1403 | &optional do-not-ask | 1550 | &optional do-not-ask |
| 1404 | non-marking) | 1551 | non-marking) |
| 1405 | "Convert an iCalendar file to an Emacs diary file. | 1552 | "Convert Calendar data to an Emacs diary file. |
| 1406 | Import VEVENTS from the iCalendar object ICAL-LIST and saves them to a | 1553 | Import VEVENTS from the iCalendar object ICAL-LIST and saves them to a |
| 1407 | DIARY-FILE. If DO-NOT-ASK is nil the user is asked for each event | 1554 | DIARY-FILE. If DO-NOT-ASK is nil the user is asked for each event |
| 1408 | whether to actually import it. NON-MARKING determines whether diary | 1555 | whether to actually import it. NON-MARKING determines whether diary |
| @@ -1432,13 +1579,13 @@ written into the buffer `*icalendar-errors*'." | |||
| 1432 | end-d | 1579 | end-d |
| 1433 | end-1-d | 1580 | end-1-d |
| 1434 | end-t | 1581 | end-t |
| 1435 | (subject (icalendar--convert-string-for-import | 1582 | (summary (icalendar--convert-string-for-import |
| 1436 | (or (icalendar--get-event-property e 'SUMMARY) | 1583 | (or (icalendar--get-event-property e 'SUMMARY) |
| 1437 | "No Subject"))) | 1584 | "No summary"))) |
| 1438 | (rrule (icalendar--get-event-property e 'RRULE)) | 1585 | (rrule (icalendar--get-event-property e 'RRULE)) |
| 1439 | (rdate (icalendar--get-event-property e 'RDATE)) | 1586 | (rdate (icalendar--get-event-property e 'RDATE)) |
| 1440 | (duration (icalendar--get-event-property e 'DURATION))) | 1587 | (duration (icalendar--get-event-property e 'DURATION))) |
| 1441 | (icalendar--dmsg "%s: `%s'" start-d subject) | 1588 | (icalendar--dmsg "%s: `%s'" start-d summary) |
| 1442 | ;; check whether start-time is missing | 1589 | ;; check whether start-time is missing |
| 1443 | (if (and dtstart | 1590 | (if (and dtstart |
| 1444 | (string= | 1591 | (string= |
| @@ -1456,7 +1603,7 @@ written into the buffer `*icalendar-errors*'." | |||
| 1456 | t)))) | 1603 | t)))) |
| 1457 | (if (and dtend-dec (not (eq dtend-dec dtend-dec-d))) | 1604 | (if (and dtend-dec (not (eq dtend-dec dtend-dec-d))) |
| 1458 | (message "Inconsistent endtime and duration for %s" | 1605 | (message "Inconsistent endtime and duration for %s" |
| 1459 | subject)) | 1606 | summary)) |
| 1460 | (setq dtend-dec dtend-dec-d) | 1607 | (setq dtend-dec dtend-dec-d) |
| 1461 | (setq dtend-1-dec dtend-1-dec-d))) | 1608 | (setq dtend-1-dec dtend-1-dec-d))) |
| 1462 | (setq end-d (if dtend-dec | 1609 | (setq end-d (if dtend-dec |
| @@ -1517,9 +1664,9 @@ written into the buffer `*icalendar-errors*'." | |||
| 1517 | (setq diary-string | 1664 | (setq diary-string |
| 1518 | (concat diary-string " " | 1665 | (concat diary-string " " |
| 1519 | (icalendar--format-ical-event e))) | 1666 | (icalendar--format-ical-event e))) |
| 1520 | (if do-not-ask (setq subject nil)) | 1667 | (if do-not-ask (setq summary nil)) |
| 1521 | (icalendar--add-diary-entry diary-string diary-file | 1668 | (icalendar--add-diary-entry diary-string diary-file |
| 1522 | non-marking subject)) | 1669 | non-marking summary)) |
| 1523 | ;; event was not ok | 1670 | ;; event was not ok |
| 1524 | (setq found-error t) | 1671 | (setq found-error t) |
| 1525 | (setq error-string | 1672 | (setq error-string |
| @@ -1570,7 +1717,7 @@ END-T is the event's end time in diary format." | |||
| 1570 | (let ((until-1 0)) | 1717 | (let ((until-1 0)) |
| 1571 | (cond ((string-equal frequency "DAILY") | 1718 | (cond ((string-equal frequency "DAILY") |
| 1572 | (setq until (icalendar--add-decoded-times | 1719 | (setq until (icalendar--add-decoded-times |
| 1573 | dtstart-dec | 1720 | dtstart-dec |
| 1574 | (list 0 0 0 (* (read count) interval) 0 0))) | 1721 | (list 0 0 0 (* (read count) interval) 0 0))) |
| 1575 | (setq until-1 (icalendar--add-decoded-times | 1722 | (setq until-1 (icalendar--add-decoded-times |
| 1576 | dtstart-dec | 1723 | dtstart-dec |
| @@ -1767,23 +1914,24 @@ END-T is the event's end time in diary format." | |||
| 1767 | start-t)))) | 1914 | start-t)))) |
| 1768 | 1915 | ||
| 1769 | (defun icalendar--add-diary-entry (string diary-file non-marking | 1916 | (defun icalendar--add-diary-entry (string diary-file non-marking |
| 1770 | &optional subject) | 1917 | &optional summary) |
| 1771 | "Add STRING to the diary file DIARY-FILE. | 1918 | "Add STRING to the diary file DIARY-FILE. |
| 1772 | STRING must be a properly formatted valid diary entry. NON-MARKING | 1919 | STRING must be a properly formatted valid diary entry. NON-MARKING |
| 1773 | determines whether diary events are created as non-marking. If | 1920 | determines whether diary events are created as non-marking. If |
| 1774 | SUBJECT is not nil it must be a string that gives the subject of the | 1921 | SUMMARY is not nil it must be a string that gives the summary of the |
| 1775 | entry. In this case the user will be asked whether he wants to insert | 1922 | entry. In this case the user will be asked whether he wants to insert |
| 1776 | the entry." | 1923 | the entry." |
| 1777 | (when (or (not subject) | 1924 | (when (or (not summary) |
| 1778 | (y-or-n-p (format "Add appointment for `%s' to diary? " | 1925 | (y-or-n-p (format "Add appointment for `%s' to diary? " |
| 1779 | subject))) | 1926 | summary))) |
| 1780 | (when subject | 1927 | (when summary |
| 1781 | (setq non-marking | 1928 | (setq non-marking |
| 1782 | (y-or-n-p (format "Make appointment non-marking? ")))) | 1929 | (y-or-n-p (format "Make appointment non-marking? ")))) |
| 1783 | (save-window-excursion | 1930 | (save-window-excursion |
| 1784 | (unless diary-file | 1931 | (unless diary-file |
| 1785 | (setq diary-file | 1932 | (setq diary-file |
| 1786 | (read-file-name "Add appointment to this diary file: "))) | 1933 | (read-file-name "Add appointment to this diary file: "))) |
| 1934 | ;; Note: make-diary-entry will add a trailing blank char.... :( | ||
| 1787 | (make-diary-entry string non-marking diary-file)))) | 1935 | (make-diary-entry string non-marking diary-file)))) |
| 1788 | 1936 | ||
| 1789 | (provide 'icalendar) | 1937 | (provide 'icalendar) |