(require 'emu)
+(require 'ew-var)
(require 'ew-unit)
(require 'ew-scan-s)
(require 'ew-scan-m)
(require 'ew-parse)
(provide 'ew-dec)
+(defvar ew-decode-field-cache-buf '())
+(defvar ew-decode-field-cache-num 300)
+
(defun ew-decode-field (field-name field-body &optional eword-filter)
"Decode MIME RFC2047 encoded-words in a field.
FIELD-NAME is a name of the field such as \"To\", \"Subject\" etc. and
each successful decoded encoded-word with decoded string as a
argument. The return value of EWORD-FILTER is used as decoding result
instead of its argument."
+ (let* ((key (ew-cons* field-name field-body eword-filter
+ (ew-dynamic-options)))
+ (tmp (assoc key ew-decode-field-cache-buf)))
+ (if tmp
+ (cdr tmp)
+ (progn
+ (setq tmp (nthcdr ew-decode-field-cache-num
+ ew-decode-field-cache-buf))
+ (if (cdr tmp)
+ (progn
+ (setcdr (cdr tmp) ew-decode-field-cache-buf)
+ (setq ew-decode-field-cache-buf (cdr tmp))
+ (setcdr tmp nil))
+ (setq ew-decode-field-cache-buf
+ (cons (cons nil nil)
+ ew-decode-field-cache-buf)))
+ (setcar (car ew-decode-field-cache-buf) key)
+ (setcdr (car ew-decode-field-cache-buf)
+ (ew-decode-field-no-cache
+ field-name field-body eword-filter))
+ (cdar ew-decode-field-cache-buf)))))
+
+(defun ew-decode-field-no-cache (field-name field-body &optional eword-filter)
+ "No caching version of ew-decode-field."
(let ((tmp (assoc (downcase field-name) ew-decode-field-syntax-alist))
frag-anchor frag1 frag2 decode)
(if tmp
(setq frag2 (get frag2 'next-frag)))
(funcall decode frag-anchor frag1 frag2 eword-filter)
(setq frag1 frag2))
- (mapconcat (lambda (frag) (or (get frag 'result) (symbol-name frag)))
- (ew-frag-list frag-anchor) "")))
+ (setq frag1 (get frag-anchor 'prev-frag)
+ tmp ())
+ (while (not (eq frag1 frag-anchor))
+ (setq tmp (cons (or (get frag1 'result) (symbol-name frag1)) tmp)
+ frag1 (get frag1 'prev-frag)))
+ (apply 'concat tmp)))
(defun ew-mark (tag anchor)
(let ((tlist (cons (list (symbol-value tag)) (ew-pair-list anchor))))
--- /dev/null
+(provide 'ew-var)
+
+;;; user customizable variables.
+
+(defvar ew-decode-sticked-encoded-word nil)
+(defvar ew-decode-quoted-encoded-word nil)
+(defvar ew-ignore-75bytes-limit nil)
+(defvar ew-ignore-76bytes-limit nil)
+(defvar ew-permit-sticked-comment nil)
+(defvar ew-permit-sticked-special nil)
+
+;;; anonymous function to decode ground string.
+;; NOTE: STR is CRLF-form and it should return as CRLF-form.
+(defvar ew-decode-us-ascii (lambda (str) (decode-coding-string str 'iso-latin-1-unix)))
+
+;;;
+(defvar ew-decode-field-syntax-alist
+'(("from" ew-scan-unibyte-std11 . ew:tag-mailbox+-tok)
+ ("sender" ew-scan-unibyte-std11 . ew:tag-mailbox-tok)
+ ("to" ew-scan-unibyte-std11 . ew:tag-address+-tok)
+ ("resent-to" ew-scan-unibyte-std11 . ew:tag-address+-tok)
+ ("cc" ew-scan-unibyte-std11 . ew:tag-address+-tok)
+ ("resent-cc" ew-scan-unibyte-std11 . ew:tag-address+-tok)
+ ("bcc" ew-scan-unibyte-std11 . ew:tag-address*-tok)
+ ("resent-bcc" ew-scan-unibyte-std11 . ew:tag-address*-tok)
+ ("message-id" ew-scan-unibyte-std11)
+ ("resent-message-id" ew-scan-unibyte-std11)
+ ("in-reply-to" ew-scan-unibyte-std11 . ew:tag-phrase-msg-id*-tok)
+ ("references" ew-scan-unibyte-std11 . ew:tag-phrase-msg-id*-tok)
+ ("keywords" ew-scan-unibyte-std11 . ew:tag-phrase*-tok)
+ ("subject" ew-scan-unibyte-unstructured)
+ ("comments" ew-scan-unibyte-unstructured)
+ ("encrypted" ew-scan-unibyte-std11)
+ ("date" ew-scan-unibyte-std11)
+ ("reply-to" ew-scan-unibyte-std11 . ew:tag-address+-tok)
+ ("received" ew-scan-unibyte-std11)
+ ("resent-reply-to" ew-scan-unibyte-std11 . ew:tag-address+-tok)
+ ("resent-from" ew-scan-unibyte-std11 . ew:tag-mailbox+-tok)
+ ("resent-sender" ew-scan-unibyte-std11 . ew:tag-mailbox-tok)
+ ("resent-date" ew-scan-unibyte-std11)
+ ("return-path" ew-scan-unibyte-std11)
+ ("mime-version" ew-scan-unibyte-std11)
+ ("content-type" ew-scan-unibyte-mime)
+ ("content-transfer-encoding" ew-scan-unibyte-mime)
+ ("content-id" ew-scan-unibyte-mime)
+ ("content-description" ew-scan-unibyte-unstructured)
+))
+
+(defvar ew-decode-field-default-syntax '(ew-scan-unibyte-unstructured))
+
+;;; constants.
+
+(defconst ew-token-regexp "[-!#-'*+0-9A-Z^-~]+")
+(defconst ew-encoded-text-regexp "[!->@-~]+")
+(defconst ew-encoded-word-regexp
+ (concat (regexp-quote "=?")
+ "\\(" ew-token-regexp "\\)"
+ (regexp-quote "?")
+ "\\(" ew-token-regexp "\\)"
+ (regexp-quote "?")
+ "\\(" ew-encoded-text-regexp "\\)"
+ (regexp-quote "?=")))
+
+;;; utilities for variables.
+
+(defun ew-dynamic-options ()
+ (list
+ ew-decode-sticked-encoded-word
+ ew-decode-quoted-encoded-word
+ ew-ignore-75bytes-limit
+ ew-ignore-76bytes-limit
+ ew-permit-sticked-comment
+ ew-permit-sticked-special))