aboutsummaryrefslogtreecommitdiff
path: root/email
diff options
context:
space:
mode:
Diffstat (limited to 'email')
-rw-r--r--email/quoted-printable.scm33
1 files changed, 33 insertions, 0 deletions
diff --git a/email/quoted-printable.scm b/email/quoted-printable.scm
index 317bf81..d084a7e 100644
--- a/email/quoted-printable.scm
+++ b/email/quoted-printable.scm
@@ -19,8 +19,11 @@
(define-module (email quoted-printable)
#:use-module (rnrs)
+ #:use-module (ice-9 format)
#:use-module (ice-9 match)
+ #:use-module (srfi srfi-26)
#:export (quoted-printable-decode
+ quoted-printable-encode
q-encoding-decode))
;; TODO: Error out on invalid quoted-printable input
@@ -49,6 +52,36 @@
(else (put-u8 out (char->integer c))
(quoted-printable-decode in out)))))))
+(define quoted-printable-encode
+ (match-lambda*
+ (((? bytevector? bv))
+ (call-with-port (open-bytevector-input-port bv)
+ quoted-printable-encode))
+ (((? port? in))
+ (call-with-output-string
+ (cut quoted-printable-encode in <>)))
+ (((? port? in) (? port? out))
+ (quoted-printable-encode in out 76))
+ (((? port? in) (? port? out) (? integer? number-of-chars-left-on-this-line))
+ (let ((x (get-u8 in))
+ (put-into-output
+ (lambda (str)
+ (let* ((len (string-length str))
+ (break-line? (<= number-of-chars-left-on-this-line len)))
+ (put-string
+ out (string-append (if break-line? "=\n" "") str))
+ (if break-line?
+ (- 76 len)
+ (- number-of-chars-left-on-this-line len))))))
+ (unless (eof-object? x)
+ (let ((c (integer->char x)))
+ (quoted-printable-encode
+ in out
+ (put-into-output
+ (if (char-set-contains?
+ (char-set-delete char-set:ascii #\newline #\return) c)
+ (string c)
+ (format #f "=~:@(~2,'0x~)" x))))))))))
(define (q-encoding-decode str)
(quoted-printable-decode