Labeling code blocks in ox-hugo
By chance, I’v stumbled over an excellent article1 about labeling code blocks in hugo.
Roger’s article answers a major part of a question2 of mine:
How to visually distinguish between blocks of source code and result
Problems
There’s no not enough visual difference between the blocks of code and result
print("foo")
foo
The code’s filepath must be written out to be displayed to the reader.
Regardless if it’s already stored as tangle
header argument3, the filepath must be written twice in order to be visible
That means alongside :tangle xyz.py
, I must as well write as a comment # xyz.py
to show what is meant.
#+begin_src python :tangle xyz.py
# xyz.py
print("foo")
#+end_src
Solution
We distinguish the code block by adding a label above it.
Before:
print("foo")
After:
print("foo")
What happens
Input org mode
file:
#+begin_src python :tangle /tmp/foo.py
print("foo")
#+end_src
Output markdown
file:
```python { tangle_filepath="/tmp/foo.py" }
print("foo")
```
Final rendered html:
print("foo")
If not necessary, we can easily disable4 the tangle function while still having access to the arguments value.
How it works
Instead of adding the filename verbatim as comment #xyz.py
like in code block, we intercept the value of :tangle
.
That intercepted value then is passed, parsed and rendered as an additional html element named <figcaption>
right above the code block.
My contribution is in two parts:
Adding a custom markup renderer
By combining parts of Roger’s instructions5 and the example in the hugo documentation, I’ve come up whith his custom code block
{{- with .Attributes.tangle_filepath }}
<figcaption>
<span>{{ . }}</span>
</figcaption>
{{- end }}
{{ $result := transform.HighlightCodeBlock . }}
{{ $result.Wrapped }}
Adding some new logic to ox-hugo.el
- First I’ve added a variable named
tangle_filepath
to the mighty ox-hugo.el6. - Second I’ve added some logic to convert the
:tangle
parameter in the org mode file to an info-string7 in the rendered markdown.
Both additions are highlighted below
diff --git a/ox-hugo.el b/ox-hugo.el
index 469002a..0a66f6b 100644
--- a/ox-hugo.el
+++ b/ox-hugo.el
@@ -3471,6 +3471,11 @@ their Hugo site's config."
;; Regular src block.
(t
(let* (;; See `org-element-src-block-parser' for all SRC-BLOCK properties.
+ (tangle-filepath
+ (let ((tangle-value (cdr (assoc :tangle parameters))))
+ (if (or (null tangle-value) (string= tangle-value "no"))
+ nil
+ tangle-value)))
(line-num-p (org-element-property :number-lines src-block)) ;Non-nil if -n or +n switch is used
(linenos-style (or (cdr (assoc :linenos parameters))
;; If `org-hugo-src-block' is called from
@@ -3572,6 +3577,11 @@ their Hugo site's config."
(setq code-attr-str (format "%s, hl_lines=%s" code-attr-str hl-lines))
(setq code-attr-str (format "hl_lines=%s" hl-lines))))
+ (when tangle-filepath
+ (if (org-string-nw-p code-attr-str)
+ (setq code-attr-str (format "%s, tangle_filepath=\"%s\"" code-attr-str tangle-filepath))
+ (setq code-attr-str (format "tangle_filepath=\"%s\"" tangle-filepath))))
+
(when code-refs
(let* ((anchor-prefix (cdr code-refs-and-anchor))
(anchor-str (format "anchorlinenos=true, lineanchors=%s" anchor-prefix)))
CSS styling
Literally similar to Roger’s article1: “I’ll leave the styling (of the figcaption html element) as an exercise for the reader”.
-
https://write.rog.gr/writing/labeling-code-blocks-in-hugo/
↩︎ ↩︎ -
https://orgmode.org/manual/Using-Header-Arguments.html#Header-arguments-in-Org-mode-properties
↩︎ -
↩︎
* org mode outline header :PROPERTIES: :header-args: :tangle no :END:
-
https://write.rog.gr/writing/labeling-code-blocks-in-hugo/#using-custom-render-hooks
↩︎ -
https://github.com/kaushalmodi/ox-hugo/blob/main/ox-hugo.el
↩︎