summaryrefslogtreecommitdiff
path: root/lisp/calendar/icalendar.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/calendar/icalendar.el')
-rw-r--r--lisp/calendar/icalendar.el88
1 files changed, 46 insertions, 42 deletions
diff --git a/lisp/calendar/icalendar.el b/lisp/calendar/icalendar.el
index 1d7de4a0c5d..eaee2e9d951 100644
--- a/lisp/calendar/icalendar.el
+++ b/lisp/calendar/icalendar.el
@@ -66,7 +66,7 @@
;; 0.02:
;; - Should work in XEmacs now. Thanks to Len Trigg for the XEmacs patches!
;; - Added exporting from Emacs diary to ical.
-;; - Some bugfixes, after testing with calendars from http://icalshare.com.
+;; - Some bugfixes, after testing with calendars from https://icalshare.com.
;; - Tested with Emacs 21.3.2 and XEmacs 21.4.12
;; 0.01: (2003-03-21)
@@ -105,10 +105,6 @@
;;; Code:
-(defconst icalendar-version "0.19"
- "Version number of icalendar.el.")
-(make-obsolete-variable 'icalendar-version nil "28.1")
-
;; ======================================================================
;; Customizables
;; ======================================================================
@@ -585,19 +581,19 @@ ALIST is a VTIMEZONE potentially containing historical records."
(list
(car
(sort components
- #'(lambda (a b)
- (let* ((get-recent (lambda (n)
- (car
- (sort
- (delq nil
- (mapcar (lambda (p)
- (and (memq (car p) '(DTSTART RDATE))
- (car (cddr p))))
- n))
- 'string-greaterp))))
- (a-recent (funcall get-recent (car (cddr a))))
- (b-recent (funcall get-recent (car (cddr b)))))
- (string-greaterp a-recent b-recent))))))))
+ (lambda (a b)
+ (let* ((get-recent (lambda (n)
+ (car
+ (sort
+ (delq nil
+ (mapcar (lambda (p)
+ (and (memq (car p) '(DTSTART RDATE))
+ (car (cddr p))))
+ n))
+ 'string-greaterp))))
+ (a-recent (funcall get-recent (car (cddr a))))
+ (b-recent (funcall get-recent (car (cddr b)))))
+ (string-greaterp a-recent b-recent))))))))
(defun icalendar--convert-all-timezones (icalendar)
"Convert all timezones in the ICALENDAR into an alist.
@@ -773,9 +769,6 @@ American format: \"month day year\"."
;; datetime == nil
nil))
-(define-obsolete-function-alias 'icalendar--datetime-to-noneuropean-date
- 'icalendar--datetime-to-american-date "icalendar 0.19")
-
(defun icalendar--datetime-to-european-date (datetime &optional separator)
"Convert the decoded DATETIME to European format.
Optional argument SEPARATOR gives the separator between month,
@@ -889,12 +882,14 @@ If DAY-SHIFT is non-nil, the result is shifted by DAY-SHIFT days."
(format "%04d%02d%02d" (nth 2 mdy) (nth 0 mdy) (nth 1 mdy))))
-(defun icalendar--datestring-to-isodate (datestring &optional day-shift)
+(defun icalendar--datestring-to-isodate (datestring &optional day-shift year-shift)
"Convert diary-style DATESTRING to iso-style date.
If DAY-SHIFT is non-nil, the result is shifted by DAY-SHIFT days
--- DAY-SHIFT must be either nil or an integer. This function
-tries to figure the date style from DATESTRING itself. If that
-is not possible it uses the current calendar date style."
+-- DAY-SHIFT must be either nil or an integer. If YEAR-SHIFT is
+non-nil, the result is shifted by YEAR-SHIFT years -- YEAR-SHIFT
+must be either nil or an integer. This function tries to figure
+the date style from DATESTRING itself. If that is not possible
+it uses the current calendar date style."
(let ((day -1) month year)
(save-match-data
(cond ( ;; iso-style numeric date
@@ -904,7 +899,7 @@ is not possible it uses the current calendar date style."
"0?\\([1-9][0-9]?\\)")
datestring)
(setq year (read (substring datestring (match-beginning 1)
- (match-end 1))))
+ (match-end 1))))
(setq month (read (substring datestring (match-beginning 2)
(match-end 2))))
(setq day (read (substring datestring (match-beginning 3)
@@ -967,6 +962,9 @@ is not possible it uses the current calendar date style."
(match-end 3)))))
(t
nil)))
+ (when year-shift
+ (setq year (+ year year-shift)))
+
(if (> day 0)
(let ((mdy (calendar-gregorian-from-absolute
(+ (calendar-absolute-from-gregorian (list month day
@@ -1000,15 +998,15 @@ TIMESTRING and has the same result as \"9:00\"."
(defun icalendar--convert-string-for-export (string)
"Escape comma and other critical characters in STRING."
- (replace-regexp-in-string "," "\\\\," string))
+ (string-replace "," "\\," string))
(defun icalendar--convert-string-for-import (string)
"Remove escape chars for comma, semicolon etc. from STRING."
- (replace-regexp-in-string
- "\\\\n" "\n " (replace-regexp-in-string
- "\\\\\"" "\"" (replace-regexp-in-string
- "\\\\;" ";" (replace-regexp-in-string
- "\\\\," "," string)))))
+ (string-replace
+ "\\n" "\n " (string-replace
+ "\\\"" "\"" (string-replace
+ "\\;" ";" (string-replace
+ "\\," "," string)))))
;; ======================================================================
;; Export -- convert emacs-diary to iCalendar
@@ -1275,7 +1273,7 @@ Returns an alist."
(concat "\\(" icalendar-import-format-uid "\\)??"))))
;; Need the \' regexp in order to detect multi-line items
(setq s (concat "\\`"
- (replace-regexp-in-string "%s" "\\(.*?\\)" s nil t)
+ (replace-regexp-in-string "%s" "\\([^z-a]*?\\)" s nil t)
"\\'"))
(if (string-match s summary-and-rest)
(let (cla des loc org sta url uid) ;; sum
@@ -1785,8 +1783,8 @@ entries. ENTRY-MAIN is the first line of the diary entry."
;;BUT remove today if `diary-float'
;;expression does not hold true for today:
(when
- (null (calendar-dlet* ((date (calendar-current-date))
- (entry entry-main))
+ (null (calendar-dlet ((date (calendar-current-date))
+ (entry entry-main))
(diary-float month dayname n)))
(concat
"\nEXDATE;VALUE=DATE:"
@@ -1916,9 +1914,9 @@ entries. ENTRY-MAIN is the first line of the diary entry."
(let* ((datetime (substring entry-main (match-beginning 1)
(match-end 1)))
(startisostring (icalendar--datestring-to-isodate
- datetime))
+ datetime nil 1))
(endisostring (icalendar--datestring-to-isodate
- datetime 1))
+ datetime 1 1))
(starttimestring (icalendar--diarytime-to-isotime
(if (match-beginning 3)
(substring entry-main
@@ -1987,9 +1985,7 @@ Argument ICAL-FILENAME output iCalendar file.
Argument DIARY-FILENAME input `diary-file'.
Optional argument NON-MARKING determines whether events are created as
non-marking or not."
- (interactive "fImport iCalendar data from file: \n\
-Finto diary file:
-P")
+ (interactive "fImport iCalendar data from file: \nFInto diary file: \nP")
;; clean up the diary file
(save-current-buffer
;; now load and convert from the ical file
@@ -2402,8 +2398,11 @@ END-T is the event's end time in diary format."
(if end-t "-" "")
(or end-t ""))))
(setq result (format
- "%%%%(and (diary-anniversary %s)) %s%s%s"
- dtstart-conv
+ "%%%%(diary-anniversary %s) %s%s%s"
+ (let* ((year (nth 5 dtstart-dec))
+ (dtstart-1y-dec (copy-sequence dtstart-dec)))
+ (setf (nth 5 dtstart-1y-dec) (1- year))
+ (icalendar--datetime-to-diary-date dtstart-1y-dec))
(or start-t "")
(if end-t "-" "") (or end-t "")))))
;; monthly
@@ -2552,6 +2551,11 @@ the entry."
(or (icalendar--get-event-property event 'URL) "")
(or (icalendar--get-event-property event 'CLASS) "")))
+;; Obsolete
+
+(defconst icalendar-version "0.19" "Version number of icalendar.el.")
+(make-obsolete-variable 'icalendar-version 'emacs-version "28.1")
+
(provide 'icalendar)
;;; icalendar.el ends here