Add h4 finding entries to the TOC nav

Each finding's detail-list table is now its own indented nav item
under "Finding Detail Lists", one click away instead of scroll-only.
Also fixes a double-space artifact in h4 badge titles (regex wasn't
consuming the whitespace after "[Severity]" before inserting the
badge span), which was most visible once those titles started
feeding the nav labels.
This commit is contained in:
2026-08-21 17:05:01 -04:00
parent 8f57ea650c
commit 3f1370eda5
+8 -7
View File
@@ -85,6 +85,7 @@ body {
.toc a:hover { color: var(--text); } .toc a:hover { color: var(--text); }
.toc a.active { color: var(--accent); border-left-color: var(--accent); } .toc a.active { color: var(--accent); border-left-color: var(--accent); }
.toc a.toc-h3 { padding-left: 1.5rem; font-size: 0.94em; } .toc a.toc-h3 { padding-left: 1.5rem; font-size: 0.94em; }
.toc a.toc-h4 { padding-left: 2.3rem; font-size: 0.88em; opacity: 0.85; }
.wrap { .wrap {
flex: 1 1 auto; flex: 1 1 auto;
min-width: 0; min-width: 0;
@@ -347,7 +348,7 @@ def badge_findings_table(html_text):
cell_html, cell_html,
) )
cell_html = re.sub( cell_html = re.sub(
rf"(<h4[^>]*>)\[{severity}\]", rf"(<h4[^>]*>)\[{severity}\]\s*",
rf'\1<span class="badge {css_class}">{severity}</span> ', rf'\1<span class="badge {css_class}">{severity}</span> ',
cell_html, cell_html,
) )
@@ -367,17 +368,17 @@ def wrap_timestamps(html_text):
return RFC3339_UTC_RE.sub(r'<span class="ts" data-utc="\1">\1</span>', html_text) return RFC3339_UTC_RE.sub(r'<span class="ts" data-utc="\1">\1</span>', html_text)
HEADING_RE = re.compile(r'<h([23]) id="([^"]+)">(.*?)</h\1>', re.S) HEADING_RE = re.compile(r'<h([234]) id="([^"]+)">(.*?)</h\1>', re.S)
def build_toc(body_html): def build_toc(body_html):
"""Sidebar nav linking to every h2/h3 in the report (h4 finding headers """Sidebar nav linking to every h2/h3/h4 in the report, including each
are left out -- there can be many of those and they'd swamp the nav).""" individual finding's detail-list table (h4) so they're one click away."""
items = [] items = []
for level, anchor_id, text in HEADING_RE.findall(body_html): for level, anchor_id, text in HEADING_RE.findall(body_html):
label = re.sub(r"<[^>]+>", "", text).strip() label = re.sub(r"\s+", " ", re.sub(r"<[^>]+>", "", text)).strip()
css_class = " toc-h3" if level == "3" else "" css_class = {"3": "toc-h3", "4": "toc-h4"}.get(level, "")
items.append(f'<a class="{css_class.strip()}" href="#{anchor_id}">{label}</a>') items.append(f'<a class="{css_class}" href="#{anchor_id}">{label}</a>')
if not items: if not items:
return "" return ""