publishing static HTML
Table of Contents
1. Publish Static HTML
In particular, including this content.
Content formatted using org-mode.
Maintaining public .org content here: https://github.com/Rconybea/org-howto
1.1. base emacs configuration for publishing
See also https://orgmode.org/worg/org-tutorials/org-publish-html-tutorial.html
org-publish-project-alist configures org trees for publishing:
;; ---------------------------------------------------------------- ;; org-mode publishing ;; (require 'ox-publish) ;; publishing setup -- this is a kitchen sink -- it's intended to cover ;; everything we want org-mode to publish ;; (setq org-publish-project-alist '( ("org-howto" :components ("org-howto-notes" "org-howto-static")) ("org-howto-notes" :base-directory "~/proj/org-howto" :base-extension "org" :publishing-directory "~/proj/public_html/org-howto" :recursive t :publishing-function org-html-publish-to-html :headling-levels 4 :auto-preamble t ) ("org-howto-static" :base-directory "~/proj/org-howto" :base-extension "css\\|html\\|js\\|svg\\|png\\|jpg\\|gif\\|pdf\\|mp3\\|ogg\\|swf" :publishing-directory "~/proj/public_html/org-howto" :recursive t :publishing-function org-publish-attachment ) ) ; ... additional org trees here ... )
With this configuration
~M-x org-publish-project org-howto~
generates HTML content in ~/proj/public_html/org-howto~.
1.2. setup for literate programming
org-mode can automate weaving together content prepared by other programs,
for example graphviz.
~/.emacs Configuration for such adopted sources (as of 1oct2023 just graphviz):
;; ---------------------------------------------------------------- ;; org-mode babel setup ;; (execute dot/ditaa/bash/c++ etc. from .org code blocks) ;; ;; see ;; [[https://orgmode.org/worg/org-contrib/babel/intro.html]] ;; [[https://orgmode.org/worg/org-contrib/babel/languages/index.html]] ;; ;; code block: ;; #+begin_src ${language} ${switches} ${headerarguments} ;; ${body} ;; #+end_src ;; ;; use header argument ;; :results output ;; to insert code-block output (i.e. contents of stdout) into .org file below code block ;; ;; use ;; :results value ;; to just take value of last statement ;; ;; use ;; :session ;; to share language sub-process across code-blocks. ;; ;; can use ;; #+name: foo ;; to name an org-mode table; then: ;; #+begin_src ... :var myfreevar=foo ;; ... ;; #+end_src ;; with body mentioning myfreevar; .org will substitute foo ;; ;; can do inline coode block with ;; src_<${lang}>{${code}} or src_<${lang}[${args}]{${code}} ;; e.g. ;; src_python[:session]{10*x} ;; ;; notes: ;; [C-c C-v] org-babel prefix ;; [C-c C-v b] -- evaluate code blocks in buffer ;; [C-c C-v s] -- evaluate code blocks in subtree ;; [C-c C-v e] -- evaluate code block at point ;; [C-c '] M-x org-edit-src-code -- puts code block in new buffer with appropriate mode activated ;; [C-c M-b p] M-x org-babel-expand-src-block -- show expanded code block prior to evaluation ;; (org-babel-lob-ingest "path/to/file.org") to share code blogs as 'library' (org-babel-do-load-languages 'org-babel-load-languages '((ditaa . t) ; ditaa (dot . t) ; graphviz [[https://orgmode.org/worg/org-contrib/babel/languages/ob-doc-dot.html]] see also graphviz-dot-mode ))
Example .org content using graphviz:
#+begin_src dot :file img/living-room-av/macmini.svg :exports results :cmdline -Tsvg
digraph {
size="4,4";
rankdir=LR;
s [label="mac mini", shape="box"];
r [label="receiver", shape="box"];
m [label="monitor", shape="box"];
sp [label="spkr", shape="ellipse"];
s -> r[label="VDP",color="red"];
s -> m[label="input#2",color="blue"];
r -> sp[color="red"];
}
#+end_src
publishing (or using C-c C-v b) creates/updates file in img/living-room-av/macmini.svg
1.3. HTML theme
Using Fabrice Niessen's awesome readtheorg theme see org-html-themes
Cloned .setup file to org-howto/ext/fniessen/theme-readtheorg.setup.
Apply theme by including the following in each .org header:
# options used exclusively by the html exporter #+setupfile: ext/fniessen/theme-readtheorg.setup
1.4. display HTML locally
Once we have HTML in ~/proj/public_html/org-howto, can view it locally:
python3 -m http.server --directory ~/proj/public_html/org-howto 8080
then point browser to localhost:8080 (or for the content you're reading now: localhost:8080/env/development-environment.html)
Caveat: builtin python webserver doesn't support https.
1.5. publish to github pages
To work with github pages, We tweak the .org tree slightly:
cd ~/proj/org-howto
ln -s ext web
This is to match the github repo name https://github.com/Rconybea/web.
When we publish .org tree to github pages, it appears at https://rconybea.github.io/web
.org pages that want to use root-relative paths, prefix with /web:
#+infojs_opt: view:showall toc:nil ltoc:nil mouse:#ffc0c0 path:/web/ext/orginfo/org-info.js #+html_head: <link rel="stylesheet" type="text/css" href="/web/css/notebook.css" />
- github pages:
/web/ext/orginfo/org-info.jsresolves viaext/orginfo/org-info.js.. - natively hosted:
/web/ext/orginfo/org-info.jsresolves viaweb/ext/orginfo-org-info.js.
Note that org-publish expands the web symlink, so everything under the ext tree will be duplicated
1.6. package as docker container
We can snapshot and serve generated html in a dedicated docker container with this flake.nix
(in ~/proj/public_html, given html output written to ~/proj/public_html/org-howto)
{
description = "publish org-howto-derived html";
# dependencies of this flake
inputs = rec {
nixpkgs.url = "github:nixos/nixpkgs/23.05";
org_howto_path = {
url = "./org-howto";
flake = false;
};
};
outputs = { self, nixpkgs, org_howto_path } :
let
system = "x86_64-linux";
pkgs = import nixpkgs { inherit system; };
# creates shell script 'serve-org-howto'.
# to use:
# $ cd ~/proj/public_html
# A.
# $ nix build
# $ ./result/bin/serve-org-howto
# B.
# $ nix run
#
serve_org_howto_deriv = pkgs.writeShellScriptBin "serve-org-howto" ''
${pkgs.python3}/bin/python3 -m http.server 8080 --directory ${org_howto_path}
'';
# builds custom docker image!
serve_org_howto_docker_deriv =
let
serve_org_howto = self.packages.${system}.serve_org_howto;
in
pkgs.dockerTools.buildLayeredImage {
name = serve_org_howto.name;
tag = "1.0";
contents = [ serve_org_howto ];
config = {
Cmd = [ "/bin/serve-org-howto" ];
WorkingDir = "/";
};
};
in rec {
packages.${system} = {
default = serve_org_howto_deriv;
serve_org_howto = serve_org_howto_deriv;
serve_org_howto_docker = serve_org_howto_docker_deriv;
};
};
}
build docker container image using
~/proj/public_html/flake.nix:$ cd ~/proj/public_html $ nix build $ ls -ld result /nix/store/dck2rix8n8sx6wi0d4is0fq17c72ddqx-serve-org-howto.tar.gz
load image into docker
$ docker load <./result
or send to some other host:
$ mycloudhost=... $ scp /nix/store/dck2rix8n8sx6wi0d4is0fq17c72ddqx-serve-org-howto.tar.gz root@${mycloudhost} $ ssh ${mycloudhost} mycloudhost$ docker load < /nix/store/dck2rix8n8sx6wi0d4is0fq17c72ddqx-serve-org-howto.tar.gz mycloudhost$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE serve-org-howto 1.0 113e8c1232fa 53 years ago 165MB mycloudhost$ docker run serve-org-howtoHTML tree now served from
${mycloudhost}:8080Docker image contains only python and our html tree, so much smaller than typical image.