* message.el (message-info): Hanlde EasyPG manual.
[gnus] / lisp / mml.el
index 5ff55db..cf592ac 100644 (file)
@@ -1,14 +1,14 @@
 ;;; mml.el --- A package for parsing and validating MML documents
 
 ;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-;;   2005, 2006, 2007 Free Software Foundation, Inc.
+;;   2005, 2006, 2007, 2008 Free Software Foundation, Inc.
 
 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
 ;; This file is part of GNU Emacs.
 
 ;; GNU Emacs is free software; you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
+;; the Free Software Foundation; either version 3, or (at your option)
 ;; any later version.
 
 ;; GNU Emacs is distributed in the hope that it will be useful,
 
 ;;; Code:
 
+;; For Emacs < 22.2.
+(eval-and-compile
+  (unless (fboundp 'declare-function) (defmacro declare-function (&rest r))))
+
 (require 'mm-util)
 (require 'mm-bodies)
 (require 'mm-encode)
   (autoload 'message-posting-charset "message")
   (autoload 'dnd-get-local-file-name "dnd"))
 
+(autoload 'message-options-set    "message")
+(autoload 'message-narrow-to-head "message")
+(autoload 'message-in-body-p      "message")
+(autoload 'message-mail-p         "message")
+
 (defvar gnus-article-mime-handles)
 (defvar gnus-mouse-2)
 (defvar gnus-newsrc-hashtb)
@@ -53,6 +62,7 @@
 (defvar message-required-mail-headers)
 (defvar message-required-news-headers)
 (defvar dnd-protocol-alist)
+(defvar mml-dnd-protocol-alist)
 
 (defcustom mml-content-type-parameters
   '(name access-type expiration size permission format)
@@ -87,7 +97,7 @@ type (e.g., text/plain) respectively, and DISPOSITION should be either
 the string \"attachment\" or the string \"inline\".  The value t for
 SUPERTYPE, SUBTYPE or TYPE matches any of those types.  The first
 match found will be used."
-  :version "23.0" ;; No Gnus
+  :version "23.1" ;; No Gnus
   :type (let ((dispositions '(radio :format "DISPOSITION: %v"
                                    :value "attachment"
                                    (const :format "%v " "attachment")
@@ -445,7 +455,7 @@ If MML is non-nil, return the buffer up till the correspondent mml tag."
        (mml-multipart-number mml-multipart-number))
     (if (not cont)
        nil
-      (with-temp-buffer
+      (mm-with-multibyte-buffer
        (if (and (consp (car cont))
                 (= (length cont) 1))
            (mml-generate-mime-1 (car cont))
@@ -535,7 +545,13 @@ If MML is non-nil, return the buffer up till the correspondent mml tag."
                        ;; insert a "; format=flowed" string unless the
                        ;; user has already specified it.
                        (setq flowed (null (assq 'format cont)))))
-                   (setq charset (mm-encode-body charset))
+                   ;; Prefer `utf-8' for text/calendar parts.
+                   (if (or charset
+                           (not (string= type "text/calendar")))
+                       (setq charset (mm-encode-body charset))
+                     (let ((mm-coding-system-priorities
+                            (cons 'utf-8 mm-coding-system-priorities)))
+                       (setq charset (mm-encode-body))))
                    (setq encoding (mm-body-encoding
                                    charset (cdr (assq 'encoding cont))))))
                  (setq coded (buffer-string)))
@@ -564,14 +580,13 @@ If MML is non-nil, return the buffer up till the correspondent mml tag."
                      (progn
                        (mm-enable-multibyte)
                        (insert contents)
-                       (setq charset (mm-encode-body charset)))
+                       (unless raw
+                         (setq charset (mm-encode-body charset))))
                    (insert contents)))))
              (setq encoding (mm-encode-buffer type)
                    coded (mm-string-as-multibyte (buffer-string))))
            (mml-insert-mime-headers cont type charset encoding nil)
-           (insert "\n")
-           (mm-with-unibyte-current-buffer
-             (insert coded)))))
+           (insert "\n" coded))))
        ((eq (car cont) 'external)
        (insert "Content-Type: message/external-body")
        (let ((parameters (mml-parameter-string
@@ -802,9 +817,9 @@ If MML is non-nil, return the buffer up till the correspondent mml tag."
         (mail-header-encode-parameter
          (symbol-name type) value))))))
 
-(eval-when-compile
-  (defvar ange-ftp-name-format)
-  (defvar efs-path-regexp))
+(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)
@@ -826,6 +841,10 @@ If MML is non-nil, return the buffer up till the correspondent mml tag."
 ;;; Transforming MIME to MML
 ;;;
 
+;; message-narrow-to-head autoloads message.
+(declare-function message-remove-header "message"
+                  (header &optional is-regexp first reverse))
+
 (defun mime-to-mml (&optional handles)
   "Translate the current buffer (which should be a message) into MML.
 If HANDLES is non-nil, use it instead reparsing the buffer."
@@ -851,16 +870,24 @@ If HANDLES is non-nil, use it instead reparsing the buffer."
     (message-remove-header "Content-Disposition")
     (message-remove-header "Content-Transfer-Encoding")))
 
+(autoload 'message-encode-message-body "message")
+(declare-function message-narrow-to-headers-or-head "message" ())
+
 (defun mml-to-mime ()
   "Translate the current buffer from MML to MIME."
-  (message-encode-message-body)
+  ;; `message-encode-message-body' will insert an encoded Content-Description
+  ;; header in the message header if the body contains a single part
+  ;; that is specified by a user with a MML tag containing a description
+  ;; token.  So, we encode the message header first to prevent the encoded
+  ;; Content-Description header from being encoded again.
   (save-restriction
     (message-narrow-to-headers-or-head)
     ;; Skip past any From_ headers.
     (while (looking-at "From ")
       (forward-line 1))
     (let ((mail-parse-charset message-default-charset))
-      (mail-encode-encoded-word-buffer))))
+      (mail-encode-encoded-word-buffer)))
+  (message-encode-message-body))
 
 (defun mml-insert-mime (handle &optional no-markup)
   (let (textp buffer mmlp)
@@ -884,7 +911,7 @@ If HANDLES is non-nil, use it instead reparsing the buffer."
       (goto-char (point-max))
       (insert "<#/mml>\n"))
      ((stringp (car handle))
-      (mapcar 'mml-insert-mime (cdr handle))
+      (mapc 'mml-insert-mime (cdr handle))
       (insert "<#/multipart>\n"))
      (textp
       (let ((charset (mail-content-type-get
@@ -990,6 +1017,14 @@ If HANDLES is non-nil, use it instead reparsing the buffer."
     (define-key main "\C-c\C-m" map)
     main))
 
+(defun mml-toggle-gcc-externalize-attachments ()
+  (interactive)
+  (prog1
+      (setq gnus-gcc-externalize-attachments
+           (not gnus-gcc-externalize-attachments))
+    (message "gnus-gcc-externalize-attachments is `%s'."
+            gnus-gcc-externalize-attachments)))
+
 (easy-menu-define
   mml-menu mml-mode-map ""
   `("Attachments"
@@ -998,10 +1033,18 @@ If HANDLES is non-nil, use it instead reparsing the buffer."
         '(:help "Attach a file at point"))]
     ["Attach Buffer..." mml-attach-buffer
      ,@(if (featurep 'xemacs) '(t)
-        '(:help "Attach a buffer to the outgoing MIME message"))]
+        '(:help "Attach a buffer to the outgoing message"))]
     ["Attach External..." mml-attach-external
      ,@(if (featurep 'xemacs) '(t)
-        '(:help "Attach reference to file"))]
+        '(:help "Attach reference to an external file"))]
+    ;; ["Externalize Attachments"
+    ;;  (lambda () (interactive) (mml-toggle-gcc-externalize-attachments))
+    ;; ,@(if (featurep 'xemacs) nil
+    ;;         '(:help "Save attachments as external parts in Gcc copies"))
+    ;; :visible (booleanp gnus-gcc-externalize-attachments)
+    ;; :style radio
+    ;; :selected (equal gnus-gcc-externalize-attachments t) ]
+    "----"
     ;;
     ("Change Security Method"
      ["PGP/MIME"
@@ -1029,6 +1072,10 @@ If HANDLES is non-nil, use it instead reparsing the buffer."
     ["Encrypt/Sign off" mml-unsecure-message
      ,@(if (featurep 'xemacs) '(t)
         '(:help "Don't Encrypt/Sign Message"))]
+    ;; Do we have separate encrypt and encrypt/sign commands for parts?
+    ["Sign Part" mml-secure-sign t]
+    ["Encrypt Part" mml-secure-encrypt t]
+    "----"
     ;; Maybe we could remove these, because people who write MML most probably
     ;; don't use the menu:
     ["Insert Part..." mml-insert-part
@@ -1036,9 +1083,6 @@ If HANDLES is non-nil, use it instead reparsing the buffer."
     ["Insert Multipart..." mml-insert-multipart
      :active (message-in-body-p)]
     ;;
-    ;; Do we have separate encrypt and encrypt/sign commands for parts?
-    ["Sign Part" mml-secure-sign t]
-    ["Encrypt Part" mml-secure-encrypt t]
     ;;["Narrow" mml-narrow-to-part t]
     ["Quote MML in region" mml-quote-region
      :active (message-mark-active-p)
@@ -1050,9 +1094,14 @@ If HANDLES is non-nil, use it instead reparsing the buffer."
     ["Emacs MIME manual" (lambda () (interactive) (message-info 4))
      ,@(if (featurep 'xemacs) '(t)
         '(:help "Display the Emacs MIME manual"))]
-    ["PGG manual" (lambda () (interactive) (message-info 16))
+    ["PGG manual" (lambda () (interactive) (message-info mml2015-use))
+     :visible (equal mml2015-use 'pgg)
+     ,@(if (featurep 'xemacs) '(t)
+        '(:help "Display the PGG manual"))]
+    ["EasyPG manual" (lambda () (interactive) (message-info mml2015-use))
+     :visible (equal mml2015-use 'epg)
      ,@(if (featurep 'xemacs) '(t)
-        '(:help "Display the PGG manual"))]))
+        '(:help "Display the EasyPG manual"))]))
 
 (defvar mml-mode nil
   "Minor mode for editing MML.")
@@ -1083,7 +1132,7 @@ See Info node `(emacs-mime)Composing'.
   "The default directory where mml will find files.
 If not set, `default-directory' will be used."
   :type '(choice directory (const :tag "Default" nil))
-  :version "23.0" ;; No Gnus
+  :version "23.1" ;; No Gnus
   :group 'message)
 
 (defun mml-minibuffer-read-file (prompt)
@@ -1195,7 +1244,7 @@ If it is a list, valid members are `type', `description' and
 don't ask for options.  If it is t, ask the user whether or not
 to specify options."
   :type '(choice
-         (const :tag "Non" nil)
+         (const :tag "None" nil)
          (const :tag "Query" t)
          (list :value (type description disposition)
           (set :inline t
@@ -1298,6 +1347,11 @@ TYPE is the MIME type to use."
   (mml-insert-tag 'part 'type type 'disposition "inline")
   (forward-line -1))
 
+(declare-function message-subscribed-p "message" ())
+(declare-function message-make-mail-followup-to "message"
+                  (&optional only-show-subscribed))
+(declare-function message-position-on-field "message" (header &rest afters))
+
 (defun mml-preview-insert-mail-followup-to ()
   "Insert a Mail-Followup-To header before previewing an article.
 Should be adopted if code in `message-send-mail' is changed."
@@ -1310,6 +1364,17 @@ Should be adopted if code in `message-send-mail' is changed."
 
 (defvar mml-preview-buffer nil)
 
+(autoload 'gnus-make-hashtable "gnus-util")
+(autoload 'widget-button-press "wid-edit" nil t)
+(declare-function widget-event-point "wid-edit" (event))
+;; If gnus-buffer-configuration is bound this is loaded.
+(declare-function gnus-configure-windows "gnus-win" (setting &optional force))
+;; Called after message-mail-p, which autoloads message.
+(declare-function message-news-p                "message" ())
+(declare-function message-options-set-recipient "message" ())
+(declare-function message-generate-headers      "message" (headers))
+(declare-function message-sort-headers          "message" ())
+
 (defun mml-preview (&optional raw)
   "Display current buffer with Gnus, in a new buffer.
 If RAW, display a raw encoded MIME message.