Nick George
Science Programming

A YASnippet for org-mode publishing

First published: August 26, 2018
Last updated: July 12, 2021

> Contents

I love standards and templates. Cookiecutter is my favorite command line template generator and I use a custom template for my lab projects.

When it comes to emacs programming and org-mode, I use the amazing YASnippet for generating templates from files called snippets. I introduced a simple snippet in my post on adding and parsing edn metadata for my static website, and here I have an expanded version that I am happy with for posts to my website.

I have a standard format for all my pages on my website, and the default org-mode export options and standard format rarely change. The format requires the following:

  1. edn metadata at the top with a set of specific keys

  2. Standard org-mode export options

  3. The date the page was created

  4. A note as to whether the page was updated and when

The snippet

Below is the text of my snippet. I will add comments in the lisp style with ;. Anything following the ;; is NOT part of the snippet, but is only there for annotation.

;; yas-snippet
# -*- mode: snippet -*-
# name: blog
# key: blog
# --
#+HTML: <div id="edn">
#+HTML: {:topic "programming" :title "${1:title}" :date "`(format-time-string "%Y-%m-%d")`" :tags ${2:["clojure"]}}
#+HTML: </div> ;; 1
#+OPTIONS: \n:1 toc:nil num:nil todo:nil ^:{} title:nil ;; 2
#+PROPERTY: header-args :eval never-export ;; 2
#+DATE: `(format-time-string "%Y-%m-%d %a")` ;; 3
#+TITLE $1 ;; 4
#+HTML:<h1 id="mainTitle">$1</h1> ;; 5
#+HTML:<div id="timedate">  ;; 6
/First published: {{{date}}}/ ;; 7
/Last updated: {{{time(%Y-%m-%d %a)}}}/ ;; 8
${3:#+TOC: headlines 2} ;; 9

You can activate a snippet by typing its key and then pushing TAB. So whenever I make a new blog post, I type blog<TAB> and this snippet expands and prompts me for input.

  1. This is where the div for my edn metadata is generated. I wrote about it briefly in this post. In org-mode, #+HTML will export as literal html. So I am first prompted to enter a title "${1:title}" , then the :date is automatically inserted with the emacs-lisp code snippet surrounded by back ticks, and I am then prompted to enter a few tags in what will be parsed as a Clojure vector.

  2. The #+OPTIONS line and #+PROPERTY set some sane defaults for org-mode export.

  3. #+DATE is an org-mode metadata item where I have also inserted emacs-lisp code to generate the date. Yup, you can insert arbitrary emacs-lisp code in snippets to execute when expanded.

  4. This line establishes the title for the post, will mirror whatever my title is ($1 mirrors ${1:title}).

  5. This line will be exported as raw html and establishes a special <h1 id> for my main title. Again, $1 mirrors the title.

  6. Here I am starting another html div that will control another metadata feature.

  7. The {{{}}} is for org-mode org-mode macro replacement. The date inside this replacement macro will insert the value #+DATE variable into that location upon export.

  8. This org-mode macro inserts the date of last export.

  9. Optional table of contents. Org-mode will automatically generate a table of contents and it will be inserted wherever I put this line. I usually don't want a table of contents, so I typically delete this part but it is there just in case.

I really like this format. It allows me to standardize the metadata of my files and provides a really nice automatic record of when I posted and updated different posts. When I first publish an article, the date and macro described in #7 will be the same, as #+DATE is set once when the snippet is first generated. If I ever update and re-export a file, then #7 will re-evaluate and display the date of the most recent export!

More snippets

I have a bunch more snippets, which you can see in my emacs-config. I stole a lot from different places on the internet, but most of these are customized to address specific problems I had or to optimize for a specific workflow. For example, I made another snippet for my regular science writing workflow called pre sets up all of my normal export options and org-ref settings.

YASnippet's are just another reason why org-mode and emacs rock!