Rename `second' -> `cadr' (Don't use cl function).
[elisp/semi.git] / mime-def.el
1 ;;; mime-def.el --- definition module for SEMI
2
3 ;; Copyright (C) 1995,1996,1997 Free Software Foundation, Inc.
4
5 ;; Author: MORIOKA Tomohiko <morioka@jaist.ac.jp>
6 ;; Version: $Id: mime-def.el,v 0.68 1997-10-02 07:46:27 morioka Exp $
7 ;; Keywords: definition, MIME, multimedia, mail, news
8
9 ;; This file is part of SEMI (SEMI is Emacs MIME Interfaces).
10
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.
15
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.
20
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.
25
26 ;;; Code:
27
28 (require 'emu)
29
30 (unless (fboundp 'butlast)
31   (defun butlast (x &optional n)
32     "Returns a copy of LIST with the last N elements removed."
33     (if (and n (<= n 0)) x
34       (nbutlast (copy-sequence x) n)))
35   
36   (defun nbutlast (x &optional n)
37     "Modifies LIST to remove the last N elements."
38     (let ((m (length x)))
39       (or n (setq n 1))
40       (and (< n m)
41            (progn
42              (if (> n 0) (setcdr (nthcdr (- (1- m) n) x) nil))
43              x))))
44   )
45
46 (defconst semi-version-name "Oyanagi")
47
48 (autoload 'mule-caesar-region "mule-caesar"
49   "Caesar rotation of current region." t)
50
51
52 ;;; @ variables
53 ;;;
54
55 (defvar mime/use-multi-frame
56   (and (>= emacs-major-version 19) window-system))
57
58 (defvar mime/find-file-function
59   (if mime/use-multi-frame
60       (function find-file-other-frame)
61     (function find-file)
62     ))
63
64
65 ;;; @ constants
66 ;;;
67
68 (defconst mime-echo-buffer-name "*MIME-echo*"
69   "Name of buffer to display MIME-playing information.")
70
71 (defconst mime-temp-buffer-name " *MIME-temp*")
72
73
74 ;;; @ definitions about MIME
75 ;;;
76
77 (defconst mime-tspecials "][()<>@,\;:\\\"/?=")
78 (defconst mime-token-regexp (concat "[^" mime-tspecials "\000-\040]+"))
79 (defconst mime-charset-regexp mime-token-regexp)
80
81 (defconst mime-media-type/subtype-regexp
82   (concat mime-token-regexp "/" mime-token-regexp))
83
84
85 ;;; @ button
86 ;;;
87
88 (defvar mime-button-face 'bold
89   "Face used for content-button or URL-button of MIME-Preview buffer.")
90
91 (defvar mime-button-mouse-face 'highlight
92   "Face used for MIME-preview buffer mouse highlighting.")
93
94 (defsubst mime-add-button (from to function &optional data)
95   "Create a button between FROM and TO with callback FUNCTION and DATA."
96   (let ((overlay (make-overlay from to)))
97     (and mime-button-face
98          (overlay-put overlay 'face mime-button-face))
99     (and mime-button-mouse-face
100          (overlay-put overlay 'mouse-face mime-button-mouse-face))
101     (add-text-properties from to (list 'mime-button-callback function))
102     (and data
103          (add-text-properties from to (list 'mime-button-data data)))
104     ;;(add-text-properties from to (list 'keymap widget-keymap))
105     ))
106
107 (defsubst mime-insert-button (string function &optional data)
108   "Insert STRING as button with callback FUNCTION and DATA."
109   (save-restriction
110     (narrow-to-region (point)(point))
111     (insert (concat "[" string "]"))
112     ;; (widget-push-button-value-create
113     ;;  (widget-convert 'push-button
114     ;;                  :notify (lambda (&rest ignore)
115     ;;                            (mime-view-play-current-entity)
116     ;;                            )
117     ;;                  string))
118     (insert "\n")
119     (mime-add-button (point-min)(point-max) function data)
120     ))
121
122 (defvar mime-button-mother-dispatcher nil)
123
124 (defun mime-button-dispatcher (event)
125   "Select the button under point."
126   (interactive "e")
127   (let (buf point func data)
128     (save-window-excursion
129       (mouse-set-point event)
130       (setq buf (current-buffer)
131             point (point)
132             func (get-text-property (point) 'mime-button-callback)
133             data (get-text-property (point) 'mime-button-data)
134             )
135       )
136     (save-excursion
137       (set-buffer buf)
138       (goto-char point)
139       (if func
140           (apply func data)
141         (if (fboundp mime-button-mother-dispatcher)
142             (funcall mime-button-mother-dispatcher event)
143           )
144         ))))
145
146
147 ;;; @ PGP
148 ;;;
149
150 (defvar pgp-function-alist
151   '(
152     ;; for mime-pgp
153     (verify             mc-verify                       "mc-toplev")
154     (decrypt            mc-decrypt                      "mc-toplev")
155     (fetch-key          mc-pgp-fetch-key                "mc-pgp")
156     (snarf-keys         mc-snarf-keys                   "mc-toplev")
157     ;; for mime-edit
158     (mime-sign          mime-mc-pgp-sign-region         "mime-mc")
159     (traditional-sign   mc-pgp-sign-region              "mc-pgp")
160     (encrypt            mime-mc-pgp-encrypt-region      "mime-mc")
161     (insert-key         mc-insert-public-key            "mc-toplev")
162     )
163   "Alist of service names vs. corresponding functions and its filenames.
164 Each element looks like (SERVICE FUNCTION FILE).
165
166 SERVICE is a symbol of PGP processing.  It allows `verify', `decrypt',
167 `fetch-key', `snarf-keys', `mime-sign', `traditional-sign', `encrypt'
168 or `insert-key'.
169
170 Function is a symbol of function to do specified SERVICE.
171
172 FILE is string of filename which has definition of corresponding
173 FUNCTION.")
174
175 (defmacro pgp-function (method)
176   "Return function to do service METHOD."
177   (` (car (cdr (assq (, method) (symbol-value 'pgp-function-alist)))))
178   )
179
180 (mapcar (function
181          (lambda (method)
182            (autoload (cadr method)(third method))
183            ))
184         pgp-function-alist)
185
186
187 ;;; @ method selector kernel
188 ;;;
189
190 (require 'atype)
191
192 ;;; @@ field unifier
193 ;;;
194
195 (defun field-unifier-for-mode (a b)
196   (let ((va (cdr a)))
197     (if (if (consp va)
198             (member (cdr b) va)
199           (equal va (cdr b))
200           )
201         (list nil b nil)
202       )))
203
204
205 ;;; @ field
206 ;;;
207
208 (defsubst regexp-or (&rest args)
209   (concat "\\(" (mapconcat (function identity) args "\\|") "\\)"))
210
211 (defun tm:set-fields (sym field-list &optional regexp-sym)
212   (or regexp-sym
213       (setq regexp-sym
214             (let ((name (symbol-name sym)))
215               (intern
216                (concat (if (string-match "\\(.*\\)-list" name)
217                            (substring name 0 (match-end 1))
218                          name)
219                        "-regexp")
220                )))
221       )
222   (set sym field-list)
223   (set regexp-sym
224        (concat "^" (apply (function regexp-or) field-list) ":"))
225   )
226
227 (defun tm:add-fields (sym field-list &optional regexp-sym)
228   (or regexp-sym
229       (setq regexp-sym
230             (let ((name (symbol-name sym)))
231               (intern
232                (concat (if (string-match "\\(.*\\)-list" name)
233                            (substring name 0 (match-end 1))
234                          name)
235                        "-regexp")
236                )))
237       )
238   (let ((fields (eval sym)))
239     (mapcar (function
240              (lambda (field)
241                (or (member field fields)
242                    (setq fields (cons field fields))
243                    )
244                ))
245             (reverse field-list)
246             )
247     (set regexp-sym
248          (concat "^" (apply (function regexp-or) fields) ":"))
249     (set sym fields)
250     ))
251
252 (defun tm:delete-fields (sym field-list &optional regexp-sym)
253   (or regexp-sym
254       (setq regexp-sym
255             (let ((name (symbol-name sym)))
256               (intern
257                (concat (if (string-match "\\(.*\\)-list" name)
258                            (substring name 0 (match-end 1))
259                          name)
260                        "-regexp")
261                )))
262       )
263   (let ((fields (eval sym)))
264     (mapcar (function
265              (lambda (field)
266                (setq fields (delete field fields))
267                ))
268             field-list)
269     (set regexp-sym
270          (concat "^" (apply (function regexp-or) fields) ":"))
271     (set sym fields)
272     ))
273
274
275 ;;; @ RCS version
276 ;;;
277
278 (defsubst get-version-string (id)
279   "Return a version-string from RCS ID."
280   (and (string-match ",v \\([0-9][0-9.][0-9.]+\\)" id)
281        (substring id (match-beginning 1)(match-end 1))
282        ))
283
284
285 ;;; @ Other Utility
286 ;;;
287
288 (defsubst eliminate-top-spaces (string)
289   "Eliminate top sequence of space or tab in STRING."
290   (if (string-match "^[ \t]+" string)
291       (substring string (match-end 0))
292     string))
293
294 (defun call-after-loaded (module func &optional hook-name)
295   "If MODULE is provided, then FUNC is called.
296 Otherwise func is set to MODULE-load-hook.
297 If optional argument HOOK-NAME is specified,
298 it is used as hook to set."
299   (if (featurep module)
300       (funcall func)
301     (or hook-name
302         (setq hook-name (intern (concat (symbol-name module) "-load-hook")))
303         )
304     (add-hook hook-name func)
305     ))
306
307
308 ;;; @ end
309 ;;;
310
311 (provide 'mime-def)
312
313 ;;; mime-def.el ends here