summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Goaziou <mail@nicolasgoaziou.fr>2019-06-09 00:51:53 +0200
committerNicolas Goaziou <mail@nicolasgoaziou.fr>2019-06-09 00:51:53 +0200
commitbba9116cb8fcb14c5ff616760b606efc0bbb738e (patch)
treeb032edd6b2e8d3b81dd345ce11c1dcb2732c58f2
parentf4083eefd83075ab9d7cb6c52470c1ffe63b7a1c (diff)
downloadorg-mode-bba9116cb8fcb14c5ff616760b606efc0bbb738e.tar.gz
org-element: Parse affiliated keywords according to granularity
* lisp/org-element.el (org-element--current-element): Parse affiliated keywords according to granularity. * lisp/ox.el (org-export-get-caption): Refactor code. * testing/lisp/test-org-element.el (test-org-element/affiliated-keywords-parser): Add tests. Reported-by: ihor <ihor@antonovs.family> <http://lists.gnu.org/r/emacs-orgmode/2019-06/msg00023.html>
-rw-r--r--lisp/org-element.el54
-rw-r--r--lisp/ox.el22
-rw-r--r--testing/lisp/test-org-element.el16
3 files changed, 58 insertions, 34 deletions
diff --git a/lisp/org-element.el b/lisp/org-element.el
index 7af2734..2577282 100644
--- a/lisp/org-element.el
+++ b/lisp/org-element.el
@@ -3899,7 +3899,8 @@ element it has to parse."
((org-at-heading-p)
(org-element-inlinetask-parser limit raw-secondary-p))
;; From there, elements can have affiliated keywords.
- (t (let ((affiliated (org-element--collect-affiliated-keywords limit)))
+ (t (let ((affiliated (org-element--collect-affiliated-keywords
+ limit (memq granularity '(nil object)))))
(cond
;; Jumping over affiliated keywords put point off-limits.
;; Parse them as regular keywords.
@@ -3985,7 +3986,7 @@ element it has to parse."
;; that element, and, in the meantime, collect information they give
;; into appropriate properties. Hence the following function.
-(defun org-element--collect-affiliated-keywords (limit)
+(defun org-element--collect-affiliated-keywords (limit parse)
"Collect affiliated keywords from point down to LIMIT.
Return a list whose CAR is the position at the first of them and
@@ -3994,13 +3995,16 @@ beginning of the first line after them.
As a special case, if element doesn't start at the beginning of
the line (e.g., a paragraph starting an item), CAR is current
-position of point and CDR is nil."
+position of point and CDR is nil.
+
+When PARSE is non-nil, values from keywords belonging to
+`org-element-parsed-keywords' are parsed as secondary strings."
(if (not (bolp)) (list (point))
(let ((case-fold-search t)
(origin (point))
;; RESTRICT is the list of objects allowed in parsed
- ;; keywords value.
- (restrict (org-element-restriction 'keyword))
+ ;; keywords value. If PARSE is nil, no object is allowed.
+ (restrict (and parse (org-element-restriction 'keyword)))
output)
(while (and (< (point) limit) (looking-at org-element--affiliated-re))
(let* ((raw-kwd (upcase (match-string 1)))
@@ -4009,35 +4013,35 @@ position of point and CDR is nil."
(kwd (or (cdr (assoc raw-kwd
org-element-keyword-translation-alist))
raw-kwd))
+ ;; PARSED? is non-nil when keyword should have its
+ ;; value parsed.
+ (parsed? (member kwd org-element-parsed-keywords))
;; Find main value for any keyword.
(value
- (save-match-data
- (org-trim
- (buffer-substring-no-properties
- (match-end 0) (line-end-position)))))
- ;; PARSEDP is non-nil when keyword should have its
- ;; value parsed.
- (parsedp (member kwd org-element-parsed-keywords))
- ;; If KWD is a dual keyword, find its secondary
- ;; value. Maybe parse it.
- (dualp (member kwd org-element-dual-keywords))
+ (let ((beg (match-end 0))
+ (end (save-excursion
+ (end-of-line)
+ (skip-chars-backward " \t")
+ (point))))
+ (if parsed?
+ (org-element--parse-objects beg end nil restrict)
+ (org-trim (buffer-substring-no-properties beg end)))))
+ ;; If KWD is a dual keyword, find its secondary value.
+ ;; Maybe parse it.
+ (dual? (member kwd org-element-dual-keywords))
(dual-value
- (and dualp
+ (and dual?
(let ((sec (match-string-no-properties 2)))
- (if (or (not sec) (not parsedp)) sec
+ (cond
+ ((and sec parsed?)
(save-match-data
(org-element--parse-objects
- (match-beginning 2) (match-end 2) nil restrict))))))
+ (match-beginning 2) (match-end 2) nil restrict)))
+ (sec sec)))))
;; Attribute a property name to KWD.
(kwd-sym (and kwd (intern (concat ":" (downcase kwd))))))
;; Now set final shape for VALUE.
- (when parsedp
- (setq value
- (org-element--parse-objects
- (match-end 0)
- (progn (end-of-line) (skip-chars-backward " \t") (point))
- nil restrict)))
- (when dualp
+ (when dual?
(setq value (and (or value dual-value) (cons value dual-value))))
(when (or (member kwd org-element-multiple-keywords)
;; Attributes can always appear on multiple lines.
diff --git a/lisp/ox.el b/lisp/ox.el
index 87daaff..6641e3d 100644
--- a/lisp/ox.el
+++ b/lisp/ox.el
@@ -3716,18 +3716,24 @@ will become the empty string."
(cdr (nreverse (cons (funcall prepare-value s) result))))))))
(if property (plist-get attributes property) attributes)))
-(defun org-export-get-caption (element &optional shortp)
+(defun org-export-get-caption (element &optional short)
"Return caption from ELEMENT as a secondary string.
-When optional argument SHORTP is non-nil, return short caption,
-as a secondary string, instead.
+When optional argument SHORT is non-nil, return short caption, as
+a secondary string, instead.
Caption lines are separated by a white space."
- (let ((full-caption (org-element-property :caption element)) caption)
- (dolist (line full-caption (cdr caption))
- (let ((cap (funcall (if shortp 'cdr 'car) line)))
- (when cap
- (setq caption (nconc (list " ") (copy-sequence cap) caption)))))))
+ (let ((full-caption (org-element-property :caption element))
+ (get (if short #'cdr #'car))
+ caption)
+ (dolist (line full-caption)
+ (pcase (funcall get line)
+ (`nil nil)
+ (c
+ (setq caption
+ (nconc (list " ")
+ (copy-sequence c) caption)))))
+ (cdr caption)))
;;;; For Derived Back-ends
diff --git a/testing/lisp/test-org-element.el b/testing/lisp/test-org-element.el
index 8b4081e..04f97f9 100644
--- a/testing/lisp/test-org-element.el
+++ b/testing/lisp/test-org-element.el
@@ -376,12 +376,26 @@ Some other text
(org-test-with-temp-text
"#+ATTR_ASCII: line1\n#+ATTR_ASCII: line2\nParagraph"
(org-element-at-point)))))
- ;; Parse "parsed" keywords.
+ ;; Parse "parsed" keywords, unless granularity prevents it.
(should
(equal
'(("caption"))
(org-test-with-temp-text "#+CAPTION: caption\nParagraph"
(car (org-element-property :caption (org-element-at-point))))))
+ (should
+ (org-test-with-temp-text "#+CAPTION: *caption*\nParagraph"
+ (org-element-map (org-element-map (org-element-parse-buffer)
+ 'paragraph
+ (lambda (e) (org-element-property :caption e)) nil t)
+ 'bold
+ #'org-element-type nil t)))
+ (should-not
+ (org-test-with-temp-text "#+CAPTION: *caption*\nParagraph"
+ (org-element-map (org-element-map (org-element-parse-buffer 'element)
+ 'paragraph
+ (lambda (e) (org-element-property :caption e)) nil t)
+ 'bold
+ #'org-element-type nil t)))
;; Parse dual keywords.
(should
(equal