<section<h#></h#>...</section> scheme not possible even with .Scratch and a counter

Hi,
I’m new to the likes of global variables and counters.
I try to implement a <section><h#>sfsfs</h#>Chapter</section> layout, for instance to give a different background to chapters with specific headings.
What I want is one Page-level variable which I would rewrite, like a counter, to signify how deep on the heading tree we are. Then I would add $dept - .Level </section> closing tags, before reducing the counter of that much.
I think of using:

{{range ((index (Scratch.Get "closing_tags") 1) - .Level)}}
</section>
{{end}}
{{$scratch.Set "closing_tags" ((index (Scratch.Get "closing_tags") 1) - .Level)}}
<section id="{{ .Anchor | safeURL }}">
	<h{{ .Level }}>
	  <a class=heading href="#{{ .Anchor | safeURL }}">{{ .Text | safeHTML }}</a>
	</h{{ .Level }}>

and at the start of baseof.html:

{{ $scratch.Set “closing_tags” 0 }}

Problem is it can’t work with the last closing tags after the last paragraph, because the footnotes (more accurately called endnotes on a webpage) are part of .Content, I can’t put anything between them and the last paragraph.

Hugo doesn’t facilitate that very common layout, if it allows it all.
I hope one day we’ll have detachable footnotes (.Endnotes) not part of .Content., to keep total control of our layout. What if I want them in a sidebar for instance ?

Perhaps CSS counters help. Though I’m not sure that I understood what you’re after.

No css counters don’t work, I need to edit the html, meaning, using partials.

I want the text to be divided by section tags like this:

 <section>
    <h1>h1 In a section></h1>
    <section>
      <h2>h2 in a nested section</h2>
      <section>
        <h3>h3 doubly nested in two sections</h3>
        text in subchapter
      </section>
      <section>
        <h3>h3 doubly nested in two sections</h3>
        text in subchapter
      </section>
    </section>
  </section>

So I need to keep track of how deep I am in the tree - which is easy with .Level, only available in render-heading.html - and at the end of the document, before <div class=footnotes>.

. In this dream, you are welcome to participate.<div class=footnote …

And I would need to insert a (.Level - 1) number of tags before the div. I can’t write that in render-heading.html (as far as I understand ?) but I can’t know the last the depth level reached down the tree outside of render-heading.html.

Unless I increment a scratch counter with every heading and use it at the end of the document to edit .Content.
But then it would have to parse .Content first… I don’t know how that works.

Your best idea?

You may wish to review: There Is No Document Outline Algorithm — Adrian Roselli
and MDN - avoid using multiple h1 elements on one page

2 Likes

It was interesting but what is your point ?
I am not wanting to do this:

<article>
  <h>Article title</h>
  <p>Lorem ipsum</p>

  <section>
    <h>A secondary heading</h>
    <p>Lorem ipsum</p>

    <section>
      <h>A tertiary heading</h>
      <p>Lorem ipsum</p>
    </section>

  </section>

  <section>
    <h>heading</h>
    <p>Lorem ipsum</p>
  <section>
</article>

for the simple reason that goldmark doesn’t work that way at all and correcting this afterwards seems very tedious. Proper headings are generated automatically so I would never need an outline algorithm with hugo/markdown.
The only reason I want to encapsulate headings and the following text within sections, is to target entire chapter of whatever depth and style them.
Without sections I don’t know how I can accomplish this.

Sorry, I wasn’t clear on what you wanted.

I think you may want to consider using either

or

configured to not render as individual pages and accessed via .GetPage in the ‘article’ page.

I think the latter option would be easier to work with.

?? How does either relate any more to my article layout issue ?

They’ll allow you to use a pair of recursive partials that ‘walk’ the content (or data) tree.

The branch page bundle choice has the advantage that you can have your headings and per-chapter / sub-chapter content together and use a layout that wraps them in a section or div quite nicely.

I’ll try to make some time to an example of what I mean, later.

Yes thanks, because I really don’t get it.

I’ve created a reasonably minimal example that I think does what you want.

A screenshot of a mostly unstyled article

And the HTML from the Hugo local server:

<!DOCTYPE html>
<html lang="en-us" dir="ltr">
<head><script src="/livereload.js?mindelay=10&amp;v=2&amp;port=1313&amp;path=livereload" data-no-instant defer></script>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Article</title>
<meta name="generator" content="Hugo 0.111.3">
<style>
   .sl2 {
      background-color: azure;
   }
   .sl3 {
      background-color: beige;
   }
   .sl4 {
      background-color: Gainsboro;
   }
</style>
</head>

<body>
<div>
<header><div><a href="/" title="Home" class="header__site-link" rel="home"><span>My New Hugo Site</span></a></div></header>

<main>
<h1>Article</h1>
<h2 id="forward">Forward</h2>
<p>A brief bit before the article.</p>

<div class="sl2">
<h2><a href="">Chapter 1</a></h2>
<div class="sl3">
<h3><a href="">Sub-part-1</a></h3>
<p>Out on the range.</p>
</div>
<div class="sl3">
<h3><a href="">Sub part 2</a></h3>
<p>Meanwhile, back at the ranch&hellip;</p>
</div>
</div>
<div class="sl2">
<h2><a href="">Chapter 2</a></h2>
<p>It&rsquo;s short.</p>
</div>
</main>

</div>
</body>
</html>

You can see the code at

And a site deployed on Netlify at Article (demo.wildtechgarden.com)

Does that make it more clear, and will that achieve what you want? If not, please let me know in what way I’ve missed what you are looking for.

1 Like

Oh…
In fact, yes it looks very close to what I would like, except heading numbers would not reset within sections. But your solution would be an absolute maintenance nightmare and it’s horribly clunky compared to writing articles in one go. I don’t even want simple leaf bundles, so this would obviously be a big no no. So goldmark doesn’t allow the layout (or anything but their plain one).
That sucks.

Do you need the section or would the following Hugo feature be enough?

Hugo supports adding attributes (e.g. CSS classes) to Markdown blocks, e.g. tables, lists, paragraphs etc.

A blockquote with a CSS class:

> foo
> bar
{.myclass}

Or if the issue is that you are unhappy with the limitations of CommonMark based Markdown, you may want to try one of Hugo’s content formats:

Name Markup identifiers Comment
Goldmark md, markdown, goldmark Note that you can set the default handler of md and markdown to something else, see Configure Markup.
Emacs Org-Mode org See go-org.
AsciiDoc asciidocext, adoc, ad Needs Asciidoctor installed.
RST rst Needs RST installed.
Pandoc pandoc, pdc Needs Pandoc installed.
HTML html, htm To be treated as a content file, with layout, shortcodes etc., it must have front matter. If not, it will be copied as-is.

I already make a generous use of this since shortcodes are so inconvenient.
But how could this target a block that doesn’t exist ? Without a framing paragraphs, there’s no targeting them with css. Foregoing markdown is out of the question for what amounts to a HTML purist’s quest.

But changing the markdown handler, why not ? I thought the reason we switched to Goldmark is that others sucked ? And I don’t know if pandoc or ascii-doc can be parameterize as to produce that headings/sections outline. Only the the default handler is explained. If I only need to write a few python or go lines, I can try.

Could supply some sample Markdown / content that have or want to have and what you want out of it, and why?

Also, what you have tried (the source and output) and why that is not what you want, would help.

It’s rather difficult to help when flying blind.

1 Like

Sorry, here’s for you:

md file

---
title: essai
---

## A
AAAA
## B
BBB
### c
BBBccc
### d
BBBddd

current ouput:

<article id=book-content>
<h2 id=a><a class=heading href=#a>A</a></h2><p>AAAA
<h2 id=b><a class=heading href=#b>B</a></h2><p>BBB
<h3 id=c><a class=heading href=#c>c</a></h3><p>BBBccc
<h3 id=d><a class=heading href=#d>d</a></h3>
<p>BBBddd
</article>

What I want:

<article id=book-content>
<section>
<h2 id=a><a class=heading href=#a>A</a></h2><p>AAAA
</section>
<section>
<h2 id=b><a class=heading href=#b>B</a></h2><p>BBB
<section>
<h3 id=c><a class=heading href=#c>c</a></h3><p>BBBccc
<section>
<h3 id=d><a class=heading href=#d>d</a></h3><p>BBBddd
</section>
</section>
</article>

Hugo facilities every and any layout. You issue is that you want to generate very specific set of markup, using content. That’s not going to be easy and seems like the hardest possible way to achieve what you want.

I’d suggest using a list template, and organising your content in the structure you want. That way you can attach any style you like directly to the content item itself, as front matter. For example, if the 3rd ‘section’ should have a green background, set that as a parameter in section-3.md and then output it as your list page loops through the sections.

However, if you are in fact dealing with a book/article/essay then the example markup you are trying to achieve is far from ideal. In your example the current output is almost perfect (it is missing closing p tags), but the example you are trying to get is not good at all from a semantics perspective, it makes no sense and the reason you gave for attempting this doesn’t make much sense either;

The only reason I want to encapsulate headings and the following text within sections, is to target entire chapter of whatever depth and style them.

Why would you want to do that??

1 Like

Why would I want to style a chapter specifically ? Why not ? It would reflect the logical structure of a book. Btw the absence of </p> is hugo’s/goldmark’s doing, not mine. It seems not to matter semantically..

Because it doesn’t make sense. The logical structure of a book is based on the order of content, and heading levels.

What you are trying to achieve would damage the logical structure, and poor html provides poor semantics.

If you are trying to change ‘the look’ use css, not arbitrary section elements as that will change ‘the meaning’. It would be trivial to attach a class to each heading element of a ‘section’ you wanted to style and use that as a hook to style that ‘section’, using the .has() selector, possibly in combination with an adjacent sibling combinator, though it depends on exactly what you are trying to achieve.

Get the html right and the document will always be right.

1 Like

I agree… if it worked. But that selector isn’t widely supported yet. This should do the trick:

h3#special_paragraph ~ *:has(~h3) {
           properties:values;
}

It would be much more indirect and cumbersome css than #special_paragraph + section {…},
with the added benefit of working with all heading levels. But I could use inline css in the heading renderhook to profit from .Level.
A big caveat though:
Borders/outline and worse background images (kinda what I was looking for, oups !) absolutely require a container(<section> !!) to not look ugly. Or am I mistaken ?

You are overspecifiying your css. Don’t use h3 as an element selector and it will work with all heading levels, but I still think the best approach is to use a list template. That way you can easily style each section however you want; just add front-matter to your ‘chapter’.

title: chapter 2
image: supporting-image.jpg
blockClass: bg-green border-2 font-papyrus text-beige 

Keeps everything you need in one place, with the content. Untested, top-of-head example list template:

{{ define "main" }}
  <article>
    <h1>{{ .Title }}</h1>
    {{ range .Pages }}
      <section{{ if isset .Params "blockClass" }} class="{{ blockClass }}"{{ end }}>
        <h2>{{ .Title }}</h2>
        {{ .Content }}
      </section>
    {{ end }}
  </article>
{{ end }}
1 Like