Skip to content

Commit

Permalink
speedup: Reduce repeated find-file ops on the same file
Browse files Browse the repository at this point in the history
A find-file used to happen for each link searched in an external Org
file when exported each subtree post when using the all-subtrees
option of the wim exporting function.

Now the export function is allowed to open as many files and buffers
as needed, but they are now killed at the very end of each export.
This immensely improves the exporting speed when doing C-c C-e H A.

- Renamed the old `org-hugo--after-export-function` to
  `org-hugo--after-1-export-function`.
- Added new hook function that's called after **all** exports are
  done: `org-hugo--after-all-exports-function`.
  • Loading branch information
kaushalmodi committed Mar 18, 2022
1 parent dd09f72 commit c450ed0
Showing 1 changed file with 59 additions and 20 deletions.
79 changes: 59 additions & 20 deletions ox-hugo.el
Expand Up @@ -155,6 +155,25 @@ Examples:
(defvar org-hugo--trim-post-marker "<!-- trim-post -->"
"Special string to mark where whitespace should be trimmed after an element.")

(defvar org-hugo--opened-buffers '()
"List of buffers opened during an export, which will be auto-closed at the end.
An export operation might need to open files for resolving links
pointing to other Org files or temporary buffers for
pre-processing an Org file. Each buffer opened during an Ox-Hugo
export gets added to this list, and they all are auto-closed at
the end of the export in `org-hugo--after-all-exports-function'.")

(defvar org-hugo--disable-after-all-exports-hook nil
"If set, `org-hugo--after-all-exports-function' function is not called.
This variable is set internally by `org-hugo-export-wim-to-md'
when its ALL-SUBTREES arg is set to a non-nil value.
Setting this to non-nil will lead to slow or incorrect
exports. This variable is for internal use only, and must not be
modified.")

(defconst org-hugo--preprocess-buffer t
"Enable pre-processing of the current Org buffer.
Expand Down Expand Up @@ -811,7 +830,7 @@ This parameter is used in `org-hugo-src-block'.
This advice is added to the ORIG-FUN only while an ox-hugo export
is in progress. See `org-hugo--before-export-function' and
`org-hugo--after-export-function'."
`org-hugo--after-1-export-function'."
(let* ((param-keys-to-be-retained '(:hl_lines :linenos :front_matter_extra))
(info (car args))
(parameters (nth 2 info))
Expand Down Expand Up @@ -861,8 +880,7 @@ https://git.savannah.gnu.org/cgit/emacs/org-mode.git/commit/?id=6b2a7cb20b357e73
"Function to be run before an ox-hugo export.
This function is called in the very beginning of
`org-hugo-export-to-md', `org-hugo-export-as-md' and
`org-hugo-publish-to-md'.
`org-hugo-export-to-md' and `org-hugo-export-as-md'.
SUBTREEP is non-nil for subtree-based exports.
Expand All @@ -873,12 +891,14 @@ This is an internal function."
(advice-add 'org-babel-exp-code :around #'org-hugo--org-babel-exp-code)
(advice-add 'org-babel--string-to-number :override #'org-hugo--org-babel--string-to-number))

(defun org-hugo--after-export-function (info outfile)
"Function to be run after an ox-hugo export.
(defun org-hugo--after-1-export-function (info outfile)
"Function to be run after exporting one post.
This function is called in the very end of
`org-hugo-export-to-md', `org-hugo-export-as-md' and
`org-hugo-publish-to-md'.
The post could be exported using the subtree-based or file-based
method.
This function is called in the end of `org-hugo-export-to-md',
and `org-hugo-export-as-md'.
INFO is a plist used as a communication channel.
Expand All @@ -896,6 +916,19 @@ This is an internal function."
(setq org-hugo--fm nil)
(setq org-hugo--fm-yaml nil))

(defun org-hugo--after-all-exports-function ()
"Function to be run after Ox-Hugo exports all the posts.
This function is called in the end of
`org-hugo-export-wim-to-md', `org-hugo-export-to-md' and
`org-hugo-export-as-md' (if its ALL-SUBTREES arg is non-nil).
This is an internal function."
;; Kill all the buffers opened by during an export.
(dolist (buf org-hugo--opened-buffers)
(kill-buffer buf))
(setq org-hugo--opened-buffers nil))

;;;; HTMLized section number for heading
(defun org-hugo--get-heading-number (heading info &optional toc)
"Return htmlized section number for the HEADING.
Expand Down Expand Up @@ -2278,6 +2311,8 @@ INFO is a plist used as a communication channel."
(unless (file-exists-p org-file)
(error "[org-hugo--search-and-get-anchor] Unable to open Org file `%s'" org-file))
(with-current-buffer (find-file-noselect org-file)
(unless buffer
(add-to-list 'org-hugo--opened-buffers (current-buffer)))
;; `org-mode' needs to be loaded for `org-link-search' to work
;; correctly. Otherwise `org-link-search' returns starting
;; points for incorrect subtrees.
Expand All @@ -2299,8 +2334,7 @@ INFO is a plist used as a communication channel."
(unless (org-export-get-node-property :EXPORT_FILE_NAME elem nil)
(setq anchor (format "#%s" anchor))))
;; (message "[search and get anchor DBG] anchor: %S" anchor)
(unless buffer ;Kill the buffer if it wasn't open already
(kill-buffer (current-buffer))))
)
anchor))

(defun org-hugo-link (link desc info)
Expand Down Expand Up @@ -2717,6 +2751,8 @@ INFO is a plist used as a communication channel."
(id-buffer (get-file-buffer id-file))) ;nil if `id-file' buffer is not already open
;; (message "[org-hugo-link--heading-anchor-maybe DBG] id-loc: %S" id-loc)
(with-current-buffer (or id-buffer (find-file-noselect id-file :nowarn))
(unless id-buffer
(add-to-list 'org-hugo--opened-buffers (current-buffer)))
(org-export-get-environment) ;Eval #+bind keywords, etc.
(goto-char id-pos)
(let* ((elem (org-element-at-point))
Expand All @@ -2726,8 +2762,6 @@ INFO is a plist used as a communication channel."
;; (message "[org-hugo-link--heading-anchor-maybe DBG] elem type: %S" (org-element-type elem))
;; (message "[org-hugo-link--heading-anchor-maybe DBG] elem: %S" elem)
;; (message "[org-hugo-link--heading-anchor-maybe DBG] anchor: %S" anchor)
(unless id-buffer ;Kill the buffer with ID if it wasn't open already
(kill-buffer (current-buffer)))
anchor))))

;;;;; Helpers
Expand Down Expand Up @@ -4443,17 +4477,18 @@ subtree-number being exported.
;; already be pre-processed in
;; `org-hugo-export-wim-to-md', so do not do that again.
(if all-subtrees
(setq ret (org-hugo-export-to-md async :subtreep visible-only))
(let ((org-hugo--disable-after-all-exports-hook t))
(setq ret (org-hugo-export-to-md async :subtreep visible-only)))

;; Do the buffer pre-processing only if the user is
;; exporting only the current valid Hugo post subtree.
(let ((current-outline-path (org-get-outline-path :with-self)))
(if org-hugo--preprocess-buffer
(let ((buffer (org-hugo--get-pre-processed-buffer)))
(with-current-buffer buffer
(add-to-list 'org-hugo--opened-buffers buffer)
(goto-char (org-find-olp current-outline-path :this-buffer))
(setq ret (org-hugo-export-to-md async :subtreep visible-only)))
(kill-buffer buffer))
(setq ret (org-hugo-export-to-md async :subtreep visible-only))))
(progn
(goto-char (org-find-olp current-outline-path :this-buffer))
(setq ret (org-hugo-export-to-md async :subtreep visible-only)))))))))
Expand Down Expand Up @@ -4649,7 +4684,8 @@ Return the buffer the export happened to."
(prog1
(org-export-to-buffer 'hugo "*Org Hugo Export*"
async subtreep visible-only nil nil (lambda () (text-mode)))
(org-hugo--after-export-function info nil))))
(org-hugo--after-1-export-function info nil)
(org-hugo--after-all-exports-function))))

;;;###autoload
(defun org-hugo-export-to-md (&optional async subtreep visible-only)
Expand Down Expand Up @@ -4694,7 +4730,9 @@ Return output file's name."
;; (message "[org-hugo-export-to-md DBG] section-dir = %s" section-dir)
(prog1
(org-export-to-file 'hugo outfile async subtreep visible-only)
(org-hugo--after-export-function info outfile))))
(org-hugo--after-1-export-function info outfile)
(unless org-hugo--disable-after-all-exports-hook
(org-hugo--after-all-exports-function)))))

;;;###autoload
(defun org-hugo-export-wim-to-md (&optional all-subtrees async visible-only noerror)
Expand Down Expand Up @@ -4751,15 +4789,15 @@ The optional argument NOERROR is passed to
(if org-hugo--preprocess-buffer
(let ((buffer (org-hugo--get-pre-processed-buffer)))
(with-current-buffer buffer
(add-to-list 'org-hugo--opened-buffers buffer)
(setq ret (org-map-entries
(lambda ()
(org-hugo--export-subtree-to-md
async visible-only :all-subtrees))
;; Export only the subtrees where
;; EXPORT_FILE_NAME property is not
;; empty.
"EXPORT_FILE_NAME<>\"\""))
(kill-buffer buffer)))
"EXPORT_FILE_NAME<>\"\""))))
(setq ret (org-map-entries
(lambda ()
(org-hugo--export-subtree-to-md
Expand All @@ -4771,7 +4809,8 @@ The optional argument NOERROR is passed to
(message "[ox-hugo] Exported %d subtree%s from %s"
org-hugo--subtree-count
(if (= 1 org-hugo--subtree-count) "" "s")
f-or-b-name))
f-or-b-name)
(org-hugo--after-all-exports-function))

;; Publish only the current valid Hugo post subtree. When
;; exporting only one subtree, buffer pre-processing is done
Expand Down

0 comments on commit c450ed0

Please sign in to comment.