;;; doc-view.el --- View PDF/PostScript/DVI files in Emacs -*- lexical-binding: t -*-
-;; Copyright (C) 2007-2013 Free Software Foundation, Inc.
+;; Copyright (C) 2007-2014 Free Software Foundation, Inc.
;;
;; Author: Tassilo Horn <tsdh@gnu.org>
;; Maintainer: Tassilo Horn <tsdh@gnu.org>
If nil, the document is re-rendered every time the scaling factor is modified.
This only has an effect if the image libraries linked with Emacs support
scaling."
+ :version "24.4"
:type 'boolean)
(defcustom doc-view-image-width 850
;; Don't do it if there's a conversion is running, since in that case, it
;; will be done later.
(with-selected-window (car winprops)
- (doc-view-goto-page 1)))))
+ (doc-view-goto-page (image-mode-window-get 'page t))))))
(defvar-local doc-view--current-files nil
"Only used internally.")
(define-key map (kbd "RET") 'image-next-line)
;; Zoom in/out.
(define-key map "+" 'doc-view-enlarge)
+ (define-key map "=" 'doc-view-enlarge)
(define-key map "-" 'doc-view-shrink)
+ (define-key map "0" 'doc-view-scale-reset)
+ (define-key map [remap text-scale-adjust] 'doc-view-scale-adjust)
;; Fit the image to the window
(define-key map "W" 'doc-view-fit-width-to-window)
(define-key map "H" 'doc-view-fit-height-to-window)
;; how many pages will be available.
(null doc-view--current-converter-processes))
(setq page len)))
+ (force-mode-line-update) ;To update `current-page'.
(setf (doc-view-current-page) page
(doc-view-current-info)
(concat
(defun doc-view-make-safe-dir (dir)
(condition-case nil
- (let ((umask (default-file-modes)))
- (unwind-protect
- (progn
- ;; Create temp files with strict access rights. It's easy to
- ;; loosen them later, whereas it's impossible to close the
- ;; time-window of loose permissions otherwise.
- (set-default-file-modes #o0700)
- (make-directory dir))
- ;; Reset the umask.
- (set-default-file-modes umask)))
+ ;; Create temp files with strict access rights. It's easy to
+ ;; loosen them later, whereas it's impossible to close the
+ ;; time-window of loose permissions otherwise.
+ (with-file-modes #o0700 (make-directory dir))
(file-already-exists
(when (file-symlink-p dir)
(error "Danger: %s points to a symbolic link" dir))
(interactive (list doc-view-shrink-factor))
(doc-view-enlarge (/ 1.0 factor)))
+(defun doc-view-scale-reset ()
+ "Reset the document size/zoom level to the initial one."
+ (interactive)
+ (if (and doc-view-scale-internally
+ (eq (plist-get (cdr (doc-view-current-image)) :type)
+ 'imagemagick))
+ (progn
+ (kill-local-variable 'doc-view-image-width)
+ (doc-view-insert-image
+ (plist-get (cdr (doc-view-current-image)) :file)
+ :width doc-view-image-width))
+ (kill-local-variable 'doc-view-resolution)
+ (doc-view-reconvert-doc)))
+
+(defun doc-view-scale-adjust (factor)
+ "Adjust the scale of the DocView page images by FACTOR.
+FACTOR defaults to `doc-view-shrink-factor'.
+
+The actual adjustment made depends on the final component of the
+key-binding used to invoke the command, with all modifiers removed:
+
+ +, = Increase the image scale by FACTOR
+ - Decrease the image scale by FACTOR
+ 0 Reset the image scale to the initial scale"
+ (interactive (list doc-view-shrink-factor))
+ (let ((ev last-command-event)
+ (echo-keystrokes nil))
+ (pcase (event-basic-type ev)
+ ((or ?+ ?=) (doc-view-enlarge factor))
+ (?- (doc-view-shrink factor))
+ (?0 (doc-view-scale-reset)))))
+
(defun doc-view-fit-width-to-window ()
"Fit the image width to the window width."
(interactive)
(car (image-size image 'pixels)))
img-width)
img-width))
- (window-width (window-width (selected-window))))
+ (window-width (window-width)))
(setf (doc-view-current-image) image)
(move-overlay ol (point-min) (point-max))
;; In case the window is wider than the image, center the image
(tooltip-show (doc-view-current-info)))
(defun doc-view-open-text ()
- "Open a buffer with the current doc's contents as text."
+ "Display the current doc's contents as text."
(interactive)
(if doc-view--current-converter-processes
(message "DocView: please wait till conversion finished.")
(let ((txt (expand-file-name "doc.txt" (doc-view--current-cache-dir))))
(if (file-readable-p txt)
- (let ((name (concat "Text contents of "
- (file-name-nondirectory buffer-file-name)))
- (dir (file-name-directory buffer-file-name)))
- (with-current-buffer (find-file txt)
- (rename-buffer name)
- (setq default-directory dir)))
+ (let ((inhibit-read-only t)
+ (buffer-undo-list t)
+ (dv-bfn doc-view--buffer-file-name))
+ (erase-buffer)
+ (set-buffer-multibyte t)
+ (insert-file-contents txt)
+ (text-mode)
+ (setq-local doc-view--buffer-file-name dv-bfn)
+ (set-buffer-modified-p nil)
+ (doc-view-minor-mode)
+ (add-hook 'write-file-functions
+ (lambda ()
+ (when (eq major-mode 'text-mode)
+ (error "Cannot save text contents of document %s"
+ buffer-file-name)))
+ nil t))
(doc-view-doc->txt txt 'doc-view-open-text)))))
;;;;; Toggle between editing and viewing
(defun doc-view-toggle-display ()
"Toggle between editing a document as text or viewing it."
(interactive)
- (if (eq major-mode 'doc-view-mode)
- ;; Switch to editing mode
- (progn
- (doc-view-kill-proc)
- (setq buffer-read-only nil)
- ;; Switch to the previously used major mode or fall back to
- ;; normal mode.
- (doc-view-fallback-mode)
- (doc-view-minor-mode 1))
+ (cond
+ ((eq major-mode 'doc-view-mode)
+ ;; Switch to editing mode
+ (doc-view-kill-proc)
+ (setq buffer-read-only nil)
+ ;; Switch to the previously used major mode or fall back to
+ ;; normal mode.
+ (doc-view-fallback-mode)
+ (doc-view-minor-mode 1))
+ ((eq major-mode 'text-mode)
+ (let ((buffer-undo-list t))
+ ;; We're currently viewing the document's text contents, so switch
+ ;; back to .
+ (setq buffer-read-only nil)
+ (insert-file-contents doc-view--buffer-file-name nil nil nil t)
+ (doc-view-fallback-mode)
+ (doc-view-minor-mode 1)
+ (set-buffer-modified-p nil)))
+ (t
;; Switch to doc-view-mode
(when (and (buffer-modified-p)
(y-or-n-p "The buffer has been modified. Save the changes? "))
(save-buffer))
- (doc-view-mode)))
+ (doc-view-mode))))
;;;; Searching
(concat "No PNG support is available, or some conversion utility for "
(file-name-extension doc-view--buffer-file-name)
" files is missing."))
- (when (and (executable-find doc-view-pdftotext-program)
- (y-or-n-p
- "Unable to render file. View extracted text instead? "))
- (doc-view-open-text))
- (doc-view-toggle-display)))
+ (if (and (executable-find doc-view-pdftotext-program)
+ (y-or-n-p
+ "Unable to render file. View extracted text instead? "))
+ (doc-view-open-text)
+ (doc-view-toggle-display))))
(defvar bookmark-make-record-function)
"Figure out the current document type (`doc-view-doc-type')."
(let ((name-types
(when buffer-file-name
- (cdr (assoc (file-name-extension buffer-file-name)
- '(
- ;; DVI
- ("dvi" dvi)
- ;; PDF
- ("pdf" pdf) ("epdf" pdf)
- ;; PostScript
- ("ps" ps) ("eps" ps)
- ;; DjVu
- ("djvu" djvu)
- ;; OpenDocument formats
- ("odt" odf) ("ods" odf) ("odp" odf) ("odg" odf)
- ("odc" odf) ("odi" odf) ("odm" odf) ("ott" odf)
- ("ots" odf) ("otp" odf) ("otg" odf)
- ;; Microsoft Office formats (also handled
- ;; by the odf conversion chain)
- ("doc" odf) ("docx" odf) ("xls" odf) ("xlsx" odf)
- ("ppt" odf) ("pptx" odf))))))
+ (cdr (assoc-string
+ (file-name-extension buffer-file-name)
+ '(
+ ;; DVI
+ ("dvi" dvi)
+ ;; PDF
+ ("pdf" pdf) ("epdf" pdf)
+ ;; PostScript
+ ("ps" ps) ("eps" ps)
+ ;; DjVu
+ ("djvu" djvu)
+ ;; OpenDocument formats.
+ ("odt" odf) ("ods" odf) ("odp" odf) ("odg" odf)
+ ("odc" odf) ("odi" odf) ("odm" odf) ("ott" odf)
+ ("ots" odf) ("otp" odf) ("otg" odf)
+ ;; Microsoft Office formats (also handled by the odf
+ ;; conversion chain).
+ ("doc" odf) ("docx" odf) ("xls" odf) ("xlsx" odf)
+ ("ppt" odf) ("pps" odf) ("pptx" odf))
+ t))))
(content-types
(save-excursion
(goto-char (point-min))
"/" (:eval (number-to-string (doc-view-last-page-number)))))
;; Don't scroll unless the user specifically asked for it.
(setq-local auto-hscroll-mode nil)
- (setq-local mwheel-scroll-up-function #'doc-view-scroll-up-or-next-page)
- (setq-local mwheel-scroll-down-function
- #'doc-view-scroll-down-or-previous-page)
+ (if (boundp 'mwheel-scroll-up-function) ; not --without-x build
+ (setq-local mwheel-scroll-up-function
+ #'doc-view-scroll-up-or-next-page))
+ (if (boundp 'mwheel-scroll-down-function)
+ (setq-local mwheel-scroll-down-function
+ #'doc-view-scroll-down-or-previous-page))
(setq-local cursor-type nil)
(use-local-map doc-view-mode-map)
(add-hook 'after-revert-hook 'doc-view-reconvert-doc nil t)
`((page . ,(doc-view-current-page))
(handler . doc-view-bookmark-jump))))
-
;;;###autoload
(defun doc-view-bookmark-jump (bmk)
;; This implements the `handler' function interface for record type
;; returned by `doc-view-bookmark-make-record', which see.
- (prog1 (bookmark-default-handler bmk)
- (let ((page (bookmark-prop-get bmk 'page)))
- (when (not (eq major-mode 'doc-view-mode))
- (doc-view-toggle-display))
- (with-selected-window
- (or (get-buffer-window (current-buffer) 0)
- (selected-window))
- (doc-view-goto-page page)))))
-
+ (let ((page (bookmark-prop-get bmk 'page))
+ (show-fn-sym (make-symbol "doc-view-bookmark-after-jump-hook")))
+ (fset show-fn-sym
+ (lambda ()
+ (remove-hook 'bookmark-after-jump-hook show-fn-sym)
+ (when (not (eq major-mode 'doc-view-mode))
+ (doc-view-toggle-display))
+ (with-selected-window
+ (or (get-buffer-window (current-buffer) 0)
+ (selected-window))
+ (doc-view-goto-page page))))
+ (add-hook 'bookmark-after-jump-hook show-fn-sym)
+ (bookmark-default-handler bmk)))
(provide 'doc-view)