Blogging with Org mode and FastPages
Tutorial to setup Fastpages with org mode
1 Introduction
Jeremy and Rachel, esteemed founders of fastai, quote Blogging is like Resume, only better in this post. Blogging really is one of the best medium to learn while doing. It helps to communicate and formulate ideas, and share knowledge with your peers and colleagues. Blogging for me addresses provides three main motivations:
- It helps in improving communication and writing skills.
- It provide medium to showcase technical expertise in programming, data science and other domains.
- It is a great medium for self learning and teaching.
With nbdev, fastai library and video courses; Fastai team has contributed some of the best material and tools for learning data science specificaaly and programming in general. The top down learning style , with focus on learning the big picture by execution and programming, is an amazingly useful and productive technique especially for someone who is working full time.
Fastpages is the recent addition in the same tradition of tools made available by FastAI team to new and practicing data scientist to facilitate there learning journey. It capitalizes on nbdev codebases, a python literate programming tool and github actions to enable blogging by jupyter notebook and markdown files.
My objective in this post is to showcase some of the minor changes which I have made which enables me to use entire toolchain of fastpages; to blog with emacs org mode along with notebook, markdown or word format. I also intend to demonstrate how powerful org mode really is ; and why it belongs in a Data Scientist toolbox alongwith the list of tools mentioned above.
2 EMACS ORG-MODE: WHAT? WHY? HOW?
BEFORE CAME JUPYTER, BEFORE CAME INTERNET AND EVEN BEFORE THERE WERE PERSONAL COMPUTERS.THERE WAS SOMETHING CALLED EMACS
2.1 The What?
So what is org-mode? At the very basic level org mode or org format is a text markup defined for structured text editing. It is similar to markdown as it is defined in plaintext, priortizes readability and has an human centric approach. Combination with emacs elisp system makes it insanely powerful. Instead of yet another markup syntax; it becomes a system of text editing which is highly extensible and infinitely programmable. With various open source plugins' it can be used like a literate programming tool like notebooks or frontend for latex report creation or even online presentations.
2.2 The Why?
So why should you be interested in Org Mode .Here is a brief list of things that you can do with it.
2.2.1 Blogging
You can write a blog post like this. Since Emacs is insanely powerful for text editing you can do really fast typing.
2.2.2 FastPages Functionality
Lot of bells and whistle related to boxes and link are enabled using org mode link functionality
- Links are prepended by a directive
- When doing html export link get converted into jekyll include statement already defined in the code
- When exporting to other backends it follows the same structure as normal link for that structure
-
Youtube Video Link
You can embed individual video or even playlist
[[yt:https://youtu.be/5haX95nk02E][New Link Feature Org Mode]]
[[yt:https://www.youtube.com/playlist?list=PLxc79l2wpbJYTI5rv2os7OoKQMqxReZpr][The Playlist for Org Mode]]
-
Twitter Card Link
[[twitter:https://twitter.com/jakevdp/status/1204765621767901185?s=20][Altair v4 release]]
Altair 4.0 is released! https://t.co/PCyrIOTcvv
— Jake VanderPlas (@jakevdp) December 11, 2019
Try it with:
pip install -U altair
The full list of changes is at https://t.co/roXmzcsT58 ...read on for some highlights. pic.twitter.com/vWJ0ZveKbZ -
Remote Image Link
[[img:https://www.fast.ai/images/fastai_paper/show_batch.png][Credits: https://www.fast.ai/2020/02/13/fastai-A-Layered-API-for-Deep-Learning/]]
[[img:https://upload.wikimedia.org/wikipedia/commons/7/71/ChessPawnSpecialMoves.gif]]
-
Local Images
[[img:/images/Emacs.png][Emacs is the king]]
This has been awesome so far.
-
Boxes and Stuff
[[alert:This is an alert box]] [[alert:box][Danger ahead]] [[info:This is info box]] [[info:box][This is for your information]] [[warning:box][You have been warned]] [[important:box][This is important]] [[tip:box][You are going to get lucky with emacs]] [[note:box][This is a note]] *I am currently in process of fixing doclink functionality inside note box* [[note:box][A doc link to [an example website: fast.ai](https://www.fast.ai/) don't work yet.]]
This is an alert boxDanger aheadThis is info boxThis is for your informationWarning: You have been warnedImportant: This is importantTip: You are going to get lucky with emacsNote: This is a noteI am currently in process of fixing doclink functionality inside note box
Note: A doc link to [an example website: fast.ai](https://www.fast.ai/) don't work yet. -
IFrames and Revealjs Presentation
[[iframe:https://revealjs.com][Reveal JS Presentation]]
You can embed websites as iframes. This is particularily useful for embedding revealjs presentation like this.
Infact it is also possible to create revealjs presentation directly from org mode. I will be working on integrating the same in next few days.
You can also embed powerpoint presentation
2.2.3 Document Embedding
For a longish article, sometimes you would like to split it in different files and combine them together. This workflow is usually better for writing as well; as each document can be focussed on a single aspect of entire topic you want to present in your article.
In org-mode it is trivial to do this using `#+INCLUDE` functionality. As an example above section on Fastpages functionality is actually part of a different blog published in here. I have just imported relevant portions for this post. Code/ configuration files in the bottom section are embedded using the same technique.
#+INCLUDE: "2020-04-29-Awesome-Org-Mode-Links.org::FastPages link" :only-contents t
2.2.4 Literate Programming
You can do literate programming just like jupyter notebooks, create technical reports, even write full fledged books. Org mode also supports various export backends which means same document can be converted to a html blog, a latex report, beamer or revealjs presentations. Here are a few good links to explore
- A Multi-Language Computing Environment for Literate programming and Reproducible Research here
- Org Mode Recipes
- Literate programming in python with org-mode and noweb here
2.2.5 GTD, Task Manager, Todo
You can use it as task manager, do project management, create to do list. Follow the recommendations of GTD managing your life in a text edit. And many many more things as described here
2.2.6 Are you excited?
What I have done is just touch upon the surface of what is possible with org mode, and by extension blogging on fastpages with org mode. There are many more options and functionality available in org mode including beamer presentation, spreadsheets , agenda views etc… which are awesome but too broad to cover in this introductory blog post. However over time I will continue to post articles on some tidbits' here and there which can greatly enhance your blogging workflow. Now I hope I have motivated you enough, so time to figure out to do it yourself.
2.3 The How?
I have already shown earlier what org mode can do and how it can enhance your writing workflow. Now I will describe how you can do it yourself. Before I go into specifics let me share a bit on general design of fastpages and describe how it can be extended.
2.3.1 Design of fastpages
So here is brief synopsis. Fastpages is based on Jekyll. It already provides you functionality to write a blog in markdown, notebook or word document. This is how it works
-
Markdown Blogging
- Markdown is the native format for Jekyll Blogging Engine. Jekyll uses an enhanced version of Markdown called Kramdown which comes with addtional functionality for source code coloring links etc…
- Layout of Jekyll (Structure of html) is written in `Liquid` template engine. You have liquid templates in two places
- _layouts folder - used for defining page/post structure.
- _includes folder - used to define general html blocks or additional functionality which may be included in an article
- YAML Front Matter - Each article needs to have a yaml frontmatter which defines specifics like title, author, layout to choose, comments to include or exclude , categories , tags etc… which are either generic cross cutting functionality or indicator to select some specific configuration for blogging engine. It needs to come at very top of page
-
Notebook Blogging
- Notebook blogging is really what makes fastpages special for data scientist.I should rather specify and say python notebook blogging is what is possible natively in fastpages. Notebook blogging is enabled by a python package called "nbdev" another tool from FastAI.
- The way it works is as follows
- You need to specify front matter in first cell of notebook
- Import / Export/ Hide / Show/ Collapsible hide etc… are directive implemented as comments which need to appear on top of cell to indicate inclusion or exclution from html export
- In reality notebooks from _notebooks folder are converted to html[not markdown] and exported to _posts folder with a fake (.md) extension as an initial preprocessing step
- From _post folder Jekyll machinery takes over to convert them into rendered site alongwith markkdown posts
- Fastpages provides various shims(utlities/methods) to convert some notebook specific directives for links, youtube or boxes to liquid include templates. These are then converted by Jekyll to final version of site.
-
Word Blogging
- Word blogging structure is a similar
- It uses pandoc for "docx" to "html" conversion. Which is copied to _posts folder with (.md) extension
- Some shim methods are provided by FastPages to handle jekyll _includes and _layout nicely
- For Words there is only one place to specify "Front Matter". It is _actionfiles/wordfrontmatter.txt file
- Word blogging structure is a similar
-
Automation via Github Actions
- All processing automation are handled by Github Actions
- Checkout code to some machine
- Cleaning up old _site or html
- Convert files in _notebooks and _word to _posts
- Building the site using Jekyll into _site
- Copying / Commiting the _site folder to ghpages etc..
- Everything in Github Actions are handled by services/ different docker containers running different scripts
- For local viewing a parallel system is provided using docker-compose.yml and Makefile.
- All processing automation are handled by Github Actions
2.3.2 General Idea for extension
So based on the intuition above we basically need to figure out 3 pieces
- HTML/Markdown Converter :Way to convert custom format to html( with fake .md extension) or actual kramdown style markdown. It needs to have a way to insert/ send YAML FrontMatter to exported files
- Shims for Jekyll: Some customization scripts to handled Jekyll _include template nicely to manage look and feel
-
Automation Code
- Github Action [ Include an addtional conversion step in ci.yml or integrate with existing action files possibly in _actionfiles/actionentrypoint.sh ]
- Update Docker Compose and Makefile
2.3.3 Org Mode Blogging
So with the ideas above , I managed to create some extensions and tricks to enable org mode blogging. It has following parts
-
Org File Customization
A small customization is required to export frontmatter from org file.
#+OPTIONS: toc:nil #+BEGIN_EXPORT html --- layout: post categories: [orgmode] title: Blogging with Org mode and FastPages description: Tutorial to setup Fastpages with org mode comments: true use_math: false --- #+END_EXPORT # COMMENT ------------------OPTIONAL FROM HERE------------------------------ #+TOC: headline 3
- I use org mode specific publishing framework which comes alongwith Emacs.
- In my export configuration, which I will talk about later, I have some settings which only export body of converted html document.
- Here first line is for disabling toc specfic to org mode. Default org mode TOC is added on top of body before content which interferes with YAML Frontmatter
- You can't include #+TITLE directive in org mode , as it is rendered before everything , and thus interfere's with Front Matter.
- Then comes section for YAML front matter. Wrapping it in html export block allows this to be the first section on the file.
- Things below OPTIONAL FROM HERE line need not be included.
In fact I am still looking forward to customize css so that we can colorize source code similar to notebooks and markdown
- With these simple rules, you can easily write a blog post with all the functionality of org mode.
-
FastPages Customization
I have done minimal non invasive customization to enable automation for org mode in fast pages.
Note: All the code described below is available in github repo: https://github.com/Rahuketu86/FastPagesDev-
Folder Structure
We need to create a _org folder . Inside _org folder , it should mirror structure of top level directories as follows
Note: For local images always assume root to be _org [The structure of _org directory should be replica of blog folder structure]. Images will always start with `/images` or `/assets` -
Github Action Customization
- I have created some custom actions, which I save in _customactionsfiles directory at top level. It has got 3 files
-
publish.el - Emacs script to control publishing from _org/posts to _posts folder and converting org to html.
-
fpemacs.el - Helper functions to enable links functionality translating to html/ jekyll includes. This is really the fastpages shim version of emacs. We can even call it fastpages-emacs library. All the changes should go here
Warning: This files contains include template in code and can't be rendered fully. Some lines are skipped. -
custom.sh - Used to run emacs in batch mode with above files
-
-
Additionally I have defined a public docker image encapsulating emacs and other dependencies for add on which is available from dockerhub as rahuketu86/fastpages-emacs. I add an addtional step to convert org files in my ci.yaml to enable this conversion automatically on git push. My modified ci now looks as follows
- I have created some custom actions, which I save in _customactionsfiles directory at top level. It has got 3 files
-
Finally for local viewing
-
I had to update docker-compose.yml to include an orgconverter service to use my rahuketu86/fastpages-emacs
-
Update Makefile to add a single line in convert [# convert word & nb without Jekyll services] to run orgconverter alongwith nbdev converter
-
-
Folder Structure
2.3.4 Trying it yourself
- Create a Repository by using fastpages template repository as documented here. Please click on this link to start generating your repository from template.
- After you finish the setup process by generating and storing ssh keys, clone your blog repository to local computer.
- Clone or copy FastPagesDev Repository to a different folder.
- Copy _org folder from FastPagesDev repository to your blog repository
- Copy _customactions folder from FastPagesDev repository to your blog repository
- Copy Makefile, docker-compose.yml and .github/ci.yml to your blog repository. This will overwrite the files in your blog repository.
- Now you are ready. You can either build your repository locally or commit your code and see it working on published gh-pages
3 Conclusion and way forward
3.1 Org Mode Bridge and Other systems
Org mode on emacs is a really powerful tool for text processing, writing and literate programming. With all the development done on this repository; it is now fairly easy to get started with org mode on fastpages. In future similar techniques can be adopted to create exporter for Rmarkdown or literate-julia or any other target. In view of author, it is important to use the language native to programming system to build these extensions. So for Rmarkdown , it would be useful to leverage existing infrastructure in "knitr" and "bookdown/ blogdown" packages rather than building things from scratch or extending nbdev. This is less burdensome to maintain and enables a writing flow where we don't have to go back and forth from existing system.
Now even though lot of functionality is enabled in orgmode bridge to fastpages, which mirrors or sometimes extends notebook version there are a few pending issues
3.2 Outstanding Tasks
-
TODO Fix links inside boxes in org mode
-
TODO Provide more controls on code folding , currently implemented on every block.
-
TODO Define a specific layout for org files which can include some common header files.
-
DONE Define a mechanism for code highlighting
It can be done using custom css like org.css. But thing approach need some customization to match with default stylesAnother approach is to use highlight.js and minor customization to read code blocks. This may be more reliable way to approach this
Note: Best Solution was to define a derived export backend and wrap source block in highlighting liquid template. It is now implemented in fpemacs.el -
TODO Handle internal links and html export more robustly
-
TODO Enable org-reveal functionality to directly generate and intergrate reveal-js presentation in blog post
-
TODO Create a demo for exporting to beamer and intergrating with blog post
Tip: Some custom function to streamline above might need to be included in fpemacs.elI hope you find this blog post informative to get started with org mode.Please share your suggestions below which can help in improving or extending this setup.