Misc manual updates.
[bpt/emacs.git] / lisp / doc-view.el
index 7bead62..53e7811 100644 (file)
@@ -1,7 +1,7 @@
 ;;; doc-view.el --- View PDF/PostScript/DVI files in Emacs -*- lexical-binding: t -*-
 
 
 ;;; doc-view.el --- View PDF/PostScript/DVI files in Emacs -*- lexical-binding: t -*-
 
 
-;; Copyright (C) 2007-2011 Free Software Foundation, Inc.
+;; Copyright (C) 2007-2012 Free Software Foundation, Inc.
 ;;
 ;; Author: Tassilo Horn <tassilo@member.fsf.org>
 ;; Maintainer: Tassilo Horn <tassilo@member.fsf.org>
 ;;
 ;; Author: Tassilo Horn <tassilo@member.fsf.org>
 ;; Maintainer: Tassilo Horn <tassilo@member.fsf.org>
 ;; (except the tooltip) if the next match is on the same page.
 
 ;; And it's much slower than the current search facility, because
 ;; (except the tooltip) if the next match is on the same page.
 
 ;; And it's much slower than the current search facility, because
-;; isearch really searches for each step forward or backward wheras
+;; isearch really searches for each step forward or backward whereas
 ;; the current approach searches once and then it knows to which
 ;; pages to jump.
 
 ;; the current approach searches once and then it knows to which
 ;; pages to jump.
 
   :group 'multimedia
   :prefix "doc-view-")
 
   :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)
   "Program to convert PS and PDF files to PNG."
   :type 'file
   :group 'doc-view)
@@ -172,10 +172,11 @@ Higher values result in larger images."
 (defcustom doc-view-image-width 850
   "Default image width.
 Has only an effect if imagemagick support is compiled into emacs."
 (defcustom doc-view-image-width 850
   "Default image width.
 Has only an effect if imagemagick support is compiled into emacs."
+  :version "24.1"
   :type 'number
   :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
   "Program to convert DVI files to PDF.
 
 DVI file will be converted to PDF before the resulting PDF is
@@ -186,7 +187,7 @@ If this and `doc-view-dvipdf-program' are set,
   :type 'file
   :group 'doc-view)
 
   :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
   "Program to convert DVI files to PDF.
 
 DVI file will be converted to PDF before the resulting PDF is
@@ -197,21 +198,22 @@ If this and `doc-view-dvipdfm-program' are set,
   :type 'file
   :group 'doc-view)
 
   :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."
   "Program to convert any file type readable by OpenOffice.org to PDF.
 
 Needed for viewing OpenOffice.org (and MS Office) files."
+  :version "24.1"
   :type 'file
   :group 'doc-view)
 
   :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)
 
   "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."
   "Program to convert PDF files to plain text.
 
 Needed for searching."
@@ -328,6 +330,10 @@ Can be `dvi', `pdf', or `ps'.")
     ;; Zoom in/out.
     (define-key map "+"               'doc-view-enlarge)
     (define-key map "-"               'doc-view-shrink)
     ;; 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)
     ;; 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)
@@ -565,18 +571,18 @@ at the top edge of the page moves to the previous page."
 (defun doc-view-make-safe-dir (dir)
   (condition-case nil
       (let ((umask (default-file-modes)))
 (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
     (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
      ;; 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
@@ -585,7 +591,12 @@ at the top edge of the page moves to the previous page."
      ;; 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.
      ;; 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-current-cache-dir ()
   "Return the directory where the png files of the current doc should be saved.
@@ -610,9 +621,10 @@ It's a subdirectory of `doc-view-cache-directory'."
 (defun doc-view-remove-if (predicate list)
   "Return LIST with all items removed that satisfy PREDICATE."
   (let (new-list)
 (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))
       (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)
 
 ;;;###autoload
 (defun doc-view-mode-p (type)
@@ -664,6 +676,78 @@ OpenDocument format)."
   (interactive (list doc-view-shrink-factor))
   (doc-view-enlarge (/ 1.0 factor)))
 
   (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-reconvert-doc ()
   "Reconvert the current document.
 Should be invoked when the cached images aren't up-to-date."
@@ -799,7 +883,7 @@ Start by converting PAGES, and then the rest."
 
 (defun doc-view-pdf->txt (pdf txt callback)
   "Convert PDF to TXT asynchronously and call CALLBACK when finished."
 
 (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)
       (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)
@@ -835,7 +919,7 @@ Start by converting PAGES, and then the rest."
 
 (defun doc-view-ps->pdf (ps pdf callback)
   "Convert PS to PDF asynchronously and call CALLBACK when finished."
 
 (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
       (error "You need the `ps2pdf' program to convert PS to PDF"))
   (doc-view-start-process "ps->pdf" doc-view-ps2pdf-program
                           (list
@@ -1420,8 +1504,11 @@ to the next best mode."
 
 ;;;###autoload
 (define-minor-mode doc-view-minor-mode
 
 ;;;###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
 See the command `doc-view-mode' for more information on this mode."
   nil " DocView" doc-view-minor-mode-map
   :group 'doc-view
@@ -1473,7 +1560,7 @@ See the command `doc-view-mode' for more information on this mode."
 (provide 'doc-view)
 
 ;; Local Variables:
 (provide 'doc-view)
 
 ;; Local Variables:
-;; mode: outline-minor
+;; eval: (outline-minor-mode 1)
 ;; End:
 
 ;;; doc-view.el ends here
 ;; End:
 
 ;;; doc-view.el ends here