diff options
| author | Francesco Potortì | 2002-12-16 16:22:41 +0000 |
|---|---|---|
| committer | Francesco Potortì | 2002-12-16 16:22:41 +0000 |
| commit | 3af9d2cf6925c8f087865f7c22baf15e991bb598 (patch) | |
| tree | 1a01c82f58bfd28865b827e08572440eefcc9e4a | |
| parent | 93ec302e30962859580451fb2e9e7f1471d7e497 (diff) | |
| download | emacs-3af9d2cf6925c8f087865f7c22baf15e991bb598.tar.gz emacs-3af9d2cf6925c8f087865f7c22baf15e991bb598.zip | |
Now supports MIME too.
| -rw-r--r-- | lisp/mail/undigest.el | 236 |
1 files changed, 157 insertions, 79 deletions
diff --git a/lisp/mail/undigest.el b/lisp/mail/undigest.el index 619c906a8b5..01ae5cd07bf 100644 --- a/lisp/mail/undigest.el +++ b/lisp/mail/undigest.el | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | ;;; undigest.el --- digest-cracking support for the RMAIL mail reader | 1 | ;;; undigest.el --- digest-cracking support for the RMAIL mail reader |
| 2 | 2 | ||
| 3 | ;; Copyright (C) 1985, 1986, 1994, 1996 Free Software Foundation, Inc. | 3 | ;; Copyright (C) 1985, 1986, 1994, 1996, 2002 |
| 4 | ;; Free Software Foundation, Inc. | ||
| 4 | 5 | ||
| 5 | ;; Maintainer: FSF | 6 | ;; Maintainer: FSF |
| 6 | ;; Keywords: mail | 7 | ;; Keywords: mail |
| @@ -24,17 +25,119 @@ | |||
| 24 | 25 | ||
| 25 | ;;; Commentary: | 26 | ;;; Commentary: |
| 26 | 27 | ||
| 27 | ;; See Internet RFC 934 | 28 | ;; See Internet RFC 934 and RFC 1153 |
| 28 | 29 | ||
| 29 | ;;; Code: | 30 | ;;; Code: |
| 30 | 31 | ||
| 31 | (require 'rmail) | 32 | (require 'rmail) |
| 32 | 33 | ||
| 33 | (defcustom rmail-digest-end-regexps | 34 | (defconst rmail-digest-methods |
| 34 | (list "End of.*Digest.*\n" "End of.*\n") | 35 | '(rmail-digest-parse-mime |
| 35 | "*Regexps matching the end of a digest message." | 36 | rmail-digest-parse-rfc1153strict |
| 36 | :group 'rmail | 37 | rmail-digest-parse-rfc1153sloppy |
| 37 | :type '(repeat regexp)) | 38 | rmail-digest-parse-rfc934) |
| 39 | "List of digest parsing functions, in preference order. | ||
| 40 | |||
| 41 | The functions operate on the current narrowing, and take no argument. A | ||
| 42 | function returns nil if it cannot parse the digest. If it can, it | ||
| 43 | returns a list of cons pairs containing the start and end positions of | ||
| 44 | each undigestified message as markers.") | ||
| 45 | |||
| 46 | (defconst rmail-digest-mail-separator | ||
| 47 | "\^_\^L\n0, unseen,,\n*** EOOH ***\n" | ||
| 48 | "String substituted to the digest separator to create separate messages.") | ||
| 49 | |||
| 50 | |||
| 51 | |||
| 52 | (defun rmail-digest-parse-mime () | ||
| 53 | (goto-char (point-min)) | ||
| 54 | (when (let ((head-end (progn (search-forward "\n\n" nil t) (point)))) | ||
| 55 | (goto-char (point-min)) | ||
| 56 | (and head-end | ||
| 57 | (re-search-forward | ||
| 58 | (concat | ||
| 59 | "^Content-type: multipart/digest;" | ||
| 60 | "\\s-* boundary=\"?\\([^\";\n]+\\)[\";\n]") head-end t) | ||
| 61 | (search-forward (match-string 1) nil t))) | ||
| 62 | ;; Ok, prolog separator found | ||
| 63 | (let ((start (make-marker)) | ||
| 64 | (end (make-marker)) | ||
| 65 | (separator (concat "\n--" (match-string 0) "\n\n")) | ||
| 66 | result) | ||
| 67 | (while (search-forward separator nil t) | ||
| 68 | (move-marker start (match-beginning 0)) | ||
| 69 | (move-marker end (match-end 0)) | ||
| 70 | (add-to-list 'result (cons (copy-marker start) (copy-marker end t)))) | ||
| 71 | ;; Return the list of marker pairs | ||
| 72 | (nreverse result)))) | ||
| 73 | |||
| 74 | (defun rmail-digest-parse-rfc1153strict () | ||
| 75 | "Parse following strictly the method defined in RFC 1153. | ||
| 76 | See rmail-digest-methods." | ||
| 77 | (rmail-digest-rfc1153 | ||
| 78 | "^-\\{70\\}\n\n" | ||
| 79 | "^\n-\\{30\\}\n\n" | ||
| 80 | "^\n-\\{30\\}\n\nEnd of .* Digest.*\n\\*\\{15,\\}\n+\'")) | ||
| 81 | |||
| 82 | (defun rmail-digest-parse-rfc1153sloppy () | ||
| 83 | "Parse using the method defined in RFC 1153, allowing for some sloppiness. | ||
| 84 | See rmail-digest-methods." | ||
| 85 | (rmail-digest-rfc1153 | ||
| 86 | "^-\\{55,\\}\n\n" | ||
| 87 | "^\n-\\{27,\\}\n\n" | ||
| 88 | "^\n-\\{27,\\}\n\nEnd of")) | ||
| 89 | |||
| 90 | (defun rmail-digest-rfc1153 (prolog-sep message-sep trailer-sep) | ||
| 91 | (goto-char (point-min)) | ||
| 92 | (when (re-search-forward prolog-sep nil t) | ||
| 93 | ;; Ok, prolog separator found | ||
| 94 | (let ((start (make-marker)) | ||
| 95 | (end (make-marker)) | ||
| 96 | separator result) | ||
| 97 | (move-marker start (match-beginning 0)) | ||
| 98 | (move-marker end (match-end 0)) | ||
| 99 | (setq result (cons (copy-marker start) (copy-marker end t))) | ||
| 100 | (when (re-search-forward message-sep nil t) | ||
| 101 | ;; Ok, at least one message separator found | ||
| 102 | (setq separator (match-string 0)) | ||
| 103 | (when (re-search-forward trailer-sep nil t) | ||
| 104 | ;; Wonderful, we found a trailer, too. Now, go on splitting | ||
| 105 | ;; the digest into separate rmail messages | ||
| 106 | (goto-char (cdar result)) | ||
| 107 | (while (search-forward separator nil t) | ||
| 108 | (move-marker start (match-beginning 0)) | ||
| 109 | (move-marker end (match-end 0)) | ||
| 110 | (add-to-list 'result | ||
| 111 | (cons (copy-marker start) (copy-marker end t)))) | ||
| 112 | ;; Undo masking of separators inside digestified messages | ||
| 113 | (goto-char (point-min)) | ||
| 114 | (while (search-forward | ||
| 115 | (replace-regexp-in-string "\n-" "\n " separator) nil t) | ||
| 116 | (replace-match separator)) | ||
| 117 | ;; Return the list of marker pairs | ||
| 118 | (nreverse result)))))) | ||
| 119 | |||
| 120 | (defun rmail-digest-parse-rfc934 () | ||
| 121 | (goto-char (point-min)) | ||
| 122 | (when (re-search-forward "^\n?-[^ ].*\n\n?" nil t) | ||
| 123 | ;; Message separator found | ||
| 124 | (let ((start (make-marker)) | ||
| 125 | (end (make-marker)) | ||
| 126 | (separator (match-string 0)) | ||
| 127 | result) | ||
| 128 | (goto-char (point-min)) | ||
| 129 | (while (search-forward separator nil t) | ||
| 130 | (move-marker start (match-beginning 0)) | ||
| 131 | (move-marker end (match-end 0)) | ||
| 132 | (add-to-list 'result (cons (copy-marker start) (copy-marker end t)))) | ||
| 133 | ;; Undo masking of separators inside digestified messages | ||
| 134 | (goto-char (point-min)) | ||
| 135 | (while (search-forward "\n- -" nil t) | ||
| 136 | (replace-match "\n-")) | ||
| 137 | ;; Return the list of marker pairs | ||
| 138 | (nreverse result)))) | ||
| 139 | |||
| 140 | |||
| 38 | 141 | ||
| 39 | ;;;###autoload | 142 | ;;;###autoload |
| 40 | (defun undigestify-rmail-message () | 143 | (defun undigestify-rmail-message () |
| @@ -43,88 +146,63 @@ Leaves original message, deleted, before the undigestified messages." | |||
| 43 | (interactive) | 146 | (interactive) |
| 44 | (with-current-buffer rmail-buffer | 147 | (with-current-buffer rmail-buffer |
| 45 | (widen) | 148 | (widen) |
| 46 | (let ((buffer-read-only nil) | ||
| 47 | (msg-string (buffer-substring (rmail-msgbeg rmail-current-message) | ||
| 48 | (rmail-msgend rmail-current-message)))) | ||
| 49 | (goto-char (rmail-msgend rmail-current-message)) | ||
| 50 | (narrow-to-region (point) (point)) | ||
| 51 | (insert msg-string) | ||
| 52 | (narrow-to-region (point-min) (1- (point-max)))) | ||
| 53 | (let ((error t) | 149 | (let ((error t) |
| 54 | (buffer-read-only nil)) | 150 | (buffer-read-only nil)) |
| 151 | (goto-char (rmail-msgend rmail-current-message)) | ||
| 152 | (let ((msg-copy (buffer-substring (rmail-msgbeg rmail-current-message) | ||
| 153 | (rmail-msgend rmail-current-message)))) | ||
| 154 | (narrow-to-region (point) (point)) | ||
| 155 | (insert msg-copy)) | ||
| 156 | (narrow-to-region (point-min) (1- (point-max))) | ||
| 55 | (unwind-protect | 157 | (unwind-protect |
| 56 | (progn | 158 | (progn |
| 57 | (save-restriction | 159 | (save-restriction |
| 58 | (goto-char (point-min)) | 160 | (goto-char (point-min)) |
| 59 | (delete-region (point-min) | 161 | (delete-region (point-min) |
| 60 | (progn (search-forward "\n*** EOOH ***\n") | 162 | (progn (search-forward "\n*** EOOH ***\n" nil t) |
| 61 | (point))) | 163 | (point))) |
| 62 | (insert "\^_\^L\n0, unseen,,\n*** EOOH ***\n") | 164 | (insert "\n" rmail-digest-mail-separator) |
| 63 | (narrow-to-region (point) | 165 | (narrow-to-region (point) |
| 64 | (point-max)) | 166 | (point-max)) |
| 65 | (let* ((fill-prefix "") | 167 | (let ((fill-prefix "") |
| 66 | (case-fold-search t) | 168 | (case-fold-search t) |
| 67 | start | 169 | digest-name type start end separator fun-list sep-list) |
| 68 | (digest-name | 170 | (setq digest-name (mail-strip-quoted-names |
| 69 | (mail-strip-quoted-names | 171 | (save-restriction |
| 70 | (or (save-restriction | 172 | (search-forward "\n\n" nil 'move) |
| 71 | (search-forward "\n\n") | 173 | (setq start (point)) |
| 72 | (setq start (point)) | 174 | (narrow-to-region (point-min) start) |
| 73 | (narrow-to-region (point-min) (point)) | 175 | (or (mail-fetch-field "Reply-To") |
| 74 | (goto-char (point-max)) | 176 | (mail-fetch-field "To") |
| 75 | (or (mail-fetch-field "Reply-To") | 177 | (mail-fetch-field "Apparently-To") |
| 76 | (mail-fetch-field "To") | 178 | (mail-fetch-field "From"))))) |
| 77 | (mail-fetch-field "Apparently-To") | 179 | (unless digest-name |
| 78 | (mail-fetch-field "From"))) | 180 | (error "Message is not a digest--bad header")) |
| 79 | (error "Message is not a digest--bad header"))))) | 181 | |
| 80 | (save-excursion | 182 | (setq fun-list rmail-digest-methods) |
| 81 | (let (found | 183 | (while (and fun-list |
| 82 | (regexps rmail-digest-end-regexps)) | 184 | (null (setq sep-list (funcall (car fun-list))))) |
| 83 | (while (and regexps (not found)) | 185 | (setq fun-list (cdr fun-list))) |
| 84 | (goto-char (point-max)) | 186 | (unless sep-list |
| 85 | ;; compensate for broken un*x digestifiers. Sigh Sigh. | 187 | (error "Message is not a digest--no messages found")) |
| 86 | (setq found (re-search-backward | 188 | |
| 87 | (concat "^\\(?:" (car regexps) "\\)") | 189 | ;;; Split the digest into separate rmail messages |
| 88 | start t)) | 190 | (while sep-list |
| 89 | (setq regexps (cdr regexps))) | 191 | (let ((start (caar sep-list)) |
| 90 | (unless found | 192 | (end (cdar sep-list))) |
| 91 | (error "Message is not a digest--no end line")))) | 193 | (delete-region start end) |
| 92 | (re-search-forward (concat "^" (make-string 55 ?-) "-*\n*")) | 194 | (goto-char start) |
| 93 | (replace-match "\^_\^L\n0, unseen,,\n*** EOOH ***\n") | 195 | (insert rmail-digest-mail-separator) |
| 94 | (save-restriction | 196 | (search-forward "\n\n" (caar (cdr sep-list)) 'move) |
| 95 | (narrow-to-region (point) | 197 | (save-restriction |
| 96 | (progn (search-forward "\n\n") | 198 | (narrow-to-region end (point)) |
| 97 | (point))) | 199 | (unless (mail-fetch-field "To") |
| 98 | (if (mail-fetch-field "To") nil | 200 | (goto-char start) |
| 99 | (goto-char (point-min)) | 201 | (insert "To: " digest-name "\n"))) |
| 100 | (insert "To: " digest-name "\n"))) | 202 | (set-marker start nil) |
| 101 | (while (re-search-forward | 203 | (set-marker end nil)) |
| 102 | (concat "\n\n" (make-string 27 ?-) "-*\n*") | 204 | (setq sep-list (cdr sep-list))))) |
| 103 | nil t) | 205 | |
| 104 | (replace-match "\n\n\^_\^L\n0, unseen,,\n*** EOOH ***\n") | ||
| 105 | (save-restriction | ||
| 106 | (if (looking-at "End ") | ||
| 107 | (insert "To: " digest-name "\n\n") | ||
| 108 | (narrow-to-region (point) | ||
| 109 | (progn (search-forward "\n\n" | ||
| 110 | nil 'move) | ||
| 111 | (point)))) | ||
| 112 | (if (mail-fetch-field "To") | ||
| 113 | nil | ||
| 114 | (goto-char (point-min)) | ||
| 115 | (insert "To: " digest-name "\n"))) | ||
| 116 | ;; Digestifiers may insert `- ' on lines that start with `-'. | ||
| 117 | ;; Undo that. | ||
| 118 | (save-excursion | ||
| 119 | (goto-char (point-min)) | ||
| 120 | (if (re-search-forward | ||
| 121 | "\n\n----------------------------*\n*" | ||
| 122 | nil t) | ||
| 123 | (let ((end (point-marker))) | ||
| 124 | (goto-char (point-min)) | ||
| 125 | (while (re-search-forward "^- " end t) | ||
| 126 | (delete-char -2))))) | ||
| 127 | ))) | ||
| 128 | (setq error nil) | 206 | (setq error nil) |
| 129 | (message "Message successfully undigestified") | 207 | (message "Message successfully undigestified") |
| 130 | (let ((n rmail-current-message)) | 208 | (let ((n rmail-current-message)) |