Commit 81d56594 authored by Glenn Morris's avatar Glenn Morris
Browse files

From Ulf Jasper <ulf.jasper@web.de>:

(icalendar-version): Increase to 0.08.
(icalendar--split-value): Change name of work buffer.
(icalendar--get-weekday-abbrev): Return nil on error.
(icalendar--date-to-isodate): New function.
(icalendar-convert-diary-to-ical)
(icalendar-extract-ical-from-buffer): Use only two args for
make-obsolete (XEmacs compatibility).
(icalendar-export-file, icalendar-import-file): Blank at end of prompt.
(icalendar-export-region): Doc fix.  If error, return non-nil
and write errors to buffer ` *icalendar-errors*'.  Use correct weekday
for weekly recurring events.  Check whether date has been parsed for
ordinary events.  Make weekly events start in the year 2000.  DTEND is
non-inclusive, shift end date by one day if necessary (not for entries
that have date and time).  Rename local let variables: oops ->
found-error, datestring -> startdatestring.
parent 3467488e
...@@ -31,16 +31,7 @@ ...@@ -31,16 +31,7 @@
;;; History: ;;; History:
;; 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.
;; 0.06: Bugfixes regarding icalendar-import-format-*. ;; 0.06: Bugfixes regarding icalendar-import-format-*.
;; Fix in icalendar-convert-diary-to-ical -- thanks to Philipp ;; Fix in icalendar-convert-diary-to-ical -- thanks to Philipp
...@@ -99,7 +90,7 @@ ...@@ -99,7 +90,7 @@
;;; Code: ;;; Code:
(defconst icalendar-version 0.07 (defconst icalendar-version 0.08
"Version number of icalendar.el.") "Version number of icalendar.el.")
;; ====================================================================== ;; ======================================================================
...@@ -333,7 +324,7 @@ children." ...@@ -333,7 +324,7 @@ children."
param-name param-value) param-name param-value)
(when value-string (when value-string
(save-current-buffer (save-current-buffer
(set-buffer (get-buffer-create " *ical-temp*")) (set-buffer (get-buffer-create " *icalendar-work*"))
(set-buffer-modified-p nil) (set-buffer-modified-p nil)
(erase-buffer) (erase-buffer)
(insert value-string) (insert value-string)
...@@ -529,7 +520,17 @@ Note that this silently ignores seconds." ...@@ -529,7 +520,17 @@ Note that this silently ignores seconds."
(setq num (1+ num)))) (setq num (1+ num))))
calendar-day-name-array)) calendar-day-name-array))
;; Error: ;; Error:
"??")) nil))
(defun icalendar--date-to-isodate (date &optional day-shift)
"Convert DATE to iso-style date.
DATE must be a list of the form (month day year).
If DAY-SHIFT is non-nil, the result is shifted by DAY-SHIFT days."
(let ((mdy (calendar-gregorian-from-absolute
(+ (calendar-absolute-from-gregorian date)
(or day-shift 0)))))
(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)
"Convert diary-style DATESTRING to iso-style date. "Convert diary-style DATESTRING to iso-style date.
...@@ -632,15 +633,17 @@ Finto iCalendar file: ") ...@@ -632,15 +633,17 @@ Finto iCalendar file: ")
(icalendar-export-region (point-min) (point-max) ical-filename))) (icalendar-export-region (point-min) (point-max) ical-filename)))
(defalias 'icalendar-convert-diary-to-ical 'icalendar-export-file) (defalias 'icalendar-convert-diary-to-ical 'icalendar-export-file)
(make-obsolete 'icalendar-convert-diary-to-ical 'icalendar-export-file (make-obsolete 'icalendar-convert-diary-to-ical 'icalendar-export-file)
"icalendar 0.07")
;; User function ;; User function
(defun icalendar-export-region (min max ical-filename) (defun icalendar-export-region (min max ical-filename)
"Export region in diary file to iCalendar format. "Export region in diary file to iCalendar format.
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
converted to iCalendar format. The result is appended to the file converted to iCalendar format. The result is appended to the file
ICAL-FILENAME." ICAL-FILENAME.
Returns non-nil if an error occurred. In this case an error message is
written to the buffer ` *icalendar-errors*'."
(interactive "r (interactive "r
FExport diary data into iCalendar file: ") FExport diary data into iCalendar file: ")
(let ((result "") (let ((result "")
...@@ -649,9 +652,14 @@ FExport diary data into iCalendar file: ") ...@@ -649,9 +652,14 @@ FExport diary data into iCalendar file: ")
(entry-rest "") (entry-rest "")
(header "") (header "")
(contents) (contents)
(oops nil) (found-error nil)
(nonmarker (concat "^" (regexp-quote diary-nonmarking-symbol) (nonmarker (concat "^" (regexp-quote diary-nonmarking-symbol)
"?"))) "?")))
;; prepare buffer with error messages
(save-current-buffer
(set-buffer (get-buffer-create " *icalendar-errors*"))
(erase-buffer))
;; here we go
(save-excursion (save-excursion
(goto-char min) (goto-char min)
(while (re-search-forward (while (re-search-forward
...@@ -664,7 +672,8 @@ FExport diary data into iCalendar file: ") ...@@ -664,7 +672,8 @@ FExport diary data into iCalendar file: ")
(car (current-time)) (car (current-time))
(cadr (current-time)) (cadr (current-time))
(car (cddr (current-time))))) (car (cddr (current-time)))))
(setq oops nil) (condition-case error-val
(progn
(cond (cond
;; anniversaries ;; anniversaries
((string-match ((string-match
...@@ -734,14 +743,14 @@ FExport diary data into iCalendar file: ") ...@@ -734,14 +743,14 @@ FExport diary data into iCalendar file: ")
"%%(diary-date \\([^)]+\\))\\s-*\\(.*\\)") "%%(diary-date \\([^)]+\\))\\s-*\\(.*\\)")
entry-main) entry-main)
(icalendar--dmsg "diary-date %s" entry-main) (icalendar--dmsg "diary-date %s" entry-main)
(setq oops t)) (error "`diary-date' is not supported yet"))
;; float events -- FIXME ;; float events -- FIXME
((string-match ((string-match
(concat nonmarker (concat nonmarker
"%%(diary-float \\([^)]+\\))\\s-*\\(.*\\)") "%%(diary-float \\([^)]+\\))\\s-*\\(.*\\)")
entry-main) entry-main)
(icalendar--dmsg "diary-float %s" entry-main) (icalendar--dmsg "diary-float %s" entry-main)
(setq oops t)) (error "`diary-float' is not supported yet"))
;; block events ;; block events
((string-match ((string-match
(concat nonmarker (concat nonmarker
...@@ -775,7 +784,7 @@ FExport diary data into iCalendar file: ") ...@@ -775,7 +784,7 @@ FExport diary data into iCalendar file: ")
"%%(\\([^)]+\\))\\s-*\\(.*\\)") "%%(\\([^)]+\\))\\s-*\\(.*\\)")
entry-main) entry-main)
(icalendar--dmsg "diary-sexp %s" entry-main) (icalendar--dmsg "diary-sexp %s" entry-main)
(setq oops t)) (error "sexp-entries are not supported yet"))
;; weekly by day ;; weekly by day
;; Monday 8:30 Team meeting ;; Monday 8:30 Team meeting
((and (string-match ((and (string-match
...@@ -824,14 +833,25 @@ FExport diary data into iCalendar file: ") ...@@ -824,14 +833,25 @@ FExport diary data into iCalendar file: ")
starttimestring)))) starttimestring))))
(setq endtimestring (format "T%06d" (+ 10000 time)))))) (setq endtimestring (format "T%06d" (+ 10000 time))))))
(setq contents (setq contents
(concat "\nDTSTART" (concat "\nDTSTART;"
(if starttimestring "" ";VALUE=DATE") (if starttimestring
":19000101" ;; FIXME? Probability that this "VALUE=DATE-TIME:"
;; is the right day is 1/7 "VALUE=DATE:")
;; find the correct week day,
;; 1st january 2000 was a saturday
(format
"200001%02d"
(+ (icalendar--get-weekday-number day) 2))
(or starttimestring "") (or starttimestring "")
"\nDTEND" "\nDTEND;"
(if endtimestring "" ";VALUE=DATE") (if endtimestring
":19000101" ;; FIXME? "VALUE=DATE-TIME:"
"VALUE=DATE:")
(format
"200001%02d"
;; end is non-inclusive!
(+ (icalendar--get-weekday-number day)
(if endtimestring 2 3)))
(or endtimestring "") (or endtimestring "")
"\nSUMMARY:" summary "\nSUMMARY:" summary
"\nRRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=" day "\nRRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=" day
...@@ -894,15 +914,20 @@ FExport diary data into iCalendar file: ") ...@@ -894,15 +914,20 @@ FExport diary data into iCalendar file: ")
starttimestring)))) starttimestring))))
(setq endtimestring (format "T%06d" (+ 10000 time)))))) (setq endtimestring (format "T%06d" (+ 10000 time))))))
(setq contents (setq contents
(concat "\nDTSTART" (concat "\nDTSTART;"
(if starttimestring "" ";VALUE=DATE") (if starttimestring "VALUE=DATE-TIME:"
(format ":1900%02d%02d" month day) "VALUE=DATE:")
(format "1900%02d%02d" month day)
(or starttimestring "") (or starttimestring "")
"\nDTEND" "\nDTEND;"
(if endtimestring "" ";VALUE=DATE") (if endtimestring "VALUE=DATE-TIME:"
(format ":1900%02d%02d" month day) "VALUE=DATE:")
;; end is not included! shift by one day
(icalendar--date-to-isodate
(list month day 1900) (if endtimestring 0 1))
(or endtimestring "") (or endtimestring "")
"\nSUMMARY:" summary "\nSUMMARY:"
summary
"\nRRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH=" "\nRRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH="
(format "%2d" month) (format "%2d" month)
";BYMONTHDAY=" ";BYMONTHDAY="
...@@ -924,8 +949,9 @@ FExport diary data into iCalendar file: ") ...@@ -924,8 +949,9 @@ FExport diary data into iCalendar file: ")
"\\s-*\\(.*\\)") "\\s-*\\(.*\\)")
entry-main) entry-main)
(icalendar--dmsg "ordinary %s" entry-main) (icalendar--dmsg "ordinary %s" entry-main)
(let* ((datestring (icalendar--datestring-to-isodate (let* ((startdatestring (icalendar--datestring-to-isodate
(substring entry-main (match-beginning 1) (substring entry-main
(match-beginning 1)
(match-end 1)))) (match-end 1))))
(starttimestring (icalendar--diarytime-to-isotime (starttimestring (icalendar--diarytime-to-isotime
(if (match-beginning 3) (if (match-beginning 3)
...@@ -952,21 +978,31 @@ FExport diary data into iCalendar file: ") ...@@ -952,21 +978,31 @@ FExport diary data into iCalendar file: ")
(summary (icalendar--convert-string-for-export (summary (icalendar--convert-string-for-export
(substring entry-main (match-beginning 8) (substring entry-main (match-beginning 8)
(match-end 8))))) (match-end 8)))))
(unless startdatestring
(error "Could not parse date"))
(when starttimestring (when starttimestring
(unless endtimestring (unless endtimestring
(let ((time (read (icalendar--rris "^T0?" "" (let ((time (read (icalendar--rris "^T0?" ""
starttimestring)))) starttimestring))))
(setq endtimestring (format "T%06d" (+ 10000 time)))))) (setq endtimestring (format "T%06d" (+ 10000 time))))))
(setq contents (format (setq contents (concat
"\nDTSTART%s:%s%s\nDTEND%s:%s%s\nSUMMARY:%s" "\nDTSTART;"
(if starttimestring "" ";VALUE=DATE") (if starttimestring "VALUE=DATE-TIME:"
datestring "VALUE=DATE:")
startdatestring
(or starttimestring "") (or starttimestring "")
(if endtimestring "" "\nDTEND;"
";VALUE=DATE") (if endtimestring "VALUE=DATE-TIME:"
datestring "VALUE=DATE:")
(icalendar--datestring-to-isodate
(substring entry-main
(match-beginning 1)
(match-end 1))
(if endtimestring 0 1))
(or endtimestring "") (or endtimestring "")
"\nSUMMARY:"
summary)) summary))
;; could not parse the date
(unless (string= entry-rest "") (unless (string= entry-rest "")
(setq contents (concat contents "\nDESCRIPTION:" (setq contents (concat contents "\nDESCRIPTION:"
(icalendar--convert-string-for-export (icalendar--convert-string-for-export
...@@ -974,11 +1010,18 @@ FExport diary data into iCalendar file: ") ...@@ -974,11 +1010,18 @@ FExport diary data into iCalendar file: ")
;; everything else ;; everything else
(t (t
;; Oops! what's that? ;; Oops! what's that?
(setq oops t))) (error "Could not parse entry")))
(if oops (setq result (concat result header contents "\nEND:VEVENT")))
(message "Cannot export entry on line %d" ;; handle errors
(count-lines (point-min) (point))) (error
(setq result (concat result header contents "\nEND:VEVENT")))) (setq found-error t)
(save-current-buffer
(set-buffer (get-buffer-create " *icalendar-errors*"))
(insert (format "Error in line %d -- %s: `%s'\n"
(count-lines (point-min) (point))
(cadr error-val)
entry-main))))))
;; we're done, insert everything into the file ;; we're done, insert everything into the file
(let ((coding-system-for-write 'utf8)) (let ((coding-system-for-write 'utf8))
(set-buffer (find-file ical-filename)) (set-buffer (find-file ical-filename))
...@@ -987,7 +1030,8 @@ FExport diary data into iCalendar file: ") ...@@ -987,7 +1030,8 @@ FExport diary data into iCalendar file: ")
(insert "\nPRODID:-//Emacs//NONSGML icalendar.el//EN") (insert "\nPRODID:-//Emacs//NONSGML icalendar.el//EN")
(insert "\nVERSION:2.0") (insert "\nVERSION:2.0")
(insert result) (insert result)
(insert "\nEND:VCALENDAR\n"))))) (insert "\nEND:VCALENDAR\n")))
found-error))
;; ====================================================================== ;; ======================================================================
;; Import -- convert icalendar to emacs-diary ;; Import -- convert icalendar to emacs-diary
...@@ -1062,9 +1106,7 @@ reading, parsing, or converting iCalendar data!" ...@@ -1062,9 +1106,7 @@ reading, parsing, or converting iCalendar data!"
"Current buffer does not contain icalendar contents!")))) "Current buffer does not contain icalendar contents!"))))
(defalias 'icalendar-extract-ical-from-buffer 'icalendar-import-buffer) (defalias 'icalendar-extract-ical-from-buffer 'icalendar-import-buffer)
(make-obsolete 'icalendar-extract-ical-from-buffer 'icalendar-import-buffer)
(make-obsolete 'icalendar-extract-ical-from-buffer 'icalendar-import-buffer
"icalendar 0.07")
;; ====================================================================== ;; ======================================================================
;; private area ;; private area
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment