#+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 them, 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=, toggled via the command =M-x preview-auto-mode=, the keybinding =C-c C-p C-a=, or the =Preview= menu.  With this minor mode activated, the visible portion of an AUCTeX buffer is continuously previewed.  Moreover, previews will automatically abort if you edit in a way that could affect their positioning.  Finally, it works in more general situations (e.g., you can use it out-of-the-box to highlight LaTeX in source code comments for other programming languages).

* 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
  :hook (LaTeX-mode . preview-auto-setup))
#+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 . preview-auto-conditionally-enable))
#+end_src

** My setup
I use something like the following =use-package= declaration:
#+begin_src elisp
(use-package preview-auto
  :after latex
  :hook (LaTeX-mode . preview-auto-setup)
  :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)

  ;; Uncomment the following only if you have followed the above
  ;; instructions concerning, e.g., hyperref:

  ;; (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.el][my config]].

** Non-file buffers and other modes
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.  For example, if "~/doit/preview-master.tex" is the name of such a file, and you want to use =preview-auto-mode= in [[https://orgmode.org/manual/Editing-Source-Code.html][indirect org-mode source blocks]], just add something like the following to your config:

#+begin_src elisp
(defun my/set-TeX-master ()
  (setq TeX-master "~/doit/preview-master.tex"))

(advice-add 'org-edit-src-code :after 'my/set-TeX-master)
#+end_src

It also works in buffers running other major modes.  (For example, I use it to preview LaTeX in comments in Lean4 files.)  Again, you just need to specify a suitable TeX-master.  For Lean4, I use something like:
#+begin_src elisp
(add-hook 'lean4-mode-hook 'my/set-TeX-master)
#+end_src
The default behavior is that in programming modes, only the comments are searched for latex code.  You can customize this via the defcustom =preview-auto-check-function=.

** VC revision files (vc.el)
When you visit a revision or version backup created by =vc.el= (e.g., via =C-x v ~=), Emacs uses file names like =paper.tex.~REV~=.  AUCTeX decides whether a buffer's file already has a TeX extension using =TeX-file-extensions=, and =preview-latex= (hence =preview-auto=) relies on that when computing the master file via =TeX-master-file=.  The default list does not match =tex.~REV~=, so AUCTeX treats these files as extension-less and appends =.tex=, producing wrong master/aux names and breaking previews.  Add the following to recognize VC revision files as TeX sources:
#+begin_src elisp
(add-to-list 'TeX-file-extensions "tex\\.~[^~]+~")
#+end_src
=preview-auto= should then work fine in such buffers.

** 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 internals a bit.

- 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=.
