tm 7.67.
[elisp/tm.git] / tm-ew-d.el
1 ;;;
2 ;;; tm-ew-d.el --- RFC 1522 based multilingual MIME message header
3 ;;;                decoder for GNU Emacs
4 ;;;
5 ;;; Copyright (C) 1995 Free Software Foundation, Inc.
6 ;;; Copyright (C) 1992 ENAMI Tsugutomo
7 ;;; Copyright (C) 1993 .. 1996 MORIOKA Tomohiko
8 ;;;
9 ;;; Author: ENAMI Tsugutomo <enami@sys.ptg.sony.co.jp>
10 ;;;         MORIOKA Tomohiko <morioka@jaist.ac.jp>
11 ;;; Maintainer: MORIOKA Tomohiko <morioka@jaist.ac.jp>
12 ;;; Created: 1993/6/3 (1995/10/3 obsolete tiny-mime.el)
13 ;;; Version: $Revision: 7.12 $
14 ;;; Keywords: mail, news, MIME, RFC 1522, multilingual, encoded-word
15 ;;;
16 ;;; This file is part of tm (Tools for MIME).
17 ;;;
18 ;;; This program is free software; you can redistribute it and/or
19 ;;; modify it under the terms of the GNU General Public License as
20 ;;; published by the Free Software Foundation; either version 2, or
21 ;;; (at your option) any later version.
22 ;;;
23 ;;; This program is distributed in the hope that it will be useful,
24 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
25 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
26 ;;; General Public License for more details.
27 ;;;
28 ;;; You should have received a copy of the GNU General Public License
29 ;;; along with This program.  If not, write to the Free Software
30 ;;; Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
31 ;;;
32 ;;; Code:
33
34 (require 'emu)
35 (require 'tl-822)
36 (require 'mel)
37 (require 'tm-def)
38
39
40 ;;; @ version
41 ;;;
42
43 (defconst tm-ew-d/RCS-ID
44   "$Id: tm-ew-d.el,v 7.12 1996/05/09 18:18:51 morioka Exp $")
45 (defconst mime/eword-decoder-version (get-version-string tm-ew-d/RCS-ID))
46
47
48 ;;; @ MIME encoded-word definition
49 ;;;
50
51 (defconst mime/encoded-text-regexp "[!->@-~]+")
52 (defconst mime/encoded-word-regexp (concat (regexp-quote "=?")
53                                            "\\("
54                                            mime/charset-regexp
55                                            "\\)"
56                                            (regexp-quote "?")
57                                            "\\(B\\|Q\\)"
58                                            (regexp-quote "?")
59                                            "\\("
60                                            mime/encoded-text-regexp
61                                            "\\)"
62                                            (regexp-quote "?=")))
63
64
65 ;;; @ for string
66 ;;;
67
68 (defun mime-eword/decode-string (str)
69   (setq str (rfc822/unfolding-string str))
70   (let ((dest "")(ew nil)
71         beg end)
72     (while (and (string-match mime/encoded-word-regexp str)
73                 (setq beg (match-beginning 0)
74                       end (match-end 0))
75                 )
76       (if (> beg 0)
77           (if (not
78                (and (eq ew t)
79                     (string-match "^[ \t]+$" (substring str 0 beg))
80                     ))
81               (setq dest (concat dest (substring str 0 beg)))
82             )
83         )
84       (setq dest (concat dest
85                          (mime/decode-encoded-word (substring str beg end))
86                          ))
87       (setq str (substring str end))
88       (setq ew t)
89       )
90     (concat dest str)
91     ))
92
93
94 ;;; @ for region
95 ;;;
96
97 (defun mime-eword/decode-region (beg end &optional unfolding)
98   (interactive "*r")
99   (save-excursion
100     (save-restriction
101       (narrow-to-region beg end)
102       (if unfolding
103           (mime/unfolding)
104         )
105       (goto-char (point-min))
106       (while (re-search-forward
107               (concat (regexp-quote "?=") "\\s +" (regexp-quote "=?"))
108               nil t)
109         (replace-match "?==?")
110         )
111       (goto-char (point-min))
112       (let (charset encoding text)
113         (while (re-search-forward mime/encoded-word-regexp nil t)
114           (insert (mime/decode-encoded-word 
115                    (prog1
116                        (buffer-substring (match-beginning 0) (match-end 0))
117                      (delete-region (match-beginning 0) (match-end 0))
118                      )
119                    ))
120           ))
121       )))
122
123
124 ;;; @ for message header
125 ;;;
126
127 (defun mime/decode-message-header ()
128   (interactive "*")
129   (save-excursion
130     (save-restriction
131       (narrow-to-region (goto-char (point-min))
132                         (progn (re-search-forward "^$" nil t) (point)))
133       (mime-eword/decode-region (point-min) (point-max) t)
134       )))
135
136 (defun mime/unfolding ()
137   (goto-char (point-min))
138   (let (field beg end)
139     (while (re-search-forward rfc822/field-top-regexp nil t)
140       (setq beg (match-beginning 0))
141       (setq end (rfc822/field-end))
142       (setq field (buffer-substring beg end))
143       (if (string-match mime/encoded-word-regexp field)
144           (save-restriction
145             (narrow-to-region (goto-char beg) end)
146             (while (re-search-forward "\n[ \t]+" nil t)
147               (replace-match " ")
148               )
149             (goto-char (point-max))
150             ))
151       )))
152
153
154 ;;; @ encoded-word decoder
155 ;;;
156
157 (defun mime/decode-encoded-word (word)
158   (or (if (string-match mime/encoded-word-regexp word)
159           (let ((charset
160                  (upcase
161                   (substring word (match-beginning 1) (match-end 1))
162                   ))
163                 (encoding
164                  (upcase
165                   (substring word (match-beginning 2) (match-end 2))
166                   ))
167                 (text
168                  (substring word (match-beginning 3) (match-end 3))
169                  ))
170             (mime/decode-encoded-text charset encoding text)
171             ))
172       word))
173
174
175 ;;; @ encoded-text decoder
176 ;;;
177
178 (defun mime/decode-encoded-text (charset encoding str)
179   (let ((dest
180          (cond ((string-equal "B" encoding)
181                 (base64-decode-string str))
182                ((string-equal "Q" encoding)
183                 (q-encoding-decode-string str))
184                (t (message "unknown encoding %s" encoding)
185                   nil))))
186     (if dest
187         (mime-charset-decode-string dest charset)
188       )))
189
190
191 ;;; @ end
192 ;;;
193
194 (provide 'tm-ew-d)
195
196 ;;; tm-ew-d.el ends here