How can I surround my paragraphs with <section> tags?

I just started using Hugo a couple days ago so I’m still getting familiar with everything. Anyways, I have some markdown files, which get converted to HTML just fine using Hugo. The headers in the markdown files get surrounded by <h2> tags and the paragraphs get surrounded by

tags. However, I was wondering if it would be possible to, when generating the HTML files, surround each paragraph with the tags (i.e. the <h2> tag and all <p> tags underneath this current header would get surrounded by a block). I would also like to be able to set the id of the section to be equal to the id of the <h2> tag.
I’ve been trying to figure out a way to do this using regular expressions but I think it might not be possible that way. Here’s a little funky regex I came up with, but it wouldn’t work because it ends up skipping every other paragraph since I have to somehow capture the next <h2> tag to know when this paragraph ends.

replaceRE "(?sU)(<h[2-3] id=\"([^\"]+)\".+)(</h[2-9]+>)((?:.|\n)*)((<h[0-9])|$)" "<section id=\"${2}\">${1}${3}${4}</section>${5}"

Any help on how to do this would be greatly appreciated!

@shsh This sounds like one of those cases where we need you to back up and explain why you want this. Unless you use HTML (.html) instead of Markdown (.md) for your content files, I think you’d need to use shortcodes, but if we know what you are after, we might know of another way to achieve what you want.

Speaking of shortcodes, have you read up on how to create them?

1 Like

So I’m using the Hugo Codex theme and it has a table-of-contents.js file that should ideally show you your location in the document through the table of contents sidebar. However, the way it is currently set up, it shows your position based on the currently visible headers on screen. This seems to work fairly well in most cases, but if you have a section with a very large body, it doesn’t accurately show your position in the table of contents anymore, until you scroll down enough to reach the next header.
To make this functionality work, I was thinking of enclosing each section of the article in tags so that the script will be able to know when an entire section is visible or not, rather than just the header.
Maybe there’s a way to alter the javascript to make this work as well, but I couldn’t figure that out either.

GIF 8-16-2021 3-22-19 PM
Here’s a little gif to show what’s happening

To answer your original question…

layouts/_default/_markup/render-heading.html

{{ if eq .Level 2 }}
  {{ printf "<!-- end-chunk -->" | safeHTML }}
  {{ printf "<!-- begin-chunk data-anchor=%q -->" .Anchor | safeHTML }}
{{ end }}
<h{{ .Level }} id="{{ .Anchor | safeURL }}">{{ .Text | safeHTML }}</h{{ .Level }}>

template

{{ range (findRE `(?s)<!-- begin-chunk.*?(?:<!-- end-chunk -->|$)` .Content) }}
  {{ $anchor := replaceRE `(?s).+data-anchor="(.+?)".+` "$1" . }}
  {{ $section := replaceRE `(?s)<!-- begin-chunk.+?-->(.+?)(?:<!-- end-chunk -->|$)` "$1" . }}
  {{/* Remove leading and trailing newlines. */}}
  {{ $section = trim $section "\n" }}
  <div id="{{ $anchor }}">
  {{ $section | safeHTML}}
  </div>
{{ end }}
This produces something like...
<div id="section-1">
  <h2 id="section-1">Section 1</h2>
  <p>This is <strong>section</strong> 1.</p>
  <p>This is section 1.</p>

  <h3 id="section-11">Section 1.1</h3>
  <p>This is <strong>section</strong> 1.1.</p>
  <p>This is section 1.1.</p>

  <h3 id="section-111">Section 1.1.1</h3>
  <p>This is <strong>section</strong> 1.1.1.</p>
  <p>This is section 1.1.1.</p>
</div>

<div id="section-2">
  <h2 id="section-2">Section 2</h2>
  <p>This is <strong>section</strong> 2.</p>
  <p>This is section 2.</p>
</div>

<div id="section-3">
  <h2 id="section-3">Section 3</h2>
  <p>This is <strong>section</strong> 3.</p>
  <p>This is section 3.</p>
</div>
3 Likes

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.