The website is created from org-mode documents. Just change the .html
extension of a page to .org.html
to see the org source 😃.
To produce the screenshots/screencasts in features, I did the following:
- Use the doom-one-light theme
- Use 24pt Source Code Pro
- Use a frame 50 columns wide, and 10–20 lines tall
- No
org-superstar
(prettify-symbols-mode -1)
(setq org-pretty-entities nil)
(setq org-hide-leading-stars nil)
(setq org-link-descriptive nil)
(org-restart-font-lock)
From here, I either use emacs-gif-screencast or the following function:
(defun org-screenshot-svg ()
"Save a screenshot of the current frame as an SVG image.
Saves to a file in ~/Pictures/Org and puts the filename in the kill ring."
(interactive)
(let* ((filename (expand-file-name (format-time-string "~/Pictures/Org/%H:%M.svg")))
(data (x-export-frames nil 'svg)))
(with-temp-file filename
(insert data))
(kill-new filename)
(message filename)))
For easy development, there are some little snippets which make SASS
recompilation, HTML exporting, and rsync
all happen automatically.
The "DESTINATION"
needs customising for your particular environment.
(defvar bulk-save nil)
(defvar batch-export nil)
(defvar org-website-folder (file-name-directory (buffer-file-name)))
(defun org-website-sync ()
(let ((file-name (buffer-file-name)))
(when (and (s-contains-p "orgweb" file-name)
(not (and (s-contains-p "html" file-name)
(file-exists-p (s-replace ".html" ".org" file-name))))
(not (s-contains-p ".git" file-name))
(not batch-export))
(when (s-contains-p ".scss" file-name)
(setq sassc-output (shell-command-to-string
(format "sassc %s %s"
file-name
(concat (file-name-sans-extension file-name) ".css"))))
(unless (string-empty-p sassc-output)
(message "Sassc error: %s" sassc-output)))
(when (s-contains-p ".org" file-name)
(unless (string= (file-name-base file-name) "setup")
(let ((org-html-style-default "")
(org-html-scripts ""))
(org-html-export-to-html)))
(htmlize-file file-name (concat file-name ".html")))
(unless bulk-save
(message "= Performing bulk save (triggerd by %s." file-name)
(let ((bulk-save t))
(save-some-buffers t)
(temp-buffer-window-show
(get-buffer-create "*orgweb rsync*"))
(set-process-sentinel
(start-process
"rsync"
(get-buffer "*orgweb rsync*")
"rsync"
"-avz" "--delete" org-website-folder "DESTINATION")
(lambda (p e)
(when (= 0 (process-exit-status p))
(delete-window (get-buffer-window "*orgweb rsync*"))))))))))
(add-hook 'after-save-hook #'org-website-sync)
(defun org-website-batch-export ()
(interactive)
(let ((batch-export t)
(files (directory-files org-website-folder t "\\.org$"))
(errors nil))
(dolist (file files)
(message "exporting: %s" file)
(with-current-buffer (find-file-noselect file)
(condition-case nil
(org-html-export-to-html)
(error (setq errors (append errors file))))))
(message "finished exporting. Experienced errors with:%s" (if errors (concat "\n - " (s-join "\n - " errors)) ""))))
We use a little shell hack to immediately call Emacs on the file
#!/usr/bin/env sh
":"; exec emacs --quick --script "$0" -- "$@" # -*- mode: emacs-lisp; lexical-binding: t; -*-
Then we can execute some Elisp. This requires the htmlize
package, and
ignore-headlines
from ox-extra
.
(require 'ox)
(require 'ox-html)
(load "~/.emacs.d/.local/straight/repos/emacs-htmlize/htmlize.el" t t) ; system-dependant
(require 'htmlize)
(load "~/.emacs.d/.local/straight/repos/org-mode/contrib/lisp/ox-extra.el" t t)
(require 'ox-extra)
(ox-extras-activate '(ignore-headlines))
(setq
org-html-style-default ""
org-html-scripts ""
org-html-htmlize-output-type 'css
org-html-doctype "html5"
org-html-html5-fancy t
org-html-validation-link nil
org-html-postamble t
org-html-postamble-format
'(("en" "<p class=\"author\">Made with <a href=\"https://orgmode.org/worg/org-site-colophon.html\">🤎</a> by <a href=\"https://github.com/tecosaur/\" style=\"font-weight: bold; font-size: 0.9em; letter-spacing: 1px\">TEC</a></p>
<p xmlns:dct=\"http://purl.org/dc/terms/\" xmlns:cc=\"http://creativecommons.org/ns#\" class=\"license-text\" style=\"color: #aaa\">licensed under <a rel=\"license\" href=\"https://creativecommons.org/licenses/by-sa/4.0/\"><img class=\"inline\" src=\"/resources/img/external/cc-by-sa.svg\" title=\"CC-BY-SA 4.0\" alt=\"CC-BY-SA\"/></a></p>"))
make-backup-files nil
debug-on-error t)
(let ((scss-files (directory-files-recursively default-directory "\\.scss$"))
(org-files (directory-files-recursively default-directory "\\.org$")))
(if (executable-find "sassc")
(dolist (scss-file scss-files)
(let ((sassc-out
(shell-command-to-string
(format "sassc %s %s"
scss-file (concat (file-name-sans-extension scss-file) ".css")))))
(message "\033[0;35m• %s%s\033[0m" (file-relative-name scss-file default-directory)
(if (string= "" sassc-out) "" (concat ":\033[31m\n" sassc-out)))))
(message "No sassc executable found"))
(dolist (org-file org-files)
(message "\033[0;34m• %s\033[90m" (file-relative-name org-file default-directory))
(with-current-buffer (find-file-literally org-file)
(condition-case err
(progn (org-html-export-to-html)
(htmlize-file org-file (concat org-file ".html")))
(error (message " \033[0;31m%s\033[90m" (error-message-string err)))))))
(message "\033[0m")
(kill-emacs 0)