From f7bee74fcbb037789dafb3fdef475798ad50db49 Mon Sep 17 00:00:00 2001 From: nat Date: Sun, 11 May 2025 15:33:29 -0700 Subject: [PATCH] code for blog/thoughts --- www/src/assets/style.css | 24 ++++++++++ www/src/build.hy | 21 +++++++- www/src/data/thoughts/dollcode.py | 2 + www/src/pages/html/view-thought.hy | 77 ++++++++++++++++++++++++++++++ www/src/templates/header.hy | 2 +- www/src/templates/page.hy | 1 - 6 files changed, 123 insertions(+), 4 deletions(-) create mode 100644 www/src/data/thoughts/dollcode.py create mode 100644 www/src/pages/html/view-thought.hy diff --git a/www/src/assets/style.css b/www/src/assets/style.css index 2d53d7f..eea117b 100644 --- a/www/src/assets/style.css +++ b/www/src/assets/style.css @@ -345,3 +345,27 @@ figure { } } } + +div.thought-list{ + display: flex; + flex-direction: column; + + > div.thought-list-entry { + margin: 10px; + padding: 10px; + background: var(--alt-bg); + display: grid; + grid-template-columns: 3fr 1fr; + grid-template-rows: 1fr min(min-content, 1fr); + + > * { + white-space: pre-wrap; + word-wrap: break-word; + overflow-wrap: anywhere; + + &.title { + font-weight: bold; + } + } + } +} diff --git a/www/src/build.hy b/www/src/build.hy index 6f1341a..359fdbd 100644 --- a/www/src/build.hy +++ b/www/src/build.hy @@ -4,12 +4,26 @@ (import templates *) (import utils *) +(import hy.compiler [hy-eval]) + (require hyrule.control [defmain]) +(setv local-scope (locals)) +(setv global-scope (globals)) + +(defmacro inherit [#* names] + (lfor name names + `(setx ~name (get local-scope (str (get '(~name) 0)))))) + +(defmacro enshrine [#* names] + (lfor name names + `(setv (get local-scope (str (get '(~name) 0))) ~name))) + (defmain [] (when (not (dir? "output")) (mkdir "output")) + (for [path (glob "./pages/**/*" :recursive True)] (when (in "__pycache__" path) (continue)) @@ -24,7 +38,10 @@ (do (print f"building {path}") (setv page-name (.split (cut path 2 -3) "/")) + (enshrine page-name) (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))))))))))) + (hy-eval (hy.read (with [source (open path "r")] + (.read source))) + :locals local-scope + :globals global-scope)))))))) diff --git a/www/src/data/thoughts/dollcode.py b/www/src/data/thoughts/dollcode.py new file mode 100644 index 0000000..263b698 --- /dev/null +++ b/www/src/data/thoughts/dollcode.py @@ -0,0 +1,2 @@ +#!/usr/bin/env -S bash -c 'python3 -c "__import__(\"sys\").setrecursionlimit(2**31-1); exec(open(\"$(which dollcode)\").read())" "$@"' _ +print((lambda d,ud,args:d(int(args[-1]))if'-n'in args else d(int(''.join(map(lambda x:str(hex(ord(x))[2::]),args[-1])),16))if'-a'in args else ud(args[-1])if'-dn'in args else(lambda h:''.join(map(lambda i:chr(int(h[i:i+2],16)),range(0,len(h),2))))(hex(ud(args[-1]))[2::])if'-da'in args else"0x6e6174\'s dollcode conversion tool\n\t-n: encode decimal number as dollcode\n\t-a: encode ascii string as dollcode\n\t-dn: decode dollcode as decimal\n\t-da:decode dollcode as ascii string")(lambda n:''.join(map(lambda n:''.join(['▖','▘','▌'][int(n)]),(lambda f:(lambda x:f(lambda y:x(x)(y)))(lambda x:f(lambda y:x(x)(y))))(lambda f:lambda n:(lambda x,y:str(f(x))+str(y))(*divmod(n-1,3))if n else'')(n))),lambda d:__import__('functools').reduce(lambda a,d:a*3+d,map(lambda x:{'▖':1,'▘':2,'▌':3}[x],d),0),__import__('sys').argv)) diff --git a/www/src/pages/html/view-thought.hy b/www/src/pages/html/view-thought.hy new file mode 100644 index 0000000..fd2e944 --- /dev/null +++ b/www/src/pages/html/view-thought.hy @@ -0,0 +1,77 @@ +(do ;; required for arcane scoping + (defn check-param-exists [param-name] + #[f[test "$(echo '{{' '{param-name}' '}}' | sed 's/ //g')" != '{{{param-name}}}']f]) + + (defn if-param-then-else [param-name param-defined otherwise [echo True]] + #[f[ {(check-param-exists param-name)} && {(if echo "echo " "")}{param-defined} || {(if echo "echo " "")}{otherwise} ]f]) + + (defn param-if-param-else [param-name otherwise] + (if-param-then-else param-name f"'{{{param-name}}}'" otherwise)) + + (defn get-thought-param-field [field] + #[f[ cat www/data/thought-registry | grep -P "\t{{thought}}\t" | awk -v FS=$'\t' '{{print ${(get (dict :tags "1" :file-name "2" :title "3" :date "4" :description "5") field)}}}' ]f]) + + (defn subshell [#* lines] + #[f[({(.join "; " lines)})]f]) + + (setv thought-tag-format (form->html + `(a (:href "?filter-tag=${tag}") "${tag}"))) + + (setv thought-tag-list-format + #[f[tags: $(while read -r tag{";"} do echo "{thought-tag-format}"{";"} done <<< "${{tags//{#[[;]]}/$'\n'}}")]f]) + + (setv thought-list-entry-format (form->html + `(div (:id "${file_name}" :class thought-list-entry) + (div (:class title) (a (:href "\\?thought=${file_name}") "${title}")) + (div (:class date) "${date}") + (div (:class description) "${description}") + (div (:class categories) ~#[f[$(echo {thought-tag-list-format})]f])))) + + (setv thought-display-meta-format (form->html + `(div (:class thought-meta) + (div (:class date) "${date}") + (div (:class tags) ~#[f[$(echo "{thought-tag-list-format}")]f])))) + + (defn thought [[title "empty title"] [description ""] [date "1970-01-01"] [tags []] [content '(p "no content provided")]] + (inherit page-name) + (with [thought-registry (open "../data/thought-registry" "a")] + (.write thought-registry f"{(.join #[[;]] tags)}\t{(get page-name -1)}\t{title}\t{date}\t{description}\n")) + + `( + ~content + ~(run "put-footnotes") + ~(comments f"/html/thought/view-thought.html?thought={(get page-name -1)}"))) + + (run "echo -n > ../data/thought-registry") + + (page + :title #[f[$[{(param-if-param-else "thought" "natalie thoughts")}]]f] + :description #[f[ + $[{(if-param-then-else "thought" #[f["$({(get-thought-param-field "description")})"]f] #[f[ + $({(if-param-then-else + "filter-tag" + "'thoughts filtered for "{filter-tag}"'" + "an enumeration of natalie thoughts. it is functionally a blog")})]f])}]]f] + + `(section + (h1 ~#[f[ + $[{(if-param-then-else "thought" #[f[$({(get-thought-param-field "title")})]f] #[f[ + $({(if-param-then-else + "filter-tag" + "'thoughts filtered for "{filter-tag}"'" + "natalie thoughts. functionally a blog")})]f])}]]f]) + + (div (:class ~#[f[$[{(if-param-then-else "thought" "thought" "thought-list")}]]f]) + ~#[f[$[{(if-param-then-else + "thought" + #[f[{(subshell + #[f[tags=$({(get-thought-param-field "tags")})]f] + #[f[date=$({(get-thought-param-field "date")})]f] + #[f[echo "{thought-display-meta-format}"]f] + #[f[include ./www/site/html/html/thoughts/$({(get-thought-param-field "file_name")}).html]f])}]f] + #[f[cat www/data/thought-registry | eval $({(if-param-then-else + "filter-tag" + #[-[grep '{filter-tag}']-] + #[-["grep -E '.*'"]-])}) | sort -t$'\t' -k4 -nr | while IFS=$'\t' read -r tags file_name title date description{";"} do echo "{thought-list-entry-format}"{";"} done]f] + :echo False)}]]f])))) + diff --git a/www/src/templates/header.hy b/www/src/templates/header.hy index 72bb9ca..be62435 100644 --- a/www/src/templates/header.hy +++ b/www/src/templates/header.hy @@ -11,4 +11,4 @@ (li (a (:href "/html/about-natalie.html") "about (natalie)")) (li - (a (:href "/html/thoughts.html") "thoughts (blog)")))))) + (a (:href "/html/view-thought.html") "thoughts (blog)")))))) diff --git a/www/src/templates/page.hy b/www/src/templates/page.hy index b86c7e2..1273f0e 100644 --- a/www/src/templates/page.hy +++ b/www/src/templates/page.hy @@ -2,7 +2,6 @@ (import templates.footer [footer]) (import utils [run hy-env]) -(import random [randint]) (defn page [html [title "natalieee.net"]