Files
gem300/gem300.rkt
2025-09-04 15:22:36 -07:00

68 lines
1.8 KiB
Racket

#lang racket
(require (prefix-in net: "net.rkt")
(prefix-in gmi: "gmi.rkt"))
;; global state variable which will be an input port containing the
;; rendered out gemtext document as it shall be shown to the user
(define document-buffer null)
;; global state which will be the document structure, before rendering
(define document null)
(define (go-cmd url)
(if (non-empty-string? url)
(let-values ([(status meta c-in) (net:get url)])
(let-values ([(doc) (gmi:parse (port->lines c-in))]
[(db-in db-out) (make-pipe #f)])
(set! document doc)
(set! document-buffer db-in)
(parameterize ([current-output-port db-out])
(gmi:render doc))
(let ([remaining (pipe-content-length db-in)])
(printf "document retrieved. ~a bytes\n" remaining))
(next-cmd)))
(displayln "go where?")))
(define (next-cmd)
(define (iter depth)
(when (> depth 0)
(let ()
(displayln (read-line document-buffer))
(iter (sub1 depth)))))
(iter 10)
(newline)
(let ([remaining (pipe-content-length document-buffer)])
(printf "~a bytes remaining\n" remaining)))
(define (visit-cmd line)
(go-cmd (gmi:match-link document (string->number line))))
(define (repl)
(display "G-300 > ")
(let ([matches (regexp-match #px"(\\w+)\\s*(.*)" (read-line))])
(cond
;; next command. also default
[(or (not matches)
(string=? (cadr matches) "next")
(string=? (cadr matches) "n"))
(next-cmd)]
;; go command
[(or (string=? (cadr matches) "go")
(string=? (cadr matches) "g"))
(go-cmd (caddr matches))]
;; visit link command
[(andmap char-numeric? (string->list (cadr matches)))
(visit-cmd (cadr matches))]))
(repl))