;;; dot.emacs --- sample init file for MU-CITE  -*-mode: emacs-lisp;-*-

;; for Wanderlust, MH-E, etc.
(add-hook 'mail-citation-hook 'mu-cite-original)
;; for Gnus
(setq message-cite-function 'mu-cite-original)
;; for Mew
(add-hook 'mew-cite-hook
	  (lambda ()
	    (mu-cite-original)
	    (exchange-point-and-mark) ;; for highlighting
	    ))
(setq mew-summary-reply-with-citation-position 'body)

;; for citation with "> " instead of "name> "
(setq mu-cite-prefix-format '("> "))
(setq mu-cite-cited-prefix-regexp nil)

;; for citation header with date and from, e.g.
;;     On Mon, 05 Oct 2020 17:03:31 +0900,
;;     Full Name <user@example.net> wrote:
(setq mu-cite-top-format '("On " date ",\n" from " wrote:\n"))
;;     On October 5, 2020, Full Name wrote:
;;     On September 24, 2020, user (at example.net) wrote:
(setq mu-cite-top-format '("On " my-us-date ", " my-full-name-or-address " wrote:\n"))
;;     On October 5, 2020, at 5:03 p.m., Full Name wrote:
;;     On September 24, 2020, at 12:27 a.m., user (at example.net) wrote:
(setq mu-cite-top-format '("On " my-us-date-at-time ", " my-full-name-or-address " wrote:\n"))
;;     On 2020-10-05 at 17:03 +0900, [mailing-list:12345], Full Name wrote:
;;     On 2020-09-24 at 00:27 +0900, user (at example.net) wrote:
(setq mu-cite-top-format '("On " my-iso-date-at-time ", " my-list-label my-full-name-or-address " wrote:\n"))

;; for my-* methods
(add-hook 'mu-cite-instantiation-hook 'my-mu-cite-set-methods)
(defun my-mu-cite-set-methods ()
  (add-to-list
   'mu-cite-methods-alist
   (cons
    'my-us-date ;; e.g. "October 5, 2020"
    (lambda ()
      (let ((dt (mu-cite-get-value 'date))
	    pdt y m d)
	(when dt
	  (setq pdt (timezone-parse-date dt))
	  (setq y (string-to-number (aref pdt 0)))
	  (setq m (string-to-number (aref pdt 1)))
	  (setq d (string-to-number (aref pdt 2))))
	(if (and dt (> y 0) (> m 0) (< m 13) (> d 0))
	    (format "%s %d, %d"
		    (aref ["January" "February" "March" "April" "May"
			   "June" "July" "August" "September" "October"
			   "November" "December"] (1- m)) d y)
	  (or dt "one day"))))))
  (add-to-list
   'mu-cite-methods-alist
   (cons
    'my-us-date-at-time ;; e.g. "October 5, 2020, at 5:03 p.m."
    (lambda ()
      (let ((dt (mu-cite-get-value 'date))
	    pdt y m d time hour min ampm zone)
	(when dt
	  (setq pdt (timezone-parse-date dt))
	  (setq y (string-to-number (aref pdt 0)))
	  (setq m (string-to-number (aref pdt 1)))
	  (setq d (string-to-number (aref pdt 2)))
	  (setq time (aref pdt 3))
;;;	  (setq zone (or (aref pdt 4) ""))
;;;	  (when (string= zone (format-time-string "%z" (current-time))) ;; omit current timezone
;;;	    (setq zone ""))
	  (when (string-match "^\\([0-9][0-9]?\\):\\([0-9][0-9]?\\)" time)
	    (setq hour (string-to-number (match-string 1 time)))
	    (setq min (string-to-number (match-string 2 time)))
	    (setq ampm "")
	    (if (< hour 12)
		(setq ampm " a.m.")
	      (when (< hour 24)
		(setq ampm " p.m.")
		(setq hour (- hour 12))))
	    (when (= hour 0)
	      (setq hour 12))
	    (setq time (format "%d:%02d%s%s" hour min ampm
			       (if (> (length zone) 0) (concat " " zone) "")))))
	(if (and dt (> y 0) (> m 0) (< m 13) (> d 0) (> (length time) 1))
	    (format "%s %d, %d, at %s"
		    (aref ["January" "February" "March" "April" "May"
			   "June" "July" "August" "September" "October"
			   "November" "December"] (1- m)) d y time)
	  (or dt "one day"))))))
  (add-to-list
   'mu-cite-methods-alist
   (cons
    'my-iso-date-at-time ;; e.g. "2020-10-05 at 17:03 +0900"
    (lambda ()
      (let ((dt (mu-cite-get-value 'date))
	    pdt y m d time zone)
	(when dt
	  (setq pdt (timezone-parse-date dt))
	  (setq y (string-to-number (aref pdt 0)))
	  (setq m (string-to-number (aref pdt 1)))
	  (setq d (string-to-number (aref pdt 2)))
	  (setq time (aref pdt 3))
	  (setq zone (or (aref pdt 4) ""))
;;;	  (when (string= zone (format-time-string "%z" (current-time))) ;; omit current timezone
;;;	    (setq zone ""))
	  (when (string-match "^\\([0-9][0-9]?\\):\\([0-9][0-9]?\\)" time)
	    (setq time (format "%02d:%02d"
			       (string-to-number (match-string 1 time))
			       (string-to-number (match-string 2 time))))))
	(if (and dt (> y 0) (> m 0) (< m 13) (> d 0) (> (length time) 1))
	    (format "%d-%02d-%02d at %s%s" y m d time
		    (if (> (length zone) 0) (concat " " zone) ""))
	  (or dt "one day"))))))
  (add-to-list
   'mu-cite-methods-alist
   (cons
    'my-list-label ;; e.g. "[mailing-list:12345], "
    (lambda ()
      (let ((subj (mu-cite-get-value 'subject))
	    ml-name ml-count)
	(if (and subj
		 (or (string-match "^\\[[a-zA-Z0-9._-]+[ :,] ?[0-9]+\\]" subj)
		     (string-match "^([a-zA-Z0-9._-]+[ :,] ?[0-9]+)" subj)))
	    (concat (match-string 0 subj) ", ")
	  (setq ml-name (mu-cite-get-field-value "X-ML-Info"))
	  (if (and ml-name (string-match ".*help=" ml-name))
	      (setq ml-name (replace-match "" nil t ml-name))
	    (setq ml-name nil))
	  (if (and ml-name (string-match "-ctl@" ml-name))
	      (setq ml-name (replace-match "@" nil t ml-name))
	    (setq ml-name nil))
	  (when (null ml-name)
	    (setq ml-name (mu-cite-get-field-value "List-Post")))
	  (if (and ml-name (string-match ".*mailto:" ml-name))
	      (setq ml-name (replace-match "" nil t ml-name))
	    (setq ml-name nil))
	  (if (and ml-name (string-match "@.*" ml-name))
	      (setq ml-name (replace-match "" nil t ml-name))
	    (setq ml-name nil))
	  (when (null ml-name)
	    (setq ml-name (mu-cite-get-value 'ml-name)))
	  (when (and ml-name (> (length ml-name) 30)) ;; avoid long name
	    (setq ml-name nil))
	  (setq ml-count (mu-cite-get-value 'ml-count))
	  (and ml-name ml-count (concat "[" ml-name ":" ml-count "], ")) ;; ml-name and ml-count
;;;	  (and ml-name (concat "[" ml-name (if ml-count ":") ml-count "], ")) ;; allow without ml-count
	  )))))
  (add-to-list
   'mu-cite-methods-alist
   (cons
    'my-full-name-or-address ;; e.g. "Full Name" or "user (at example.net)"
    (lambda ()
      (let ((name (mu-cite-get-value 'full-name))
	    adr)
	(when (and name (string-match "[ \t]+via[ \t].*" name)) ;; remove " via ..."
	  (setq name (replace-match "" nil t name)))
	(when (and name (> (length name) 30)) ;; avoid long name
	  (setq name nil))
;;;	(when (and name (string-match "[^\0-\577]" name)) ;; avoid CJK, accept Latin
;;;	  (setq name nil))
;;;	(when (and name (string-match "[^\0-\177]" name)) ;; avoid non-ASCII
;;;	  (setq name nil))
	(when (null name) ;; fallback to 'address
	  (setq adr (mu-cite-get-value 'address))
	  (when (and adr (string-match "@" adr))
	    (setq name (concat (replace-match " (at " nil t adr) ")"))))
	(when (null name) ;; fallback to 'from
	  (setq name (mu-cite-get-value 'from)))
	(when name
	  (while (string-match "@" name)
	    (setq name (replace-match "[at]" nil t name))))
	(or name "someone"))))))

;;; dot.emacs ends here
