From: Michael Brand <michael.ch.brand@gmail.com>
To: Org Mode <emacs-orgmode@gnu.org>
Cc: nicholas.dokos@hp.com
Subject: Re: Add the capture feature "%(sexp)" to org-feed
Date: Sun, 24 Jun 2012 19:51:32 +0200 [thread overview]
Message-ID: <CALn3zoipejd1=f_KR3V0qAphReU6P5nWj0jiy56MmdG0hT4njw@mail.gmail.com> (raw)
In-Reply-To: <7822.1339898820@alphaville>
[-- Attachment #1: Type: text/plain, Size: 1227 bytes --]
Hi all
On Sun, Jun 17, 2012 at 4:07 AM, Nick Dokos <nicholas.dokos@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
[-- Attachment #2: 0001-Add-the-capture-feature-sexp-to-org-feed.patch.txt --]
[-- Type: text/plain, Size: 7262 bytes --]
From a0932d9aedfd00fdeb2446b441b4572e39f8111a Mon Sep 17 00:00:00 2001
From: Michael Brand <michael.ch.brand@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
next prev parent reply other threads:[~2012-06-24 17:51 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 [this message]
2012-08-07 23:05 ` Bastien
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='CALn3zoipejd1=f_KR3V0qAphReU6P5nWj0jiy56MmdG0hT4njw@mail.gmail.com' \
--to=michael.ch.brand@gmail.com \
--cc=emacs-orgmode@gnu.org \
--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).