diff --git a/vcarded.scm b/vcarded.scm index 94e72ab..04434e4 100644 --- a/vcarded.scm +++ b/vcarded.scm @@ -84,9 +84,7 @@ ;; description, but unfortunately I’m coming up empty! =w=, (define (write-vcard vcard-alist #!optional (port (current-output-port))) (for-each (lambda (element) - (write-string (serialize-vcard-element element) #f port) - (write-char #\return port) - (write-char #\newline port)) + (write-folded-line (serialize-vcard-element element))) vcard-alist)) @@ -185,7 +183,7 @@ - ;;; ~ Property-value parsers ~ + ;;; ~ Property-value parsers/serializers ~ ;; List of all properties with semicoloned-structured strings. (define vcard-semicoloned-properties @@ -328,16 +326,37 @@ ;; Reader-thunk. Read a “logical” folded-line, where a line beginning with a ;; space is a continuation of the previous line — like with vcards. - (define (read-folded-line #!optional (limit 100) (port (current-input-port))) - (if (not (eof-object? (peek-char port))) - (let [(line (read-line port limit))] - (if (or (eq? (peek-char port) #\space) - (eq? (peek-char port) #\tab)) - (string-concatenate - (list line - (string-drop (read-folded-line limit port) 1))) - line)) - "")) + ;; LIMIT is the maximum amount of characters it will read before giving up + ;; on finding a newline. + ;; It will default to (current-input-port) as the PORT. + (define (read-folded-line #!optional (limit #f) (port (current-input-port))) + (let [(port (or port (current-input-port)))] + (if (not (eof-object? (peek-char port))) + (let [(line (read-line port limit))] + (if (or (eq? (peek-char port) #\space) + (eq? (peek-char port) #\tab)) + (string-concatenate + (list line + (string-drop (read-folded-line limit port) 1))) + line)) + ""))) + + + ;; Write a line to a port as a “logical” folded-line string, in the style of + ;; vCard and vCalendar. If the line is too long (passed FOLD-LENGTH [70]), it + ;; will be written as several lines of FOLD-LENGTH, with each such line + ;; prepended by the CREASE-CHAR (#\tab). + ;; It will default to (current-output-port), if PORT is #f or unspecified. + (define (write-folded-line string #!optional + (port (current-output-port)) + (fold-length 70) + (crease-char #\tab)) + (write-string + (string-concatenate + (list (string-join (string-split-by-lengths string fold-length) + (list->string (list #\return #\newline crease-char))) + (list->string '(#\return #\newline)))) + #f (or port (current-output-port)))) ;; Split a STRING into strings of a size of (at most) LENGTH signs.