changeset 112039:2fef20daac2b

* doc-view.el (doc-view-set-doc-type): New function refactored from doc-view-mode. (doc-view-fallback-mode): New function. (doc-view-mode): Use it. (doc-view-mode-maybe): New function that checks if doc-view-mode can be used and falls back to the next best mode otherwise. * files.el (auto-mode-alist): Use doc-view-mode-maybe for PDF, DVI, OpenDocument, and MS Office files.
author Tassilo Horn <tassilo@member.fsf.org>
date Thu, 30 Dec 2010 19:08:18 +0100
parents ad2a8fce0d7a
children 491d94613848
files lisp/ChangeLog lisp/doc-view.el lisp/files.el
diffstat 3 files changed, 76 insertions(+), 41 deletions(-) [+]
line wrap: on
line diff
--- a/lisp/ChangeLog	Thu Dec 30 16:15:34 2010 +0100
+++ b/lisp/ChangeLog	Thu Dec 30 19:08:18 2010 +0100
@@ -1,3 +1,15 @@
+2010-12-30  Tassilo Horn  <tassilo@member.fsf.org>
+
+	* doc-view.el (doc-view-set-doc-type): New function refactored
+	from doc-view-mode.
+	(doc-view-fallback-mode): New function.
+	(doc-view-mode): Use it.
+	(doc-view-mode-maybe): New function that checks if doc-view-mode
+	can be used and falls back to the next best mode otherwise.
+
+	* files.el (auto-mode-alist): Use doc-view-mode-maybe for PDF,
+	DVI, OpenDocument, and MS Office files.
+
 2010-12-30  Andreas Schwab  <schwab@linux-m68k.org>
 
 	* emacs-lisp/rx.el (rx-syntax): Fix typo.
--- a/lisp/doc-view.el	Thu Dec 30 16:15:34 2010 +0100
+++ b/lisp/doc-view.el	Thu Dec 30 19:08:18 2010 +0100
@@ -1059,11 +1059,7 @@
 	(set (make-local-variable 'image-mode-winprops-alist) t)
 	;; Switch to the previously used major mode or fall back to
 	;; normal mode.
-	(if doc-view-previous-major-mode
-	    (funcall doc-view-previous-major-mode)
-	  (let ((auto-mode-alist (rassq-delete-all 'doc-view-mode
-						   (copy-alist auto-mode-alist))))
-	    (normal-mode)))
+	(doc-view-fallback-mode)
 	(doc-view-minor-mode 1))
     ;; Switch to doc-view-mode
     (when (and (buffer-modified-p)
@@ -1250,6 +1246,41 @@
     (dolist (x l1) (if (memq x l2) (push x l)))
     l))
 
+(defun doc-view-set-doc-type ()
+  "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)
+			 ;; 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))))))
+	(content-types
+	 (save-excursion
+	   (goto-char (point-min))
+	   (cond
+	    ((looking-at "%!") '(ps))
+	    ((looking-at "%PDF") '(pdf))
+	    ((looking-at "\367\002") '(dvi))))))
+    (set (make-local-variable 'doc-view-doc-type)
+	 (car (or (doc-view-intersection name-types content-types)
+		  (when (and name-types content-types)
+		    (error "Conflicting types: name says %s but content says %s"
+			   name-types content-types))
+		  name-types content-types
+		  (error "Cannot determine the document type"))))))
+
 ;;;###autoload
 (defun doc-view-mode ()
   "Major mode in DocView buffers.
@@ -1266,49 +1297,19 @@
       ;; The doc is empty or doesn't exist at all, so fallback to
       ;; another mode.  We used to also check file-exists-p, but this
       ;; returns nil for tar members.
-      (let ((auto-mode-alist (remq (rassq 'doc-view-mode auto-mode-alist)
-				   auto-mode-alist)))
-	(normal-mode))
+      (doc-view-fallback-mode)
 
     (let* ((prev-major-mode (if (eq major-mode 'doc-view-mode)
 				doc-view-previous-major-mode
-			      (when (not (eq major-mode 'fundamental-mode))
+			      (when (not (memq major-mode
+					       '(doc-view-mode fundamental-mode)))
 				major-mode))))
       (kill-all-local-variables)
       (set (make-local-variable 'doc-view-previous-major-mode) prev-major-mode))
 
     ;; Figure out the document 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)
-			   ;; 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))))))
-	  (content-types
-	   (save-excursion
-	     (goto-char (point-min))
-	     (cond
-	      ((looking-at "%!") '(ps))
-	      ((looking-at "%PDF") '(pdf))
-	      ((looking-at "\367\002") '(dvi))))))
-      (set (make-local-variable 'doc-view-doc-type)
-	   (car (or (doc-view-intersection name-types content-types)
-		    (when (and name-types content-types)
-		      (error "Conflicting types: name says %s but content says %s"
-			     name-types content-types))
-		    name-types content-types
-		    (error "Cannot determine the document type")))))
+    (unless doc-view-doc-type
+      (doc-view-set-doc-type))
 
     (doc-view-make-safe-dir doc-view-cache-directory)
     ;; Handle compressed files, remote files, files inside archives
@@ -1376,6 +1377,28 @@
     (set (make-local-variable 'view-read-only) nil)
     (run-mode-hooks 'doc-view-mode-hook)))
 
+(defun doc-view-fallback-mode ()
+  "Fallback to the previous or next best major mode."
+  (if doc-view-previous-major-mode
+      (funcall doc-view-previous-major-mode)
+    (let ((auto-mode-alist (rassq-delete-all
+			    'doc-view-mode-maybe
+			    (rassq-delete-all 'doc-view-mode
+					      (copy-alist auto-mode-alist)))))
+      (normal-mode))))
+
+;;;###autoload
+(defun doc-view-mode-maybe ()
+  "Switch to `doc-view-mode' if possible.
+If the required external tools are not available, then fallback
+to the next best mode."
+  (condition-case nil
+      (doc-view-set-doc-type)
+    (error (doc-view-fallback-mode)))
+  (if (doc-view-mode-p doc-view-doc-type)
+      (doc-view-mode)
+    (doc-view-fallback-mode)))
+
 ;;;###autoload
 (define-minor-mode doc-view-minor-mode
   "Toggle Doc view minor mode.
--- a/lisp/files.el	Thu Dec 30 16:15:34 2010 +0100
+++ b/lisp/files.el	Thu Dec 30 19:08:18 2010 +0100
@@ -2372,7 +2372,7 @@
      ("\\.\\(diffs?\\|patch\\|rej\\)\\'" . diff-mode)
      ("\\.\\(dif\\|pat\\)\\'" . diff-mode) ; for MSDOG
      ("\\.[eE]?[pP][sS]\\'" . ps-mode)
-     ("\\.\\(?:PDF\\|DVI\\|pdf\\|dvi\\)\\'" . doc-view-mode)
+     ("\\.\\(?:PDF\\|DVI\\|OD[FGPST]\\|DOCX?\\|XLSX?\\|PPTX?\\|pdf\\|dvi\\|od[fgpst]\\|docx?\\|xlsx?\\|pptx?\\)\\'" . doc-view-mode-maybe)
      ("configure\\.\\(ac\\|in\\)\\'" . autoconf-mode)
      ("\\.s\\(v\\|iv\\|ieve\\)\\'" . sieve-mode)
      ("BROWSE\\'" . ebrowse-tree-mode)