Source blocks

ox-hugo tries to generate Markdown with fenced code blocks if possible. It also supports exporting source blocks with line numbers and/or highlighting enabled for specific lines.

Code Fences #

By default, the HUGO_CODE_FENCE property is set to a non-nil value. So the code blocks will be exported with GitHub-style code-fencing with triple-backticks when possible.

Example:

```emacs-lisp
(message "Hello")
```
Note
It is necessary to set the Hugo site config variable pygmentsCodeFences to true for syntax highlighting to work for fenced code blocks.

The Hugo highlight shortcode is automatically used instead of code fences (even with this property at a non-nil value) if:

  • Line numbers are enabled using the Org -n / +n syntax (see below), or
  • Line highlighting is enabled using the :hl_lines parameter in the source block header (see below).

Set the HUGO_CODE_FENCE property to nil if you want to always use the Hugo highlight shortcode.

Line numbers #

Line numbers can be enabled/configured using the Org -n / +n syntax. See the Info node (org) Literal examples for more information.

Here are some examples fetched from the “Source blocks with line number annotation” test case in the all-posts.org.

Default new line number start #

Org source #

#+begin_src emacs-lisp -n
;; this will export with line number 1 (default)
(message "This is line 2")
#+end_src

Output #

1
2
;; this will export with line number 1 (default)
(message "This is line 2")

Specify new line number start #

Org source #

#+begin_src emacs-lisp -n 20
;; this will export with line number 20
(message "This is line 21")
#+end_src

Output #

20
21
;; this will export with line number 20
(message "This is line 21")

Default continued line numbers #

Org source #

#+begin_src emacs-lisp +n
;; This will be listed as line 22
(message "This is line 23")
#+end_src

Output #

22
23
;; This will be listed as line 22
(message "This is line 23")

Specify continued line numbers jump #

Org source #

#+begin_src emacs-lisp +n 10
;; This will be listed as line 33
(message "This is line 34")
#+end_src

Output #

33
34
;; This will be listed as line 33
(message "This is line 34")

Highlighting #

Implementing this feature was interesting, because while Org doesn’t have a syntax to enable highlighting only specific lines, the Hugo highlight shortcode does allow that via hl_lines argument.

So the challenge was to present that “lines to be highlighted” information in the Org source in a nice format and then translate that to the hl_lines highlight shortcode argument at the time of exporting.

It involved hacking the org-babel-exp-code. See this discussion on the emacs-orgmode thread if interested.

This feature is implemented by using a parameter called :hl_lines in the header of source blocks. This parameter is specific to ox-hugo, and that’s why implementing this needed that hack.

If a user wants to highlight lines 1, and then 3 to 5, they would add :hl_lines 1,3-5 to the source block header.

Source block with line numbers examples #

#+begin_src emacs-lisp -n
;; this will export with line number 1 (default)
(message "This is line 2")
#+end_src
#+begin_src emacs-lisp -n 20
;; this will export with line number 20
(message "This is line 21")
#+end_src
#+begin_src emacs-lisp +n
;; This will be listed as line 22
(message "This is line 23")
#+end_src
#+begin_src emacs-lisp +n 10
;; This will be listed as line 33
(message "This is line 34")
#+end_src

Source block with line highlighting examples #

#+begin_src emacs-lisp :hl_lines 2
(message "This is line 1")
(message "This is line 2")
(message "This is line 3")
#+end_src
#+begin_src emacs-lisp :hl_lines 1,3-5
(message "This is line 1")
(message "This is line 2")
(message "This is line 3")
(message "This is line 4")
(message "This is line 5")
(message "This is line 6")
#+end_src
#+begin_src emacs-lisp -n 7 :hl_lines 1,3-5
(message "This is line 7 in code, but line 1 for highlighting reference")
(message "This is line 8 in code, but line 2 for highlighting reference")
(message "This is line 9 in code, but line 3 for highlighting reference")
(message "This is line 10 in code, but line 4 for highlighting reference")
(message "This is line 11 in code, but line 5 for highlighting reference")
(message "This is line 12 in code, but line 6 for highlighting reference")
#+end_src
#+begin_src emacs-lisp -n :hl_lines 1,3-5
(message "This is line 1")
(message "This is line 2")
(message "This is line 3")
(message "This is line 4")
(message "This is line 5")
(message "This is line 6")
#+end_src

Without line numbers #

Org source #

#+begin_src emacs-lisp :hl_lines 1,3-5
(message "This is line 1")
(message "This is line 2")
(message "This is line 3")
(message "This is line 4")
(message "This is line 5")
(message "This is line 6")
#+end_src

Output #

(message "This is line 1")
(message "This is line 2")
(message "This is line 3")
(message "This is line 4")
(message "This is line 5")
(message "This is line 6")

Above highlighting might look weird as the highlighting spans the full page/container width. This could be either called a bug in Hugo, or the HTML limitation.

A workaround is below.. use line numbers too!.

Highlighting only 1 line #

Org source #
#+begin_src emacs-lisp :hl_lines 2
(message "This is line 1")
(message "This is line 2")
(message "This is line 3")
#+end_src
Output #
(message "This is line 1")
(message "This is line 2")
(message "This is line 3")

With line numbers #

The Org source for the below is similar to the above, except that the -n switch is also added to enable the line numbers.

With line numbers enabled, the highlighting is limited to the width of the HTML table rows (because ox-hugo sets the linenos=table option in the highlight shortcode when line numbers are enabled).

Note 1
When using both, switches (like -n), and header args (like :hl_lines), the switches have to come first.
Note 2
The line numbers in the value for :hl_lines parameter is always with the starting line number reference of 1. That has no relation with the value of the line numbers displayed using the -n or +n switches!

Org source #

#+begin_src emacs-lisp -n 7 :hl_lines 1,3-5
(message "This is line 7 in code, but line 1 for highlighting reference")
(message "This is line 8 in code, but line 2 for highlighting reference")
(message "This is line 9 in code, but line 3 for highlighting reference")
(message "This is line 10 in code, but line 4 for highlighting reference")
(message "This is line 11 in code, but line 5 for highlighting reference")
(message "This is line 12 in code, but line 6 for highlighting reference")
#+end_src

Output #

7
8
9
10
11
12
(message "This is line 7 in code, but line 1 for highlighting reference")
(message "This is line 8 in code, but line 2 for highlighting reference")
(message "This is line 9 in code, but line 3 for highlighting reference")
(message "This is line 10 in code, but line 4 for highlighting reference")
(message "This is line 11 in code, but line 5 for highlighting reference")
(message "This is line 12 in code, but line 6 for highlighting reference")
Fork me on GitHub