# HG changeset patch # User Tassilo Horn # Date 1293732498 -3600 # Node ID 2fef20daac2b4aa83843e5e1818a4c54b9104e16 # Parent ad2a8fce0d7a80678f8869cdbd647ff836ce7d3a * 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. diff -r ad2a8fce0d7a -r 2fef20daac2b lisp/ChangeLog --- 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 + + * 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 * emacs-lisp/rx.el (rx-syntax): Fix typo. diff -r ad2a8fce0d7a -r 2fef20daac2b lisp/doc-view.el --- 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. diff -r ad2a8fce0d7a -r 2fef20daac2b lisp/files.el --- 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)