Mercurial > emacs
comparison lisp/gnus/ietf-drums.el @ 31717:6b20b7e85e3c
*** empty log message ***
author | Gerd Moellmann <gerd@gnu.org> |
---|---|
date | Tue, 19 Sep 2000 13:40:08 +0000 |
parents | |
children | a8017f96379d |
comparison
equal
deleted
inserted
replaced
31716:9968f55ad26e | 31717:6b20b7e85e3c |
---|---|
1 ;;; ietf-drums.el --- Functions for parsing RFC822bis headers | |
2 ;; Copyright (C) 1998, 1999, 2000 | |
3 ;; Free Software Foundation, Inc. | |
4 | |
5 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org> | |
6 ;; This file is part of GNU Emacs. | |
7 | |
8 ;; GNU Emacs is free software; you can redistribute it and/or modify | |
9 ;; it under the terms of the GNU General Public License as published by | |
10 ;; the Free Software Foundation; either version 2, or (at your option) | |
11 ;; any later version. | |
12 | |
13 ;; GNU Emacs is distributed in the hope that it will be useful, | |
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 ;; GNU General Public License for more details. | |
17 | |
18 ;; You should have received a copy of the GNU General Public License | |
19 ;; along with GNU Emacs; see the file COPYING. If not, write to the | |
20 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
21 ;; Boston, MA 02111-1307, USA. | |
22 | |
23 ;;; Commentary: | |
24 | |
25 ;; DRUMS is an IETF Working Group that works (or worked) on the | |
26 ;; successor to RFC822, "Standard For The Format Of Arpa Internet Text | |
27 ;; Messages". This library is based on | |
28 ;; draft-ietf-drums-msg-fmt-05.txt, released on 1998-08-05. | |
29 | |
30 ;;; Code: | |
31 | |
32 (require 'time-date) | |
33 (require 'mm-util) | |
34 | |
35 (defvar ietf-drums-no-ws-ctl-token "\001-\010\013\014\016-\037\177" | |
36 "US-ASCII control characters excluding CR, LF and white space.") | |
37 (defvar ietf-drums-text-token "\001-\011\013\014\016-\177" | |
38 "US-ASCII characters exlcuding CR and LF.") | |
39 (defvar ietf-drums-specials-token "()<>[]:;@\\,.\"" | |
40 "Special characters.") | |
41 (defvar ietf-drums-quote-token "\\" | |
42 "Quote character.") | |
43 (defvar ietf-drums-wsp-token " \t" | |
44 "White space.") | |
45 (defvar ietf-drums-fws-regexp | |
46 (concat "[" ietf-drums-wsp-token "]*\n[" ietf-drums-wsp-token "]+") | |
47 "Folding white space.") | |
48 (defvar ietf-drums-atext-token "-^a-zA-Z0-9!#$%&'*+/=?_`{|}~" | |
49 "Textual token.") | |
50 (defvar ietf-drums-dot-atext-token "-^a-zA-Z0-9!#$%&'*+/=?_`{|}~." | |
51 "Textual token including full stop.") | |
52 (defvar ietf-drums-qtext-token | |
53 (concat ietf-drums-no-ws-ctl-token "\041\043-\133\135-\177") | |
54 "Non-white-space control characaters, plus the rest of ASCII excluding backslash and doublequote.") | |
55 (defvar ietf-drums-tspecials "][()<>@,;:\\\"/?=" | |
56 "Tspecials.") | |
57 | |
58 (defvar ietf-drums-syntax-table | |
59 (let ((table (copy-syntax-table emacs-lisp-mode-syntax-table))) | |
60 (modify-syntax-entry ?\\ "/" table) | |
61 (modify-syntax-entry ?< "(" table) | |
62 (modify-syntax-entry ?> ")" table) | |
63 (modify-syntax-entry ?@ "w" table) | |
64 (modify-syntax-entry ?/ "w" table) | |
65 (modify-syntax-entry ?= " " table) | |
66 (modify-syntax-entry ?* " " table) | |
67 (modify-syntax-entry ?\; " " table) | |
68 (modify-syntax-entry ?\' " " table) | |
69 table)) | |
70 | |
71 (defun ietf-drums-token-to-list (token) | |
72 "Translate TOKEN into a list of characters." | |
73 (let ((i 0) | |
74 b e c out range) | |
75 (while (< i (length token)) | |
76 (setq c (mm-char-int (aref token i))) | |
77 (incf i) | |
78 (cond | |
79 ((eq c (mm-char-int ?-)) | |
80 (if b | |
81 (setq range t) | |
82 (push c out))) | |
83 (range | |
84 (while (<= b c) | |
85 (push (mm-make-char 'ascii b) out) | |
86 (incf b)) | |
87 (setq range nil)) | |
88 ((= i (length token)) | |
89 (push (mm-make-char 'ascii c) out)) | |
90 (t | |
91 (when b | |
92 (push (mm-make-char 'ascii b) out)) | |
93 (setq b c)))) | |
94 (nreverse out))) | |
95 | |
96 (defsubst ietf-drums-init (string) | |
97 (set-syntax-table ietf-drums-syntax-table) | |
98 (insert string) | |
99 (ietf-drums-unfold-fws) | |
100 (goto-char (point-min))) | |
101 | |
102 (defun ietf-drums-remove-comments (string) | |
103 "Remove comments from STRING." | |
104 (with-temp-buffer | |
105 (let (c) | |
106 (ietf-drums-init string) | |
107 (while (not (eobp)) | |
108 (setq c (char-after)) | |
109 (cond | |
110 ((eq c ?\") | |
111 (forward-sexp 1)) | |
112 ((eq c ?\() | |
113 (delete-region (point) (progn (forward-sexp 1) (point)))) | |
114 (t | |
115 (forward-char 1)))) | |
116 (buffer-string)))) | |
117 | |
118 (defun ietf-drums-remove-whitespace (string) | |
119 "Remove whitespace from STRING." | |
120 (with-temp-buffer | |
121 (ietf-drums-init string) | |
122 (let (c) | |
123 (while (not (eobp)) | |
124 (setq c (char-after)) | |
125 (cond | |
126 ((eq c ?\") | |
127 (forward-sexp 1)) | |
128 ((eq c ?\() | |
129 (forward-sexp 1)) | |
130 ((memq c '(? ?\t ?\n)) | |
131 (delete-char 1)) | |
132 (t | |
133 (forward-char 1)))) | |
134 (buffer-string)))) | |
135 | |
136 (defun ietf-drums-get-comment (string) | |
137 "Return the first comment in STRING." | |
138 (with-temp-buffer | |
139 (ietf-drums-init string) | |
140 (let (result c) | |
141 (while (not (eobp)) | |
142 (setq c (char-after)) | |
143 (cond | |
144 ((eq c ?\") | |
145 (forward-sexp 1)) | |
146 ((eq c ?\() | |
147 (setq result | |
148 (buffer-substring | |
149 (1+ (point)) | |
150 (progn (forward-sexp 1) (1- (point)))))) | |
151 (t | |
152 (forward-char 1)))) | |
153 result))) | |
154 | |
155 (defun ietf-drums-strip (string) | |
156 "Remove comments and whitespace from STRING." | |
157 (ietf-drums-remove-whitespace (ietf-drums-remove-comments string))) | |
158 | |
159 (defun ietf-drums-parse-address (string) | |
160 "Parse STRING and return a MAILBOX / DISPLAY-NAME pair." | |
161 (with-temp-buffer | |
162 (let (display-name mailbox c display-string) | |
163 (ietf-drums-init string) | |
164 (while (not (eobp)) | |
165 (setq c (char-after)) | |
166 (cond | |
167 ((or (eq c ? ) | |
168 (eq c ?\t)) | |
169 (forward-char 1)) | |
170 ((eq c ?\() | |
171 (forward-sexp 1)) | |
172 ((eq c ?\") | |
173 (push (buffer-substring | |
174 (1+ (point)) (progn (forward-sexp 1) (1- (point)))) | |
175 display-name)) | |
176 ((looking-at (concat "[" ietf-drums-atext-token "@" "]")) | |
177 (push (buffer-substring (point) (progn (forward-sexp 1) (point))) | |
178 display-name)) | |
179 ((eq c ?<) | |
180 (setq mailbox | |
181 (ietf-drums-remove-whitespace | |
182 (ietf-drums-remove-comments | |
183 (buffer-substring | |
184 (1+ (point)) | |
185 (progn (forward-sexp 1) (1- (point)))))))) | |
186 (t (error "Unknown symbol: %c" c)))) | |
187 ;; If we found no display-name, then we look for comments. | |
188 (if display-name | |
189 (setq display-string | |
190 (mapconcat 'identity (reverse display-name) " ")) | |
191 (setq display-string (ietf-drums-get-comment string))) | |
192 (if (not mailbox) | |
193 (when (string-match "@" display-string) | |
194 (cons | |
195 (mapconcat 'identity (nreverse display-name) "") | |
196 (ietf-drums-get-comment string))) | |
197 (cons mailbox display-string))))) | |
198 | |
199 (defun ietf-drums-parse-addresses (string) | |
200 "Parse STRING and return a list of MAILBOX / DISPLAY-NAME pairs." | |
201 (with-temp-buffer | |
202 (ietf-drums-init string) | |
203 (let ((beg (point)) | |
204 pairs c) | |
205 (while (not (eobp)) | |
206 (setq c (char-after)) | |
207 (cond | |
208 ((memq c '(?\" ?< ?\()) | |
209 (forward-sexp 1)) | |
210 ((eq c ?,) | |
211 (push (ietf-drums-parse-address (buffer-substring beg (point))) | |
212 pairs) | |
213 (forward-char 1) | |
214 (setq beg (point))) | |
215 (t | |
216 (forward-char 1)))) | |
217 (push (ietf-drums-parse-address (buffer-substring beg (point))) | |
218 pairs) | |
219 (nreverse pairs)))) | |
220 | |
221 (defun ietf-drums-unfold-fws () | |
222 "Unfold folding white space in the current buffer." | |
223 (goto-char (point-min)) | |
224 (while (re-search-forward ietf-drums-fws-regexp nil t) | |
225 (replace-match " " t t)) | |
226 (goto-char (point-min))) | |
227 | |
228 (defun ietf-drums-parse-date (string) | |
229 "Return an Emacs time spec from STRING." | |
230 (apply 'encode-time (parse-time-string string))) | |
231 | |
232 (defun ietf-drums-narrow-to-header () | |
233 "Narrow to the header section in the current buffer." | |
234 (narrow-to-region | |
235 (goto-char (point-min)) | |
236 (if (re-search-forward "^\r?$" nil 1) | |
237 (match-beginning 0) | |
238 (point-max))) | |
239 (goto-char (point-min))) | |
240 | |
241 (defun ietf-drums-quote-string (string) | |
242 "Quote string if it needs quoting to be displayed in a header." | |
243 (if (string-match (concat "[^" ietf-drums-atext-token "]") string) | |
244 (concat "\"" string "\"") | |
245 string)) | |
246 | |
247 (provide 'ietf-drums) | |
248 | |
249 ;;; ietf-drums.el ends here |