You will have to use a custom partial like this: {{- $headers := findRE "<h[2-4].*>(.|\n])+</h[2-4]>" .Content -}}. This will find all h2 to h4 from the .Content which also includes Shortcodes.
Shortcodes using the % as the outer-most delimiter will now be fully rendered when sent to the content renderer. They can be part of the generated table of contents, footnotes, etc.
content/post/test.md
+++
title = "Test"
date = 2021-03-27T04:48:08-07:00
draft = false
introduction = "This is the introduction."
conclusion = "This is the conclusion."
+++
{{% my-shortcode introduction %}}
{{% my-shortcode conclusion %}}
layouts/shortcodes/my-shortcode.html
{{ with $topic := .Get 0 }}
## {{ $topic | title }}
{{ index $.Page.Params $topic }}
{{ else }}
{{ errorf "The %s shortcode requires a single positional parameter. See %s" .Name .Position }}
{{ end }}
Produces this HTML.
<nav id="TableOfContents">
<ul>
<li><a href="#introduction">Introduction</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
</nav>
<h1>Test</h1>
<h2 id="introduction">Introduction</h2>
<p>This is the introduction.</p>
<h2 id="conclusion">Conclusion</h2>
<p>This is the conclusion.</p>