Comment detail

日本語メールのエンコード (Nested Flatten)
quick&dirtyバージョンです。
ロバストにやろうとすると結構面倒なので、やはりまとまったライブラリが欲しいところですね。
(差し込みデータに改行や不正文字が入っていた場合とか、ヘッダ行が長すぎる場合に適切に折り返したりとか)

実行はこんな感じで。
(define *template* "From: [[from]]
To: [[to]]
Subject: [[name]]さんにメッセージが届いています。

[[name]]さんに[[fromname]]さんからメッセージが届いています。
以下のURLからアクセスできます。
[[url]]"
)

(define *bindings* '(("from"     . "from@example.org")
                     ("to"       . "to@example.org")
                     ("name"     . "どう書く")
                     ("fromname" . "管理者")
                     ("url"      . "http://ja.doukaku.org/")))

(display (prepare-message (apply-template *template* *bindings*)))
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
(use rfc.822)
(use rfc.base64)
(use util.list)
(use gauche.charconv)
(use srfi-13)
(use srfi-19)
(use srfi-27)

(define (apply-template tmpl bindings)
  (regexp-replace-all #/\[\[(\w+)\]\]/ tmpl
                      (lambda (m) (assoc-ref bindings (m 1) (m 0)))))

(define (rfc2047-encode s)
  (if (= (string-length s) (string-size s))
    s
    (format "=?ISO-2022-JP?B?~a?="
            (base64-encode-string (ces-convert s #f 'iso-2022-jp)))))

(define (prepare-message input)
  (call-with-string-io input
    (lambda (in out)
      (let* ((now     (current-date))
             (hdrs    (append (rfc822-header->list in)
                              `(("message-id"
                                 ,(format "<~a.~a@example.org>"
                                          (sys-getpid) (date-nanosecond now)))
                                ("date"
                                 ,(date->string now "~a, ~e ~b ~Y ~T ~z"))))))
        (dolist (hdr hdrs)
          (format out "~a: ~a\n" (string-titlecase (car hdr)) (rfc2047-encode (cadr hdr))))
        (newline out)
        (let1 cout (wrap-with-output-conversion out 'iso-2022-jp)
          (copy-port in cout)
          (newline cout)
          (close-output-port cout))))))

Index

Feed

Other

Link

Pathtraq

loading...