Blame prv-xemacs.el

Packit f2bd10
;;; prv-xemacs.el --- XEmacs support for preview-latex
Packit f2bd10
Packit f2bd10
;; Copyright (C) 2001-2006, 2017 Free Software Foundation, Inc.
Packit f2bd10
Packit f2bd10
;; Author: David Kastrup
Packit f2bd10
;; Keywords: convenience, tex, wp
Packit f2bd10
Packit f2bd10
;; This file is free software; you can redistribute it and/or modify
Packit f2bd10
;; it under the terms of the GNU General Public License as published by
Packit f2bd10
;; the Free Software Foundation; either version 3, or (at your option)
Packit f2bd10
;; any later version.
Packit f2bd10
Packit f2bd10
;; This file is distributed in the hope that it will be useful,
Packit f2bd10
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit f2bd10
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit f2bd10
;; GNU General Public License for more details.
Packit f2bd10
Packit f2bd10
;; You should have received a copy of the GNU General Public License
Packit f2bd10
;; along with GNU Emacs; see the file COPYING.  If not, write to
Packit f2bd10
;; the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
Packit f2bd10
;; Boston, MA 02110-1301, USA.
Packit f2bd10
Packit f2bd10
;;; Commentary:
Packit f2bd10
Packit f2bd10
;; 
Packit f2bd10
Packit f2bd10
;;; Code:
Packit f2bd10
Packit f2bd10
(require 'overlay)
Packit f2bd10
(require 'tex-site)
Packit f2bd10
(require 'tex)
Packit f2bd10
(require 'latex)
Packit f2bd10
Packit f2bd10
;; Compatibility macros and functions.
Packit f2bd10
Packit f2bd10
(eval-when-compile
Packit f2bd10
  (defvar preview-compatibility-macros nil
Packit f2bd10
    "List of macros only present when compiling/loading uncompiled.")
Packit f2bd10
Packit f2bd10
  (defmacro preview-defmacro (name &rest rest)
Packit f2bd10
    (when (featurep 'xemacs)
Packit f2bd10
      (push
Packit f2bd10
       (if (fboundp name)
Packit f2bd10
	   (cons name (symbol-function name))
Packit f2bd10
	 name)
Packit f2bd10
       preview-compatibility-macros)
Packit f2bd10
      `(eval-when-compile (defmacro ,name ,@rest))))
Packit f2bd10
  (push 'preview-defmacro preview-compatibility-macros))
Packit f2bd10
Packit f2bd10
(preview-defmacro assoc-default (key alist test)
Packit f2bd10
  `(cdr (assoc* ,key ,alist
Packit f2bd10
                :test #'(lambda(a b) (funcall ,test b a)))))
Packit f2bd10
Packit f2bd10
(preview-defmacro display-mm-height () '(device-mm-height))
Packit f2bd10
(preview-defmacro display-mm-width () '(device-mm-width))
Packit f2bd10
(preview-defmacro display-pixel-height () '(device-pixel-height))
Packit f2bd10
(preview-defmacro display-pixel-width () '(device-pixel-width))
Packit f2bd10
(preview-defmacro line-beginning-position () '(point-at-bol))
Packit f2bd10
(preview-defmacro line-end-position () '(point-at-eol))
Packit f2bd10
Packit f2bd10
;; This is not quite the case, but unless we're playing with duplicable extents,
Packit f2bd10
;; the two are equivalent in XEmacs.
Packit f2bd10
(preview-defmacro match-string-no-properties (&rest args)
Packit f2bd10
  `(match-string ,@args))
Packit f2bd10
Packit f2bd10
(preview-defmacro face-attribute (face attr)
Packit f2bd10
  (cond
Packit f2bd10
    ((eq attr :height)
Packit f2bd10
     `(round (/ (* ,(/ 720.0 25.4)
Packit f2bd10
		   (face-height ,face)
Packit f2bd10
		   (device-mm-height))
Packit f2bd10
		(device-pixel-height))))
Packit f2bd10
    ((eq attr :foreground)
Packit f2bd10
     `(face-foreground-instance ,face))
Packit f2bd10
    ((eq attr :background)
Packit f2bd10
     `(face-background-instance ,face))
Packit f2bd10
    (t
Packit f2bd10
     (error 'unimplemented (format "Don't know how to fake %s" attr)))))
Packit f2bd10
Packit f2bd10
(preview-defmacro make-temp-file (prefix dir-flag)
Packit f2bd10
  (if (not dir-flag)
Packit f2bd10
      (error 'unimplemented "Can only fake make-temp-file for directories"))
Packit f2bd10
  `(let (file)
Packit f2bd10
     (while (condition-case ()
Packit f2bd10
                (progn
Packit f2bd10
                  (setq file
Packit f2bd10
                        (make-temp-name ,prefix))
Packit f2bd10
                  (make-directory file)
Packit f2bd10
                  nil)
Packit f2bd10
              (file-already-exists t))
Packit f2bd10
       nil)
Packit f2bd10
     file))
Packit f2bd10
Packit f2bd10
(preview-defmacro set-buffer-multibyte (multibyte)
Packit f2bd10
  "Set the representation type of the current buffer.  If MULTIBYTE
Packit f2bd10
is non-`nil', the buffer becomes multibyte.  If MULTIBYTE is
Packit f2bd10
`nil', the buffer becomes unibyte.
Packit f2bd10
Packit f2bd10
Because XEmacs does not implement multibyte versus unibyte buffers
Packit f2bd10
per se (they just have encodings which may be unibyte or multibyte),
Packit f2bd10
this is only implemented for the `nil' case."
Packit f2bd10
  (if (not multibyte)
Packit f2bd10
      `(if (fboundp 'set-buffer-file-coding-system)
Packit f2bd10
           (set-buffer-file-coding-system 'binary))
Packit f2bd10
    (error 'unimplemented "`set-buffer-multibyte is only implemented for the binary case.")))
Packit f2bd10
Packit f2bd10
(preview-defmacro next-single-char-property-change (pos prop)
Packit f2bd10
  "Return the position of next property change for a specific property.
Packit f2bd10
This is like `next-single-property-change', except that if no
Packit f2bd10
change is found before the end of the buffer, it returns
Packit f2bd10
\(point-max) rather than `nil'."
Packit f2bd10
  `(or (next-single-property-change ,pos ,prop)
Packit f2bd10
       (point-max)))
Packit f2bd10
Packit f2bd10
(preview-defmacro previous-single-char-property-change (pos prop)
Packit f2bd10
  "Return the position of previous property change for a specific property.
Packit f2bd10
This is like `next-single-property-change', except that if no
Packit f2bd10
change is found before the end of the buffer, it returns
Packit f2bd10
\(point-min) rather than `nil'."
Packit f2bd10
  `(or (previous-single-property-change ,pos ,prop)
Packit f2bd10
       (point-min)))
Packit f2bd10
Packit f2bd10
(preview-defmacro with-temp-message (message &rest body)
Packit f2bd10
  "Display MESSAGE temporarily if non-nil while BODY is evaluated.
Packit f2bd10
The original message is restored to the echo area after BODY has finished.
Packit f2bd10
The value returned is the value of the last form in BODY.
Packit f2bd10
MESSAGE is written to the message log buffer if `message-log-max' is non-nil.
Packit f2bd10
If MESSAGE is nil, the echo area and message log buffer are unchanged.
Packit f2bd10
Use a MESSAGE of \"\" to temporarily clear the echo area.
Packit f2bd10
Packit f2bd10
The message is displayed with label `progress'; see `display-message'."
Packit f2bd10
  (let ((current-message (make-symbol "current-message"))
Packit f2bd10
        (temp-message (make-symbol "with-temp-message")))
Packit f2bd10
    `(let ((,temp-message ,message)
Packit f2bd10
           (,current-message))
Packit f2bd10
       (unwind-protect
Packit f2bd10
           (progn
Packit f2bd10
             (when ,temp-message
Packit f2bd10
               (setq ,current-message (current-message))
Packit f2bd10
               (display-message 'progress ,temp-message))
Packit f2bd10
             ,@body)
Packit f2bd10
         (and ,temp-message
Packit f2bd10
              (if ,current-message
Packit f2bd10
                  (display-message 'progress ,current-message)
Packit f2bd10
                (message nil)))))))
Packit f2bd10
Packit f2bd10
(defun preview-mark-active ()
Packit f2bd10
  "Return t if the mark is active."
Packit f2bd10
  (and (mark)
Packit f2bd10
       t))
Packit f2bd10
Packit f2bd10
(defvar preview-transparent-border)
Packit f2bd10
Packit f2bd10
;; Images.
Packit f2bd10
Packit f2bd10
(defsubst preview-supports-image-type (imagetype)
Packit f2bd10
  "Return whether IMAGETYPE is supported by XEmacs."
Packit f2bd10
  (memq imagetype (image-instantiator-format-list)))
Packit f2bd10
Packit f2bd10
;; TODO: Generalize this so we can create the fixed icons using it.
Packit f2bd10
Packit f2bd10
;; Argh, dired breaks :file :(
Packit f2bd10
;; This is a temporary kludge to get around that until a fixed dired
Packit f2bd10
;; or a fixed XEmacs is released.
Packit f2bd10
Packit f2bd10
(defun preview-create-icon-1 (file type ascent)
Packit f2bd10
  "Create an icon from FILE, image TYPE and ASCENT."
Packit f2bd10
  (let ((glyph
Packit f2bd10
	 (make-glyph
Packit f2bd10
	  (vector type
Packit f2bd10
		  :file file
Packit f2bd10
		  :data (with-temp-buffer
Packit f2bd10
			  (insert-file-contents-literally file)
Packit f2bd10
			  (buffer-string))))))
Packit f2bd10
    (set-glyph-baseline glyph ascent)
Packit f2bd10
    glyph))
Packit f2bd10
Packit f2bd10
(defun preview-create-icon (file type ascent border)
Packit f2bd10
  "Create an icon from FILE, image TYPE, ASCENT and BORDER."
Packit f2bd10
  (list
Packit f2bd10
   (preview-create-icon-1 file type ascent)
Packit f2bd10
   file type ascent border))
Packit f2bd10
Packit f2bd10
(defvar preview-ascent-spec)
Packit f2bd10
Packit f2bd10
(put 'preview-filter-specs :type
Packit f2bd10
     #'(lambda (keyword value &rest args)
Packit f2bd10
	 (if (preview-supports-image-type value)
Packit f2bd10
	     (let* (preview-ascent-spec
Packit f2bd10
		    (glyph (make-glyph `[,value
Packit f2bd10
					 ,@(preview-filter-specs-1 args)])))
Packit f2bd10
	       (when preview-ascent-spec
Packit f2bd10
		 (set-glyph-baseline glyph preview-ascent-spec))
Packit f2bd10
	       glyph)
Packit f2bd10
	   (throw 'preview-filter-specs nil))))
Packit f2bd10
Packit f2bd10
(put 'preview-filter-specs :ascent
Packit f2bd10
     #'(lambda (keyword value &rest args)
Packit f2bd10
	 (setq preview-ascent-spec value)
Packit f2bd10
	 (preview-filter-specs-1 args)))
Packit f2bd10
Packit f2bd10
;; No defcustom here: does not seem to make sense.
Packit f2bd10
Packit f2bd10
(defvar preview-tb-icon-specs
Packit f2bd10
  '((:type xpm :file "prvtex-cap-up.xpm" :ascent 75)
Packit f2bd10
    (:type xbm :file "prvtex24.xbm" :ascent 75)))
Packit f2bd10
Packit f2bd10
(defvar preview-tb-icon nil)
Packit f2bd10
Packit f2bd10
;; Image frobbing.
Packit f2bd10
Packit f2bd10
(defun preview-add-urgentization (fun ov &rest rest)
Packit f2bd10
  "Cause FUN (function call form) to be called when redisplayed.
Packit f2bd10
FUN must be a form with OV as first argument,
Packit f2bd10
REST as the remainder, returning T.  An alternative is to give
Packit f2bd10
what `preview-remove-urgentization' returns, this will reinstate
Packit f2bd10
the previous state."
Packit f2bd10
  (set-extent-initial-redisplay-function
Packit f2bd10
   ov
Packit f2bd10
   (if (null rest)
Packit f2bd10
       fun
Packit f2bd10
     `(lambda (ov) (,fun ,ov ,@rest)))))
Packit f2bd10
Packit f2bd10
(defun preview-remove-urgentization (ov)
Packit f2bd10
  "Undo urgentization of OV by `preview-add-urgentization'.
Packit f2bd10
Returns the old arguments to `preview-add-urgentization'
Packit f2bd10
if there was any urgentization."
Packit f2bd10
  (prog1 (list (extent-property ov 'initial-redisplay-function) ov)
Packit f2bd10
    (set-extent-initial-redisplay-function ov nil)))
Packit f2bd10
Packit f2bd10
(defsubst preview-icon-copy (icon)
Packit f2bd10
  "Prepare for a later call of `preview-replace-active-icon'."
Packit f2bd10
  icon)
Packit f2bd10
Packit f2bd10
(defsubst preview-replace-active-icon (ov replacement)
Packit f2bd10
  "Replace the active Icon in OV by REPLACEMENT, another icon."
Packit f2bd10
  (set-extent-property ov 'preview-image replacement)
Packit f2bd10
  (add-text-properties 0 1 (list 'end-glyph (car replacement))
Packit f2bd10
		       (car (extent-property ov 'strings)))
Packit f2bd10
  (if (eq (extent-property ov 'preview-state) 'active)
Packit f2bd10
      (set-extent-end-glyph ov (car replacement))))
Packit f2bd10
Packit f2bd10
(defvar preview-button-1 'button2)
Packit f2bd10
(defvar preview-button-2 'button3)
Packit f2bd10
Packit f2bd10
;; The `x' and invisible junk is because XEmacs doesn't bother to insert
Packit f2bd10
;; the extents of a zero-length string. Bah.
Packit f2bd10
;; When this is fixed, we'll autodetect this case and use zero-length
Packit f2bd10
;; strings where possible.
Packit f2bd10
(defmacro preview-make-clickable (&optional map glyph helpstring click1 click2)
Packit f2bd10
  "Generate a clickable string or keymap.
Packit f2bd10
If MAP is non-nil, it specifies a keymap to add to, otherwise
Packit f2bd10
a new one is created.  If GLYPH is given, the result is made
Packit f2bd10
to display it wrapped in a string.  In that case,
Packit f2bd10
HELPSTRING is a format string with one or two %s specifiers
Packit f2bd10
for preview's clicks, displayed as a help-echo.  CLICK1 and CLICK2
Packit f2bd10
are functions to call on preview's clicks."
Packit f2bd10
  `(let (,@(and glyph '((res (copy-sequence "x"))))
Packit f2bd10
           (resmap ,(or map '(make-sparse-keymap))))
Packit f2bd10
     ,@(if click1
Packit f2bd10
           `((define-key resmap preview-button-1 ,click1)))
Packit f2bd10
     ,@(if click2
Packit f2bd10
           `((define-key resmap preview-button-2 ,click2)))
Packit f2bd10
     ,@(if glyph
Packit f2bd10
	   `((add-text-properties
Packit f2bd10
              0 1
Packit f2bd10
              (list 'end-glyph ,glyph
Packit f2bd10
		    'mouse-face 'highlight
Packit f2bd10
              'preview-balloon-help
Packit f2bd10
	      ,(if (stringp helpstring)
Packit f2bd10
		   (format helpstring preview-button-1 preview-button-2)
Packit f2bd10
		 `(format ,helpstring preview-button-1 preview-button-2))
Packit f2bd10
              'preview-keymap resmap)
Packit f2bd10
              res)
Packit f2bd10
             res)
Packit f2bd10
	 '(resmap))))
Packit f2bd10
Packit f2bd10
(defun preview-click-reroute (ov event)
Packit f2bd10
  "If OV received a click EVENT on a glyph, reroute to special map."
Packit f2bd10
  (let ((oldmap (extent-keymap ov)))
Packit f2bd10
    (unwind-protect
Packit f2bd10
	(progn
Packit f2bd10
	  (set-extent-keymap ov
Packit f2bd10
			     (and (event-over-glyph-p event)
Packit f2bd10
				  (extent-property ov 'preview-keymap)))
Packit f2bd10
	  (dispatch-event event))
Packit f2bd10
      (set-extent-keymap ov oldmap))))
Packit f2bd10
Packit f2bd10
(defun preview-reroute-map (ov)
Packit f2bd10
  "Get rerouting keymap for OV for catching glyph clicks only."
Packit f2bd10
  (let ((map (make-sparse-keymap))
Packit f2bd10
	(fun `(lambda (event)
Packit f2bd10
		(interactive "e")
Packit f2bd10
		(preview-click-reroute ,ov event))))
Packit f2bd10
    (define-key map preview-button-1 fun)
Packit f2bd10
    (define-key map preview-button-2 fun)
Packit f2bd10
    map))
Packit f2bd10
Packit f2bd10
(defun preview-balloon-reroute (ov)
Packit f2bd10
  "Give balloon help only if over glyph of OV."
Packit f2bd10
  (and (eq ov (event-glyph-extent (mouse-position-as-motion-event)))
Packit f2bd10
       (extent-property ov 'preview-balloon-help)))
Packit f2bd10
Packit f2bd10
;; Most of the changes to this are junking the use of overlays;
Packit f2bd10
;; a bit of it is different, and there's a little extra paranoia.
Packit f2bd10
Packit f2bd10
;; We also have to move the image from the begin to the end-glyph
Packit f2bd10
;; whenever the extent is invisible because of a bug in XEmacs-21.4's
Packit f2bd10
;; redisplay engine.
Packit f2bd10
(defun preview-toggle (ov &optional arg event)
Packit f2bd10
  "Toggle visibility of preview overlay OV.
Packit f2bd10
ARG can be one of the following: t displays the overlay,
Packit f2bd10
nil displays the underlying text, and 'toggle toggles.
Packit f2bd10
If EVENT is given, it indicates the window where the event
Packit f2bd10
occured, either by being a mouse event or by directly being
Packit f2bd10
the window in question.  This may be used for cursor restoration
Packit f2bd10
purposes."
Packit f2bd10
  (if (not (bufferp (extent-object ov)))
Packit f2bd10
      (error 'wrong-type-argument ov))
Packit f2bd10
  (let ((old-urgent (preview-remove-urgentization ov))
Packit f2bd10
        (preview-state
Packit f2bd10
         (if (if (eq arg 'toggle)
Packit f2bd10
                 (not (eq (extent-property ov 'preview-state) 'active))
Packit f2bd10
               arg)
Packit f2bd10
             'active
Packit f2bd10
           'inactive))
Packit f2bd10
        (strings (extent-property ov 'strings)))
Packit f2bd10
    (unless (eq (extent-property ov 'preview-state) 'disabled)
Packit f2bd10
      (set-extent-property ov 'preview-state preview-state)
Packit f2bd10
      (if (eq preview-state 'active)
Packit f2bd10
          (progn
Packit f2bd10
	    (unless (extent-keymap ov)
Packit f2bd10
	      (set-extent-keymap ov (preview-reroute-map ov))
Packit f2bd10
	      (set-extent-property ov 'balloon-help #'preview-balloon-reroute))
Packit f2bd10
	    (set-extent-begin-glyph ov nil)
Packit f2bd10
	    (set-extent-end-glyph-layout ov 'text)
Packit f2bd10
	    (set-extent-end-glyph ov (get-text-property
Packit f2bd10
				      0 'end-glyph (car strings)))
Packit f2bd10
            (set-extent-properties ov '(invisible t
Packit f2bd10
					isearch-open-invisible ignore
Packit f2bd10
					isearch-invisible t
Packit f2bd10
                                        face nil))
Packit f2bd10
	    (dolist (prop '(preview-keymap
Packit f2bd10
			    mouse-face preview-balloon-help))
Packit f2bd10
              (set-extent-property ov prop
Packit f2bd10
                                   (get-text-property 0 prop (car strings)))))
Packit f2bd10
	(unless (cdr strings)
Packit f2bd10
	  (setcdr strings (preview-inactive-string ov)))
Packit f2bd10
	(set-extent-end-glyph ov nil)
Packit f2bd10
	(set-extent-begin-glyph-layout ov 'text)
Packit f2bd10
	(set-extent-begin-glyph ov (get-text-property
Packit f2bd10
				    0 'end-glyph (cdr strings)))
Packit f2bd10
        (set-extent-properties ov `(face preview-face
Packit f2bd10
				    mouse-face nil
Packit f2bd10
				    invisible nil
Packit f2bd10
				    isearch-invisible nil
Packit f2bd10
				    preview-keymap
Packit f2bd10
				    ,(get-text-property
Packit f2bd10
				     0 'preview-keymap (cdr strings))
Packit f2bd10
				    preview-balloon-help
Packit f2bd10
				    ,(get-text-property
Packit f2bd10
				     0 'preview-balloon-help (cdr strings)))))
Packit f2bd10
      (if old-urgent
Packit f2bd10
          (apply 'preview-add-urgentization old-urgent))))
Packit f2bd10
  (if event
Packit f2bd10
      (preview-restore-position
Packit f2bd10
       ov
Packit f2bd10
       (if (windowp event)
Packit f2bd10
	   event
Packit f2bd10
	 (event-window event)))))
Packit f2bd10
Packit f2bd10
; Does FALLBACKS need to be implemented? Likely not.
Packit f2bd10
(defmacro preview-inherited-face-attribute (face attribute &optional
Packit f2bd10
                                              fallbacks)
Packit f2bd10
  "Fetch face attribute while adhering to inheritance.
Packit f2bd10
This searches FACE and all its ancestors for an ATTRIBUTE.
Packit f2bd10
FALLBACKS is unused."
Packit f2bd10
  `(face-attribute ,face ,attribute))
Packit f2bd10
Packit f2bd10
(defun preview-get-colors ()
Packit f2bd10
  "Return colors from the current display.
Packit f2bd10
Fetches the current screen colors and makes a vector
Packit f2bd10
of colors as numbers in the range 0..65535.
Packit f2bd10
Pure borderless black-on-white will return quadruple NIL."
Packit f2bd10
  (let
Packit f2bd10
      ((bg (color-instance-rgb-components (preview-inherited-face-attribute
Packit f2bd10
             'preview-reference-face :background 'default)))
Packit f2bd10
       (fg (color-instance-rgb-components (preview-inherited-face-attribute
Packit f2bd10
                                           'preview-reference-face :foreground 'default))))
Packit f2bd10
    (if (equal '(65535 65535 65535) bg)
Packit f2bd10
        (setq bg nil))
Packit f2bd10
    (if (equal '(0 0 0) fg)
Packit f2bd10
        (setq fg nil))
Packit f2bd10
    (vector bg fg nil nil)))
Packit f2bd10
Packit f2bd10
(defcustom preview-use-balloon-help nil
Packit f2bd10
  "*Is balloon help enabled in preview-latex?"
Packit f2bd10
  :group 'preview-appearance
Packit f2bd10
  :type 'boolean)
Packit f2bd10
Packit f2bd10
(defcustom preview-buffer-recoding-alist
Packit f2bd10
  (if (and (= emacs-major-version 21)
Packit f2bd10
	   (< emacs-minor-version 5))
Packit f2bd10
      '((utf-8-unix . raw-text-unix)
Packit f2bd10
	(utf-8-dos . raw-text-dos)
Packit f2bd10
	(utf-8-mac . raw-text-mac)
Packit f2bd10
	(utf-8 . raw-text)))
Packit f2bd10
  "Translate buffer encodings into process encodings.
Packit f2bd10
TeX is sometimes bad dealing with 8bit encodings and rather bad
Packit f2bd10
dealing with multibyte encodings.  So the process encoding output
Packit f2bd10
might need to get temporarily reprocessed into the original byte
Packit f2bd10
stream before the buffer characters can be identified.  XEmacs
Packit f2bd10
21.4 is rather bad at preserving incomplete multibyte characters
Packit f2bd10
in that process.  This variable makes it possible to use a
Packit f2bd10
reconstructable coding system in the run buffer instead.  Specify
Packit f2bd10
an alist of coding system names here, which you can get using
Packit f2bd10
Packit f2bd10
  \(coding-system-name buffer-file-coding-system)
Packit f2bd10
Packit f2bd10
in properly detected buffers."
Packit f2bd10
  :group 'preview-latex
Packit f2bd10
  :type '(repeat (cons symbol symbol)))
Packit f2bd10
Packit f2bd10
(defun preview-buffer-recode-system (base)
Packit f2bd10
  "This is supposed to translate unrepresentable base encodings
Packit f2bd10
 into something that can be used safely for byte streams in the
Packit f2bd10
 run buffer.  XEmacs mule-ucs is so broken that this may be
Packit f2bd10
 needed."
Packit f2bd10
  (or (cdr (assq (coding-system-name base)
Packit f2bd10
		 preview-buffer-recoding-alist))
Packit f2bd10
      base))
Packit f2bd10
Packit f2bd10
(if (and (featurep 'mule)
Packit f2bd10
	 (= emacs-major-version 21)
Packit f2bd10
	 (< emacs-minor-version 5))
Packit f2bd10
    (defadvice coding-system-change-eol-conversion
Packit f2bd10
	(after fallback activate)
Packit f2bd10
      "Return CODING-SYSTEM as-is if the result is nil.
Packit f2bd10
XEmacs 21.4 mule-ucs fails to define utf-8 to respond properly to
Packit f2bd10
this function."
Packit f2bd10
      (unless ad-return-value
Packit f2bd10
	(setq ad-return-value (ad-get-arg 0)))))
Packit f2bd10
Packit f2bd10
(defun preview-mode-setup ()
Packit f2bd10
  "Setup proper buffer hooks and behavior for previews."
Packit f2bd10
  (set (make-local-variable 'desktop-save-buffer)
Packit f2bd10
       #'desktop-buffer-preview-misc-data)
Packit f2bd10
  (mapc #'make-local-hook
Packit f2bd10
        '(pre-command-hook post-command-hook
Packit f2bd10
	  before-change-functions after-change-functions))
Packit f2bd10
  (add-hook 'pre-command-hook #'preview-mark-point nil t)
Packit f2bd10
  (add-hook 'post-command-hook #'preview-move-point nil t)
Packit f2bd10
  (and preview-use-balloon-help
Packit f2bd10
       (not (and (boundp 'balloon-help-mode)
Packit f2bd10
		 balloon-help-mode))
Packit f2bd10
       (balloon-help-minor-mode 1))
Packit f2bd10
  (add-hook 'before-change-functions #'preview-handle-before-change nil t)
Packit f2bd10
  (add-hook 'after-change-functions #'preview-handle-after-change nil t)
Packit f2bd10
  (easy-menu-add preview-menu)
Packit f2bd10
  (unless preview-tb-icon
Packit f2bd10
    (setq preview-tb-icon (preview-filter-specs
Packit f2bd10
				       preview-tb-icon-specs))
Packit f2bd10
    (when preview-tb-icon
Packit f2bd10
      (setq preview-tb-icon
Packit f2bd10
	    (vector
Packit f2bd10
	     (list preview-tb-icon)
Packit f2bd10
	     #'preview-at-point
Packit f2bd10
	     t
Packit f2bd10
	     "Preview on/off at point"))))
Packit f2bd10
;;; [Courtesy Stephen J. Turnbull, with some modifications
Packit f2bd10
;;;  Message-ID: <87el9fglsj.fsf@tleepslib.sk.tsukuba.ac.jp>
Packit f2bd10
;;;  I could not have figured this out for the world]
Packit f2bd10
;;; Hm, there really ought to be a way to get the spec that would be
Packit f2bd10
;;; instantiated in a given domain
Packit f2bd10
  (when preview-tb-icon
Packit f2bd10
    (let ((tb (cdadar (or (specifier-spec-list default-toolbar (current-buffer))
Packit f2bd10
			  (specifier-spec-list default-toolbar 'global)))))
Packit f2bd10
      (unless (member preview-tb-icon tb)
Packit f2bd10
	(set-specifier default-toolbar
Packit f2bd10
		       (append tb (list preview-tb-icon))
Packit f2bd10
		       (current-buffer)))))
Packit f2bd10
  (when buffer-file-name
Packit f2bd10
    (let* ((filename (expand-file-name buffer-file-name))
Packit f2bd10
	   format-cons)
Packit f2bd10
      (when (string-match (concat "\\." TeX-default-extension "\\'")
Packit f2bd10
			  filename)
Packit f2bd10
	(setq filename (substring filename 0 (match-beginning 0))))
Packit f2bd10
      (setq format-cons (assoc filename preview-dumped-alist))
Packit f2bd10
      (when (consp (cdr format-cons))
Packit f2bd10
	(preview-unwatch-preamble format-cons)
Packit f2bd10
	(preview-watch-preamble (current-buffer)
Packit f2bd10
				(cadr format-cons)
Packit f2bd10
				format-cons)))))
Packit f2bd10
Packit f2bd10
(defvar preview-marker (make-marker)
Packit f2bd10
  "Marker for fake intangibility.")
Packit f2bd10
Packit f2bd10
(defvar preview-temporary-opened nil)
Packit f2bd10
Packit f2bd10
(defvar preview-last-location nil
Packit f2bd10
  "Restored cursor position marker for reopened previews.")
Packit f2bd10
(make-variable-buffer-local 'preview-last-location)
Packit f2bd10
Packit f2bd10
(defun preview-mark-point ()
Packit f2bd10
  "Mark position for fake intangibility."
Packit f2bd10
  (when (eq (get-char-property (point) 'preview-state) 'active)
Packit f2bd10
    (unless preview-last-location
Packit f2bd10
      (setq preview-last-location (make-marker)))
Packit f2bd10
    (set-marker preview-last-location (point))
Packit f2bd10
    (set-marker preview-marker (point))
Packit f2bd10
    (preview-move-point))
Packit f2bd10
  (set-marker preview-marker (point)))
Packit f2bd10
Packit f2bd10
(defun preview-restore-position (ov window)
Packit f2bd10
  "Tweak position after opening/closing preview.
Packit f2bd10
The treated overlay OV has been triggered in WINDOW.  This function
Packit f2bd10
records the original buffer position for reopening, or restores it
Packit f2bd10
after reopening.  Note that by using the mouse, you can open/close
Packit f2bd10
overlays not in the active window."
Packit f2bd10
  (when (eq (extent-object ov) (window-buffer window))
Packit f2bd10
    (with-current-buffer (extent-object ov)
Packit f2bd10
      (if (eq (extent-property ov 'preview-state) 'active)
Packit f2bd10
	  (setq preview-last-location
Packit f2bd10
		(set-marker (or preview-last-location (make-marker))
Packit f2bd10
			    (window-point window)))
Packit f2bd10
	(when (and
Packit f2bd10
	       (markerp preview-last-location)
Packit f2bd10
	       (eq (extent-object ov) (marker-buffer preview-last-location))
Packit f2bd10
	       (< (extent-start-position ov) preview-last-location)
Packit f2bd10
	       (> (extent-end-position ov) preview-last-location))
Packit f2bd10
	  (set-window-point window preview-last-location))))))
Packit f2bd10
Packit f2bd10
(defun preview-move-point ()
Packit f2bd10
  "Move point out of fake-intangible areas."
Packit f2bd10
  (preview-check-changes)
Packit f2bd10
  (let (newlist (pt (point)) distance)
Packit f2bd10
    (setq preview-temporary-opened
Packit f2bd10
	  (dolist (ov preview-temporary-opened newlist)
Packit f2bd10
	    (and (extent-object ov)
Packit f2bd10
		 (not (extent-detached-p ov))
Packit f2bd10
		 (eq (extent-property ov 'preview-state) 'inactive)
Packit f2bd10
		 (if (and (eq (extent-object ov) (current-buffer))
Packit f2bd10
			  (or (<= pt (extent-start-position ov))
Packit f2bd10
			      (>= pt (extent-end-position ov))))
Packit f2bd10
		     (preview-toggle ov t)
Packit f2bd10
		   (push ov newlist)))))
Packit f2bd10
    (if	(preview-auto-reveal-p
Packit f2bd10
	 preview-auto-reveal
Packit f2bd10
	 (setq distance
Packit f2bd10
	       (and (eq (marker-buffer preview-marker)
Packit f2bd10
			(current-buffer))
Packit f2bd10
		    (- pt (marker-position preview-marker)))))
Packit f2bd10
	(map-extents #'preview-open-overlay nil
Packit f2bd10
		     pt pt nil nil 'preview-state 'active)
Packit f2bd10
      (let (newpt)
Packit f2bd10
	(while (setq newpt
Packit f2bd10
		     (map-extents #'preview-skip-overlay nil
Packit f2bd10
				  pt pt (and distance (< distance 0)) nil
Packit f2bd10
				  'preview-state 'active))
Packit f2bd10
	  (setq pt newpt))
Packit f2bd10
	(goto-char pt)))))
Packit f2bd10
Packit f2bd10
(defun preview-skip-overlay (ovr backward)
Packit f2bd10
  "Skip point over OVR, BACKWARD is set if backwards.
Packit f2bd10
Returns new position or NIL."
Packit f2bd10
  (if backward
Packit f2bd10
      (and (> (extent-start-position ovr) (point-min))
Packit f2bd10
	   (1- (extent-start-position ovr)))
Packit f2bd10
    (and (<= (extent-end-position ovr) (point-max))
Packit f2bd10
	 (> (extent-end-position ovr) (extent-start-position ovr))
Packit f2bd10
	 (extent-end-position ovr))))
Packit f2bd10
Packit f2bd10
(defun preview-open-overlay (ovr ignored)
Packit f2bd10
  "Open the active preview OVR, IGNORED gets ignored.
Packit f2bd10
NIL is returned: this is for `map-extents'."
Packit f2bd10
  (preview-toggle ovr)
Packit f2bd10
  (push ovr preview-temporary-opened)
Packit f2bd10
  nil)
Packit f2bd10
Packit f2bd10
(defadvice isearch-highlight (before preview protect disable)
Packit f2bd10
  "Make isearch open preview text that's a search hit.
Packit f2bd10
Also make `query-replace' open preview text about to be replaced."
Packit f2bd10
  (map-extents #'preview-open-overlay nil
Packit f2bd10
	       (ad-get-arg 0) (ad-get-arg 1)
Packit f2bd10
	       nil nil 'preview-state 'active))
Packit f2bd10
Packit f2bd10
(defcustom preview-query-replace-reveal t
Packit f2bd10
  "*Make `isearch' and `query-replace' autoreveal previews."
Packit f2bd10
  :group 'preview-appearance
Packit f2bd10
  :type 'boolean
Packit f2bd10
  :require 'preview
Packit f2bd10
  :set (lambda (symbol value)
Packit f2bd10
	 (set-default symbol value)
Packit f2bd10
	 (if value
Packit f2bd10
	     (ad-enable-advice 'isearch-highlight 'before 'preview)
Packit f2bd10
	   (ad-disable-advice 'isearch-highlight 'before 'preview))
Packit f2bd10
	 (ad-activate 'isearch-highlight))
Packit f2bd10
  :initialize #'custom-initialize-reset)
Packit f2bd10
Packit f2bd10
;; Here is the beef: for best intuitiveness, we want to have
Packit f2bd10
;; insertions be carried out as expected before iconized text
Packit f2bd10
;; passages, but we want to insert *into* the overlay when not
Packit f2bd10
;; iconized.  A preview that has become empty can not get content
Packit f2bd10
;; again: we remove it.  A disabled preview needs no insert-in-front
Packit f2bd10
;; handler.
Packit f2bd10
Packit f2bd10
(defvar preview-change-list nil
Packit f2bd10
  "List of tentatively changed overlays.")
Packit f2bd10
Packit f2bd10
(defcustom preview-dump-threshold
Packit f2bd10
  "^ *\\\\begin *{document}[ %]*$"
Packit f2bd10
  "*Regexp denoting end of preamble.
Packit f2bd10
This is the location up to which preamble changes are considered
Packit f2bd10
to require redumping of a format."
Packit f2bd10
  :group 'preview-latex
Packit f2bd10
  :type 'string)
Packit f2bd10
Packit f2bd10
(defvar preview-preamble-format-cons nil
Packit f2bd10
  "Where our preamble is supposed to end.")
Packit f2bd10
(make-variable-buffer-local 'preview-preamble-format-cons)
Packit f2bd10
Packit f2bd10
(defun preview-preamble-check-change (beg end)
Packit f2bd10
  "Hook function for change hooks on preamble.
Packit f2bd10
Reacts to changes between BEG and END."
Packit f2bd10
  (when (and (consp (cdr preview-preamble-format-cons))
Packit f2bd10
	     (cddr preview-preamble-format-cons)
Packit f2bd10
	     (< beg (cddr preview-preamble-format-cons)))
Packit f2bd10
    (preview-unwatch-preamble preview-preamble-format-cons)
Packit f2bd10
    (preview-format-kill preview-preamble-format-cons)
Packit f2bd10
    (setcdr preview-preamble-format-cons t)))
Packit f2bd10
Packit f2bd10
(defun preview-watch-preamble (file command format-cons)
Packit f2bd10
  "Set up a watch on master file FILE.
Packit f2bd10
FILE can be an associated buffer instead of a filename.
Packit f2bd10
COMMAND is the command that generated the format.
Packit f2bd10
FORMAT-CONS contains the format info for the main
Packit f2bd10
format dump handler."
Packit f2bd10
  (let ((buffer (if (bufferp file)
Packit f2bd10
		    file
Packit f2bd10
		  (find-buffer-visiting file))) ov)
Packit f2bd10
    (setq preview-preamble-format-cons nil)
Packit f2bd10
    (setcdr
Packit f2bd10
     format-cons
Packit f2bd10
     (cons command
Packit f2bd10
	   (when buffer
Packit f2bd10
	     (with-current-buffer buffer
Packit f2bd10
	       (save-excursion
Packit f2bd10
		 (save-restriction
Packit f2bd10
		   (widen)
Packit f2bd10
		   (goto-char (point-min))
Packit f2bd10
		   (unless (re-search-forward preview-dump-threshold nil t)
Packit f2bd10
		     (error "Can't find preamble of `%s'" file))
Packit f2bd10
		   (setq preview-preamble-format-cons format-cons)
Packit f2bd10
		   (point)))))))))
Packit f2bd10
Packit f2bd10
(defun preview-unwatch-preamble (format-cons)
Packit f2bd10
  "Stop watching a format on FORMAT-CONS.
Packit f2bd10
The watch has been set up by `preview-watch-preamble'."
Packit f2bd10
  (when (consp (cdr format-cons))
Packit f2bd10
    (setcdr (cdr format-cons) nil)))
Packit f2bd10
Packit f2bd10
(defun preview-register-change (ov map-arg)
Packit f2bd10
  "Register not yet changed OV for verification.
Packit f2bd10
This stores the old contents of the overlay in the
Packit f2bd10
`preview-prechange' property and puts the overlay into
Packit f2bd10
`preview-change-list' where `preview-check-changes' will
Packit f2bd10
find it at some later point of time.  MAP-ARG is ignored;
Packit f2bd10
it is usually generated by `map-extents'."
Packit f2bd10
  (unless (extent-property ov 'preview-prechange)
Packit f2bd10
    (if (eq (extent-property ov 'preview-state) 'disabled)
Packit f2bd10
	(set-extent-property ov 'preview-prechange t)
Packit f2bd10
      (set-extent-property ov
Packit f2bd10
			   'preview-prechange
Packit f2bd10
			   (save-restriction
Packit f2bd10
			     (widen)
Packit f2bd10
			     (buffer-substring-no-properties
Packit f2bd10
			      (extent-start-position ov)
Packit f2bd10
			      (extent-end-position ov)))))
Packit f2bd10
    (push ov preview-change-list))
Packit f2bd10
  nil)
Packit f2bd10
Packit f2bd10
(defun preview-check-changes ()
Packit f2bd10
  "Check whether the contents under the overlay have changed.
Packit f2bd10
Disable it if that is the case.  Ignores text properties."
Packit f2bd10
  (dolist (ov preview-change-list)
Packit f2bd10
    (condition-case nil
Packit f2bd10
	(with-current-buffer (extent-object ov)
Packit f2bd10
	  (let ((text (save-restriction
Packit f2bd10
			(widen)
Packit f2bd10
			(buffer-substring-no-properties
Packit f2bd10
			 (extent-start-position ov)
Packit f2bd10
			 (extent-end-position ov)))))
Packit f2bd10
	    (if (or (zerop (length text))
Packit f2bd10
		    (extent-detached-p ov))
Packit f2bd10
		(preview-delete ov)
Packit f2bd10
	      (unless
Packit f2bd10
		  (or (eq (extent-property ov 'preview-state) 'disabled)
Packit f2bd10
		      (preview-relaxed-string=
Packit f2bd10
		       text (extent-property ov 'preview-prechange)))
Packit f2bd10
		(preview-disable ov)))))
Packit f2bd10
      (error nil))
Packit f2bd10
    (set-extent-property ov 'preview-prechange nil))
Packit f2bd10
  (setq preview-change-list nil))
Packit f2bd10
Packit f2bd10
(defun preview-handle-before-change (beg end)
Packit f2bd10
  "Hook function for `before-change-functions'.
Packit f2bd10
Receives BEG and END, the affected region."
Packit f2bd10
  (map-extents #'preview-register-change nil beg end
Packit f2bd10
	       nil nil 'preview-state)
Packit f2bd10
  (preview-preamble-check-change beg end))
Packit f2bd10
Packit f2bd10
(defun preview-handle-after-change (beg end length)
Packit f2bd10
  "Hook function for `after-change-functions'.
Packit f2bd10
Receives BEG and END, the affected region, and LENGTH
Packit f2bd10
of an insertion."
Packit f2bd10
  (when (and preview-change-list
Packit f2bd10
	     (zerop length)
Packit f2bd10
	     (not (eq this-command 'undo)))
Packit f2bd10
    (map-extents (lambda (ov maparg)
Packit f2bd10
		   (set-extent-endpoints
Packit f2bd10
		    ov maparg (extent-end-position ov))) nil
Packit f2bd10
		    beg beg end 'start-in-region 'preview-state 'active)
Packit f2bd10
    (map-extents (lambda (ov maparg)
Packit f2bd10
		   (set-extent-endpoints
Packit f2bd10
		    ov (extent-start-position ov) maparg)) nil
Packit f2bd10
		    end end beg 'end-in-region 'preview-state 'active)))
Packit f2bd10
Packit f2bd10
(defun preview-import-image (image)
Packit f2bd10
  "Convert the printable IMAGE rendition back to an image."
Packit f2bd10
  (cond ((stringp image)
Packit f2bd10
	 (setq image (copy-sequence image))
Packit f2bd10
	 (add-text-properties 0 (length image)
Packit f2bd10
			      '(face preview-face)
Packit f2bd10
			      image)
Packit f2bd10
	 image)
Packit f2bd10
	((eq (car image) 'image)
Packit f2bd10
	 (let ((plist (cdr image)))
Packit f2bd10
	   (preview-create-icon-1
Packit f2bd10
	    (plist-get plist :file)
Packit f2bd10
	    (plist-get plist :type)
Packit f2bd10
	    (plist-get plist :ascent))))
Packit f2bd10
	(t
Packit f2bd10
	 (preview-create-icon-1 (nth 0 image)
Packit f2bd10
				(nth 1 image)
Packit f2bd10
				(nth 2 image)))))
Packit f2bd10
Packit f2bd10
(if (eq system-type 'windows-nt)
Packit f2bd10
    (defadvice preview-ps-quote-filename (around path-sep-to-slash)
Packit f2bd10
      "Make path separator to slash so that the function will not be confused."
Packit f2bd10
      (let ((directory-sep-char ?/))
Packit f2bd10
	ad-do-it)))
Packit f2bd10
Packit f2bd10
(provide 'prv-xemacs)
Packit f2bd10
Packit f2bd10
;;; Local variables:
Packit f2bd10
;;; eval: (put 'preview-defmacro 'lisp-indent-function 'defun)
Packit f2bd10
;;; end:
Packit f2bd10
Packit f2bd10
;;; prv-xemacs.el ends here