From 4e322c636bbc3e8064342931fe604bc6ddbe5f4e Mon Sep 17 00:00:00 2001 From: Jan Tuomi Date: Tue, 6 Feb 2024 16:26:36 +0200 Subject: Implement basic site generation from .md --- app.scm | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ article.md | 42 ++++++++++++++++++++++++++ index.html | 80 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 222 insertions(+) create mode 100644 app.scm create mode 100644 article.md create mode 100644 index.html diff --git a/app.scm b/app.scm new file mode 100644 index 0000000..7b22dbf --- /dev/null +++ b/app.scm @@ -0,0 +1,100 @@ +(import (chicken base) + utf8 + spiffy + nrepl + srfi-18 + (chicken file) + (chicken io) + (chicken port) + (chicken format) + (chicken pretty-print) + lowdown + sxml-transforms + matchable + (chicken irregex) + shell + srfi-13 + intarweb + html-parser) + +(define (pipe x . fns) + (match fns + [() x] + [(fn . rest) (apply pipe (fn x) rest)])) + +;; Convenience macro (@ expr ...) that expands to (lambda (x) (expr ... x)) +(define-syntax @ + (syntax-rules () + ((_ fn-body expr ...) + (lambda (x) (fn-body expr ... x))))) + +(define (replace from to str) + (irregex-replace/all from str to)) + +(define (html-unescape html) + (pipe html + (@ replace """ "\"") + (@ replace "'" "'") + (@ replace "&" "&") + (@ replace "<" "<") + (@ replace ">" ">"))) + +(define (highlight ext code) + (define tmp-file-path (create-temporary-file ext)) + (with-output-to-file tmp-file-path + (lambda () (display code))) + (define result (capture ,(format "highlight ~A -O html -f" tmp-file-path))) + (delete-file tmp-file-path) + result) + +(define (replace-code-block content return) + (define irx (irregex "^%lang (\\S+)%\\n?" 's)) + (define lang-match + (irregex-search irx content)) + (if (not lang-match) + (return content)) + + (define lang + (irregex-match-substring lang-match 1)) + + (pipe content + (@ replace irx "") + (@ html-unescape) + (@ highlight lang) + (@ string-trim-both))) + +(define (convert-md-to-html filepath) + (with-output-to-string + (lambda () (markdown->html (open-input-file filepath))))) + +(define (highlight-code-blocks html) + (define (highlight-match m) + (format "~A" + (call/cc (@ replace-code-block (irregex-match-substring m 1))))) + + (irregex-replace/all (irregex "(.*?)" 's) html + highlight-match)) + +(define (insert-to-page-tmpl tmpl-path html) + (format (read-string #f (open-input-file tmpl-path)) + html)) + +(define (app c) + (define html-text + (pipe "article.md" + (@ convert-md-to-html) + (@ highlight-code-blocks) + (@ insert-to-page-tmpl "index.html"))) + + (send-response body: html-text + headers: '((content-type #(text/html ((charset . utf-8))))))) + +(thread-start! + (lambda () + (print "starting nrepl on port 1234") + (nrepl-prompt (lambda () (display "#;0> "))) + (nrepl 1234))) + +(vhost-map `((".*" . ,(lambda (c) (app c))))) + +(start-server) diff --git a/article.md b/article.md new file mode 100644 index 0000000..bc0d9db --- /dev/null +++ b/article.md @@ -0,0 +1,42 @@ +# Article title + +Some text + +[Link text](http://example.com) + +Paragraph with inline _Python code_: `%lang py% import foo`, wonder what this looks like. + +## Subtitle + + %lang c% + int main() { + return 0; + } + +### Let's try a Lisp + + %lang scm% + (define foo (+ 1 2 3 4)) + +### And Rust + + %lang rs% + const STARTING_MISSILES: i32 = 8; + const READY_AMOUNT: i32 = 2; + + fn main() { + let mut missiles: i32 = STARTING_MISSILES; + let ready: i32 = READY_AMOUNT; + println!("Firing {} of my {} missiles...", ready, missiles); + missiles = missiles - ready; + println!("{} missiles left", missiles); + } + +## client side jäsä (juuso commission) + + %lang js% + alert("beenis"); + +> This is a quote +> +> > Alas poor Yorick diff --git a/index.html b/index.html new file mode 100644 index 0000000..b1e4892 --- /dev/null +++ b/index.html @@ -0,0 +1,80 @@ + + + + Test + + + + + + + + ~A + + -- cgit v1.3