org-export-as: Do not update buffer settings when not modified

* lisp/ox.el (org-export-as): Use `buffer-chars-modified-tick' and
avoid extra invocations of `org-set-regexps-and-options' and
`org-update-radio-target-regexp' when the buffer is not changed.
Also, disable folding checks.  Folding is irrelevant inside export
buffer.
This commit is contained in:
Ihor Radchenko 2022-06-16 01:03:18 +08:00
parent aa789b89d7
commit 076dd92acc
No known key found for this signature in database
GPG Key ID: 6470762A7DA11D8B
1 changed files with 135 additions and 128 deletions

View File

@ -2938,135 +2938,142 @@ still inferior to file-local settings.
Return code as a string." Return code as a string."
(when (symbolp backend) (setq backend (org-export-get-backend backend))) (when (symbolp backend) (setq backend (org-export-get-backend backend)))
(org-export-barf-if-invalid-backend backend) (org-export-barf-if-invalid-backend backend)
(save-excursion (org-fold-core-ignore-modifications
(save-restriction (save-excursion
;; Narrow buffer to an appropriate region or subtree for (save-restriction
;; parsing. If parsing subtree, be sure to remove main ;; Narrow buffer to an appropriate region or subtree for
;; headline, planning data and property drawer. ;; parsing. If parsing subtree, be sure to remove main
(cond ((org-region-active-p) ;; headline, planning data and property drawer.
(narrow-to-region (region-beginning) (region-end))) (cond ((org-region-active-p)
(subtreep (narrow-to-region (region-beginning) (region-end)))
(org-narrow-to-subtree) (subtreep
(goto-char (point-min)) (org-narrow-to-subtree)
(org-end-of-meta-data) (goto-char (point-min))
(narrow-to-region (point) (point-max)))) (org-end-of-meta-data)
;; Initialize communication channel with original buffer (narrow-to-region (point) (point-max))))
;; attributes, unavailable in its copy. ;; Initialize communication channel with original buffer
(let* ((org-export-current-backend (org-export-backend-name backend)) ;; attributes, unavailable in its copy.
(info (org-combine-plists (let* ((org-export-current-backend (org-export-backend-name backend))
(org-export--get-export-attributes (info (org-combine-plists
backend subtreep visible-only body-only) (org-export--get-export-attributes
(org-export--get-buffer-attributes))) backend subtreep visible-only body-only)
(parsed-keywords (org-export--get-buffer-attributes)))
(delq nil (parsed-keywords
(mapcar (lambda (o) (and (eq (nth 4 o) 'parse) (nth 1 o))) (delq nil
(append (org-export-get-all-options backend) (mapcar (lambda (o) (and (eq (nth 4 o) 'parse) (nth 1 o)))
org-export-options-alist)))) (append (org-export-get-all-options backend)
tree) org-export-options-alist))))
;; Update communication channel and get parse tree. Buffer tree modified-tick)
;; isn't parsed directly. Instead, all buffer modifications ;; Update communication channel and get parse tree. Buffer
;; and consequent parsing are undertaken in a temporary copy. ;; isn't parsed directly. Instead, all buffer modifications
(org-export-with-buffer-copy ;; and consequent parsing are undertaken in a temporary copy.
;; Run first hook with current back-end's name as argument. (org-export-with-buffer-copy
(run-hook-with-args 'org-export-before-processing-hook (font-lock-mode -1)
(org-export-backend-name backend)) ;; Run first hook with current back-end's name as argument.
(org-export-expand-include-keyword) (run-hook-with-args 'org-export-before-processing-hook
(org-export--delete-comment-trees) (org-export-backend-name backend))
(org-macro-initialize-templates org-export-global-macros) (org-export-expand-include-keyword)
(org-macro-replace-all org-macro-templates parsed-keywords) (org-export--delete-comment-trees)
;; Refresh buffer properties and radio targets after previous (org-macro-initialize-templates org-export-global-macros)
;; potentially invasive changes. (org-macro-replace-all org-macro-templates parsed-keywords)
(org-set-regexps-and-options) ;; Refresh buffer properties and radio targets after previous
(org-update-radio-target-regexp) ;; potentially invasive changes.
;; Possibly execute Babel code. Re-run a macro expansion
;; specifically for {{{results}}} since inline source blocks
;; may have generated some more. Refresh buffer properties
;; and radio targets another time.
(when org-export-use-babel
(org-babel-exp-process-buffer)
(org-macro-replace-all '(("results" . "$1")) parsed-keywords)
(org-set-regexps-and-options) (org-set-regexps-and-options)
(org-update-radio-target-regexp)) (org-update-radio-target-regexp)
;; Run last hook with current back-end's name as argument. (setq modified-tick (buffer-chars-modified-tick))
;; Update buffer properties and radio targets one last time ;; Possibly execute Babel code. Re-run a macro expansion
;; before parsing. ;; specifically for {{{results}}} since inline source blocks
(goto-char (point-min)) ;; may have generated some more. Refresh buffer properties
(save-excursion ;; and radio targets another time.
(run-hook-with-args 'org-export-before-parsing-hook (when org-export-use-babel
(org-export-backend-name backend))) (org-babel-exp-process-buffer)
(org-set-regexps-and-options) (org-macro-replace-all '(("results" . "$1")) parsed-keywords)
(org-update-radio-target-regexp) (unless (eq modified-tick (buffer-chars-modified-tick))
;; Update communication channel with environment. (org-set-regexps-and-options)
(setq info (org-update-radio-target-regexp))
(org-combine-plists (setq modified-tick (buffer-chars-modified-tick)))
info (org-export-get-environment backend subtreep ext-plist))) ;; Run last hook with current back-end's name as argument.
;; Pre-process citations environment, i.e. install ;; Update buffer properties and radio targets one last time
;; bibliography list, and citation processor in INFO. ;; before parsing.
(org-cite-store-bibliography info) (goto-char (point-min))
(org-cite-store-export-processor info) (save-excursion
;; De-activate uninterpreted data from parsed keywords. (run-hook-with-args 'org-export-before-parsing-hook
(dolist (entry (append (org-export-get-all-options backend) (org-export-backend-name backend)))
org-export-options-alist)) (unless (eq modified-tick (buffer-chars-modified-tick))
(pcase entry (org-set-regexps-and-options)
(`(,p ,_ ,_ ,_ parse) (org-update-radio-target-regexp))
(let ((value (plist-get info p))) (setq modified-tick (buffer-chars-modified-tick))
(plist-put info ;; Update communication channel with environment.
p (setq info
(org-export--remove-uninterpreted-data value info)))) (org-combine-plists
(_ nil))) info (org-export-get-environment backend subtreep ext-plist)))
;; Install user's and developer's filters. ;; Pre-process citations environment, i.e. install
(setq info (org-export-install-filters info)) ;; bibliography list, and citation processor in INFO.
;; Call options filters and update export options. We do not (org-cite-store-bibliography info)
;; use `org-export-filter-apply-functions' here since the (org-cite-store-export-processor info)
;; arity of such filters is different. ;; De-activate uninterpreted data from parsed keywords.
(let ((backend-name (org-export-backend-name backend))) (dolist (entry (append (org-export-get-all-options backend)
(dolist (filter (plist-get info :filter-options)) org-export-options-alist))
(let ((result (funcall filter info backend-name))) (pcase entry
(when result (setq info result))))) (`(,p ,_ ,_ ,_ parse)
;; Parse buffer. (let ((value (plist-get info p)))
(setq tree (org-element-parse-buffer nil visible-only)) (plist-put info
;; Prune tree from non-exported elements and transform p
;; uninterpreted elements or objects in both parse tree and (org-export--remove-uninterpreted-data value info))))
;; communication channel. (_ nil)))
(org-export--prune-tree tree info) ;; Install user's and developer's filters.
(org-export--remove-uninterpreted-data tree info) (setq info (org-export-install-filters info))
;; Call parse tree filters. ;; Call options filters and update export options. We do not
(setq tree ;; use `org-export-filter-apply-functions' here since the
(org-export-filter-apply-functions ;; arity of such filters is different.
(plist-get info :filter-parse-tree) tree info)) (let ((backend-name (org-export-backend-name backend)))
;; Now tree is complete, compute its properties and add them (dolist (filter (plist-get info :filter-options))
;; to communication channel. (let ((result (funcall filter info backend-name)))
(setq info (org-export--collect-tree-properties tree info)) (when result (setq info result)))))
;; Process citations and bibliography. Replace each citation ;; Parse buffer.
;; and "print_bibliography" keyword in the parse tree with (setq tree (org-element-parse-buffer nil visible-only))
;; the output of the selected citation export processor. ;; Prune tree from non-exported elements and transform
(org-cite-process-citations info) ;; uninterpreted elements or objects in both parse tree and
(org-cite-process-bibliography info) ;; communication channel.
;; Eventually transcode TREE. Wrap the resulting string into (org-export--prune-tree tree info)
;; a template. (org-export--remove-uninterpreted-data tree info)
(let* ((body (org-element-normalize-string ;; Call parse tree filters.
(or (org-export-data tree info) ""))) (setq tree
(inner-template (cdr (assq 'inner-template (org-export-filter-apply-functions
(plist-get info :translate-alist)))) (plist-get info :filter-parse-tree) tree info))
(full-body (org-export-filter-apply-functions ;; Now tree is complete, compute its properties and add them
(plist-get info :filter-body) ;; to communication channel.
(if (not (functionp inner-template)) body (setq info (org-export--collect-tree-properties tree info))
(funcall inner-template body info)) ;; Process citations and bibliography. Replace each citation
info)) ;; and "print_bibliography" keyword in the parse tree with
(template (cdr (assq 'template ;; the output of the selected citation export processor.
(plist-get info :translate-alist)))) (org-cite-process-citations info)
(output (org-cite-process-bibliography info)
(if (or (not (functionp template)) body-only) full-body ;; Eventually transcode TREE. Wrap the resulting string into
(funcall template full-body info)))) ;; a template.
;; Call citation export finalizer. (let* ((body (org-element-normalize-string
(setq output (org-cite-finalize-export output info)) (or (org-export-data tree info) "")))
;; Remove all text properties since they cannot be (inner-template (cdr (assq 'inner-template
;; retrieved from an external process. Finally call (plist-get info :translate-alist))))
;; final-output filter and return result. (full-body (org-export-filter-apply-functions
(org-no-properties (plist-get info :filter-body)
(org-export-filter-apply-functions (if (not (functionp inner-template)) body
(plist-get info :filter-final-output) (funcall inner-template body info))
output info)))))))) info))
(template (cdr (assq 'template
(plist-get info :translate-alist))))
(output
(if (or (not (functionp template)) body-only) full-body
(funcall template full-body info))))
;; Call citation export finalizer.
(setq output (org-cite-finalize-export output info))
;; Remove all text properties since they cannot be
;; retrieved from an external process. Finally call
;; final-output filter and return result.
(org-no-properties
(org-export-filter-apply-functions
(plist-get info :filter-final-output)
output info)))))))))
;;;###autoload ;;;###autoload
(defun org-export-string-as (string backend &optional body-only ext-plist) (defun org-export-string-as (string backend &optional body-only ext-plist)