Post about blogging with org. develop master
authorJames Richardson <j@mesrichardson.com>
Mon, 16 Mar 2020 02:13:36 +0000 (22:13 -0400)
committerJames Richardson <j@mesrichardson.com>
Mon, 16 Mar 2020 02:13:36 +0000 (22:13 -0400)
.gitignore [new file with mode: 0644]
blog/blog.org [new file with mode: 0644]
blog/entry/blog-with-only-orgmode.org [new file with mode: 0644]
blog/header.html [new file with mode: 0644]
css/main.css [new file with mode: 0644]
css/org.css [new file with mode: 0644]
pages/about.org [new file with mode: 0644]
pages/header.html [new file with mode: 0644]
pages/index.org

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..b25c15b
--- /dev/null
@@ -0,0 +1 @@
+*~
diff --git a/blog/blog.org b/blog/blog.org
new file mode 100644 (file)
index 0000000..f8d60f8
--- /dev/null
@@ -0,0 +1,5 @@
+#+TITLE: Blog articles
+
+- [[file:theindex.org][Index]]
+- entry
+  - [[file:entry/blog-with-only-orgmode.org][blog-with-only-orgmode]]
\ No newline at end of file
diff --git a/blog/entry/blog-with-only-orgmode.org b/blog/entry/blog-with-only-orgmode.org
new file mode 100644 (file)
index 0000000..9f29024
--- /dev/null
@@ -0,0 +1,172 @@
+#+options: title:nil num:t
+
+#+TITLE: Blog With Only Orgmode
+#+DATE: <2020-03-15 Sun>
+
+This blog is now being written with [[https://orgmode.org/][org-mode]] and [[https://www.gnu.org/software/emacs][Emacs]]. I have been
+threatening to do so for a while now. I have previously used [[https://ikiwiki.info][ikiwiki]],
+which is also a static site generator. I have switched to org-mode,
+mainly because I like org markup better than [[https://en.wikipedia.org/wiki/Markdown][markdown]]. I write most
+everything else in org-mode; the context switch, I think, kept me from
+writing.[fn:1]
+
+* Blog files setup
+As I have decided that all I need is the [[https://orgmode.org/manual/Publishing.html][publishing features of
+org-mode]], I had to structure the sources for the blog smartly. I think
+I have come up with a structure that can be maintained and grokked
+by ~(org-publish)~ without requiring too much additional [[https://en.wikipedia.org/wiki/Emacs_Lisp][Emacs Lisp]].
+
+Another thing I am changing is not publishing directly from a
+=git hook=. Not publishing directly from a =git hook= allows easier
+writing across several computers. I have ~(org-publish)~ write to
+=~/public_html/jamestechnotes.com= for local testing.
+
+This is my setup, from which I borrowed heavily from [[https://ogbe.net/blog/blogging_with_org.html][Dennis Ogbe's
+writeup]]: 
++ All of my websites are beneath ~~/src/wikis~. This one is beneath
+  ~/src/wikis/jamestechnotes.com~. If you happen to be really
+  interested in the layout, all of the source is [[https://git.jamestechnotes.com/?p=jamestechnotes.com.git;a=summary][published]].[fn:2]
++ The elisp that glues all of this together is in my [[https://git.jamestechnotes.com/?p=james/home/home-etc.git;a=blob;f=.emacs.d/config/org.el;h=bb3385aaf086305e389ae6b7251f4f735589dedc;hb=HEAD][emacs config]];
+  relevant sections will be detailed below.
++ The blog files split into the following structure:
+  - =/pages/= --- Static pages, like the [[https://jamestechnotes.com][home page]], live here as org
+    files.
+  - =/css/= --- css files live here.
+  - =/blog/entry/= --- individual blog posts live here.
+  - =/img/= -- (Not yet implemented) images would live here.
+** How does this help?
+Hopefully, =/css/= and =/img/= are rather clear. They hold, well, css
+files and images. The images bother me. As images are binary
+artifacts, they are rather awkward[fn:3] to check into git. I suspect
+if I start accumulating large images, I will look into using some like
+[[https://git-annex.branchable.com][git annex]] to manage them.
+
+Static pages, which don't change often, live out of the way beneath
+=/pages/=. There is a separate publishing project just for these.
+
+Individual blog entries live in their own org file in
+=/blog/entry/=. If I actually start writing many post and the
+directory get unwieldy, I will have to hash the entries, probably by
+year. This section also has it's own publishing project, that also
+generates a sitemap index. Elisp will be developed to coerce this
+sitemap into a proper blog index.
+
+I have an elisp function, =jr/prepare-pages=, which looks for a file
+named =header.html= in the =base-directory= of the project. The
+function is called when ~(org-publish)~ generates the preamble of each
+page. I use this machinery to build the top navigation menu on the
+pages.
+
+A benefit of this layout, to which I did not pay attention, is the top
+directory of the web site contains no content that is
+publishable. Adding a todo.org file here will allow me to add [[https://www.orgmode.org/manual/TODO-Items.html][org todo
+items]]  with ideas for future blog post and have them show up in my
+[[https://orgmode.org/manual/Agenda-Views.html][Agenda]]. I could also add actual todo headline in actual blog posts and
+mark them =noexport= so they won't publish.
+
+* Show me the code
+While ~(org-publish)~ already does a lot out of the box, a bit of help
+is need to achieve the desired layout. First, links to stylesheets
+need to be added to the =<head>= of the document. The variable
+~jr/html-head~ contains text which is inserted in the document.
+#+BEGIN_SRC emacs-lisp
+  (setq jr/html-head
+        (concat
+         "<link rel=\"stylesheet\" href=\"/../css/org.css\" />\n" ;; start with org.css
+         "<link rel=\"stylesheet\" href=\"/../css/main.css\" />"))
+#+END_SRC
+=org.css= was copied from an exported html buffer. =main.css= contains
+custom layouts which will override the defaults from =org.css= and
+required.
+
+The =jr/prepare-pages= function mentioned earlier the inserts
+=header.html= into the preamble is listed here:
+#+BEGIN_SRC emacs-lisp
+  (defun jr/prepare-pages (plist)
+    (message "In the prepare pages.")
+    (message (plist-get plist :base-directory))
+    (let ((header (concat
+                   (file-name-as-directory
+                    (plist-get plist :base-directory))
+                   "header.html")))
+      (message header)
+      (when (file-exists-p header)
+        (with-temp-buffer
+          (insert-file-contents header)
+          (buffer-string)))))
+#+END_SRC
+
+Now comes the publishing project:
+#+BEGIN_SRC emacs-lisp
+  (setq org-publish-project-alist
+        `(("jamestechnotes-com" :components ("jamestechnotes-com-css"
+                                             "jamestechnotes-com-entries"
+                                             "jamestechnotes-com-pages"))
+          ("jamestechnotes-com-css"
+           :base-directory "~/src/wikis/jamestechnotes.com/css"
+           :publishing-directory "~/public_html/jamestechnotes.com/css"
+           :base-extension "css"
+           :publishing-function org-publish-attachment)
+          ("jamestechnotes-com-entries"
+           :base-directory "~/src/wikis/jamestechnotes.com/blog"
+           :publishing-directory "~/public_html/jamestechnotes.com/blog"
+           :recursive t
+           :publishing-function org-html-publish-to-html
+           :preparation-function jr/prepare-pages
+           :htmlized-source t
+           :with-toc nil
+           :section-numbers nil
+           :html-doctype "xhtml5"
+           :html-html5-fancy t
+           :html-head-include-default-style nil
+           :html-head-include-scripts nil
+           :html-head ,jr/html-head
+           :html-preamble jr/prepare-pages
+
+           :auto-sitemap t
+           :sitemap-filename "blog.org"
+           :sitemap-title "Blog articles"
+           :sitemap-sort-files anti-chronologically
+
+           :makeindex t)
+          ("jamestechnotes-com-pages"
+           :base-directory "~/src/wikis/jamestechnotes.com/pages"
+           :publishing-directory "~/public_html/jamestechnotes.com"
+           :publishing-function org-html-publish-to-html
+           :preparation-function jr/prepare-pages
+           :htmlized-source t
+           :with-toc nil
+           :section-numbers nil
+           :html-doctype "xhtml5"
+           :html-html5-fancy t
+           :html-head-include-default-style nil
+           :html-head-include-scripts nil
+           :html-head ,jr/html-head
+           :html-preamble jr/prepare-pages
+
+           :auto-sitemap t
+           :sitemap-filename "blog.org"
+           :sitemap-title "Blog articles"
+           :sitemap-sort-files anti-chronologically
+
+           :makeindex t)))
+#+END_SRC
+The interesting thing to note here is the use of quasiquote ~`~,
+which allows use of unquote ~,~ for ~:html-head~. ~:html-head~
+requires a string, not a variable containing a string. The ~unquote~
+and ~quasiquote~ allows this to function.
+
+* TODO adfadf                                                      :noexport:
+afdafdafsfas
+
+
+* Footnotes
+
+[fn:3] Git handles binary artifacts reasonably well. I just think such
+shouldn't be done in general. 
+
+[fn:2] All of the code I write (that isn't owned by others) lives in
+[[https://git.jamestechnotes.com][my git repositories]], including source for my websites.
+
+[fn:1]Well, at least that my excuse. ;)
diff --git a/blog/header.html b/blog/header.html
new file mode 100644 (file)
index 0000000..bac06d5
--- /dev/null
@@ -0,0 +1,13 @@
+<header>
+  <div class="banner">
+    <a id="myname" href="/">James Richardson</a>
+    <hr>
+    <nav>
+      <p>
+        <a href="/">Home</a>
+        <a href="/blog/blog.html">Blog</a>
+        <a href="/about.html">About</a>
+      </p>
+    </nav>
+  </div>
+</header>
diff --git a/css/main.css b/css/main.css
new file mode 100644 (file)
index 0000000..682ad20
--- /dev/null
@@ -0,0 +1,15 @@
+/* Layout myname */
+#myname {text-decoration: none; font-size: 200%; font-weight:bold; color: black;}
+
+/* Add space a bottom of #preamble, and center text */
+#preamble {margin-bottom: 30px; text-align: center;}
+
+/* header layout */
+.banner nav {font-size: 115%; font-weight: bolder; }
+.banner nav a {color: blue; text-decoration: none; height: 30px;}
+.banner p {word-spacing: .5em; margin: 0;}
+
+/* set content width, so it will center. */
+#content {width: 80%; margin-left: auto; margin-right: auto;}
+/* hide this for now */
+#postamble {display: none;}
diff --git a/css/org.css b/css/org.css
new file mode 100644 (file)
index 0000000..b0cf6b2
--- /dev/null
@@ -0,0 +1,180 @@
+.title  { text-align: center;
+           margin-bottom: .2em; }
+.subtitle { text-align: center;
+            font-size: medium;
+            font-weight: bold;
+            margin-top:0; }
+.todo   { font-family: monospace; color: red; }
+.done   { font-family: monospace; color: green; }
+.priority { font-family: monospace; color: orange; }
+.tag    { background-color: #eee; font-family: monospace;
+          padding: 2px; font-size: 80%; font-weight: normal; }
+.timestamp { color: #bebebe; }
+.timestamp-kwd { color: #5f9ea0; }
+.org-right  { margin-left: auto; margin-right: 0px;  text-align: right; }
+.org-left   { margin-left: 0px;  margin-right: auto; text-align: left; }
+.org-center { margin-left: auto; margin-right: auto; text-align: center; }
+.underline { text-decoration: underline; }
+#postamble p { font-size: 90%; margin: .2em; }
+p.verse { margin-left: 3%; }
+pre {
+  border: 1px solid #ccc;
+  box-shadow: 3px 3px 3px #eee;
+  padding: 8pt;
+  font-family: monospace;
+  overflow: auto;
+  margin: 1.2em;
+}
+pre.src {
+  position: relative;
+  overflow: visible;
+  padding-top: 1.2em;
+}
+pre.src:before {
+  display: none;
+  position: absolute;
+  background-color: white;
+  top: -10px;
+  right: 10px;
+  padding: 3px;
+  border: 1px solid black;
+}
+pre.src:hover:before { display: inline;}
+/* Languages per Org manual */
+pre.src-asymptote:before { content: 'Asymptote'; }
+pre.src-awk:before { content: 'Awk'; }
+pre.src-C:before { content: 'C'; }
+/* pre.src-C++ doesn't work in CSS */
+pre.src-clojure:before { content: 'Clojure'; }
+pre.src-css:before { content: 'CSS'; }
+pre.src-D:before { content: 'D'; }
+pre.src-ditaa:before { content: 'ditaa'; }
+pre.src-dot:before { content: 'Graphviz'; }
+pre.src-calc:before { content: 'Emacs Calc'; }
+pre.src-emacs-lisp:before { content: 'Emacs Lisp'; }
+pre.src-fortran:before { content: 'Fortran'; }
+pre.src-gnuplot:before { content: 'gnuplot'; }
+pre.src-haskell:before { content: 'Haskell'; }
+pre.src-hledger:before { content: 'hledger'; }
+pre.src-java:before { content: 'Java'; }
+pre.src-js:before { content: 'Javascript'; }
+pre.src-latex:before { content: 'LaTeX'; }
+pre.src-ledger:before { content: 'Ledger'; }
+pre.src-lisp:before { content: 'Lisp'; }
+pre.src-lilypond:before { content: 'Lilypond'; }
+pre.src-lua:before { content: 'Lua'; }
+pre.src-matlab:before { content: 'MATLAB'; }
+pre.src-mscgen:before { content: 'Mscgen'; }
+pre.src-ocaml:before { content: 'Objective Caml'; }
+pre.src-octave:before { content: 'Octave'; }
+pre.src-org:before { content: 'Org mode'; }
+pre.src-oz:before { content: 'OZ'; }
+pre.src-plantuml:before { content: 'Plantuml'; }
+pre.src-processing:before { content: 'Processing.js'; }
+pre.src-python:before { content: 'Python'; }
+pre.src-R:before { content: 'R'; }
+pre.src-ruby:before { content: 'Ruby'; }
+pre.src-sass:before { content: 'Sass'; }
+pre.src-scheme:before { content: 'Scheme'; }
+pre.src-screen:before { content: 'Gnu Screen'; }
+pre.src-sed:before { content: 'Sed'; }
+pre.src-sh:before { content: 'shell'; }
+pre.src-sql:before { content: 'SQL'; }
+pre.src-sqlite:before { content: 'SQLite'; }
+/* additional languages in org.el's org-babel-load-languages alist */
+pre.src-forth:before { content: 'Forth'; }
+pre.src-io:before { content: 'IO'; }
+pre.src-J:before { content: 'J'; }
+pre.src-makefile:before { content: 'Makefile'; }
+pre.src-maxima:before { content: 'Maxima'; }
+pre.src-perl:before { content: 'Perl'; }
+pre.src-picolisp:before { content: 'Pico Lisp'; }
+pre.src-scala:before { content: 'Scala'; }
+pre.src-shell:before { content: 'Shell Script'; }
+pre.src-ebnf2ps:before { content: 'ebfn2ps'; }
+/* additional language identifiers per "defun org-babel-execute"
+     in ob-*.el */
+pre.src-cpp:before  { content: 'C++'; }
+pre.src-abc:before  { content: 'ABC'; }
+pre.src-coq:before  { content: 'Coq'; }
+pre.src-groovy:before  { content: 'Groovy'; }
+/* additional language identifiers from org-babel-shell-names in
+   ob-shell.el: ob-shell is the only babel language using a lambda to put
+   the execution function name together. */
+pre.src-bash:before  { content: 'bash'; }
+pre.src-csh:before  { content: 'csh'; }
+pre.src-ash:before  { content: 'ash'; }
+pre.src-dash:before  { content: 'dash'; }
+pre.src-ksh:before  { content: 'ksh'; }
+pre.src-mksh:before  { content: 'mksh'; }
+pre.src-posh:before  { content: 'posh'; }
+/* Additional Emacs modes also supported by the LaTeX listings package */
+pre.src-ada:before { content: 'Ada'; }
+pre.src-asm:before { content: 'Assembler'; }
+pre.src-caml:before { content: 'Caml'; }
+pre.src-delphi:before { content: 'Delphi'; }
+pre.src-html:before { content: 'HTML'; }
+pre.src-idl:before { content: 'IDL'; }
+pre.src-mercury:before { content: 'Mercury'; }
+pre.src-metapost:before { content: 'MetaPost'; }
+pre.src-modula-2:before { content: 'Modula-2'; }
+pre.src-pascal:before { content: 'Pascal'; }
+pre.src-ps:before { content: 'PostScript'; }
+pre.src-prolog:before { content: 'Prolog'; }
+pre.src-simula:before { content: 'Simula'; }
+pre.src-tcl:before { content: 'tcl'; }
+pre.src-tex:before { content: 'TeX'; }
+pre.src-plain-tex:before { content: 'Plain TeX'; }
+pre.src-verilog:before { content: 'Verilog'; }
+pre.src-vhdl:before { content: 'VHDL'; }
+pre.src-xml:before { content: 'XML'; }
+pre.src-nxml:before { content: 'XML'; }
+/* add a generic configuration mode; LaTeX export needs an additional
+   (add-to-list 'org-latex-listings-langs '(conf " ")) in .emacs */
+pre.src-conf:before { content: 'Configuration File'; }
+
+table { border-collapse:collapse; }
+caption.t-above { caption-side: top; }
+caption.t-bottom { caption-side: bottom; }
+td, th { vertical-align:top;  }
+th.org-right  { text-align: center;  }
+th.org-left   { text-align: center;   }
+th.org-center { text-align: center; }
+td.org-right  { text-align: right;  }
+td.org-left   { text-align: left;   }
+td.org-center { text-align: center; }
+dt { font-weight: bold; }
+.footpara { display: inline; }
+.footdef  { margin-bottom: 1em; }
+.figure { padding: 1em; }
+.figure p { text-align: center; }
+.equation-container {
+  display: table;
+  text-align: center;
+  width: 100%;
+}
+.equation {
+  vertical-align: middle;
+}
+.equation-label {
+  display: table-cell;
+  text-align: right;
+  vertical-align: middle;
+}
+.inlinetask {
+  padding: 10px;
+  border: 2px solid gray;
+  margin: 10px;
+  background: #ffffcc;
+}
+#org-div-home-and-up
+ { text-align: right; font-size: 70%; white-space: nowrap; }
+textarea { overflow-x: auto; }
+.linenr { font-size: smaller }
+.code-highlighted { background-color: #ffff00; }
+.org-info-js_info-navigation { border-style: none; }
+#org-info-js_console-label
+  { font-size: 10px; font-weight: bold; white-space: nowrap; }
+.org-info-js_search-highlight
+  { background-color: #ffff00; color: #000000; font-weight: bold; }
+.org-svg { width: 90%; }
diff --git a/pages/about.org b/pages/about.org
new file mode 100644 (file)
index 0000000..425d8cb
--- /dev/null
@@ -0,0 +1,12 @@
+#+TITLE: About - James Richardson's Engineering Notebook
+#+AUTHOR: James Richardson
+#+EMAIL: j@mesrichardson.com
+#+DATE:
+#+STARTUP: showall
+#+STARTUP: inlineimages
+
+#+options: title:nil
+
+Nothing here yet.
+
+See [[https://jamestechnotes.com/blog/blog.html][blog posts]] or [[https://jamesrichardson.name][my personal site]].
diff --git a/pages/header.html b/pages/header.html
new file mode 100644 (file)
index 0000000..bac06d5
--- /dev/null
@@ -0,0 +1,13 @@
+<header>
+  <div class="banner">
+    <a id="myname" href="/">James Richardson</a>
+    <hr>
+    <nav>
+      <p>
+        <a href="/">Home</a>
+        <a href="/blog/blog.html">Blog</a>
+        <a href="/about.html">About</a>
+      </p>
+    </nav>
+  </div>
+</header>
index 19ed55a7a09e45de509d3d02f5320e03d854edd6..af72d6285459da44843ffd962e6999c6241ea0d4 100644 (file)
@@ -7,7 +7,11 @@
 
 #+options: title:nil
 
-* this is a test page
+Welcome!
+
+[[https://jamestechnotes.com/blog/blog.html][Here]] is my technical blog. I also have a [[https://jamesrichardson.name][personal]] site.
+
+