About Projects GitLab GitHub Page-Source

Ody55eus.gitlab.io Readme

This code generates my webpage.

I created this page using Emacs OrgMode. To learn more about OrgMode and publishing org files, see respective links to the original documentation.

Org Babel Tangle

This Readme contains the entire configuration needed to export the Org Roam (Zettelkasten) directory located in digital-garden/.

The default variables are stored in the INFO file:

To read these variables, Emacs executes the following line in shell whenever gvar(variable) gets called in this org file:

cat ./INFO | grep -i $variable | cut -d "|" -f3

For Example, the version is .

Writing

This code block lets me set the Org Roam (Zettelkasten) directory to the digital-garden/ folder for the current buffer. Additionally the org-roam-capture-templates and the org-roam-db-location are updated to create a new org-roam.db file and update org capture temlates.

Init.el

Be careful, when using this code. Changing your OrgMode directories can break some configurations. When using (jp/init-webpage) the old Org Roam files are no longer available. There should be a better way to do this (maybe something like this emacs-profiles.el from benoitj or config-local-file).

Requires find-lisp

You need the package find-lisp installed in your local Emacs config.

(require 'find-lisp)

Initialize local variables

(defun jp/init-webpage ()
  (defvar jp/url "https://ody5.eu")
  (defvar jp/gl-url "https://gitlab.ody5.de")
  (defvar jp/repository "https://gitlab.com/ody55eus/digital-garden")
  (defvar jp/root (expand-file-name "."))
  (defvar jp/zk-root (expand-file-name "digital-garden" jp/root))
  (setq org-roam-directory (concat
                            jp/root
                            "/digital-garden/")
        org-roam-v2-ack t
        org-link-abbrev-alist '(("gitlab" . "https://gitlab.com/")
                                ("github" . "https://github.com/")
                                ("ody5" . (concat jp/gl-url "/"))
                                )
        org-directory (concat
                       jp/root
                       "/digital-garden/")
        org-roam-db-location (concat jp/root "/org-roam.db")
        org-id-extra-files (find-lisp-find-files org-roam-directory "\.org$")
        org-roam-capture-templates '(("d" "default" plain
                                      "%?\n\nSee also %a.\n"
                                      :if-new (file+head
                                               "${slug}.org"
                                               "#+title: ${title}\n")
                                      :unnarrowed t)
                                     ("b" "Blog Entry" plain
                                      "%?"
                                      :if-new (file+head
                                               "Blog/${slug}.org"
                                               "#+title: ${title}\n#+date: %U")
                                      :unnarrowed t
                                      )
                                     ("l" "Literature")
                                     ("ll" "Literature Note" plain
                                      "%?\n\nSee also %a.\n* Links\n- %x\n* Notes\n"
                                      :if-new (file+head
                                               "Literature/${slug}.org"
                                               "#+title: ${title}\n")
                                      :unnarrowed t
                                      )
                                     ("lr" "Bibliography reference" plain
                                      "#+ROAM_KEY: %^{citekey}\n#+PROPERTY: type %^{entry-type}\n#+FILETAGS: %^{keywords}\n#+AUTHOR: %^{author}\n%?"
                                      :if-new (file+head
                                               "References/${citekey}.org"
                                               "#+title: ${title}\n")
                                      :unnarrowed t
                                      )
                                     ("p" "Projects" plain
                                      "%?"
                                      :if-new (file+head
                                               "Projects/${slug}.org"
                                               "#+title: ${title}\n")
                                      :unnarrowed t
                                      )
                                     )))

Publish

Gitlab CI

This configuration loads my docker image ody55eus/emacs-straight and executes the Publish.el.

image: ody55eus/emacs-straight

pages:
  before_script:
    - git clone https://gitlab.com/ody55eus/dotfiles.git
  script:
    - emacs --quick --script publish.el --funcall=jp/publish-html
  artifacts:
    paths:
      - public
  only:
    - main
    - feature/*

GitHub Actions

name: Publish to GitHub Pages

on:
  push:
    branches:
      - main
      - feature/*

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - name: Check out
        uses: actions/checkout@v1

      - name: Install Emacs
        run: sudo apt install emacs-nox --yes

      - name: Clone dotfiles
        run: git clone https://gitlab.com/ody55eus/dotfiles.git

      - name: Build the site
        run: emacs --quick --script publish.el --funcall=jp/publish-html

      - name: Publish generated content to GitHub Pages
        uses: JamesIves/github-pages-deploy-action@4.1.4
        with:
          branch: gh-pages
          folder: public

Makefile

##
# Ody55eus.gitlab.io
#
# @version <<gvar("version")>>

make: html

install:
        emacs --quick --script requirements.el

download-puml:
        curl -L http://sourceforge.net/projects/plantuml/files/plantuml.jar/download > ~/plantuml.jar

diag:
        java -jar ~/plantuml.jar diag/*

html:
        emacs --quick --script publish.el --funcall=jp/publish-html

clean:
        rm -f *.cache && rm -rf public && rm -f diag/*.png
# end

Publish.el

Inspired from ambrevar, SystemCrafters and commonplace.

Install

Requirements: org-roam, htmlize, esxml, webfeeder Unfortunately the org-roam package is needed to translate the page. We install this with straight:

(defvar bootstrap-version)
(let ((bootstrap-file
       (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
      (bootstrap-version 5))
  (unless (file-exists-p bootstrap-file)
    (with-current-buffer
        (url-retrieve-synchronously
         "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
         'silent 'inhibit-cookies)
      (goto-char (point-max))
      (eval-print-last-sexp)))
  (load bootstrap-file nil 'nomessage))

(straight-use-package 'org-roam)
(straight-use-package 'htmlize)
(straight-use-package 'esxml)
(straight-use-package 'webfeeder)
(require 'ox-publish)
(require 'ox-html)
(require 'org-roam)
(require 'find-lisp)
(require 'htmlize)

Define jp/init-webpage

Same as in Initialize local variables:

(defun jp/init-webpage ()
  (defvar jp/url "https://ody5.eu")
  (defvar jp/gl-url "https://gitlab.ody5.de")
  (defvar jp/repository "https://gitlab.com/ody55eus/digital-garden")
  (defvar jp/root (expand-file-name "."))
  (defvar jp/zk-root (expand-file-name "digital-garden" jp/root))
  (setq org-roam-directory (concat
                            jp/root
                            "/digital-garden/")
        org-roam-v2-ack t
        org-link-abbrev-alist '(("gitlab" . "https://gitlab.com/")
                                ("github" . "https://github.com/")
                                ("ody5" . (concat jp/gl-url "/"))
                                )
        org-directory (concat
                       jp/root
                       "/digital-garden/")
        org-roam-db-location (concat jp/root "/org-roam.db")
        org-id-extra-files (find-lisp-find-files org-roam-directory "\.org$")
        org-roam-capture-templates '(("d" "default" plain
                                      "%?\n\nSee also %a.\n"
                                      :if-new (file+head
                                               "${slug}.org"
                                               "#+title: ${title}\n")
                                      :unnarrowed t)
                                     ("b" "Blog Entry" plain
                                      "%?"
                                      :if-new (file+head
                                               "Blog/${slug}.org"
                                               "#+title: ${title}\n#+date: %U")
                                      :unnarrowed t
                                      )
                                     ("l" "Literature")
                                     ("ll" "Literature Note" plain
                                      "%?\n\nSee also %a.\n* Links\n- %x\n* Notes\n"
                                      :if-new (file+head
                                               "Literature/${slug}.org"
                                               "#+title: ${title}\n")
                                      :unnarrowed t
                                      )
                                     ("lr" "Bibliography reference" plain
                                      "#+ROAM_KEY: %^{citekey}\n#+PROPERTY: type %^{entry-type}\n#+FILETAGS: %^{keywords}\n#+AUTHOR: %^{author}\n%?"
                                      :if-new (file+head
                                               "References/${citekey}.org"
                                               "#+title: ${title}\n")
                                      :unnarrowed t
                                      )
                                     ("p" "Projects" plain
                                      "%?"
                                      :if-new (file+head
                                               "Projects/${slug}.org"
                                               "#+title: ${title}\n")
                                      :unnarrowed t
                                      )
                                     )))
(jp/init-webpage)

Set important export variables

  • Org Export Settings
    ;; Timestamps can be used to avoid rebuilding everything.
    ;; This is useful locally for testing.
    ;; It won't work on Gitlab when stored in ./: the timestamps file should
    ;; probably be put inside the public/ directory.  It's not so useful there
    ;; however since generation is fast enough.
    (setq org-publish-use-timestamps-flag t
          org-publish-timestamp-directory "./")
    
    ;; Get rid of index.html~ and the like that pop up during generation.
    (setq make-backup-files nil)
    
    (setq org-export-with-section-numbers nil
          org-export-with-smart-quotes t
          org-export-with-email t
          org-export-with-date t
          org-export-with-tags 'not-in-toc
          org-export-with-toc t
          org-html-container-element "section"
          org-html-metadata-timestamp-format "%Y-%m-%d"
          org-html-checkbox-type 'html
          org-html-html5-fancy t
          org-html-validation-link nil
          org-html-doctype "html5")
    
  • Preamble
    (defun jp/preamble (info)
      "Return preamble as a string."
      (let* ((file (plist-get info :input-file))
             (gitlab-url "https://gitlab.com/ody55eus")
             (github-url "https://github.com/ody55eus")
             (prefix (file-relative-name jp/zk-root
                                         (file-name-directory file)))
             (prefix2 (file-relative-name
                                         (file-name-directory file)
                                         jp/zk-root))
             (filename (file-name-nondirectory file))
             (filepath (if (string-equal prefix2 ".")
                               filename
                               (concat prefix2 filename))))
        (format
         (concat
         "<a href=\"%1$s/index.html\"><i class=\"fa fa-home\"></i> About</a>
    <a href=\"%1$s/Projects/projects.html\"><i class=\"fa fa-folder-open\"></i> Projects</a>
    <img class=\"logo\" src=\"%1$s/logo.png\">
    <span class=\"banner\"><a
      href=\"%4$s\"><i class=\"fa fa-gitlab\"></i></a><a
      href=\"%5$s\"><i class=\"fa fa-github\"></i></a>Ody55eus</span>
    <span class=\"source\"><a href=\"%3$s/-/tree/main/%2$s\"><i class=\"fa fa-code\"></i> Page-Source</a></span>
    ")
         prefix filepath jp/repository gitlab-url github-url)))
    
     ;; Use custom preamble function to compute relative links.
     org-html-preamble #'jp/preamble
    
  • Postamble
    (setq ;; org-html-divs '((preamble "header" "top")
     ;;                 (content "main" "content")
     ;;                 (postamble "footer" "postamble"))
     org-html-postamble t
     org-html-postamble-format `(("en" ,(concat "<p class=\"comments\"><a href=\""
                                                jp/repository "/issues\">Comments</a></p>
    
    <p class=\"date\">Date: %u</p>
    <p class=\"creator\">Made with %c</p>
    <p class=\"license\">
      &copy; 2021/2022 Jonathan Pieper
      <a rel=\"license\" href=\"https://www.gnu.org/licenses/gpl-3.0.en.html\"><img alt=\"GNU General Public License\" width=\"64px\" style=\"border-width:0\" src=\"https://www.gnu.org/graphics/gplv3-127x51.png\" /></a>
      <a rel=\"license\" href=\"http://creativecommons.org/licenses/by-sa/4.0/\"><img alt=\"Creative Commons License\" width=\"64px\" style=\"border-width:0\" src=\"https://mirrors.creativecommons.org/presskit/buttons/88x31/png/by-sa.png\" /></a>
    </p>")))
    )
    
  • Htmlize
    (setq org-html-style-plain org-html-style-default
          org-html-htmlize-output-type 'css)
    

Define some helper functions

  • Git Helper
    ;; Some help functions
    (defun jp/git-creation-date (file)
      "Return the first commit date of FILE.
    Format is %Y-%m-%d."
      (with-temp-buffer
        (call-process "git" nil t nil "log" "--reverse" "--date=short" "--pretty=format:%cd" file)
        (goto-char (point-min))
        (buffer-substring-no-properties (line-beginning-position) (line-end-position))))
    
    (defun jp/git-last-update-date (file)
      "Return the last commit date of FILE.
    Format is %Y-%m-%d."
      (with-output-to-string
        (with-current-buffer standard-output
          (call-process "git" nil t nil "log" "-1" "--date=short" "--pretty=format:%cd" file))))
    
    (defun jp/org-html-format-spec (info)
      "Return format specification for preamble and postamble.
    INFO is a plist used as a communication channel.
    Just like `org-html-format-spec' but uses git to return creation and last update
    dates.
    The extra `u` specifier displays the creation date along with the last update
    date only if they differ."
      (let* ((timestamp-format (plist-get info :html-metadata-timestamp-format))
             (file (plist-get info :input-file))
             (meta-date (org-export-data (org-export-get-date info timestamp-format)
                                         info))
             (creation-date (if (string= "" meta-date)
                                (jp/git-creation-date file)
                              ;; Default to the #+DATE value when specified.  This
                              ;; can be useful, for instance, when Git gets the file
                              ;; creation date wrong if the file was renamed.
                              meta-date))
             (last-update-date (jp/git-last-update-date file)))
        `((?t . ,(org-export-data (plist-get info :title) info))
          (?s . ,(org-export-data (plist-get info :subtitle) info))
          (?d . ,creation-date)
          (?T . ,(format-time-string timestamp-format))
          (?a . ,(org-export-data (plist-get info :author) info))
          (?e . ,(mapconcat
                  (lambda (e) (format "<a href=\"mailto:%s\">%s</a>" e e))
                  (split-string (plist-get info :email)  ",+ *")
                  ", "))
          (?c . ,(plist-get info :creator))
          (?C . ,last-update-date)
          (?v . ,(or (plist-get info :html-validation-link) ""))
          (?u . ,(if (string= creation-date last-update-date)
                     creation-date
                   (format "%s (<a href=%s>Last update: %s</a>)"
                           creation-date
                           (format "%s/commits/main/%s" jp/repository (file-relative-name file jp/zk-root))
                           last-update-date))))))
    (advice-add 'org-html-format-spec :override 'jp/org-html-format-spec)
    
    
  • Find Date

    jp/org-publish-find-date is just like org-publish-find-date just uses git instead and does not fall back on file system timestamp and returns nil instead.

    (defun jp/org-publish-find-date (file project)
      "Find the date of FILE in PROJECT.
    Just like `org-publish-find-date' but do not fall back on file
    system timestamp and return nil instead."
      (let ((file (org-publish--expand-file-name file project)))
        (or (org-publish-cache-get-file-property file :date nil t)
        (org-publish-cache-set-file-property
         file :date
         (let ((date (org-publish-find-property file :date project)))
           ;; DATE is a secondary string.  If it contains
           ;; a time-stamp, convert it to internal format.
           ;; Otherwise, use FILE modification time.
               (let ((ts (and (consp date) (assq 'timestamp date))))
             (and ts
              (let ((value (org-element-interpret-data ts)))
                (and (org-string-nw-p value)
                 (org-time-string-to-time value))))))))))
    
  • Collapsable src and example blocks

    From Tecosaur/Emacs-config.

    By wrapping the <pre> element in a <details> block, we can obtain collapsable blocks with no CSS, though we will toss a little in anyway to have this looking somewhat spiffy.

    Since this collapsability seems useful to have on by default for certain chunks of code, it would be nice if you could set it with #+attr_html: :collapsed t.

    It would be nice to also have a corresponding global / session-local way of setting this, but I haven’t quite been able to get that working (yet).

    (defvar org-html-export-collapsed nil)
    (eval '(cl-pushnew '(:collapsed "COLLAPSED" "collapsed" org-html-export-collapsed t)
                       (org-export-backend-options (org-export-get-backend 'html))))
    (add-to-list 'org-default-properties "EXPORT_COLLAPSED")
    

    We can take our src block modification a step further, and add a gutter on the side of the src block containing both an anchor referencing the current block, and a button to copy the content of the block.

    (defun org-html-src-block-collapsable
        (orig-fn src-block contents info)
      "Wrap the usual <pre> block in a <details>"
      (if
          (or
           (not org-fancy-html-export-mode)
           (bound-and-true-p org-msg-export-in-progress))
          (funcall orig-fn src-block contents info)
        (let*
            ((properties
              (cadr src-block))
             (lang
              (mode-name-to-lang-name
               (plist-get properties :language)))
             (name
              (plist-get properties :name))
             (ref
              (org-export-get-reference src-block info))
             (collapsed-p
              (member
               (or
                (org-export-read-attribute :attr_html src-block :collapsed)
                (plist-get info :collapsed))
               '("y" "yes" "t" t "true" "all"))))
          (format "<details id='%s' class='code'%s>\n<summary%s>%s</summary>\n<div class='gutter'><a href='#%s'>#</a>\n<button title='Copy to clipboard' onclick='copyPreToClipbord(this)'>⎘</button></div>\n%s\n\n</details>" ref
                  (if collapsed-p "" " open")
                  (if name " class='named'" "")
                  (concat
                   (when name
                     (concat "<span class=\"name\">" name "</span>"))
                   "<span class=\"lang\">" lang "</span>")
                  ref
                  (if name
                      (replace-regexp-in-string
                       (format "<pre\\( class=\"[^\"]+\"\\)? id=\"%s\">" ref)
                       "<pre\\1>"
                       (funcall orig-fn src-block contents info))
                    (funcall orig-fn src-block contents info))))))
    (advice-add 'org-html-src-block-collapsable :around #'org-html-src-block)
    
    (defun mode-name-to-lang-name (mode)
      (or (cadr (assoc mode
                       '(("asymptote" "Asymptote")
                         ("awk" "Awk")
                         ("C" "C")
                         ("clojure" "Clojure")
                         ("css" "CSS")
                         ("D" "D")
                         ("ditaa" "ditaa")
                         ("dot" "Graphviz")
                         ("calc" "Emacs Calc")
                         ("emacs-lisp" "Emacs Lisp")
                         ("fortran" "Fortran")
                         ("gnuplot" "gnuplot")
                         ("haskell" "Haskell")
                         ("hledger" "hledger")
                         ("java" "Java")
                         ("js" "Javascript")
                         ("latex" "LaTeX")
                         ("ledger" "Ledger")
                         ("lisp" "Lisp")
                         ("lilypond" "Lilypond")
                         ("lua" "Lua")
                         ("matlab" "MATLAB")
                         ("mscgen" "Mscgen")
                         ("ocaml" "Objective Caml")
                         ("octave" "Octave")
                         ("org" "Org mode")
                         ("oz" "OZ")
                         ("plantuml" "Plantuml")
                         ("processing" "Processing.js")
                         ("python" "Python")
                         ("R" "R")
                         ("ruby" "Ruby")
                         ("sass" "Sass")
                         ("scheme" "Scheme")
                         ("screen" "Gnu Screen")
                         ("sed" "Sed")
                         ("sh" "shell")
                         ("sql" "SQL")
                         ("sqlite" "SQLite")
                         ("forth" "Forth")
                         ("io" "IO")
                         ("J" "J")
                         ("makefile" "Makefile")
                         ("maxima" "Maxima")
                         ("perl" "Perl")
                         ("picolisp" "Pico Lisp")
                         ("scala" "Scala")
                         ("shell" "Shell Script")
                         ("ebnf2ps" "ebfn2ps")
                         ("cpp" "C++")
                         ("abc" "ABC")
                         ("coq" "Coq")
                         ("groovy" "Groovy")
                         ("bash" "bash")
                         ("csh" "csh")
                         ("ash" "ash")
                         ("dash" "dash")
                         ("ksh" "ksh")
                         ("mksh" "mksh")
                         ("posh" "posh")
                         ("ada" "Ada")
                         ("asm" "Assembler")
                         ("caml" "Caml")
                         ("delphi" "Delphi")
                         ("html" "HTML")
                         ("idl" "IDL")
                         ("mercury" "Mercury")
                         ("metapost" "MetaPost")
                         ("modula-2" "Modula-2")
                         ("pascal" "Pascal")
                         ("ps" "PostScript")
                         ("prolog" "Prolog")
                         ("simula" "Simula")
                         ("tcl" "tcl")
                         ("tex" "LaTeX")
                         ("plain-tex" "TeX")
                         ("verilog" "Verilog")
                         ("vhdl" "VHDL")
                         ("xml" "XML")
                         ("nxml" "XML")
                         ("conf" "Configuration File"))))
          mode))
    
    (defun org-html-block-collapsable (orig-fn block contents info)
      "Wrap the usual block in a <details>"
      (if (or (not org-fancy-html-export-mode) (bound-and-true-p org-msg-export-in-progress))
          (funcall orig-fn block contents info)
        (let ((ref (org-export-get-reference block info))
              (type (pcase (car block)
                      ('property-drawer "Properties")))
              (collapsed-default (pcase (car block)
                                   ('property-drawer t)
                                   (_ nil)))
              (collapsed-value (org-export-read-attribute :attr_html block :collapsed))
              (collapsed-p (or (member (org-export-read-attribute :attr_html block :collapsed)
                                       '("y" "yes" "t" t "true"))
                               (member (plist-get info :collapsed) '("all")))))
          (format
           "<details id='%s' class='code'%s>
    <summary%s>%s</summary>
    <div class='gutter'>\
    <a href='#%s'>#</a>
    <button title='Copy to clipboard' onclick='copyPreToClipbord(this)'>⎘</button>\
    </div>
    %s\n
    </details>"
           ref
           (if (or collapsed-p collapsed-default) "" " open")
           (if type " class='named'" "")
           (if type (format "<span class='type'>%s</span>" type) "")
           ref
           (funcall orig-fn block contents info)))))
    
    (advice-add 'org-html-example-block   :around #'org-html-block-collapsable)
    (advice-add 'org-html-fixed-width     :around #'org-html-block-collapsable)
    (advice-add 'org-html-property-drawer :around #'org-html-block-collapsable)
    

Sitemap

  • Define jp/org-publish-sitemap
    (defun jp/org-publish-sitemap (title list)
      "Outputs site map, as a string.
    See `org-publish-sitemap-default'. "
      ;; Remove index and non articles.
      (setcdr list (seq-filter
                    (lambda (file)
                      (string-match "file:.*.org" (car file)))
                    (cdr list)))
      ;; TODO: Include subtitle?  It may be wiser, at least for projects.
      (concat "#+TITLE: " title "\n"
              "#+HTML_HEAD: <script type=\"text/javascript\" src=\"../lib/js/jquery.min.js\"></script>"
              "\n"
              "#+HTML_HEAD: <script type=\"text/javascript\" src=\"../lib/js/bootstrap.min.js\"></script>"
              "\n"
              "#+HTML_HEAD: <script type=\"text/javascript\" src=\"../lib/js/jquery.stickytableheaders.min.js\"></script>"
              "\n"
              "#+HTML_HEAD: <script type=\"text/javascript\" src=\"../js/readtheorg.js\"></script>"
              "\n"
              "#+HTML_HEAD: <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/readtheorg.css\" />"
              "\n"
              "#+HTML_HEAD: <link rel=\"stylesheet\" type=\"text/css\" href=\"../css/htmlize.css\">"
              "\n"
              "#+HTML_HEAD: <link rel=\"icon\" type=\"image/x-icon\" href=\"../logo.png\"> "
              "\n"
              (org-list-to-org list)))
    
  • Define jp/org-publish-main-sitemap
    (defun jp/org-publish-main-sitemap (title list)
      "Outputs site map, as a string.
    See `org-publish-sitemap-default'. "
      ;; Remove index and non articles.
      (setcdr list (seq-filter
                    (lambda (file)
                      (string-match "file:.*.org" (car file)))
                    (cdr list)))
      (concat "#+TITLE: " title "\n"
              "#+HTML_HEAD: <script type=\"text/javascript\" src=\"lib/js/jquery.min.js\"></script>"
              "\n"
              "#+HTML_HEAD: <script type=\"text/javascript\" src=\"lib/js/bootstrap.min.js\"></script>"
              "\n"
              "#+HTML_HEAD: <script type=\"text/javascript\" src=\"lib/js/jquery.stickytableheaders.min.js\"></script>"
              "\n"
              "#+HTML_HEAD: <script type=\"text/javascript\" src=\"js/readtheorg.js\"></script>"
              "\n"
              "#+HTML_HEAD: <link rel=\"stylesheet\" type=\"text/css\" href=\"css/readtheorg.css\" />"
              "\n"
              "#+HTML_HEAD: <link rel=\"stylesheet\" type=\"text/css\" href=\"css/htmlize.css\">"
              "\n"
              "#+HTML_HEAD: <link rel=\"icon\" type=\"image/x-icon\" href=\"logo.png\"> "
              "\n"
              (org-list-to-org list)))
    
  • Define jp/org-publish-sitemap-entry
    (defun jp/org-publish-sitemap-entry (entry style project)
      "Custom format for site map ENTRY, as a string.
    See `org-publish-sitemap-default-entry'."
      (cond ((not (directory-name-p entry))
             (let* ((meta-date (jp/org-publish-find-date entry project))
                    (file (expand-file-name entry
                                            (org-publish-property :base-directory project)))
                    (creation-date (if (not meta-date)
                                       (jp/git-creation-date file)
                                     ;; Default to the #+DATE value when specified.  This
                                     ;; can be useful, for instance, when Git gets the file
                                     ;; creation date wrong if the file was renamed.
                                     (format-time-string "%Y-%m-%d" meta-date)))
                    (last-date (jp/git-last-update-date file)))
               (format "[[file:%s][%s]]^{ (%s)}"
                       entry
                       (org-publish-find-title entry project)
                       (if (string= creation-date last-date)
                           creation-date
                         (format "%s, updated %s" creation-date last-date)))))
            ((eq style 'tree)
             ;; Return only last subdir.
             (capitalize (file-name-nondirectory (directory-file-name entry))))
            (t entry)))
    

Setting org-publish-project-alist

(setq org-publish-project-alist
      (list
       (list "all-site-pages-org"
             :base-directory "./digital-garden/"
             :recursive t
             :publishing-function '(org-html-publish-to-html)
             :publishing-directory "./public/"
             :auto-sitemap nil
             :html-head-include-default-style nil
             :html-head-include-scripts nil
             :html-head "<link rel=\"icon\" type=\"image/x-icon\" href=\"logo.png\">
<script type=\"text/javascript\" src=\"lib/js/jquery.min.js\"></script>
<script type=\"text/javascript\" src=\"lib/js/bootstrap.min.js\"></script>
<script type=\"text/javascript\" src=\"lib/js/jquery.stickytableheaders.min.js\"></script>
<script type=\"text/javascript\" src=\"js/readtheorg.js\"></script>
<link rel=\"stylesheet\" type=\"text/css\" href=\"css/readtheorg.css\" />
<link rel=\"stylesheet\" type=\"text/css\" href=\"css/htmlize.css\" />")
       (list "main-site-org"
             :base-directory "./digital-garden/"
             :recursive nil
             :publishing-function '(org-html-publish-to-html)
             :publishing-directory "./public/"
             :sitemap-format-entry #'jp/org-publish-sitemap-entry
             :auto-sitemap t
             :sitemap-title "Sitemap"
             :sitemap-filename "sitemap.org"
             ;; :sitemap-file-entry-format "%d *%t*"
             :sitemap-style 'list
             :sitemap-function #'jp/org-publish-main-sitemap
             ;; :sitemap-ignore-case t
             :sitemap-sort-files 'anti-chronologically
             :html-head-include-default-style nil
             :html-head-include-scripts nil
             :html-head "<link rel=\"icon\" type=\"image/x-icon\" href=\"logo.png\">
<script type=\"text/javascript\" src=\"lib/js/jquery.min.js\"></script>
<script type=\"text/javascript\" src=\"lib/js/bootstrap.min.js\"></script>
<script type=\"text/javascript\" src=\"lib/js/jquery.stickytableheaders.min.js\"></script>
<script type=\"text/javascript\" src=\"js/readtheorg.js\"></script>
<link rel=\"stylesheet\" type=\"text/css\" href=\"css/readtheorg.css\" />
<link rel=\"stylesheet\" type=\"text/css\" href=\"css/htmlize.css\" />")
       (list "site-projects-org"
             :base-directory "./digital-garden/Projects"
             :recursive t
             :publishing-function '(org-html-publish-to-html)
             :publishing-directory "./public/Projects"
             :sitemap-format-entry #'jp/org-publish-sitemap-entry
             :auto-sitemap t
             :sitemap-title "Projects"
             :sitemap-filename "projects.org"
             ;; :sitemap-file-entry-format "%d *%t*"
             :sitemap-style 'list
             :sitemap-function #'jp/org-publish-sitemap
             ;; :sitemap-ignore-case t
             :sitemap-sort-files 'anti-chronologically
             :html-head-include-default-style nil
             :html-head-include-scripts nil
             :html-head "<link rel=\"icon\" type=\"image/x-icon\" href=\"../logo.png\">
<script type=\"text/javascript\" src=\"../lib/js/jquery.min.js\"></script>
<script type=\"text/javascript\" src=\"../lib/js/bootstrap.min.js\"></script>
<script type=\"text/javascript\" src=\"../lib/js/jquery.stickytableheaders.min.js\"></script>
<script type=\"text/javascript\" src=\"../js/readtheorg.js\"></script>
<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/readtheorg.css\" />
<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/htmlize.css\" />")
       (list "site-literature-org"
             :base-directory "./digital-garden/Literature"
             :recursive nil
             :publishing-function '(org-html-publish-to-html)
             :publishing-directory "./public/Literature"
             :auto-sitemap nil
             :html-head-include-default-style nil
             :html-head-include-scripts nil
             :html-head "<link rel=\"icon\" type=\"image/x-icon\" href=\"../logo.png\">
<script type=\"text/javascript\" src=\"../lib/js/jquery.min.js\"></script>
<script type=\"text/javascript\" src=\"../lib/js/bootstrap.min.js\"></script>
<script type=\"text/javascript\" src=\"../lib/js/jquery.stickytableheaders.min.js\"></script>
<script type=\"text/javascript\" src=\"../js/readtheorg.js\"></script>
<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/readtheorg.css\" />
<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/htmlize.css\" />")
       (list "site-static"
             :base-directory "static/"
             :exclude "\\.org\\'"
             :base-extension 'any
             :publishing-directory "./public"
             :publishing-function 'org-publish-attachment
             :recursive t)
       (list "site" :components '("main-site-org" "site-projects-org" "site-literature-org" "site-static"))))

Define jp/publish-html

(defun jp/publish-html ()
  (jp/init-webpage)
  (org-roam-setup)
  (org-id-update-id-locations)
  (org-publish-all)
  )

End of File (EOF)

(provide 'publish)
;;; publish.el ends here

Build

  • Install Requirements:
    • Emacs
  • Just run the following command, to deploy all:

Deploy

Just commit the newly build page into the branch gh-pages which is synchronized to the page:

commit=$(git rev-parse HEAD)
git branch -u origin/gh-pages gh-pages
git fetch origin gh-pages
echo $(git branch -v)
git checkout gh-pages
cp -Rf public/* .
rm -rf public
git commit -a -m "Depolyment of ${commit}"
git push origin HEAD

License

This content is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/4.0/

The code creating these pages is licensed under GNU GPLv3+.

Copyright (C) 2021-2024 Jonathan Pieper

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Comments

Date: 2022-05-28 (Last update: 2024-11-23)

Made with Emacs 29.4 (Org mode 9.7.14)

© 2021-2024 Jonathan Pieper GNU General Public License Creative Commons License