summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Tuomi <jans.tuomi@gmail.com>2024-03-25 22:48:16 +0200
committerJan Tuomi <jans.tuomi@gmail.com>2024-03-26 21:25:10 +0200
commitf03dcea8d512b661f7f4156367e0ce09ea20f2b0 (patch)
treea43a303cabe18cb6868cfb26745025772b3a44bd
parentc445eb61781c268c7a9c5eb065c9fb4bab03391e (diff)
Initial commit
-rw-r--r--.gitignore3
-rw-r--r--main.scm87
-rw-r--r--template.html111
3 files changed, 201 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..f494f20
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+pages
+out
+
diff --git a/main.scm b/main.scm
new file mode 100644
index 0000000..eb46fad
--- /dev/null
+++ b/main.scm
@@ -0,0 +1,87 @@
+(import (chicken base)
+ (chicken io)
+ (chicken file posix)
+ (chicken file)
+ (chicken string)
+ (chicken pathname)
+ (chicken format)
+ (chicken process-context)
+ (chicken irregex)
+ (chicken process)
+ (matchable))
+
+; utils
+
+(define-syntax @
+ (syntax-rules ()
+ ((_ fn-body expr ...)
+ (lambda (x) (fn-body expr ... x)))))
+
+(define (last lst)
+ (if (null? (cdr lst))
+ (car lst)
+ (last (cdr lst))))
+
+(define (pipe x . fns)
+ (match fns
+ [() x]
+ [(fn . rest) (apply pipe (fn x) rest)]))
+
+(define (flow . fns)
+ (lambda (x) (apply pipe x fns)))
+
+; application
+
+(define src-dir (or (get-environment-variable "SRC_DIR")
+ "pages"))
+(define out-dir (or (get-environment-variable "OUT_DIR")
+ "out"))
+(define template-path (or (get-environment-variable "PANDOC_TEMPLATE")
+ "template.html"))
+
+(define (process-path path)
+ (match path
+ [(? is-md?) (process-md path)]
+ [(? directory?) (process-dir (format "~A" path))]
+ [other (printf "TODO other file ~A~%" path)]))
+
+(define (is-md? path)
+ (define parts (string-split path "."))
+ (string=? "md" (last parts)))
+
+(define (process-md md-path)
+ (define out-html-file (pipe md-path
+ (lambda (p) (irregex-replace (format "^~A" src-dir) p out-dir))
+ (lambda (p) (irregex-replace "\.md$" p ".html"))))
+
+ (define-values (html-dir html-filename html-ext) (decompose-pathname out-html-file))
+ (create-directory html-dir #t)
+ (pandoc-md-to-html md-path out-html-file))
+
+(define (pandoc-md-to-html md-path html-path)
+ (define args (list md-path
+ "-o" html-path
+ "--standalone"
+ "--template" template-path
+ "--highlight-style" "pygments"))
+ (printf "pandoc ~A" args)
+ (process "pandoc" args))
+
+(define (process-dir dir-path)
+ (define out-dir-path (irregex-replace (format "^~A" src-dir) out-dir))
+ (create-directory out-dir-path #t)
+ (define paths (glob (format "~A/*" dir-path)))
+ (define paths (map (lambda (p) (irregex-replace "^\./" p "")) paths))
+ (for-each process-path paths))
+
+(define (clean-dir dir)
+ (define (delete path)
+ (if (directory? path)
+ (delete-directory path #t)
+ (delete-file path)))
+ (for-each (@ delete) (glob (format "~A/*" dir))))
+
+; run
+
+(clean-dir out-dir)
+(process-dir src-dir)
diff --git a/template.html b/template.html
new file mode 100644
index 0000000..d0160cd
--- /dev/null
+++ b/template.html
@@ -0,0 +1,111 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
+<head>
+ <meta charset="utf-8" />
+ <meta name="generator" content="pandoc" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
+$for(author-meta)$
+ <meta name="author" content="$author-meta$" />
+$endfor$
+$if(date-meta)$
+ <meta name="dcterms.date" content="$date-meta$" />
+$endif$
+$if(keywords)$
+ <meta name="keywords" content="$for(keywords)$$keywords$$sep$, $endfor$" />
+$endif$
+$if(description-meta)$
+ <meta name="description" content="$description-meta$" />
+$endif$
+ <title>$if(title-prefix)$$title-prefix$ – $endif$$pagetitle$</title>
+
+ <style>
+ $styles.html()$
+ </style>
+
+ <style>
+@font-face {
+ font-family: 'Merriweather';
+ src: url('/static/Merriweather-Regular.ttf') format('truetype');
+ font-weight: normal;
+ font-style: normal;
+}
+
+@font-face {
+ font-family: 'Merriweather';
+ src: url('/static/Merriweather-Bold.ttf') format('truetype');
+ font-weight: bold;
+ font-style: normal;
+}
+
+@font-face {
+ font-family: 'Merriweather';
+ src: url('/static/Merriweather-Italic.ttf') format('truetype');
+ font-weight: normal;
+ font-style: italic;
+}
+ </style>
+
+ <link rel="stylesheet" href="/static/style.css" />
+ <link rel="alternate"
+ type="application/rss+xml"
+ title="RSS Feed for jan.systems"
+ href="/feed.xml" />
+
+$for(header-includes)$
+ $header-includes$
+$endfor$
+$if(math)$
+$if(mathjax)$
+ <script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
+$endif$
+ $math$
+$endif$
+</head>
+<body>
+ <div class="header-row">
+ <h1><a class="page-title" href="/">jan&#39;s garden</a></h1>
+ <div id="dark-mode-btn"></div>
+ </div>
+ <nav>
+ <a href="/liked">liked</a> &#x2022;
+ <a href="/now">now</a> &#x2022;
+ <a href="/projects">projects</a> &#x2022;
+ <a href="/archive">archive</a>
+ </nav>
+
+$body$
+
+<script>
+document.querySelector("#dark-mode-btn").tagName = "button";
+document.querySelector("#dark-mode-btn").innerHTML = "🌓";
+
+const initialManualColorScheme = localStorage.getItem("colorScheme");
+// If null, no manual color scheme is set
+if (initialManualColorScheme === "dark") {
+ document.body.parentElement.classList.add("dark");
+} else if (initialManualColorScheme === "light") {
+ document.body.parentElement.classList.add("light");
+}
+
+function getCurrentManualColorScheme() {
+ if (document.body.parentElement.classList.contains("dark")) return "dark";
+ if (document.body.parentElement.classList.contains("light")) return "light";
+ return null;
+}
+
+document.querySelector("#dark-mode-btn").addEventListener("click", function () {
+ const manualColorScheme = getCurrentManualColorScheme();
+ const userPreferenceIsDark = (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches);
+
+ const currentColorScheme = manualColorScheme ?? (userPreferenceIsDark ? "dark" : "light");
+ const newColorScheme = currentColorScheme === "dark" ? "light" : "dark";
+
+ document.body.parentElement.classList.remove("dark", "light");
+ document.body.parentElement.classList.add(newColorScheme);
+
+ localStorage.setItem("colorScheme", newColorScheme);
+});
+</script>
+
+</body>
+</html>