Browse Source

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 <http://lists.gnu.org/archive/html/emacs-orgmode/2019-02/msg00138.html>.
Nicolas Goaziou 8 months ago
parent
commit
6d9022df22
6 changed files with 109 additions and 92 deletions
  1. 2 2
      contrib/lisp/org-drill.el
  2. 12 10
      doc/org-manual.org
  3. 6 0
      etc/ORG-NEWS
  4. 6 0
      lisp/org-compat.el
  5. 2 2
      lisp/org-keys.el
  6. 81 78
      lisp/org.el

+ 2 - 2
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 ()

+ 12 - 10
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
-
-     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.
+- {{{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 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

+ 6 - 0
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

+ 6 - 0
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

+ 2 - 2
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)

+ 81 - 78
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.
-
-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-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))))
+
+(defun org-latex-preview (&optional arg)
+  "Toggle preview of the LaTeX fragment at point.
+
+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 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."
+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