(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 "" `(: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 "" `(: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 "" `(: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 "" `(: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))