implement primitive and bare minimum gemtext parsing
This commit is contained in:
77
gem300.rkt
77
gem300.rkt
@@ -3,6 +3,83 @@
|
||||
(require openssl)
|
||||
(require net/url)
|
||||
|
||||
(struct text (str))
|
||||
(struct link (url str))
|
||||
(struct preformatted (str))
|
||||
|
||||
(define (parse-url line)
|
||||
(let ([split (string-split (substring line 2))])
|
||||
;; there are necessarily at least two elements
|
||||
;; in the split (the => and the URL) otherwise
|
||||
;; its just text.
|
||||
(if (>= (length split) 2)
|
||||
(link (second split)
|
||||
;; if there are at least three elements in the split,
|
||||
;; that means that everything after the URL is text.
|
||||
(if (>= (length split) 3)
|
||||
(string-join (drop split 2))
|
||||
#f))
|
||||
(text line))))
|
||||
|
||||
|
||||
(define (gemtext-parse lines)
|
||||
(define (iter document lines state)
|
||||
;; when there are no more lines, we have finished parsing.
|
||||
(if (empty? lines)
|
||||
document
|
||||
|
||||
;; otherwise, we have a state machine to traverse.
|
||||
(cond
|
||||
;; turn off preformatted mode
|
||||
[(and (symbol=? 'preformatted state)
|
||||
(or (empty? (cdr lines))
|
||||
(string-prefix? (car lines) "```")))
|
||||
|
||||
(iter document
|
||||
(cdr lines)
|
||||
'normal)]
|
||||
|
||||
;; add line to most recent preformat block
|
||||
[(symbol=? 'preformatted state)
|
||||
(if (preformatted? (car document))
|
||||
;; little bit hard to follow: take the existing
|
||||
;; preformatted blocks content, cons the new line;
|
||||
;; then, cons the new preformatted block to the cdr of
|
||||
;; the document
|
||||
(iter (cons (preformatted (cons (car lines)
|
||||
(preformatted-str (car document))))
|
||||
(cdr document))
|
||||
(cdr lines)
|
||||
'preformatted)
|
||||
|
||||
(iter (cons (preformatted (list)) document)
|
||||
(cdr lines)
|
||||
'preformatted))]
|
||||
|
||||
;; rest of this is normal mode
|
||||
|
||||
;; link lines
|
||||
[(string-prefix? (car lines) "=>")
|
||||
(iter (cons (parse-url (car lines))
|
||||
document)
|
||||
(cdr lines)
|
||||
'normal)]
|
||||
|
||||
;; preformatting toggle lines
|
||||
[(string-prefix? (car lines) "```")
|
||||
;; add preformatted block to document and toggle mode
|
||||
(iter document
|
||||
(cdr lines)
|
||||
'preformatted)]
|
||||
|
||||
[else
|
||||
(iter (cons (text (car lines))
|
||||
document)
|
||||
(cdr lines)
|
||||
'normal)])))
|
||||
|
||||
(displayln (iter (list) lines 'normal)))
|
||||
|
||||
(define (request url-str)
|
||||
(define url (string->url url-str))
|
||||
(define-values (c-in c-out)
|
||||
|
Reference in New Issue
Block a user