Files
willfullyobtuse.com/onerc.el

222 lines
8.3 KiB
EmacsLisp

(setq wfot-styles
'((mvp . "https://unpkg.com/mvp.css")
(bahunya . "https://cdn.jsdelivr.net/gh/kimeiga/bahunya/dist/bahunya.min.css")
(awsm . "https://unpkg.com/awsm.css/dist/awsm.min.css")
(holiday . "https://cdn.jsdelivr.net/npm/holiday.css@0.11.2")
(tacit . "https://cdn.jsdelivr.net/gh/yegor256/tacit@gh-pages/tacit-css-1.8.1.min.css")
(writ . "//writ.cmcenroe.me/1.0.4/writ.min.css")
(simple . "https://cdn.simplecss.org/simple.min.css")
(pico-amber . "https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.classless.amber.min.css")
(pico-fluid . "https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.fluid.classless.min.css")
(pico . "https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.classless.min.css")))
(setq primary-css (alist-get 'pico-amber wfot-styles))
(defun wfot-default (page-tree pages _global)
"willfullyobtuse default render function
See `one-is-page', `one-render-pages' and `one-default-css'."
(let* ((title (org-element-property :raw-value page-tree))
(path (org-element-property :CUSTOM_ID page-tree))
(content (org-export-data-with-backend
(org-element-contents page-tree)
'one-ox nil))
(website-name (one-default-website-name pages))
(nav (one-default-nav path pages)))
(jack-html
"<!DOCTYPE html>"
`(:html
(:head
(:meta (@ :name "viewport" :content "width=device-width,initial-scale=1"))
(:link (@ :rel "stylesheet" :href primary-css))
(:link (@ :rel "stylesheet" :href "wfot.css"))
(:title ,title))
(:body
(:header (:a (@ :href "/") ,website-name))
(:main
(:section (:h1.title
,(if (not (string= path "/"))
`(:div.title (:h1 ,title))
'(:div.title-empty))))
(:section (:article ,content))))))))
(defun wfot-default-home-list-pages (page-tree pages _global)
"Default render function to use in the home page that lists pages.
See `one-is-page' for the meaning of PAGE-TREE and PAGES.
Also see `one-render-pages' and `one-default-css'."
(let* ((title (org-element-property :raw-value page-tree))
(content (org-export-data-with-backend
(org-element-contents page-tree)
'one-ox nil))
(website-name (one-default-website-name pages))
;; All pages but the home pages
(pages-list (wfot-default-pages pages "/.+")))
(jack-html
"<!DOCTYPE html>"
`(:html
(:head
(:meta (@ :name "viewport" :content "width=device-width,initial-scale=1"))
(:link (@ :rel "stylesheet" :href primary-css))
(:link (@ :rel "stylesheet" :href "wfot.css"))
(:title ,title))
(:body
(:header (:a (@ :href "/") ,website-name))
(:main
(:div/home-list-pages ,content)
(:div/pages (:ul ,(reverse pages-list)))))))))
(defun wfot-default-pages (pages &optional filter)
"Return `jack-html' list of PAGES component.
If FILTER is non-nil, a page is listed only when its path (value
of `:one-path' property) matches FILTER regexp.
Evaluating the following form
(wfot-default-pages
\\='((:one-title \"HOME\" :one-path \"/\")
(:one-title \"FOO-1\" :one-path \"/foo-1/\")
(:one-title \"FOO-2\" :one-path \"/foo-2/\")))
returns:
(:ul
(:li (:a (@ :href \"/\") \"HOME\"))
(:li (:a (@ :href \"/foo-1/\") \"FOO-1\"))
(:li (:a (@ :href \"/foo-2/\") \"FOO-2\")))
And evaluating the following form with the filter \"/.+\"
(wfot-default-pages
\\='((:one-title \"HOME\" :one-path \"/\")
(:one-title \"FOO-1\" :one-path \"/foo-1/\")
(:one-title \"FOO-2\" :one-path \"/foo-2/\"))
\"/.+\")
returns a list which doesn't include the home page:
(:ul
(:li (:a (@ :href \"/foo-1/\") \"FOO-1\"))
(:li (:a (@ :href \"/foo-2/\") \"FOO-2\")))"
(when-let ((li-items
(delq nil
(mapcar
(lambda (page)
(let ((href (plist-get page :one-path))
(title (plist-get page :one-title))
(date (org-element-property :DATE (plist-get page :one-page-tree))))
(when (string-match-p (or filter ".*") href)
`(:li (@ :class "post-item") (:div (@ :class "post-date") ,date) (:a (@ :href ,href) (:span ,title)) ))))
pages))))
`(:ul ,@li-items)))
(defun wfot-default-home (page-tree pages _global)
"Default render function to use in the home page.
See `one-is-page' for the meaning of PAGE-TREE and PAGES.
Also see `one-render-pages' and `one-default-css'."
(let* ((title (org-element-property :raw-value page-tree))
(content (org-export-data-with-backend
(org-element-contents page-tree)
'one-ox nil))
(website-name (one-default-website-name pages)))
(jack-html
"<!DOCTYPE html>"
`(:html
(:head
(:meta (@ :name "viewport" :content "width=device-width,initial-scale=1"))
(:link (@ :rel "stylesheet" :href primary-css))
(:link (@ :rel "stylesheet" :href "wfot.css"))
(:title ,title))
(:body
(:header ,website-name)
(:main
(:div/home ,content)))))))
(defun wfot-default-with-sidebar (page-tree pages global)
"Default render function with a sidebar listing PAGES.
See `one-is-page' for the meaning of PAGE-TREE and GLOBAL.
Also see `one-default-sidebar', `one-render-pages' and `one-default-css'."
(wfot-default-sidebar page-tree pages global))
(defun wfot-default-sidebar (page-tree pages _global &optional with-toc)
"Return a HTML string with PAGES listed in a sidebar.
The arguments PAGE-TREE, PAGES and _GLOBAL are the same as
render functions take (See `one-is-page').
When WITH-TOC is non-nil, add the table of content of PAGE-TREE
in the HTML string.
This function is meant to be used by `one-default-with-sidebar'
and `one-default-doc' render functions.
See `one-render-pages', `one-default-css' and `wfot-default-pages'."
(let* ((title (org-element-property :raw-value page-tree))
(path (org-element-property :CUSTOM_ID page-tree))
(content (org-export-data-with-backend
(org-element-contents page-tree)
'one-ox nil))
(website-name (one-default-website-name pages))
(pages-list (wfot-default-pages pages))
(headlines (cdr (one-default-list-headlines page-tree)))
(toc (one-default-toc-component headlines))
(nav (one-default-nav path pages)))
(jack-html
"<!DOCTYPE html>"
`(:html
(:head
(:meta (@ :name "viewport" :content "width=device-width,initial-scale=1"))
(:link (@ :rel "stylesheet" :href primary-css))
(:link (@ :rel "stylesheet" :href "wfot.css"))
(:title ,title))
(:body
;; sidebar-left and sidebar-main are for small devices
(:div/sidebar-left (@ :onclick "followSidebarLink()")
(:div (:div "Pages"))
,pages-list)
(:div/sidebar-main)
(:div/sidebar-header
(:svg/hamburger (@ :viewBox "0 0 24 24" :onclick "sidebarShow()")
(:path (@ :d "M21,6H3V5h18V6z M21,11H3v1h18V11z M21,17H3v1h18V17z")))
(:a (@ :href "/") ,website-name))
(:div/sidebar-content
(:div/sidebar ,pages-list)
(:article
,(if (not (string= path "/"))
`(:div.title (:h1 ,title))
'(:div.title-empty))
,(when with-toc toc)
,content
,nav)))
(:script "
function sidebarShow() {
if (window.innerWidth < 481)
document.getElementById('sidebar-left').style.width = '75vw';
else {
document.getElementById('sidebar-left').style.width = 'min(300px, 34vw)';
}
document.getElementById('sidebar-main').setAttribute('onclick', 'sidebarHide()');
document.getElementById('sidebar-main').style.display = 'block';
}
function sidebarHide() {
document.getElementById('sidebar-left').style.width = '0';
document.getElementById('sidebar-main').style.display = 'none';
}
")))))
(defun wfot-default-doc (page-tree pages global)
"Default render function with a sidebar listing PAGES and the table of content.
See `one-is-page' for the meaning of PAGE-TREE and GLOBAL.
Also see `one-default-sidebar', `one-render-pages' and `one-default-css'."
(wfot-default-sidebar page-tree pages global 'with-toc))