aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--module/vcomponent.scm142
-rw-r--r--module/vcomponent/parse.scm76
2 files changed, 112 insertions, 106 deletions
diff --git a/module/vcomponent.scm b/module/vcomponent.scm
index add08775..cb01d1f1 100644
--- a/module/vcomponent.scm
+++ b/module/vcomponent.scm
@@ -78,73 +78,75 @@
(define* (parse-calendar path)
- (let ((root (parse-cal-path path)))
- (let* ((component
- (case (string->symbol (or (attr root "X-HNH-SOURCETYPE") "no-type"))
- ;; == Single ICS file ==
- ;; Remove the abstract ROOT component,
- ;; returning the wanted VCALENDAR component
- ((file)
- ;; TODO test this when an empty file is given.
- (car (children root)))
-
- ;; == Assume vdir ==
- ;; Also removes the abstract ROOT component, but also
- ;; merges all VCALENDAR's children into the a newly
- ;; created VCALENDAR component, and return that component.
- ;;
- ;; TODO the other VCALENDAR components might not get thrown away,
- ;; this since I protect them from the GC in the C code.
- ((vdir)
- (let ((accum (make-vcomponent 'VCALENDAR))
- (ch (children root)))
-
- ;; Copy attributes from our parsed VCALENDAR
- ;; to our newly created one.
- (unless (null? ch)
- (for key in (attributes (car ch))
- (set! (attr accum key) (attr (car ch) key))))
-
- ;; Merge all children
- (let ((tz '()))
- (for cal in ch
- (for component in (children cal)
- (case (type component)
- ((VTIMEZONE)
- ;; (set! tz (cons component tz))
- (unless (find (lambda (o) (and (eq? 'VTIMEZONE (type o))
- (string=? (attr o "TZID")
- (attr component "TZID"))))
- (children accum))
- (add-child! accum component)))
- ((VEVENT)
- (add-child! accum component)
- )
- (else => (lambda (type)
- (format (current-error-port)
- "Got unexpected component of type ~a~%" type))
- #; (add-child! accum component)
- ))))
-
- (unless (null? tz)
- (add-child! accum (car tz)))
- )
- ;; return
- accum))
-
- ((no-type) (error 'no-type)))))
-
- (parse-dates! component)
-
- (unless (attr component "NAME")
- (set! (attr component "NAME")
- (or (attr component "X-WR-CALNAME")
- (attr root "NAME")
- "[NAMELESS]")))
-
- (unless (attr component "COLOR")
- (set! (attr component "COLOR")
- (attr root "COLOR")))
-
- ;; return
- component)))
+ (let ((component (parse-cal-path path)))
+ ;; let*
+ #;
+ ((component
+ (case (string->symbol (or (attr root "X-HNH-SOURCETYPE") "no-type"))
+ ;; == Single ICS file ==
+ ;; Remove the abstract ROOT component,
+ ;; returning the wanted VCALENDAR component
+ ((file)
+ ;; TODO test this when an empty file is given.
+ (car (children root)))
+
+ ;; == Assume vdir ==
+ ;; Also removes the abstract ROOT component, but also
+ ;; merges all VCALENDAR's children into the a newly
+ ;; created VCALENDAR component, and return that component.
+ ;;
+ ;; TODO the other VCALENDAR components might not get thrown away,
+ ;; this since I protect them from the GC in the C code.
+ ((vdir)
+ (let ((accum (make-vcomponent 'VCALENDAR))
+ (ch (children root)))
+
+ ;; Copy attributes from our parsed VCALENDAR
+ ;; to our newly created one.
+ (unless (null? ch)
+ (for key in (attributes (car ch))
+ (set! (attr accum key) (attr (car ch) key))))
+
+ ;; Merge all children
+ (let ((tz '()))
+ (for cal in ch
+ (for component in (children cal)
+ (case (type component)
+ ((VTIMEZONE)
+ ;; (set! tz (cons component tz))
+ (unless (find (lambda (o) (and (eq? 'VTIMEZONE (type o))
+ (string=? (attr o "TZID")
+ (attr component "TZID"))))
+ (children accum))
+ (add-child! accum component)))
+ ((VEVENT)
+ (add-child! accum component)
+ )
+ (else => (lambda (type)
+ (format (current-error-port)
+ "Got unexpected component of type ~a~%" type))
+ #; (add-child! accum component)
+ ))))
+
+ (unless (null? tz)
+ (add-child! accum (car tz)))
+ )
+ ;; return
+ accum))
+
+ ((no-type) (error 'no-type)))))
+
+ (parse-dates! component)
+
+ (unless (attr component "NAME")
+ (set! (attr component "NAME")
+ (or (attr component "X-WR-CALNAME")
+ "[NAMELESS]")))
+
+ #;
+ (unless (attr component "COLOR")
+ (set! (attr component "COLOR")
+ (attr root "COLOR")))
+
+ ;; return
+ component))
diff --git a/module/vcomponent/parse.scm b/module/vcomponent/parse.scm
index f862b18a..29537a5e 100644
--- a/module/vcomponent/parse.scm
+++ b/module/vcomponent/parse.scm
@@ -1,6 +1,7 @@
(define-module (vcomponent parse)
:use-module ((rnrs io ports) :select (get-u8))
:use-module (rnrs bytevectors)
+ :use-module (srfi srfi-1)
:use-module (srfi srfi-9)
:use-module ((ice-9 rdelim) :select (read-line))
:use-module ((ice-9 textual-ports) :select (unget-char))
@@ -11,6 +12,8 @@
:use-module (vcomponent base)
)
+(use-modules ((rnrs base) #:select (assert)))
+
@@ -200,48 +203,49 @@ row ~a column ~a ctx = ~a
-(define-public (read-vcalendar path)
+(define (parse-vdir path)
+ (let ((/ (lambda args (string-join args file-name-separator-string 'infix))))
+ (let ((color
+ (catch 'system-error
+ (lambda () (call-with-input-file (/ path "color") read-line))
+ (const "#FFFFFF")))
+ (name
+ (catch 'system-error
+ (lambda () (call-with-input-file (/ path "displayname") read-line))
+ (const (basename path "/")))))
+
+ (reduce (lambda (item calendar)
+ (assert (eq? 'VCALENDAR (type calendar)))
+ (assert (eq? 'VCALENDAR (type item)))
+ (for child in (children item)
+ (assert (memv (type child) '(VTIMEZONE VEVENT)))
+ (add-child! calendar child))
+ calendar)
+ (make-vcomponent)
+ (map (lambda (fname)
+ (let ((fullname (/ path fname)))
+ (let ((cal (call-with-input-file fullname
+ parse-calendar)))
+ (set! (attr cal 'COLOR) color
+ (attr cal 'NAME) name)
+ cal)))
+ (scandir path (lambda (s) (and (not (string= "." (string-take s 1)))
+ (string= "ics" (string-take-right s 3))))))))))
+
+(define-public (parse-cal-path path)
(define st (stat path))
(case (stat:type st)
- [(regular) (let ((comp (call-with-input-file path parse-calendar)))
- (set! (attr comp 'X-HNH-SOURCETYPE) "file")
- (list comp))]
+ [(regular)
+ (let ((comp (call-with-input-file path parse-calendar)))
+ (set! (attr comp 'X-HNH-SOURCETYPE) "file")
+ comp) ]
[(directory)
-
- (let ((/ (lambda args (string-join args file-name-separator-string 'infix))))
- (let ((color
- (catch 'system-error
- (lambda () (call-with-input-file (/ path "color") read-line))
- (const "#FFFFFF")))
- (name
- (catch 'system-error
- (lambda () (call-with-input-file (/ path "displayname") read-line))
- (const (basename path)))))
-
- (map (lambda (fname)
- (let ((fullname (/ path fname)))
- (let ((cal (call-with-input-file fullname
- parse-calendar)))
- (set! (attr cal 'COLOR) color
- (attr cal 'NAME) name)
- cal)))
- (scandir path (lambda (s) (and (not (string= "." (string-take s 1)))
- (string= "ics" (string-take-right s 3))))))))]
+ (let ((comp (parse-vdir path)))
+ (set! (attr comp 'X-HNH-SOURCETYPE) "vdir")
+ comp)]
[(block-special char-special fifo socket unknown symlink)
=> (lambda (t) (error "Can't parse file of type " t))]))
-
-(define-public (parse-cal-path path)
- (let ((parent (make-vcomponent)))
- (for-each (lambda (child) (add-child! parent child))
- (read-vcalendar path))
- (set! (attr parent 'X-HNH-SOURCETYPE)
- (if (null? (children parent))
- "vdir"
- (or (attr (car (children parent))
- 'X-HNH-SOURCETYPE)
- "vdir")))
- parent))
(define-public (read-tree path)