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 non-nil. So the code
blocks will be exported with CommonMark code fences when possible.
For example, below Org source block:
#+begin_src emacs-lisp
(message "Hello")
#+end_src
will export to:
```emacs-lisp
(message "Hello")
```
- Note
- It is necessary to set the Hugo site config variable
markup.highlight.codeFences
totrue
(which is the default at least as of Hugo v0.60.0) for syntax highlighting to work for fenced code blocks.
Line numbers #
Line numbers can be enabled/configured using the Org -n
/ +n
syntax. See Org Info: 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 #
|
|
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 #
|
|
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 #
|
|
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 #
|
|
Line number Style (linenos) #
The value of linenos
(Hugo’s default value or the site-global value
set in its config.toml
) can be overridden per source block using the
:linenos
parameter in that source block’s header.
:linenos value |
Description |
---|---|
false |
Disable line numbers. |
true |
Enable line numbers with Hugo’s default value of lineNumbersInTable . |
inline |
Enable line numbers where the line numbers and code are rendered in HTML <div> and <span> tags. |
table |
Enable line numbers where the line numbers and code are rendered in HTML tables. |
Example usage: If a user has enabled the line numbers by default by
adding this in their site’s config.toml
:
[markup]
[markup.highlight]
lineNos = true
, they can disable line numbers for selected source blocks by adding
:linenos false
to their headers.
#+begin_src emacs-lisp :linenos false
(message "hello")
(message "bye")
#+end_src
The :linenos
header arg works for example blocks too.
Line numbers in HTML table #
The source block or code block rendering is done by Hugo using the
chroma syntax highlighter. When the line numbers are enabled, the line
numbers and code blocks can be rendered either in HTML tables
(lineNumbersInTable = true
) or in the div
and span
tags
(lineNumbersInTable = false
). See Hugo’s default value of this
config variable here.
To render the line numbers and code blocks in HTML tables regardless
of Hugo’s default value, add this to your site’s config.toml
:
[markup]
[markup.highlight]
lineNumbersInTable = true
To override the rendering of line numbers and code blocks to happen in
<div>
and <span>
tags, set lineNumbersInTable = false
instead,
but this is not recommended. With lineNumbersInTable = false
,
when the code blocks are copied in Firefox, extra blank lines get
inserted after each line when pasted elsewhere. See Bugzilla #
1273836.
Highlight Lines #
Implementing this feature was interesting, because while Org doesn’t
have a syntax to enable highlighting only specific lines, Hugo
supports line highlighting using the hl_lines
attribute for code
fences (Hugo v0.60.0+) or its highlight
shortcode.
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
attribute with the required format 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.
Highlighting 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")
Highlighting 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 if the linenos
option is set to table
(default).
- 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 #
|
|
Hiding source block caption numbers #
The “Code Snippet <number>:” part of the source block captions can be hidden by adding this to the CSS:
.src-block-number {
display: none;
}
Code References #
ox-hugo
generates code references hyperlinked to line numbers of
source and example blocks when using the (ref:REF)
syntax in the
blocks as explained in Org Info: Literal Examples.
Org interprets strings like
(ref:name)
as labels, and use them as targets for special hyperlinks like[[(name)]]
— i.e., the reference name enclosed in single parenthesis.You can also add a
-r
switch which removes the labels from the source code.
One convenience feature added by ox-hugo
is that the -n
is always
implied when code references are detected in the source or example
blocks.
- Note
- It is the user’s responsibility to ensure that all code ref labels used within a single post are unique.
Code references exported with labels #
As an example, this in Org source:
#+begin_src emacs-lisp
(save-excursion (ref:sc)
(goto-char (point-min)) (ref:jump)
#+end_src
In line [[(sc)]] we remember the current position. [[(jump)][Line (jump)]] jumps to
~point-min~.
exports to:
In line sc we remember the current position. Line jump jumps to
point-min
.
Code references exported without labels #
When the -r
switch is used in the header, the code ref labels are
removed from the exported code block, and the labels in code ref link
descriptions are replaced with line numbers.
As an example, this in Org source:
#+begin_src emacs-lisp -r
(save-excursion (ref:sc1)
(goto-char (point-min)) (ref:jump1)
#+end_src
In line [[(sc1)]] we remember the current position. [[(jump1)][Line (jump1)]] jumps to
~point-min~.
exports to:
In line 1 we remember the current position. Line 2 jumps to
point-min
.
highlight
shortcode #
By default, ox-hugo
tries to avoid using this shortcode because it
is buggy (#161), and also it’s better to export
CommonMark supported code fences than Hugo-specific shortcodes.
The Hugo highlight
shortcode is used instead of code fences if one
of these is true:
HUGO_CODE_FENCE
is set to nil.- “Blackfriday mode” is enabled (
HUGO_GOLDMARK
is nil) and either of the line numbering, line highlighting or code ref features are enabled, or if the:linenos
parameter is specified in the source block header.