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)