org-bibtex-import-from-file: Improve performance

* lisp/ol-bibtex.el (org-bibtex-put): Add new optional argument to
insert node property at point directly, without leveraging
`org-set-property'.  Add docstring.
(org-bibtex-write): Insert headline properties directly.  Add new
optional argument to suppress indentation.  Do not use `length' to
check if `org-bibtex-entries' list empty---`length' is too slow on
large lists.
(org-bibtex-import-from-file): Postpone indentation after all the
entries are imported.
* lisp/org.el (org-indent-region): Use cache.
This commit is contained in:
Ihor Radchenko 2022-08-27 12:09:31 +08:00
parent 372788a189
commit 5ba90e161b
No known key found for this signature in database
GPG Key ID: 6470762A7DA11D8B
2 changed files with 39 additions and 22 deletions

View File

@ -344,14 +344,20 @@ and `org-tags-exclude-from-inheritance'."
(upcase property)))))))
(when it (org-trim it))))
(defun org-bibtex-put (property value)
(let ((prop (upcase (if (keywordp property)
(substring (symbol-name property) 1)
property))))
(org-set-property
(concat (unless (string= org-bibtex-key-property prop) org-bibtex-prefix)
prop)
value)))
(defun org-bibtex-put (property value &optional insert-raw)
"Set PROPERTY of headline at point to VALUE.
The PROPERTY will be prefixed with `org-bibtex-prefix' when necessary.
With non-nil optional argument INSERT-RAW, insert node property string
at point."
(let* ((prop (upcase (if (keywordp property)
(substring (symbol-name property) 1)
property)))
(prop (concat (unless (string= org-bibtex-key-property prop)
org-bibtex-prefix)
prop)))
(if insert-raw
(insert (format ":%s: %s\n" prop value))
(org-set-property prop value))))
(defun org-bibtex-headline ()
"Return a bibtex entry of the given headline as a string."
@ -703,10 +709,12 @@ Return the number of saved entries."
(interactive "fFile: ")
(org-bibtex-read-buffer (find-file-noselect file 'nowarn 'rawfile)))
(defun org-bibtex-write ()
"Insert a heading built from the first element of `org-bibtex-entries'."
(defun org-bibtex-write (&optional noindent)
"Insert a heading built from the first element of `org-bibtex-entries'.
When optional argument NOINDENT is non-nil, do not indent the properties
drawer."
(interactive)
(when (= (length org-bibtex-entries) 0)
(unless org-bibtex-entries
(error "No entries in `org-bibtex-entries'"))
(let* ((entry (pop org-bibtex-entries))
(org-special-properties nil) ; avoids errors with `org-entry-put'
@ -714,14 +722,16 @@ Return the number of saved entries."
(togtag (lambda (tag) (org-toggle-tag tag 'on))))
(org-insert-heading)
(insert (funcall org-bibtex-headline-format-function entry))
(org-bibtex-put "TITLE" (funcall val :title))
(insert "\n:PROPERTIES:\n")
(org-bibtex-put "TITLE" (funcall val :title) 'insert)
(org-bibtex-put org-bibtex-type-property-name
(downcase (funcall val :type)))
(downcase (funcall val :type))
'insert)
(dolist (pair entry)
(pcase (car pair)
(:title nil)
(:type nil)
(:key (org-bibtex-put org-bibtex-key-property (cdr pair)))
(:key (org-bibtex-put org-bibtex-key-property (cdr pair) 'insert))
(:keywords (if org-bibtex-tags-are-keywords
(dolist (kw (split-string (cdr pair) ", *"))
(funcall
@ -729,9 +739,14 @@ Return the number of saved entries."
(replace-regexp-in-string
"[^[:alnum:]_@#%]" ""
(replace-regexp-in-string "[ \t]+" "_" kw))))
(org-bibtex-put (car pair) (cdr pair))))
(_ (org-bibtex-put (car pair) (cdr pair)))))
(mapc togtag org-bibtex-tags)))
(org-bibtex-put (car pair) (cdr pair) 'insert)))
(_ (org-bibtex-put (car pair) (cdr pair) 'insert))))
(insert ":END:\n")
(mapc togtag org-bibtex-tags)
(unless noindent
(org-indent-region
(save-excursion (org-back-to-heading t) (point))
(point)))))
(defun org-bibtex-yank ()
"If kill ring holds a bibtex entry yank it as an Org headline."
@ -745,10 +760,12 @@ Return the number of saved entries."
(defun org-bibtex-import-from-file (file)
"Read bibtex entries from FILE and insert as Org headlines after point."
(interactive "fFile: ")
(dotimes (_ (org-bibtex-read-file file))
(save-excursion (org-bibtex-write))
(re-search-forward org-property-end-re)
(open-line 1) (forward-char 1)))
(let ((pos (point)))
(dotimes (i (org-bibtex-read-file file))
(save-excursion (org-bibtex-write 'noindent))
(re-search-forward org-property-end-re)
(insert "\n"))
(org-indent-region pos (point))))
(defun org-bibtex-export-to-kill-ring ()
"Export current headline to kill ring as bibtex entry."

View File

@ -18734,7 +18734,7 @@ assumed to be significant there."
(end (copy-marker end)))
(while (< (point) end)
(if (or (looking-at-p " \r\t\n") (org-at-heading-p)) (forward-line)
(let* ((element (org-element-at-point-no-context))
(let* ((element (org-element-at-point))
(type (org-element-type element))
(element-end (copy-marker (org-element-property :end element)))
(ind (org--get-expected-indentation element nil)))