forked from mirrors/org-mode
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>
This commit is contained in:
parent
f4083eefd8
commit
bba9116cb8
|
@ -3899,7 +3899,8 @@ element it has to parse."
|
||||||
((org-at-heading-p)
|
((org-at-heading-p)
|
||||||
(org-element-inlinetask-parser limit raw-secondary-p))
|
(org-element-inlinetask-parser limit raw-secondary-p))
|
||||||
;; From there, elements can have affiliated keywords.
|
;; 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
|
(cond
|
||||||
;; Jumping over affiliated keywords put point off-limits.
|
;; Jumping over affiliated keywords put point off-limits.
|
||||||
;; Parse them as regular keywords.
|
;; Parse them as regular keywords.
|
||||||
|
@ -3985,7 +3986,7 @@ element it has to parse."
|
||||||
;; that element, and, in the meantime, collect information they give
|
;; that element, and, in the meantime, collect information they give
|
||||||
;; into appropriate properties. Hence the following function.
|
;; 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.
|
"Collect affiliated keywords from point down to LIMIT.
|
||||||
|
|
||||||
Return a list whose CAR is the position at the first of them and
|
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
|
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
|
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))
|
(if (not (bolp)) (list (point))
|
||||||
(let ((case-fold-search t)
|
(let ((case-fold-search t)
|
||||||
(origin (point))
|
(origin (point))
|
||||||
;; RESTRICT is the list of objects allowed in parsed
|
;; RESTRICT is the list of objects allowed in parsed
|
||||||
;; keywords value.
|
;; keywords value. If PARSE is nil, no object is allowed.
|
||||||
(restrict (org-element-restriction 'keyword))
|
(restrict (and parse (org-element-restriction 'keyword)))
|
||||||
output)
|
output)
|
||||||
(while (and (< (point) limit) (looking-at org-element--affiliated-re))
|
(while (and (< (point) limit) (looking-at org-element--affiliated-re))
|
||||||
(let* ((raw-kwd (upcase (match-string 1)))
|
(let* ((raw-kwd (upcase (match-string 1)))
|
||||||
|
@ -4009,35 +4013,35 @@ position of point and CDR is nil."
|
||||||
(kwd (or (cdr (assoc raw-kwd
|
(kwd (or (cdr (assoc raw-kwd
|
||||||
org-element-keyword-translation-alist))
|
org-element-keyword-translation-alist))
|
||||||
raw-kwd))
|
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.
|
;; Find main value for any keyword.
|
||||||
(value
|
(value
|
||||||
(save-match-data
|
(let ((beg (match-end 0))
|
||||||
(org-trim
|
(end (save-excursion
|
||||||
(buffer-substring-no-properties
|
(end-of-line)
|
||||||
(match-end 0) (line-end-position)))))
|
(skip-chars-backward " \t")
|
||||||
;; PARSEDP is non-nil when keyword should have its
|
(point))))
|
||||||
;; value parsed.
|
(if parsed?
|
||||||
(parsedp (member kwd org-element-parsed-keywords))
|
(org-element--parse-objects beg end nil restrict)
|
||||||
;; If KWD is a dual keyword, find its secondary
|
(org-trim (buffer-substring-no-properties beg end)))))
|
||||||
;; value. Maybe parse it.
|
;; If KWD is a dual keyword, find its secondary value.
|
||||||
(dualp (member kwd org-element-dual-keywords))
|
;; Maybe parse it.
|
||||||
|
(dual? (member kwd org-element-dual-keywords))
|
||||||
(dual-value
|
(dual-value
|
||||||
(and dualp
|
(and dual?
|
||||||
(let ((sec (match-string-no-properties 2)))
|
(let ((sec (match-string-no-properties 2)))
|
||||||
(if (or (not sec) (not parsedp)) sec
|
(cond
|
||||||
|
((and sec parsed?)
|
||||||
(save-match-data
|
(save-match-data
|
||||||
(org-element--parse-objects
|
(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.
|
;; Attribute a property name to KWD.
|
||||||
(kwd-sym (and kwd (intern (concat ":" (downcase kwd))))))
|
(kwd-sym (and kwd (intern (concat ":" (downcase kwd))))))
|
||||||
;; Now set final shape for VALUE.
|
;; Now set final shape for VALUE.
|
||||||
(when parsedp
|
(when dual?
|
||||||
(setq value
|
|
||||||
(org-element--parse-objects
|
|
||||||
(match-end 0)
|
|
||||||
(progn (end-of-line) (skip-chars-backward " \t") (point))
|
|
||||||
nil restrict)))
|
|
||||||
(when dualp
|
|
||||||
(setq value (and (or value dual-value) (cons value dual-value))))
|
(setq value (and (or value dual-value) (cons value dual-value))))
|
||||||
(when (or (member kwd org-element-multiple-keywords)
|
(when (or (member kwd org-element-multiple-keywords)
|
||||||
;; Attributes can always appear on multiple lines.
|
;; Attributes can always appear on multiple lines.
|
||||||
|
|
22
lisp/ox.el
22
lisp/ox.el
|
@ -3716,18 +3716,24 @@ will become the empty string."
|
||||||
(cdr (nreverse (cons (funcall prepare-value s) result))))))))
|
(cdr (nreverse (cons (funcall prepare-value s) result))))))))
|
||||||
(if property (plist-get attributes property) attributes)))
|
(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.
|
"Return caption from ELEMENT as a secondary string.
|
||||||
|
|
||||||
When optional argument SHORTP is non-nil, return short caption,
|
When optional argument SHORT is non-nil, return short caption, as
|
||||||
as a secondary string, instead.
|
a secondary string, instead.
|
||||||
|
|
||||||
Caption lines are separated by a white space."
|
Caption lines are separated by a white space."
|
||||||
(let ((full-caption (org-element-property :caption element)) caption)
|
(let ((full-caption (org-element-property :caption element))
|
||||||
(dolist (line full-caption (cdr caption))
|
(get (if short #'cdr #'car))
|
||||||
(let ((cap (funcall (if shortp 'cdr 'car) line)))
|
caption)
|
||||||
(when cap
|
(dolist (line full-caption)
|
||||||
(setq caption (nconc (list " ") (copy-sequence cap) caption)))))))
|
(pcase (funcall get line)
|
||||||
|
(`nil nil)
|
||||||
|
(c
|
||||||
|
(setq caption
|
||||||
|
(nconc (list " ")
|
||||||
|
(copy-sequence c) caption)))))
|
||||||
|
(cdr caption)))
|
||||||
|
|
||||||
|
|
||||||
;;;; For Derived Back-ends
|
;;;; For Derived Back-ends
|
||||||
|
|
|
@ -376,12 +376,26 @@ Some other text
|
||||||
(org-test-with-temp-text
|
(org-test-with-temp-text
|
||||||
"#+ATTR_ASCII: line1\n#+ATTR_ASCII: line2\nParagraph"
|
"#+ATTR_ASCII: line1\n#+ATTR_ASCII: line2\nParagraph"
|
||||||
(org-element-at-point)))))
|
(org-element-at-point)))))
|
||||||
;; Parse "parsed" keywords.
|
;; Parse "parsed" keywords, unless granularity prevents it.
|
||||||
(should
|
(should
|
||||||
(equal
|
(equal
|
||||||
'(("caption"))
|
'(("caption"))
|
||||||
(org-test-with-temp-text "#+CAPTION: caption\nParagraph"
|
(org-test-with-temp-text "#+CAPTION: caption\nParagraph"
|
||||||
(car (org-element-property :caption (org-element-at-point))))))
|
(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.
|
;; Parse dual keywords.
|
||||||
(should
|
(should
|
||||||
(equal
|
(equal
|
||||||
|
|
Loading…
Reference in a new issue