Daniel Liden

Blog / About Me / Photos / Notebooks / Notes /

Org Mode Headlines in Org Source Blocks

Note: I know the org-mode syntax highlighting in the current theme is very low-contrast. I will update this soon.

The Problem

When writing about org mode, one often wants to show what particular org headline look like in terms of formatting, properties, tags, options, etc,. However, even within a babel org source block, an org header will be parsed and exported as a header. We can get around this by prepending the headline with a comma. The comma won't show up when exported: all that is exported is a nicely-formatted example of an org headline.

Here is an example of the issue. Below, I inserted an org source block (defined with #+begin_src org) with a first-level org headline inside, without inserting a comma before the headline.


#+beginsrc org

This Headline Is in an Org Source Block

And it is still parsed and exported as a headline, not as an example. #+endsrc


Clearly, this isn't what we want.

Prepend Headlines in Source Blocks with Commas

This issue is easily resolved: just insert a comma before the headline in the source block (e.g. ,* Headline). This results in the following:

* This Headline Is in an Org Source Block
and it looks like org source, not like an exported org file.

This approach works well with more complicated org-mode syntax, as well. For example, the following block:

,* Headline 1
:PROPERTIES:
:ID:       642BF4EE-3139-4B96-97C4-D3BABD86FFD5
:END:
,** Headline 2
This headline is also prepended with a comma!
,** Even a Nested Source Block!
,#+begin_src R
1+1
,#+end_src

,#+RESULTS:
: 2

leads to the following (when we specify that it is an org source block).

* Headline 1
:PROPERTIES:
:ID:       642BF4EE-3139-4B96-97C4-D3BABD86FFD5
:END:
** Headline 2
This headline is also prepended with a comma!
** Even a Nested Source Block!
#+begin_src R
1+1
#+end_src

#+RESULTS:
: 2

An Easier Way

We can use the org-edit-special command (C-c ') within an org source block to open a separate editing environment (in this case, another org buffer). We can then write some org syntax. When we exit the environment (again, with C-c '), it will be properly formatted for export.

The following block was generated using this method:

,* Headline 1                                                    :example_tag:
This is an org headline with a tag.
,** TODO Second Headline
SCHEDULED: <2022-02-15 Tue>
:PROPERTIES:
:CUSTOM_ID: headline_1
:END:
,** Babel

,#+begin_src jupyter-python :session datasci
import numpy as np

np.array(range(1,10))
,#+end_src

,#+RESULTS:
: array([1, 2, 3, 4, 5, 6, 7, 8, 9])

Which generates:

* Headline 1                                                    :example_tag:
This is an org headline with a tag.
** TODO Second Headline
SCHEDULED: <2022-02-15 Tue>
:PROPERTIES:
:CUSTOM_ID: headline_1
:END:
** Babel

#+begin_src jupyter-python :session datasci
import numpy as np

np.array(range(1,10))
#+end_src

#+RESULTS:
: array([1, 2, 3, 4, 5, 6, 7, 8, 9])

This approach is easier because there is no need to remember or guess what, exactly, needs to be prepended with a comma. In this case, the headlines themselves, the nested #+begin_src and #+end_src lines, and the #+RESULTS: line were all escaped with commas.

With both of these approaches available, writing about org mode with example org source blocks should be much easier.

Date: 2022-02-08 Tue 00:00

Emacs 29.3 (Org mode 9.6.15)