summaryrefslogtreecommitdiff
path: root/z.scm
diff options
context:
space:
mode:
Diffstat (limited to 'z.scm')
-rw-r--r--z.scm103
1 files changed, 72 insertions, 31 deletions
diff --git a/z.scm b/z.scm
index 65f73af..59f93be 100644
--- a/z.scm
+++ b/z.scm
@@ -128,9 +128,6 @@
(display "---\n" file)
(format file "~a" (get-content node)))))
-(define-generic render-li)
-(define-generic render-full)
-
;; Parsing Nodes
(define-peg-string-patterns "\
@@ -199,23 +196,51 @@ NL < '\n'
(define (get-by-title title)
(dict.get *titles* title))
- ;; webserver
-
-(define *css* "body{max-width:650px;margin:40px auto;padding:0 10px;font:18px/1.5 -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";color:#444}h1,h2,h3{line-height:1.2}@media (prefers-color-scheme: dark){body{color:white;background:#444}a:link{color:#5bf}a:visited{color:#ccf}}")
+ ;; view
+
+(define *css* "
+@import url('https://fonts.googleapis.com/css2?family=Source+Code+Pro:ital,wght@0,400;0,700;1,400&family=Source+Sans+Pro:ital,wght@0,400;0,700;1,400&family=Source+Serif+Pro:wght@400;700&display=swap');
+body
+{ max-width: 900px; min-height: 100vh
+; margin: 0 auto; padding: 0 10px
+; color:#444
+; font: 18px/1.5 -apple-system, 'Source Sans Pro',
+ BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial,
+ \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\",
+ \"Segoe UI Symbol\", \"Noto Color Emoji\"
+; display: flex; flex-direction: column; justify-content: center
+}
+main,nav,aside { font-family: 'Source Sans Pro', sans-serif; }
+nav { order: -1 }
+h1,h2,h3 { line-height: 1.2 }
+p, li { line-height: 1.4rem }
+p { margin: 0 0 1.8rem 0 }
+.serif { font-family: 'Source Sans Pro', serif }
+@media (prefers-color-scheme: dark)
+{
+ body { color: white; background: #444 }
+ a:link { color: #5bf }
+ a:visited { color: #ccf }
+}
+@media (min-width: 768px) {
+ body { flex-direction: row; flex: 1 }
+ main { flex: 1 }
+ nav, aside { flex: 0 0 12em }
+}
+")
+;; global navbar on the left side
(define *navbar*
- (let ((items (lambda ()
- (unzip2
- '(("index" "/")
- #;("new" "/id/new")
- ("tags" "/tag"))))))
- `(nav
- (ul
- ,@(call-with-values items
- (lambda (names paths)
- (map (lambda (name path)
- `(li (a (@ (href ,path)) ,name)))
- names paths)))))))
+ `(nav
+ (h1 (a (@ (href "/") (class "serif")) "z"))
+ (ul
+ ,@(receive (names paths)
+ (unzip2 '(("index" "/")
+ #;("new" "/id/new")
+ ("tags" "/tag")))
+ (map (lambda (name path)
+ `(li (a (@ (href ,path)) ,name)))
+ names paths)))))
(define (template title body)
`(html (head
@@ -224,11 +249,32 @@ NL < '\n'
(content "width=device-width, initial-scale=1"))))
(style ,*css*)
(body
- (h1 (a (@ (href "/"))
- "z"))
- ,*navbar*
,@body)))
+(define (link-tag tag)
+ `(a (@ (href ,(fmt "/tag/~a" tag)))
+ ,(fmt "~a" tag)))
+
+(define (view-content node)
+ `(main
+ (h2 ,(title node))
+ ,(->> node
+ get-content
+ pandoc
+ ;; wrap in article tags so sxml includes all of the
+ ;; content, not just the first element
+ ((/. s (string.str "<article>" s "</article>")))
+ xml->sxml)))
+
+(define (view-meta node)
+ `(aside
+ (ul
+ (li ,(created node))
+ ,(turn (tags node)
+ (/. tag `(li ,(link-tag tag)))))))
+
+ ;; webserver
+
(define* (respond #:optional body #:key
(status 200)
(title "z")
@@ -268,14 +314,10 @@ NL < '\n'
(let* ([node (load-node (string->id id))]
[txt (or (get-content node) "")])
(respond
- (->> txt
- pandoc
- ;; wrap in article tags so sxml includes all of the
- ;; content, not jus the first element
- ((/. s (string.str "<article>" s "</article>")))
- xml->sxml
- ;; wrap in a list to prevent *TOP* from being rendered
- list)
+ (list
+ (view-content node)
+ (view-meta node)
+ *navbar*)
#:title (fmt "z - ~a" (title node))))]
[("tag")
(begin
@@ -283,8 +325,7 @@ NL < '\n'
(respond
`((ul ,@(turn (dict.keys *tags*)
(lambda [tag]
- `(li (a (@ (href ,(fmt "/tag/~a" tag)))
- ,(fmt "~a" tag)))))))))]
+ `(li ,(link-tag tag))))))))]
[("tag" tag)
(respond
`((ul ,@(turn (tagged tag)