org-latex-preview: Check all fragments produced

* lisp/org-latex-preview.el (org-latex-preview--check-all-fragments-produced):
Create a new callback that checks that each fragment has indeed been
produced not, and if not guesses the last produced fragment caused a
problem.  The last produced fragment is then marked as erroneous,
its cache entry updated (replaced and re-inserted), and the remaining
fragments are regenerated.
(org-latex-preview-create-image-async): Run
`org-latex-preview--check-all-fragments-produced' after successfully
extracting images.
(org-latex-preview--cache-name, org-latex-preview--cache-image,
org-latex-preview--get-cached): Use a defconst instead of hardcoding the
cache container string in `org-latex-preview--cache-image' and
`org-latex-preview--get-cached'.
(org-latex-preview--remove-cached): Easy removal of an item from the
org-persist cache, as a counterpart to `org-latex-preview--cache-image'.
This commit is contained in:
TEC 2023-01-04 01:24:06 +08:00
parent b77f8b6e12
commit b9e0db41ce
Signed by: tec
SSH Key Fingerprint: SHA256:eobz41Mnm0/iYWBvWThftS0ElEs1ftBr6jamutnXc/A
1 changed files with 49 additions and 4 deletions

View File

@ -900,7 +900,9 @@ during processing to hold more information on the fragments."
(img-extract-async (img-extract-async
(org-latex-preview--image-extract-async extended-info))) (org-latex-preview--image-extract-async extended-info)))
(plist-put (cddr img-extract-async) :success (plist-put (cddr img-extract-async) :success
(list #'org-latex-preview--cleanup-callback)) (list ; The order is important here.
#'org-latex-preview--check-all-fragments-produced
#'org-latex-preview--cleanup-callback))
(pcase processing-type (pcase processing-type
('dvipng ('dvipng
(plist-put (cddr img-extract-async) :filter (plist-put (cddr img-extract-async) :filter
@ -1082,6 +1084,40 @@ The path of the created LaTeX file is returned."
(when (file-exists-p (concat basename ext)) (when (file-exists-p (concat basename ext))
(delete-file (concat basename ext)))))) (delete-file (concat basename ext))))))
(defun org-latex-preview--check-all-fragments-produced (_exit-code _stdout extended-info)
"Check each of the fragments in EXTENDED-INFO has a path.
Should this not be the case, the fragment immediately before the first
fragment without a path is marked as erronious, and the remaining
fragments are regenerated."
(let ((fragments (cons nil (copy-sequence (plist-get extended-info :fragments)))))
(while (cdr fragments)
(if (or (plist-get (cadr fragments) :path)
(plist-get (cadr fragments) :error))
(setq fragments (cdr fragments))
;; If output ends prematurely, this is most likely due to an issue with
;; the last "succesfully" produced fragment, and so we mark it as erronious
;; and attempt to re-generate the rest.
(let ((bad-fragment (car fragments))
(bad-fragment-err (plist-get (car fragments) :errors)))
(plist-put bad-fragment :errors
(concat bad-fragment-err
(and bad-fragment-err "\n\n")
"Preview generation catastrophically failed after this fragment."))
(org-latex-preview--remove-cached
(plist-get bad-fragment :key))
(org-latex-preview--update-overlay
(plist-get bad-fragment :overlay)
(org-latex-preview--cache-image
(plist-get bad-fragment :key)
(plist-get bad-fragment :path)
(org-latex-preview--display-info
extended-info bad-fragment))))
;; Re-generate the remaining fragments.
(org-latex-preview-create-image-async
(plist-get extended-info :processor)
(cdr fragments))
(setq fragments nil)))))
(defun org-latex-preview--display-info (extended-info fragment-info) (defun org-latex-preview--display-info (extended-info fragment-info)
"From FRAGMENT-INFO and EXTENDED-INFO obtain display-relevant information." "From FRAGMENT-INFO and EXTENDED-INFO obtain display-relevant information."
(let ((image-type (intern (plist-get extended-info :image-output-type))) (let ((image-type (intern (plist-get extended-info :image-output-type)))
@ -1282,14 +1318,17 @@ listed in EXTENDED-INFO will be used."
(org-latex-preview--display-info (org-latex-preview--display-info
extended-info fragment-info)))))))) extended-info fragment-info))))))))
(defconst org-latex-preview--cache-name "LaTeX preview cached image data"
"The name used for Org LaTeX Preview objects in the org-persist cache.")
(defun org-latex-preview--cache-image (key path info) (defun org-latex-preview--cache-image (key path info)
"Save the image at PATH with associated INFO in the cache indexed by KEY. "Save the image at PATH with associated INFO in the cache indexed by KEY.
Return (path . info)." Return (path . info)."
(let ((label-path-info (let ((label-path-info
(or (org-persist-read "LaTeX preview cached image data" (or (org-persist-read org-latex-preview--cache-name
(list :key key) (list :key key)
nil nil :read-related t) nil nil :read-related t)
(org-persist-register `("LaTeX preview cached image data" (org-persist-register `(,org-latex-preview--cache-name
(file ,path) (file ,path)
(elisp-data ,info)) (elisp-data ,info))
(list :key key) (list :key key)
@ -1308,12 +1347,18 @@ Example result:
:depth 0.2 :depth 0.2
:errors nil)" :errors nil)"
(when-let ((label-path-info (when-let ((label-path-info
(org-persist-read "LaTeX preview cached image data" (org-persist-read org-latex-preview--cache-name
(list :key key) (list :key key)
nil nil :read-related t))) nil nil :read-related t)))
(cons (cadr label-path-info) (cons (cadr label-path-info)
(caddr label-path-info)))) (caddr label-path-info))))
(defun org-latex-preview--remove-cached (key)
"Remove the fragment cache associated with KEY."
(org-persist-unregister org-latex-preview--cache-name
(list :key key)
:remove-related t))
;; TODO: Switching processes from imagemagick to dvi* with an existing ;; TODO: Switching processes from imagemagick to dvi* with an existing
;; dump-file during a single Emacs session should trigger ;; dump-file during a single Emacs session should trigger
;; re-precompilation with the new precompile command. ;; re-precompilation with the new precompile command.