aboutsummaryrefslogtreecommitdiff
path: root/module/vcomponent/parse/new.scm
blob: 46660a9fea7686d18ef8c0baa3954ad809511089 (plain)
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
(define-module (vcomponent parse new)
  :use-module (util)
  :use-module ((ice-9 rdelim) :select (read-line))
  :use-module (vcomponent base)
 )


;; (define f (open-input-file (car (glob "~/.local/var/cal/Calendar/c17*"))))
;; (parse (map tokenize (read-file file)))

;; port → (list string)
(define (read-file port)
 (let loop ((done '()))
   (let ((line (read-line port)))
     (if (eof-object? line)
         (reverse! done)
         (loop
          (if (char=? #\space (string-ref line 0))
              (cons (string-append (car done)
                                   (string-drop line 1))
                    (cdr done))
              (cons line done)))))))

;; (list string) → (list (key kv ... value))
(define (tokenize line)
  (define colon-idx (string-index line #\:))
  (define semi-idxs
    (let loop ((idx 0))
      (aif (string-index line #\; idx colon-idx)
           (cons it (loop (1+ it)))
           (list colon-idx (string-length line)))))
  (map (lambda (start end)
         (substring line (1+ start) end))
       (cons -1 semi-idxs)
       semi-idxs))


;; (parse-itemline '("DTEND" "TZID=Europe/Stockholm" "VALUE=DATE-TIME" "20200407T130000"))
;; ⇒ #<<vline> value: "20200407T130000" parameters: #<hash-table 7f4294c913a0 2/31>>
(define (parse-itemline itemline)
  (define all
    (reverse
     (let loop ((rem (cdr itemline)))
       (if (null? (cdr rem))
           rem                             ; (list (car rem))
           (let* ((kv (car rem))
                  (idx (string-index kv #\=)))
             (cons (cons (string->symbol (substring kv 0 idx))
                         ;; NOTE handle value parsing here?
                         (substring kv (1+ idx)))
                   (loop (cdr rem))))))))

  (make-vline% (car all) (alist->hashq-table (cdr all))))



(use-modules (srfi srfi-9))
(define-record-type <component>
  (make-component% type children attributes parent)
  component?
  (type type)
  (children children)
  (attributes attributes))

(define (make-component args)
  (let* ((type (car args))
         (children attributes (partition component? (cdr args))))
    (make-component% type children attributes)))

;; (list (key kv ... value)) → <vcomponent>
(define (parse lst)
  (let loop ((lst lst)
             (stack '()))
    (if (null? lst)
        stack
        (let ((head (car lst)))
          (cond [(string=? "BEGIN" (car head))
                 (loop (cdr lst) (cons (list (string->symbol (cadr head))) stack))]
                [(string=? "END" (car head))
                 (loop (cdr lst)
                       (let* ((frame (reverse (car stack)))
                              (component (make-component frame)))
                         (if (null? (cdr stack))
                             component
                             (cons (cons component (cadr stack))
                                   (cddr stack)))))]
                [else
                 (loop (cdr lst)
                       (cons (cons (parse-itemline head)
                                   (car stack))
                             (cdr stack)))])))))