2001-06-30 YAGI Tatsuya <yagi@is.titech.ac.jp>
[gnus] / lisp / mml.el
index 1a1cbd7..ad1c450 100644 (file)
@@ -1,5 +1,5 @@
 ;;; mml.el --- A package for parsing and validating MML documents
-;; Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
+;; Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
 
 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
 ;; This file is part of GNU Emacs.
 (eval-and-compile
   (autoload 'message-make-message-id "message")
   (autoload 'gnus-setup-posting-charset "gnus-msg")
+  (autoload 'gnus-add-minor-mode "gnus-ems")
   (autoload 'message-fetch-field "message")
   (autoload 'message-posting-charset "message"))
 
 (defvar mml-generate-multipart-alist nil
   "*Alist of multipart generation functions.
 Each entry has the form (NAME . FUNCTION), where
-NAME is a string containing the name of the part (without the 
+NAME is a string containing the name of the part (without the
 leading \"/multipart/\"),
 FUNCTION is a Lisp function which is called to generate the part.
 
@@ -77,7 +78,7 @@ one charsets.")
 
 (defvar mml-buffer-list nil)
 
-(defun mml-generate-new-buffer (name) 
+(defun mml-generate-new-buffer (name)
   (let ((buf (generate-new-buffer name)))
     (push buf mml-buffer-list)
     buf))
@@ -89,13 +90,14 @@ one charsets.")
 
 (defun mml-parse ()
   "Parse the current buffer as an MML document."
-  (goto-char (point-min))
-  (let ((table (syntax-table)))
-    (unwind-protect
-       (progn
-         (set-syntax-table mml-syntax-table)
-         (mml-parse-1))
-      (set-syntax-table table))))
+  (save-excursion
+    (goto-char (point-min))
+    (let ((table (syntax-table)))
+      (unwind-protect
+         (progn
+           (set-syntax-table mml-syntax-table)
+           (mml-parse-1))
+       (set-syntax-table table)))))
 
 (defun mml-parse-1 ()
   "Parse the current buffer as an MML document."
@@ -119,15 +121,19 @@ one charsets.")
        (setq raw (cdr (assq 'raw tag))
              point (point)
              contents (mml-read-part (eq 'mml (car tag)))
-             charsets (if raw nil 
+             charsets (if raw nil
                         (mm-find-mime-charset-region point (point))))
        (when (and (not raw) (memq nil charsets))
          (if (or (memq 'unknown-encoding mml-confirmation-set)
-                 (y-or-n-p
-                  "Message contains characters with unknown encoding.  Really send?"))
-             (if (setq use-ascii 
+                  (message-options-get 'unknown-encoding)
+                 (and (y-or-n-p "\
+Message contains characters with unknown encoding.  Really send?")
+                       (message-options-set 'unknown-encoding t)))
+             (if (setq use-ascii
                        (or (memq 'use-ascii mml-confirmation-set)
-                           (y-or-n-p "Use ASCII as charset?")))
+                            (message-options-get 'use-ascii)
+                           (and (y-or-n-p "Use ASCII as charset?")
+                                 (message-options-set 'use-ascii t))))
                  (setq charsets (delq nil charsets))
                (setq warn nil))
            (error "Edit your message to remove those characters")))
@@ -143,18 +149,18 @@ one charsets.")
                          tag point (point) use-ascii)))
            (when (and warn
                       (not (memq 'multipart mml-confirmation-set))
-                      (not
-                       (y-or-n-p
-                        (format
-                         "Warning: Your message contains more than %d parts.  Really send? "
-                         (length nstruct)))))
+                       (not (message-options-get 'multipart))
+                      (not (and (y-or-n-p (format "\
+A message part needs to be split into %d charset parts.  Really send? "
+                                                   (length nstruct)))
+                                 (message-options-set 'multipart t))))
              (error "Edit your message to use only one charset"))
            (setq struct (nconc nstruct struct)))))))
     (unless (eobp)
       (forward-line 1))
     (nreverse struct)))
 
-(defun mml-parse-singlepart-with-multiple-charsets 
+(defun mml-parse-singlepart-with-multiple-charsets
   (orig-tag beg end &optional use-ascii)
   (save-excursion
     (save-restriction
@@ -214,7 +220,8 @@ one charsets.")
 
 (defun mml-read-tag ()
   "Read a tag and return the contents."
-  (let (contents name elem val)
+  (let ((orig-point (point))
+       contents name elem val)
     (forward-char 2)
     (setq name (buffer-substring-no-properties
                (point) (progn (forward-sexp 1) (point))))
@@ -232,6 +239,8 @@ one charsets.")
     (goto-char (match-end 0))
     ;; Don't skip the leading space.
     ;;(skip-chars-forward " \t\n")
+    ;; Put the tag location into the returned contents
+    (setq contents (append (list (cons 'tag-location orig-point)) contents))
     (cons (intern name) (nreverse contents))))
 
 (defun mml-read-part (&optional mml)
@@ -247,7 +256,7 @@ If MML is non-nil, return the buffer up till the correspondent mml tag."
            (if (re-search-forward "<#\\(/\\)?mml." nil t)
                (setq count (+ count (if (match-beginning 1) -1 1)))
              (goto-char (point-max))))
-         (buffer-substring-no-properties beg (if (> count 0) 
+         (buffer-substring-no-properties beg (if (> count 0)
                                                  (point)
                                                (match-beginning 0))))
       (if (re-search-forward
@@ -280,7 +289,7 @@ If MML is non-nil, return the buffer up till the correspondent mml tag."
        (buffer-string)))))
 
 (defun mml-generate-mime-1 (cont)
-  (let ((mm-use-ultra-safe-encoding 
+  (let ((mm-use-ultra-safe-encoding
         (or mm-use-ultra-safe-encoding (assq 'sign cont))))
     (save-restriction
       (narrow-to-region (point) (point))
@@ -292,9 +301,10 @@ If MML is non-nil, return the buffer up till the correspondent mml tag."
          (if (and (not raw)
                   (member (car (split-string type "/")) '("text" "message")))
              (with-temp-buffer
-               (setq charset (mm-charset-to-coding-system 
+               (setq charset (mm-charset-to-coding-system
                               (cdr (assq 'charset cont))))
-               (if (eq charset 'ascii) (setq charset nil))
+               (when (eq charset 'ascii)
+                 (setq charset nil))
                (cond
                 ((cdr (assq 'buffer cont))
                  (insert-buffer-substring (cdr (assq 'buffer cont))))
@@ -311,10 +321,11 @@ If MML is non-nil, return the buffer up till the correspondent mml tag."
                    ;; Remove quotes from quoted tags.
                    (goto-char (point-min))
                    (while (re-search-forward
-                           "<#!+/?\\(part\\|multipart\\|external\\|mml\\)" nil t)
+                           "<#!+/?\\(part\\|multipart\\|external\\|mml\\)"
+                           nil t)
                      (delete-region (+ (match-beginning 0) 2)
                                     (+ (match-beginning 0) 3))))))
-               (cond 
+               (cond
                 ((eq (car cont) 'mml)
                  (let ((mml-boundary (funcall mml-boundary-function
                                               (incf mml-multipart-number)))
@@ -327,7 +338,7 @@ If MML is non-nil, return the buffer up till the correspondent mml tag."
                  (let ((mm-7bit-chars (concat mm-7bit-chars "\x1b")))
                    ;; ignore 0x1b, it is part of iso-2022-jp
                    (setq encoding (mm-body-7-or-8))))
-                (t 
+                (t
                  (setq charset (mm-encode-body charset))
                  (setq encoding (mm-body-encoding
                                  charset (cdr (assq 'encoding cont))))))
@@ -369,7 +380,7 @@ If MML is non-nil, return the buffer up till the correspondent mml tag."
               (concat "access-type="
                       (if (member (nth 0 name) '("ftp@" "anonymous@"))
                           "anon-ftp"
-                        "ftp")))))      
+                        "ftp")))))
          (when url
            (mml-insert-parameter
             (mail-header-encode-parameter "url" url)
@@ -523,8 +534,9 @@ If MML is non-nil, return the buffer up till the correspondent mml tag."
         (mail-header-encode-parameter
          (symbol-name type) value))))))
 
-(defvar ange-ftp-name-format)
-(defvar efs-path-regexp)
+(eval-when-compile
+  (defvar ange-ftp-name-format)
+  (defvar efs-path-regexp))
 (defun mml-parse-file-name (path)
   (if (if (boundp 'efs-path-regexp)
          (string-match efs-path-regexp path)
@@ -585,7 +597,7 @@ If HANDLES is non-nil, use it instead reparsing the buffer."
        (save-excursion
          (set-buffer (setq buffer (mml-generate-new-buffer " *mml*")))
          (mm-insert-part handle)
-         (if (setq mmlp (equal (mm-handle-media-type handle) 
+         (if (setq mmlp (equal (mm-handle-media-type handle)
                                "message/rfc822"))
              (mime-to-mml)))))
     (if mmlp
@@ -594,7 +606,7 @@ If HANDLES is non-nil, use it instead reparsing the buffer."
                   (equal (mm-handle-media-type handle) "text/plain"))
        (mml-insert-mml-markup handle buffer textp)))
     (cond
-     (mmlp 
+     (mmlp
       (insert-buffer buffer)
       (goto-char (point-max))
       (insert "<#/mml>\n"))
@@ -849,7 +861,7 @@ If RAW, don't highlight the article."
   (interactive "P")
   (let ((buf (current-buffer))
        (message-options message-options)
-       (message-posting-charset (or (gnus-setup-posting-charset 
+       (message-posting-charset (or (gnus-setup-posting-charset
                                      (save-restriction
                                        (message-narrow-to-headers-or-head)
                                        (message-fetch-field "Newsgroups")))
@@ -875,8 +887,10 @@ If RAW, don't highlight the article."
        (run-hooks 'gnus-article-decode-hook)
        (let ((gnus-newsgroup-name "dummy"))
          (gnus-article-prepare-display))))
-    (fundamental-mode)
+    ;; Disable article-mode-map. 
+    (use-local-map nil)
     (setq buffer-read-only t)
+    (local-set-key "q" (lambda () (interactive) (kill-buffer nil)))
     (goto-char (point-min))))
 
 (defun mml-validate ()