emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: Bastien <bzg@gnu.org>
To: Michael Brand <michael.ch.brand@gmail.com>
Cc: nicholas.dokos@hp.com, Org Mode <emacs-orgmode@gnu.org>
Subject: Re: Add the capture feature "%(sexp)" to org-feed
Date: Wed, 08 Aug 2012 01:05:10 +0200	[thread overview]
Message-ID: <87y5lqe21l.fsf@gnu.org> (raw)
In-Reply-To: <CALn3zoipejd1=f_KR3V0qAphReU6P5nWj0jiy56MmdG0hT4njw@mail.gmail.com> (Michael Brand's message of "Sun, 24 Jun 2012 19:51:32 +0200")

[-- Attachment #1: Type: text/plain, Size: 373 bytes --]

Hi Michael,

Michael Brand <michael.ch.brand@gmail.com> writes:

> Thank you for the help. I have chosen the solution with require org-capture.
>
> The patch is now finished and attached:

I've reworked some parts of your patch, specifically, I used
`org-at-regexp-p' instead of `org-capture-inside-embedded-elisp-p'.

Can you check this is working okay for you?

Thanks!


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-org-feed.el-Add-the-capture-feature-sexp.patch --]
[-- Type: text/x-patch, Size: 6125 bytes --]

From 35e5c3d0b098dc65f321cc32626172e984cf2c2f Mon Sep 17 00:00:00 2001
From: Bastien Guerry <bzg@altern.org>
Date: Wed, 8 Aug 2012 01:01:29 +0200
Subject: [PATCH] org-feed.el: Add the capture feature "%(sexp)".

* org-feed.el (org-feed-format-entry): Support %(sexp).
(org-feed-default-template): Update docstring to document the
support of %(sexp).

* org-capture.el (org-capture-template-embedded-elisp-re): New
constant.
(org-capture-eval-and-replace-embedded-elisp): New function.
(org-capture-fill-template): Use the new function.
---
 lisp/org-capture.el |   25 ++++++++++++++---------
 lisp/org-feed.el    |   56 ++++++++++++++++++++++++++++++++++-----------------
 2 files changed, 53 insertions(+), 28 deletions(-)

diff --git a/lisp/org-capture.el b/lisp/org-capture.el
index 05e3a0c..352e655 100644
--- a/lisp/org-capture.el
+++ b/lisp/org-capture.el
@@ -74,6 +74,9 @@
 ;; to indicate that the link properties have already been stored
 (defvar org-capture-link-is-already-stored nil)
 
+(defconst org-capture-template-embedded-elisp-re
+  "%\\((\\(.\\|\n\\)*)\\)")
+
 (defgroup org-capture nil
   "Options concerning capturing new entries."
   :tag "Org Capture"
@@ -1277,6 +1280,18 @@ Lisp programs can force the template by setting KEYS to a string."
 	       '(("C" "Customize org-capture-templates")
 		 ("q" "Abort"))))))
 
+(defun org-capture-eval-and-replace-embedded-elisp ()
+  "Evaluate embedded elisp %(sexp) and replace with the result."
+  (goto-char (point-min))
+  (while (re-search-forward org-capture-template-embedded-elisp-re nil t)
+    (unless (org-capture-escaped-%)
+      (goto-char (match-beginning 0))
+      (let ((template-start (point)))
+	(forward-char 1)
+	(let ((result (org-eval (read (current-buffer)))))
+	  (delete-region template-start (point))
+	  (insert result))))))
+
 (defun org-capture-fill-template (&optional template initial annotation)
   "Fill a template and return the filled template as a string.
 The template may still contain \"%?\" for cursor positioning."
@@ -1371,15 +1386,7 @@ The template may still contain \"%?\" for cursor positioning."
 	      (error (insert (format "%%![Couldn't insert %s: %s]"
 				     filename error)))))))
       ;; %() embedded elisp
-      (goto-char (point-min))
-      (while (re-search-forward "%\\((.+)\\)" nil t)
-	(unless (org-capture-escaped-%)
-	  (goto-char (match-beginning 0))
-	  (let ((template-start (point)))
-	    (forward-char 1)
-	    (let ((result (org-eval (read (current-buffer)))))
-	      (delete-region template-start (point))
-	      (insert result)))))
+      (org-capture-eval-and-replace-embedded-elisp)
 
       ;; The current time
       (goto-char (point-min))
diff --git a/lisp/org-feed.el b/lisp/org-feed.el
index 6901ffa..912dd6e 100644
--- a/lisp/org-feed.el
+++ b/lisp/org-feed.el
@@ -225,12 +225,15 @@ Any fields from the feed item can be interpolated into the template with
 %name, for example %title, %description, %pubDate etc.  In addition, the
 following special escapes are valid as well:
 
-%h      the title, or the first line of the description
-%t      the date as a stamp, either from <pubDate> (if present), or
-        the current date.
-%T      date and time
-%u,%U   like %t,%T, but inactive time stamps
-%a      A link, from <guid> if that is a permalink, else from <link>"
+%h      The title, or the first line of the description
+%t      The date as a stamp, either from <pubDate> (if present), or
+        The current date.
+%T      Date and time
+%u,%U   Like %t,%T, but inactive time stamps
+%a      A link, from <guid> if that is a permalink, else from <link>
+%(sexp) Evaluate the Elisp sexp `(sexp)' and replace with the result.
+        The above simple %-escapes can be used as arguments,
+        for example %(capitalize \\\"%h\\\")"
   :group 'org-feed
   :type '(string :tag "Template"))
 
@@ -506,9 +509,10 @@ This will find DRAWER and extract the alist."
 ENTRY is a property list.  This function adds a `:formatted-for-org' property
 and returns the full property list.
 If that property is already present, nothing changes."
+  (require 'org-capture)
   (if formatter
       (funcall formatter entry)
-    (let (dlines fmt tmp indent time name
+    (let (dlines time escape name tmp
 		 v-h v-t v-T v-u v-U v-a)
       (setq dlines (org-split-string (or (plist-get entry :description) "???")
 				     "\n")
@@ -527,20 +531,34 @@ If that property is already present, nothing changes."
 		  ""))
       (with-temp-buffer
 	(insert template)
+
+	;; Simple %-escapes before embedded elisp to support simple
+	;; %-escapes as arguments for embedded elisp
 	(goto-char (point-min))
 	(while (re-search-forward "%\\([a-zA-Z]+\\)" nil t)
-	  (setq name (match-string 1))
-	  (cond
-	   ((member name '("h" "t" "T" "u" "U" "a"))
-	    (replace-match (symbol-value (intern (concat "v-" name))) t t))
-	   ((setq tmp (plist-get entry (intern (concat ":" name))))
-	    (save-excursion
-	      (save-match-data
-		(beginning-of-line 1)
-		(when (looking-at (concat "^\\([ \t]*\\)%" name "[ \t]*$"))
-		  (setq tmp (org-feed-make-indented-block
-			     tmp (org-get-indentation))))))
-	    (replace-match tmp t t))))
+	  (unless (org-capture-escaped-%)
+	    (setq name (match-string 1)
+		  escape (org-at-regexp-p org-capture-template-embedded-elisp-re))
+	    (cond
+	     ((member name '("h" "t" "T" "u" "U" "a"))
+	      (setq tmp (symbol-value (intern (concat "v-" name)))))
+	     ((setq tmp (plist-get entry (intern (concat ":" name))))
+	      (save-excursion
+		(save-match-data
+		  (beginning-of-line 1)
+		  (when (looking-at
+			 (concat "^\\([ \t]*\\)%" name "[ \t]*$"))
+		    (setq tmp (org-feed-make-indented-block
+			       tmp (org-get-indentation))))))))
+	    (when tmp
+	      ;; escape string delimiters `"' when inside %() embedded lisp
+	      (when escape
+		(setq tmp (replace-regexp-in-string "\"" "\\\\\"" tmp)))
+	      (replace-match tmp t t))))
+
+	;; %() embedded elisp
+	(org-capture-eval-and-replace-embedded-elisp)
+
 	(decode-coding-string
 	 (buffer-string) (detect-coding-region (point-min) (point-max) t))))))
 
-- 
1.7.10.2


[-- Attachment #3: Type: text/plain, Size: 14 bytes --]


-- 
 Bastien

  reply	other threads:[~2012-08-07 23:04 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-06-16 15:53 Add the capture feature "%(sexp)" to org-feed Michael Brand
2012-06-17  2:07 ` Nick Dokos
2012-06-24 17:51   ` Michael Brand
2012-08-07 23:05     ` Bastien [this message]
2012-08-09 14:07       ` Michael Brand
2012-08-09 14:53         ` Bastien
2012-08-09 18:00           ` Michael Brand
2012-08-10  8:53             ` Bastien
2012-08-11 15:31               ` Michael Brand
2012-08-11 16:55                 ` Bastien
2012-08-11 18:11                   ` Michael Brand
2012-08-11 21:59                     ` Bastien
2012-08-12  9:37                       ` Michael Brand
2012-08-12 10:12                         ` Bastien
2012-08-09 21:09           ` Ivan Andrus
2012-08-10  4:48             ` Michael Brand
2012-08-10  7:24               ` 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=87y5lqe21l.fsf@gnu.org \
    --to=bzg@gnu.org \
    --cc=emacs-orgmode@gnu.org \
    --cc=michael.ch.brand@gmail.com \
    --cc=nicholas.dokos@hp.com \
    /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).