Hi all

On Sun, Jun 17, 2012 at 4:07 AM, Nick Dokos <nicholas.do...@hp.com> wrote:
> Either require org-capture in org-feed or move the function to org.el, which
> both org-capture and org-feed require.

Thank you for the help. I have chosen the solution with require org-capture.

The patch is now finished and attached:

Add the capture feature "%(sexp)" to org-feed

* lisp/org-capture.el (org-capture-fill-template): Fold the code for
embedded elisp $(sexp) into the following new function and constant.
(org-capture-template-embedded-elisp-re): New constant, contains the
already existing common regexp.
(org-capture-eval-and-replace-embedded-elisp): New function, contains the
already existing common code.
(org-capture-inside-embedded-elisp-p): New function to tell whether the
point is inside embedded elisp %(sexp).
* lisp/org-feed.el (org-feed-default-template): Add the new functionality
to the docstring.
(org-feed-format-entry): Add require org-capture to access the new common
function.  Add escaping of `"' to "simple %-escapes" if necessary for
embedded lisp %(sexp).  Add evaluation and replacement of embedded lisp
%(sexp).

Support for example %(capitalize \\\"%h\\\")" in the template of org-feed.

Michael
From a0932d9aedfd00fdeb2446b441b4572e39f8111a Mon Sep 17 00:00:00 2001
From: Michael Brand <michael.ch.br...@gmail.com>
Date: Sun, 24 Jun 2012 19:46:17 +0200
Subject: [PATCH] Add the capture feature "%(sexp)" to org-feed

* lisp/org-capture.el (org-capture-fill-template): Fold the code for
embedded elisp $(sexp) into the following new function and constant.
(org-capture-template-embedded-elisp-re): New constant, contains the
already existing common regexp.
(org-capture-eval-and-replace-embedded-elisp): New function, contains the
already existing common code.
(org-capture-inside-embedded-elisp-p): New function to tell whether the
point is inside embedded elisp %(sexp).
* lisp/org-feed.el (org-feed-default-template): Add the new functionality
to the docstring.
(org-feed-format-entry): Add require org-capture to access the new common
function.  Add escaping of `"' to "simple %-escapes" if necessary for
embedded lisp %(sexp).  Add evaluation and replacement of embedded lisp
%(sexp).

Support for example %(capitalize \\\"%h\\\")" in the template of org-feed.
---
 lisp/org-capture.el |   51 ++++++++++++++++++++++++++++++++++++++++++---------
 lisp/org-feed.el    |   51 +++++++++++++++++++++++++++++++++++++--------------
 2 files changed, 79 insertions(+), 23 deletions(-)

diff --git a/lisp/org-capture.el b/lisp/org-capture.el
index 0e6ab2c..9a0e9c2 100644
--- a/lisp/org-capture.el
+++ b/lisp/org-capture.el
@@ -1369,15 +1369,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))
@@ -1511,6 +1503,43 @@ The template may still contain \"%?\" for cursor 
positioning."
        t)
     nil))
 
+(defconst org-capture-template-embedded-elisp-re
+  ;; embedded elisp %(sexp) in `org-feed-format-entry' supports simple
+  ;; %-escapes as arguments, therefore allow here \n coming from the
+  ;; result of evaluated simple %-escapes inside embedded elisp %(sexp)
+  "%\\((\\(.\\|\n\\)*\\)")
+
+(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-inside-embedded-elisp-p ()
+  "Return non-nil if point is inside of embedded elisp %(sexp)."
+  (let ((p-orig (point)) p-temp embedded)
+    (save-excursion
+      (save-match-data
+       (when (re-search-backward org-capture-template-embedded-elisp-re
+                                 nil t)
+         ;; match again forward, backward did not match beyond its start
+         (re-search-forward org-capture-template-embedded-elisp-re nil t)
+         ;; convert original point to corresponding point in temp buffer
+         (setq p-temp (+ p-orig (- (match-beginning 1)) 1))
+         (setq embedded (match-string 1))
+         (with-temp-buffer  ; don't interfere with original major mode
+           (insert embedded)
+           (beginning-of-buffer)
+           (emacs-lisp-mode)  ; to deal with for example %(length ")")
+           (when (ignore-errors (forward-sexp) t)
+             (< p-temp (point)))))))))
+
 ;;;###autoload
 (defun org-capture-import-remember-templates ()
   "Set org-capture-templates to be similar to `org-remember-templates'."
@@ -1552,4 +1581,8 @@ The template may still contain \"%?\" for cursor 
positioning."
 
 (provide 'org-capture)
 
+;; Local variables:
+;; sentence-end-double-space: t
+;; End:
+
 ;;; org-capture.el ends here
diff --git a/lisp/org-feed.el b/lisp/org-feed.el
index 6901ffa..46dc6b7 100644
--- a/lisp/org-feed.el
+++ b/lisp/org-feed.el
@@ -230,7 +230,10 @@ following special escapes are valid as well:
         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>"
+%a      A link, from <guid> if that is a permalink, else from <link>
+%(sexp) evaluate elisp `(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,35 @@ 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 escape (org-capture-inside-embedded-elisp-p)
+                 name (match-string 1))
+           (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))))))
 
@@ -673,4 +692,8 @@ formatted as a string, not the original XML data."
 
 (provide 'org-feed)
 
+;; Local variables:
+;; sentence-end-double-space: t
+;; End:
+
 ;;; org-feed.el ends here
-- 
1.7.4.2

Reply via email to