UP | HOME

Speedrun guide to Org Mode

Table of Contents

Commentary

This started as a set of notes on Literate Devops with Emacs. I never thought this was to be published, but it was revised on <2025-03-20 Thu>, so that I can send it to a friend of mine.

Feel free to look at the source code of this file, since the whole post was written in Org Mode.

Introduction

Org Mode is a wonderful plain text markup format. It is like markdown on steroids, yet much more intuitive and readable.

* Header
Headers start with *, this is a *bold* word, this is /italics/

You can have custom blocks with
#+begin_src, language
echo "I am no salesman, but well, you can also *execute* scripts inline with C-c C-c"
#+end_src
while inline code looks like this ~echo Hello World~

You can have references [[cref:...]], footnotes [[fn:1]] (C-c C-x f)...


#+NAME: This is a table
| column 1   | column 2    |
|------------+-------------|
| Elementary | Dear Watson |
|            |             |

#+CAPTION: Image caption
#+attr_latex: :width 0.65\linewidth
#+attr_html: :alt It usually works out best
[[file:/the/path/to/a.img]]

Links can be efficiently inserted with C-c C-l and look like this:
[[http://chatziiola.github.io][Link]]

The thing is that OrgMode works best from within Emacs. Extensions exist for Nvim and other editors, but nothing even comes close.

Org mode features

This is found somewhere in the documentation of OrgMode (but it could have been CDLatex for `) - in any case it stands true:

When in doubt use C-c - (it is the default prefix for OrgMode shortcuts)

Writing code

  1. You can write code easily within source blocks. You can write #+begin_src <lang> , followed by #+end_src, but the simpler solution here is to use C-c C-,. A menu then spawns showing you the different environments you can use:
  2. You can edit the source block more efficiently, taking advantage of your programming configuration by using C-c ' while inside it.
  3. After you have finished writing everything, execute it with C-c C-c
  4. The RESULTS will be shown in buffer
brew search pyenv
#+RESULTS:
| pyenv                   |
| pyenv-ccache            |
| pyenv-pip-migrate       |
| pyenv-virtualenv        |
| pyenv-virtualenvwrapper |
| pyenv-which-ext         |
| plenv                   |
| pipenv                  |

Customizing the source blocks

By adding options to the first line of the source block one can modify its behavior. An example of that is the following, making sure that when exporting this file (see the exporting section for more), only the code block (not the results) will be exported:

#+begin_src python3 :exports code
print("Nice ;)")
#+end_src

You can also set the directory where the code block will be executed1, or set variables:

#+begin_src sh :dir ~
pwd
#+end_src

#+RESULTS:
: /Users/sickvm
#+begin_src sh :var hellostring="Hello World"
echo $hellostring
#+end_src

#+RESULTS:
Hello World

Exporting

OrgMode files can instantly be exported to \LaTeX, HTML, ODT(?), even Markdown2. Just run C-c C-e to see more.

If you are interested in what an Org to HTML workflow looks like, this is an excellent article to have a look at… What a writer :P

Tangling

This is one of the best features of org mode, and in fact this is what leads us to the next section of this article. One can use tangling so that independent begin_src blocks are then (through org-babel-tangle) combined to produce independent files. The next section, if tangled, creates a minimal emacs configuration for writing in OrgMode.

#+begin_src sh :tangle <filename>

You can even set it for a whole file

#+TITLE: My file
#+PROPERTY: :tangle ~/filename"


* Header
:PROPERTIES:
:header-args:elisp: :tangle "~/filename"
:END:

Sample-Configuration   config

Package Management

Straight configuration

Using straight.el for package management

This snippet is necessary to load bootstrap.el and get straight up and running.

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

This needs to be here to avoid mismatch org version

(straight-use-package 'org)
(setq straight-vc-git-default-clone-depth 1)
(setq straight-recipes-gnu-elpa-use-mirror t)

Use use-package forms when installing packages. This allows for the numerous pieces of code to be self-dependent.

(straight-use-package 'use-package)
(setq straight-use-package-by-default t)

Auto Package Update

(use-package auto-package-update
  :custom
  (auto-package-update-interval 7)
  (auto-package-update-prompt-before-update t)
  (auto-package-update-hide-results t)
  :config
  (auto-package-update-maybe)
  (auto-package-update-at-time "09:00"))

Evil Mode and some useful packages

If you are a Vim user, then evil mode is ideal, I can not help but suggest it:

(use-package evil
    :demand
    :init
        (setq evil-want-keybinding nil)
        (setq evil-want-C-u-scroll t)
        (setq evil-want-integration t)
        (setq evil-want-keybinding nil)
        (setq evil-split-window-below t)
        (setq evil-vsplit-window-right t)
        (setq evil-want-C-u-scroll t)
        (setq evil-want-C-i-jump t)
        (setq evil-want-Y-yank-to-eol t)
    :config
        (evil-mode 1)
        ;; No really need to set leader keys like that
        (evil-set-leader 'normal (kbd "<SPC>"))
        (evil-set-leader 'insert (kbd "M-<SPC>"))
        ;; Use visual line motions even outside of visual-line-mode buffers
        (evil-global-set-key 'motion "j" 'evil-next-visual-line)
        (evil-global-set-key 'motion "k" 'evil-previous-visual-line)
)

Evil Collection

Evil collection is a collection of multiple useful keybindings. Just like it is shown in the following snippet, I have decided against using the default evil-collection-mode-list, mainly to avoid unwanted behavior in certain modes. I have decided to keep evil collection only on certain modes (the ones described).

(use-package evil-collection
  :after evil
  :config
  (let ((evil-collection-mode-list 
         '(org help man info helpful imenu imenu-list corfu popup (magit magit-repos
         magit-submodule magit-section magit-todos) org-roam git dired flycheck
         (pdf pdfview) doc-view eldoc python hackernews (term term mult-term)
         (which-key))))
    (evil-collection-init))
  )

This is for commenting out text as in vim

(use-package evil-commentary
  :ensure t
  :config
  (global-unset-key (kbd "C-x C-;")) ;; ;Do not use the default
  (evil-commentary-mode)) ;; Enables gc by default

Keyboard

The mode displays the key bindings following your currently entered incomplete command in a popup.

(use-package which-key
    :config (which-key-mode))

Clipboard

Allows system and Emacs clipboard to communicate smoothly (both ways)

(setq-default select-enable-clipboard t) ; Merge system's and Emacs' clipboard

Org Mode

Automatically tangle org-mode files with the option #+auto_tangle: t

; Tangle org file when it is saved
(use-package org-auto-tangle     
    :hook (org-mode . org-auto-tangle-mode))

This is mind-breaking, allowing you to quickly insert images, handling the file creation part. I use this with snippets, but it still is extremely powerful.

(use-package org-download
  :config
  (setq org-download-heading-lvl nil)            ;; don't use headings when creating image names
  (setq org-download-timestamp "%Y%m%d_%H%M%S_") 
  (setq org-download-screenshot-method "/user/local/bin/pngpaste %s")
  ;; Set the directory for storing images using :hook
  :hook
  (org-mode . (lambda () (setq-local org-download-image-dir "./images/"))))

And for references - bibliography management:

(use-package org-ref
  :config
    (setq org-ref-notes-directory "~/org")
    (setq org-ref-bibliography-notes (expand-file-name "notes.org" org-ref-notes-directory))
    (setq org-ref-default-bibliography '("/path/to/your.bib"))
    (setq bibtex-completion-bibliography org-ref-default-bibliography)
    (setq bibtex-completion-notes-path org-ref-notes-directory)
    (setq bibtex-autokey-name-case-convert-function 'capitalize)
    (setq bibtex-autokey-name-year-separator "")
    (setq bibtex-autokey-titleword-length 5)
    (setq bibtex-autokey-titleword-separator "")
    (setq bibtex-autokey-titlewords 2)
    (setq bibtex-autokey-titlewords-stretch 1)
    (setq bibtex-autokey-year-length 4)
    (setq bibtex-autokey-year-title-separator "")
    (setq bibtex-completion-pdf-field "file")
    (setq org-ref-default-ref-type "cref")
    (setq bibtex-completion-pdf-open-function (lambda (fpath) (start-process "open-pdf" "*open-pdf*" "open" fpath)))
    (define-key bibtex-mode-map (kbd "H-b") 'org-ref-bibtex-hydra/body)
    (define-key org-mode-map (kbd "M-[") 'org-ref-insert-link-hydra/body))

Documents need to end with:

**** References
<<bibliographystyle link>>

bibliographystyle:ieeetr

<<bibliography link>> bibliography:~/static/miref/master.bib

Further suggestions

  • Snippets (Yasnippets): Cause we all want to write less and get more done
  • Vertico: Revolutionizes the way you move around
  • Magit: Git Integration
  • CDLaTeX: Efficiently writing LaTeX in Org
  • Org-Roam: An org-based obsidian-like solution
  • Deft: If you are more into having lots of notes within one directory - like using nvim with ripgrep.
  • Colorschemes / Aesthetically configuring your emacs instance: Now this is purely subjective, but I use nano, with nano-modeline, but there is no shortage of configurations online. Find one that works for you.

I will try to publish my full emacs configuration some day in this blog. Have a look at tags/emacs: Maybe I finally got to it.

Footnotes:

1

You can even make it execute in a remote server, yet I have not played with that setting: dir: /<server-dns>:path

2

If I remember correctly there is even an org to markdown conversion for those that want to publish their sites with hugo and other technologies :P

Originally created on 2023-01-09 Mon 11:34