(article-date-ut): Fix previous commit.
[gnus] / lisp / mailcap.el
1 ;;; mailcap.el --- MIME media types configuration
2
3 ;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
4 ;;   2005, 2006, 2007, 2008 Free Software Foundation, Inc.
5
6 ;; Author: William M. Perry <wmperry@aventail.com>
7 ;;      Lars Magne Ingebrigtsen <larsi@gnus.org>
8 ;; Keywords: news, mail, multimedia
9
10 ;; This file is part of GNU Emacs.
11
12 ;; GNU Emacs is free software: you can redistribute it and/or modify
13 ;; it under the terms of the GNU General Public License as published by
14 ;; the Free Software Foundation, either version 3 of the License, or
15 ;; (at your option) any later version.
16
17 ;; GNU Emacs is distributed in the hope that it will be useful,
18 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 ;; GNU General Public License for more details.
21
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
24
25 ;;; Commentary:
26
27 ;; Provides configuration of MIME media types from directly from Lisp
28 ;; and via the usual mailcap mechanism (RFC 1524).  Deals with
29 ;; mime.types similarly.
30
31 ;;; Code:
32
33 (eval-when-compile (require 'cl))
34 (autoload 'mail-header-parse-content-type "mail-parse")
35
36 ;; `mm-delete-duplicates' is an alias for `delete-dups' in Emacs 22.
37 (defalias 'mailcap-delete-duplicates
38   (if (fboundp 'delete-dups)
39       'delete-dups
40     (autoload 'mm-delete-duplicates "mm-util")
41     'mm-delete-duplicates))
42
43 ;; `mailcap-replace-in-string' is an alias like `gnus-replace-in-string'.
44 (eval-and-compile
45   (cond
46    ((fboundp 'replace-regexp-in-string)
47     (defun mailcap-replace-in-string  (string regexp newtext &optional literal)
48       "Replace all matches for REGEXP with NEWTEXT in STRING.
49 If LITERAL is non-nil, insert NEWTEXT literally.  Return a new
50 string containing the replacements.
51 This is a compatibility function for different Emacsen."
52       (replace-regexp-in-string regexp newtext string nil literal)))
53    ((fboundp 'replace-in-string)
54     (defalias 'mailcap-replace-in-string 'replace-in-string))))
55
56 (defgroup mailcap nil
57   "Definition of viewers for MIME types."
58   :version "21.1"
59   :group 'mime)
60
61 (defvar mailcap-parse-args-syntax-table
62   (let ((table (copy-syntax-table emacs-lisp-mode-syntax-table)))
63     (modify-syntax-entry ?' "\"" table)
64     (modify-syntax-entry ?` "\"" table)
65     (modify-syntax-entry ?{ "(" table)
66     (modify-syntax-entry ?} ")" table)
67     table)
68   "A syntax table for parsing SGML attributes.")
69
70 (eval-and-compile
71   (when (featurep 'xemacs)
72     (condition-case nil
73         (require 'lpr)
74       (error nil))))
75
76 (defvar mailcap-print-command
77   (mapconcat 'identity
78              (cons (if (boundp 'lpr-command)
79                        lpr-command
80                      "lpr")
81                    (when (boundp 'lpr-switches)
82                      (if (stringp lpr-switches)
83                          (list lpr-switches)
84                        lpr-switches)))
85              " ")
86   "Shell command (including switches) used to print Postscript files.")
87
88 ;; Postpone using defcustom for this as it's so big and we essentially
89 ;; have to have two copies of the data around then.  Perhaps just
90 ;; customize the Lisp viewers and rely on the normal configuration
91 ;; files for the rest?  -- fx
92 (defvar mailcap-mime-data
93   `(("application"
94      ("vnd.ms-excel"
95       (viewer . "gnumeric %s")
96       (test   . (getenv "DISPLAY"))
97       (type . "application/vnd.ms-excel"))
98      ("x-x509-ca-cert"
99       (viewer . ssl-view-site-cert)
100       (test . (fboundp 'ssl-view-site-cert))
101       (type . "application/x-x509-ca-cert"))
102      ("x-x509-user-cert"
103       (viewer . ssl-view-user-cert)
104       (test . (fboundp 'ssl-view-user-cert))
105       (type . "application/x-x509-user-cert"))
106      ("octet-stream"
107       (viewer . mailcap-save-binary-file)
108       (non-viewer . t)
109       (type . "application/octet-stream"))
110      ("dvi"
111       (viewer . "xdvi -safer %s")
112       (test   . (eq window-system 'x))
113       ("needsx11")
114       (type   . "application/dvi")
115       ("print" . "dvips -qRP %s"))
116      ("dvi"
117       (viewer . "dvitty %s")
118       (test   . (not (getenv "DISPLAY")))
119       (type   . "application/dvi")
120       ("print" . "dvips -qRP %s"))
121      ("emacs-lisp"
122       (viewer . mailcap-maybe-eval)
123       (type   . "application/emacs-lisp"))
124      ("x-emacs-lisp"
125       (viewer . mailcap-maybe-eval)
126       (type   . "application/x-emacs-lisp"))
127      ("x-tar"
128       (viewer . mailcap-save-binary-file)
129       (non-viewer . t)
130       (type   . "application/x-tar"))
131      ("x-latex"
132       (viewer . tex-mode)
133       (test   . (fboundp 'tex-mode))
134       (type   . "application/x-latex"))
135      ("x-tex"
136       (viewer . tex-mode)
137       (test   . (fboundp 'tex-mode))
138       (type   . "application/x-tex"))
139      ("latex"
140       (viewer . tex-mode)
141       (test   . (fboundp 'tex-mode))
142       (type   . "application/latex"))
143      ("tex"
144       (viewer . tex-mode)
145       (test   . (fboundp 'tex-mode))
146       (type   . "application/tex"))
147      ("texinfo"
148       (viewer . texinfo-mode)
149       (test   . (fboundp 'texinfo-mode))
150       (type   . "application/tex"))
151      ("zip"
152       (viewer . mailcap-save-binary-file)
153       (non-viewer . t)
154       (type   . "application/zip")
155       ("copiousoutput"))
156      ("pdf"
157       (viewer . "gv -safer %s")
158       (type . "application/pdf")
159       (test . window-system)
160       ("print" . ,(concat "pdf2ps %s - | " mailcap-print-command)))
161      ("pdf"
162       (viewer . "gpdf %s")
163       (type . "application/pdf")
164       ("print" . ,(concat "pdftops %s - | " mailcap-print-command))
165       (test . (eq window-system 'x)))
166      ("pdf"
167       (viewer . "xpdf %s")
168       (type . "application/pdf")
169       ("print" . ,(concat "pdftops %s - | " mailcap-print-command))
170       (test . (eq window-system 'x)))
171      ("pdf"
172       (viewer . ,(concat "pdftotext %s -"))
173       (type   . "application/pdf")
174       ("print" . ,(concat "pdftops %s - | " mailcap-print-command))
175       ("copiousoutput"))
176      ("postscript"
177       (viewer . "gv -safer %s")
178       (type . "application/postscript")
179       (test   . window-system)
180       ("print" . ,(concat mailcap-print-command " %s"))
181       ("needsx11"))
182      ("postscript"
183       (viewer . "ghostview -dSAFER %s")
184       (type . "application/postscript")
185       (test   . (eq window-system 'x))
186       ("print" . ,(concat mailcap-print-command " %s"))
187       ("needsx11"))
188      ("postscript"
189       (viewer . "ps2ascii %s")
190       (type . "application/postscript")
191       (test . (not (getenv "DISPLAY")))
192       ("print" . ,(concat mailcap-print-command " %s"))
193       ("copiousoutput"))
194      ("sieve"
195       (viewer . sieve-mode)
196       (test   . (fboundp 'sieve-mode))
197       (type   . "application/sieve"))
198      ("pgp-keys"
199       (viewer . "gpg --import --interactive --verbose")
200       (type   . "application/pgp-keys")
201       ("needsterminal")))
202     ("audio"
203      ("x-mpeg"
204       (viewer . "maplay %s")
205       (type   . "audio/x-mpeg"))
206      (".*"
207       (viewer . "showaudio")
208       (type   . "audio/*")))
209     ("message"
210      ("rfc-*822"
211       (viewer . mm-view-message)
212       (test   . (and (featurep 'gnus)
213                      (gnus-alive-p)))
214       (type   . "message/rfc822"))
215      ("rfc-*822"
216       (viewer . vm-mode)
217       (test   . (fboundp 'vm-mode))
218       (type   . "message/rfc822"))
219      ("rfc-*822"
220       (viewer . w3-mode)
221       (test   . (fboundp 'w3-mode))
222       (type   . "message/rfc822"))
223      ("rfc-*822"
224       (viewer . view-mode)
225       (type   . "message/rfc822")))
226     ("image"
227      ("x-xwd"
228       (viewer  . "xwud -in %s")
229       (type    . "image/x-xwd")
230       ("compose" . "xwd -frame > %s")
231       (test    . (eq window-system 'x))
232       ("needsx11"))
233      ("x11-dump"
234       (viewer . "xwud -in %s")
235       (type . "image/x-xwd")
236       ("compose" . "xwd -frame > %s")
237       (test   . (eq window-system 'x))
238       ("needsx11"))
239      ("windowdump"
240       (viewer . "xwud -in %s")
241       (type . "image/x-xwd")
242       ("compose" . "xwd -frame > %s")
243       (test   . (eq window-system 'x))
244       ("needsx11"))
245      (".*"
246       (viewer . "display %s")
247       (type . "image/*")
248       (test   . (eq window-system 'x))
249       ("needsx11"))
250      (".*"
251       (viewer . "ee %s")
252       (type . "image/*")
253       (test   . (eq window-system 'x))
254       ("needsx11")))
255     ("text"
256      ("plain"
257       (viewer  . w3-mode)
258       (test    . (fboundp 'w3-mode))
259       (type    . "text/plain"))
260      ("plain"
261       (viewer  . view-mode)
262       (test    . (fboundp 'view-mode))
263       (type    . "text/plain"))
264      ("plain"
265       (viewer  . fundamental-mode)
266       (type    . "text/plain"))
267      ("enriched"
268       (viewer . enriched-decode)
269       (test   . (fboundp 'enriched-decode))
270       (type   . "text/enriched"))
271      ("html"
272       (viewer . mm-w3-prepare-buffer)
273       (test   . (fboundp 'w3-prepare-buffer))
274       (type   . "text/html"))
275      ("dns"
276       (viewer . dns-mode)
277       (test   . (fboundp 'dns-mode))
278       (type   . "text/dns")))
279     ("video"
280      ("mpeg"
281       (viewer . "mpeg_play %s")
282       (type   . "video/mpeg")
283       (test   . (eq window-system 'x))
284       ("needsx11")))
285     ("x-world"
286      ("x-vrml"
287       (viewer  . "webspace -remote %s -URL %u")
288       (type    . "x-world/x-vrml")
289       ("description"
290        "VRML document")))
291     ("archive"
292      ("tar"
293       (viewer . tar-mode)
294       (type . "archive/tar")
295       (test . (fboundp 'tar-mode)))))
296   "The mailcap structure is an assoc list of assoc lists.
297 1st assoc list is keyed on the major content-type
298 2nd assoc list is keyed on the minor content-type (which can be a regexp)