emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/preview-auto 0887964888 12/36: clean up, add readme


From: ELPA Syncer
Subject: [elpa] externals/preview-auto 0887964888 12/36: clean up, add readme
Date: Thu, 6 Jun 2024 03:59:52 -0400 (EDT)

branch: externals/preview-auto
commit 08879648884fc4ff06461a4b6c0e05f5fe2e7051
Author: Paul Nelson <ultrono@gmail.com>
Commit: Paul Nelson <ultrono@gmail.com>

    clean up, add readme
---
 README.org      |  91 ++++++++++++++++++++++++++++++++++++++++
 preview-auto.el | 128 +++++++++++++++++++++++++++++++-------------------------
 2 files changed, 162 insertions(+), 57 deletions(-)

diff --git a/README.org b/README.org
new file mode 100644
index 0000000000..ed927e447c
--- /dev/null
+++ b/README.org
@@ -0,0 +1,91 @@
+#+title: preview-auto.el: Automatic previews in AUCTeX
+#+author: Paul Nelson
+
+* Overview
+The 
[[https://www.gnu.org/software/auctex/manual/preview-latex/Introduction.html#Introduction][introduction]]
 to the =preview= manual reads as follows:
+
+#+begin_quote
+Does your neck hurt from turning between previewer windows and the source too 
often? This AUCTeX component will render your displayed LaTeX equations right 
into the editing window where they belong.
+
+The purpose of preview-latex is to embed LaTeX environments such as display 
math or figures into the source buffers and switch conveniently between source 
and image representation.
+#+end_quote
+
+AUCTeX provides commands for generating previews in various regions: the 
current section, the entire document, the marked region, and so on.  While 
these previews generate, you're not supposed to edit while the previews 
generate, because that can mess up their positioning.  A typical workflow is 
thus to run the command =preview-section= (=C-c C-p C-s=) every few minutes, 
during pauses in editing.  This introduces a bit of overhead if you prefer to 
have previews on by default.
+
+This package provides a minor mode =preview-auto-mode= in which the visible 
portion of an AUCTeX buffer is continuously previewed.  It can be toggled via 
the command =M-x preview-auto-mode=, the keybinding =C-c C-p C-a=, or the 
=Preview= menu.
+
+* Configuration
+This package requires 
[[https://www.gnu.org/software/auctex/manual/auctex/Installation.html#Installation][AUCTeX]],
 so install that first, and check that the 
[[https://www.gnu.org/software/auctex/manual/preview-latex/index.html#Top][preview-latex]]
 feature of AUCTeX works.
+
+Download this repository, install using =M-x package-install-file= (or 
package-vc-install, straight, elpaca, ...), and add something like the 
following to your [[https://www.emacswiki.org/emacs/InitFile][init file]]:
+#+begin_src elisp
+(use-package preview-auto)
+#+end_src
+
+Customization options can be discovered via =M-x customize-group preview-auto=.
+
+** Recommended AUCTeX settings
+We recommend the following AUCTeX settings.
+#+begin_src elisp
+(setq preview-locating-previews-message nil)
+(setq preview-protect-point t)
+(setq preview-leave-open-previews-visible t)
+#+end_src
+
+** Optimization
+The following setting makes preview always use DVI's, which generate faster 
than PDF's:
+#+begin_src elisp
+(setq preview-LaTeX-command-replacements '(preview-LaTeX-disable-pdfoutput))
+#+end_src
+If you use a package such as =hyperref= that works only with PDF's, then you 
should replace =\usepackage{hyperref}= in your TeX file with something like the 
following:
+#+begin_src latex
+\usepackage{ifpdf}
+\ifpdf \usepackage{hyperref} \fi
+#+end_src
+
+** Always enable
+If you want =preview-auto-mode= to activate automatically when you visit a tex 
file (but not when you visit a bbl file), then use the following config:
+#+begin_src elisp
+(use-package preview-auto
+  :hook
+  (LaTeX-mode . czm-preview-mode-conditionally-enable))
+#+end_src
+
+** My setup
+I use something like the following =use-package= declaration:
+#+begin_src elisp
+(use-package preview-auto
+  :after latex
+  :config
+  (setq preview-protect-point t)
+  (setq preview-locating-previews-message nil)
+  (setq preview-leave-open-previews-visible t)
+  :custom
+  (preview-auto-interval 0.1)
+  (preview-LaTeX-command-replacements
+   '(preview-LaTeX-disable-pdfoutput)))  
+#+end_src
+
+My precise current setup may be found in 
[[https://github.com/ultronozm/emacsd/blob/main/init-latex.el][the LaTeX part 
of my config]] (=elpaca= branch).
+
+* Non-file buffers
+This package works fine in non-file buffers running =LaTeX-mode=, provided 
that you set the local variable =TeX-master= to the name of a valid tex file 
containing all the macros that you use.
+
+* tikzpicture support
+According to section B.4.5 of the =preview-latex= info manual, support for the 
tikzpicture environment can be enabled by adding the following lines to your 
document preamble:
+#+begin_src latex
+\usepackage[displaymath,sections,graphics,floats,textmath]{preview}
+\PreviewEnvironment[{[]}]{tikzpicture}
+#+end_src
+If you want =preview-auto-mode= to preview such environments automatically 
(including when they are not wrapped in some math environment), then you should 
add "tikzpicture" to the customizable list variable 
=preview-auto--extra-environments=, e.g., by putting
+#+begin_src elisp
+(add-to-list 'preview-auto--extra-environments "tikzpicture")
+#+end_src
+in your config.  I keep this disabled by default because of the extra setup 
required in the document preamble, without which =preview-latex= would return 
"LaTeX found no preview images" errors.
+
+* Issues
+- Sometimes the preview command run by the timer produces the same error over 
and over again, effectively locking Emacs.  If this happens, you should hold 
down =C-g= until the timer dies.  Then, try using =preview= "normally" and sort 
out the erorrs.  Finally, toggle =preview-auto-mode=.
+  
+- When the timer provided by =preview-auto= fires, it clears the minibuffer.  
This is because =inhibit-message= is used surrounding a call to =write-region= 
to prevent flooding the minibuffer with "Wrote..." messages, but messages sent 
under =inhibit-message= still clear the minibuffer.  This can be a bit annoying 
if you are looking at the minibuffer for some other reason (e.g., Flymake) 
while the =preview-auto= timer is firing a bunch.  Fixing this would require 
tweaking AUCTeX's intern [...]
+
+- Very rarely, I've seen some =preview-latex= process (e.g., Ghostscript) gets 
stuck.  The symptom is that =preview-auto= will not generate anything, even 
after resetting the mode.  You can check if this has happened using =M-: 
(get-buffer-process (TeX-process-buffer-name (TeX-region-file)))=.  The fix is 
then to navigate to the =_region_.tex= buffer and do =M-x TeX-kill-job=.
diff --git a/preview-auto.el b/preview-auto.el
index 06bebcb75a..01a7370a12 100644
--- a/preview-auto.el
+++ b/preview-auto.el
@@ -3,7 +3,7 @@
 ;; Copyright (C) 2024  Paul D. Nelson
 
 ;; Author: Paul D. Nelson <nelson.paul.david@gmail.com>
-;; Version: 0.0
+;; Version: 0.1
 ;; URL: https://github.com/ultronozm/preview-auto.el
 ;; Package-Requires: ((emacs "26.1") (auctex "14.0.5"))
 ;; Keywords: tex, convenience
@@ -55,7 +55,7 @@ For this to have any effect, it must be set before
   "Controls how many characters above point to preview."
   :type 'integer)
 
-(defcustom preview-auto-chars-below 10000
+(defcustom preview-auto-chars-below 6000
   "Controls how many characters below point to preview."
   :type 'integer)
 
@@ -64,29 +64,11 @@ For this to have any effect, it must be set before
 (defvar-local preview-auto--keepalive t
   "Used to keep track of when we should preview some more.")
 
-(defcustom preview-auto-rules-function nil
-  "Function to generate rules for identifying math environments.
-If non-nil, `preview-auto--generate-rules' delegates to this function.
-The function should return a list of rules for identifying math
-environments, as described in the documentation of
-`preview-auto--generate-rules'."
-  :type '(choice (const :tag "Default" nil) function))
-
 (defcustom preview-auto--extra-environments nil
   "Extra environments to consider for automatic previewing."
   :type '(repeat string))
 
-(defvar preview-auto--rules nil
-  "Rules for identifying math environments.
-Each rule is an iterated cons cell ((BEGIN . END) . PREDICATE), where
-BEGIN and END are the delimiters and PREDICATE is a function, called
-just beyond the BEGIN delimiter, that returns non-nil if the environment
-is valid.")
-
-(defvar preview-auto--begin-re nil
-  "Regular expression for identifying the beginning of a math environment.")
-
-(defun preview-auto--cheap-texmathp ()
+(defun preview-auto--math-p ()
   "Return non-nil if point is in a math environment.
 Should work in AUCTeX `LaTeX-mode' buffers.  Implemented using
 `font-latex-math-face'."
@@ -99,23 +81,31 @@ Should work in AUCTeX `LaTeX-mode' buffers.  Implemented 
using
 
 (defun preview-auto--generate-rules ()
   "Return list of rules for identifying math environments."
-  (if preview-auto-rules-function
-      (funcall preview-auto-rules-function)
-    (let* ((basic-rules
-            (mapcar (lambda (pair)
-                      (cons (car pair)
-                            (cons (cdr pair) '(preview-auto--cheap-texmathp))))
-                    '(("$" . "$") ("$$" . "$$") ("\\(" . "\\)") ("\\[" . 
"\\]"))))
-           (env-rules
-            (mapcar (lambda (env)
-                      (cons (format "\\begin{%s}" env)
-                            (cons (format "\\end{%s}" env) t)))
-                    (append texmathp-environments
-                            preview-auto--extra-environments)))
-           (rules (append basic-rules env-rules)))
-      rules)))
-
-(defun preview-auto--cheap-comment ()
+  (let* ((basic-rules
+          (mapcar (lambda (pair)
+                    (cons (car pair)
+                          (cons (cdr pair) '(preview-auto--math-p))))
+                  '(("$" . "$") ("$$" . "$$") ("\\(" . "\\)") ("\\[" . 
"\\]"))))
+         (env-rules
+          (mapcar (lambda (env)
+                    (cons (format "\\begin{%s}" env)
+                          (cons (format "\\end{%s}" env) t)))
+                  (append texmathp-environments
+                          preview-auto--extra-environments)))
+         (rules (append basic-rules env-rules)))
+    rules))
+
+(defvar-local preview-auto--rules nil
+  "Rules for identifying math environments.
+Each rule is an iterated cons cell ((BEGIN . END) . PREDICATE), where
+BEGIN and END are the delimiters and PREDICATE is a function, called
+just beyond the BEGIN delimiter, that returns non-nil if the environment
+is valid.")
+
+(defvar-local preview-auto--begin-re nil
+  "Regular expression for identifying the beginning of a math environment.")
+
+(defun preview-auto--comment-p ()
   "Return non-nil if point is in a comment or verbatim environment.
 Implemented using font-lock faces."
   (let ((comment-faces '(font-lock-comment-face
@@ -133,7 +123,7 @@ Implemented using font-lock faces."
 Ignore comments and verbatim environments."
   (catch 'found
     (while (re-search-forward regexp bound t)
-      (when (not (preview-auto--cheap-comment))
+      (when (not (preview-auto--comment-p))
         (throw 'found (point))))))
 
 (defcustom preview-auto-refresh-after-compilation t
@@ -143,6 +133,11 @@ the result is that preview equation numbers are updated 
automatically to
 the correct form."
   :type 'boolean)
 
+(defconst preview-auto--refresh-delay '(0 1)
+  "Delay in seconds before refreshing previews after compilation.
+This is used to avoid refreshing previews while the aux file is in some
+intermediate state.")
+
 (defun preview-auto--tex-fold-at (&optional pos)
   "Return non-nil when there is a tex-fold at POS."
   (cl-some
@@ -164,11 +159,14 @@ more recently than the aux file."
           (let* ((image (overlay-get ov 'preview-image))
                  (image-file (nth 1 image))
                  (image-time (nth 5 (file-attributes image-file)))
-                 (aux-file (TeX-master-file "aux"))
+                 (aux-file (TeX-master-output-file "aux"))
                  (aux-time (nth 5 (file-attributes aux-file))))
             (or (null image-time)
                 (null aux-time)
-                (time-less-p aux-time image-time))))))
+                (time-less-p aux-time image-time)
+                (time-less-p (current-time)
+                             (time-add aux-time
+                                       preview-auto--refresh-delay)))))))
    (overlays-at (or pos (point)))))
 
 (defcustom preview-auto-predicate nil
@@ -309,10 +307,6 @@ otherwise from END."
   "Return last maximal valid region for previewing between BEG and END."
   (preview-auto--get-valid-region beg end nil))
 
-(defvar preview-auto--inhibit-message t
-  "If non-nil, inhibit messages in `preview-auto--preview-something'.
-It can be useful to turn this off when using edebug.")
-
 (defvar preview-auto--debug nil
   "If non-nil, print debug messages.")
 
@@ -326,11 +320,22 @@ It can be useful to turn this off when using edebug.")
        (apply #'format format-string args))
       (insert "\n"))))
 
+(defun preview-auto--silent-write-region (orig-fun &rest args)
+  "Like `write-region', but suppresses messages.
+Imperfection: still causes current message to disappear."
+  (let ((noninteractive t)
+        (inhibit-message t)
+        message-log-max)
+    (apply orig-fun args)))
+
 (defun preview-auto--region-wrapper (beg end)
   "Preview region between BEG and END, possibly inhibiting messages."
-  ;; (preview-auto--debug-log "Previewing region %d,  %d" beg end)
-  (let ((inhibit-message preview-auto--inhibit-message))
-    (preview-region beg end)))
+  (preview-auto--debug-log "Previewing region %d,  %d" beg end)
+  (let ((TeX-suppress-compilation-message t)
+        (save-silently t))
+    (advice-add 'write-region :around #'preview-auto--silent-write-region)
+    (preview-region beg end)
+    (advice-remove 'write-region #'preview-auto--silent-write-region)))
 
 (defun preview-auto--update-editing-region ()
   "Update preview of environment being edited."
@@ -359,7 +364,7 @@ It can be useful to turn this off when using edebug.")
                     (and (string= why "$")
                          (string-match
                           "[\n\r]" (buffer-substring-no-properties begin end)))
-                  (preview-auto--debug-log "Previewing editing region %d, %d" 
begin end)
+                  (preview-auto--debug-log "Previewing editing region")
                   (preview-auto--region-wrapper begin end))))))))))
 
 (defun preview-auto--base-range ()
@@ -398,18 +403,27 @@ group."
     (pcase-let ((`(,pmin . ,pmax) (preview-auto--base-range)))
       (setq preview-auto--keepalive t)
       (cond
-       ((when-let ((region (preview-auto--last-valid-region
-                            pmin (min pmax (point)))))
-          (preview-auto--debug-log "Previewing above: %d, %d" (car region) 
(cdr region))
-          (preview-auto--region-wrapper (car region) (cdr region))))
-       ((when-let ((region (preview-auto--first-valid-region
-                            (max pmin (point)) pmax)))
-          (preview-auto--debug-log "Previewing below: %d, %d" (car region) 
(cdr region))
-          (preview-auto--region-wrapper (car region) (cdr region))))
        ((and
          (< pmin (point) pmax)
          preview-protect-point
          (preview-auto--update-editing-region)))
+       ((let ((region-above (preview-auto--last-valid-region
+                             pmin (min pmax (point))))
+              (region-below (preview-auto--first-valid-region
+                             (max pmin (point)) pmax)))
+          (when (or region-above region-below)
+            (let* ((should-preview-above (or (not region-below)
+                                             (and region-above region-below
+                                                  (<= (- (point) (cdr 
region-above))
+                                                      (- (car region-below) 
(point))))))
+                   (region (if should-preview-above region-above 
region-below)))
+              (preview-auto--debug-log
+               (concat "Previewing "
+                       (if should-preview-above "above" "below")
+                       (when (and region-above region-below)
+                         "(closer)")))
+              (prog1 t
+                (preview-auto--region-wrapper (car region) (cdr region)))))))
        (t
         (setq preview-auto--keepalive nil))))))
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]