+;;; @ formats
+;;;
+
+(defcustom mu-cite-cited-prefix-regexp
+ "\\(^[^ \t\n<>]+>+[ \t]*\\|^[ \t]*$\\)"
+ "Regexp to match the citation prefix.
+If match, mu-cite doesn't insert citation prefix."
+ :type 'regexp
+ :group 'mu-cite)
+
+(defcustom mu-cite-prefix-format '(prefix-register-verbose "> ")
+ "List to represent citation prefix.
+Each elements must be string or method name."
+ :type (list 'repeat
+ (nconc '(choice :tag "String or Method name")
+ (mapcar
+ (function
+ (lambda (elem) (list 'choice-item (car elem))))
+ mu-cite-default-methods-alist)
+ '((symbol :tag "Other Method")
+ (item "-")
+ (choice-item :tag "String: \"> \"" "> ")
+ (string :tag "Other String"))))
+ :group 'mu-cite)
+
+(defcustom mu-cite-top-format '(in-id ">>>>>\t" from " wrote:\n")
+ "List to represent top string of citation.
+Each elements must be string or method name."
+ :type (list 'repeat
+ (nconc
+ '(choice :tag "String or Method name")
+ (mapcar
+ (function
+ (lambda (elem) (list 'choice-item (car elem))))
+ mu-cite-default-methods-alist)
+ '((symbol :tag "Other Method")
+ (item "-")
+ (choice-item :tag "String: \">>>>>\\t\"" ">>>>>\t")
+ (choice-item :tag "String: \" wrote:\\n\"" " wrote:\n")
+ (string :tag "Other String"))))
+ :group 'mu-cite)
+
+
+;;; @ hooks
+;;;
+
+(defcustom mu-cite-load-hook nil
+ "List of functions called after mu-cite is loaded.
+Use this hook to add your own methods to `mu-cite-default-methods-alist'."
+ :type 'hook
+ :group 'mu-cite)
+
+(defcustom mu-cite-instantiation-hook nil
+ "List of functions called just before narrowing to the message."
+ :type 'hook
+ :group 'mu-cite)
+
+(defcustom mu-cite-pre-cite-hook nil
+ "List of functions called before citing a region of text."
+ :type 'hook
+ :group 'mu-cite)
+
+(defcustom mu-cite-post-cite-hook nil
+ "List of functions called after citing a region of text."
+ :type 'hook
+ :group 'mu-cite)
+
+
+;;; @ field
+;;;
+
+(defvar mu-cite-get-field-value-method-alist nil
+ "Alist major-mode vs. function to get field-body of header.")
+
+(defun mu-cite-get-field-value (name)
+ (or (std11-field-body name)
+ (let ((method (assq major-mode mu-cite-get-field-value-method-alist)))
+ (when method
+ (funcall (cdr method) name)))))
+
+
+;;; @ prefix registration
+;;;
+
+(defcustom mu-cite-registration-file (expand-file-name "~/.mu-cite.el")
+ "The name of the user environment file for mu-cite."
+ :type 'file
+ :group 'mu-cite)
+
+(defcustom mu-cite-allow-null-string-registration nil
+ "If non-nil, null-string citation-name is registered."
+ :type 'boolean
+ :group 'mu-cite)
+
+(defcustom mu-cite-registration-file-coding-system-for-read nil
+ "Coding system for reading registration file."
+ :group 'mu-cite)
+
+(defcustom mu-cite-registration-file-coding-system-for-write nil
+ "Coding system for writing registration file."
+ :group 'mu-cite)
+
+(defcustom mu-cite-registration-file-modes 384
+ "Mode bits of `mu-cite-registration-file', as an integer."
+ :type 'integer
+ :group 'mu-cite)
+
+(defvar mu-cite-registration-symbol 'mu-cite-citation-name-alist)
+
+(defvar mu-cite-citation-name-alist nil)
+(unless (eq 'mu-cite-citation-name-alist mu-cite-registration-symbol)
+ (setq mu-cite-citation-name-alist
+ (symbol-value mu-cite-registration-symbol)))
+(defvar mu-cite-minibuffer-history nil)
+
+;; get citation-name from the database
+(defun mu-cite-get-citation-name (from)
+ (cdr (assoc from mu-cite-citation-name-alist)))
+
+;; register citation-name to the database
+(defun mu-cite-add-citation-name (name from)
+ (setq mu-cite-citation-name-alist
+ (put-alist from name mu-cite-citation-name-alist))
+ (mu-cite-save-registration-file))
+
+;; load/save registration file
+;;(defun mu-cite-load-registration-file ()
+;; (let ((file mu-cite-registration-file))
+;; (when (and file
+;; (file-readable-p file))
+;; (let ((alist
+;; (with-temp-buffer
+;; (eval
+;; (` (let ((, mu-cite-registration-symbol))
+;; (if mu-cite-registration-file-coding-system-for-read
+;; (insert-file-contents-as-coding-system
+;; mu-cite-registration-file-coding-system-for-read
+;; file)
+;; (insert-file-contents file))
+;; (condition-case nil
+;; (progn
+;; (eval-current-buffer)
+;; (, mu-cite-registration-symbol))
+;; (error nil))))))))
+;; (when alist
+;; (setq mu-cite-citation-name-alist alist))))))
+(defun mu-cite-load-registration-file ()
+ (let ((file (mu-cite-registration-file)))
+ (when (and file
+ (file-readable-p file))
+ (let ((alist
+ (with-temp-buffer
+ (eval
+ (` (let ((, mu-cite-registration-symbol)
+ mu-cite/citation-name-alist)
+ (if mu-cite-registration-file-coding-system-for-read
+ (insert-file-contents-as-coding-system
+ mu-cite-registration-file-coding-system-for-read
+ file)
+ (insert-file-contents file))
+ (condition-case nil
+ (progn
+ (eval-current-buffer)
+ (or mu-cite/citation-name-alist
+ (, mu-cite-registration-symbol)))
+ (error nil))))))))
+ (when alist
+ (setq mu-cite-citation-name-alist alist))))))
+(add-hook 'mu-cite-load-hook (function mu-cite-load-registration-file))
+
+(defun mu-cite-save-registration-file ()
+ ;;(let ((file mu-cite-registration-file))
+ (let ((file (mu-cite-registration-file)))
+ (when file
+ (with-temp-buffer
+ (setq buffer-file-name file)
+ (insert ";;; " (file-name-nondirectory file) "\n")
+ (insert ";;; This file is generated automatically by mu-cite "
+ mu-cite-version "\n\n")
+ (insert "(setq "
+ (symbol-name mu-cite-registration-symbol)
+ "\n '(")
+ (insert (mapconcat
+ (function prin1-to-string)
+ mu-cite-citation-name-alist "\n "))
+ (insert "\n ))\n\n")
+ (insert ";;; "
+ (file-name-nondirectory file)
+ " ends here.\n")
+ (write-region 1 1 file nil 'nomsg)
+ (condition-case nil
+ (set-file-modes file mu-cite-registration-file-modes)
+ (error nil))
+ (if mu-cite-registration-file-coding-system-for-write
+ (save-buffer-as-coding-system
+ mu-cite-registration-file-coding-system-for-write)
+ (save-buffer))))))
+
+
+;;; @ item methods
+;;;
+
+;;; @@ ML count
+;;;
+
+(defcustom mu-cite-ml-count-field-list
+ '("X-Ml-Count" "X-Mail-Count" "X-Seqno" "X-Sequence" "Mailinglist-Id")
+ "List of header fields which contain sequence number of mailing list."
+ :type '(repeat (choice (choice-item "X-Ml-Count")
+ (choice-item "X-Mail-Count")
+ (choice-item "X-Seqno")
+ (choice-item "X-Sequence")
+ (choice-item "Mailinglist-Id")
+ (item "-")
+ (string :tag "Other")))
+ :group 'mu-cite)
+
+(defun mu-cite-get-ml-count-method ()
+ (let ((field-list mu-cite-ml-count-field-list))
+ (catch 'tag
+ (while field-list
+ (let* ((field (car field-list))
+ (ml-count (mu-cite-get-field-value field)))
+ (when (and ml-count (string-match "[0-9]+" ml-count))
+ (throw 'tag
+ (substring ml-count
+ (match-beginning 0)(match-end 0))))
+ (setq field-list (cdr field-list)))))))
+
+
+;;; @@ prefix and registration
+;;;
+
+(defun mu-cite-get-prefix-method ()
+ (or (mu-cite-get-citation-name (mu-cite-get-value 'address))
+ ">"))
+
+(defun mu-cite-get-prefix-register-method ()
+ (let ((addr (mu-cite-get-value 'address)))
+ (or (mu-cite-get-citation-name addr)
+ (let ((return
+ (read-string "Citation name? "
+ (or (mu-cite-get-value 'x-attribution)
+ (mu-cite-get-value 'full-name))
+ 'mu-cite-minibuffer-history)))
+ (when (and (or mu-cite-allow-null-string-registration
+ (not (string-equal return "")))
+ (y-or-n-p (format "Register \"%s\"? " return)))
+ (mu-cite-add-citation-name return addr))
+ return))))
+
+(defun mu-cite-get-prefix-register-verbose-method ()
+ (let* ((addr (mu-cite-get-value 'address))
+ (return1 (mu-cite-get-citation-name addr))
+ (return (read-string "Citation name? "
+ (or return1
+ (mu-cite-get-value 'x-attribution)
+ (mu-cite-get-value 'full-name))
+ 'mu-cite-minibuffer-history)))
+ (when (and (or mu-cite-allow-null-string-registration
+ (not (string-equal return "")))
+ (not (string-equal return return1))
+ (y-or-n-p (format "Register \"%s\"? " return)))
+ (mu-cite-add-citation-name return addr))
+ return))
+
+