emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: Niels Giesen <niels.giesen@gmail.com>
To: Bastien <bastien.guerry@wikimedia.fr>
Cc: emacs-orgmode@gnu.org
Subject: Re: More entries able to export to icalendar format
Date: Sat, 12 Feb 2011 18:30:13 +0100	[thread overview]
Message-ID: <87ipwpnot6.fsf@gmail.com> (raw)
In-Reply-To: <87mxm24aru.fsf@gnu.org> (Bastien's message of "Fri, 11 Feb 2011 20:43:49 +0100")

Hi Bastien,

> Both attaching and quoting patches should be fine.

Alright, I will quote the patches, so that readers of the list can also
easily access them. The details are described in the patches. By the
way, I have made some changes since I last sent my redefinitions of
these functions, as a few things did not work correctly. They do now.

First, a tiny change to org-icalendar, adding the uid as a text-property:
   
#+begin_src diff
From 4ed18aa7aa13ac02784ad536fff5d5719f2942b9 Mon Sep 17 00:00:00 2001
From: Niels Giesen <niels.giesen@gmail.com>
Date: Fri, 11 Feb 2011 13:59:12 +0100
Subject: [PATCH] Add uid text property to diary entries

* lisp/org-icalendar.el (org-print-icalendar-entries): Add 'uid text
  property based on the ID property of the org entry to the first
  character of the diary entry.

This text property can be used by `icalendar--create-uid', instead
of creating a uid by itself.

NOTE: `icalendar--create-uid' should be patched to pick up this uid.

TINYCHANGE
---
 lisp/org-icalendar.el |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/lisp/org-icalendar.el b/lisp/org-icalendar.el
index 3583e6a..093ff93 100644
--- a/lisp/org-icalendar.el
+++ b/lisp/org-icalendar.el
@@ -412,7 +412,10 @@ When COMBINE is non nil, add the category to each line."
 	  (if scheduledp (setq summary (concat "S: " summary)))
 	  (if (string-match "\\`<%%" ts)
 	      (with-current-buffer sexp-buffer
-		(insert (substring ts 1 -1) " " summary "\n"))
+		(let ((entry (substring ts 1 -1)))
+		  (put-text-property 0 1 'uid
+				     (concat " " prefix uid) entry)
+		  (insert entry " " summary "\n")))
 	    (princ (format "BEGIN:VEVENT
 UID: %s
 %s
-- 
1.7.1

#+end_src   

Then, in icalendar.el, pick up that uid:

#+begin_src diff
From 9958d2783887dde8bcd6d50a28ecbafca31eb7c1 Mon Sep 17 00:00:00 2001
From: Niels Giesen <niels.giesen@gmail.com>
Date: Fri, 11 Feb 2011 14:23:33 +0100
Subject: [PATCH 1/2] Pick up uid that may have been set by another application, e.g.
 org-mode.

* lisp/calendar/icalendar.el (icalendar--create-uid): get a value for
uid from 'uid text-property from first character of the entry, if
existing, otherwise create the uid as before.
---
 lisp/calendar/icalendar.el |    7 +++++--
 1 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/lisp/calendar/icalendar.el b/lisp/calendar/icalendar.el
index ca88548..b1d2bba 100644
--- a/lisp/calendar/icalendar.el
+++ b/lisp/calendar/icalendar.el
@@ -925,7 +925,10 @@ ENTRY-FULL is the full diary entry string.  CONTENTS is the
 current iCalendar object, as a string.  Increase
 `icalendar--uid-count'.  Returns the UID string."
   (let ((uid icalendar-uid-format))
-    
+    (if
+	;;Allow other apps (such as org-mode) to create its own uid
+	(get-text-property 0 'uid entry-full)
+	(setq uid (get-text-property 0 'uid entry-full))
     (setq uid (replace-regexp-in-string
 	       "%c"
 	       (format "%d" icalendar--uid-count)
@@ -945,7 +948,7 @@ current iCalendar object, as a string.  Increase
     (let ((dtstart (if (string-match "^DTSTART[^:]*:\\([0-9]*\\)" contents)
                        (substring contents (match-beginning 1) (match-end 1))
                    "DTSTART")))
-          (setq uid (replace-regexp-in-string "%s" dtstart uid t t)))
+          (setq uid (replace-regexp-in-string "%s" dtstart uid t t))))
 
     ;; Return the UID string
     uid))
-- 
1.7.1

#+end_src

And finally, the largest change, as it implements exports of `diary-float':

#+begin_src diff
From a2db198dae5210fa3d2a4353667f2c75d28cd16a Mon Sep 17 00:00:00 2001
From: Niels Giesen <niels.giesen@gmail.com>
Date: Sat, 12 Feb 2011 18:12:16 +0100
Subject: [PATCH 2/2] Export `diary-float' entries.

* lisp/calendar/icalendar.el (require 'diary-lib): diary-lib required
by code now used in `icalendar--convert-float-to-ical'.
* lisp/calendar/icalendar.el (icalendar--convert-float-to-ical):
Implement the body of this function instead of backing out.

This change implements the export of `diary-float' entries save for
those with the optional day entry.

The current date is used as the start date (but excluded if the
current date does not match the `diary-float' arguments).

The use of the current date as the start date is quite arbitrary, in
the same way as the start dates for weekly and yearly events are
arbitrary. It might be wise to bring the behaviour for these different
entries more in line with each other, perhaps leaving the user a
choice via customization.
---
 lisp/calendar/icalendar.el |   74 ++++++++++++++++++++++++++++++++++++-------
 1 files changed, 62 insertions(+), 12 deletions(-)

diff --git a/lisp/calendar/icalendar.el b/lisp/calendar/icalendar.el
index b1d2bba..38a74df 100644
--- a/lisp/calendar/icalendar.el
+++ b/lisp/calendar/icalendar.el
@@ -34,6 +34,8 @@
 ;;   week of the year 2000 when they are exported.
 ;; - Yearly diary entries are assumed to occur the first time in the year
 ;;   1900 when they are exported.
+;; - Float diary entries are assumed to occur the first time on the
+;;   day when they are exported.
 
 ;;; History:
 
@@ -241,6 +243,7 @@ code for the event, and your personal domain name."
 ;; all the other libs we need
 ;; ======================================================================
 (require 'calendar)
+(require 'diary-lib)
 
 ;; ======================================================================
 ;; misc
@@ -1548,18 +1551,65 @@ entries.  ENTRY-MAIN is the first line of the diary entry."
     nil))
 
 (defun icalendar--convert-float-to-ical (nonmarker entry-main)
-  "Convert float diary entry to icalendar format -- unsupported!
-
-FIXME!
-
-NONMARKER is a regular expression matching the start of non-marking
-entries.  ENTRY-MAIN is the first line of the diary entry."
-  (if (string-match (concat nonmarker
-                            "%%(diary-float \\([^)]+\\))\\s-*\\(.*?\\) ?$")
-                    entry-main)
-      (progn
-        (icalendar--dmsg "diary-float %s" entry-main)
-        (error "`diary-float' is not supported yet"))
+  "Convert float diary entry to icalendar format -- partially unsupported!
+  
+  FIXME! DAY from diary-float yet unimplemented.
+  
+  NONMARKER is a regular expression matching the start of non-marking
+  entries.  ENTRY-MAIN is the first line of the diary entry."
+  (if (string-match (concat nonmarker "%%\\((diary-float .+\\) ?$") entry-main)
+      (with-temp-buffer
+        (insert (match-string 1 entry-main))
+        (goto-char (point-min))
+        (let* ((sexp (read (current-buffer))) ;using `read' here
+					      ;easier than regexp
+					      ;matching, esp. with
+					      ;different forms of
+					      ;MONTH
+               (month (nth 1 sexp))
+               (dayname (nth 2 sexp))
+               (n (nth 3 sexp))
+               (day (nth 4 sexp))
+               (summary
+		(replace-regexp-in-string 
+		 "\\(^\s+\\|\s+$\\)" "" 
+		 (buffer-substring (point) (point-max)))))
+
+          (when day
+            (progn
+              (icalendar--dmsg "diary-float %s" entry-main)
+              (error "Don't know if or how to implement day in `diary-float'")))
+
+          (list (concat
+                 ;;Start today (yes this is an arbitrary choice):
+                 "\nDTSTART;VALUE=DATE:"
+                 (format-time-string "%Y%m%d" (current-time))
+                 ;;BUT remove today if `diary-float'
+                 ;;expression does not hold true for today:
+                 (when
+                     (null (let ((date (calendar-current-date))
+                                 (entry entry-main))
+                             (diary-float month dayname n)))
+                   (concat 
+                    "\nEXDATE;VALUE=DATE:"
+                    (format-time-string "%Y%m%d" (current-time))))
+                 "\nRRULE:"
+                 (if (or (numberp month) (listp month))
+                     "FREQ=YEARLY;BYMONTH="
+                   "FREQ=MONTHLY")
+                 (when
+                     (listp month)
+                   (mapconcat
+                    (lambda (m)
+                      (number-to-string m))
+                    (cadr month) ","))
+                 (when
+                     (numberp month)
+                   (number-to-string month))
+                 ";BYDAY="
+                 (number-to-string n)
+		 (aref icalendar--weekday-array dayname))
+                summary)))
     ;; no match
     nil))
 
-- 
1.7.1

#+end_src

Perhaps this should go to emacs-devel as well, but I first wanted your
opinions on the matter as org -> ical exporting seems to be a hot matter
on this list.

Cheers,
Niels.

-- 
http://pft.github.com/

  reply	other threads:[~2011-02-12 17:30 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-02-04 11:43 More entries able to export to icalendar format Niels Giesen
2011-02-11 11:43 ` Bastien
2011-02-11 18:46   ` Niels Giesen
2011-02-11 19:43     ` Bastien
2011-02-12 17:30       ` Niels Giesen [this message]
2011-02-13  0:34         ` Bastien

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.orgmode.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87ipwpnot6.fsf@gmail.com \
    --to=niels.giesen@gmail.com \
    --cc=bastien.guerry@wikimedia.fr \
    --cc=emacs-orgmode@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).