Ravi Sagar | Home | Blog

Blogging with Emacs and Org Mode

Table of Contents

1 Overview

So you ar wondering if Emacs1 can be used to do blogging and at the same time also thinking about why use Org Mode2? Well the answer is simple. I want to keep things simple. Blogging is all about content and I spend lot of time making notes, keeping a list of things I want to do in Org Mode, there are lot of blog I just couldn't write on my Drupal site www.ravisagar.in because it is a bit of a pain to copy, organise and transfer it to a web portal.

With Emacs and Org mode you can just do blogging from your terminal (yes I used Emacs in terminal mode) and I believe I can do it much faster and will be able to share more information quickly whenever I want. Also the other benefit is that with Org mode I can share code snippets that can also be run and evaluated. It is so much fun :)

2 Who this blog is for?

  • You use Emacs
  • You use Org mode
  • You want to blog
  • You want to share content with code
  • You like simplicity

3 This blog/site is built with Emacs and Org Mode

I made this site using Emacs of course (otherwise what is the point). Apart from my Drupal sites I have tried using Hugo, Grav, Github pages before, I still have those blogs up and running but I don't plan to update it with more content. Those static site generator where more of an experiment. I personally loved working on Hugo for its simplicity and I was amazed by Grav for its CMS like capabilities (it is still file based).

4 What can you learn here on this blog post?

  • Learn how to use Emacs (not an expert level but enough to get you started)
  • Learn how to use Org Mode for note taking
  • Learn how to use Org Mode for blogging
  • Publish yyour blog and host it

The idea of this blog is to create one big (not too big) document that will make it very easy for anyone to install Emacs and start using it.

5 Come back to this blog post

I will keep on updating this blog post with new content. So you may want to come back to this post if you have want to learn more.

6 Emacs fundamentals

6.1 Basic commands

Let us learn the fundamentals first. I also made a video to show these basic commands.

Abbreviations use:

  • C is Ctrl key
  • M is Meta

Windows - Meta key is Alt Mac - Meta key is Esc

  • Close the IDE: C-x C-c
  • Save the file: C-x C-s
  • Cut: C-w
  • Paste: C-y
  • Undo: C-_
  • Copy: M-w
  • Search: C-s

6.2 Split the screen

  • Vertical split: C-x-3
  • Horizontal split: C-x-2
  • Move between windows: C-x-b
  • Closing the active window: C-x-0
  • Full screen: M-M-M
  • Make current window wider: C-x }
  • Make current window narrower: C-x {
  • Specify the size to make things simpler C-u 40 C-x } or M-40 C-x } 3
  • Specify the default size of 4 by doing C-u C-x } 3
  • Specify size before the split C-u 40 C-x-3 3

6.3 Tips for making writing experience better

  • Insert a link C-c C-l
  • Make the text fit in the window: visual-line-mode
  • Indentation based on the headers: org-indent-mode
  • Insert footnote: C-c C-x f


6.4 Macros in Emacs

C-x ( - Start the macro C-x ) - end the macro C-x e - repeat the macro

6.5 Switch between buffers

If you do C-x b then you can type in the name of the buffer or you can press C-x C-b it will bring up the list of all the buffers. However there is another way. You can use C-x <left> and C-x <right> as well which is quicker.

7 What is Org Mode?

Org-mode is a document editing, formatting, and organizing mode, designed for notes, planning, and authoring within the free software text editor Emacs. Source: Wikipedia.

8 What can you do with Org Mode

8.1 Note taking

8.2 Task management

8.3 Blogging

8.4 Write documents

8.5 Literate Programming with Org Babel

To insert a template I use a short <s - <tab> and it will insert a source block but you can also insert your own block templates.

Insert this in your .emacs file

(add-to-list 'org-structure-template-alist
             '("g" "#+NAME: fileName ?\n#+BEGIN_SRC groovy :exports code :results output :tangle directory/fileName.groovy \n\n#+END_SRC"))

Now using <g - <tab> you can quickly insert this groovy specific template. ? mark is the place where your cursor will be when you insert the template.

For more than one template use the following code.

(add-to-list 'org-structure-template-alist
             '("g" "#+NAME: fileName ?\n#+BEGIN_SRC groovy :exports code :results output :tangle directory/fileName.groovy \n\n#+END_SRC"))
(add-to-list 'org-structure-template-alist
             '("t" "#+TITLE: ?\n#+DATE: \n#+AUTHOR: "))

9 Key features of Org Mode

9.1 Folding

9.2 States

9.3 Track progress

9.4 Agenda view

Week-agenda (W17): Monday 20 April 2020 W17 misc: Sched.65x: TODO Update Expense sheet spx: Sched.41x: How to un-exclude the issues from a plan? :video::t1719: spx: Sched.41x: Blog about why I like Jira :blog::t1719: spx: Sched.40x: Create a project using a Groovy script: link :video::p912: spx: Sched.40x: Video Create a project using a Groovy script: link :p912:video: spx: Sched.40x: Write a script to create linked issue :video::p912:

9.5 TODO Schedule tasks SCHEDULED: <2020-04-21 Tue>

9.6 Deadline DEADLINE: <2020-04-22 Wed>

9.7 Org Capture

9.8 Refile

9.9 Spell check

M-$ on the word and it will give you suggestions with numbers. Just press the number if you want to use the suggestion.

10 Do you need Org Mode?

Short answer is yes but don't expect immediate results. You need to spend time learning it. It is mostly for geeky people who are comfortable using terminal. If you are not used to typing commands then don't bother.

11 How to start using Org Mode?

11.1 First install Emacs and then install the org package M-x package-install RET org RET.

11.2 Your best place to learn is https://orgmode.org/

12 Publish a website

So are you ready to launch a website using Org mode? Great. Let us begin. First you need to modify your Emacs configuration file - .emacs for publishing to work.

12.1 Snippet of my .emacs file responsible for publishing this blog

The following code make sure that it will read the *.org files in a specific directory and it will generate HTML out of it and also add few other things like header, footer and css.

; Publishing using Org-mode
;(add-to-list 'load-path "~/.emacs.d/ox-rss.el")
(require 'ox-rss)

(defvar ravipro-html-head
  "<link rel='stylesheet' href='css/style.css' type='text/css'/>")

(defvar ravipro-html-blog-head
  "<link rel='stylesheet' href='../css/style.css' type='text/css'/>")

(defvar ravipro-html-preamble "<div class='preamble'><a href='/'>Ravi Sagar</a> | <a href='/'>Home</a> | <a href='blog/blog.html'>Blog</a></div>")
(defvar ravipro-html-blog-preamble "<div class='preamble'><a href='/'>Ravi Sagar</a> | <a href='/'>Home</a> | <a href='../blog/blog.html'>Blog</a></div>")

(defvar ravipro-html-postamble
  "<div class='nav'>
<li><a href='/'>Home</a></li>
<li><a href='sitemap.html'>Sitemap</a></li>
<li><a href='blog/blog.html'>Blogs</a></li>
<li><a href='http://twitter.com/ravisagar'>Twitter</a></li>
<div class='footer'>Copyright © 2020. Last updated: %C, built with %c</div>"

(defvar ravipro-html-blog-postamble
  "<div class='nav'>
<li><a href='/'>Home</a></li>
<li><a href='../sitemap.html'>Sitemap</a></li>
<li><a href='../blog/blog.html'>Blogs</a></li>
<li><a href='http://twitter.com/ravisagar'>Twitter</a></li>
<div class='footer'>Copyright © 2020. Created %d, Last updated %C, built with %c</div>"

(defun ravipro-format-entry (entry style project)
    (format "[[file:%s][%s]] --- %s"
            (org-publish-find-title entry project)
            (format-time-string "%Y-%m-%d" (org-publish-find-date entry project))))

(setq org-publish-project-alist
         :base-directory "~/ravi.pro/"
          :publishing-directory "/Users/spareuser/projects/ravi.pro/"
          :recursive t
          :exclude "level-.*\\|.*\.draft\.org"
          :publishing-function org-html-publish-to-html
          :auto-sitemap t
          :sitemap-filename "sitemap.org"
          :sitemap-title "Sitemap"
          :sitemap-sort-files anti-chronologically
          :with-toc nil
          :html-head ,ravipro-html-head
          :html-link-up "/"
          :html-link-home "/"
          :html-preamble ,ravipro-html-preamble
          :html-postamble ,ravipro-html-postamble

          :base-directory "~/ravi.pro/blog/"
          :publishing-directory "/Users/spareuser/projects/ravi.pro/blog/"
          :exclude "level-.*\\|.*\.draft\.org"
          :publishing-function org-html-publish-to-html
          :auto-sitemap t
          :sitemap-filename "blog.org"
          :sitemap-title "All Blogs"
          :sitemap-sort-files anti-chronologically
          :sitemap-format-entry ravipro-format-entry
          :html-head ,ravipro-html-blog-head
          :html-link-up "/"
          :html-link-home "/"
          :html-preamble ,ravipro-html-blog-preamble
          :html-postamble ,ravipro-html-blog-postamble


          :base-directory "~/ravi.pro/images/"
          :base-extension "png\\|jpg"
          :publishing-directory "/Users/spareuser/projects/ravi.pro/images/"
          :recursive t
          :publishing-function org-publish-attachment

          :base-directory "~/ravi.pro/css/"
          :base-extension "css"
          :publishing-directory "/Users/spareuser/projects/ravi.pro/css/"
          :recursive t
          :publishing-function org-publish-attachment

          :base-directory "~/ravi.pro/"
          :publishing-directory "/Users/spareuser/projects/ravi.pro/"
          :base-extension "org"
          :html-link-home "https://www.ravi.pro/"
          :html-link-use-abs-url t
          :rss-extension "xml"
          :publishing-function (org-rss-publish-to-rss)
          :recursive t


         ("website" :components ("home" "blog" "images" "css"))


12.1.1 TODO So let us discuss this piece of code

12.2 Publishing commands

These commands will be used to publish the site into HTML format to a specific location that you set above in the .emacs file.

  • Publish: M-x org-publish
  • Shortcut: C-c C-e P x PROJECTNAME
  • Force publish (all files): C-u M-x org-publish

12.2.1 Issues you may encounter

  • Sitemap title not updating?: Clear the content of ~/.org-timestamps folder and export again.

12.3 CSS used on my site


    max-width: 70%;
    margin: auto;
    font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
    color: #222222;

.nav {
    background: #aeaeae;
    padding: 10px;
.preamble {
    background: #330000;
    padding: 10px;
    color: #ffffff;

.preamble a:visited {
    color: #ffffff;

.preamble a:link {
    color: #ffffff;

12.4 Host your website

Here are the steps.

  1. First setup the repository with the correct name.

There are 2 main ways of doing it on GitLab.com. Refer to this page.

  • Under your username user create a project user.gitlab.io and enable the GitLab pages and your website will be published under https://user.gitlab.io
  • Under your group group create a project group.gitlab.io and enable the GitLab pages and your website will be published under https://group.gitlab.io

Make sure pages can be viewed by everyone.

  1. Create a file called .gitlab-ci.yml in your repository root with the following content.
  stage: deploy
    - mkdir .public
    - cp -r * .public
    - mv .public public
      - public
    - master

I use GitLab.com to host my site. I manage the directory where I publish my HTML in my Git repository on GitLab. I also made a video about it.

  1. Add CNAME record that points to user.gitlab.io
  2. Verify your domain

Go to your repository settings and add both example.com and www.example.com. You will then get a TXT record that you need to add for your domain. Wait for the verification to finish and you now have a site hosted for free on GitLab. Cool isn't it?

13 Execute code - Literate Programming

You can insert code snippets in your document.

  • C-c C-c – Execute the code

When you export to HTML you will be asked to export all the code blocks one by one. However you can execute them without your confirmation.

Two ways to do it.

  1. Set this in your .emacs file.
(setq org-confirm-babel-evaluate nil)
  1. Add this on top of your file, close and open the file again.
# -*- org-confirm-babel-evaluate: nil -*-

14 Open a website in Emacs

Emacs Web Wowser - eww can be used to open sites.

  • M-x-eww then type in the url.

15 Good external resources



Thanks Robert Davis for the tip: https://youtu.be/C2ZSa9RshbU