-;;; -*- lexical-binding: t -*-
-;;; doc-view.el --- View PDF/PostScript/DVI files in Emacs
+;;; doc-view.el --- View PDF/PostScript/DVI files in Emacs -*- lexical-binding: t -*-
+
;; Copyright (C) 2007-2011 Free Software Foundation, Inc.
;;
:group 'multimedia
:prefix "doc-view-")
-(defcustom doc-view-ghostscript-program (executable-find "gs")
+(defcustom doc-view-ghostscript-program "gs"
"Program to convert PS and PDF files to PNG."
:type 'file
:group 'doc-view)
:type 'number
:group 'doc-view)
-(defcustom doc-view-dvipdfm-program (executable-find "dvipdfm")
+(defcustom doc-view-dvipdfm-program "dvipdfm"
"Program to convert DVI files to PDF.
DVI file will be converted to PDF before the resulting PDF is
:type 'file
:group 'doc-view)
-(defcustom doc-view-dvipdf-program (executable-find "dvipdf")
+(defcustom doc-view-dvipdf-program "dvipdf"
"Program to convert DVI files to PDF.
DVI file will be converted to PDF before the resulting PDF is
:type 'file
:group 'doc-view)
-(defcustom doc-view-unoconv-program (executable-find "unoconv")
+(defcustom doc-view-unoconv-program "unoconv"
"Program to convert any file type readable by OpenOffice.org to PDF.
Needed for viewing OpenOffice.org (and MS Office) files."
:type 'file
:group 'doc-view)
-(defcustom doc-view-ps2pdf-program (executable-find "ps2pdf")
+(defcustom doc-view-ps2pdf-program "ps2pdf"
"Program to convert PS files to PDF.
PS files will be converted to PDF before searching is possible."
:type 'file
:group 'doc-view)
-(defcustom doc-view-pdftotext-program (executable-find "pdftotext")
+(defcustom doc-view-pdftotext-program "pdftotext"
"Program to convert PDF files to plain text.
Needed for searching."
;; Zoom in/out.
(define-key map "+" 'doc-view-enlarge)
(define-key map "-" 'doc-view-shrink)
+ ;; 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)
+ (define-key map "P" 'doc-view-fit-page-to-window)
;; Killing the buffer (and the process)
(define-key map (kbd "k") 'doc-view-kill-proc-and-buffer)
(define-key map (kbd "K") 'doc-view-kill-proc)
(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)))
+ (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)))
(file-already-exists
- (if (file-symlink-p dir)
- (error "Danger: %s points to a symbolic link" dir))
+ (when (file-symlink-p dir)
+ (error "Danger: %s points to a symbolic link" dir))
;; In case it was created earlier with looser rights.
;; We could check the mode info returned by file-attributes, but it's
;; a pain to parse and it may not tell you what we want under
;; This also ends up checking a bunch of useful conditions: it makes
;; sure we have write-access to the directory and that we own it, thus
;; closing a bunch of security holes.
- (set-file-modes dir #o0700))))
+ (condition-case error
+ (set-file-modes dir #o0700)
+ (file-error
+ (error
+ (format "Unable to use temporary directory %s: %s"
+ dir (mapconcat 'identity (cdr error) " "))))))))
(defun doc-view-current-cache-dir ()
"Return the directory where the png files of the current doc should be saved.
(defun doc-view-remove-if (predicate list)
"Return LIST with all items removed that satisfy PREDICATE."
(let (new-list)
- (dolist (item list (nreverse new-list))
+ (dolist (item list)
(when (not (funcall predicate item))
- (setq new-list (cons item new-list))))))
+ (setq new-list (cons item new-list))))
+ (nreverse new-list)))
;;;###autoload
(defun doc-view-mode-p (type)
(interactive (list doc-view-shrink-factor))
(doc-view-enlarge (/ 1.0 factor)))
+(defun doc-view-fit-width-to-window ()
+ "Fit the image width to the window width."
+ (interactive)
+ (let ((win-width (- (nth 2 (window-inside-pixel-edges))
+ (nth 0 (window-inside-pixel-edges))))
+ (slice (doc-view-current-slice)))
+ (if (not slice)
+ (let ((img-width (car (image-display-size
+ (image-get-display-property) t))))
+ (doc-view-enlarge (/ (float win-width) (float img-width))))
+
+ ;; If slice is set
+ (let* ((slice-width (nth 2 slice))
+ (scale-factor (/ (float win-width) (float slice-width)))
+ (new-slice (mapcar (lambda (x) (ceiling (* scale-factor x))) slice)))
+
+ (doc-view-enlarge scale-factor)
+ (setf (doc-view-current-slice) new-slice)
+ (doc-view-goto-page (doc-view-current-page))))))
+
+(defun doc-view-fit-height-to-window ()
+ "Fit the image height to the window height."
+ (interactive)
+ (let ((win-height (- (nth 3 (window-inside-pixel-edges))
+ (nth 1 (window-inside-pixel-edges))))
+ (slice (doc-view-current-slice)))
+ (if (not slice)
+ (let ((img-height (cdr (image-display-size
+ (image-get-display-property) t))))
+ ;; When users call 'doc-view-fit-height-to-window',
+ ;; they might want to go to next page by typing SPC
+ ;; ONLY once. So I used '(- win-height 1)' instead of
+ ;; 'win-height'
+ (doc-view-enlarge (/ (float (- win-height 1)) (float img-height))))
+
+ ;; If slice is set
+ (let* ((slice-height (nth 3 slice))
+ (scale-factor (/ (float (- win-height 1)) (float slice-height)))
+ (new-slice (mapcar (lambda (x) (ceiling (* scale-factor x))) slice)))
+
+ (doc-view-enlarge scale-factor)
+ (setf (doc-view-current-slice) new-slice)
+ (doc-view-goto-page (doc-view-current-page))))))
+
+(defun doc-view-fit-page-to-window ()
+ "Fit the image to the window.
+More specifically, this function enlarges image by:
+
+min {(window-width / image-width), (window-height / image-height)} times."
+ (interactive)
+ (let ((win-width (- (nth 2 (window-inside-pixel-edges))
+ (nth 0 (window-inside-pixel-edges))))
+ (win-height (- (nth 3 (window-inside-pixel-edges))
+ (nth 1 (window-inside-pixel-edges))))
+ (slice (doc-view-current-slice)))
+ (if (not slice)
+ (let ((img-width (car (image-display-size
+ (image-get-display-property) t)))
+ (img-height (cdr (image-display-size
+ (image-get-display-property) t))))
+ (doc-view-enlarge (min (/ (float win-width) (float img-width))
+ (/ (float (- win-height 1)) (float img-height)))))
+ ;; If slice is set
+ (let* ((slice-width (nth 2 slice))
+ (slice-height (nth 3 slice))
+ (scale-factor (min (/ (float win-width) (float slice-width))
+ (/ (float (- win-height 1)) (float slice-height))))
+ (new-slice (mapcar (lambda (x) (ceiling (* scale-factor x))) slice)))
+ (doc-view-enlarge scale-factor)
+ (setf (doc-view-current-slice) new-slice)
+ (doc-view-goto-page (doc-view-current-page))))))
+
(defun doc-view-reconvert-doc ()
"Reconvert the current document.
Should be invoked when the cached images aren't up-to-date."
(defun doc-view-pdf->txt (pdf txt callback)
"Convert PDF to TXT asynchronously and call CALLBACK when finished."
- (or doc-view-pdftotext-program
+ (or (executable-find doc-view-pdftotext-program)
(error "You need the `pdftotext' program to convert a PDF to text"))
(doc-view-start-process "pdf->txt" doc-view-pdftotext-program
(list "-raw" pdf txt)
(defun doc-view-ps->pdf (ps pdf callback)
"Convert PS to PDF asynchronously and call CALLBACK when finished."
- (or doc-view-ps2pdf-program
+ (or (executable-find doc-view-ps2pdf-program)
(error "You need the `ps2pdf' program to convert PS to PDF"))
(doc-view-start-process "ps->pdf" doc-view-ps2pdf-program
(list
;;;###autoload
(define-minor-mode doc-view-minor-mode
- "Toggle Doc view minor mode.
-With arg, turn Doc view minor mode on if arg is positive, off otherwise.
+ "Toggle displaying buffer via Doc View (Doc View minor mode).
+With a prefix argument ARG, enable Doc View minor mode if ARG is
+positive, and disable it otherwise. If called from Lisp, enable
+the mode if ARG is omitted or nil.
+
See the command `doc-view-mode' for more information on this mode."
nil " DocView" doc-view-minor-mode-map
:group 'doc-view
(provide 'doc-view)
;; Local Variables:
-;; mode: outline-minor
+;; eval: (outline-minor-mode 1)
;; End:
;;; doc-view.el ends here