Configuration for this Website
This file contains the entire configuration for this website including the css styling and org-publish configuration. The features this website supports can be seen here seen here. Ideas for features I’d like to implement in the future can be found here.
The following blog posts pertain to the evolution of this website and blog:
- In search of “functional” CSS
- Creating Lists of Tagged Posts using Emacs Lisp Part 2
- CSS in
org-publish
- Creating Lists of Tagged Posts using Emacs Lisp
- Brief foray into
ox-slimhtml
- Using Literate Programming to make CSS+HTML+JS+ELisp play nice together
- Beginning Blogging with
org-publish
CSS
Spacemacs Dark Theme
https://github.com/nashamri/spacemacs-theme
:root { /* generic */ --act1 : #222226; --act2 : #5d4d7a; --base : #b2b2b2; --base-dim : #686868; --bg1 : #292b2e; --bg2 : #212026; --bg3 : #100a14; --bg4 : #0a0814; --border : #5d4d7a; --cblk : #cbc1d5; --cblk-bg : #2f2b33; --cblk-ln : #827591; --cblk-ln-bg : #373040; --cursor : #e3dedd; --const : #a45bad; --comment : #2aa1ae; --comment-light : #2aa1ae; --comment-bg : #292e34; --comp : #c56ec3; --err : #e0211d; --func : #bc6ec5; --head1 : #4f97d7; --head1-bg : #293239; --head2 : #2d9574; --head2-bg : #293235; --head3 : #67b11d; --head3-bg : #293235; --head4 : #b1951d; --head4-bg : #32322c; --highlight : #444155; --highlight-dim : #3b314d; --keyword : #4f97d7; --lnum : #44505c; --mat : #86dc2f; --meta : #9f8766; --str : #2d9574; --suc : #86dc2f; --ttip : #9a9aba; --ttip-sl : #5e5079; --ttip-bg : #34323e; --type : #ce537a; --var : #7590db; --war : #dc752f; /* colors */ --aqua : #2d9574; --aqua-bg : #293235; --green : #67b11d; --green-bg : #293235; --green-bg-s : #29422d; --cyan : #28def0; --red : #f2241f; --red-bg : #3c2a2c; --red-bg-s : #512e31; --blue : #4f97d7; --blue-bg : #293239; --blue-bg-s : #2d4252; --magenta : #a31db1; --yellow : #b1951d; --yellow-bg : #32322c; }
Spacemacs Light Theme
.light { /* generic */ --act1 : #e7e5eb; --act2 : #d3d3e7; --base : #655370; --base-dim : #a094a2; --bg1 : #fbf8ef; --bg2 : #efeae9; --bg3 : #e3dedd; --bg4 : #d2ceda; --border : #b3b9be; --cblk : #655370; --cblk-bg : #e8e3f0; --cblk-ln : #9380b2; --cblk-ln-bg : #ddd8eb; --cursor : #100a14; --const : #4e3163; --comment : #2aa1ae; --comment-light : #a49da5; --comment-bg : #ecf3ec; --comp : #6c4173; --err : #e0211d; --func : #6c3163; --head1 : #3a81c3; --head1-bg : #edf1ed; --head2 : #2d9574; --head2-bg : #edf2e9; --head3 : #67b11d; --head3-bg : #edf2e9; --head4 : #b1951d; --head4-bg : #f6f1e1; --highlight : #d3d3e7; --highlight-dim : #e7e7fc; --keyword : #3a81c3; --lnum : #a8a8bf; --mat : #ba2f59; --meta : #da8b55; --str : #2d9574; --suc : #42ae2c; --ttip : #8c799f; --ttip-sl : #c8c6dd; --ttip-bg : #e2e0ea; --type : #ba2f59; --var : #715ab1; --war : #dc752f; /* colors */ --aqua : #2d9574; --aqua-bg : #edf2e9; --green : #67b11d; --green-bg : #edf2e9; --green-bg-s : #dae6d0; --cyan : #21b8c7; --red : #f2241f; --red-bg : #faede4; --red-bg-s : #eed9d2; --blue : #3a81c3; --blue-bg : #edf1ed; --blue-bg-s : #d1dcdf; --magenta : #a31db1; --yellow : #b1951d; --yellow-bg : #f6f1e1; }
elements
body { font-family: "Helvetica Neue", Helvetica, sans-serif; color: var(--base); background-color: var(--bg1); max-width: 45em; margin: auto; } #preamble { text-align: center; } #postamble { text-align: center; margin: 2em; } .menu { display: inline-block; padding: 1em 0.5em 0.5em; position: relative; top: -0.5em; background-color: var(--bg4); border-radius: 0.4em; } button { border: none; background-color: inherit; font-size: inherit; font: inherit; cursor: pointer; color: var(--head1); } button:hover { text-decoration: underline; } .menu-btn { transition: all 0.2s ease; color: var(--base); padding: 0.3em; margin: 0.2em; border-radius: 0.2em; border: 2px solid var(--func); fill: var(--base); } .menu-btn:hover { background-color: var(--func); color: var(--act1); fill: var(--act1); } a { color: var(--head1); background-color: inherit; font: inherit; text-decoration: inherit; } a:hover { text-decoration: underline; } .title { text-align: center; margin-bottom: .2em; } .subtitle { text-align: center; font-size: medium; font-weight: bold; margin-top:0; } .todo { font-family: monospace; color: red; } .done { font-family: monospace; color: green; } .priority { font-family: monospace; color: orange; } .tag { background-color: #eee; font-family: monospace; padding: 2px; font-size: 80%; font-weight: normal; } .timestamp { color: #bebebe; } .timestamp-kwd { color: #5f9ea0; } .org-right { margin-left: auto; margin-right: 0px; text-align: right; } .org-left { margin-left: 0px; margin-right: auto; text-align: left; } .org-center { margin-left: auto; margin-right: auto; text-align: center; } .underline { text-decoration: underline; } #postamble p, #preamble p { font-size: 90%; margin: .2em; } p.verse { margin-left: 3%; } table { border-collapse:collapse; } caption.t-above { caption-side: top; } caption.t-bottom { caption-side: bottom; } td, th { vertical-align:top; } th.org-right { text-align: center; } th.org-left { text-align: center; } th.org-center { text-align: center; } td.org-right { text-align: right; } td.org-left { text-align: left; } td.org-center { text-align: center; } dt { font-weight: bold; } .footpara { display: inline; } .footdef { margin-bottom: 1em; } .figure { padding: 1em; } .figure p { text-align: center; } .inlinetask { padding: 10px; border: 2px solid gray; margin: 10px; background: #ffffcc; } #org-div-home-and-up { text-align: right; font-size: 70%; white-space: nowrap; } textarea { overflow-x: auto; } .linenr { font-size: smaller } .code-highlighted { background-color: #ffff00; } .org-info-js_info-navigation { border-style: none; } #org-info-js_console-label { font-size: 10px; font-weight: bold; white-space: nowrap; } .org-info-js_search-highlight { background-color: #ffff00; color: #000000; font-weight: bold; } .org-svg { width: 90%; } .org-src-container { } .org-ul {}
org classes
.org-builtin { /* font-lock-builtin-face */ color: var(--head1); } .org-comment { /* font-lock-comment-face */ color: var(--comment); background-color: var(--comment-bg); } .org-comment-delimiter { /* font-lock-comment-delimiter-face */ color: var(--comment); background-color: var(--comment-bg); } .org-constant { /* font-lock-constant-face */ color: var(--const); } .org-css-property { /* css-property */ color: var(--head1); font-weight: bold; font-style: italic; } .org-css-selector { /* css-selector */ color: var(--func); font-weight: bold; } .org-doc { /* font-lock-doc-face */ color: var(--meta); } .org-font-latex-bold { /* font-latex-bold-face */ color: var(--comp); } .org-font-latex-math { /* font-latex-math-face */ color: #deb887; } .org-font-latex-script-char { /* font-latex-script-char-face */ color: #8b0000; } .org-font-latex-sedate { /* font-latex-sedate-face */ color: #d3d3d3; } .org-function-name { /* font-lock-function-name-face */ color: var(--func); font-weight: bold; } .org-highlight-numbers-number { /* highlight-numbers-number */ color: var(--const); } .org-keyword { /* font-lock-keyword-face */ color: var(--head1); font-weight: bold; font-style: italic; } .org-negation-char { /* font-lock-negation-char-face */ color: var(--const); } .org-org-block { /* org-block */ color: var(--cblk); background-color: var(--cblk-bg); } .org-org-block-begin-line { /* org-block-begin-line */ color: var(--cblk-ln); background-color: var(--cblk-ln-bg); } .org-org-block-end-line { /* org-block-end-line */ color: var(--cblk-ln); background-color: var(--cblk-ln-bg); } .org-org-meta-line { /* org-meta-line */ color: var(--meta); } .org-org-target { /* org-target */ text-decoration: underline; } .org-rainbow-delimiters-depth-1 { /* rainbow-delimiters-depth-1-face */ color: var(--head1); } .org-rainbow-delimiters-depth-2 { /* rainbow-delimiters-depth-2-face */ color: var(--func); } .org-rainbow-delimiters-depth-3 { /* rainbow-delimiters-depth-3-face */ color: var(--head2); } .org-rainbow-delimiters-depth-4 { /* rainbow-delimiters-depth-4-face */ color: var(--head3); } .org-rainbow-delimiters-depth-5 { /* rainbow-delimiters-depth-5-face */ color: var(--head4); } .org-rainbow-delimiters-depth-6 { /* rainbow-delimiters-depth-6-face */ color: var(--head1); } .org-rainbow-delimiters-depth-7 { /* rainbow-delimiters-depth-7-face */ color: var(--func); } .org-rainbow-delimiters-depth-8 { /* rainbow-delimiters-depth-8-face */ color: var(--head2); } .org-rainbow-delimiters-depth-9 { /* rainbow-delimiters-depth-9-face */ color: #9cb6ad; } .org-regexp-grouping-backslash { /* font-lock-regexp-grouping-backslash */ font-weight: bold; } .org-regexp-grouping-construct { /* font-lock-regexp-grouping-construct */ font-weight: bold; } .org-sh-heredoc { /* sh-heredoc */ color: #ffff00; font-weight: bold; } .org-sh-quoted-exec { /* sh-quoted-exec */ color: #fa8072; } .org-string { /* font-lock-string-face */ color: var(--str); } .org-type { /* font-lock-type-face */ color: var(--type); font-weight: bold; } .org-variable-name { /* font-lock-variable-name-face */ color: var(--var); } .org-warning { /* warning */ color: var(--war); }
Source Code
pre { border: 1px solid #ccc; box-shadow: 3px 3px 3px #eee; padding: 8pt; font-family: monospace; overflow: auto; margin: 1.2em; } pre.src { position: relative; overflow: visible; padding-top: 1.2em; } pre.src:before { display: none; position: absolute; background-color: white; top: -10px; right: 10px; padding: 3px; border: 1px solid black; } pre.src:hover:before { display: inline;} pre.src-C:before { content: 'C'; } pre.src-css:before { content: 'CSS'; } pre.src-dot:before { content: 'Graphviz'; } pre.src-calc:before { content: 'Emacs Calc'; } pre.src-emacs-lisp:before { content: 'Emacs Lisp'; } pre.src-elisp:before { content: 'Emacs Lisp'; } pre.src-fortran:before { content: 'Fortran'; } pre.src-haskell:before { content: 'Haskell'; } pre.src-js:before { content: 'Javascript'; } pre.src-latex:before { content: 'LaTeX'; } pre.src-lisp:before { content: 'Lisp'; } pre.src-lua:before { content: 'Lua'; } pre.src-org:before { content: 'Org mode'; } pre.src-python:before { content: 'Python'; } pre.src-ipython:before { content: 'IPython'; } pre.src-ruby:before { content: 'Ruby'; } pre.src-scheme:before { content: 'Scheme'; } pre.src-sed:before { content: 'Sed'; } pre.src-sh:before { content: 'shell'; } pre.src-makefile:before { content: 'Makefile'; } pre.src-perl:before { content: 'Perl'; } pre.src-shell:before { content: 'Shell Script'; } pre.src-cpp:before { content: 'C++'; } pre.src-bash:before { content: 'bash'; } pre.src-html:before { content: 'HTML'; } pre.src-prolog:before { content: 'Prolog'; } pre.src-tex:before { content: 'TeX'; } pre.src-plain-tex:before { content: 'Plain TeX'; } pre.src-conf:before { content: 'Configuration File'; }
JS
/* @licstart The following is the entire license notice for the JavaScript code in this tag. Copyright (C) 2012-2019 Free Software Foundation, Inc. The JavaScript code in this tag is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License (GNU GPL) as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. The code is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU GPL for more details. As additional permission under GNU GPL version 3 section 7, you may distribute non-source (e.g., minimized or compacted) forms of that code without the copy of the GNU GPL normally required by section 4, provided you include this license notice and a URL through which recipients can access the Corresponding Source. @licend The above is the entire license notice for the JavaScript code in this tag. */ function CodeHighlightOn(elem, id) { var target = document.getElementById(id); if(null != target) { elem.cacheClassElem = elem.className; elem.cacheClassTarget = target.className; target.className = "code-highlighted"; elem.className = "code-highlighted"; } } function CodeHighlightOff(elem, id) { var target = document.getElementById(id); if(elem.cacheClassElem) elem.className = elem.cacheClassElem; if(elem.cacheClassTarget) target.className = elem.cacheClassTarget; }
document.addEventListener('DOMContentLoaded', function() { let toggle_theme_light = document.querySelector('#toggle-theme-light') let toggle_theme_dark = document.querySelector('#toggle-theme-dark') function lights_on(e) { if (e) { e.preventDefault(); } document.body.classList.add('light'); toggle_theme_dark.style.display = null; toggle_theme_light.style.display = "none"; localStorage.setItem('light', true); } function lights_off(e) { if (e) { e.preventDefault(); } document.body.classList.remove('light'); toggle_theme_dark.style.display = "none"; toggle_theme_light.style.display = null; localStorage.removeItem('light'); } if (localStorage.getItem('light')) { lights_on(null); } else { lights_off(null); } toggle_theme_light.addEventListener('click', lights_on); toggle_theme_dark.addEventListener('click', lights_off); document.body.style.transition = "all 0.4s ease"; }, false);
HTML
<script src="/scripts.js" type="text/javascript"></script> <link href="/styles.css" rel="stylesheet" type="text/css">
<div class="menu"> <a class="menu-btn" href="/"> <svg viewBox="0 0 514.767 514.767" overflow="visible" style="height: auto; width: 1em;"> <g> <path d="M198.602,6.733c-61.081,14.269-113.787,50.292-149.529,99.45h248.979L198.602,6.733z"/> <path d="M316.165,508.032c61.081-14.269,113.786-50.292,149.528-99.449H216.715L316.165,508.032z"/> <path d="M38.583,121.711C5.481,174.992-6.315,237.732,3.171,297.766l176.055-176.055H38.583z"/> <path d="M476.184,393.054c33.102-53.28,44.897-116.021,35.412-176.054L335.541,393.055L476.184,393.054z"/> <path d="M6.733,316.164c14.269,61.081,50.292,113.786,99.45,149.529V216.714L6.733,316.164z"/> <path d="M508.032,198.602C493.764,137.52,457.74,84.815,408.584,49.072v248.979L508.032,198.602z"/> <path d="M121.711,476.184c53.281,33.102,116.021,44.897,176.055,35.412L121.711,335.54V476.184z"/> <path d="M393.054,38.583C339.773,5.481,277.033-6.314,217,3.17l176.055,176.055L393.054,38.583z"/> </g> </svg> About</a> <a class="menu-btn" href="/blog">Blog</a> <a class="menu-btn" href="https://github.com/akirakyle">GitHub</a> <button class="menu-btn" style="display: none" id="toggle-theme-light">Light Theme</button> <button class="menu-btn" style="display: none" id="toggle-theme-dark" >Dark Theme</button> </div> <div>%d</div>
Email: <a href="mailto:akira@akirakyle.com">akira@akirakyle.com</a> <br> GPG Public Key: <a href="/public-key.html">963C 2413 0BD3 BF1B 624C EF4C 8850 284C 20B8 078D</a>
Emacs Lisp org-publish
(org-babel-lob-ingest (buffer-file-name))
(let* ((named-element (org-element-map (org-element-parse-buffer) org-element-all-elements (lambda (element) (when (string= (org-element-property :name element) name) element)) nil t)) (result (org-element-property :value named-element))) (format "\"%s\"" (replace-regexp-in-string "\\\"" "\\\\\"" result))) ;; escape quote
(setq my-website-org-dir (file-name-as-directory "~/websites/org-website")) (setq my-website-blog-dir (file-name-as-directory (concat my-website-org-dir "blog"))) (setq my-website-publish-dir (file-name-as-directory "~/websites/akirakyle.com")) (defun my-blog-get-post-filenames () "Returns a list of all posts." (reverse (seq-filter (lambda (el) (not (string-match ".*index\\.org$" el))) (directory-files my-website-blog-dir t ".*\\.org$" nil)))) (defun my-org-get-env-key (post-filename key) "Extract the value of `#+title:`, `#+author:`, `#+date:`, or `#+filetags:` from post-filename." (with-temp-buffer (insert-file-contents post-filename) (plist-get (org-export-get-environment) key))) (defun my-blog-get-tag-tree () "Return an association list of tags to filenames. e.g. `(('foo' 'file1.org' 'file2.org') ('bar' 'file2.org'))`" (let ((tag-tree '())) (dolist (post-filename (my-blog-get-post-filenames)) (let ((tags (my-org-get-env-key post-filename :filetags))) (dolist (tag tags) (if (assoc-string tag tag-tree t) (push post-filename (cdr (assoc-string tag tag-tree t))) (push (cons tag (list post-filename)) tag-tree))))) tag-tree)) (defun my-blog-posts-to-list (post-filenames) (seq-reduce (lambda (acc el) (concat acc "\n- " el)) (seq-map (lambda (fname) (concat "/" (org-element-interpret-data (my-org-get-env-key fname :date)) "/ " (org-link-make-string (concat "file:" (file-relative-name fname)) (org-export-data-with-backend (my-org-get-env-key fname :title) 'org nil)))) post-filenames) "")) (defun my-blog-filenames-for-tag (tag) (reverse (cdr (seq-find (lambda (el) (string= (car el) tag)) (my-blog-get-tag-tree))))) (setq org-babel-default-header-args '((:session . "none") (:results . "replace") (:exports . "code") (:cache . "no") (:noweb . "no") (:hlines . "no") (:tangle . "no") (:eval . "no-export"))) ;; better to set :eval no-export than (setq org-export-use-babel nil) ;; https://stackoverflow.com/questions/23297422/org-mode-timestamp-format-when-exported ;; http://endlessparentheses.com/better-time-stamps-in-org-export.html ;;(setq org-export-date-timestamp-format "%B %e, %Y") (setq org-html-metadata-timestamp-format "%B %e, %Y") (setq org-html-htmlize-output-type 'css) (setq org-html-html5-fancy t) (setq org-publish-project-alist `( ("pages" :base-directory ,my-website-org-dir :publishing-directory ,my-website-publish-dir :recursive t :base-extension "org" :publishing-function org-html-publish-to-html :author "Akira Kyle" :email "akira@akirakyle.com" :with-author nil :with-toc nil :section-numbers nil :html-doctype "html5" :html-head-include-default-style nil :html-head-include-scripts nil :html-head nil :html-preamble nil :html-postamble nil ;:auto-sitemap t ;:sitemap-filename "sitemap.org" ;:sitemap-title "Akira Kyle's Blog" ) ("resources" :base-directory ,my-website-org-dir :publishing-directory ,my-website-publish-dir :recursive t :base-extension "svg\\|pdf\\|html\\|ico" :publishing-function org-publish-attachment ) ("website" :components ("pages" "resources")) )) (org-publish "website" t) (org-babel-tangle-file (buffer-file-name) (concat my-website-publish-dir "styles.css") "css") (org-babel-tangle-file (buffer-file-name) (concat my-website-publish-dir "scripts.js") "js") (write-region "akirakyle.com" nil (concat my-website-publish-dir "CNAME"))