add static site generator
This commit is contained in:
9
www/build.sh
Executable file
9
www/build.sh
Executable file
@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
(cd src; hy build.hy)
|
||||
mkdir -p site/{html,assets,scripts}
|
||||
cp -r src/output/* site/html
|
||||
echo 'html generated'
|
||||
cp -r src/scripts site/
|
||||
echo 'scripts copied'
|
||||
cp -r src/assets site/
|
||||
echo 'assets copied'
|
30
www/src/build.hy
Normal file
30
www/src/build.hy
Normal file
@ -0,0 +1,30 @@
|
||||
(import glob [glob])
|
||||
(import os [mkdir])
|
||||
(import os.path [isfile :as file? isdir :as dir?])
|
||||
(import templates *)
|
||||
(import utils *)
|
||||
|
||||
(require hyrule.control [defmain])
|
||||
|
||||
(defmain []
|
||||
(when (not (dir? "output"))
|
||||
(mkdir "output"))
|
||||
|
||||
(for [path (glob "./pages/**/*" :recursive True)]
|
||||
(when (in "__pycache__" path)
|
||||
(continue))
|
||||
|
||||
(cond
|
||||
(and (dir? path) (not (dir? (.replace path "pages" "output"))))
|
||||
(do
|
||||
(print f"creating {path}")
|
||||
(mkdir (.replace path "pages" "output")))
|
||||
|
||||
(file? path)
|
||||
(do
|
||||
(print f"building {path}")
|
||||
(setv page-name (.split (cut path 2 -3) "/"))
|
||||
(with [target (open (+ "./output/" (.join "/" (cut page-name 1 None)) ".html") "w")]
|
||||
(.write target (form->html
|
||||
(hy.eval (hy.read (with [source (open path "r")]
|
||||
(.read source)))))))))))
|
5
www/src/templates/__init__.hy
Normal file
5
www/src/templates/__init__.hy
Normal file
@ -0,0 +1,5 @@
|
||||
(import .footer [footer])
|
||||
(import .header [header])
|
||||
(import .page [page])
|
||||
(import .comments [comments])
|
||||
(import .link [link])
|
12
www/src/templates/comments.hy
Normal file
12
www/src/templates/comments.hy
Normal file
@ -0,0 +1,12 @@
|
||||
(import urllib.parse [quote-plus])
|
||||
|
||||
(defn comments [route]
|
||||
`(section (:class comments)
|
||||
(h2 comments)
|
||||
(form (:id comment :method post :action ~f"/comment?route={route}" :autocomplete off)
|
||||
(textarea (:id comment :name comment :placeholder comment :required True :maxlength 2048))
|
||||
(input (:id name :type text :name name :placeholder username :required True :maxlength 32))
|
||||
(input (:id website :type text :name site :placeholder "website (not required)" :maxlength 256))
|
||||
(input (:id submit :type submit :value post)))
|
||||
|
||||
(~f"$[ls -r ./www/data/comments/{(quote-plus route :safe "")} | xargs -I# cat ./www/data/comments/{(quote-plus route :safe "")}/#]")))
|
18
www/src/templates/footer.hy
Normal file
18
www/src/templates/footer.hy
Normal file
@ -0,0 +1,18 @@
|
||||
(import utils [run])
|
||||
|
||||
(defn footer []
|
||||
`(footer
|
||||
(div
|
||||
"page rendered at $[date +%s]"
|
||||
(br)
|
||||
"page compiled at " ~(run "date +%s"))
|
||||
(img (:src "/assets/88x31/natalieee.net.png" :alt "natalieee.net 88x31" :width "88" :height "31"))
|
||||
(div
|
||||
(footnote (:style "margin-top: 5px") "all content, with the exception of 88x31 buttons or unless otherwise noted is created by natalie and is licensed under a CC BY-NC-SA 4.0 license."))
|
||||
(a (:href "https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en")
|
||||
(img (:src "/assets/88x31/by-nc-sa.png" :alt "license 88x31" :width "88" :height "31")))
|
||||
(footnote (:style "margin-top: 5px") "▖▖▖▖▘▖▖▖▖▘▌▖▖▖▘"
|
||||
(div (:style "flex-direction: row; width: 14ch; gap: 1ch; margin-right: 5px;")
|
||||
(a (:href "https://stellophiliac.github.io/roboring/0x6e6174/previous") "<-")
|
||||
(a (:href "https://stellophiliac.github.io/roboring") "roboring")
|
||||
(a (:href "https://stellophiliac.github.io/roboring/0x6e6174/next") "->")))))
|
14
www/src/templates/header.hy
Normal file
14
www/src/templates/header.hy
Normal file
@ -0,0 +1,14 @@
|
||||
(defn header []
|
||||
`(header
|
||||
(nav
|
||||
(ul
|
||||
(li
|
||||
(a (:href "/") "natalieee.net"))
|
||||
(li
|
||||
(a (:href "./..") "back"))
|
||||
(li
|
||||
(a (:href "/html/about-site.html") "about (site)"))
|
||||
(li
|
||||
(a (:href "/html/about-natalie.html") "about (natalie)"))
|
||||
(li
|
||||
(a (:href "/html/thoughts.html") "thoughts (blog)"))))))
|
2
www/src/templates/link.hy
Normal file
2
www/src/templates/link.hy
Normal file
@ -0,0 +1,2 @@
|
||||
(defn link [link [label None]]
|
||||
`(a (:href ~link) ~(if label label link)))
|
30
www/src/templates/page.hy
Normal file
30
www/src/templates/page.hy
Normal file
@ -0,0 +1,30 @@
|
||||
(import templates.header [header])
|
||||
(import templates.footer [footer])
|
||||
|
||||
(import utils [run hy-env])
|
||||
(import random [randint])
|
||||
|
||||
(defn page [html
|
||||
[title "natalieee.net"]
|
||||
[author "natalie roentgen connolly"]
|
||||
[description ""]
|
||||
[extra-head None]]
|
||||
(run "echo > /tmp/footnote_count")
|
||||
`(html (:lang "en")
|
||||
(head ()
|
||||
(link (:rel "stylesheet" :href "/assets/style.css" :type "text/css"))
|
||||
(link (:rel preload :href "/assets/style.css"))
|
||||
(meta (:http-equiv "content-type" :content "text/html; charset=utf-8"))
|
||||
(meta (:name "viewport" :content "width=device-width, initial-scale=1"))
|
||||
(meta (:name "author" :content ~author))
|
||||
(meta (:name "fediverse:creator" :content "@0x6e6174@catgirl.cloud"))
|
||||
~(when description `(meta (:name "description" :content ~description)))
|
||||
~(when description `(meta (:name "og:description" :content ~description)))
|
||||
(link (:rel "me" :href "https://mastodon.catgirl.cloud/@0x6e6174"))
|
||||
~(when extra-head extra-head)
|
||||
(title ~title))
|
||||
(body ()
|
||||
~(header)
|
||||
(main ()
|
||||
~html)
|
||||
~(footer))))
|
48
www/src/utils.hy
Normal file
48
www/src/utils.hy
Normal file
@ -0,0 +1,48 @@
|
||||
(import html [escape])
|
||||
(import itertools [batched])
|
||||
(import subprocess [run :as subprocess/run PIPE])
|
||||
(import os [environ :as hy-env])
|
||||
|
||||
(require hyrule.destructure [setv+])
|
||||
|
||||
(setv self-closing-tags ['area 'base 'br 'col 'embed 'hr 'img 'input 'link 'meta 'param 'source 'track 'wbr])
|
||||
|
||||
(defn run [command]
|
||||
(setv env hy-env)
|
||||
(setv (get env "PATH") (+ (get hy-env "PATH") ":./scripts"))
|
||||
(.decode (getattr (subprocess/run command :env env :shell True :stdout PIPE :stderr None) "stdout")))
|
||||
|
||||
(defn form->html [html]
|
||||
(when (is html None)
|
||||
(return ""))
|
||||
|
||||
(cond
|
||||
(isinstance html str) (str html)
|
||||
(or (isinstance html int) (isinstance html float)) (str html)
|
||||
(isinstance html hy.models.Expression)
|
||||
(cond
|
||||
(not (isinstance (get html 0) hy.models.Symbol))
|
||||
(.join "" (map form->html html))
|
||||
|
||||
True
|
||||
(do
|
||||
(setv+ [tag attrs :& rest] html)
|
||||
(when (is attrs None) (setv attrs []))
|
||||
|
||||
(when (len attrs)
|
||||
(when (not (isinstance (get attrs 0) hy.models.Keyword))
|
||||
(do
|
||||
(setv rest (+ [attrs] rest))
|
||||
(setv attrs []))))
|
||||
|
||||
(when (not (isinstance tag hy.models.Symbol))
|
||||
(return ""))
|
||||
|
||||
(.format "<{}{}>{}{}"
|
||||
(.lower tag)
|
||||
(+ (if (len attrs) " " "") (.join " " (lfor [k v] (batched attrs :n 2)
|
||||
f"{(cut (str k) 1 None)}=\"{v}\"")))
|
||||
(.join "" (map form->html rest))
|
||||
(if (not-in tag self-closing-tags)
|
||||
f"</{(.lower tag)}>"
|
||||
""))))))
|
Reference in New Issue
Block a user