org-element.el: Make affiliated keyword interpreter faster
* lisp/org-element.el (org-element--interpret-affiliated-keywords): Optimize performance by bypassing unnecessary types and reducing loop complexity. Added new constant `org-element-elements-no-affiliated` which stores the types to be bypassed. This function was doing redundant work on several levels which dramatically reduced performance of interpreting element nodes relative to object nodes. First, all types were interpreted regardless of if they could possibly contain affiliated keywords. Skipping these types dramatically speeds up typical use cases since many of these skipped types are common (headline, item, etc). Second, the loop was much more complex than needed. The loop included :standard-properties which should not be necessary here. It also duplicated some work between calls to `org-element--properties-mapc` and `mapconcat` (the code was moved entirely under the former). The result should be faster and more readable. TINYCHANGE
This commit is contained in:
parent
e87ecf88be
commit
1b4fb607bd
|
@ -335,6 +335,11 @@ specially in `org-element--object-lex'.")
|
|||
(append org-element-recursive-objects '(paragraph table-row verse-block))
|
||||
"List of object or element types that can directly contain objects.")
|
||||
|
||||
(defconst org-element-elements-no-affiliated
|
||||
'(org-data comment clock headline inlinetask item
|
||||
node-property planning property-drawer
|
||||
section table-row))
|
||||
|
||||
(defconst org-element-affiliated-keywords
|
||||
'("CAPTION" "DATA" "HEADER" "HEADERS" "LABEL" "NAME" "PLOT" "RESNAME" "RESULT"
|
||||
"RESULTS" "SOURCE" "SRCNAME" "TBLNAME")
|
||||
|
@ -5517,11 +5522,7 @@ to interpret. Return Org syntax as a string."
|
|||
(make-string blank ?\n)))))))))
|
||||
(funcall fun data nil)))
|
||||
|
||||
(defun org-element--interpret-affiliated-keywords (element)
|
||||
"Return ELEMENT's affiliated keywords as Org syntax.
|
||||
If there is no affiliated keyword, return the empty string."
|
||||
(let ((keyword-to-org
|
||||
(lambda (key value)
|
||||
(defun org-element--keyword-to-org (key value)
|
||||
(let (dual)
|
||||
(when (member key org-element-dual-keywords)
|
||||
(setq dual (cdr value) value (car value)))
|
||||
|
@ -5532,34 +5533,35 @@ If there is no affiliated keyword, return the empty string."
|
|||
(if (member key org-element-parsed-keywords)
|
||||
(org-element-interpret-data value)
|
||||
value)
|
||||
"\n")))))
|
||||
(mapconcat
|
||||
(lambda (prop)
|
||||
(let ((value (org-element-property prop element))
|
||||
(keyword (upcase (substring (symbol-name prop) 1))))
|
||||
(when value
|
||||
(if (or (member keyword org-element-multiple-keywords)
|
||||
;; All attribute keywords can have multiple lines.
|
||||
(string-match-p "^ATTR_" keyword))
|
||||
(mapconcat (lambda (line) (funcall keyword-to-org keyword line))
|
||||
value "")
|
||||
(funcall keyword-to-org keyword value)))))
|
||||
;; List all ELEMENT's properties matching an attribute line or an
|
||||
;; affiliated keyword, but ignore translated keywords since they
|
||||
;; cannot belong to the property list.
|
||||
"\n")))
|
||||
|
||||
(defun org-element--interpret-affiliated-keywords (element)
|
||||
"Return ELEMENT's affiliated keywords as Org syntax.
|
||||
If there is no affiliated keyword, return the empty string."
|
||||
;; there are some elements that will never have affiliated keywords,
|
||||
;; so do nothing for these
|
||||
(if (member (org-element-type element) org-element-elements-no-affiliated)
|
||||
""
|
||||
(let (acc)
|
||||
(org-element-properties-mapc
|
||||
(lambda (prop _ __)
|
||||
(org-element-properties-resolve element t)
|
||||
(org-element--properties-mapc
|
||||
(lambda (prop value)
|
||||
(when value
|
||||
(let ((keyword (upcase (substring (symbol-name prop) 1))))
|
||||
(when (or (string-match-p "^ATTR_" keyword)
|
||||
(and
|
||||
(member keyword org-element-affiliated-keywords)
|
||||
(not (assoc keyword
|
||||
org-element-keyword-translation-alist))))
|
||||
(push prop acc))))
|
||||
element t)
|
||||
(nreverse acc))
|
||||
"")))
|
||||
(push (if (or (member keyword org-element-multiple-keywords)
|
||||
;; All attribute keywords can have multiple lines.
|
||||
(string-match-p "^ATTR_" keyword))
|
||||
(mapconcat (lambda (line) (org-element--keyword-to-org keyword line))
|
||||
value "")
|
||||
(org-element--keyword-to-org keyword value))
|
||||
acc)))))
|
||||
element nil t)
|
||||
(apply #'concat (nreverse acc)))))
|
||||
|
||||
;; Because interpretation of the parse tree must return the same
|
||||
;; number of blank lines between elements and the same number of white
|
||||
|
|
Loading…
Reference in New Issue