org-element: Fix object parsing in captions

* lisp/org-element.el (org-element-parse-secondary-string): Clone all
  local variables from current buffer before parsing a secondary
  string.  Small refactoring.
(org-element-object-variables): Remove variable.

* testing/lisp/test-org-element.el (test-org-element/secondary-string-parsing):
  Add test.

Thanks to Thomas S. Dye for reporting it.
http://permalink.gmane.org/gmane.emacs.orgmode/88850
This commit is contained in:
Nicolas Goaziou 2014-07-25 14:47:38 +02:00
parent 43a8b979f8
commit 0e01e3eb13
2 changed files with 57 additions and 55 deletions

View File

@ -360,11 +360,6 @@ still has an entry since one of its properties (`:title') does.")
(footnote-reference . :inline-definition))
"Alist between element types and location of secondary value.")
(defconst org-element-object-variables '(org-link-abbrev-alist-local)
"List of buffer-local variables used when parsing objects.
These variables are copied to the temporary buffer created by
`org-export-secondary-string'.")
;;; Accessors and Setters
@ -4089,21 +4084,18 @@ looked after.
Optional argument PARENT, when non-nil, is the element or object
containing the secondary string. It is used to set correctly
`:parent' property within the string."
;; Copy buffer-local variables listed in
;; `org-element-object-variables' into temporary buffer. This is
;; required since object parsing is dependent on these variables.
(let ((pairs (delq nil (mapcar (lambda (var)
(when (boundp var)
(cons var (symbol-value var))))
org-element-object-variables))))
(let ((local-variables (buffer-local-variables)))
(with-temp-buffer
(mapc (lambda (pair) (org-set-local (car pair) (cdr pair))) pairs)
(dolist (v local-variables)
(ignore-errors
(if (symbolp v) (makunbound v)
(org-set-local (car v) (cdr v)))))
(insert string)
(restore-buffer-modified-p nil)
(let ((secondary (org-element--parse-objects
(point-min) (point-max) nil restriction)))
(when parent
(mapc (lambda (obj) (org-element-put-property obj :parent parent))
secondary))
(dolist (o secondary) (org-element-put-property o :parent parent)))
secondary))))
(defun org-element-map

View File

@ -2789,47 +2789,57 @@ Paragraph \\alpha."
(ert-deftest test-org-element/secondary-string-parsing ()
"Test if granularity correctly toggles secondary strings parsing."
;; 1. With a granularity bigger than `object', no secondary string
;; should be parsed.
;;
;; 1.1. Test with `headline' type.
(org-test-with-temp-text "* Headline"
(let ((headline
(org-element-map (org-element-parse-buffer 'headline) 'headline
'identity
nil
'first-match)))
(should (stringp (org-element-property :title headline)))))
;; 1.2. Test with `item' type.
(org-test-with-temp-text "* Headline\n- tag :: item"
(let ((item (org-element-map (org-element-parse-buffer 'element)
'item
'identity
nil
'first-match)))
(should (stringp (org-element-property :tag item)))))
;; 1.3. Test with `inlinetask' type, if avalaible.
;; With a granularity bigger than `object', no secondary string
;; should be parsed.
(should
(stringp
(org-test-with-temp-text "* Headline"
(let ((headline
(org-element-map (org-element-parse-buffer 'headline) 'headline
#'identity nil 'first-match)))
(org-element-property :title headline)))))
(should
(stringp
(org-test-with-temp-text "* Headline\n- tag :: item"
(let ((item (org-element-map (org-element-parse-buffer 'element) 'item
#'identity nil 'first-match)))
(org-element-property :tag item)))))
(when (featurep 'org-inlinetask)
(let ((org-inlinetask-min-level 15))
(org-test-with-temp-text "*************** Inlinetask"
(let ((inlinetask (org-element-map (org-element-parse-buffer 'element)
'inlinetask
'identity
nil
'first-match)))
(should (stringp (org-element-property :title inlinetask)))))))
;; 2. With a default granularity, secondary strings should be
;; parsed.
(org-test-with-temp-text "* Headline"
(let ((headline
(org-element-map (org-element-parse-buffer) 'headline
'identity
nil
'first-match)))
(should (listp (org-element-property :title headline)))))
;; 3. `org-element-at-point' should never parse a secondary string.
(org-test-with-temp-text "* Headline"
(should (stringp (org-element-property :title (org-element-at-point))))))
(should
(stringp
(let ((org-inlinetask-min-level 15))
(org-test-with-temp-text "*************** Inlinetask"
(let ((inlinetask (org-element-map (org-element-parse-buffer 'element)
'inlinetask
#'identity nil 'first-match)))
(org-element-property :title inlinetask)))))))
;; With a default granularity, secondary strings should be parsed.
(should
(listp
(org-test-with-temp-text "* Headline"
(let ((headline
(org-element-map (org-element-parse-buffer) 'headline
#'identity nil 'first-match)))
(org-element-property :title headline)))))
;; `org-element-at-point' should never parse a secondary string.
(should-not
(listp
(org-test-with-temp-text "* Headline"
(org-element-property :title (org-element-at-point)))))
;; Preserve current local variables when parsing a secondary string.
(should
(let ((org-entities nil)
(org-entities-user nil))
(org-test-with-temp-text "
#+CAPTION: \\foo
Text
# Local Variables:
# org-entities-user: ((\"foo\"))
# End:"
(let ((safe-local-variable-values '((org-entities-user . (("foo"))))))
(hack-local-variables))
(org-element-map (org-element-parse-buffer) 'entity
#'identity nil nil nil t)))))