This is the first useful thing I've written in Racket, converting simple gemtext to html.
My aim in using gemtext is to pare down what I write so that I don't get bogged down with how things look, or think about any audience other than myself.
cobblers.rkt:
#! /usr/bin/env racket #lang racket (require racket/cmdline) (require racket/file) (require string-util) (require gemtext) (define (transform-url url-string) (regexp-replace #rx".gmi" url-string ".html")) (define (sanitize-text text) (let* ((text (regexp-replace* #rx"&" text "\\&")) (text (regexp-replace* #rx"<" text "\\<")) (text (regexp-replace* #rx">" text "\\>"))) text)) (define (gmi-heading->html element) (let ((level (gmi-heading-level element)) (text (gmi-heading-text element))) (format "<h~a>~a</h~a>\n" level (sanitize-text text) level))) (define (gmi-link->html element) (let ((url (gmi-link-url element)) (text (gmi-link-text element))) (format "<a href='~a'>~a</a><br/>\n" (transform-url url) (sanitize-text text)))) (define (gmi-list->html elements) (format "<ul>\n~a</ul>\n" (apply string-append (for/list ((element (gmi-list-items elements))) (format "<li>~a</li>\n" (sanitize-text element)))))) (define (gmi-blockquote->html element) (format "<blockquote>~a</blockquote>\n" (sanitize-text (gmi-blockquote-body element)))) (define (gmi-pre->html elements) (format "<pre>\n~a</pre>\n" (apply string-append (for/list ((element (gmi-pre-body elements))) (format "~a\n" (sanitize-text element)))))) (define (gmi->html gmi-elements) (format (string-append (file->string "./template/prelude.html") "~a" (file->string "./template/postlude.html")) (apply string-append (for/list ((element gmi-elements)) (cond ((gmi-heading? element) (gmi-heading->html element)) ((gmi-link? element) (gmi-link->html element)) ((gmi-list? element) (gmi-list->html element)) ((gmi-blockquote? element) (gmi-blockquote->html element)) ((gmi-pre? element) (gmi-pre->html element)) ((string? element) (if (string=? element "") "" (format "<p>~a</p>\n" (sanitize-text element)))) (else "")))))) (define (main) (command-line #:args (input-file-name output-file-name) (display-to-file (gmi->html (string->gmi (file->string input-file-name))) output-file-name #:exists 'replace))) (main)
That does the conversion for a single file, so then I use make to automate the process of building, and publishing, the site.
Makefile:
GMI_FILES = $(shell find gemini/ -type f -name '*.gmi') HTML_FILES = $(patsubst gemini/%.gmi, website/%.html, $(GMI_FILES)) build: $(HTML_FILES) website/style.css all: clean build publish website/%.html: gemini/%.gmi @mkdir -p "$(@D)" $(CURDIR)/cobblers.rkt "$<" "$@" website/style.css: template/style.css @cp template/style.css website/style.css clean: rm -rf website/* publish: rsync -a --delete-after website/ monospod@tty.sdf.org:html/
... and it's "Cobblers", because it's both cobbled together, and a comment on what I'm sure I'll be writing.