(import janet-html :as html)
(import ./utils)
# defining the basic structure of each page
# thanks to https://css-tricks.com/emojis-as-favicons/
(defn as-html [h]
(html/encode (html/doctype :html5) [:html h]))
(def favicon
"data:image/svg+xml,")
(defn html-head [data]
[:head
[:meta {:charset "utf-8"}]
[:title (get-in data [:config :title])]
[:link {:rel "icon"
:href favicon}]
[:link {:rel "stylesheet"
:href (get-in data [:config :stylesheet])}]])
# below are some functions we need for the unique svgs generated for each page
# arc drawing in svg is a bit messy. these two links helped me:
# - http://xahlee.info/js/svg_circle_arc.html
# - https://stackoverflow.com/a/18473154
(defn polar->cartesian
```
Given a pair of coordinates representing the center, returns the cartesian
coordinate for a straight line drawn at radian angle `alpha` with
length `len`.
```
[c-x c-y radius alpha]
[(+ c-x (* radius (math/cos alpha)))
(+ c-y (* radius (math/sin alpha)))])
(defn arc
```
Draws an svg arc with the given radius with a center at `c-x` and `c-y`. Note
that `start` and `end` have to be given in radians. Due to limitations in SVG
angles at exactly (* 2 math/pi) are not possible.
```
[c-x c-y radius start end]
(let [large-arc? (<= (- end start) math/pi)
[x1 y1] (polar->cartesian c-x c-y radius end)
[x2 y2] (polar->cartesian c-x c-y radius start)]
[:path {:d (string/format
"M %.2f %.2f A %.2f %.2f 0 %.0f 0 %.2f %.2f"
# starting point
x1 y1
# defining the arc
radius radius (if large-arc? 0 1)
# end point
x2 y2)}]))
(def num-tiles 10)
(def width 500)
(def height 500)
(def half-pi (/ math/pi 2))
(defn ten-print
"Generates a unique SVG pattern for some given content."
[content]
(let [radius (/ width num-tiles 2)
xs (map |(* width (/ $0 num-tiles)) (range (+ num-tiles 1)))
ys (map |(* height (/ $0 num-tiles)) (range (+ num-tiles 1)))]
(math/seedrandom (hash content))
[:svg.ten-print
{:viewBox (string/format "%d %d %d %d" (- radius) (- radius)
(+ width (* 2 radius))
(+ height (* 2 radius)))
:xmlns "http://www.w3.org/2000/svg"
:style "overflow: visible"}
[:style "path { fill: none; stroke: none; }"] # avoid flash of unstyled content
[:g {:transform "translate(0.5, 0.5"}
(mapcat
(fn [y]
(map (fn [x]
(let [rand (math/random)
start-angle (if (< rand 0.5) half-pi 0)]
(arc x y radius start-angle (+ start-angle (* 3 half-pi)))))
xs)) ys)]]))
(defn base
```
You can call this with some content and have it generate an entire HTML
structure for you.
```
[page data nav body &opt raw?]
(default raw? false)
(as-html [(html-head data)
[:body
[:main {:class page}
[:header (ten-print body)]
[:nav
[:h1 (get-in data [:config :title])]
nav]
[:article (if raw? (html/raw body) body)]]]]))
#
# different page types
#
(defn debug [jdn]
(string/format "%j" jdn))
(defn home [data]
(base "home"
data
[[:h2 "Projects"]
[:ul
[:li "Berliner Winter"]
[:li "Vanilla Sky"]
[:li "All My Friends"]
[:li "Kosmopolit"]]
[:h2 "Recent Posts"]
[:ul
(map (fn [post]
[:li [:a {:href (utils/slugify-content data post)} (post "title")]]) (data :posts))]]
[]))
(defn post [data item]
(base "post"
data
[:ul
[:li [:a {:href (get-in data [:config :base-url])} "Home"]]
[:li [:a {:href "#"} "Projects"]]
[:li [:a {:href "#"} "Posts"]]
[:li [:a {:href "#"} "About"]]]
(bagatto/mmarkdown->html (item :contents)) true))