Browse Source

Implement better handling of deadlines in iCalendar Export.

Deadlines in TODO entries are now used as DUE dates.
Carsten Dominik 17 years ago
parent
commit
ec5b77ccd2
4 changed files with 116 additions and 17 deletions
  1. 33 1
      ORGWEBPAGE/Changes.org
  2. 13 8
      doc/org.texi
  3. 6 0
      lisp/ChangeLog
  4. 64 8
      lisp/org-exp.el

+ 33 - 1
ORGWEBPAGE/Changes.org

@@ -10,11 +10,43 @@
 #+LINK_UP: index.html
 #+LINK_UP: index.html
 #+LINK_HOME: http://orgmode.org
 #+LINK_HOME: http://orgmode.org
 
 
-* Version 6.05
+* Version 6.06
 :PROPERTIES:
 :PROPERTIES:
 :VISIBILITY: content
 :VISIBILITY: content
 :END:
 :END:
 
 
+** Overview
+** Details
+*** Changes in iCalendar export
+    Deadline and scheduling time stamps are now treated
+    differently in iCalendar export.  The default behavior is now
+    the following:
+
+    - a DEADLINE that appears in an entry that is a TODO item is
+      used as the item's DUE date.  Therefore, such a deadline
+      will no longer show up in the calendar.
+
+    - a DEADLINE that appears in an item that is *not* a TODO
+      item is exported as an EVENT and will show up in the
+      calendar.
+
+    - a SCHEDULED timestamp in a TODO item will be used as the
+      items DTSTART.  Therefore, such a timestamp will not show
+      up in the calendar.
+
+    - a SCHEDULED timestamp in an item that is not a TODO has no
+      effect on iCalendar export at all.  It will be ignored.
+
+    Of course this would not be Emacs if you could not configure
+    exactly what you want.  Take a look at the variables
+    =org-icalendar-use-deadlines= and
+    =org-icalendar-use-deadlines= if you want to go back to the
+    old behavior or even do something completely different.
+
+    Thanks to Karen Cooke for triggering this change.
+
+* Version 6.05
+
 If I were to name my releases, this one would be called "Adam".
 If I were to name my releases, this one would be called "Adam".
 Adam, you definitely owe me a beer :-).  And I owe you one, too -
 Adam, you definitely owe me a beer :-).  And I owe you one, too -
 thanks for all the great ideas.
 thanks for all the great ideas.

+ 13 - 8
doc/org.texi

@@ -7546,13 +7546,18 @@ Export only the visible part of the document.
 @section iCalendar export
 @section iCalendar export
 @cindex iCalendar export
 @cindex iCalendar export
 
 
-Some people like to use Org mode for keeping track of projects, but
+Some people like to use Org mode for keeping track of projects, but still
-still prefer a standard calendar application for anniversaries and
+prefer a standard calendar application for anniversaries and appointments.
-appointments.  In this case it can be useful to have deadlines and
+In this case it can be useful to have deadlines and other time-stamped items
-other time-stamped items in Org files show up in the calendar
+in Org files show up in the calendar application.  Org mode can export
-application.  Org mode can export calendar information in the standard
+calendar information in the standard iCalendar format.  If you also want to
-iCalendar format.  If you also want to have TODO entries included in the
+have TODO entries included in the export, configure the variable
-export, configure the variable @code{org-icalendar-include-todo}.
+@code{org-icalendar-include-todo}.  iCalendar export will export plain time
+stamps as VEVENT, and TODO items as VTODO.  It will also create events from
+deadlines that are in non-TODO items.  Deadlines and scheduling dates in TODO
+items will be used to set the start and due dates for the todo
+entry@footnote{See the variables @code{org-icalendar-use-deadline} and
+@code{org-icalendar-use-scheduled}.}.
 
 
 The iCalendar standard requires each entry to have a globally unique
 The iCalendar standard requires each entry to have a globally unique
 identifier (UID).  Org creates these identifiers during export.  If you set
 identifier (UID).  Org creates these identifiers during export.  If you set
@@ -7586,7 +7591,7 @@ the selected entries have them.  If not, the summary will be derived
 from the headline, and the description from the body (limited to
 from the headline, and the description from the body (limited to
 @code{org-icalendar-include-body} characters).
 @code{org-icalendar-include-body} characters).
 
 
-How this calendar is best read and updated, depends on the application
+How this calendar is best read and updated, that depends on the application
 you are using.  The FAQ covers this issue.
 you are using.  The FAQ covers this issue.
 
 
 @node Publishing, Miscellaneous, Exporting, Top
 @node Publishing, Miscellaneous, Exporting, Top

+ 6 - 0
lisp/ChangeLog

@@ -1,5 +1,11 @@
 2008-06-23  Carsten Dominik  <dominik@science.uva.nl>
 2008-06-23  Carsten Dominik  <dominik@science.uva.nl>
 
 
+	* org-exp.el (org-icalendar-use-deadline)
+	(org-icalendar-use-scheduled): New options.
+	(org-icalendar-include-todo): Default changed to t.
+	(org-print-icalendar-entries): Implement better utilization of
+	scheduling and deadline time stamps.
+
 	* org-clock.el (org-clocktable-shift): Also undertand yesterday,
 	* org-clock.el (org-clocktable-shift): Also undertand yesterday,
 	lastweek etc.
 	lastweek etc.
 	(org-clock-special-range): Also undertand yesterday, lastweek etc.
 	(org-clock-special-range): Also undertand yesterday, lastweek etc.

+ 64 - 8
lisp/org-exp.el

@@ -625,6 +625,46 @@ The file name should be absolute, the file will be overwritten without warning."
   :group 'org-export-icalendar
   :group 'org-export-icalendar
   :type 'file)
   :type 'file)
 
 
+(defcustom org-icalendar-combined-name "OrgMode"
+  "Calendar name for the combined iCalendar representing all agenda files."
+  :group 'org-export-icalendar
+  :type 'string)
+
+(defcustom org-icalendar-use-deadline '(event-if-not-todo todo-due)
+  "Contexts where iCalendar export should use a deadline time stamp.
+This is a list with several symbols in it.  Valid symbol are:
+
+event-if-todo       Deadlines in TODO entries become calendar events.
+event-if-not-todo   Deadlines in non-TODO entries become calendar events.
+todo-due            Use deadlines in TODO entries as due-dates"
+  :group 'org-export-icalendar
+  :type '(set :greedy t
+	      (const :tag "Deadlines in non-TODO entries become events"
+		     event-if-not-todo)
+	      (const :tag "Deadline in TODO entries become events"
+		     event-if-todo)
+	      (const :tag "Deadlines in TODO entries become due-dates"
+		     todo-due)))
+
+(defcustom org-icalendar-use-scheduled '(todo-start)
+  "Contexts where iCalendar export should use a scheduling time stamp.
+This is a list with several symbols in it.  Valid symbol are:
+
+event-if-todo       Scheduling time stamps in TODO entries become an event.
+event-if-not-todo   Scheduling time stamps in non-TODO entries become an event.
+todo-start          Scheduling time stamps in TODO entries become start date.
+                    Some calendar applications show TODO entries only after
+                    that date."
+  :group 'org-export-icalendar
+  :type '(set :greedy t
+	      (const :tag
+		     "SCHEDULED timestamps in non-TODO entries become events"
+		     event-if-not-todo)
+	      (const :tag "SCHEDULED timestamps in TODO entries become events"
+		     event-if-todo)
+	      (const :tag "SCHEDULED in TODO entries become start date"
+		     todo-start)))
+
 (defcustom org-icalendar-include-todo nil
 (defcustom org-icalendar-include-todo nil
   "Non-nil means, export to iCalendar files should also cover TODO items."
   "Non-nil means, export to iCalendar files should also cover TODO items."
   :group 'org-export-icalendar
   :group 'org-export-icalendar
@@ -650,11 +690,6 @@ The text will be inserted into the DESCRIPTION field."
 	  (const :tag "Everything" t)
 	  (const :tag "Everything" t)
 	  (integer :tag "Max characters")))
 	  (integer :tag "Max characters")))
 
 
-(defcustom org-icalendar-combined-name "OrgMode"
-  "Calendar name for the combined iCalendar representing all agenda files."
-  :group 'org-export-icalendar
-  :type 'string)
-
 (defcustom org-icalendar-store-UID nil
 (defcustom org-icalendar-store-UID nil
   "Non-nil means, store any created UIDs in properties.
   "Non-nil means, store any created UIDs in properties.
 The iCalendar standard requires that all entries have a unique identifyer.
 The iCalendar standard requires that all entries have a unique identifyer.
@@ -3933,7 +3968,7 @@ When COMBINE is non nil, add the category to each line."
 	      (format-time-string (cdr org-time-stamp-formats) (current-time))
 	      (format-time-string (cdr org-time-stamp-formats) (current-time))
 	      "DTSTART"))
 	      "DTSTART"))
 	hd ts ts2 state status (inc t) pos b sexp rrule
 	hd ts ts2 state status (inc t) pos b sexp rrule
-	scheduledp deadlinep prefix
+	scheduledp deadlinep todo prefix due start
 	tmp pri category entry location summary desc uid
 	tmp pri category entry location summary desc uid
 	(sexp-buffer (get-buffer-create "*ical-tmp*")))
 	(sexp-buffer (get-buffer-create "*ical-tmp*")))
     (org-refresh-category-properties)
     (org-refresh-category-properties)
@@ -3982,8 +4017,21 @@ When COMBINE is non nil, add the category to each line."
 			ts)
 			ts)
 		  deadlinep (string-match org-deadline-regexp tmp)
 		  deadlinep (string-match org-deadline-regexp tmp)
 		  scheduledp (string-match org-scheduled-regexp tmp)
 		  scheduledp (string-match org-scheduled-regexp tmp)
+		  todo (org-get-todo-state)
 		  ;; donep (org-entry-is-done-p)
 		  ;; donep (org-entry-is-done-p)
 		  ))
 		  ))
+	  (when (and
+		 deadlinep
+		 (if todo
+		     (not (memq 'event-if-todo org-icalendar-use-deadline))
+		   (not (memq 'event-if-not-todo org-icalendar-use-deadline))))
+	    (throw :skip t))
+	  (when (and
+		 scheduledp
+		 (if todo
+		     (not (memq 'event-if-todo org-icalendar-use-scheduled))
+		   (not (memq 'event-if-not-todo org-icalendar-use-scheduled))))
+	    (throw :skip t))
 	  (setq prefix (if deadlinep "DL-" (if scheduledp "SC-" "TS-")))
 	  (setq prefix (if deadlinep "DL-" (if scheduledp "SC-" "TS-")))
 	  (if (or (string-match org-tr-regexp hd)
 	  (if (or (string-match org-tr-regexp hd)
 		  (string-match org-ts-regexp hd))
 		  (string-match org-ts-regexp hd))
@@ -4071,9 +4119,16 @@ END:VEVENT\n"
 			  t org-icalendar-include-body)
 			  t org-icalendar-include-body)
 		    location (org-icalendar-cleanup-string
 		    location (org-icalendar-cleanup-string
 			      (org-entry-get nil "LOCATION"))
 			      (org-entry-get nil "LOCATION"))
+		    due (and (member 'todo-due org-icalendar-use-deadline)
+			     (org-entry-get nil "DEADLINE"))
+		    start (and (member 'todo-start org-icalendar-use-scheduled)
+			     (org-entry-get nil "SCHEDULED"))
 		    uid (if org-icalendar-store-UID
 		    uid (if org-icalendar-store-UID
 			    (org-id-get-create)
 			    (org-id-get-create)
 			  (or (org-id-get) (org-id-new))))
 			  (or (org-id-get) (org-id-new))))
+	      (and due (setq due (org-ical-ts-to-string due "DUE")))
+	      (and start (setq start (org-ical-ts-to-string start "DTSTART")))
+
 	      (if (string-match org-bracket-link-regexp hd)
 	      (if (string-match org-bracket-link-regexp hd)
 		  (setq hd (replace-match (if (match-end 3) (match-string 3 hd)
 		  (setq hd (replace-match (if (match-end 3) (match-string 3 hd)
 					    (match-string 1 hd))
 					    (match-string 1 hd))
@@ -4089,19 +4144,20 @@ END:VEVENT\n"
 	      (princ (format "BEGIN:VTODO
 	      (princ (format "BEGIN:VTODO
 UID: %s
 UID: %s
 %s
 %s
-SUMMARY:%s%s%s
+SUMMARY:%s%s%s%s
 CATEGORIES:%s
 CATEGORIES:%s
 SEQUENCE:1
 SEQUENCE:1
 PRIORITY:%d
 PRIORITY:%d
 STATUS:%s
 STATUS:%s
 END:VTODO\n"
 END:VTODO\n"
 			     (concat prefix uid)
 			     (concat prefix uid)
-			     dts
+			     (or start dts)
 			     (or summary hd)
 			     (or summary hd)
 			     (if (and location (string-match "\\S-" location))
 			     (if (and location (string-match "\\S-" location))
 				 (concat "\nLOCATION: " location) "")
 				 (concat "\nLOCATION: " location) "")
 			     (if (and desc (string-match "\\S-" desc))
 			     (if (and desc (string-match "\\S-" desc))
 				 (concat "\nDESCRIPTION: " desc) "")
 				 (concat "\nDESCRIPTION: " desc) "")
+			     (if due (concat "\n" due) "")
 			     category
 			     category
 			     pri status)))))))))
 			     pri status)))))))))