Implement proper UIDs for iCalendar export.

This works now fine except for sexp entries which don't
get reusable UIDs, but fresh ones each time they are exported......
This commit is contained in:
Carsten Dominik 2008-05-19 08:22:51 +02:00
parent ea6cb1cdb9
commit 24fd4650de
4 changed files with 82 additions and 19 deletions

View File

@ -8,6 +8,33 @@
#+LINK_UP: index.html
#+LINK_HOME: http://orgmode.org
* Version 6.04
** Details
*** iCalendar now defines proper UIDs for entries
This is necessary for synchronization services. The UIDs are
created using the the org-id.el module. If you set the variable
: (setq org-icalendar-store-UID t)
then all created UIDs will be stored in the entry as an =:ID:=
property. You should definitely do this if you plan to use
synchronization.
Diary sexp entries do not yet receive proper persistent UIDs,
because they are transformed to iCalendar format by icalendar.el
which creates fresh UIDs each time, based on the current time.
A single entry can give rise to multiple iCalendar entries (as a
timestamp, a deadline, a scheduled item, and as a TODO
item). Therefore, Org adds prefixes "TS-", "DL-" "CS-", and "TD-"
to the UID during iCalendar export, depending on what triggered
the inclusion of the entry. In this way the UID remains unique,
but a synchronization program can still figure out from which
entry all the different instances originate.
* Version 6.03
:PROPERTIES:
:VISIBILITY: content

View File

@ -3984,8 +3984,10 @@ capture, you can use 3 values:
@example
local @r{use the tree in which the capture block is located}
global @r{make a global view, including all headings in the file}
"label" @r{call column view in the tree that has and @code{:ID:}}
@r{property with the value @i{label}}
"label" @r{call column view in the tree that has an @code{:ID:}}
@r{property with the value @i{label}. You can use}
@r{@kbd{M-x org-id-copy} to create a globally unique ID for}
@r{the current entry and copy it to the kill-ring.}
@end example
@item :hlines
When @code{t}, insert a hline after every line. When a number N, insert
@ -7426,6 +7428,16 @@ application. Org mode can export calendar information in the standard
iCalendar format. If you also want to have TODO entries included in the
export, configure the variable @code{org-icalendar-include-todo}.
The iCalendar standard requires each entry to have a globally unique
identifier (UID). Org creates these identifiers during export. If you set
the variable @code{org-icalendar-store-UID}, the UID will be stored in the
@code{:ID:} property of the entry and re-used next time you report this
entry. Since a single entry can give rise to multiple iCalendar entries (as
a timestamp, a deadline, a scheduled item, and as a TODO item), Org adds
prefixes to the UID, depending on what triggered the inclusion of the entry.
In this way the UID remains unique, but a synchronization program can still
figure out from which entry all the different instances originate.
@table @kbd
@kindex C-c C-e i
@item C-c C-e i

View File

@ -1,3 +1,9 @@
2008-05-19 Carsten Dominik <dominik@science.uva.nl>
* org-exp.el (org-icalendar-store-UID): New option.
(org-icalendar-force-UID): Option removed.
(org-print-icalendar-entries): IMplement UIDs.
2008-05-18 Carsten Dominik <dominik@science.uva.nl>
* org-mhe.el (org-mhe-follow-link): Fix bug in mhe searches.

View File

@ -634,9 +634,17 @@ The text will be inserted into the DESCRIPTION field."
:group 'org-export-icalendar
:type 'string)
(defcustom org-icalendar-force-UID nil
"Non-nil means, each exported entry must have a UID.
If not present, that UID will be created."
(defcustom org-icalendar-store-UID nil
"Non-nil means, store any created UIDs in properties.
The iCalendar standard requires that all entries have a unique identifyer.
Org will create these identifiers as needed. When this variable is non-nil,
the created UIDs will be stored in the ID property of the entry. Then the
next time this entry is exported, it will be exported with the same UID,
superceeding the previous form of it. This is essential for
synchronization services.
This variable is not turned on by default because we want to avoid creating
a property drawer in every entry if people are only playing with this feature,
or if they are only using it locally."
:group 'org-export-icalendar
:type 'boolean)
@ -3696,7 +3704,8 @@ When COMBINE is non nil, add the category to each line."
(format-time-string (cdr org-time-stamp-formats) (current-time))
"DTSTART"))
hd ts ts2 state status (inc t) pos b sexp rrule
scheduledp deadlinep tmp pri category entry location summary desc uid
scheduledp deadlinep prefix
tmp pri category entry location summary desc uid
(sexp-buffer (get-buffer-create "*ical-tmp*")))
(org-refresh-category-properties)
(save-excursion
@ -3724,10 +3733,11 @@ When COMBINE is non nil, add the category to each line."
t org-icalendar-include-body)
location (org-icalendar-cleanup-string
(org-entry-get nil "LOCATION"))
uid (if org-icalendar-force-UID
uid (if org-icalendar-store-UID
(org-id-get-create)
(org-id-get))
category (org-get-category))
(or (org-id-get) (org-id-new)))
category (org-get-category)
deadlinep nil scheduledp nil)
(if (looking-at re2)
(progn
(goto-char (match-end 0))
@ -3745,6 +3755,7 @@ When COMBINE is non nil, add the category to each line."
scheduledp (string-match org-scheduled-regexp tmp)
;; donep (org-entry-is-done-p)
))
(setq prefix (if deadlinep "DL-" (if scheduledp "SC-" "TS-")))
(if (or (string-match org-tr-regexp hd)
(string-match org-ts-regexp hd))
(setq hd (replace-match "" t t hd)))
@ -3762,19 +3773,21 @@ When COMBINE is non nil, add the category to each line."
(setq summary
(replace-match (if (match-end 3)
(match-string 3 summary)
(match-string 1 summary))
t t summary)))
(match-string 1 summary))
t t summary)))
(if deadlinep (setq summary (concat "DL: " summary)))
(if scheduledp (setq summary (concat "S: " summary)))
(if (string-match "\\`<%%" ts)
(with-current-buffer sexp-buffer
(insert (substring ts 1 -1) " " summary "\n"))
(princ (format "BEGIN:VEVENT
UID: %s
%s
%s%s
SUMMARY:%s%s%s
CATEGORIES:%s%s
CATEGORIES:%s
END:VEVENT\n"
(concat prefix uid)
(org-ical-ts-to-string ts "DTSTART")
(org-ical-ts-to-string ts2 "DTEND" inc)
rrule summary
@ -3782,8 +3795,7 @@ END:VEVENT\n"
(concat "\nDESCRIPTION: " desc) "")
(if (and location (string-match "\\S-" location))
(concat "\nLOCATION: " location) "")
category
(if uid (concat "\nUID: " uid) ""))))))
category)))))
(when (and org-icalendar-include-sexps
(condition-case nil (require 'icalendar) (error nil))
(fboundp 'icalendar-export-region))
@ -3800,8 +3812,9 @@ END:VEVENT\n"
(with-current-buffer sexp-buffer
(insert sexp "\n"))
(princ (org-diary-to-ical-string sexp-buffer)))))
(when org-icalendar-include-todo
(setq prefix "TODO-")
(goto-char (point-min))
(while (re-search-forward org-todo-line-regexp nil t)
(catch :skip
@ -3827,7 +3840,10 @@ END:VEVENT\n"
(and org-icalendar-include-body (org-get-entry)))
t org-icalendar-include-body)
location (org-icalendar-cleanup-string
(org-entry-get nil "LOCATION")))
(org-entry-get nil "LOCATION"))
uid (if org-icalendar-store-UID
(org-id-get-create)
(or (org-id-get) (orgg-id-new))))
(if (string-match org-bracket-link-regexp hd)
(setq hd (replace-match (if (match-end 3) (match-string 3 hd)
(match-string 1 hd))
@ -3841,20 +3857,23 @@ END:VEVENT\n"
(- org-lowest-priority org-highest-priority))))))
(princ (format "BEGIN:VTODO
UID: %s
%s
SUMMARY:%s%s%s
CATEGORIES:%s
CATEGORIES:%s%s
SEQUENCE:1
PRIORITY:%d
STATUS:%s
END:VTODO\n"
(concat prefix uid)
dts
(or summary hd)
(if (and location (string-match "\\S-" location))
(concat "\nLOCATION: " location) "")
(if (and desc (string-match "\\S-" desc))
(concat "\nDESCRIPTION: " desc) "")
category pri status)))))))))
category
pri status)))))))))
(defun org-icalendar-cleanup-string (s &optional is-body maxlength)
"Take out stuff and quote what needs to be quoted.
@ -4022,4 +4041,3 @@ The XOXO buffer is named *xoxo-<source buffer name>*"
;;; org-exp.el ends here