Writing posts with emacs
Published:
I tried lately to get a bit more into emacs, by rewriting my configuration, and try to learn bits of emacs-lisp in the process. It lead me to try to be able to maintain this website, and to create posts using org-mode, and automating the process the best I could. Indeed, I found the process of writing in markdown, whose syntax is close albeit different enough from the org-mode quite painful.
For this, I use a combination of org-mode, yasnippet, all of this wrapped in a simple function. This is mainly stitching together various pieces I found here and there, and trying to understand the process. I am by no means an expert in anything and I do this for my own entertainment.
Create the file using a elisp function
Definition of the function
We are going to define a function, which creates the proper file, with the proper formatting etc. This function is taken from here.
(defun create-blogpost (x) "Create a new blogpost." (interactive "sPost title: ") (let ((date (shell-command-to-string "echo -n $(date +%Y-%m-%d)")) (title (s-replace " " "-" x)) filename filepath) (setf filename (concat date "-" title ".org")) (setf filepath (concat "~/vtrappler.github.io/org_posts/" filename)) (write-region "" 0 filepath t) (find-file filepath)) (insert "jekyll-autofilled-frontmatter") ;; use the yassnippet (yas-expand) )
This function will then be called using M-x create-blogpost
.
Step by step description
Let us describe step by step how this function is created:
(interactive "sPost title:")
This prompts an user input, in this case the title of the post we wish to create. The seemingly missplaced s
is not a typo, but a code letter indicating that the format of the input is a string. This defines x
, as it is not stated when calling the function.
(let ((date (shell-command-to-string "echo -n $(date +%Y-%m-%d)")) (title (s-replace " " "-" x)) filename filepath)
The bash command "echo -n $(date +%Y-%m-%d)"
here outputs the current date, in the format YYYY-MM-DD, and we assign the output string to the variable date
. Then we replace all the whitespaces in the title by dashes, and assign it to the variable title
. Finally, the filename
and filepath
variables are declared. Their values are set next:
(setf filename (concat date "-" title ".org")) (setf filepath (concat "~/vtrappler.github.io/org_posts/" filename))
The filename is then in the format YYYY-MM-DD-title-with-dashes.org
, as recognized by Jekyll.
The next two calls ensures that this file can and is created.
(write-region "" 0 filepath t) (find-file filepath)) ;;Closes the parenthesis of (let ...
The last calls inside the function insert the text necessary to incorporate the Jekyll frontmatter.
(insert "jekyll-autofilled-frontmatter") ;; insert the key of the snippet (yas-expand)
The snippet is described in the next section
Using yassnippets for the frontmatter used in jekyll
We created in a separate file the following snippet to generate properly the Jekyll frontmatter. As one can execute directly elisp code at the insertion of the snippet, we can exploit this property in order to get the correct format for the file. To avoid passing arguments from the create-blogpost
, we are going to simply retrieve all the info, by stripping the filename of the dashes, while the current date and the .org
extension are removed in a hardcoded manner.
# -*- mode: snippet -*- # name: jekyll-frontmatter-create # key: jekyll-autofilled-frontmatter # -- #+BEGIN_EXPORT html --- title: `(s-replace "-" " " (substring (buffer-name) 11 -4))` date: `(shell-command-to-string "echo -n $(date +%Y-%m-%d)"))` permalink: /posts/`(shell-command-to-string "echo -n $(date +%Y/%m)")`/`(substring (buffer-name) 11 -4)` tags: --- #+END_EXPORT #+OPTIONS: toc:nil #+OPTIONS: num:nil
Export org files to html
Finally, once the org file is written, we are going to export it to html: the parameters of publication are adapted from there
(setq org-publish-project-alist ;; https://thackl.github.io/blogging-with-emacs-org-mode-and-jekyll '(("vtrappler.github.io" ;; name of the page ) ;; Path to org files. :base-directory "~/vtrappler.github.io/org_posts/" :base-extension "org" ;; Path to Jekyll Posts :publishing-directory "~/vtrappler.github.io/_posts/" :recursive t :publishing-function org-html-publish-to-html :headline-levels 4 :html-extension "html" :body-only t )))
Final process
The final process of writing a blog post is then
M-x create-blogpost
, and type the title of the post when prompted- Write the post
C-c C-e P f
, publish to html- Add, commit and push if applicable to update your website