about summary refs log tree commit diff stats
path: root/lib/read.scm
diff options
context:
space:
mode:
authorCase Duckworth2024-06-05 09:21:25 -0500
committerCase Duckworth2024-06-05 09:21:25 -0500
commit423ac382f9e73bf1ca7fc6b400f98db087cd7d22 (patch)
tree1992e3dc7e71cd40eb7cdbc0b6d0c3cdf82c4332 /lib/read.scm
parentUpdate README, add COPYING (diff)
downloadjimmy-423ac382f9e73bf1ca7fc6b400f98db087cd7d22.tar.gz
jimmy-423ac382f9e73bf1ca7fc6b400f98db087cd7d22.zip
Write executable
This involved moving `src' to `lib' and making `bin'.
`bin' holds the program, which only imports `jimmy.main' from lib.
Diffstat (limited to 'lib/read.scm')
-rw-r--r--lib/read.scm88
1 files changed, 88 insertions, 0 deletions
diff --git a/lib/read.scm b/lib/read.scm new file mode 100644 index 0000000..1b611bb --- /dev/null +++ b/lib/read.scm
@@ -0,0 +1,88 @@
1(declare (module (jimmy read)))
2
3(import scheme (chicken base)
4 (jimmy util)
5 (only (chicken io) read-lines)
6 (only (chicken string) string-split))
7
8(define-public line-types
9 ;; (sigil type inlines word-select)
10 `((default para (link) ,identity) ; if nothing else matches
11 ("```" verb)
12 ("=>" link)
13 (">" quot)
14 ("#" hdr1)
15 ("##" hdr2)
16 ("###" hdr3)
17 ("*" list)
18 ;; extra!
19 (":" meta)))
20
21(define-public (parse #!optional port)
22 (parse-lines (read-lines (or port (current-input-port))) '()))
23
24(define (line-type line)
25 (let ((lin (if (string? line) (string-split line) line))
26 (def (cdr (assoc 'default line-types))))
27 (cond
28 ((null? lin) def) ; empty line
29 ((assoc (car lin) line-types) => cdr) ; a line type exists
30 (else def)))) ; otherwise ...
31
32(define (parse-lines lines doc)
33 (if (null? lines) (reverse doc)
34 (let ((words (string-split (car lines))))
35 (cond
36 ((null? words) ; empty line
37 (parse-lines (cdr lines) doc))
38 ((equal? (car words) "```") ; verbatim
39 ;; Format for verbatim header:
40 ;; ``` ?html | command ...
41 ;; -- only run command on block with html output.
42 ;; other outputs process the block normally
43 ;; ``` ?!html | command ...
44 ;; -- only run command on block when *not* outputting html.
45 ;; html processes the block normally
46 ;; ``` ?:html | command ...
47 ;; -- like ?html, but ignore the block in non-html outputs.
48 ;;;; FIXME: I think this necessitates a special emit-verbatim
49 ;;;; function.
50 (parse-verbatim (cdr lines) doc '()
51 #; (if (< 1 (length words))
52 (cons 'verb (cdr words))
53 'verb)
54 'verb))
55 (else ; another line type
56 (apply parse-stanza lines doc '() (line-type words)))))))
57
58(define (parse-verbatim lines doc block bhead)
59 (define (close-verbatim) (cons (cons bhead (reverse block)) doc))
60 (cond
61 ((null? lines) ; end of document
62 (parse-lines lines (close-verbatim)))
63 ((equal? (car lines) "```") ; end of verbatim block
64 (parse-lines (cdr lines) (close-verbatim)))
65 (else ; verbatim block continues
66 (parse-verbatim (cdr lines) doc (cons (list (car lines)) block) bhead))))
67
68(define (parse-stanza lines doc stanza st-type
69 #!optional (st-inlines '()) (st-words cdr))
70 (define (close-stanza) (cons (cons st-type (reverse stanza)) doc))
71 (if (null? lines) ; end of document
72 (parse-lines lines (close-stanza))
73 (let* ((ln (car lines))
74 (ws (string-split ln))
75 (lt (line-type ln)))
76 (cond
77 ((null? ws) ; end of stanza (blank line)
78 (parse-lines (cdr lines) (close-stanza)))
79 ((memq (car lt) st-inlines) ; in-line for *this* stanza
80 (parse-stanza (cdr lines) doc
81 (cons (cons (car lt) (cdr ws)) stanza)
82 st-type st-inlines st-words))
83 ((not (eq? st-type (car (line-type ws)))) ; beginning of a new stanza
84 (parse-lines lines (close-stanza)))
85 (else ; continue this stanza
86 (parse-stanza (cdr lines) doc
87 (cons (st-words ws) stanza)
88 st-type st-inlines st-words))))))