How to imitate CSS counters?

For my projects I often use CSS counters for numbering sections, images etc.

Is it possible to imitate the behavior of CSS counters with the Go templating language?

Here is a quick example:

One level

Let’s say I want all images to have a number, I can do something like this:

shortcodes/figure.html

{{ .Page.Scratch.Add "figure" 1 }}
{{ $figure := .Page.Scratch.Get "figure" }}
<figure id="figure-{{ $figure }}">Figure {{ $figure }}</figure>

Two (or more) levels

Now let’s say I have another shortcode

shortcodes/example.html

{{ .Page.Scratch.Add "example" 1 }}
{{ $figure := .Page.Scratch.Get "example" }}
<div id="example-{{ $example }}">
    <div>Example {{ $example }}</div>
   {{ .Inner }}
</div>

In my article every example consists of several figures. I want the figure number to reset on every new example. How can I do that?

So instead of

Example 1

  • Figure 1
  • Figure 2

Example 2

  • Figure 3
  • Figure 4

I want

Example 1

  • Figure 1
  • Figure 2

Example 2

  • Figure 1
  • Figure 2

Brainstorming

In the example shortcode we add an array

{{ .Page.Scratch.Add "figure" (dict $example 0) }}

Then in the figure shortcode we add 1 to the number of the example with the highest number.

Any better ideas?

One way would be to range through the children of .Content or an outer Shortcode.

Here is a technique for counting the children of a Shortcode: Range over the children of a Shortcode - #6 by onedrawingperday

It can be adapted as needed.

The general idea would be to create the numbering within the scope of a: range $i, $e := $inner

$i stands for index
$e for element

Does your solution work if there is other content (than the counted one) in the main shortcode?

{{% example %}}

Some text.

{{< figure >}}

Some text.

{{< figure >}}

{{% /example %}}

What I posted in the linked topic, sometime ago, depends upon splitting newlines to create the collection of the Shortcode children.

Therefore I suppose that you could achieve what you’re asking by omitting the newline for items that you do not want to interfere with the index.