chicken-vcarded/vcarded.scm

80 lines
2.4 KiB
Scheme
Raw Normal View History

2024-02-05 11:24:30 -06:00
;; Copyright © 2024 Jaidyn Ann <jadedctrl@posteo.at>
;;
;; This program is free software: you can redistribute it and/or
;; modify it under the terms of the GNU General Public License as
;; published by the Free Software Foundation, either version 3 of
;; the License, or (at your option) any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
2024-02-05 21:02:24 -06:00
2024-02-05 11:24:30 -06:00
(import
scheme
(chicken io)
(chicken irregex)
2024-02-05 21:02:24 -06:00
srfi-1
srfi-130)
;; Splits a string into a list of CRLFd lines.
(define (unlines lines)
(string-join lines "\r\n"))
2024-02-05 11:24:30 -06:00
;; Splits a string into a list of CRLFd lines.
(define (lines string)
(remove string-null? (string-split string "\r\n")))
;; Create irregx-format regex for matching an unescaped character.
(define (regex-unescaped-char char-string)
`(: (neg-look-behind "\\") ,char-string))
;; Splits a line into a list of key/value pairs.
(define (split-vcard-line line)
2024-02-05 21:02:24 -06:00
(let [(split (irregex-split (regex-unescaped-char ":") line))]
2024-02-05 11:24:30 -06:00
(if (>= (length split) 2)
(cons
(car split)
2024-02-05 21:02:24 -06:00
(reduce-right
(lambda (a b) (string-concatenate (list a ":" b)))
"" (cdr split)))
2024-02-05 11:24:30 -06:00
#f)))
;; Splits a key or value-element into its (potentially multiple) parameters.
(define (split-vcard-element key-or-value)
2024-02-05 21:02:24 -06:00
(irregex-extract "(\\\\;|[^;])*" key-or-value))
(define (parse-vcard-element kv-pair)
(case (car kv-pair)
('VERSION
(append (list (car kv-pair) (string->number (second kv-pair)))
(cddr kv-pair)))
(else kv-pair)))
2024-02-05 11:24:30 -06:00
;; Parse a line of a vcard file into an alist-friendly format:
;; (KEY ("keyprop1=d" "keyprop2=b") "VALUE" ("valprop1=a" "valprop2=b"))
(define (parse-vcard-line line)
2024-02-05 21:02:24 -06:00
(let* [(key-value-strings (split-vcard-line line))
(key-elements (split-vcard-element (car key-value-strings)))
(value-elements (split-vcard-element (cdr key-value-strings)))]
2024-02-05 11:24:30 -06:00
(list (string->symbol (car key-elements))
(car value-elements)
2024-02-05 21:02:24 -06:00
(cdr key-elements)
2024-02-05 11:24:30 -06:00
(cdr value-elements))))
2024-02-05 21:02:24 -06:00
(define (vcard-string->alist string)
(map parse-vcard-line (lines string)))