Configuration

This file is a test of creating a derived org export customizing the output. We need a common prefix for our code generation and it will be domac as in do macroexpand. You are currently interactnig with the result of exporting and tangling this file.

HTML layout

Some fundamendental named building blocks for the page. These are referenced later on in our template transcoder.

Preamble
<!DOCTYPE html> <html> <head> <title>(do (macroexpand 'net))</title> <link rel="stylesheet" href="css/style.css"/> <script src="js/main.js"></script> <meta name="viewport" content="width=device-width, initial-scale=1" /> </head> <body> <div class="editor">
Postamble
</div> </body> </html>
Modifications to org

This subtree needs to be executed before attempting export. Use C-c C-v C-s here.

Teach babel to execute html

Define html src block as just returning itself quoted.

(defun org-babel-execute:html (body params) (if (eq (car (alist-get :var params)) 'js) (format "`%s`" body) (format "%S" body)))

Enable execution of this language.

(org-babel-do-load-languages 'org-babel-load-language '((html . t)))
Transcoders

Here we define any override we want to the html export backends transcoders. These functions that get hooked in throught the html derived backend.

Template

Important to call preamble and postamble or they will be inserted verbatim (incorrectly quoted). This is the overarching layout of the page.

(defun org-domac-template (contents info) (concat <<preamble-html()>> contents <<postamble-html()>>))
Headline
(defun org-domac-headline (headline contents info) (let ((level (org-export-get-relative-level headline info)) (title (org-element-property :raw-value headline))) (format "<org-outline level=%d><span slot=\"title\">%s</span>%s</org-outline>" level title contents)))
Src
(defun org-domac-src (src contents info) (let ((code (org-html-format-code src info)) (lang (org-element-property :language src)) (name (or (org-element-property :name src) ""))) (format "<org-src lang=%S name=%S>%s</org-src>" lang name code)))
Derived backend

Export of this page can be accomplished via C-c C-e x as per defined below.

(load-library "ox-html") (defun org-domac-export (a s v b) (org-export-to-file 'domac "index.html")) (org-export-define-derived-backend 'domac 'html :menu-entry '(?x "Domac" org-domac-export) :translate-alist '((template . org-domac-template) (headline . org-domac-headline) (src-block . org-domac-src)))
Linked resources

This subtree should be tangled to produce css/style.css and js/main.js. Use C-c C-v C-t here.

Styling

Some general css linked into the resulting page via preamble references.

Root
:root { --background: #242424; --foreground: #f6f3e8; --blue: #8ac6f2; --green: #95e454; --yellow: #cae682; --font-regular: "DejaVu Sans Mono, Monospace"; --size: 14px; } @media screen and (min-width: 800px) { :root { --size: 22px; } }
Reset
html, body { box-sizing: border-box; margin: 0; padding: 0; background: var(--background); } *, *:before, *:after { box-sizing: inherit; }
Editor
.editor { background: var(--background); color: var(--foreground); font-size: var(--size); font-family: var(--font-regular); padding: calc(var(--size) * 0.5); }
Links
a, a:hover, a:visited, a:active { color: var(--foreground); text-decoration: none; font-weight: bold; white-space: nowrap; } a:before { content: '[👉 '; } a:after { content: ']'; } a:hover:before, a:hover:after { color: var(--blue); }
Code
code { background: var(--yellow); font-size: 0.9em; padding: 0.1em; color: var(--background); border: solid 1px var(--green); font-family: monospace; }
Css file to tangle
<<root-css>> <<reset-css>> <<editor-css>> <<link-css>> <<code-css>>
Custom elements

Custom element definitions also get linked in via the preamble.

Outline
.org-outline { padding: 0 0 0 1em; border-left: solid 4px #8ac6f2; margin-left: calc(var(--size), 0.5); } .org-outline__title { cursor: pointer; font-size: 1.25em; font-weight: bold; color: #95e454; } .org-outline__title::marker { content: ""; } .org-outline__title:before { content: '+'; margin-right: 0.5em; } .org-outline[open] { margin-bottom: 1em; } .org-outline[open] .org-outline__title:before { content: '−'; } <style> <<org-outline-css>> </style> <details class="org-outline"> <summary class="org-outline__title"><slot name="title"></slot></summary> <slot></slot> </details> class OrgOutline extends HTMLElement { constructor () { super() this.attachShadow({ mode: 'open' }) const template = document.createElement('template') template.innerHTML = <<org-outline-template(js=1)>> this.shadowRoot.appendChild(template.content.cloneNode(true)) } connectedCallback () { const level = this.attributes.level.value if (level < 3) { this.shadowRoot.querySelector('details').open = true } } } customElements.define('org-outline', OrgOutline)
Src
.org-src { margin-top: 1em; margin-right: 1em; border: solid 2px #c4a5a5; } .org-src summary { display: flex; flex-flow: row nowrap; justify-content: space-between; cursor: pointer; padding: 0.35em; font-size: 1em; color: #444; background: #c4a5a5; font-family: Arial; } .org-src__name { color: #a82d20; font-weight: bold; } .org-src__name:before { content: 'name: '; color: #444; font-size: 0.8em; font-family: Hack; } .org-src__language { color: #fff; font-size: 0.9em; font-family: monospace; text-shadow: 1px 1px 2px #a82d20; } .org-src__code { overflow-x: scroll; margin: 0; font-family: Hack; padding: 0.5em; background: #111; color: #fff; font-size: 0.9em; } <link rel='stylesheet' href='//cdn.jsdelivr.net/npm/hack-font@3.3.0/build/web/hack-subset.css' /> <style> <<org-src-css>> </style> <details open="" class="org-src"> <summary> <span class="org-src__name"> <slot name="name"></slot> </span> <span class="org-src__language"> <slot name="language"></slot> </span> </summary> <pre class="org-src__code"><slot></slot></pre> </details> class OrgSrc extends HTMLElement { constructor () { super() this.attachShadow({ mode: 'open' }) const template = document.createElement('template') template.innerHTML = <<org-src-template(js=1)>> this.shadowRoot.appendChild(template.content.cloneNode(true)) } connectedCallback () { const language = this.attributes.lang.value const name = this.attributes.name.value this.shadowRoot.querySelector("slot[name='name']").innerHTML=name this.shadowRoot.querySelector("slot[name='language']").innerHTML=language } } customElements.define('org-src', OrgSrc)
Main javascript file

The main javascript file containing our custom element definitions.

<<org-outline>> <<org-src>>