From 6d9022df22f86e8b0ea00dfb9179128136edc49a Mon Sep 17 00:00:00 2001 From: Nicolas Goaziou Date: Wed, 13 Feb 2019 23:52:13 +0100 Subject: [PATCH] Make LaTeX preview toggle more useful and predictable * lisp/org.el (org-remove-highlights-with-change): (org-mode): Update. (org--format-latex-make-overlay): (org--list-latex-overlays): Remove functions. (org--make-preview-overlay): (org-clear-latex-preview): (org--latex-preview-region): (org-latex-preview): New functions. (org-format-latex): Use new function * lisp/org-compat.el (org-toggle-latex-fragment): (org-remove-latex-fragment-image-overlays): Deprecate. * doc/org-manual.org (Previewing LaTeX fragments): Update documentation about `org-latex-preview'. See . --- contrib/lisp/org-drill.el | 4 +- doc/org-manual.org | 20 ++--- etc/ORG-NEWS | 6 ++ lisp/org-compat.el | 6 ++ lisp/org-keys.el | 4 +- lisp/org.el | 157 +++++++++++++++++++------------------- 6 files changed, 107 insertions(+), 90 deletions(-) diff --git a/contrib/lisp/org-drill.el b/contrib/lisp/org-drill.el index 6f9a8a323..1c115157d 100644 --- a/contrib/lisp/org-drill.el +++ b/contrib/lisp/org-drill.el @@ -1874,7 +1874,7 @@ Note: does not actually alter the item." (defun org-drill--show-latex-fragments () - (org-remove-latex-fragment-image-overlays) + (org-clear-latex-preview) (if (fboundp 'org-toggle-latex-fragment) (org-toggle-latex-fragment '(4)) (org-preview-latex-fragment '(4)))) @@ -2273,7 +2273,7 @@ See `org-drill' for more details." (funcall answer-fn (lambda () (org-drill-reschedule)))))))) (run-hook-with-args 'org-drill-entry-after-hook) - (org-remove-latex-fragment-image-overlays))))))) + (org-clear-latex-preview))))))) (defun org-drill-entries-pending-p () diff --git a/doc/org-manual.org b/doc/org-manual.org index a79bd60da..96a914787 100644 --- a/doc/org-manual.org +++ b/doc/org-manual.org @@ -10810,16 +10810,18 @@ In particular, the ~:scale~ (and for HTML export, ~:html-scale~) property of the former can be used to adjust the size of the preview images. -- {{{kbd(C-c C-x C-l)}}} (~org-toggle-latex-fragment~) :: - #+kindex: C-c C-x C-l - #+findex: org-toggle-latex-fragment +- {{{kbd(C-c C-x C-l)}}} (~org-latex-preview~) :: + #+kindex: C-c C-x C-l + #+findex: org-latex-preview - Produce a preview image of the LaTeX fragment at point and - overlay it over the source code. If there is no fragment at - point, process all fragments in the current entry (between two - headlines). When called with a prefix argument, process the - entire subtree. When called with two prefix arguments, or when - point is before the first headline, process the entire buffer. + Produce a preview image of the LaTeX fragment at point and overlay + it over the source code. If there is no fragment at point, process + all fragments in the current entry -- between two headlines. + + When called with a single prefix argument, clear all images in the + current entry. Two prefix arguments produce a preview image for all + fragments in the buffer, while three of them clear all the images in + that buffer. #+vindex: org-startup-with-latex-preview You can turn on the previewing of all LaTeX fragments in a file with diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS index bf14412fd..057440a71 100644 --- a/etc/ORG-NEWS +++ b/etc/ORG-NEWS @@ -136,6 +136,12 @@ dynamic block in ~org-dynamic-block-alist~. It was unused throughout the code base. ** Miscellaneous +*** LaTeX preview is simplified + +Function ~org-latex-preview~, formerly known as +~org-toggle-latex-fragment~, has a hopefully simpler and more +predictable behavior. See its docstring for details. + *** No more special indentation for description items Descriptions items are indented like regular ones, i.e., text starts diff --git a/lisp/org-compat.el b/lisp/org-compat.el index 6788a70be..4690d429f 100644 --- a/lisp/org-compat.el +++ b/lisp/org-compat.el @@ -257,6 +257,12 @@ Counting starts at 1." (define-obsolete-variable-alias 'org-effort-durations 'org-duration-units "Org 9.2") +(define-obsolete-function-alias 'org-toggle-latex-fragment 'org-latex-preview + "Org 9.3") + +(define-obsolete-function-alias 'org-remove-latex-fragment-image-overlays + 'org-clear-latex-preview "Org 9.3") + (defun org-in-fixed-width-region-p () "Non-nil if point in a fixed-width region." (save-match-data diff --git a/lisp/org-keys.el b/lisp/org-keys.el index 2998e9d77..d103957a9 100644 --- a/lisp/org-keys.el +++ b/lisp/org-keys.el @@ -195,7 +195,7 @@ (declare-function org-toggle-comment "org" ()) (declare-function org-toggle-fixed-width "org" ()) (declare-function org-toggle-inline-images "org" (&optional include-linked)) -(declare-function org-toggle-latex-fragment "org" (&optional arg)) +(declare-function org-latex-preview "org" (&optional arg)) (declare-function org-toggle-narrow-to-subtree "org" ()) (declare-function org-toggle-ordered-property "org" ()) (declare-function org-toggle-pretty-entities "org" ()) @@ -647,7 +647,7 @@ COMMANDS is a list of alternating OLDDEF NEWDEF command names." (org-defkey org-mode-map (kbd "C-c C-x C-d") #'org-clock-display) (org-defkey org-mode-map (kbd "C-c C-x x") #'org-dynamic-block-insert-dblock) (org-defkey org-mode-map (kbd "C-c C-x C-u") #'org-dblock-update) -(org-defkey org-mode-map (kbd "C-c C-x C-l") #'org-toggle-latex-fragment) +(org-defkey org-mode-map (kbd "C-c C-x C-l") #'org-latex-preview) (org-defkey org-mode-map (kbd "C-c C-x C-v") #'org-toggle-inline-images) (org-defkey org-mode-map (kbd "C-c C-x C-M-v") #'org-redisplay-inline-images) (org-defkey org-mode-map (kbd "C-c C-x \\") #'org-toggle-pretty-entities) diff --git a/lisp/org.el b/lisp/org.el index f13d5287f..9b1e3ad18 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -1635,8 +1635,8 @@ changed by an edit command." Such highlights are created by `org-occur' and `org-clock-display'. When nil, `\\[org-ctrl-c-ctrl-c]' needs to be used \ to get rid of the highlights. -The highlights created by `org-toggle-latex-fragment' always need -`\\[org-toggle-latex-fragment]' to be removed." +The highlights created by `org-latex-preview' always need +`\\[org-latex-preview]' to be removed." :group 'org-sparse-trees :group 'org-time :type 'boolean) @@ -5443,7 +5443,7 @@ The following commands are available: (t #'org-table-shrink)) t)) (when org-startup-with-inline-images (org-display-inline-images)) - (when org-startup-with-latex-preview (org-toggle-latex-fragment '(16))) + (when org-startup-with-latex-preview (org-latex-preview '(16))) (unless org-inhibit-startup-visibility-stuff (org-set-startup-visibility)) (when org-startup-truncated (setq truncate-lines t)) (when org-startup-indented (require 'org-indent) (org-indent-mode 1)))) @@ -18018,7 +18018,7 @@ looks only before point, not after." (org-in-regexp "\\\\[a-zA-Z]+\\*?\\(\\(\\[[^][\n{}]*\\]\\)\\|\\({[^{}\n]*}\\)\\)*"))) -(defun org--format-latex-make-overlay (beg end image &optional imagetype) +(defun org--make-preview-overlay (beg end image &optional imagetype) "Build an overlay between BEG and END using IMAGE file. Argument IMAGETYPE is the extension of the displayed image, as a string. It defaults to \"png\"." @@ -18034,88 +18034,91 @@ as a string. It defaults to \"png\"." 'display (list 'image :type imagetype :file image :ascent 'center)))) -(defun org--list-latex-overlays (&optional beg end) - "List all Org LaTeX overlays in current buffer. -Limit to overlays between BEG and END when those are provided." - (cl-remove-if-not - (lambda (o) (eq (overlay-get o 'org-overlay-type) 'org-latex-overlay)) - (overlays-in (or beg (point-min)) (or end (point-max))))) - -(defun org-remove-latex-fragment-image-overlays (&optional beg end) +(defun org-clear-latex-preview (&optional beg end) "Remove all overlays with LaTeX fragment images in current buffer. When optional arguments BEG and END are non-nil, remove all overlays between them instead. Return a non-nil value when some overlays were removed, nil otherwise." - (let ((overlays (org--list-latex-overlays beg end))) + (let ((overlays + (cl-remove-if-not + (lambda (o) (eq (overlay-get o 'org-overlay-type) 'org-latex-overlay)) + (overlays-in (or beg (point-min)) (or end (point-max)))))) (mapc #'delete-overlay overlays) overlays)) -(defun org-toggle-latex-fragment (&optional arg) - "Preview the LaTeX fragment at point, or all locally or globally. +(defun org--latex-preview-region (beg end) + "Preview LaTeX fragments between BEG and END. +BEG and END are buffer positions." + (let ((file (buffer-file-name (buffer-base-buffer)))) + (save-excursion + (org-format-latex + (concat org-preview-latex-image-directory "org-ltximg") + beg end + ;; Emacs cannot overlay images from remote hosts. Create it in + ;; `temporary-file-directory' instead. + (if (or (not file) (file-remote-p file)) + temporary-file-directory + default-directory) + 'overlays nil 'forbuffer org-preview-latex-default-process)))) -If the cursor is on a LaTeX fragment, create the image and overlay -it over the source code, if there is none. Remove it otherwise. -If there is no fragment at point, display all fragments in the -current section. +(defun org-latex-preview (&optional arg) + "Toggle preview of the LaTeX fragment at point. -With prefix ARG, preview or clear image for all fragments in the -current subtree or in the whole buffer when used before the first -headline. With a prefix ARG `\\[universal-argument] \ -\\[universal-argument]' preview or clear images -for all fragments in the buffer." +If the cursor is on a LaTeX fragment, create the image and +overlay it over the source code, if there is none. Remove it +otherwise. If there is no fragment at point, display images for +all fragments in the current section. + +With a `\\[universal-argument]' prefix argument ARG, clear images \ +for all fragments +in the current section. + +With a `\\[universal-argument] \\[universal-argument]' prefix \ +argument ARG, display image for all +fragments in the buffer. + +With a `\\[universal-argument] \\[universal-argument] \ +\\[universal-argument]' prefix argument ARG, clear image for all +fragments in the buffer." (interactive "P") - (when (display-graphic-p) - (catch 'exit - (save-excursion - (let (beg end msg) - (cond - ((or (equal arg '(16)) - (and (equal arg '(4)) - (org-with-limited-levels (org-before-first-heading-p)))) - (if (org-remove-latex-fragment-image-overlays) - (progn (message "LaTeX fragments images removed from buffer") - (throw 'exit nil)) - (setq msg "Creating images for buffer..."))) - ((equal arg '(4)) - (org-with-limited-levels (org-back-to-heading t)) - (setq beg (point)) - (setq end (progn (org-end-of-subtree t) (point))) - (if (org-remove-latex-fragment-image-overlays beg end) - (progn - (message "LaTeX fragment images removed from subtree") - (throw 'exit nil)) - (setq msg "Creating images for subtree..."))) - ((let ((datum (org-element-context))) - (when (memq (org-element-type datum) - '(latex-environment latex-fragment)) - (setq beg (org-element-property :begin datum)) - (setq end (org-element-property :end datum)) - (if (org-remove-latex-fragment-image-overlays beg end) - (progn (message "LaTeX fragment image removed") - (throw 'exit nil)) - (setq msg "Creating image..."))))) - (t - (org-with-limited-levels - (setq beg (if (org-at-heading-p) (line-beginning-position) - (outline-previous-heading) - (point))) - (setq end (progn (outline-next-heading) (point))) - (if (org-remove-latex-fragment-image-overlays beg end) - (progn - (message "LaTeX fragment images removed from section") - (throw 'exit nil)) - (setq msg "Creating images for section..."))))) - (let ((file (buffer-file-name (buffer-base-buffer)))) - (org-format-latex - (concat org-preview-latex-image-directory "org-ltximg") - beg end - ;; Emacs cannot overlay images from remote hosts. Create - ;; it in `temporary-file-directory' instead. - (if (or (not file) (file-remote-p file)) - temporary-file-directory - default-directory) - 'overlays msg 'forbuffer org-preview-latex-default-process)) - (message (concat msg "done"))))))) + (cond + ((not (display-graphic-p)) nil) + ;; Clear whole buffer. + ((equal arg '(64)) + (org-clear-latex-preview (point-min) (point-max)) + (message "LaTeX previews removed from buffer")) + ;; Preview whole buffer. + ((equal arg '(16)) + (message "Creating LaTeX previews in buffer...") + (org--latex-preview-region (point-min) (point-max)) + (message "Creating LaTeX previews in buffer... done.")) + ;; Clear current section. + ((equal arg '(4)) + (org-clear-latex-preview + (if (org-before-first-heading-p) (point-min) + (save-excursion + (org-with-limited-levels (org-back-to-heading t) (point)))) + (org-with-limited-levels (org-entry-end-position)))) + ;; Toggle preview on LaTeX code at point. + ((let ((datum (org-element-context))) + (and (memq (org-element-type datum) '(latex-environment latex-fragment)) + (let ((beg (org-element-property :begin datum)) + (end (org-element-property :end datum))) + (if (org-clear-latex-preview beg end) + (message "LaTeX preview removed") + (message "Creating LaTeX preview...") + (org--latex-preview-region beg end) + (message "Creating LaTeX preview... done.")) + t)))) + ;; Preview current section. + (t + (let ((beg (if (org-before-first-heading-p) (point-min) + (save-excursion + (org-with-limited-levels (org-back-to-heading t) (point))))) + (end (org-with-limited-levels (org-entry-end-position)))) + (message "Creating LaTeX previews in section...") + (org--latex-preview-region beg end) + (message "Creating LaTeX previews in section... done."))))) (defun org-format-latex (prefix &optional beg end dir overlays msg forbuffer processing-type) @@ -18216,7 +18219,7 @@ Some of the options can be changed using the variable (when (eq (overlay-get o 'org-overlay-type) 'org-latex-overlay) (delete-overlay o))) - (org--format-latex-make-overlay beg end movefile imagetype) + (org--make-preview-overlay beg end movefile imagetype) (goto-char end)) (delete-region beg end) (insert