diff options
author | mattkae <mattkae@protonmail.com> | 2022-06-07 08:23:47 -0400 |
---|---|---|
committer | mattkae <mattkae@protonmail.com> | 2022-06-07 08:23:47 -0400 |
commit | bd18a38c2898548a3664a9ddab9f79c84f2caf4a (patch) | |
tree | 95b9933376770381bd8859782ae763be81c2d72b /elpa/auctex-13.1.3/preview.el | |
parent | b07628dddf418d4f47b858e6c35fd3520fbaeed2 (diff) | |
parent | ef160dea332af4b4fe5e2717b962936c67e5fe9e (diff) |
Merge conflict
Diffstat (limited to 'elpa/auctex-13.1.3/preview.el')
-rw-r--r-- | elpa/auctex-13.1.3/preview.el | 4288 |
1 files changed, 0 insertions, 4288 deletions
diff --git a/elpa/auctex-13.1.3/preview.el b/elpa/auctex-13.1.3/preview.el deleted file mode 100644 index ad48b09..0000000 --- a/elpa/auctex-13.1.3/preview.el +++ /dev/null @@ -1,4288 +0,0 @@ -;;; preview.el --- embed preview LaTeX images in source buffer -*- lexical-binding: t; -*- - -;; Copyright (C) 2001-2022 Free Software Foundation, Inc. - -;; Author: David Kastrup -;; Keywords: tex, wp, convenience - -;; This file is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 3, or (at your option) -;; any later version. - -;; This file is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to -;; the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, -;; Boston, MA 02110-1301, USA. - -;;; Commentary: - -;; This style is for the "seamless" embedding of generated images -;; into LaTeX source code. Please see the README and INSTALL files -;; for further instruction. -;; -;; Please use the usual configure script for installation: more than -;; just Elisp files are involved: a LaTeX style, icon files, startup -;; code and so on. -;; -;; Quite a few things with regard to preview-latex's operation can be -;; configured by using -;; M-x customize-group RET preview RET -;; -;; Please report bugs with M-x preview-report-bug RET. - -;;; Code: - -(require 'tex-site) -(require 'tex) -(require 'latex) - -(eval-when-compile - (condition-case nil - (require 'desktop) - (file-error (message "Missing desktop package: -preview-latex buffers will not survive across sessions."))) - (condition-case nil - (require 'reporter) - (file-error (message "Missing reporter library, probably from the mail-lib package: -preview-latex's bug reporting commands will probably not work."))) - (require 'info)) - -(defgroup preview nil "Embed Preview images into LaTeX buffers." - :group 'AUCTeX - :prefix "preview-" - :link '(custom-manual "(preview-latex)Top") - :link '(info-link "(preview-latex)The Emacs interface") - :link '(url-link :tag "Homepage" "https://www.gnu.org/software/auctex/")) - -(defgroup preview-gs nil "Preview's Ghostscript renderer." - :group 'preview - :prefix "preview-") - -(defgroup preview-appearance nil "Preview image appearance." - :group 'preview - :prefix "preview-") - -(defconst preview-specs-type - '(repeat - (list :tag "Image spec" - ;; Use an extra :value keyword to avoid a bug in - ;; `widget-convert' of XEmacs 21.4 and Emacs 21. - ;; Analogously for the following `const' statements. - (const :format "" :value :type) - (choice :tag "Image type" - (const xpm) - (const xbm) - (symbol :tag "Other")) - (set :inline t :tag "Minimum font size" - (list :inline t :tag "" - (const :format "" :value :min) - (integer :tag "pixels"))) - (const :format "" :value :file) (string :tag "Filename") - (set :inline t :tag "Ascent ratio" - (list :inline t :tag "" - (const :format "" :value :ascent) - (integer :tag "percent of image" - :value 50)))))) - -(defun preview-specs-setter (symbol value) - "Set SYMBOL to VALUE and clear `preview-min-alist' property. -This is used in icon specs, so that customizing will -clear cached icons." - (put symbol 'preview-min-alist nil) - (set-default symbol value)) - -(defcustom preview-nonready-icon-specs - '((:type xpm :min 26 :file "prvwrk24.xpm" :ascent 90) - (:type xpm :min 22 :file "prvwrk20.xpm" :ascent 90) - (:type xpm :min 17 :file "prvwrk16.xpm" :ascent 90) - (:type xpm :min 15 :file "prvwrk14.xpm" :ascent 90) - (:type xpm :file "prvwrk12.xpm" :ascent 90) - (:type xbm :file "prvwrk24.xbm" :ascent 90)) - "The icon used for previews to be generated. -The spec must begin with `:type'. File names are relative to -`load-path' and `data-directory', a spec `:min' requires a -minimal pixel height for `preview-reference-face' before the spec -will be considered. Since evaluating the `:file' spec takes -considerable time under XEmacs, it should come after the `:min' -spec to avoid unnecessary evaluation time." - :group 'preview-appearance - :type preview-specs-type - :set #'preview-specs-setter) - -(defvar preview-nonready-icon nil - "The icon used for previews to be generated. -Suitable spec is chosen from `preview-nonready-icon-specs'.") - -(defcustom preview-error-icon-specs - '((:type xpm :min 22 :file "prverr24.xpm" :ascent 90) - (:type xpm :min 18 :file "prverr20.xpm" :ascent 90) - (:type xpm :file "prverr16.xpm" :ascent 90) - (:type xbm :file "prverr24.xbm" :ascent 90)) - "The icon used for PostScript errors. -The spec must begin with `:type'. File names are relative to -`load-path' and `data-directory', a spec `:min' requires a -minimal pixel height for `preview-reference-face' before the spec -will be considered. Since evaluating the `:file' spec takes -considerable time under XEmacs, it should come after the `:min' -spec to avoid unnecessary evaluation time." - :group 'preview-appearance - :type preview-specs-type - :set #'preview-specs-setter -) - -(defvar preview-error-icon nil - "The icon used for PostScript errors. -Suitable spec is chosen from `preview-error-icon-specs'.") - -(defcustom preview-icon-specs - '((:type xpm :min 24 :file "prvtex24.xpm" :ascent 75) - (:type xpm :min 20 :file "prvtex20.xpm" :ascent 75) - (:type xpm :min 16 :file "prvtex16.xpm" :ascent 75) - (:type xpm :file "prvtex12.xpm" :ascent 75) - (:type xbm :min 24 :file "prvtex24.xbm" :ascent 75) - (:type xbm :min 16 :file "prvtex16.xbm" :ascent 75) - (:type xbm :file "prvtex12.xbm" :ascent 75)) - "The icon used for an open preview. -The spec must begin with `:type'. File names are relative to -`load-path' and `data-directory', a spec `:min' requires a -minimal pixel height for `preview-reference-face' before the spec -will be considered. Since evaluating the `:file' spec takes -considerable time under XEmacs, it should come after the `:min' -spec to avoid unnecessary evaluation time." - :group 'preview-appearance - :type preview-specs-type - :set #'preview-specs-setter) - -(defvar preview-icon nil - "The icon used for an open preview. -Suitable spec is chosen from `preview-icon-specs'.") - -(defgroup preview-latex nil "LaTeX options for preview." - :group 'preview - :prefix "preview-") - -(defcustom preview-image-creators - '((dvipng - (open preview-gs-open preview-dvipng-process-setup) - (place preview-gs-place) - (close preview-dvipng-close)) - (png (open preview-gs-open) - (place preview-gs-place) - (close preview-gs-close)) - (jpeg (open preview-gs-open) - (place preview-gs-place) - (close preview-gs-close)) - (pnm (open preview-gs-open) - (place preview-gs-place) - (close preview-gs-close)) - (tiff (open preview-gs-open) - (place preview-gs-place) - (close preview-gs-close))) - "Define functions for generating images. -These functions get called in the process of generating inline -images of the specified type. The open function is called -at the start of a rendering pass, the place function for -placing every image, the close function at the end of -the pass. Look at the documentation of the various -functions used here for the default settings, and at -the function `preview-call-hook' through which those are -called. Additional argument lists specified in here -are passed to the functions before any additional -arguments given to `preview-call-hook'. - -Not all of these image types may be supported by your copy -of Ghostscript, or by your copy of Emacs." - :group 'preview-gs - :type '(alist :key-type (symbol :tag "Preview's image type") - :value-type - (alist :tag "Handler" :key-type (symbol :tag "Operation:") - :value-type (list :tag "Handler" - (function :tag "Handler function") - (repeat :tag "Additional \ -function args" :inline t sexp)) - :options (open place close)))) - -(defcustom preview-gs-image-type-alist - '((png png "-sDEVICE=png16m") - (dvipng png "-sDEVICE=png16m") - (jpeg jpeg "-sDEVICE=jpeg") - (pnm pbm "-sDEVICE=pnmraw") - (tiff tiff "-sDEVICE=tiff12nc")) - "Alist of image types and corresponding Ghostscript options. -The `dvipng' and `postscript' (don't use) entries really specify -a fallback device when images can't be processed by the requested -method, like when PDFTeX was used." - :group 'preview-gs - :type '(repeat (list :tag nil (symbol :tag "preview image-type") - (symbol :tag "Emacs image-type") - (repeat :inline t :tag "Ghostscript options" string)))) - -(defcustom preview-image-type 'png - "Image type to be used in images." - :group 'preview-gs - :type (append '(choice) - (mapcar (lambda (symbol) (list 'const (car symbol))) - preview-image-creators) - '((symbol :tag "Other")))) - -(defun preview-call-hook (symbol &rest rest) - "Call a function from `preview-image-creators'. -This looks up SYMBOL in the `preview-image-creators' entry -for the image type `preview-image-type' and calls the -hook function given there with the arguments specified there -followed by REST. If such a function is specified in there, -that is." - (let ((hook (cdr (assq symbol - (cdr (assq preview-image-type - preview-image-creators)))))) - (when hook - (apply (car hook) (append (cdr hook) rest))))) - - -(defvar TeX-active-tempdir nil - "List of directory name, top directory name and reference count.") -(make-variable-buffer-local 'TeX-active-tempdir) - -(defcustom preview-bb-filesize 1024 - "Size of file area scanned for bounding box information." - :group 'preview-gs :type 'integer) - -(defcustom preview-preserve-indentation t - "Whether to keep additional whitespace at the left of a line." - :group 'preview-appearance :type 'boolean) - -(defun preview-extract-bb (filename) - "Extract EPS bounding box vector from FILENAME." - (with-temp-buffer - (insert-file-contents-literally filename nil 0 preview-bb-filesize - t) - (goto-char (point-min)) - (when (search-forward-regexp "%%BoundingBox:\ - +\\([-+]?[0-9.]+\\)\ - +\\([-+]?[0-9.]+\\)\ - +\\([-+]?[0-9.]+\\)\ - +\\([-+]?[0-9.]+\\)" nil t) - (vector - (if preview-preserve-indentation - (min 72 (string-to-number (match-string 1))) - (string-to-number (match-string 1))) - (string-to-number (match-string 2)) - (string-to-number (match-string 3)) - (string-to-number (match-string 4)) - )))) - -(defcustom preview-prefer-TeX-bb nil - "Prefer TeX bounding box to EPS one if available. -If `preview-fast-conversion' is set, this option is not - consulted since the TeX bounding box has to be used anyway." - :group 'preview-gs - :type 'boolean) - -(defcustom preview-TeX-bb-border 0.5 - "Additional space in pt around Bounding Box from TeX." - :group 'preview-gs - :type 'number) - -(defvar preview-parsed-font-size nil - "Font size as parsed from the log of LaTeX run.") -(make-variable-buffer-local 'preview-parsed-font-size) -(defvar preview-parsed-magnification nil - "Magnification as parsed from the log of LaTeX run.") -(make-variable-buffer-local 'preview-parsed-magnification) -(defvar preview-parsed-pdfoutput nil - "PDFoutput as parsed from the log of LaTeX run.") -(make-variable-buffer-local 'preview-parsed-pdfoutput) -(defvar preview-parsed-counters nil - "Counters as parsed from the log of LaTeX run.") -(make-variable-buffer-local 'preview-parsed-counters) -(defvar preview-parsed-tightpage nil - "Tightpage as parsed from the log of LaTeX run.") -(make-variable-buffer-local 'preview-parsed-tightpage) - -(defun preview-get-magnification () - "Get magnification from `preview-parsed-magnification'." - (if preview-parsed-magnification - (/ preview-parsed-magnification 1000.0) 1.0)) - -(defun preview-TeX-bb (list) - "Calculate bounding box from (ht dp wd). -LIST consists of TeX dimensions in sp (1/65536 TeX point)." - (and - (consp list) - (let* ((dims (vconcat (mapcar - #'(lambda (x) - (/ x 65781.76)) - list))) - (box - (vector - (+ 72 (min 0 (aref dims 2))) - (+ 720 (min (aref dims 0) (- (aref dims 1)) 0)) - (+ 72 (max 0 (aref dims 2))) - (+ 720 (max (aref dims 0) (- (aref dims 1)) 0)))) - (border (if preview-parsed-tightpage - (vconcat (mapcar - #'(lambda(x) - (/ x 65781.76)) - preview-parsed-tightpage)) - (vector (- preview-TeX-bb-border) - (- preview-TeX-bb-border) - preview-TeX-bb-border - preview-TeX-bb-border)))) - (dotimes (i 4) - (aset box i (+ (aref box i) (aref border i)))) - box))) - -(defcustom preview-gs-command - (or ;; The GS wrapper coming with TeX Live - (executable-find "rungs") - ;; The MikTeX builtin GS - (let ((gs (executable-find "mgs"))) - ;; Check if mgs is functional for external non-MikTeX apps. - ;; See http://blog.miktex.org/post/2005/04/07/Starting-mgsexe-at-the-DOS-Prompt.aspx - (when (and gs (= 0 (shell-command (concat (shell-quote-argument gs) " -q -dNODISPLAY -c quit")))) - gs)) - ;; Windows ghostscript - (executable-find "GSWIN32C.EXE") - ;; standard GhostScript - (executable-find "gs")) - "How to call gs for conversion from EPS. See also `preview-gs-options'." - :group 'preview-gs - :type 'string) - -(defcustom preview-gs-options '("-q" "-dDELAYSAFER" "-dNOPAUSE" - "-DNOPLATFONTS" "-dPrinted" - "-dTextAlphaBits=4" - "-dGraphicsAlphaBits=4") - "Options with which to call gs for conversion from EPS. -See also `preview-gs-command'." - :group 'preview-gs - :type '(repeat string)) - -(defvar preview-gs-queue nil - "List of overlays to convert using gs. -Buffer-local to the appropriate TeX process buffer.") -(make-variable-buffer-local 'preview-gs-queue) - -(defvar preview-gs-outstanding nil - "Overlays currently processed.") -(make-variable-buffer-local 'preview-gs-outstanding) - -(defcustom preview-gs-outstanding-limit 2 - "Number of requests allowed to be outstanding. -This is the number of not-yet-completed requests we -might at any time have piped into Ghostscript. If -this number is larger, the probability of Ghostscript -working continuously is higher when Emacs is rather -busy. If this number is smaller, redisplay will -follow changes in the displayed buffer area faster." - :group 'preview-gs - :type '(restricted-sexp - :match-alternatives - ((lambda (value) (and - (integerp value) - (> value 0) - (< value 10)))) - :tag "small number")) - -(defvar preview-gs-answer nil - "Accumulated answer of Ghostscript process.") -(make-variable-buffer-local 'preview-gs-answer) - -(defvar preview-gs-image-type nil - "Image type for gs produced images.") -(make-variable-buffer-local 'preview-gs-image-type) - -(defvar preview-gs-sequence nil - "Pair of sequence numbers for gs produced images.") -(make-variable-buffer-local 'preview-gs-sequence) - -(defvar preview-scale nil - "Screen scale of images. -Magnify by this factor to make images blend with other -screen content. Buffer-local to rendering buffer.") -(make-variable-buffer-local 'preview-scale) - -(defvar preview-colors nil - "Color setup list. -An array with elements 0, 1 and 2 for background, -foreground and border colors, respectively. Each element -is a list of 3 real numbers between 0 and 1, or nil -of nothing special should be done for the color") -(make-variable-buffer-local 'preview-colors) - -(defvar preview-gs-init-string nil - "Ghostscript setup string.") -(make-variable-buffer-local 'preview-gs-init-string) - -(defvar preview-ps-file nil - "PostScript file name for fast conversion.") -(make-variable-buffer-local 'preview-ps-file) - -(defvar preview-gs-dsc nil - "Parsed DSC information.") -(make-variable-buffer-local 'preview-gs-dsc) - -(defvar preview-resolution nil - "Screen resolution where rendering started. -Cons-cell of x and y resolution, given in -dots per inch. Buffer-local to rendering buffer.") -(make-variable-buffer-local 'preview-resolution) - -(defun preview-gs-resolution (scale xres yres) - "Generate resolution argument for gs. -Calculated from real-life factor SCALE and XRES and -YRES, the screen resolution in dpi." - (format "-r%gx%g" - (/ (* scale xres) (preview-get-magnification)) - (/ (* scale yres) (preview-get-magnification)))) - -(defun preview-gs-behead-outstanding (err) - "Remove leading element of outstanding queue after error. -Return element if non-nil. ERR is the error string to -show as response of Ghostscript." - (let ((ov (pop preview-gs-outstanding))) - (when ov - (preview-gs-flag-error ov err) - (overlay-put ov 'queued nil)) - ov)) - -(defvar preview-gs-command-line nil) -(make-variable-buffer-local 'preview-gs-command-line) -(defvar preview-gs-file nil) -(make-variable-buffer-local 'preview-gs-file) - -(defcustom preview-fast-conversion t - "Set this for single-file PostScript conversion. -This will have no effect when `preview-image-type' is -set to `postscript'." - :group 'preview-latex - :type 'boolean) - -(defun preview-string-expand (arg &optional separator) - "Expand ARG as a string. -It can already be a string. Or it can be a list, then it is -recursively evaluated using SEPARATOR as separator. If a list -element is in itself a CONS cell, the CAR of the list (after symbol -dereferencing) can evaluate to either a string, in which case it is -used as a separator for the rest of the list, -or a boolean (t or nil) in which case the rest of the list is -either evaluated and concatenated or ignored, respectively. -ARG can be a symbol, and so can be the CDR -of a cell used for string concatenation." - (cond - ((stringp arg) arg) - ((consp arg) - (mapconcat - #'identity - (delq nil - (mapcar - (lambda(x) - (if (consp x) - (let ((sep (car x))) - (while (and (symbolp sep) - (not (memq sep '(t nil)))) - (setq sep (symbol-value sep))) - (if (stringp sep) - (preview-string-expand (cdr x) sep) - (and sep - (preview-string-expand (cdr x))))) - (preview-string-expand x))) - arg)) - (or separator ""))) - ((and (symbolp arg) (not (memq arg '(t nil)))) - (preview-string-expand (symbol-value arg) separator)) - (t (error "Bad string expansion")))) - -(defconst preview-expandable-string - (let ((f (lambda (x) - `(choice - string - (repeat :tag "Concatenate" - (choice - string - (cons :tag "Separated list" - (choice (string :tag "Separator") - (symbol :tag - "Indirect separator or flag")) - ,x) - (symbol :tag "Indirect variable (no separator)"))) - (symbol :tag "Indirect variable (with separator)"))))) - (funcall f (funcall f 'sexp))) - "Type to be used for `preview-string-expand'. -Just a hack until we get to learn how to do this properly. -Recursive definitions are not popular with Emacs, -so we define this type just two levels deep. This -kind of expandible string can either be just a string, or a -cons cell with a separator string in the CAR, and either -an explicit list of elements in the CDR, or a symbol to -be consulted recursively.") - -(defcustom preview-dvipng-command - "dvipng -picky -noghostscript %d -o %m/prev%%03d.png" - "Command used for converting to separate PNG images. - -You might specify options for converting to other image types, -but then you'll need to adapt `preview-dvipng-image-type'." - :group 'preview-latex - :type 'string) - -(defcustom preview-dvipng-image-type - 'png - "Image type that dvipng produces. - -You'll need to change `preview-dvipng-command' too, -if you customize this." - :group 'preview-latex - :type '(choice (const png) - (const gif) - (symbol :tag "Other" :value png))) - -(defcustom preview-dvips-command - "dvips -Pwww -i -E %d -o %m/preview.000" - "Command used for converting to separate EPS images." - :group 'preview-latex - :type 'string) - -(defcustom preview-fast-dvips-command - "dvips -Pwww %d -o %m/preview.ps" - "Command used for converting to a single PS file." - :group 'preview-latex - :type 'string) - -(defcustom preview-pdf2dsc-command - "pdf2dsc %(O?pdf) %m/preview.dsc" - "Command used for generating dsc from a PDF file." - :group 'preview-latex - :type 'string) - -(defun preview-gs-queue-empty () - "Kill off everything remaining in `preview-gs-queue'." - (mapc #'preview-delete preview-gs-outstanding) - (dolist (ov preview-gs-queue) - (if (overlay-get ov 'queued) - (preview-delete ov))) - (setq preview-gs-outstanding nil) - (setq preview-gs-queue nil)) - -(defvar preview-error-condition nil - "Last error raised and to be reported.") - -(defun preview-log-error (err context &optional process) - "Log an error message to run buffer. -ERR is the caught error syndrome, CONTEXT is where it -occured, PROCESS is the process for which the run-buffer -is to be used." - (when (or (null process) (buffer-name (process-buffer process))) - (with-current-buffer (or (and process - (process-buffer process)) - (current-buffer)) - (save-excursion - (goto-char (or (and process - (process-buffer process) - (marker-buffer (process-mark process)) - (process-mark process)) - (point-max))) - (insert-before-markers - (format "%s: %s\n" - context (error-message-string err))) - (display-buffer (current-buffer))))) - (setq preview-error-condition err)) - -(defun preview-reraise-error (&optional process) - "Raise an error that has been logged. -Makes sure that PROCESS is removed from the \"Compilation\" -tag in the mode line." - (when preview-error-condition - (unwind-protect - (signal (car preview-error-condition) (cdr preview-error-condition)) - (setq preview-error-condition nil - compilation-in-progress (delq process compilation-in-progress))))) - -(defcustom preview-pdf-color-adjust-method t - "Method to adjust colors of images generated from PDF. -It is not consulted when the latex command produces DVI files. - -The valid values are: - -t: preview-latex transfers the foreground and background colors -of Emacs to the generated images. This option requires that -Ghostscript has working DELAYBIND feature, thus is invalid with -gs 9.27 (and possibly < 9.27). - -`compatible': preview-latex uses another mothod to transfer -colors. This option is provided for compatibility with older gs. -See the below explanation for detail. - -nil: no adjustment is done and \"black on white\" image is -generated regardless of Emacs color. This is provided for fallback for -gs 9.27 users with customized foreground color. See the below -explanation for detail. - -When the latex command produces PDF rather than DVI and Emacs has -non-trivial foreground color, the traditional method (`compatible') -makes gs >= 9.27 to stop with error. Here, \"non-trivial foreground -color\" includes customized themes. - -If you use such non-trivial foreground color and the version of -Ghostscript equals to 9.27, you have two options: - -- Choose the value `compatible' and customize -`preview-reference-face' to have default (black) foreground -color. This makes the generated image almost non-readable on -dark background, so the next option would be your only choice in -that case. -- Choose the value nil, which forces plain \"black on white\" -appearance for the generated image. You can at least read what -are written in the image although they may not match with your -Emacs color well." - :group 'preview-appearance - :type '(choice - (const :tag "Adjust to Emacs color (gs > 9.27)" t) - (const :tag "Compatibility for gs =< 9.27" compatible) - (const :tag "No adjustment (B/W, for gs 9.27)" nil))) - -(defun preview-gs-sentinel (process string) - "Sentinel function for rendering process. -Gets the default PROCESS and STRING arguments -and tries to restart Ghostscript if necessary." - (condition-case err - (let ((status (process-status process))) - (when (memq status '(exit signal)) - (setq compilation-in-progress (delq process compilation-in-progress))) - (when (buffer-name (process-buffer process)) - (with-current-buffer (process-buffer process) - (goto-char (point-max)) - (insert-before-markers "\n" mode-name " " string) - (forward-char -1) - (insert " at " - (substring (current-time-string) 0 -5)) - (forward-char 1) - (TeX-command-mode-line process) - (when (memq status '(exit signal)) - ;; process died. - ;; Throw away culprit, go on. - (let* ((err (concat preview-gs-answer "\n" - (process-name process) " " string)) - (ov (preview-gs-behead-outstanding err))) - (when (and (null ov) preview-gs-queue) - (save-excursion - (goto-char (if (marker-buffer (process-mark process)) - (process-mark process) - (point-max))) - (insert-before-markers err))) - (delete-process process) - (if (or (null ov) - (eq status 'signal)) - ;; if process was killed explicitly by signal, or if nothing - ;; was processed, we give up on the matter altogether. - (progn - (when preview-ps-file - (condition-case nil - (preview-delete-file preview-ps-file) - (file-error nil))) - (preview-gs-queue-empty)) - - ;; restart only if we made progress since last call - (let (filenames) - (dolist (ov preview-gs-outstanding) - (setq filenames (overlay-get ov 'filenames)) - (condition-case nil - (preview-delete-file (nth 1 filenames)) - (file-error nil)) - (setcdr filenames nil))) - (setq preview-gs-queue (nconc preview-gs-outstanding - preview-gs-queue)) - (setq preview-gs-outstanding nil) - (preview-gs-restart))))))) - (error (preview-log-error err "Ghostscript" process))) - (preview-reraise-error process)) - -(defun preview-gs-filter (process string) - "Filter function for processing Ghostscript output. -Gets the usual PROCESS and STRING parameters, see -`set-process-filter' for a description." - (with-current-buffer (process-buffer process) - (setq preview-gs-answer (concat preview-gs-answer string)) - (while (string-match "GS\\(<[0-9]+\\)?>" preview-gs-answer) - (let* ((pos (match-end 0)) - (answer (substring preview-gs-answer 0 pos))) - (setq preview-gs-answer (substring preview-gs-answer pos)) - (condition-case err - (preview-gs-transact process answer) - (error (preview-log-error err "Ghostscript filter" process)))))) - (preview-reraise-error)) - -(defun preview-gs-restart () - "Start a new Ghostscript conversion process." - (when preview-gs-queue - (if preview-gs-sequence - (setcar preview-gs-sequence (1+ (car preview-gs-sequence))) - (setq preview-gs-sequence (list 1))) - (setcdr preview-gs-sequence 1) - (let* ((process-connection-type nil) - (outfile (format "-sOutputFile=%s" - (file-relative-name - (format "%s/pr%d-%%d.%s" - (car TeX-active-tempdir) - (car preview-gs-sequence) - preview-gs-image-type)))) - (process - (apply #'start-process - "Preview-Ghostscript" - (current-buffer) - preview-gs-command - outfile - preview-gs-command-line))) - (goto-char (point-max)) - (insert-before-markers "Running `Preview-Ghostscript' with ``" - (mapconcat #'shell-quote-argument - (append - (list preview-gs-command - outfile) - preview-gs-command-line) - " ") "''\n") - (setq preview-gs-answer "") - (set-process-query-on-exit-flag process nil) - (set-process-sentinel process #'preview-gs-sentinel) - (set-process-filter process #'preview-gs-filter) - (process-send-string process preview-gs-init-string) - (setq mode-name "Preview-Ghostscript") - (push process compilation-in-progress) - (TeX-command-mode-line process) - (force-mode-line-update) - process))) - -(defun preview-gs-open (&optional setup) - "Start a Ghostscript conversion pass. -SETUP may contain a parser setup function." - (let ((image-info (assq preview-image-type preview-gs-image-type-alist))) - (setq preview-gs-image-type (nth 1 image-info)) - (setq preview-gs-sequence nil) - (setq preview-gs-command-line (append - preview-gs-options - (nthcdr 2 image-info)) - preview-gs-init-string - (format "{DELAYSAFER{.setsafe}if}stopped pop\ -/.preview-BP currentpagedevice/BeginPage get dup \ -null eq{pop{pop}bind}if def\ -<</BeginPage{currentpagedevice/PageSize get dup 0 get 1 ne exch 1 get 1 ne or\ -{.preview-BP %s}{pop}ifelse}bind/PageSize[1 1]>>setpagedevice\ -/preview-do{/.preview-ST[count 4 roll save]def dup length 0 eq\ -{pop}{setpagedevice}{ifelse exec}\ -stopped{handleerror quit}if \ -.preview-ST aload pop restore}bind def " - (preview-gs-color-string - preview-colors - ;; Compatibility for gs 9.27 with non-trivial - ;; foreground color and dark background. - ;; Suppress color adjustment with PDF backend - ;; when `preview-pdf-color-adjust-method' is nil. - (and (not preview-pdf-color-adjust-method) - ;; The switch `preview-parsed-pdfoutput' isn't - ;; set before parsing the latex output, so use - ;; heuristic here. - (with-current-buffer TeX-command-buffer - (and TeX-PDF-mode - (not (TeX-PDF-from-DVI)))))))) - (preview-gs-queue-empty) - (preview-parse-messages (or setup #'preview-gs-dvips-process-setup)))) - -(defun preview-gs-color-value (value) - "Return string to be used as color value for an RGB component. -Conversion from Emacs color numbers (0 to 65535) in VALUE -to Ghostscript floats." - (format "%g" (/ value 65535.0))) - -(defun preview-pdf-color-string (colors) - "Return a string that patches PDF foreground color to work properly." - (let ((fg (aref colors 1))) - (if fg - (cond ((eq preview-pdf-color-adjust-method t) - ;; New code for gs > 9.27. - ;; This assumes DELAYBIND feature, which is known to be - ;; broken in gs 9.27 (and possibly, < 9.27). - ;; <URL:https://lists.gnu.org/archive/html/auctex-devel/2019-07/msg00000.html> - ;; DELAYBIND is sometimes mentioned in association with - ;; security holes in the changelog of Ghostscript: - ;; <URL:https://www.ghostscript.com/doc/9.27/History9.htm> - ;; Thus we might have to be prepared for removal of this - ;; feature in future Ghostscript. - (concat - "/initgraphics { - //initgraphics - /RG where { - pop " - (mapconcat #'preview-gs-color-value fg " ") - " 3 copy rg RG - } if -} bind def .bindnow ")) - ((eq preview-pdf-color-adjust-method 'compatible) - ;; Traditional code for gs < 9.27. - (concat - "/GS_PDF_ProcSet GS_PDF_ProcSet dup maxlength dict copy dup begin\ -/graphicsbeginpage{//graphicsbeginpage exec " - (mapconcat #'preview-gs-color-value fg " ") - " 3 copy rg RG}bind store end readonly store ")) - (;; Do nothing otherwise. - t - ""))))) - -(defun preview-gs-color-string (colors &optional suppress-fgbg) - "Return a string setting up COLORS. -If optional argument SUPPRESS-FGBG is non-nil, behave as if FG/BG -colors were just the default value." - (let ((bg (and (not suppress-fgbg) - (aref colors 0))) - (fg (and (not suppress-fgbg) - (aref colors 1))) - (mask (aref colors 2)) - (border (aref colors 3))) - (concat - (and (or (and mask border) (and bg (not fg))) - "gsave ") - (and bg - (concat - (mapconcat #'preview-gs-color-value bg " ") - " setrgbcolor clippath fill ")) - (and mask border - (format "%s setrgbcolor false setstrokeadjust %g \ -setlinewidth clippath strokepath \ -matrix setmatrix true \ -{2 index{newpath}if round exch round exch moveto pop false}\ -{round exch round exch lineto}{curveto}{closepath}\ -pathforall pop fill " - (mapconcat #'preview-gs-color-value mask " ") - (* 2 border))) - ;; I hate antialiasing. Warp border to integral coordinates. - (and (or (and mask border) (and bg (not fg))) - "grestore ") - (and fg - (concat - (mapconcat #'preview-gs-color-value fg " ") - " setrgbcolor"))))) - -(defun preview-dvipng-color-string (colors res) - "Return color setup tokens for dvipng. -Makes a string of options suitable for passing to dvipng. -Pure borderless black-on-white will return an empty string." - (let - ((bg (aref colors 0)) - (fg (aref colors 1)) - (mask (aref colors 2)) - (border (aref colors 3))) - (concat - (and bg - (format "--bg \"rgb %s\" " - (mapconcat #'preview-gs-color-value bg " "))) - (and fg - (format "--fg \"rgb %s\" " - (mapconcat #'preview-gs-color-value fg " "))) - (and mask border - (format "--bd \"rgb %s\" " - (mapconcat #'preview-gs-color-value mask " "))) - (and border - (format "--bd %d" (max 1 (round (/ (* res border) 72.0)))))))) - -(defsubst preview-supports-image-type (imagetype) - "Check if IMAGETYPE is supported." - (image-type-available-p imagetype)) - -(defun preview-gs-dvips-process-setup () - "Set up Dvips process for conversions via gs." - (unless (preview-supports-image-type preview-gs-image-type) - (error "preview-image-type setting '%s unsupported by this Emacs" - preview-gs-image-type)) - (setq preview-gs-command-line (append - preview-gs-command-line - (list (preview-gs-resolution - (preview-hook-enquiry preview-scale) - (car preview-resolution) - (cdr preview-resolution))))) - (if preview-parsed-pdfoutput - (preview-pdf2dsc-process-setup) - (let ((process (preview-start-dvips preview-fast-conversion))) - (setq TeX-sentinel-function #'preview-gs-dvips-sentinel) - (list process (current-buffer) TeX-active-tempdir preview-ps-file - preview-gs-image-type)))) - -(defun preview-dvipng-process-setup () - "Set up dvipng process for conversion." - (setq preview-gs-command-line (append - preview-gs-command-line - (list (preview-gs-resolution - (preview-hook-enquiry preview-scale) - (car preview-resolution) - (cdr preview-resolution))))) - (if preview-parsed-pdfoutput - (if (preview-supports-image-type preview-gs-image-type) - (preview-pdf2dsc-process-setup) - (error "preview-image-type setting '%s unsupported by this Emacs" - preview-gs-image-type)) - (unless (preview-supports-image-type preview-dvipng-image-type) - (error "preview-dvipng-image-type setting '%s unsupported by this Emacs" - preview-dvipng-image-type)) - (let ((process (preview-start-dvipng))) - (setq TeX-sentinel-function #'preview-dvipng-sentinel) - (list process (current-buffer) TeX-active-tempdir t - preview-dvipng-image-type)))) - - -(defun preview-pdf2dsc-process-setup () - (let ((process (preview-start-pdf2dsc))) - (setq TeX-sentinel-function #'preview-pdf2dsc-sentinel) - (list process (current-buffer) TeX-active-tempdir preview-ps-file - preview-gs-image-type))) - -(defun preview-dvips-abort () - "Abort a Dvips run." - (preview-gs-queue-empty) - (condition-case nil - (delete-file - (let ((gsfile preview-gs-file)) - (with-current-buffer TeX-command-buffer - (funcall (car gsfile) "dvi" t)))) - (file-error nil)) - (when preview-ps-file - (condition-case nil - (preview-delete-file preview-ps-file) - (file-error nil))) - (setq TeX-sentinel-function nil)) - -(defalias 'preview-dvipng-abort #'preview-dvips-abort) -; "Abort a DviPNG run.") - -(defun preview-gs-dvips-sentinel (process _command &optional gsstart) - "Sentinel function for indirect rendering DviPS process. -The usual PROCESS and COMMAND arguments for -`TeX-sentinel-function' apply. Starts gs if GSSTART is set." - (condition-case err - (let ((status (process-status process)) - (gsfile preview-gs-file)) - (cond ((eq status 'exit) - (delete-process process) - (setq TeX-sentinel-function nil) - (condition-case nil - (delete-file - (with-current-buffer TeX-command-buffer - (funcall (car gsfile) "dvi" t))) - (file-error nil)) - (if preview-ps-file - (preview-prepare-fast-conversion)) - (when gsstart - (if preview-gs-queue - (preview-gs-restart) - (when preview-ps-file - (condition-case nil - (preview-delete-file preview-ps-file) - (file-error nil)))))) - ((eq status 'signal) - (delete-process process) - (preview-dvips-abort)))) - (error (preview-log-error err "DviPS sentinel" process))) - (preview-reraise-error process)) - -(defun preview-pdf2dsc-sentinel (process _command &optional gsstart) - "Sentinel function for indirect rendering PDF process. -The usual PROCESS and COMMAND arguments for -`TeX-sentinel-function' apply. Starts gs if GSSTART is set." - (condition-case err - (let ((status (process-status process))) - (cond ((eq status 'exit) - (delete-process process) - (setq TeX-sentinel-function nil) - ;; Add DELAYBIND option for adjustment of foreground - ;; color to work. - (if (and (eq preview-pdf-color-adjust-method t) - (aref preview-colors 1)) - (setq preview-gs-command-line (append - preview-gs-command-line - '("-dDELAYBIND")))) - (setq preview-gs-init-string - (concat preview-gs-init-string - (preview-pdf-color-string preview-colors))) - (preview-prepare-fast-conversion) - (when gsstart - (if preview-gs-queue - (preview-gs-restart) - (when preview-ps-file - (condition-case nil - (preview-delete-file preview-ps-file) - (file-error nil)))))) - ((eq status 'signal) - (delete-process process) - (preview-dvips-abort)))) - (error (preview-log-error err "PDF2DSC sentinel" process))) - (preview-reraise-error process)) - -(defun preview-gs-close (process closedata) - "Clean up after PROCESS and set up queue accumulated in CLOSEDATA." - (setq preview-gs-queue (nconc preview-gs-queue closedata)) - (if process - (if preview-gs-queue - (if TeX-process-asynchronous - (if (and (eq (process-status process) 'exit) - (null TeX-sentinel-function)) - ;; Process has already finished and run sentinel - (progn - (when preview-ps-file - (condition-case nil - (preview-delete-file preview-ps-file) - (file-error nil))) - (preview-gs-restart)) - (setq TeX-sentinel-function - (let ((fun (if preview-parsed-pdfoutput - #'preview-pdf2dsc-sentinel - #'preview-gs-dvips-sentinel))) - (lambda (process command) - (funcall fun process command t))))) - (TeX-synchronous-sentinel "Preview-DviPS" (cdr preview-gs-file) - process)) - ;; pathological case: no previews although we sure thought so. - (delete-process process) - (unless (eq (process-status process) 'signal) - (preview-dvips-abort))))) - -(defun preview-dvipng-sentinel (process _command &optional placeall) - "Sentinel function for indirect rendering DviPNG process. -The usual PROCESS and COMMAND arguments for -`TeX-sentinel-function' apply. Places all snippets if PLACEALL is set." - (condition-case err - (let ((status (process-status process))) - (cond ((eq status 'exit) - (delete-process process) - (setq TeX-sentinel-function nil) - (when placeall - (preview-dvipng-place-all))) - ((eq status 'signal) - (delete-process process) - (preview-dvipng-abort)))) - (error (preview-log-error err "DviPNG sentinel" process))) - (preview-reraise-error process)) - -(defun preview-dvipng-close (process closedata) - "Clean up after PROCESS and set up queue accumulated in CLOSEDATA." - (if preview-parsed-pdfoutput - (preview-gs-close process closedata) - (setq preview-gs-queue (nconc preview-gs-queue closedata)) - (if process - (if preview-gs-queue - (if TeX-process-asynchronous - (if (and (eq (process-status process) 'exit) - (null TeX-sentinel-function)) - ;; Process has already finished and run sentinel - (preview-dvipng-place-all) - (setq TeX-sentinel-function (lambda (process command) - (preview-dvipng-sentinel - process - command - t)))) - (TeX-synchronous-sentinel "Preview-DviPNG" (cdr preview-gs-file) - process)) - ;; pathological case: no previews although we sure thought so. - (delete-process process) - (unless (eq (process-status process) 'signal) - (preview-dvipng-abort)))))) - -(defun preview-dsc-parse (file) - "Parse DSC comments of FILE. -Return a vector with offset/length pairs corresponding to -the pages. Page 0 corresponds to the initialization section." - (with-temp-buffer - (set-buffer-multibyte nil) - (insert-file-contents-literally file) - (let ((last-pt (point-min)) - trailer - pagelist - lastbegin - pt - case-fold-search - (level 0)) - (while (search-forward-regexp "\ -%%\\(?:\\(BeginDocument:\\)\\|\ -\\(EndDocument[\n\r]\\)\\|\ -\\(Page:\\)\\|\ -\\(Trailer[\n\r]\\)\\)" nil t) - (setq pt (match-beginning 0)) - (cond ((null (memq (char-before pt) '(?\C-j ?\C-m nil)))) - (trailer (error "Premature %%%%Trailer in `%s' at offsets %d/%d" - file trailer pt)) - ((match-beginning 1) - (if (zerop level) - (setq lastbegin pt)) - (setq level (1+ level))) - ((match-beginning 2) - (if (zerop level) - (error "Unmatched %%%%EndDocument in `%s' at offset %d" - file pt) - (setq level (1- level)))) - ((> level 0)) - ((match-beginning 3) - (push (list last-pt (- pt last-pt)) pagelist) - (setq last-pt pt)) - ((match-beginning 4) - (setq trailer pt)))) - (unless (zerop level) - (error "Unmatched %%%%BeginDocument in `%s' at offset %d" - file lastbegin)) - (push (list last-pt - (- (or trailer (point-max)) last-pt)) pagelist) - (vconcat (nreverse pagelist))))) - -(defun preview-gs-dsc-cvx (page dsc) - "Generate PostScript code accessing PAGE in the DSC object. -The returned PostScript code will need the file on -top of the stack, and will replace it with an executable -object corresponding to the wanted page." - (let ((curpage (aref dsc page))) - (format "dup %d setfileposition %d()/SubFileDecode filter cvx" - (1- (car curpage)) (nth 1 curpage)))) - -(defun preview-ps-quote-filename (str &optional nonrel) - "Make a PostScript string from filename STR. -The file name is first made relative unless -NONREL is not nil." - (unless nonrel (setq str (file-relative-name str))) - (let ((index 0)) - (while (setq index (string-match "[\\()]" str index)) - (setq str (replace-match "\\\\\\&" t nil str) - index (+ 2 index))) - (concat "(" str ")"))) - -(defun preview-prepare-fast-conversion () - "This fixes up all parameters for fast conversion." - (let* ((file (if (consp (car preview-ps-file)) - (if (consp (caar preview-ps-file)) - (car (last (caar preview-ps-file))) - (caar preview-ps-file)) - (car preview-ps-file))) - (all-files (if (and (consp (car preview-ps-file)) - (consp (caar preview-ps-file))) - (caar preview-ps-file) - (list file)))) - (setq preview-gs-dsc (preview-dsc-parse file)) - (setq preview-gs-init-string - ;; Add commands for revised file access controls introduced - ;; after gs 9.27 (bug#37719) - (concat (format "systemdict /.addcontrolpath known {%s} if " - (mapconcat (lambda (f) - (format "/PermitFileReading %s .addcontrolpath" - (preview-ps-quote-filename f))) - all-files "\n")) - (format "{<</PermitFileReading[%s]>> setuserparams \ -.locksafe} stopped pop " - (mapconcat #'preview-ps-quote-filename all-files "")) - preview-gs-init-string - (format " %s(r)file /.preview-ST 1 index def %s exec .preview-ST " - (preview-ps-quote-filename file) - (preview-gs-dsc-cvx 0 preview-gs-dsc)))))) - -(defun preview-gs-urgentize (ov buff) - "Make a displayed overlay render with higher priority. -This function is used in fake conditional display properties -for reordering the conversion order to prioritize on-screen -images. OV is the overlay in question, and BUFF is the -Ghostscript process buffer where the buffer-local queue -is located." - ;; It does not matter that ov gets queued twice in that process: the - ;; first version to get rendered will clear the 'queued property. - ;; It cannot get queued more than twice since we remove the - ;; conditional display property responsible for requeuing here. - ;; We don't requeue if the overlay has been killed (its buffer made - ;; nil). Not necessary, but while we are checking... - ;; We must return t. - (preview-remove-urgentization ov) - (when (and (overlay-get ov 'queued) - (overlay-buffer ov)) - (with-current-buffer buff - (push ov preview-gs-queue))) - t) - -(defsubst preview-icon-copy (icon) - "Prepare a later call of `preview-replace-active-icon'." - - ;; This is just a GNU Emacs specific efficiency hack because it - ;; is easy to do. When porting, don't do anything complicated - ;; here, rather deliver just the unchanged icon and make - ;; `preview-replace-active-icon' do the necessary work of replacing - ;; the icon where it actually has been stored, probably - ;; in the car of the strings property of the overlay. This string - ;; might probably serve as a begin-glyph as well, in which case - ;; modifying the string in the strings property would change that - ;; glyph automatically. - - (cons 'image (cdr icon))) - -(defsubst preview-replace-active-icon (ov replacement) - "Replace the active Icon in OV by REPLACEMENT, another icon." - (let ((img (overlay-get ov 'preview-image))) - (setcdr (car img) (cdar replacement)) - (setcdr img (cdr replacement)))) - -(defun preview-gs-place (ov snippet box run-buffer tempdir ps-file _imagetype) - "Generate an image placeholder rendered over by Ghostscript. -This enters OV into all proper queues in order to make it render -this image for real later, and returns the overlay after setting -a placeholder image. SNIPPET gives the number of the -snippet in question for the file to be generated. -BOX is a bounding box if we already know one via TeX. -RUN-BUFFER is the buffer of the TeX process, -TEMPDIR is the correct copy of `TeX-active-tempdir', -PS-FILE is a copy of `preview-ps-file', IMAGETYPE is the image type -for the file extension." - (overlay-put ov 'filenames - (unless (eq ps-file t) - (list - (preview-make-filename - (or ps-file - (format "preview.%03d" snippet)) - tempdir)))) - (overlay-put ov 'queued - (vector box nil snippet)) - (overlay-put ov 'preview-image - (list (preview-icon-copy preview-nonready-icon))) - (preview-add-urgentization #'preview-gs-urgentize ov run-buffer) - (list ov)) - -(defvar view-exit-action) - -(eval-and-compile - (defvar preview-button-1 [mouse-2]) - (defvar preview-button-2 [mouse-3])) - -(defmacro preview-make-clickable (&optional map glyph helpstring click1 click2) - "Generate a clickable string or keymap. -If MAP is non-nil, it specifies a keymap to add to, otherwise -a new one is created. If GLYPH is given, the result is made -to display it wrapped in a string. In that case, -HELPSTRING is a format string with one or two %s specifiers -for preview's clicks, displayed as a help-echo. CLICK1 and CLICK2 -are functions to call on preview's clicks." - `(let ((resmap ,(or map '(make-sparse-keymap)))) - ,@(if click1 - `((define-key resmap preview-button-1 ,click1))) - ,@(if click2 - `((define-key resmap preview-button-2 ,click2))) - ,(if glyph - `(propertize - "x" - 'display ,glyph - 'mouse-face 'highlight - 'help-echo - ,(if (stringp helpstring) - (format helpstring preview-button-1 preview-button-2) - `(format ,helpstring preview-button-1 preview-button-2)) - 'keymap resmap) - 'resmap))) - -(defun preview-mouse-open-error (string) - "Display STRING in a new view buffer on click." - (let ((buff (get-buffer-create - "*Preview-Ghostscript-Error*"))) - (with-current-buffer buff - (kill-all-local-variables) - (set (make-local-variable 'view-exit-action) #'kill-buffer) - (setq buffer-undo-list t) - (erase-buffer) - (insert string) - (goto-char (point-min))) - (view-buffer-other-window buff))) - -(defun preview-mouse-open-eps (file &optional position) - "Display eps FILE in a view buffer on click. -Place point at POSITION, else beginning of file." - (let ((default-mode - ;; FIXME: Yuck! Just arrange for the file name to have the right - ;; extension instead! - (assoc-default "x.ps" auto-mode-alist #'string-match)) - (buff (get-file-buffer file))) - (save-excursion - (if buff - (pop-to-buffer buff) - (view-file-other-window file)) - (if (and (eq major-mode (default-value 'major-mode)) - default-mode) - (funcall default-mode)) - (goto-char (or position (point-min))) - (message "%s" (substitute-command-keys "\ -Try \\[ps-run-start] \\[ps-run-buffer] and \ -\\<ps-run-mode-map>\\[ps-run-mouse-goto-error] on error offset."))))) - -(defun preview-gs-flag-error (ov err) - "Make an eps error flag in overlay OV for ERR string." - (let* ((filenames (overlay-get ov 'filenames)) - (file (car (nth 0 filenames))) - ;; FIXME: This format isn't equal to actual invocation of gs - ;; command constructed in `preview-gs-restart', which - ;; contains "%d". - (outfile (format "-sOutputFile=%s" - (file-relative-name - (car (nth 1 filenames))))) - (ps-open - (let ((string - (concat - (mapconcat #'shell-quote-argument - (append (list - preview-gs-command - outfile) - preview-gs-command-line) - " ") - "\nGS>" - preview-gs-init-string - (aref (overlay-get ov 'queued) 1) - err))) - (lambda () (interactive "@") (preview-mouse-open-error string)))) - (str - (preview-make-clickable - nil - preview-error-icon - "%s views error message -%s more options" - ps-open - (let ((args - (if preview-ps-file - (list - (if (consp (car file)) (nth 1 (car file)) (car file)) - (nth 0 (aref preview-gs-dsc - (aref (overlay-get ov 'queued) 2)))) - (list file)))) - (lambda () (interactive) - (popup-menu - `("PostScript error" - ["View error" ,ps-open] - ["View source" ,(lambda () (interactive "@") - (apply #'preview-mouse-open-eps - args))]))))))) - (overlay-put ov 'strings (cons str str)) - (preview-toggle ov))) - -(defun preview-gs-transact (process answer) - "Work off Ghostscript transaction. -This routine is the action routine called via the process filter. -The Ghostscript process buffer of PROCESS will already be selected, and -and the standard output of Ghostscript up to the next prompt will be -given as ANSWER." - (let ((ov (pop preview-gs-outstanding)) - (have-error (not - (string-match "\\`GS\\(<[0-9]+\\)?>\\'" answer )))) - (when (and ov (overlay-buffer ov)) - (let ((queued (overlay-get ov 'queued))) - (when queued - (let* ((bbox (aref queued 0)) - (filenames (overlay-get ov 'filenames)) - (oldfile (nth 0 filenames)) - (newfile (nth 1 filenames))) - (if have-error - (preview-gs-flag-error ov answer) - (condition-case nil - (preview-delete-file oldfile) - (file-error nil)) - (overlay-put ov 'filenames (cdr filenames)) - (preview-replace-active-icon - ov - (preview-create-icon (car newfile) - preview-gs-image-type - (preview-ascent-from-bb - bbox) - (aref preview-colors 2)))) - (overlay-put ov 'queued nil))))) - (while (and (< (length preview-gs-outstanding) - preview-gs-outstanding-limit) - (setq ov (pop preview-gs-queue))) - (let ((queued (overlay-get ov 'queued))) - (when (and queued - (not (memq ov preview-gs-outstanding)) - (overlay-buffer ov)) - (let* ((filenames (overlay-get ov 'filenames)) - (oldfile (car (nth 0 - (nconc filenames - (list - (preview-make-filename - (format "pr%d-%d.%s" - (car preview-gs-sequence) - (cdr preview-gs-sequence) - preview-gs-image-type) - TeX-active-tempdir)))))) - (bbox (aset queued 0 - (or (and preview-prefer-TeX-bb - (aref queued 0)) - (and (stringp oldfile) - (preview-extract-bb - oldfile)) - (aref queued 0) - (error "No bounding box")))) - (snippet (aref queued 2)) - (gs-line - (format - "%s<<%s>>preview-do\n" - (if preview-ps-file - (concat "dup " - (preview-gs-dsc-cvx - snippet - preview-gs-dsc)) - (format "%s(r)file cvx" - (preview-ps-quote-filename - (if (listp oldfile) - (car (last oldfile)) - oldfile)))) - (if preview-parsed-tightpage - "" - (format "/PageSize[%g %g]/PageOffset[%g \ -%g[1 1 dtransform exch]{0 ge{neg}if exch}forall]" - (- (aref bbox 2) (aref bbox 0)) - (- (aref bbox 3) (aref bbox 1)) - (aref bbox 0) (aref bbox 1)))))) - (setcdr preview-gs-sequence (1+ (cdr preview-gs-sequence))) - (setq preview-gs-outstanding - (nconc preview-gs-outstanding - (list ov))) - (aset queued 1 gs-line) - ;; ignore errors because of dying processes: they will get - ;; caught by the sentinel, anyway. - (condition-case nil - (process-send-string - process - gs-line) - (error nil)))))) - (unless preview-gs-outstanding - (condition-case nil - (process-send-eof process) - (error nil))))) - -(defun preview-hook-enquiry (hook) - "Gets a value from a configured hook. -HOOK is a list or single item, for which the first resolving to -non-nil counts. Entries can be a callable function, or -a symbol that is consulted, or a value. Lists are evaluated -recursively." - (cond ((functionp hook) - (funcall hook)) - ((consp hook) - (let (res) - (while (and (not res) hook) - (setq res (preview-hook-enquiry (car hook)) - hook (cdr hook))) - res)) - ((and (symbolp hook) (boundp hook)) - (symbol-value hook)) - (t hook))) - -(defun preview-inherited-face-attribute (face attribute &optional inherit) - "Fetch face attribute while adhering to inheritance. -This searches FACE for an ATTRIBUTE, using INHERIT -for resolving unspecified or relative specs. See the fourth -argument of function `face-attribute' for details." - (face-attribute face attribute nil inherit)) - -(defcustom preview-scale-function #'preview-scale-from-face - "Scale factor for included previews. -This can be either a function to calculate the scale, or -a fixed number." - :group 'preview-appearance - :type '(choice (function-item preview-scale-from-face) - (const 1.0) - (number :value 1.0) - (function :value preview-scale-from-face))) - -(defcustom preview-default-document-pt 10 - "Assumed document point size for `preview-scale-from-face'. -If the point size (such as 11pt) of the document cannot be -determined from the document options itself, assume this size. -This is for matching screen font size and previews." - :group 'preview-appearance - :type - '(choice (const :tag "10pt" 10) - (const :tag "11pt" 11) - (const :tag "12pt" 12) - (number :tag "Other" :value 11.0))) - -(defcustom preview-document-pt-list '(preview-parsed-font-size - preview-auctex-font-size - preview-default-document-pt) - "How `preview-document-pt' figures out the document size." - :group 'preview-appearance - :type - '(repeat (choice - ;; FIXME: It seems that the bug mentioned below doesn't exist - ;; at least for emacs 27.2. - ;; This is a bug: type function seems to match variables, too. - (restricted-sexp :match-alternatives (functionp) - :tag "Function" :value preview-auctex-font-size) - (variable :value preview-parsed-font-size) - (number :value 11)))) - -(defun preview-auctex-font-size () - "Calculate the default font size of document. -If packages, classes or styles were called with an option -like 10pt, size is taken from the first such option if you -had let your document be parsed by AUCTeX." - (let* ((regexp "\\`\\([0-9]+\\)pt\\'") - (option - (or - (LaTeX-match-class-option regexp) - ;; We don't have `LaTeX-match-package-option'. - (TeX-member regexp - (apply #'append - (mapcar #'cdr LaTeX-provided-package-options)) - #'string-match)))) - (if option (string-to-number (match-string 1 option))))) - -(defsubst preview-document-pt () - "Calculate the default font size of document." - (preview-hook-enquiry preview-document-pt-list)) - -(defun preview-scale-from-face () - "Calculate preview scale from `preview-reference-face'. -This calculates the scale of EPS images from a document assumed -to have a default font size given by function `preview-document-pt' -so that they match the reference face in height." - (let ((d (/ (preview-inherited-face-attribute 'preview-reference-face :height - 'default) - 10.0))) - (lambda () (/ d (preview-document-pt))))) - -(defvar preview-min-spec nil - "Value to filter out too large icons. -Icon specs with :size larger than this value is not used. -Appropriate value is determined at run time according to the -display in use.") - -(defun preview-make-image (symbol) - "Make an image from a preview spec list. -The first spec that is workable (given the current setting of -`preview-min-spec') from the given SYMBOL is used here. The -icon is cached in the property list of the SYMBOL." - (let ((alist (get symbol 'preview-min-alist))) - (cdr (or - (assq preview-min-spec alist) - (car (put symbol 'preview-min-alist - (cons - (cons preview-min-spec - (preview-filter-specs - (symbol-value symbol))) - alist))))))) - -(defun preview-filter-specs (spec-list) - "Find the first of the fitting specs and make an image." - (let (image) - (while (and spec-list - (not (setq image - (catch 'preview-filter-specs - (preview-filter-specs-1 (car spec-list)))))) - (setq spec-list (cdr spec-list))) - image)) - -(defun preview-filter-specs-1 (specs) - (and specs - (if (get 'preview-filter-specs (car specs)) - (apply (get 'preview-filter-specs (car specs)) specs) - `(,(nth 0 specs) ,(nth 1 specs) - ,@(preview-filter-specs-1 (nthcdr 2 specs)))))) - -(put 'preview-filter-specs :min - #'(lambda (_keyword value &rest args) - (if (> value preview-min-spec) - (throw 'preview-filter-specs nil) - (preview-filter-specs-1 args)))) - -(put 'preview-filter-specs :file - #'(lambda (_keyword value &rest args) - `(:file ,(expand-file-name value (expand-file-name "images" - TeX-data-directory)) - ,@(preview-filter-specs-1 args)))) - -(defun preview-ascent-from-bb (bb) - "This calculates the image ascent from its bounding box. -The bounding box BB needs to be a 4-component vector of -numbers (can be float if available)." - ;; baseline is at 1in from the top of letter paper (11in), so it is - ;; at 10in from the bottom precisely, which is 720 in PostScript - ;; coordinates. If our bounding box has its bottom not above this - ;; line, and its top above, we can calculate a useful ascent value. - ;; If not, something is amiss. We just use 100 in that case. - - (let ((bottom (aref bb 1)) - (top (aref bb 3))) - (if (and (<= bottom 720) - (> top 720)) - (round (* 100.0 (/ (- top 720.0) (- top bottom)))) - 100))) - -(defface preview-face '((((background dark)) - (:background "dark slate gray")) - (t - (:background "beige"))) - "Face to use for the preview source." - :group 'preview-appearance) - -(defface preview-reference-face '((t nil)) - "Face consulted for colors and scale of active previews. -Fallback to :inherit and 'default implemented." - :group 'preview-appearance) - -(defcustom preview-auto-reveal - '(eval (preview-arrived-via (key-binding [left]) (key-binding [right]) - #'backward-char #'forward-char)) - "Cause previews to open automatically when entered. -Possibilities are: -t autoopens, -nil doesn't, -a symbol will have its value consulted if it exists, -defaulting to nil if it doesn't. -An integer will specify a maximum cursor movement distance. -Larger movements won't open the preview. -A CONS-cell means to call a function for determining the value. -The CAR of the cell is the function to call which receives -the CDR of the CONS-cell in the rest of the arguments, while -point and current buffer point to the position in question. -All of the options show reasonable defaults." - :group 'preview-appearance - :type '(choice (const :tag "Off" nil) - (const :tag "On" t) - (symbol :tag "Indirect variable" :value reveal-mode) - (integer :tag "Maximum distance" :value 1) - (cons :tag "Function call" - :value (eval (preview-arrived-via - (key-binding [left]) - (key-binding [right]))) - function (list :tag "Argument list" - (repeat :inline t sexp))))) - -(defun preview-auto-reveal-p (mode distance) - "Decide whether to auto-reveal. -Return non-nil if region should be auto-opened. -See `preview-auto-reveal' for definitions of MODE, which gets -set to `preview-auto-reveal'. DISTANCE specifies the movement -distance with which point has been reached in case it has been -a movement starting in the current buffer." - (cond ((symbolp mode) - (and (boundp mode) - (symbol-value mode))) - ((integerp mode) - (and distance (/= 0 distance) (<= (abs distance) mode))) - ((consp mode) - (apply (car mode) (cdr mode))) - (t mode))) - -(defun preview-arrived-via (&rest list) - "Indicate auto-opening. -Return non-nil if called by one of the commands in LIST." - (memq this-command list)) - -(defcustom preview-equality-transforms '(identity - preview-canonical-spaces) -"Transformation functions for region changes. -These functions are tried in turn on the strings from the -regions of a preview to decide whether a preview is to be considered -changed. If any transform leads to equal results, the preview is -considered unchanged." - :group 'preview-appearance - :type '(repeat function)) - -(defcustom preview-transparent-color '(highlight :background) - "Color to appear transparent in previews. -Set this to something unusual when using `preview-transparent-border', -to the default background in most other cases." - :type '(radio (const :tag "None" nil) - (const :tag "Autodetect" t) - (color :tag "By name" :value "white") - (list :tag "Take from face" - :value (default :background) - (face) - (choice :tag "What to take" - (const :tag "Background" :value :background) - (const :tag "Foreground" :value :foreground)))) - :group 'preview-appearance) - -;; Note that the following default introduces a border only when -;; Emacs blinks politely when point is on an image (the tested -;; unrelated function was introduced at about the time image blinking -;; became tolerable). -(defcustom preview-transparent-border nil - "Width of transparent border for previews in pt. -Setting this to a numeric value will add a border of -`preview-transparent-color' around images, and will turn -the heuristic-mask setting of images to default to 't since -then the borders are correctly detected even in case of -palette operations. If the transparent color is something -not present otherwise in the image, the cursor display -will affect just this border. A width of 0 is interpreted -by PostScript as meaning a single pixel, other widths are -interpreted as PostScript points (1/72 of 1in)" - :group 'preview-appearance - :type '(choice (const :value nil :tag "No border") - (number :value 1.5 :tag "Border width in pt"))) - -(defun preview-get-heuristic-mask () - "Get heuristic-mask to use for previews. -Consults `preview-transparent-color'." - (cond ((stringp preview-transparent-color) - (color-values preview-transparent-color)) - ((or (not (consp preview-transparent-color)) - (integerp (car preview-transparent-color))) - preview-transparent-color) - (t (color-values (preview-inherited-face-attribute - (nth 0 preview-transparent-color) - (nth 1 preview-transparent-color) - 'default))))) - -(defsubst preview-create-icon-1 (file type ascent border) - `(image - :file ,file - :type ,type - :ascent ,ascent - ,@(and border - '(:mask (heuristic t))))) - -(defun preview-create-icon (file type ascent border) - "Create an icon from FILE, image TYPE, ASCENT and BORDER." - (list - (preview-create-icon-1 file type ascent border) - file type ascent border)) - -(put 'preview-filter-specs :type - (lambda (_keyword value &rest args) - (if (image-type-available-p value) - `(image :type ,value - ,@(preview-filter-specs-1 args)) - (throw 'preview-filter-specs nil)))) - -(defun preview-import-image (image) - "Convert the printable IMAGE rendition back to an image." - (cond ((stringp image) - (propertize image 'face 'preview-face)) - ((eq (car image) 'image) - image) - (t - (preview-create-icon-1 (nth 0 image) - (nth 1 image) - (nth 2 image) - (if (< (length image) 4) - (preview-get-heuristic-mask) - (nth 3 image)))))) - -;; No defcustom here: does not seem to make sense. - -(defvar preview-tb-icon-specs - '((:type xpm :file "prvtex24.xpm") - (:type xbm :file "prvtex24.xbm"))) - -(defvar preview-tb-icon nil) - -(defun preview-add-urgentization (fun ov &rest rest) - "Cause FUN (function call form) to be called when redisplayed. -FUN must be a form with OV as first argument, -REST as the remainder, returning T." - (let ((dispro (overlay-get ov 'display))) - (unless (eq (car dispro) 'when) - (overlay-put ov 'display `(when (,fun ,ov ,@rest) . ,dispro))))) - -(defun preview-remove-urgentization (ov) - "Undo urgentization of OV by `preview-add-urgentization'. -Return the old arguments to `preview-add-urgentization' -if there was any urgentization." - (let ((dispro (overlay-get ov 'display))) - (when (eq (car-safe dispro) 'when) - (prog1 - (car (cdr dispro)) - (overlay-put ov 'display (cdr (cdr dispro))))))) - -(defvar preview-overlay nil) - -(put 'preview-overlay - 'modification-hooks - '(preview-handle-modification)) - -(put 'preview-overlay - 'insert-in-front-hooks - '(preview-handle-insert-in-front)) - -(put 'preview-overlay - 'insert-behind-hooks - '(preview-handle-insert-behind)) - -;; We have to fake our way around atomicity. - -;; Here is the beef: for best intuitiveness, we want to have -;; insertions be carried out as expected before iconized text -;; passages, but we want to insert *into* the overlay when not -;; iconized. A preview that has become empty can not get content -;; again: we remove it. A disabled preview needs no insert-in-front -;; handler. - -(defvar preview-change-list nil - "List of tentatively changed overlays.") - -(defcustom preview-dump-threshold - "^ *\\\\begin *{document}[ %]*$" - "Regexp denoting end of preamble. -This is the location up to which preamble changes are considered -to require redumping of a format." - :group 'preview-latex - :type 'string) - -(defun preview-preamble-changed-function - (ov _after-change _beg _end &optional _length) - "Hook function for change hooks on preamble. -See info node `(elisp) Overlay Properties' for -definition of OV, AFTER-CHANGE, BEG, END and LENGTH." - (let ((format-cons (overlay-get ov 'format-cons))) - (preview-unwatch-preamble format-cons) - (preview-format-kill format-cons) - (setcdr format-cons t))) - -(defun preview-watch-preamble (file command format-cons) - "Set up a watch on master file FILE. -FILE can be an associated buffer instead of a filename. -COMMAND is the command that generated the format. -FORMAT-CONS contains the format info for the main -format dump handler." - (let ((buffer (if (bufferp file) - file - (find-buffer-visiting file))) ov) - (setcdr - format-cons - (cons command - (when buffer - (with-current-buffer buffer - (save-excursion - (save-restriction - (widen) - (goto-char (point-min)) - (unless (re-search-forward preview-dump-threshold nil t) - (error "Can't find preamble of `%s'" file)) - (setq ov (make-overlay (point-min) (point))) - (overlay-put ov 'format-cons format-cons) - (overlay-put ov 'insert-in-front-hooks - '(preview-preamble-changed-function)) - (overlay-put ov 'modification-hooks - '(preview-preamble-changed-function)) - ov)))))))) - -(defun preview-unwatch-preamble (format-cons) - "Stop watching a format on FORMAT-CONS. -The watch has been set up by `preview-watch-preamble'." - (when (consp (cdr format-cons)) - (when (cddr format-cons) - (delete-overlay (cddr format-cons))) - (setcdr (cdr format-cons) nil))) - -(defun preview-register-change (ov) - "Register not yet changed OV for verification. -This stores the old contents of the overlay in the -`preview-prechange' property and puts the overlay into -`preview-change-list' where `preview-check-changes' will -find it at some later point of time." - (unless (overlay-get ov 'preview-prechange) - (if (eq (overlay-get ov 'preview-state) 'disabled) - (overlay-put ov 'preview-prechange t) - (overlay-put ov 'preview-prechange - (save-restriction - (widen) - (buffer-substring-no-properties - (overlay-start ov) (overlay-end ov))))) - (push ov preview-change-list))) - -(defun preview-check-changes () - "Check whether the contents under the overlay have changed. -Disable it if that is the case. Ignores text properties." - (dolist (ov preview-change-list) - (condition-case nil - (with-current-buffer (overlay-buffer ov) - (let ((text (save-restriction - (widen) - (buffer-substring-no-properties - (overlay-start ov) (overlay-end ov))))) - (if (zerop (length text)) - (preview-delete ov) - (unless - (or (eq (overlay-get ov 'preview-state) 'disabled) - (preview-relaxed-string= - text (overlay-get ov 'preview-prechange))) - (overlay-put ov 'insert-in-front-hooks nil) - (overlay-put ov 'insert-behind-hooks nil) - (preview-disable ov))))) - (error nil)) - (overlay-put ov 'preview-prechange nil)) - (setq preview-change-list nil)) - -(defun preview-handle-insert-in-front - (ov after-change _beg end &optional _length) - "Hook function for `insert-in-front-hooks' property. -See info node `(elisp) Overlay Properties' for -definition of OV, AFTER-CHANGE, BEG, END and LENGTH." - (if after-change - (unless undo-in-progress - (if (eq (overlay-get ov 'preview-state) 'active) - (move-overlay ov end (overlay-end ov)))) - (preview-register-change ov))) - -(defun preview-handle-insert-behind - (ov after-change beg _end &optional _length) - "Hook function for `insert-behind-hooks' property. -This is needed in case `insert-before-markers' is used at the -end of the overlay. See info node `(elisp) Overlay Properties' -for definition of OV, AFTER-CHANGE, BEG, END and LENGTH." - (if after-change - (unless undo-in-progress - (if (eq (overlay-get ov 'preview-state) 'active) - (move-overlay ov (overlay-start ov) beg))) - (preview-register-change ov))) - -(defun preview-handle-modification - (ov after-change _beg _end &optional _length) - "Hook function for `modification-hooks' property. -See info node `(elisp) Overlay Properties' for -definition of OV, AFTER-CHANGE, BEG, END and LENGTH." - (unless after-change - (preview-register-change ov))) - -(defun preview-toggle (ov &optional arg event) - "Toggle visibility of preview overlay OV. -ARG can be one of the following: t displays the overlay, -nil displays the underlying text, and 'toggle toggles. -If EVENT is given, it indicates the window where the event -occured, either by being a mouse event or by directly being -the window in question. This may be used for cursor restoration -purposes." - (let ((old-urgent (preview-remove-urgentization ov)) - (preview-state - (if (if (eq arg 'toggle) - (null (eq (overlay-get ov 'preview-state) 'active)) - arg) - 'active - 'inactive)) - (strings (overlay-get ov 'strings))) - (unless (eq (overlay-get ov 'preview-state) 'disabled) - (overlay-put ov 'preview-state preview-state) - (if (eq preview-state 'active) - (progn - (overlay-put ov 'category 'preview-overlay) - (if (eq (overlay-start ov) (overlay-end ov)) - (overlay-put ov 'before-string (car strings)) - (dolist (prop '(display keymap mouse-face help-echo)) - (overlay-put ov prop - (get-text-property 0 prop (car strings)))) - (overlay-put ov 'before-string nil)) - (overlay-put ov 'face nil)) - (dolist (prop '(display keymap mouse-face help-echo)) - (overlay-put ov prop nil)) - (overlay-put ov 'face 'preview-face) - (unless (cdr strings) - (setcdr strings (preview-inactive-string ov))) - (overlay-put ov 'before-string (cdr strings))) - (if old-urgent - (apply #'preview-add-urgentization old-urgent)))) - (if event - (preview-restore-position - ov - (if (windowp event) - event - (posn-window (event-start event)))))) - -(defvar preview-marker (make-marker) - "Marker for fake intangibility.") - -(defvar preview-temporary-opened nil) - -(defvar preview-last-location nil - "Restored cursor position marker for reopened previews.") -(make-variable-buffer-local 'preview-last-location) - -(defun preview-mark-point () - "Mark position for fake intangibility." - (when (eq (get-char-property (point) 'preview-state) 'active) - (unless preview-last-location - (setq preview-last-location (make-marker))) - (set-marker preview-last-location (point)) - (set-marker preview-marker (point)) - (preview-move-point)) - (set-marker preview-marker (point))) - -(defun preview-restore-position (ov window) - "Tweak position after opening/closing preview. -The treated overlay OV has been triggered in WINDOW. This function -records the original buffer position for reopening, or restores it -after reopening. Note that by using the mouse, you can open/close -overlays not in the active window." - (when (eq (overlay-buffer ov) (window-buffer window)) - (with-current-buffer (overlay-buffer ov) - (if (eq (overlay-get ov 'preview-state) 'active) - (setq preview-last-location - (set-marker (or preview-last-location (make-marker)) - (window-point window))) - (when (and - (markerp preview-last-location) - (eq (overlay-buffer ov) (marker-buffer preview-last-location)) - (< (overlay-start ov) preview-last-location) - (> (overlay-end ov) preview-last-location)) - (set-window-point window preview-last-location)))))) - -(defun preview-move-point () - "Move point out of fake-intangible areas." - (preview-check-changes) - (let* (newlist (pt (point)) (lst (overlays-at pt)) distance) - (setq preview-temporary-opened - (dolist (ov preview-temporary-opened newlist) - (and (overlay-buffer ov) - (eq (overlay-get ov 'preview-state) 'inactive) - (if (and (eq (overlay-buffer ov) (current-buffer)) - (or (<= pt (overlay-start ov)) - (>= pt (overlay-end ov)))) - (preview-toggle ov t) - (push ov newlist))))) - (when lst - (if (or disable-point-adjustment - global-disable-point-adjustment - (preview-auto-reveal-p - preview-auto-reveal - (setq distance - (and (eq (marker-buffer preview-marker) - (current-buffer)) - (- pt (marker-position preview-marker)))))) - (preview-open-overlays lst) - (while lst - (setq lst - (if (and - (eq (overlay-get (car lst) 'preview-state) 'active) - (> pt (overlay-start (car lst)))) - (overlays-at - (setq pt (if (and distance (< distance 0)) - (overlay-start (car lst)) - (overlay-end (car lst))))) - (cdr lst)))) - (goto-char pt))))) - -(defun preview-open-overlays (list &optional pos) - "Open all previews in LIST, optionally restricted to enclosing POS." - (dolist (ovr list) - (when (and (eq (overlay-get ovr 'preview-state) 'active) - (or (null pos) - (and - (> pos (overlay-start ovr)) - (< pos (overlay-end ovr))))) - (preview-toggle ovr) - (push ovr preview-temporary-opened)))) - -(defun preview--open-for-replace (beg end &rest _) - "Make `query-replace' open preview text about to be replaced." - (preview-open-overlays (overlays-in beg end))) - -(defcustom preview-query-replace-reveal t - "Make `query-replace' autoreveal previews." - :group 'preview-appearance - :type 'boolean - :require 'preview - :set (lambda (symbol value) - (set-default symbol value) - (if value - (advice-add 'replace-highlight :before - #'preview--open-for-replace) - (advice-remove 'replace-highlight - #'preview--open-for-replace))) - :initialize #'custom-initialize-reset) - -(defun preview-relaxed-string= (&rest args) -"Check for functional equality of arguments. -The arguments ARGS are checked for equality by using -`preview-equality-transforms' on them until it is exhausted -or one transform returns equality." - (let ((lst preview-equality-transforms)) - (while (and lst (not (apply #'string= (mapcar (car lst) args)))) - (setq lst (cdr lst))) - lst)) - -(defun preview-canonical-spaces (arg) - "Convert ARG into canonical form. -Removes comments and collapses white space, except for multiple newlines." - (let (pos) - (while (setq pos (string-match "\\s<.*[\n\r][ \t]*" arg pos)) - (setq arg (replace-match "" t t arg 0))) - (while (setq pos (string-match "[ \t]*\\(\\([ \t]\\)\\|[\n\r][ \t]*\\)" - arg pos)) - (setq arg (replace-match (if (match-beginning 2) " " "\n") t t arg 0) - pos (1+ pos))) - (while (setq pos (string-match "\n+" arg pos)) - (if (string= "\n" (match-string 0 arg)) - (setq arg (replace-match " " t t arg 0) - pos (1+ pos)) - (setq pos (match-end 0))))) - arg) - -(defun preview-regenerate (ovr) - "Pass the modified region in OVR again through LaTeX." - (let ((begin (overlay-start ovr)) - (end (overlay-end ovr))) - (with-current-buffer (overlay-buffer ovr) - (preview-delete ovr) - (preview-region begin end)))) - -(defcustom preview-inner-environments '("Bmatrix" "Vmatrix" "aligned" - "array" "bmatrix" "cases" - "gathered" "matrix" "pmatrix" - "smallmatrix" "split" - "subarray" "vmatrix") - "Environments not to be previewed on their own." - :group 'preview-latex - :type '(repeat string)) - - -(defun preview-next-border (backwards) - "Search for the next interesting border for `preview-at-point'. -Searches backwards if BACKWARDS is non-nil." - (let (history preview-state (pt (point))) - (catch 'exit - (while - (null - (memq - (setq preview-state - (if backwards - (if (> (setq pt - (previous-single-char-property-change - pt 'preview-state)) (point-min)) - (get-char-property (1- pt) 'preview-state) - (throw 'exit (or history (point-min)))) - (if (< (setq pt - (next-single-char-property-change - pt 'preview-state)) (point-max)) - (get-char-property pt 'preview-state) - (throw 'exit (or history (point-max)))))) - '(active inactive))) - (setq history (and (not preview-state) pt))) - (or history pt)))) - -(defun preview-at-point () - "Do the appropriate preview thing at point. -If point is positioned on or inside of an unmodified preview area, -its visibility is toggled. - -If not, the surroundings are run through preview. The -surroundings don't extend into unmodified previews or past -contiguous previews invalidated by modifications. - -Overriding any other action, if a region is -active (`transient-mark-mode'), it is run through `preview-region'." - (interactive) - (if (TeX-active-mark) - (preview-region (region-beginning) (region-end)) - (catch 'exit - (dolist (ovr (overlays-in (max (point-min) (1- (point))) - (min (point-max) (1+ (point))))) - (let ((preview-state (overlay-get ovr 'preview-state))) - (when preview-state - (unless (eq preview-state 'disabled) - (preview-toggle ovr 'toggle (selected-window)) - (throw 'exit t))))) - (preview-region (preview-next-border t) - (preview-next-border nil))))) - -(defun preview-disabled-string (ov) - "Generate a before-string for disabled preview overlay OV." - (concat (preview-make-clickable - (overlay-get ov 'preview-map) - preview-icon - "\ -%s regenerates preview -%s more options" - (lambda () (interactive) (preview-regenerate ov))) -;; icon on separate line only for stuff starting on its own line - (with-current-buffer (overlay-buffer ov) - (save-excursion - (save-restriction - (widen) - (goto-char (overlay-start ov)) - (if (bolp) "\n" "")))))) - -(defun preview-disable (ovr) - "Change overlay behaviour of OVR after source edits." - (overlay-put ovr 'queued nil) - (preview-remove-urgentization ovr) - (overlay-put ovr 'preview-image nil) - (overlay-put ovr 'timestamp nil) - (setcdr (overlay-get ovr 'strings) (preview-disabled-string ovr)) - (preview-toggle ovr) - (overlay-put ovr 'preview-state 'disabled) - (dolist (filename (overlay-get ovr 'filenames)) - (condition-case nil - (preview-delete-file filename) - (file-error nil)) - (overlay-put ovr 'filenames nil))) - -(defun preview-delete (ovr &rest _ignored) - "Delete preview overlay OVR, taking any associated file along. -IGNORED arguments are ignored, making this function usable as -a hook in some cases" - (let ((filenames (overlay-get ovr 'filenames))) - (overlay-put ovr 'filenames nil) - (delete-overlay ovr) - (dolist (filename filenames) - (condition-case nil - (preview-delete-file filename) - (file-error nil))))) - -(defun preview-clearout (&optional start end timestamp) - "Clear out all previews in the current region. -When called interactively, the current region is used. -Non-interactively, the region between START and END is -affected. Those two values default to the borders of -the entire buffer. If TIMESTAMP is non-nil, previews -with a `timestamp' property of it are kept." - (interactive "r") - (dolist (ov (overlays-in (or start (point-min)) - (or end (point-max)))) - (and (overlay-get ov 'preview-state) - (not (and timestamp - (equal timestamp (overlay-get ov 'timestamp)))) - (preview-delete ov)))) - -(defun preview-clearout-buffer (&optional buffer) - "Clearout BUFFER from previews, current buffer if nil." - (interactive) - (if buffer - (with-current-buffer buffer (preview-clearout)) - (preview-clearout))) - -(defun preview-clearout-section () - "Clearout previews from LaTeX section." - (interactive) - (save-excursion - (LaTeX-mark-section) - (preview-clearout (region-beginning) (region-end)))) - -(defun preview-clearout-at-point () - "Clearout any preview at point." - (interactive) - (preview-clearout (max (point-min) (1- (point))) - (min (point-max) (1+ (point))))) - -(defun preview-walk-document (func) - "Cycle through all buffers belonging to current document. -Each buffer having the same master file as the current file -has FUNC called with its current buffer being set to it." - (let* ((buffers (buffer-list)) - (master (expand-file-name (TeX-master-file t))) - (default-buffers (list (current-buffer) - (find-buffer-visiting master)))) - (while buffers - (with-current-buffer (pop buffers) - (when - (or (memq (current-buffer) default-buffers) - (and (memq major-mode '(plain-tex-mode latex-mode)) - (or (stringp TeX-master) - (eq TeX-master t)) - (string= (expand-file-name (TeX-master-file t)) - master))) - (funcall func)))))) - -(defun preview-clearout-document () - "Clear out all previews in current document. -The document consists of all buffers that have the same master file -as the current buffer. This makes the current document lose -all previews." - (interactive) - (preview-walk-document #'preview-clearout-buffer)) - -(defun preview-kill-buffer-cleanup (&optional buf) - "This is a cleanup function just for use in hooks. -Cleans BUF or current buffer. The difference to -`preview-clearout-buffer' is that previews -associated with the last buffer modification time are -kept." - (with-current-buffer (or buf (current-buffer)) - (save-restriction - (widen) - (preview-clearout (point-min) (point-max) (visited-file-modtime))))) - -(add-hook 'kill-buffer-hook #'preview-kill-buffer-cleanup) -(add-hook 'before-revert-hook #'preview-kill-buffer-cleanup) - -(defvar preview-last-counter nil - "Last counter information.") - -(defun preview-extract-counters (ctr) - (setq preview-last-counter - (prog1 (copy-sequence ctr) - (dolist (elt preview-last-counter) - (setq ctr (delete elt ctr))))) - (apply #'concat ctr)) - -(defun desktop-buffer-preview-misc-data (&rest _ignored) - "Hook function that extracts previews for persistent sessions." - (unless (buffer-modified-p) - (setq preview-last-counter nil) - (save-restriction - (widen) - (let (save-info (timestamp (visited-file-modtime))) - (dolist (ov (sort (overlays-in (point-min) (point-max)) - (lambda (x y) (< (overlay-start x) - (overlay-start y))))) - (when (and (memq (overlay-get ov 'preview-state) '(active inactive)) - (null (overlay-get ov 'queued)) - (cdr (overlay-get ov 'preview-image))) - (push (preview-dissect ov timestamp) save-info))) - (and save-info - (cons 'preview (cons timestamp (nreverse save-info)))))))) - -(eval-after-load "desktop" - '(add-hook - 'desktop-buffer-misc-functions - #'desktop-buffer-preview-misc-data)) - -(defvar preview-temp-dirs nil -"List of top level temporary directories in use from preview. -Any directory not in this list will be cleared out by preview -on first use.") - -(defun preview-dissect (ov timestamp) - "Extract all persistent data from OV and TIMESTAMP it." - (let ((filenames (butlast (nth 0 (overlay-get ov 'filenames))))) - (overlay-put ov 'timestamp timestamp) - (list (overlay-start ov) - (overlay-end ov) - (cdr (overlay-get ov 'preview-image)) - filenames - (let ((ctr (overlay-get ov 'preview-counters))) - (and ctr - (cons (preview-extract-counters (car ctr)) - (preview-extract-counters (cdr ctr)))))))) - -(defun preview-buffer-restore-internal (buffer-misc) - "Restore previews from BUFFER-MISC if proper. -Remove them if they have expired." - (let ((timestamp (visited-file-modtime)) tempdirlist files) - (setq preview-parsed-counters nil) - (when (eq 'preview (pop buffer-misc)) - (preview-get-geometry) - (if (equal (pop buffer-misc) timestamp) - (dolist (ovdata buffer-misc) - (setq tempdirlist - (apply #'preview-reinstate-preview tempdirlist - timestamp ovdata))) - (dolist (ovdata buffer-misc) - (setq files (nth 3 ovdata)) - (condition-case nil - (delete-file (nth 0 files)) - (file-error nil)) - (unless (member (nth 1 files) tempdirlist) - (push (nth 1 files) tempdirlist))) - (dolist (dir tempdirlist) - (condition-case nil - (delete-directory dir) - (file-error nil))))))) - - -(defun preview-buffer-restore (buffer-misc) - "At end of desktop load, reinstate previews. -This delay is so that minor modes changing buffer positions -\(like `x-symbol-mode' does) will not wreak havoc. -BUFFER-MISC is the appropriate data to be used." - (add-hook 'desktop-delay-hook - (let ((buf (current-buffer))) - (lambda () - (with-current-buffer buf - (preview-buffer-restore-internal - buffer-misc)))))) - -(defun desktop-buffer-preview (file-name _buffer-name misc) - "Hook function for restoring persistent previews into a buffer." - (when (and file-name (file-readable-p file-name)) - (let ((buf (find-file-noselect file-name))) - (if (eq (car misc) 'preview) - (with-current-buffer buf - (preview-buffer-restore misc) - buf) - buf)))) - -(eval-after-load "desktop" - '(if (boundp 'desktop-buffer-mode-handlers) - (add-to-list 'desktop-buffer-mode-handlers - '(latex-mode . desktop-buffer-preview)) - (defvar desktop-buffer-file-name) - (defvar desktop-buffer-name) - (defvar desktop-buffer-misc) - (add-hook 'desktop-buffer-handlers (lambda () - (desktop-buffer-preview - desktop-buffer-file-name - desktop-buffer-name - desktop-buffer-misc))))) - -(defcustom preview-auto-cache-preamble 'ask - "Whether to generate a preamble cache format automatically. -Possible values are nil, t, and `ask'." - :group 'preview-latex - :type '(choice (const :tag "Cache" t) - (const :tag "Don't cache" nil) - (const :tag "Ask" ask))) - -(defvar preview-dumped-alist nil - "Alist of dumped masters. -The elements are (NAME . ASSOC). NAME is the master file name -\(without extension), ASSOC is what to do with regard to this -format. Possible values: nil means no format is available -and none should be generated. t means no format is available, -it should be generated on demand. If the value is a cons cell, -the CAR of the cons cell is the command with which the format -has been generated, and the CDR is some Emacs-flavor specific -value used for maintaining a watch on possible changes of the -preamble.") - -(defun preview-cleanout-tempfiles () - "Clean out all directories and files with non-persistent data. -This is called as a hook when exiting Emacs." - (mapc #'preview-kill-buffer-cleanup (buffer-list)) - (mapc #'preview-format-kill preview-dumped-alist)) - -(defun preview-inactive-string (ov) - "Generate before-string for an inactive preview overlay OV. -This is for overlays where the source text has been clicked -visible. For efficiency reasons it is expected that the buffer -is already selected and unnarrowed." - (concat - (preview-make-clickable (overlay-get ov 'preview-map) - preview-icon - "\ -%s redisplays preview -%s more options") -;; icon on separate line only for stuff starting on its own line - (with-current-buffer (overlay-buffer ov) - (save-excursion - (save-restriction - (widen) - (goto-char (overlay-start ov)) - (if (bolp) "\n" "")))))) - -(defun preview-dvipng-place-all () - "Place all images dvipng has created, if any. -Deletes the dvi file when finished." - (let (filename queued oldfiles snippet) - (dolist (ov (prog1 preview-gs-queue (setq preview-gs-queue nil))) - (when (and (setq queued (overlay-get ov 'queued)) - (setq snippet (aref (overlay-get ov 'queued) 2)) - (setq filename (preview-make-filename - (format "prev%03d.%s" - snippet preview-dvipng-image-type) - TeX-active-tempdir))) - (if (file-exists-p (car filename)) - (progn - (overlay-put ov 'filenames (list filename)) - (preview-replace-active-icon - ov - (preview-create-icon (car filename) - preview-dvipng-image-type - (preview-ascent-from-bb - (aref queued 0)) - (aref preview-colors 2))) - (overlay-put ov 'queued nil)) - (push filename oldfiles) - (overlay-put ov 'filenames nil) - (push ov preview-gs-queue)))) - (if (setq preview-gs-queue (nreverse preview-gs-queue)) - (progn - (preview-start-dvips preview-fast-conversion) - (setq TeX-sentinel-function (lambda (process command) - (preview-gs-dvips-sentinel - process - command - t))) - (dolist (ov preview-gs-queue) - (setq snippet (aref (overlay-get ov 'queued) 2)) - (overlay-put ov 'filenames - (list - (preview-make-filename - (or preview-ps-file - (format "preview.%03d" snippet)) - TeX-active-tempdir)))) - (while (setq filename (pop oldfiles)) - (condition-case nil - (preview-delete-file filename) - (file-error nil)))) - (condition-case nil - (let ((gsfile preview-gs-file)) - (delete-file - (with-current-buffer TeX-command-buffer - (funcall (car gsfile) "dvi" t)))) - (file-error nil))))) - -(defun preview-active-string (ov) - "Generate before-string for active image overlay OV." - (preview-make-clickable - (overlay-get ov 'preview-map) - (car (overlay-get ov 'preview-image)) - "%s opens text -%s more options")) - -(defun preview-make-filename (file tempdir) - "Generate a preview filename from FILE and TEMPDIR. -Filenames consist of a CONS-cell with absolute file name as CAR -and TEMPDIR as CDR. TEMPDIR is a copy of `TeX-active-tempdir' -with the directory name, the reference count and its top directory -name elements. If FILE is already in that form, the file name itself -gets converted into a CONS-cell with a name and a reference count." - (if (consp file) - (progn - (if (consp (car file)) - (setcdr (car file) (1+ (cdr (car file)))) - (setcar file (cons (car file) 1))) - file) - (setcar (nthcdr 2 tempdir) (1+ (nth 2 tempdir))) - (cons (expand-file-name file (nth 0 tempdir)) - tempdir))) - -(defun preview-attach-filename (attached file) - "Attaches the absolute file name ATTACHED to FILE." - (if (listp (caar file)) - (setcar (car file) (cons attached (caar file))) - (setcar (car file) (list attached (caar file)))) - file) - -(defun preview-delete-file (file) - "Delete a preview FILE. -See `preview-make-filename' for a description of the data -structure. If the containing directory becomes empty, -it gets deleted as well." - (let ((filename - (if (consp (car file)) - (and (zerop - (setcdr (car file) (1- (cdr (car file))))) - (car (car file))) - (car file)))) - (if filename - (unwind-protect - (if (listp filename) - (dolist (elt filename) (delete-file elt)) - (delete-file filename)) - (let ((tempdir (cdr file))) - (when tempdir - (if (> (nth 2 tempdir) 1) - (setcar (nthcdr 2 tempdir) (1- (nth 2 tempdir))) - (setcdr file nil) - (delete-directory (nth 0 tempdir))))))))) - -(defvar preview-buffer-has-counters nil) -(make-variable-buffer-local 'preview-buffer-has-counters) - -(defun preview-place-preview (snippet start end - box counters tempdir place-opts) - "Generate and place an overlay preview image. -This generates the filename for the preview -snippet SNIPPET in the current buffer, and uses it for the -region between START and END. BOX is an optional preparsed -TeX bounding BOX passed on to the `place' hook. -COUNTERS is the info about saved counter structures. -TEMPDIR is a copy of `TeX-active-tempdir'. -PLACE-OPTS are additional arguments passed into -`preview-parse-messages'. Return -a list with additional info from the placement hook. -Those lists get concatenated together and get passed -to the close hook." - (preview-clearout start end tempdir) - (let ((ov (make-overlay start end nil nil nil))) - (overlay-put ov 'priority (TeX-overlay-prioritize start end)) - (overlay-put ov 'preview-map - (preview-make-clickable - nil nil nil - (lambda (event) (interactive "e") - (preview-toggle ov 'toggle event)) - (lambda (event) (interactive "e") - (preview-context-menu ov event)))) - (overlay-put ov 'timestamp tempdir) - (when (cdr counters) - (overlay-put ov 'preview-counters counters) - (setq preview-buffer-has-counters t)) - (prog1 (apply #'preview-call-hook 'place ov snippet box - place-opts) - (overlay-put ov 'strings - (list (preview-active-string ov))) - (preview-toggle ov t)))) - -(defun preview-counter-find (begin) - "Fetch the next preceding or next preview-counters property. -Factored out because of compatibility macros XEmacs would -not use in advice." - (or (car (get-char-property begin 'preview-counters)) - (cdr (get-char-property (max (point-min) - (1- begin)) - 'preview-counters)) - (cdr (get-char-property - (max (point-min) - (1- (previous-single-char-property-change - begin - 'preview-counters))) - 'preview-counters)) - (car (get-char-property - (next-single-char-property-change begin 'preview-counters) - 'preview-counters)))) - -(defun preview--counter-information (begin) - "Return repeated \\setcounter declaration based on point BEGIN. -If `preview-buffer-has-counters' is non-nil, return string to -insert into region tex file containing as many -\\setcounter{COUNTER}{VALUE} as possible built from -`preview-counters' property near the point BEGIN. Otherwise, -return nil." - (if preview-buffer-has-counters - (mapconcat - #'identity - (cons - "" - (preview-counter-find begin)) - "\\setcounter"))) - -(defun preview-reinstate-preview (tempdirlist timestamp start end - image filename &optional counters) - "Reinstate a single preview. -This gets passed TEMPDIRLIST, a list consisting of the kind -of entries used in `TeX-active-tempdir', and TIMESTAMP, the -time stamp under which the file got read in. It returns an augmented -list. START and END give the buffer location where the preview -is to be situated, IMAGE the image to place there, and FILENAME -the file to use: a triple consisting of filename, its temp directory -and the corresponding topdir. COUNTERS is saved counter information, -if any." - (when - (or (null filename) (file-readable-p (car filename))) - (when filename - (unless (equal (nth 1 filename) (car TeX-active-tempdir)) - (setq TeX-active-tempdir - (or (assoc (nth 1 filename) tempdirlist) - (car (push (append (cdr filename) (list 0)) - tempdirlist)))) - (setcar (cdr TeX-active-tempdir) - (car (or (member (nth 1 TeX-active-tempdir) - preview-temp-dirs) - (progn - (add-hook 'kill-emacs-hook - #'preview-cleanout-tempfiles t) - (push (nth 1 TeX-active-tempdir) - preview-temp-dirs)))))) - (setcar (nthcdr 2 TeX-active-tempdir) - (1+ (nth 2 TeX-active-tempdir))) - (setcdr filename TeX-active-tempdir) - (setq filename (list filename))) - (let ((ov (make-overlay start end nil nil nil))) - (overlay-put ov 'priority (TeX-overlay-prioritize start end)) - (overlay-put ov 'preview-map - (preview-make-clickable - nil nil nil - (lambda (event) (interactive "e") - (preview-toggle ov 'toggle event)) - (lambda (event) (interactive "e") - (preview-context-menu ov event)))) - (when counters - (overlay-put - ov 'preview-counters - (cons - (mapcar #'cdr - (if (string= (car counters) "") - preview-parsed-counters - (setq preview-parsed-counters - (preview-parse-counters (car counters))))) - (mapcar #'cdr - (if (string= (cdr counters) "") - preview-parsed-counters - (setq preview-parsed-counters - (preview-parse-counters (cdr counters))))))) - (setq preview-buffer-has-counters t)) - (overlay-put ov 'filenames filename) - (overlay-put ov 'preview-image (cons (preview-import-image image) - image)) - (overlay-put ov 'strings - (list (preview-active-string ov))) - (overlay-put ov 'timestamp timestamp) - (preview-toggle ov t))) - tempdirlist) - -(defun preview-back-command (&optional nocomplex) - "Move backward a TeX token. -If NOCOMPLEX is set, only basic tokens and no argument sequences -will be skipped over backwards." - (let ((oldpos (point)) oldpoint) - (condition-case nil - (or (search-backward-regexp "\\(\\$\\$?\ -\\|\\\\[^a-zA-Z@]\ -\\|\\\\[a-zA-Z@]+\ -\\|\\\\begin[ \t]*{[^}]+}\ -\\)\\=" (line-beginning-position) t) - nocomplex - (if (eq ?\) (char-syntax (char-before))) - (while - (progn - (setq oldpoint (point)) - (backward-sexp) - (and (not (eq oldpoint (point))) - (eq ?\( (char-syntax (char-after)))))) - (backward-char))) - (error (goto-char oldpos))))) - -(defcustom preview-required-option-list '("active" "tightpage" "auctex" - (preview-preserve-counters - "counters")) - "Specifies required options passed to the preview package. -These are passed regardless of whether there is an explicit -\\usepackage of that package present." - :group 'preview-latex - :type preview-expandable-string) - -(defcustom preview-preserve-counters nil - "Try preserving counters for partial runs if set." - :group 'preview-latex - :type 'boolean) - -(defcustom preview-default-option-list '("displaymath" "floats" - "graphics" "textmath" "sections" - "footnotes") - "Specifies default options to pass to preview package. -These options are only used when the LaTeX document in question does -not itself load the preview package, namely when you use preview -on a document not configured for preview. \"auctex\", \"active\", -\"dvips\" and \"delayed\" need not be specified here." - :group 'preview-latex - :type '(list (set :inline t :tag "Options known to work" - :format "%t:\n%v%h" :doc - "The above options are all the useful ones -at the time of the release of this package. -You should not need \"Other options\" unless you -upgraded to a fancier version of just the LaTeX style. -Please also note that `psfixbb' fails to have an effect if -`preview-fast-conversion' or `preview-prefer-TeX-bb' -are selected." - (const "displaymath") - (const "floats") - (const "graphics") - (const "textmath") - (const "sections") - (const "footnotes") - (const "showlabels") - (const "psfixbb")) - (set :tag "Expert options" :inline t - :format "%t:\n%v%h" :doc - "Expert options should not be enabled permanently." - (const "noconfig") - (const "showbox") - (const "tracingall")) - (repeat :inline t :tag "Other options" (string)))) - -(defcustom preview-default-preamble - '("\\RequirePackage[" ("," . preview-default-option-list) - "]{preview}[2004/11/05]") - "Specifies default preamble code to add to a LaTeX document. -If the document does not itself load the preview package, that is, -when you use preview on a document not configured for preview, this -list of LaTeX commands is inserted just before \\begin{document}." - :group 'preview-latex - :type preview-expandable-string) - -(defcustom preview-LaTeX-command '("%`%l \"\\nonstopmode\\nofiles\ -\\PassOptionsToPackage{" ("," . preview-required-option-list) "}{preview}\ -\\AtBeginDocument{\\ifx\\ifPreview\\undefined" -preview-default-preamble "\\fi}\"%' \"\\detokenize{\" %(t-filename-only) \"}\"") - ;; Since TeXLive 2018, the default encoding for LaTeX files has been - ;; changed to UTF-8 if used with classic TeX or pdfTeX. I.e., - ;; \usepackage[utf8]{inputenc} is enabled by default in (pdf)latex. - ;; c.f. LaTeX News issue 28 - ;; Due to this change, \detokenize is required to recognize - ;; non-ascii characters in the file name when \input is supplemented - ;; implicitly by %`-%' pair. - "Command used for starting a preview. -See description of `TeX-command-list' for details." - :group 'preview-latex - :type preview-expandable-string) - -(defun preview-goto-info-page () - "Read documentation for preview-latex in the info system." - (interactive) - (info "(preview-latex)")) - -(eval-after-load 'info '(add-to-list 'Info-file-list-for-emacs - '("preview" . "preview-latex"))) - -(defvar preview-map - (let ((map (make-sparse-keymap))) - (define-key map "\C-p" #'preview-at-point) - (define-key map "\C-r" #'preview-region) - (define-key map "\C-b" #'preview-buffer) - (define-key map "\C-d" #'preview-document) - (define-key map "\C-f" #'preview-cache-preamble) - (define-key map "\C-c\C-f" #'preview-cache-preamble-off) - (define-key map "\C-i" #'preview-goto-info-page) - ;; (define-key map "\C-q" #'preview-paragraph) - (define-key map "\C-e" #'preview-environment) - (define-key map "\C-s" #'preview-section) - (define-key map "\C-w" #'preview-copy-region-as-mml) - (define-key map "\C-c\C-p" #'preview-clearout-at-point) - (define-key map "\C-c\C-r" #'preview-clearout) - (define-key map "\C-c\C-s" #'preview-clearout-section) - (define-key map "\C-c\C-b" #'preview-clearout-buffer) - (define-key map "\C-c\C-d" #'preview-clearout-document) - map)) - -(defun preview-copy-text (ov) - "Copy the text of OV into the kill buffer." - (with-current-buffer (overlay-buffer ov) - (copy-region-as-kill (overlay-start ov) (overlay-end ov)))) - -(defun preview-copy-mml (ov) - "Copy an MML representation of OV into the kill buffer. -This can be used to send inline images in mail and news when -using MML mode." - (when (catch 'badcolor - (let ((str (car (preview-format-mml ov)))) - (if str - (if (eq last-command #'kill-region) - (kill-append str nil) - (kill-new str)) - (error "No image file available"))) - nil) - (let (preview-transparent-border) - (preview-regenerate ov)))) - -(defun preview-copy-region-as-mml (start end) - (interactive "r") - (when (catch 'badcolor - (let (str lst dont-ask) - (dolist (ov (overlays-in start end)) - (when (setq str (preview-format-mml ov dont-ask)) - (setq dont-ask (cdr str)) - (and - (>= (overlay-start ov) start) - (<= (overlay-end ov) end) - (push (list (- (overlay-start ov) start) - (- (overlay-end ov) start) - (car str)) lst)))) - (setq str (buffer-substring start end)) - (dolist (elt (nreverse (sort lst #'car-less-than-car))) - (setq str (concat (substring str 0 (nth 0 elt)) - (nth 2 elt) - (substring str (nth 1 elt))))) - (if (eq last-command #'kill-region) - (kill-append str nil) - (kill-new str))) - nil) - (let (preview-transparent-border) - (preview-region start end)))) - -(autoload 'mailcap-extension-to-mime "mailcap") - -(defun preview-format-mml (ov &optional dont-ask) - "Return an MML representation of OV as string. -This can be used to send inline images in mail and news when -using MML mode. If there is nothing current available, -nil is returned. If the image has a colored border and the -user wants it removed when asked (unless DONT-ASK is set), -`badcolor' is thrown a t. The MML is returned in the car of the -result, DONT-ASK in the cdr." - (and (memq (overlay-get ov 'preview-state) '(active inactive)) - (not (overlay-get ov 'queued)) - (let* ((text (with-current-buffer (overlay-buffer ov) - (buffer-substring (overlay-start ov) - (overlay-end ov)))) - (image (cdr (overlay-get ov 'preview-image))) - file type) - (cond ((consp image) - (and (not dont-ask) - (nth 3 image) - (if (y-or-n-p "Replace colored borders? ") - (throw 'badcolor t) - (setq dont-ask t))) - (setq file (car (car (last (overlay-get ov 'filenames)))) - type (mailcap-extension-to-mime - (file-name-extension file))) - (cons - (format "<#part %s -description=\"%s\" -filename=%s> -<#/part>" - (if type - (format "type=\"%s\" disposition=inline" type) - "disposition=attachment") - (if (string-match "[\n\"]" text) - "preview-latex image" - text) - (if (string-match "[ \n<>]" file) - (concat "\"" file "\"") - file)) - dont-ask)) - ((stringp image) - (cons image dont-ask)))))) - -(defun preview-active-contents (ov) - "Check whether we have a valid image associated with OV." - (and (memq (overlay-get ov 'preview-state) '(active inactive)) t)) - -(defun preview-context-menu (ov ev) - "Pop up a menu for OV at position EV." - (popup-menu - `("Preview" - ["Toggle" (preview-toggle ,ov 'toggle ',ev) - (preview-active-contents ,ov)] - ["Regenerate" (preview-regenerate ,ov)] - ["Remove" (preview-delete ,ov)] - ["Copy text" (preview-copy-text ,ov)] - ["Copy MIME" (preview-copy-mml ,ov) - (preview-active-contents ,ov)]) - ev)) - -(defvar preview-TeX-style-dir) - -(defun preview-TeX-style-cooked () - "Return `preview-TeX-style-dir' in cooked form. -This will be fine for prepending to a `TEXINPUTS' style -environment variable, including an initial `.' at the front." - (if (or (zerop (length preview-TeX-style-dir)) - (member (substring preview-TeX-style-dir -1) '(";" ":"))) - preview-TeX-style-dir - (let ((sep - (cond - ((stringp TeX-kpathsea-path-delimiter) - TeX-kpathsea-path-delimiter) - ((string-match - "\\`.[:]" - (if (file-name-absolute-p preview-TeX-style-dir) - preview-TeX-style-dir - (expand-file-name preview-TeX-style-dir))) - ";") - (t ":")))) - (concat "." sep preview-TeX-style-dir sep)))) - -(defun preview-set-texinputs (&optional remove) - "Add `preview-TeX-style-dir' into `TEXINPUTS' variables. -With prefix argument REMOVE, remove it again." - (interactive "P") - (let ((case-fold-search nil) - (preview-TeX-style-dir (preview-TeX-style-cooked)) - pattern) - (if remove - (progn - (setq pattern (concat "\\`\\(TEXINPUTS[^=]*\\)=\\(.*\\)" - (regexp-quote preview-TeX-style-dir))) - (dolist (env (copy-sequence process-environment)) - (if (string-match pattern env) - (setenv (match-string 1 env) - (and (or (< (match-beginning 2) (match-end 2)) - (< (match-end 0) (length env))) - (concat (match-string 2 env) - (substring env (match-end 0)))))))) - (setq pattern (regexp-quote preview-TeX-style-dir)) - (dolist (env (cons "TEXINPUTS=" (copy-sequence process-environment))) - (if (string-match "\\`\\(TEXINPUTS[^=]*\\)=" env) - (unless (save-match-data (string-match pattern env)) - (setenv (match-string 1 env) - (concat preview-TeX-style-dir - (substring env (match-end 0)))))))))) - -(defcustom preview-TeX-style-dir nil - "This variable contains the location of uninstalled TeX styles. -If this is nil, the preview styles are considered to be part of -the installed TeX system. - -Otherwise, it can either just specify an absolute directory, or -it can be a complete TEXINPUTS specification. If it is the -latter, it has to be followed by the character with which -kpathsea separates path components, either `:' on Unix-like -systems, or `;' on Windows-like systems. And it should be -preceded with .: or .; accordingly in order to have . first in -the search path. - -The `TEXINPUTS' environment type variables will get this prepended -at load time calling \\[preview-set-texinputs] to reflect this. -You can permanently install the style files using -\\[preview-install-styles]. - -Don't set this variable other than with customize so that its -changes get properly reflected in the environment." - :group 'preview-latex - :set (lambda (var value) - (and (boundp var) - (symbol-value var) - (preview-set-texinputs t)) - (set var value) - (and (symbol-value var) - (preview-set-texinputs))) - :type '(choice (const :tag "Installed" nil) - (string :tag "Style directory or TEXINPUTS path"))) - -;;;###autoload -(defun preview-install-styles (dir &optional force-overwrite - force-save) - "Installs the TeX style files into a permanent location. -This must be in the TeX search path. If FORCE-OVERWRITE is greater -than 1, files will get overwritten without query, if it is less -than 1 or nil, the operation will fail. The default of 1 for interactive -use will query. - -Similarly FORCE-SAVE can be used for saving -`preview-TeX-style-dir' to record the fact that the uninstalled -files are no longer needed in the search path." - (interactive "DPermanent location for preview TeX styles -pp") - (unless preview-TeX-style-dir - (error "Styles are already installed")) - (dolist (file (or - (condition-case nil - (directory-files - (progn - (string-match - "\\`\\(\\.[:;]\\)?\\(.*?\\)\\([:;]\\)?\\'" - preview-TeX-style-dir) - (match-string 2 preview-TeX-style-dir)) - t "\\.\\(sty\\|def\\|cfg\\)\\'") - (error nil)) - (error "Can't find files to install"))) - (copy-file file dir (cond ((eq force-overwrite 1) 1) - ((numberp force-overwrite) - (> force-overwrite 1)) - (t force-overwrite)))) - (if (cond ((eq force-save 1) - (y-or-n-p "Stop using non-installed styles permanently ")) - ((numberp force-save) - (> force-save 1)) - (t force-save)) - (customize-save-variable 'preview-TeX-style-dir nil) - (customize-set-variable 'preview-TeX-style-dir nil))) - -(defun preview-mode-setup () - "Setup proper buffer hooks and behavior for previews." - (set (make-local-variable 'desktop-save-buffer) - #'desktop-buffer-preview-misc-data) - (add-hook 'pre-command-hook #'preview-mark-point nil t) - (add-hook 'post-command-hook #'preview-move-point nil t) - (when buffer-file-name - (let* ((filename (expand-file-name buffer-file-name)) - format-cons) - (when (string-match (concat "\\." TeX-default-extension "\\'") - filename) - (setq filename (substring filename 0 (match-beginning 0)))) - (setq format-cons (assoc filename preview-dumped-alist)) - (when (consp (cdr format-cons)) - (preview-unwatch-preamble format-cons) - (preview-watch-preamble (current-buffer) - (cadr format-cons) - format-cons))))) - -;;;###autoload -(defun LaTeX-preview-setup () - "Hook function for embedding the preview package into AUCTeX. -This is called by `LaTeX-mode-hook' and changes AUCTeX variables -to add the preview functionality." - ;; This has to be done only once. - (unless (and (boundp 'LaTeX-mode-hook) - (memq #'preview-mode-setup LaTeX-mode-hook)) - (remove-hook 'LaTeX-mode-hook #'LaTeX-preview-setup) - (add-hook 'LaTeX-mode-hook #'preview-mode-setup) - (define-key LaTeX-mode-map "\C-c\C-p" preview-map) - (easy-menu-define preview-menu LaTeX-mode-map - "This is the menu for preview-latex." - '("Preview" - "Generate previews" - ["(or toggle) at point" preview-at-point] - ["for environment" preview-environment] - ["for section" preview-section] - ["for region" preview-region mark-active] - ["for buffer" preview-buffer] - ["for document" preview-document] - "---" - "Remove previews" - ["at point" preview-clearout-at-point] - ["from section" preview-clearout-section] - ["from region" preview-clearout mark-active] - ["from buffer" preview-clearout-buffer] - ["from document" preview-clearout-document] - "---" - "Turn preamble cache" - ["on" preview-cache-preamble] - ["off" preview-cache-preamble-off] - "---" - ("Customize" - ["Browse options" - (customize-group 'preview)] - ["Extend this menu" - (easy-menu-add-item - nil '("Preview") - (customize-menu-create 'preview))]) - ["Read documentation" preview-goto-info-page] - ["Report Bug" preview-report-bug])) - (if (eq major-mode 'latex-mode) - (preview-mode-setup)) - (unless preview-tb-icon - (setq preview-tb-icon (preview-filter-specs preview-tb-icon-specs))) - (when preview-tb-icon - (define-key LaTeX-mode-map [tool-bar preview] - `(menu-item "Preview at point" preview-at-point - :image ,preview-tb-icon - :help "Preview on/off at point" - :vert-only t))) - (if (boundp 'desktop-buffer-misc) - (preview-buffer-restore desktop-buffer-misc)))) - -(defun preview-clean-subdir (dir) - "Cleans out a temporary DIR with preview image files." - (condition-case err - (progn - (mapc #'delete-file - (directory-files dir t "\\`pr" t)) - (delete-directory dir)) - (error (message "Deletion of `%s' failed: %s" dir - (error-message-string err))))) - -(defun preview-clean-topdir (topdir) - "Cleans out TOPDIR from temporary directories. -This does not erase the directory itself since its permissions -might be needed for colloborative work on common files." - (mapc #'preview-clean-subdir - (condition-case nil - (directory-files topdir t "\\`tmp" t) - (file-error nil)))) - -(defun preview-create-subdirectory () - "Create a temporary subdir for the current TeX process. -If necessary, generates a fitting top -directory or cleans out an existing one (if not yet -visited in this session), then returns the name of -the created subdirectory relative to the master directory, -in shell-quoted form. `TeX-active-tempdir' is -set to the corresponding TEMPDIR descriptor as described -in `preview-make-filename'. The directory is registered -in `preview-temp-dirs' in order not to be cleaned out -later while in use." - (let ((topdir (expand-file-name (TeX-active-master "prv")))) - (if (file-directory-p topdir) - (unless (member topdir preview-temp-dirs) - ;; Cleans out the top preview directory by - ;; removing subdirs possibly left from a previous session. - (preview-clean-topdir topdir) - (push topdir preview-temp-dirs)) - (make-directory topdir) - (add-to-list 'preview-temp-dirs topdir)) - (add-hook 'kill-emacs-hook #'preview-cleanout-tempfiles t) - (setq TeX-active-tempdir - (list (make-temp-file (expand-file-name - "tmp" (file-name-as-directory topdir)) t) - topdir - 0)) - (shell-quote-argument - (concat (file-name-as-directory - ;; Don't use topdir, because %m expects the path to be - ;; relative to master - (TeX-active-master "prv" t)) - (file-name-nondirectory (nth 0 TeX-active-tempdir)))))) - -(defun preview-parse-counters (string) - "Extract counter information from STRING." - (let ((list preview-parsed-counters) (pos 0)) - (while (eq pos (string-match " *\\({\\([^{}]+\\)}{[-0-9]+}\\)" string pos)) - (setcdr (or (assoc (match-string 2 string) list) - (car (push (list (match-string 2 string)) list))) - (match-string 1 string)) - (setq pos (match-end 1))) - list)) - -(defun preview-parse-tightpage (string) - "Build tightpage vector from STRING," - (read (concat "[" string "]"))) - -(defvar preview-parse-variables - '(("Fontsize" preview-parsed-font-size - "\\` *\\([0-9.]+\\)pt\\'" 1 string-to-number) - ("Magnification" preview-parsed-magnification - "\\` *\\([0-9]+\\)\\'" 1 string-to-number) - ("PDFoutput" preview-parsed-pdfoutput - "" 0 stringp) - ("Counters" preview-parsed-counters - ".*" 0 preview-parse-counters) - ("Tightpage" preview-parsed-tightpage - "\\` *\\(-?[0-9]+ *\\)\\{4\\}\\'" 0 preview-parse-tightpage))) - -(defun preview-error-quote (string) - "Turn STRING with potential ^^ sequences into a regexp. -To preserve sanity, additional ^ prefixes are matched literally, -so the character represented by ^^^ preceding extended characters -will not get matched, usually." - (let (output case-fold-search) - ;; Some coding systems (e.g. japanese-shift-jis) use regexp meta - ;; characters on encoding. Such meta characters would be - ;; interfered with `regexp-quote' below. Thus the idea of - ;; "encoding entire string beforehand and decoding it at the last - ;; stage" does not work for such coding systems. - ;; Rather, we work consistently with decoded text. - - ;; Bytes with value from 0x80 to 0xFF represented with ^^ form are - ;; converted to byte sequence, and decoded by the file coding - ;; system. - (setq string - (preview--decode-^^ab string buffer-file-coding-system)) - - ;; Then, control characters are taken into account. - (while (string-match "\\^\\{2,\\}\\([@-_?]\\)" string) - (setq output - (concat output - (regexp-quote (substring string - 0 - (- (match-beginning 1) 2))) - (concat - "\\(?:" (regexp-quote - (substring string - (- (match-beginning 1) 2) - (match-end 0))) - "\\|" - (char-to-string - (logxor (aref string (match-beginning 1)) 64)) - "\\)")) - string (substring string (match-end 0)))) - (setq output (concat output (regexp-quote string))) - output)) - -(defun preview--decode-^^ab (string coding-system) - "Decode ^^ sequences in STRING with CODING-SYSTEM. -Sequences of control characters such as ^^I are left untouched. - -Return a new string." - ;; Since the given string can contain multibyte characters, decoding - ;; should be performed seperately on each segment made up entirely - ;; with ASCII and raw 8-bit characters. - ;; Raw 8-bit characters can arise if the latex outputs multibyte - ;; characters with partial ^^-quoting. - (let ((result "")) - ;; Here we want to collect all the ASCII and raw 8-bit bytes, - ;; excluding proper multibyte characters. The regexp - ;; [^[:multibyte:]]+ serves for that purpose. The alternative - ;; [\x00-\xFF]+ does the job as well at least for emacs 24-26, so - ;; use it instead if the former becomes invalid in future. - ;; N.B. [[:unibyte:]]+ doesn't match raw 8-bit bytes, contrary to - ;; naive expectation. - (while (string-match "[^[:multibyte:]]+" string) - (setq result - (concat result - (substring string 0 (match-beginning 0)) - (let ((text - (save-match-data - (preview--convert-^^ab - (match-string 0 string))))) - (decode-coding-string text coding-system))) - string (substring string (match-end 0)))) - (setq result (concat result string)) - result)) - -(defun preview--convert-^^ab (string) - "Convert ^^ sequences in STRING to raw 8bit. -Sequences of control characters such as ^^I are left untouched. - -Return a new string." - (let ((result "")) - (while (string-match "\\^\\^[8-9a-f][0-9a-f]" string) - (setq result - (concat result - (substring string 0 (match-beginning 0)) - (let ((byte (string-to-number - (substring string - (+ (match-beginning 0) 2) - (match-end 0)) 16))) - (byte-to-string byte))) - string (substring string (match-end 0)))) - (setq result (concat result string)) - result)) - -(defun preview-parse-messages (open-closure) - "Turn all preview snippets into overlays. -This parses the pseudo error messages from the preview -document style for LaTeX. OPEN-CLOSURE is called once -it is certain that we have a valid output file, and it has -to return in its CAR the PROCESS parameter for the CLOSE -call, and in its CDR the final stuff for the placement hook." - (with-temp-message "locating previews..." - (let (TeX-error-file TeX-error-offset snippet box counters - file line - (lsnippet 0) lstart (lfile "") lline lbuffer lpoint - lcounters - string after-string - offset - parsestate (case-fold-search nil) - (run-buffer (current-buffer)) - (run-directory default-directory) - tempdir - close-data - open-data - fast-hook - slow-hook - TeX-translate-location-file - TeX-translate-location-line - TeX-translate-location-error - TeX-translate-location-offset - TeX-translate-location-context - TeX-translate-location-string) - ;; clear parsing variables - (dolist (var preview-parse-variables) - (set (nth 1 var) nil)) - (goto-char (point-min)) - (unwind-protect - (progn - (while - (re-search-forward "\ -^\\(!\\|\\(.*?\\):[0-9]+:\\) \\|\ -\(\\(/*\ -\\(?:\\.+[^()\r\n{} /]*\\|[^()\r\n{} ./]+\ -\\(?: [^()\r\n{} ./]+\\)*\\(?:\\.[-0-9a-zA-Z_.]*\\)?\\)\ -\\(?:/+\\(?:\\.+[^()\r\n{} /]*\\|[^()\r\n{} ./]+\ -\\(?: [^()\r\n{} ./]+\\)*\\(?:\\.[-0-9a-zA-Z_.]*\\)?\\)?\\)*\\)\ -)*\\(?: \\|\r?$\\)\\|\ -\\()+\\)\\|\ - !\\(?:offset(\\([---0-9]+\\))\\|\ -name(\\([^)]+\\))\\)\\|\ -^Preview: \\([a-zA-Z]+\\) \\([^\n\r]*\\)\r?$" nil t) -;;; Ok, here is a line by line breakdown: -;;; match-alternative 1: -;;; error indicator for TeX error, either style. -;;; match-alternative 2: -;;; The same, but file-line-error-style, matching on file name. -;;; match-alternative 3: -;;; Too ugly to describe in detail. In short, we try to catch file -;;; names built from path components that don't contain spaces or -;;; other special characters once the file extension has started. -;;; -;;; Position for searching immediately after the file name so as to -;;; not miss closing parens or something. -;;; (match-string 3) is the file name. -;;; match-alternative 4: -;;; )+\( \|$\) -;;; a closing paren followed by the end of line or a space: a just -;;; closed file. -;;; match-alternative 5 (wrapped into one shy group with -;;; match-alternative 6, so that the match on first char is slightly -;;; faster): -;;; !offset(\([---0-9]+\)) -;;; an AUCTeX offset message. (match-string 5) is the offset itself -;;; !name(\([^)]+\)) -;;; an AUCTeX file name message. (match-string 6) is the file name -;;; TODO: Actually, the latter two should probably again match only -;;; after a space or newline, since that it what \message produces. -;;; disabled in prauctex.def: -;;; \(?:Ov\|Und\)erfull \\.*[0-9]*--[0-9]* -;;; \(?:.\{79\} -;;; \)*.*$\)\| -;;; This would have caught overfull box messages that consist of -;;; several lines of context all with 79 characters in length except -;;; of the last one. prauctex.def kills all such messages. - (setq file (match-string-no-properties 2)) - (cond - ((match-beginning 1) - (if (looking-at "\ -\\(?:Preview\\|Package Preview Error\\): Snippet \\([---0-9]+\\) \\(started\\|ended\\(\ -\\.? *(\\([---0-9]+\\)\\+\\([---0-9]+\\)x\\([---0-9]+\\))\\)?\\)\\.") - (progn - (when file - (unless TeX-error-file - (push nil TeX-error-file) - (push nil TeX-error-offset)) - (unless (car TeX-error-offset) - (rplaca TeX-error-file file))) - (setq snippet (string-to-number (match-string 1)) - box (unless - (string= (match-string 2) "started") - (if (match-string 4) - (mapcar #'(lambda (x) - (* (preview-get-magnification) - (string-to-number x))) - (list - (match-string 4) - (match-string 5) - (match-string 6))) - t)) - counters (mapcar #'cdr preview-parsed-counters) - - ;; And the line number to position the cursor. - line (progn - (setq lpoint (point)) - (end-of-line) -;;; variant 1: profiling seems to indicate the regexp-heavy solution -;;; to be favorable. Removing incomplete characters from the error -;;; context is an absolute nuisance. - (and (re-search-forward "\ -^l\\.\\([0-9]+\\) \\(\\.\\.\\.\\(?:\\^*\\(?:[89a-f][0-9a-f]\\|[]@-\\_?]\\)\\|\ -\[0-9a-f]?\\)\\)?\\([^\n\r]*?\\)\r? -\\([^\n\r]*?\\)\\(\\(?:\\^+[89a-f]?\\)?\\.\\.\\.\\)?\r?$" nil t) - (string-to-number (match-string 1)))) - ;; And a string of the context to search for. - string (and line (match-string 3)) - after-string (and line (buffer-substring - (+ (match-beginning 4) - (- (match-end 3) - (match-beginning 0))) - (match-end 4))) - - ;; We may use these in another buffer. - offset (or (car TeX-error-offset) 0) - file (car TeX-error-file)) - (when (and (stringp file) - (or (string= file "<none>") - (TeX-match-extension file))) - ;; if we are the first time round, check for fast hooks: - (when (null parsestate) - (setq open-data - (save-excursion (funcall open-closure)) - tempdir TeX-active-tempdir) - (dolist - (lst (if (listp TeX-translate-location-hook) - TeX-translate-location-hook - (list TeX-translate-location-hook))) - (let ((fast - (and (symbolp lst) - (get lst 'TeX-translate-via-list)))) - (if fast - (setq fast-hook - (nconc fast-hook (list fast))) - (setq slow-hook - (nconc slow-hook (list lst))))))) - ;; Functions in `TeX-translate-location-hook' - ;; may examine and modify the following variables. - (setq TeX-translate-location-file file - TeX-translate-location-line line - ;; TeX-translate-location-error error - TeX-translate-location-offset offset - ;; TeX-translate-location-context context - TeX-translate-location-string string) - (condition-case err - (save-excursion (mapc #'funcall slow-hook)) - (error (preview-log-error err "Translation hook"))) - (setq file TeX-translate-location-file - line TeX-translate-location-line - ;; error TeX-translate-location-error - offset TeX-translate-location-offset - ;; context TeX-translate-location-context - string TeX-translate-location-string) - (push (vector file (+ line offset) - string after-string - snippet box counters) - parsestate))) - ;; else normal error message - (forward-line) - (re-search-forward "^l\\.[0-9]" nil t) - (forward-line 2))) - ((match-beginning 3) - ;; New file -- Push on stack - (push (match-string-no-properties 3) TeX-error-file) - (push nil TeX-error-offset) - (goto-char (match-end 3))) - ((match-beginning 4) - ;; End of file -- Pop from stack - (when (> (length TeX-error-file) 1) - (pop TeX-error-file) - (pop TeX-error-offset)) - (goto-char (1+ (match-beginning 0)))) - ((match-beginning 5) - ;; Hook to change line numbers - (setq TeX-error-offset - (list (string-to-number (match-string 5))))) - ((match-beginning 6) - ;; Hook to change file name - (setq TeX-error-file (list (match-string-no-properties 6)))) - ((match-beginning 7) - (let ((var - (assoc (match-string-no-properties 7) - preview-parse-variables)) - (offset (- (match-beginning 0) (match-beginning 8))) - (str (match-string-no-properties 8))) - ;; paste together continuation lines: - (while (= (- (length str) offset) 79) - (search-forward-regexp "^\\([^\n\r]*\\)\r?$") - (setq offset (- (length str)) - str (concat str (match-string-no-properties 1)))) - (when (and var - (string-match (nth 2 var) str)) - (set (nth 1 var) - (funcall (nth 4 var) - (match-string-no-properties - (nth 3 var) - str)))))))) - (when (null parsestate) - (error "LaTeX found no preview images"))) - (unwind-protect - (save-excursion - (setq parsestate (nreverse parsestate)) - (condition-case err - (dolist (fun fast-hook) - (setq parsestate - (save-excursion (funcall fun parsestate)))) - (error (preview-log-error err "Fast translation hook"))) - (setq snippet 0) - (dolist (state parsestate) - (setq lsnippet snippet - file (aref state 0) - line (aref state 1) - string (aref state 2) - after-string (aref state 3) - snippet (aref state 4) - box (aref state 5) - counters (aref state 6)) - (unless (string= lfile file) - (set-buffer (if (string= file "<none>") - (with-current-buffer run-buffer - TeX-command-buffer) - (find-file-noselect - (expand-file-name file run-directory)))) - (setq lfile file)) - (save-excursion - (save-restriction - (widen) - ;; a fast hook might have positioned us already: - (if (number-or-marker-p string) - (progn - (goto-char string) - (setq lpoint - (if (number-or-marker-p after-string) - after-string - (line-beginning-position)))) - (if (and (eq (current-buffer) lbuffer) - (<= lline line)) - ;; while Emacs does the perfectly correct - ;; thing even when when the line differences - ;; get zero or negative, I don't trust this - ;; to be universally the case across other - ;; implementations. Besides, if the line - ;; number gets smaller again, we are probably - ;; rereading the file, and restarting from - ;; the beginning will probably be faster. - (progn - (goto-char lpoint) - (if (/= lline line) - (if (eq selective-display t) - (re-search-forward "[\n\C-m]" nil - 'end - (- line lline)) - (forward-line (- line lline))))) - (goto-char (point-min)) - (forward-line (1- line))) - (setq lpoint (point)) - (cond - ((search-forward (concat string after-string) - (line-end-position) t) - (backward-char (length after-string))) - ;;ok, transform ^^ sequences - ((search-forward-regexp - (concat "\\(" - (setq string - (preview-error-quote - string)) - "\\)" - (setq after-string - (preview-error-quote - after-string))) - (line-end-position) t) - (goto-char (match-end 1))) - ((search-forward-regexp - (concat "\\(" - (if (string-match - "^[^\0-\177]\\{1,6\\}" string) - (setq string - (substring string (match-end 0))) - string) - "\\)" - (if (string-match - "[^\0-\177]\\{1,6\\}$" after-string) - (setq after-string - (substring after-string - 0 (match-beginning 0))))) - (line-end-position) t) - (goto-char (match-end 1))) - (t (search-forward-regexp - string - (line-end-position) t)))) - (setq lline line - lbuffer (current-buffer)) - (if box - (progn - (if (and lstart (= snippet lsnippet)) - (setq close-data - (nconc - (preview-place-preview - snippet - (save-excursion - (preview-back-command - (= (prog1 (point) - (goto-char lstart)) - lstart)) - (point)) - (point) - (preview-TeX-bb box) - (cons lcounters counters) - tempdir - (cdr open-data)) - close-data)) - (with-current-buffer run-buffer - (preview-log-error - (list 'error - (format - "End of Preview snippet %d unexpected" - snippet)) "Parser"))) - (setq lstart nil)) - ;; else-part of if box - (setq lstart (point) lcounters counters) - ;; >= because snippets in between might have - ;; been ignored because of TeX-default-extension - (unless (>= snippet (1+ lsnippet)) - (with-current-buffer run-buffer - (preview-log-error - (list 'error - (format - "Preview snippet %d out of sequence" - snippet)) "Parser")))))))) - (preview-call-hook 'close (car open-data) close-data)))))) - -(defun preview-get-dpi () - ;; TODO: Remove false-case when required emacs version is bumped to - ;; 24.4 or newer as this is the version where - ;; `frame-monitor-attributes' has been introduced. - (if (fboundp 'frame-monitor-attributes) - (let* ((monitor-attrs (frame-monitor-attributes)) - (mm-dims (cdr (assoc 'mm-size monitor-attrs))) - (mm-width (nth 0 mm-dims)) - (mm-height (nth 1 mm-dims)) - (pixel-dims (cdddr (assoc 'geometry monitor-attrs))) - (pixel-width (nth 0 pixel-dims)) - (pixel-height (nth 1 pixel-dims))) - (cons (/ (* 25.4 pixel-width) mm-width) - (/ (* 25.4 pixel-height) mm-height))) - (cons (/ (* 25.4 (display-pixel-width)) - (display-mm-width)) - (/ (* 25.4 (display-pixel-height)) - (display-mm-height))))) - -(defun preview-get-geometry () - "Transfer display geometry parameters from current display. -Return list of scale, resolution and colors. Calculation -is done in current buffer." - (condition-case err - (let* ((geometry - (list (preview-hook-enquiry preview-scale-function) - (preview-get-dpi) - (preview-get-colors))) - (preview-min-spec - (* (cdr (nth 1 geometry)) - (/ - (preview-inherited-face-attribute - 'preview-reference-face :height 'default) - 720.0)))) - (setq preview-icon (preview-make-image 'preview-icon-specs) - preview-error-icon (preview-make-image - 'preview-error-icon-specs) - preview-nonready-icon (preview-make-image - 'preview-nonready-icon-specs)) - geometry) - (error (error "Display geometry unavailable: %s" - (error-message-string err))))) - -(defun preview-set-geometry (geometry) - "Set geometry variables from GEOMETRY. -Buffer-local `preview-scale', `preview-resolution', -and `preview-colors' are set as given." - (setq preview-scale (nth 0 geometry) - preview-resolution (nth 1 geometry) - preview-colors (nth 2 geometry))) - -(defun preview-get-colors () - "Return colors from the current display. -Fetches the current screen colors and makes a vector -of colors as numbers in the range 0..65535. -Pure borderless black-on-white will return triple nil. -The fourth value is the transparent border thickness." - (let - ((bg (color-values (preview-inherited-face-attribute - 'preview-reference-face :background 'default))) - (fg (color-values (preview-inherited-face-attribute - 'preview-reference-face :foreground 'default))) - (mask (preview-get-heuristic-mask))) - (if (equal '(65535 65535 65535) bg) - (setq bg nil)) - (if (equal '(0 0 0) fg) - (setq fg nil)) - (unless (and (numberp preview-transparent-border) - (consp mask) (integerp (car mask))) - (setq mask nil)) - (vector bg fg mask preview-transparent-border))) - -(defun preview-start-dvipng () - "Start a DviPNG process.." - (let* (;; (file preview-gs-file) - tempdir - (res (/ (* (car preview-resolution) - (preview-hook-enquiry preview-scale)) - (preview-get-magnification))) - (resolution (format " -D%d " res)) - (colors (preview-dvipng-color-string preview-colors res)) - (command (with-current-buffer TeX-command-buffer - (prog1 - (concat (TeX-command-expand preview-dvipng-command) - " " colors resolution) - (setq tempdir TeX-active-tempdir)))) - (name "Preview-DviPNG")) - (setq TeX-active-tempdir tempdir) - (goto-char (point-max)) - (insert-before-markers "Running `" name "' with ``" command "''\n") - (setq mode-name name) - (setq TeX-sentinel-function - (lambda (_process name) (message "%s: done." name))) - (if TeX-process-asynchronous - (let ((process (start-process name (current-buffer) TeX-shell - TeX-shell-command-option - command))) - (if TeX-after-start-process-function - (funcall TeX-after-start-process-function process)) - (TeX-command-mode-line process) - (set-process-filter process #'TeX-command-filter) - (set-process-sentinel process #'TeX-command-sentinel) - (set-marker (process-mark process) (point-max)) - (push process compilation-in-progress) - (sit-for 0) - process) - (setq mode-line-process ": run") - (force-mode-line-update) - (call-process TeX-shell nil (current-buffer) nil - TeX-shell-command-option - command)))) - -(defun preview-start-dvips (&optional fast) - "Start a DviPS process. -If FAST is set, do a fast conversion." - (let* (;; (file preview-gs-file) - tempdir - (command (with-current-buffer TeX-command-buffer - (prog1 - (TeX-command-expand (if fast - preview-fast-dvips-command - preview-dvips-command)) - (setq tempdir TeX-active-tempdir)))) - (name "Preview-DviPS")) - (setq TeX-active-tempdir tempdir) - (setq preview-ps-file (and fast - (preview-make-filename - (preview-make-filename - "preview.ps" tempdir) - tempdir))) - (goto-char (point-max)) - (insert-before-markers "Running `" name "' with ``" command "''\n") - (setq mode-name name) - (setq TeX-sentinel-function - (lambda (_process name) (message "%s: done." name))) - (if TeX-process-asynchronous - (let ((process (start-process name (current-buffer) TeX-shell - TeX-shell-command-option - command))) - (if TeX-after-start-process-function - (funcall TeX-after-start-process-function process)) - (TeX-command-mode-line process) - (set-process-filter process #'TeX-command-filter) - (set-process-sentinel process #'TeX-command-sentinel) - (set-marker (process-mark process) (point-max)) - (push process compilation-in-progress) - (sit-for 0) - process) - (setq mode-line-process ": run") - (force-mode-line-update) - (call-process TeX-shell nil (current-buffer) nil - TeX-shell-command-option - command)))) - -(defun preview-start-pdf2dsc () - "Start a PDF2DSC process." - (let* ((file preview-gs-file) - tempdir - pdfsource - (command (with-current-buffer TeX-command-buffer - (prog1 - (TeX-command-expand preview-pdf2dsc-command) - (setq tempdir TeX-active-tempdir - pdfsource (funcall (car file) "pdf" t))))) - (name "Preview-PDF2DSC")) - (setq TeX-active-tempdir tempdir) - (setq preview-ps-file (preview-attach-filename - pdfsource - (preview-make-filename - (preview-make-filename - "preview.dsc" tempdir) - tempdir))) - (goto-char (point-max)) - (insert-before-markers "Running `" name "' with ``" command "''\n") - (setq mode-name name) - (setq TeX-sentinel-function - (lambda (_process name) (message "%s: done." name))) - (if TeX-process-asynchronous - (let ((process (start-process name (current-buffer) TeX-shell - TeX-shell-command-option - command))) - (if TeX-after-start-process-function - (funcall TeX-after-start-process-function process)) - (TeX-command-mode-line process) - (set-process-filter process #'TeX-command-filter) - (set-process-sentinel process #'TeX-command-sentinel) - (set-marker (process-mark process) (point-max)) - (push process compilation-in-progress) - (sit-for 0) - process) - (setq mode-line-process ": run") - (force-mode-line-update) - (call-process TeX-shell nil (current-buffer) nil - TeX-shell-command-option - command)))) - -(defun preview-TeX-inline-sentinel (process _name) - "Sentinel function for preview. -See `TeX-sentinel-function' and `set-process-sentinel' -for definition of PROCESS and NAME." - (if process (TeX-format-mode-line process)) - (let ((status (process-status process))) - (if (memq status '(signal exit)) - (delete-process process)) - (when (eq status 'exit) - (save-excursion - (goto-char (point-max)) - (forward-line -1) - (if (search-forward "abnormally with code 1" nil t) - (replace-match "as expected with code 1" t t) - (if (search-forward "finished" nil t) - (insert " with nothing to show")))) - (condition-case err - (preview-call-hook 'open) - (error (preview-log-error err "LaTeX" process))) - (preview-reraise-error process)))) - -(defcustom preview-format-extensions '(".fmt" ".efmt") - "Possible extensions for format files. -Those are just needed for cleanup." - :group 'preview-latex - :type '(repeat string)) - -(defun preview-format-kill (format-cons) - "Kill a cached format. -FORMAT-CONS is intended to be an element of `preview-dumped-alist'. -Tries through `preview-format-extensions'." - (dolist (ext preview-format-extensions) - (condition-case nil - (delete-file (preview-dump-file-name (concat (car format-cons) ext))) - (file-error nil)))) - -(defun preview-dump-file-name (file) - "Make a file name suitable for dumping from FILE." - (if file - (concat (file-name-directory file) - "prv_" - (progn - (setq file (file-name-nondirectory file)) - (while (string-match " " file) - (setq file (replace-match "_" t t file))) - file)) - "prv_texput")) - -(defun preview-do-replacements (string replacements) - "Perform replacements in string. -STRING is the input string, REPLACEMENTS is a list of replacements. -A replacement is a cons-cell, where the car is the match string, -and the cdr is a list of strings or symbols. Symbols get dereferenced, -and strings get evaluated as replacement strings." - (let (rep case-fold-search) - (while replacements - (setq rep (pop replacements)) - (cond ((symbolp rep) - (setq string (preview-do-replacements - string (symbol-value rep)))) - ((string-match (car rep) string) - (setq string - (mapconcat (lambda(x) - (if (symbolp x) - (symbol-value x) - (replace-match x t nil string))) - (cdr rep) "")))))) - string) - -(defconst preview-LaTeX-disable-pdfoutput - '(("\\`\\(pdf[^ ]*\\)\ -\\(\\( +[-&]\\([^ \"]\\|\"[^\"]*\"\\)*\\|\ - +\"[-&][^\"]*\"\\)*\\)\\(.*\\)\\'" - . ("\\1\\2 \"\\\\pdfoutput=0 \" \\5"))) - "This replacement places `\"\\pdfoutput=0 \"' after the options -of any command starting with `pdf'.") - -(defcustom preview-LaTeX-command-replacements - nil - "Replacement for `preview-LaTeX-command'. -This is passed through `preview-do-replacements'." - :group 'preview-latex - :type '(repeat - (choice - (symbol :tag "Named replacement" :value preview-LaTeX-disable-pdfoutput) - (cons (string :tag "Matched string") - (repeat :tag "Concatenated elements for replacement" - (choice (symbol :tag "Variable with literal string") - (string :tag "non-literal regexp replacement"))))))) - -(defvar preview-format-name nil - "Format name when enabling preamble cache.") - -(defcustom preview-dump-replacements - '(preview-LaTeX-command-replacements - ;; If -kanji option exists, pick it up as the second match. - ;; Discard all other options. - ("\\`\\([^ ]+\\)\ -\\(?: +\\(?:\\(--?kanji[= ][^ ]+\\)\\|\\(--?output-directory[= ][^ ]+\\)\\|-\\(?:[^ \\\"]\\|\\\\.\\|\"[^\"]*\"\\)*\\)\\)*\\(.*\\)\\'" - . ("\\1 -ini \\2 \\3 -interaction=nonstopmode \"&\\1\" " preview-format-name ".ini \\4"))) - "Generate a dump command from the usual preview command." - :group 'preview-latex - :type '(repeat - (choice (symbol :tag "Named replacement") - (cons string (repeat (choice symbol string)))))) - -(defcustom preview-undump-replacements - ;; If -kanji option exists, pick it up as the second match. - ;; Discard all other options. - '(("\\`\\([^ ]+\\)\ -\\(?: +\\(?:\\(--?kanji[= ][^ ]+\\)\\|\\(--?output-directory[= ][^ ]+\\)\\|-\\(?:[^ \\\"]\\|\\\\.\\|\"[^\"]*\"\\)*\\)\\)*.*\ - \"\\\\input\" \"\\\\detokenize{\" \\(.*\\) \"}\"\\'" - . ("\\1 \\2 \\3 -interaction=nonstopmode -file-line-error " - preview-format-name " \"/AUCTEXINPUT{\" \\4 \"}\""))) - ;; See the ini file code below in `preview-cache-preamble' for the - ;; weird /AUCTEXINPUT construct. In short, it is crafted so that - ;; dumped format file can read file of non-ascii name. - "Use a dumped format for reading preamble." - :group 'preview-latex - :type '(repeat - (choice (symbol :tag "Named replacement") - (cons string (repeat (choice symbol string)))))) - - -(defun preview-cache-preamble (&optional format-cons) - "Dump a pregenerated format file. -For the rest of the session, this file is used when running -on the same master file. - -Return the process for dumping, nil if there is still a valid -format available. - -If FORMAT-CONS is non-nil, a previous format may get reused." - (interactive) - (setq TeX-current-process-region-p nil) - (let* ((dump-file - (expand-file-name (preview-dump-file-name (TeX-master-file "ini")))) - (master (TeX-master-file)) - (format-name (expand-file-name master)) - (preview-format-name (shell-quote-argument - (preview-dump-file-name (file-name-nondirectory - master)))) - (master-file (expand-file-name (TeX-master-file t))) - (command (preview-do-replacements - (TeX-command-expand - (preview-string-expand preview-LaTeX-command)) - preview-dump-replacements)) - (preview-auto-cache-preamble nil)) - (unless (and (consp (cdr format-cons)) - (string= command (cadr format-cons))) - (unless format-cons - (setq format-cons (assoc format-name preview-dumped-alist))) - (if format-cons - (preview-cache-preamble-off format-cons) - (setq format-cons (list format-name)) - (push format-cons preview-dumped-alist)) - ;; mylatex.ltx expects a file name to follow. Bad. `.tex' - ;; in the tools bundle is an empty file. - (write-region "\\let\\PREVIEWdump\\dump\\def\\dump{% -\\edef\\next{{\\ifx\\pdfoutput\\undefined\\else\ -\\pdfoutput=\\the\\pdfoutput\\relax\\fi\ -\\the\\everyjob}}\\everyjob\\next\\catcode`\\ 10 % -\\catcode`/ 0 % -\\def\\AUCTEXINPUT##1{\\catcode`/ 12\\relax\\catcode`\\ 9\\relax\\input\\detokenize{##1}\\relax}% -\\let\\dump\\PREVIEWdump\\dump}\\input mylatex.ltx \\relax%\n" nil dump-file) - (TeX-save-document #'TeX-master-file) - (prog1 (preview-generate-preview master command) - (add-hook 'kill-emacs-hook #'preview-cleanout-tempfiles t) - (setq TeX-sentinel-function - (lambda (process _status) - (condition-case err - (progn - (if (and (eq (process-status process) 'exit) - (zerop (process-exit-status process))) - (preview-watch-preamble - master-file - command - format-cons) - (preview-format-kill format-cons)) - (delete-file dump-file)) - (error (preview-log-error err "Dumping" process))) - (preview-reraise-error process))))))) - -(defun preview-cache-preamble-off (&optional old-format) - "Clear the pregenerated format file. -The use of the format file is discontinued. -OLD-FORMAT may already contain a format-cons as -stored in `preview-dumped-alist'." - (interactive) - (unless old-format - (setq old-format - (let ((master-file (expand-file-name (TeX-master-file)))) - (or (assoc master-file preview-dumped-alist) - (car (push (list master-file) preview-dumped-alist)))))) - (preview-unwatch-preamble old-format) - (preview-format-kill old-format) - (setcdr old-format nil)) - -(defun preview-region (begin end) - "Run preview on region between BEGIN and END." - (interactive "r") - (let ((TeX-region-extra - ;; Write out counter information to region. - (concat (preview--counter-information begin) - TeX-region-extra))) - (TeX-region-create (TeX-region-file TeX-default-extension) - (buffer-substring-no-properties begin end) - (if buffer-file-name - (file-name-nondirectory buffer-file-name) - "<none>") - (TeX-current-offset begin))) - (setq TeX-current-process-region-p t) - (preview-generate-preview (TeX-region-file) - (preview-do-replacements - (TeX-command-expand - (preview-string-expand preview-LaTeX-command)) - preview-LaTeX-command-replacements))) - -(defun preview-buffer () - "Run preview on current buffer." - (interactive) - (preview-region (point-min) (point-max))) - -;; We have a big problem: When we are dumping preambles, diagnostics -;; issued in later runs will not make it to the output when the -;; predumped format skips the preamble. So we have to place those -;; after \begin{document}. This we can only do if regions never -;; include the preamble. We could do this in our own functions, but -;; that would not extend to the operation of C-c C-r g RET. So we -;; make this preamble skipping business part of TeX-region-create. -;; This will fail if the region is to contain just part of the -;; preamble -- a bad idea anyhow. - -(defun preview--skip-preamble-region (region-text region-offset) - "Skip preamble for the sake of predumped formats. -Helper function of `TeX-region-create'. - -If REGION-TEXT doesn't contain preamble, it returns nil. -Otherwise, it returns cons (ALTERED-TEXT . ALTERED-OFFSET) where -ALTERED-TEXT is REGION-TEXT without the preamble part and -ALTERED-OFFSET is REGION-OFFSET increased by the number of lines -of the preamble part of REGION-TEXT." - (if (string-match TeX-header-end region-text) - (cons (substring region-text (match-end 0)) - (with-temp-buffer - (insert (substring region-text 0 (match-end 0))) - (+ region-offset (TeX-current-offset)))))) - -(defun preview-document () - "Run preview on master document." - (interactive) - (TeX-save-document #'TeX-master-file) - (setq TeX-current-process-region-p nil) - (preview-generate-preview - (TeX-master-file) - (preview-do-replacements - (TeX-command-expand - (preview-string-expand preview-LaTeX-command)) - preview-LaTeX-command-replacements))) - -(defun preview-environment (count) - "Run preview on LaTeX environment. -This avoids running environments through preview that are -indicated in `preview-inner-environments'. If you use a prefix -argument COUNT, the corresponding level of outward nested -environments is selected." - (interactive "p") - (save-excursion - (let (currenv) - (dotimes (_ (1- count)) - (setq currenv (LaTeX-current-environment)) - (if (string= currenv "document") - (error "No enclosing outer environment found")) - (LaTeX-find-matching-begin)) - (while (member (setq currenv (LaTeX-current-environment)) - preview-inner-environments) - (LaTeX-find-matching-begin)) - (if (string= currenv "document") - (error "No enclosing outer environment found")) - (preview-region - (save-excursion (LaTeX-find-matching-begin) (point)) - (save-excursion (LaTeX-find-matching-end) (point)))))) - -(defun preview-section () - "Run preview on LaTeX section." (interactive) - (save-excursion - (LaTeX-mark-section) - (preview-region (region-beginning) (region-end)))) - - -(defun preview-generate-preview (file command) - "Generate a preview. -FILE the file (without default extension), COMMAND is the command -to use. - -It returns the started process." - (let* ((geometry (preview-get-geometry)) - (commandbuff (current-buffer)) - (pr-file (cons - #'TeX-active-master - (file-name-nondirectory file))) - (master (TeX-master-file)) - (master-file (expand-file-name master)) - (dumped-cons (assoc master-file - preview-dumped-alist)) - process) - (unless dumped-cons - (push (setq dumped-cons (cons master-file - (if (eq preview-auto-cache-preamble 'ask) - (y-or-n-p "Cache preamble? ") - preview-auto-cache-preamble))) - preview-dumped-alist)) - (when (cdr dumped-cons) - (let* (TeX-current-process-region-p) - (setq process (preview-cache-preamble dumped-cons)) - (if process - ;; FIXME: Use `add-function'. - (setq TeX-sentinel-function - (let ((prev-fun TeX-sentinel-function)) - (lambda (process string) - (funcall prev-fun process string) - (TeX-inline-preview-internal - command file - pr-file commandbuff - dumped-cons - master - geometry - (buffer-string)))))))) - (or process - (TeX-inline-preview-internal command file - pr-file commandbuff - dumped-cons master - geometry)))) - -(defun TeX-inline-preview-internal (command file pr-file - commandbuff dumped-cons _master - geometry - &optional str) - "Internal stuff for previewing. -COMMAND and FILE should be explained in `TeX-command-list'. -PR-FILE is the target file name in the form for `preview-gs-file'. -COMMANDBUFF, DUMPED-CONS, MASTER, and GEOMETRY are -internal parameters, STR may be a log to insert into the current log." - (set-buffer commandbuff) - (let* - ((preview-format-name (shell-quote-argument - (concat "&" - (preview-dump-file-name - ;; Get the filename from - ;; `TeX-master-file' with prv to - ;; get the correct path but then - ;; strip the extension - (file-name-sans-extension - (TeX-master-file "prv" t)))))) - (process-environment (copy-sequence process-environment)) - (process - (progn - ;; Fix Bug#20773, Bug#27088. - ;; Make LaTeX not to insert newline in lines necessary to - ;; identify Bounding Boxes. - (setenv "max_print_line" "1000") - (TeX-run-command - "Preview-LaTeX" - (if (consp (cdr dumped-cons)) - (preview-do-replacements - command - preview-undump-replacements) - command) - file)))) - (condition-case err - (progn - (when str - (save-excursion - (goto-char (point-min)) - (insert str) - (when (= (process-mark process) (point-min)) - (set-marker (process-mark process) (point))))) - (preview-set-geometry geometry) - (setq preview-gs-file pr-file) - (setq TeX-sentinel-function #'preview-TeX-inline-sentinel) - (TeX-parse-reset) - (setq TeX-parse-function #'TeX-parse-TeX) - (if TeX-process-asynchronous - process - (TeX-synchronous-sentinel "Preview-LaTeX" file process))) - (error (preview-log-error err "Preview" process) - (delete-process process) - (preview-reraise-error process))))) - -(defconst preview-version AUCTeX-version - "Preview version. -If not a regular release, the date of the last change.") - -(defconst preview-release-date AUCTeX-date - "Preview release date using the ISO 8601 format, yyyy-mm-dd.") - -(defun preview-dump-state (buffer) - (condition-case nil - (progn - (unless (local-variable-p 'TeX-command-buffer (current-buffer)) - (setq buffer (with-current-buffer buffer (TeX-active-buffer)))) - (when (bufferp buffer) - (insert "\nRun buffer contents:\n\n") - (if (< (buffer-size buffer) 5000) - (insert-buffer-substring buffer) - (insert-buffer-substring buffer 1 2500) - (insert "...\n\n[...]\n\n\t...") - (insert-buffer-substring buffer - (- (buffer-size buffer) 2500) - (buffer-size buffer))) - (insert "\n"))) - (error nil))) - -;;;###autoload -(defun preview-report-bug () "Report a bug in the preview-latex package." - (interactive) - (let ((reporter-prompt-for-summary-p "Bug report subject: ")) - (reporter-submit-bug-report - "bug-auctex@gnu.org" - preview-version - '(AUCTeX-version - LaTeX-command-style - image-types - preview-image-type - preview-image-creators - preview-dvipng-image-type - preview-dvipng-command - preview-pdf2dsc-command - preview-gs-command - preview-gs-options - preview-gs-image-type-alist - preview-fast-conversion - preview-prefer-TeX-bb - preview-dvips-command - preview-fast-dvips-command - preview-scale-function - preview-LaTeX-command - preview-required-option-list - preview-preserve-counters - preview-default-option-list - preview-default-preamble - preview-LaTeX-command-replacements - preview-dump-replacements - preview-undump-replacements - preview-auto-cache-preamble - preview-TeX-style-dir) - (let ((buf (current-buffer))) - (lambda () (preview-dump-state buf))) - (lambda () - (insert (format "\nOutput from running `%s -h':\n" - preview-gs-command)) - (call-process preview-gs-command nil t nil "-h") - (insert "\n")) - "Remember to cover the basics. Including a minimal LaTeX example -file exhibiting the problem might help." - ))) - -(provide 'preview) -;;; preview.el ends here |