Hugo Code Block Folding
Strictly speaking, it is not folding, it just limits the maximum height of code blocks, though the effect is quite good.
Steps
All of the following operations are performed in the root directory of the blog site.
Control the layout with css
First add a code.css to assets/css/extended/code.css, which limits the maximum height of code blocks via css, and can be adjusted according to your own blog layout.
| |
Content:
| |
Implement synchronized scrolling with js
However, this introduces a problem: when scrolling through a code block, the code scrolls but the line numbers do not scroll in sync. You need to add js code to make them scroll together.
| |
Content:
Line number positioning stopped working after some update. I don’t plan to maintain it; use the
collapse shortcode instead. 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
{{- /* Footer custom content area start */ -}}
{{- /* Insert any custom code web-analytics, resources, etc. here */ -}}
{{- /* Footer custom content area end */ -}}
{{- if (and (eq .Kind "page") (ne .Layout "archives") (ne .Layout "search") (.Param "ShowCodeCopyButtons")) }}
<script>
// Synchronize scrolling between the code block and the line numbers.
// After the page loads, match up the code block and line-number containers and bind scroll events
window.addEventListener('load', function () {
// Get the code block and line-number container elements
var codeContainers = document.querySelectorAll('.highlight code[class^="language-"]');
var lineNumbersContainers = document.querySelectorAll('.highlight code[class^="hljs "]');
// Add the scroll event listener
var isScrollSyncing = false; // Flag indicating whether a scroll-sync operation is in progress
codeContainers.forEach(function (container, index) {
container.addEventListener('scroll', function () {
if (!isScrollSyncing) {
isScrollSyncing = true;
// Set the line-number container's scroll position to the same value
lineNumbersContainers[index].scrollTop = container.scrollTop;
isScrollSyncing = false;
}
});
});
lineNumbersContainers.forEach(function (container, index) {
container.addEventListener('scroll', function () {
if (!isScrollSyncing) {
isScrollSyncing = true;
// Set the code block container's scroll position to the same value
codeContainers[index].scrollTop = container.scrollTop;
isScrollSyncing = false;
}
});
});
});
</script>
{{- end }}
Additional Notes
Thanks to the extensibility of Hugo and the extension interface provided by the PaperMod theme, rich effects can be achieved quite easily.
I also reviewed my frontend coding style and was forced to debug the issue of scrolling not staying in sync. That is the nice thing about frontend development: what you see is what you get. With a browser you don’t even need to set up an environment, haha.
Finally, thanks to Sulv’s blog for the idea, see Git for Sulv’s Blog.