X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/be520aca79dd429d55012a1916bdc97f06773fc5..2393085c9ac30ac7378a39ee77760dfdecd4b509:/lisp/org/org-feed.el diff --git a/lisp/org/org-feed.el b/lisp/org/org-feed.el index 07558af462..f012124215 100644 --- a/lisp/org/org-feed.el +++ b/lisp/org/org-feed.el @@ -1,11 +1,10 @@ ;;; org-feed.el --- Add RSS feed items to Org files ;; -;; Copyright (C) 2009-2011 Free Software Foundation, Inc. +;; Copyright (C) 2009-2015 Free Software Foundation, Inc. ;; ;; Author: Carsten Dominik ;; Keywords: outlines, hypermedia, calendar, wp ;; Homepage: http://orgmode.org -;; Version: 7.4 ;; ;; This file is part of GNU Emacs. ;; @@ -81,7 +80,7 @@ ;; that received the input of the feed. You should add FEEDSTATUS ;; to your list of drawers in the files that receive feed input: ;; -;; #+DRAWERS: PROPERTIES LOGBOOK FEEDSTATUS +;; #+DRAWERS: PROPERTIES CLOCK LOGBOOK RESULTS FEEDSTATUS ;; ;; Acknowledgments ;; --------------- @@ -101,6 +100,10 @@ (declare-function xml-get-attribute-or-nil "xml" (node attribute)) (declare-function xml-substitute-special "xml" (string)) +(declare-function org-capture-escaped-% "org-capture" ()) +(declare-function org-capture-inside-embedded-elisp-p "org-capture" ()) +(declare-function org-capture-expand-embedded-elisp "org-capture" ()) + (defgroup org-feed nil "Options concerning RSS feeds as inputs for Org files." :tag "Org Feed" @@ -180,34 +183,34 @@ Here are the keyword-value pair allows in `org-feed-alist'. :group 'org-feed :type '(repeat (list :value ("" "http://" "" "") - (string :tag "Name") - (string :tag "Feed URL") - (file :tag "File for inbox") - (string :tag "Headline for inbox") - (repeat :inline t - (choice - (list :inline t :tag "Filter" - (const :filter) - (symbol :tag "Filter Function")) - (list :inline t :tag "Template" - (const :template) - (string :tag "Template")) - (list :inline t :tag "Formatter" - (const :formatter) - (symbol :tag "Formatter Function")) - (list :inline t :tag "New items handler" - (const :new-handler) - (symbol :tag "Handler Function")) - (list :inline t :tag "Changed items" - (const :changed-handler) - (symbol :tag "Handler Function")) - (list :inline t :tag "Parse Feed" - (const :parse-feed) - (symbol :tag "Parse Feed Function")) - (list :inline t :tag "Parse Entry" - (const :parse-entry) - (symbol :tag "Parse Entry Function")) - ))))) + (string :tag "Name") + (string :tag "Feed URL") + (file :tag "File for inbox") + (string :tag "Headline for inbox") + (repeat :inline t + (choice + (list :inline t :tag "Filter" + (const :filter) + (symbol :tag "Filter Function")) + (list :inline t :tag "Template" + (const :template) + (string :tag "Template")) + (list :inline t :tag "Formatter" + (const :formatter) + (symbol :tag "Formatter Function")) + (list :inline t :tag "New items handler" + (const :new-handler) + (symbol :tag "Handler Function")) + (list :inline t :tag "Changed items" + (const :changed-handler) + (symbol :tag "Handler Function")) + (list :inline t :tag "Parse Feed" + (const :parse-feed) + (symbol :tag "Parse Feed Function")) + (list :inline t :tag "Parse Entry" + (const :parse-entry) + (symbol :tag "Parse Entry Function")) + ))))) (defcustom org-feed-drawer "FEEDSTATUS" "The name of the drawer for feed status information. @@ -226,12 +229,14 @@ 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 (if present), or - the current date. -%T date and time -%u,%U like %t,%T, but inactive time stamps -%a A link, from if that is a permalink, else from " +%h The title, or the first line of the description +%t The date as a stamp, either from (if present), or + the current date +%T Date and time +%u,%U Like %t,%T, but inactive time stamps +%a A link, from if that is a permalink, else from +%(sexp) Evaluate elisp `(sexp)' and replace with the result, the simple + %-escapes above can be used as arguments, e.g. %(capitalize \\\"%h\\\")" :group 'org-feed :type '(string :tag "Template")) @@ -252,7 +257,7 @@ of the file pointed to by the URL." (const :tag "Externally with wget" wget) (function :tag "Function"))) - (defcustom org-feed-before-adding-hook nil +(defcustom org-feed-before-adding-hook nil "Hook that is run before adding new feed items to a file. You might want to commit the file in its current state to version control, for example." @@ -436,7 +441,7 @@ it can be a list structured like an entry in `org-feed-alist'." (if (stringp feed) (setq feed (assoc feed org-feed-alist))) (unless feed (error "No such feed in `org-feed-alist")) - (switch-to-buffer + (org-pop-to-buffer-same-window (org-feed-update feed 'retrieve-only)) (goto-char (point-min))) @@ -451,8 +456,8 @@ Switch to that buffer, and return the position of that headline." nil t) (goto-char (match-beginning 0)) (goto-char (point-max)) - (insert "\n\n* " heading "\n\n") - (org-back-to-heading t)) + (insert "\n\n* " heading "\n\n") + (org-back-to-heading t)) (point)) (defun org-feed-read-previous-status (pos drawer) @@ -507,9 +512,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") @@ -528,20 +534,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 name (match-string 1) + escape (org-capture-inside-embedded-elisp-p)) + (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-expand-embedded-elisp) + (decode-coding-string (buffer-string) (detect-coding-region (point-min) (point-max) t)))))) @@ -674,4 +695,8 @@ formatted as a string, not the original XML data." (provide 'org-feed) +;; Local variables: +;; generated-autoload-file: "org-loaddefs.el" +;; End: + ;;; org-feed.el ends here