* doc-view.el (doc-view-set-doc-type): New function refactored
authorTassilo Horn <tassilo@member.fsf.org>
Thu, 30 Dec 2010 18:08:18 +0000 (19:08 +0100)
committerTassilo Horn <tassilo@member.fsf.org>
Thu, 30 Dec 2010 18:08:18 +0000 (19:08 +0100)
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.

lisp/ChangeLog
lisp/doc-view.el
lisp/files.el

index 7081edf..6a7bcf9 100644 (file)
@@ -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.
index a5dbff1..801cddd 100644 (file)
@@ -1059,11 +1059,7 @@ For now these keys are useful:
        (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 @@ If BACKWARD is non-nil, jump to the previous match."
     (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 @@ toggle between displaying the document or editing it as text.
       ;; 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 @@ toggle between displaying the document or editing it as text.
     (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.
index e89c307..76526de 100644 (file)
@@ -2372,7 +2372,7 @@ ARC\\|ZIP\\|LZH\\|LHA\\|ZOO\\|[JEW]AR\\|XPI\\|RAR\\|7Z\\)\\'" . archive-mode)
      ("\\.\\(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)