1 ;;; mailcap.el --- mailcap parser
3 ;; Copyright (C) 1997,1998 Free Software Foundation, Inc.
5 ;; Author: MORIOKA Tomohiko <morioka@jaist.ac.jp>
7 ;; Keywords: mailcap, setting, configuration, MIME, multimedia
9 ;; This file is part of SEMI (Spadework for Emacs MIME Interfaces).
11 ;; This program is free software; you can redistribute it and/or
12 ;; modify it under the terms of the GNU General Public License as
13 ;; published by the Free Software Foundation; either version 2, or (at
14 ;; your option) any later version.
16 ;; This program is distributed in the hope that it will be useful, but
17 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 ;; General Public License for more details.
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GNU Emacs; see the file COPYING. If not, write to the
23 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24 ;; Boston, MA 02111-1307, USA.
34 (defsubst mailcap-skip-comment ()
35 (let ((chr (char-after (point))))
46 (defsubst mailcap-look-at-token ()
47 (if (looking-at mime-token-regexp)
48 (let ((beg (match-beginning 0))
51 (buffer-substring beg end)
58 (defsubst mailcap-look-at-type-field ()
59 (let ((type (mailcap-look-at-token)))
61 (if (eq (char-after (point)) ?/)
64 (let ((subtype (mailcap-look-at-token)))
66 (cons (cons 'type (intern type))
67 (unless (string= subtype "*")
68 (list (cons 'subtype (intern subtype)))
70 (list (cons 'type (intern type)))
77 (defsubst mailcap-skip-field-separator ()
78 (let ((ret (looking-at "\\([ \t]\\|\\\\\n\\)*;\\([ \t]\\|\\\\\n\\)*")))
80 (goto-char (match-end 0))
87 (defsubst mailcap-look-at-schar ()
88 (let ((chr (char-after (point))))
97 (defsubst mailcap-look-at-qchar ()
98 (let ((chr (char-after (point))))
101 (char-before (point))
104 (defsubst mailcap-look-at-mtext ()
106 (while (or (mailcap-look-at-qchar)
107 (mailcap-look-at-schar)))
108 (buffer-substring beg (point))
115 (defsubst mailcap-look-at-field ()
116 (let ((token (mailcap-look-at-token)))
118 (if (looking-at "[ \t]*=[ \t]*")
120 (goto-char (match-end 0))
121 (mailcap-look-at-mtext))))
123 (cons (intern token) value)
125 (list (intern token))
132 (defun mailcap-look-at-entry ()
133 (let ((type (mailcap-look-at-type-field)))
134 (if (and type (mailcap-skip-field-separator))
135 (let ((view (mailcap-look-at-mtext))
138 (while (and (mailcap-skip-field-separator)
139 (setq field (mailcap-look-at-field))
141 (setq fields (cons field fields))
144 (list (cons 'view view))
151 (defun mailcap-parse-buffer (&optional buffer order)
152 "Parse BUFFER as a mailcap, and return the result.
153 If optional argument ORDER is a function, result is sorted by it.
154 If optional argument ORDER is not specified, result is sorted original
155 order. Otherwise result is not sorted."
159 (goto-char (point-min))
162 (while (mailcap-skip-comment))
163 (setq entry (mailcap-look-at-entry))
165 (setq entries (cons entry entries))
168 (cond ((functionp order) (sort entries order))
169 ((null order) (nreverse entries))
174 (defcustom mailcap-file "~/.mailcap"
175 "*File name of user's mailcap file."
179 (defun mailcap-parse-file (&optional filename order)
180 "Parse FILENAME as a mailcap, and return the result.
181 If optional argument ORDER is a function, result is sorted by it.
182 If optional argument ORDER is not specified, result is sorted original
183 order. Otherwise result is not sorted."
185 (setq filename mailcap-file))
187 (insert-file-contents filename)
188 (mailcap-parse-buffer (current-buffer) order)
191 (defun mailcap-format-command (mtext situation)
192 "Return formated command string from MTEXT and SITUATION.
194 MTEXT is a command text of mailcap specification, such as
197 SITUATION is an association-list about information of entity. Its key
200 'type primary media-type
201 'subtype media-subtype
203 STRING parameter of Content-Type field"
209 (let ((chr (aref mtext i)))
214 (let ((file (cdr (assq 'filename situation))))
216 (error "'filename is not specified in situation.")
217 (setq dest (concat dest
218 (substring mtext p (1- i))
224 (let ((type (or (mime-type/subtype-string
225 (cdr (assq 'type situation))
226 (cdr (assq 'subtype situation)))
228 (setq dest (concat dest
229 (substring mtext p (1- i))
236 (if (not (string-match "}" mtext i))
237 (error "parse error!!!")
238 (let* ((me (match-end 0))
239 (attribute (substring mtext i (1- me)))
240 (parameter (cdr (assoc attribute situation))))
242 (error "\"%s\" is not specified in situation."
244 (setq dest (concat dest
245 (substring mtext p (- i 2))
251 (t (error "Invalid sequence `%%%c'." chr))
254 (setq dest (concat dest (substring mtext p i))
260 (concat dest (substring mtext p))
269 ;;; mailcap.el ends here