Blogging with Org Mode
I currently use spacemacs
, this is the setup I have in my .spacemacs
file.
It is used to publish the blog articles.
(defun dotspacemacs/user-config () "Configuration for user code: This function is called at the very end of Spacemacs startup, after layer configuration. Put your configuration code here, except for variables that should be set before packages are loaded." ;; omitted code (with-eval-after-load 'org ;; omitted code ;; project publish config (setq org-publish-project-alist `(("blog-articles" :base-directory "~/org/blog/" :recursive t :base-extension "org" :publishing-directory "~/org/www/blog/" :publishing-function org-html-publish-to-html ;; :exclude "PrivatePage.org" ;; regexp :headline-levels 4 :section-numbers nil :auto-sitemap t :sitemap-filename "sitemap.org" :sitemap-title "blog.jonasmitchell.com" :html-postamble nil :html-head-include-default-style nil :html-head ,(concat "<link rel=\"stylesheet\" type=\"text/css\" href=\"/styles/basic.css\" />" "<script src=\"/js/basic.js\"></script>") :html-preamble t) ("blog-resource" :base-directory "~/org/blog/resource/" :recursive t :base-extension "png\\|jpg\\|gif\\|pdf\\|mp3\\|ogg\\|swf\\|tf" :publishing-directory "~/org/www/blog/resource/" :publishing-function org-publish-attachment) ("blog-js" :base-directory "~/org/blog/js/" :recursive t :base-extension "js" :publishing-directory "~/org/www/blog/js/" :publishing-function org-publish-attachment) ("blog-styles" :base-directory "~/org/blog/styles/" :recursive t :base-extension "css" :publishing-directory "~/org/www/blog/styles/" :publishing-function org-publish-attachment) ("blog" :components ("blog-articles" "blog-resource" "blog-styles" "blog-js"))))))
My current js and css which get added to every page of the blog.
https://stackoverflow.com/questions/3337587/wrapping-a-set-of-dom-elements-using-javascript/13169465#13169465 // Wrap an HTMLElement around each element in an HTMLElement array. HTMLElement.prototype.wrap = function(elms) { // Convert `elms` to an array, if necessary. if (!elms.length) elms = [elms]; // Loops backwards to prevent having to clone the wrapper on the // first element (see `child` below). for (var i = elms.length - 1; i >= 0; i--) { var child = (i > 0) ? this.cloneNode(true) : this; var el = elms[i]; // Cache the current parent and sibling. var parent = el.parentNode; var sibling = el.nextSibling; // Wrap the element (is automatically removed from its current // parent). child.appendChild(el); // If the element had a sibling, insert the wrapper before // the sibling to maintain the HTML structure; otherwise, just // append it to the parent. if (sibling) { parent.insertBefore(child, sibling); } else { parent.appendChild(child); } } }; window.onload = function() { var headerIcons = [ { tag: "h2", icon:"radio_button_checked", style: "md-dark" }, { tag: "h3", icon:"radio_button_unchecked", style: "hd-dark" }, { tag: "h4", icon:"star", style: "hd-dark" }, { tag: "h5", icon:"star_border", style: "hd-dark" } ]; // function to add material icons to elements by tag name var addIconBeforeElementsByTagName = function addIconBeforeElementsByTagName(elementObj) { var elementList = document.getElementsByTagName(elementObj.tag); for (var i = 0; i < elementList.length; i++) { var element = elementList[i]; element.innerHTML = '<i class="material-icons ' + elementObj.style + ' "> ' + elementObj.icon +"</i> " + element.innerHTML; } }; // add icons to headings headerIcons.forEach(h => { addIconBeforeElementsByTagName(h); }); var wrapElements = function wrapElements(elements, wrapperClassName) { for (var i = 0; i < elements.length; i++) { var element = elements[i]; var wrapper = document.createElement("div"); wrapper.className = wrapperClassName; wrapper.wrap(element); } }; // function to wrap elements for css reasons var wrapElementsByClassName = function wrapElementsByClassName(className, wrapperClassName) { // wrap elements with divs var elements = document.getElementsByClassName(className); wrapElements(elements, wrapperClassName); }; // function to wrap elements for css reasons var wrapElementsByTagName = function wrapElementsByTagName(tagName, wrapperClassName) { // wrap elements with divs var elements = document.getElementsByTagName(tagName); wrapElements(elements, wrapperClassName); }; // function to wrap elements for css reasons var wrapElementsBySelector = function wrapElementsBySelector(tagName, wrapperClassName) { // wrap elements with divs var elements = document.querySelectorAll(tagName); wrapElements(elements, wrapperClassName); }; // function to wrap tables for css reasons var wrapTables = function wrapTables() { // wrap tables with divs with class table-wrapper wrapElementsByTagName("table", "table-wrapper"); }; var toggleTableOfContents = function toggleTableOfContents (event) { var tocElement = document.querySelector("#table-of-contents"); tocElement.style.display = tocElement.style.display ? "" : "inline"; }; var addMenuIcon = function addMenuIcon() { var iconType = document.createTextNode("toc"); var menuIcon = document.createElement("i"); menuIcon.className = "material-icons"; menuIcon.appendChild(iconType); var menuWrapper = document.createElement("div"); menuWrapper.className = "menu-wrapper"; menuWrapper.appendChild(menuIcon); menuWrapper.onclick = toggleTableOfContents; document.body.appendChild(menuWrapper); }; var closeTocOnClick = function closeTocOnClick() { var tocLinks = document.querySelectorAll("#table-of-contents a"); for (var i = 0; i < tocLinks.length; i++) { var link = tocLinks[i]; link.onclick = function(event) { toggleTableOfContents(event); }; } }; closeTocOnClick(); wrapTables(); addMenuIcon(); };
@import url("https://unpkg.com/normalize.css/normalize.css"); @import url('https://fonts.googleapis.com/css?family=Roboto:100,100i,300,300i,400,400i,500,500i,700,700i,900,900i|Source+Code+Pro:200,300,400,500,600,700,900&display=swap'); @import url('https://fonts.googleapis.com/icon?family=Material+Icons'); body { box-sizing: border-box; font-family: 'Source Code Pro', monospace; font-family: 'Roboto', sans-serif; background-color: #292b2e; color: #b2b2b2; padding: 0px 15px 0px 15px; } a { color: #2aa1ae; } h1 { color: #c56ec3; } h2 { color: #4f97d7; } h2:hover { background-color: #293239; } .outline-2 { padding-left: 5px; } h3 { color: #2d9574; } h3:hover { background-color: #293235; } .outline-3 { padding-left: 10px; } h4 { color: #67b11d; } h4:hover { background-color: #293235; } .outline-4 { padding-left: 15px; } h5 { color: #b1951d; } h5:hover { background-color: #32322c; } .outline-5 { padding-left: 20px; } .src, blockquote, pre.example { color: #cbc1d5; background-color: #2f2b33; outline: thick ridge #5d4d7a; padding: 5px; overflow-x: auto; } code { /* color: #28def0; */ color: #4f97d7; } .done { color: #86dc2f; background-color:#293235; font-weight: 700; } .todo { color: #dc752f; background-color: #32322c; font-weight: 700; } .timestamp-wrapper { color:#7590db; } .tag { color: #9f8766; float: right; } .tag>*::before, .tag>*:last-child::after { content: ":"; } img { max-width: calc(100vw - 75px); } table { color: #b2b2b2; background-color: #293239; } .table-wrapper { overflow-x: auto; } #table-of-contents { display: none; position: fixed; width: 100vw; height: 100vh; z-index: 10; background-color: #292b2e; top: 0px; } .menu-wrapper { position: fixed; z-index: 10; top: 10px; right: 10px; cursor: pointer; } /* #content { */ /* box-sizing: border-box; */ /* display: grid; */ /* grid-template-areas: */ /* 'toc heading heading heading heading heading' */ /* 'toc content content content content content' */ /* 'toc content content content content content' */ /* 'toc content content content content content'; */ /* grid-template-rows: repeat (auto-fll, auto); */ /* grid-template-columns: repeat(auto, 1fr); */ /* justify-content: start; */ /* } */ /* #title { */ /* grid-area: heading; */ /* } */ /* #table-of-contents { */ /* grid-area: toc; */ /* } */ /* .outline-2 { */ /* grid-area: content; */ /* } */ /* p.author author information, including email */ /* p.date publishing date */ /* p.creator creator info, about org mode version */ /* .title document title */ /* .subtitle document subtitle */ /* .todo TODO keywords, all not-done states */ /* .done the DONE keywords, all states that count as done */ /* .WAITING each TODO keyword also uses a class named after itself */ /* .timestamp timestamp */ /* .timestamp-kwd keyword associated with a timestamp, like ‘SCHEDULED’ */ /* .timestamp-wrapper span around keyword plus timestamp */ /* .tag tag in a headline */ /* ._HOME each tag uses itself as a class, “@” replaced by “_” */ /* .target target for links */ /* .linenr the line number in a code example */ /* .code-highlighted for highlighting referenced code lines */ /* div.outline-N div for outline level N (headline plus text) */ /* div.outline-text-N extra div for text at outline level N */ /* .section-number-N section number in headlines, different for each level */ /* .figure-number label like “Figure 1:” */ /* .table-number label like “Table 1:” */ /* .listing-number label like “Listing 1:” */ /* div.figure how to format an in-lined image */ /* pre.src formatted source code */ /* pre.example normal example */ /* p.verse verse paragraph */ /* div.footnotes footnote section headline */ /* p.footnote footnote definition paragraph, containing a footnote */ /* .footref a footnote reference number (always a <sup>) */ /* .footnum footnote number in footnote definition (always <sup>) */ /* .org-svg default class for a linked ‘.svg’ imag */