feature: Add hierarchical figure numbers for picture, photo, and table tags

This commit is contained in:
Lars Weiler
2026-01-06 14:22:22 +01:00
committed by Lars Weiler
parent 2a6b8eac21
commit 072aaf2e49
5 changed files with 374 additions and 20 deletions
+79 -4
View File
@@ -28,7 +28,16 @@ class FiftyOhmHtmlRenderer(HtmlRenderer):
ref_id = 0
def __init__(
self, *extras, question_renderer=None, picture_handler=None, photo_handler=None, include_handler=None, **kwargs
self,
*extras,
question_renderer=None,
picture_handler=None,
photo_handler=None,
include_handler=None,
edition=None,
chapter=None,
section=None,
**kwargs,
):
super().__init__(
Dash,
@@ -61,6 +70,17 @@ class FiftyOhmHtmlRenderer(HtmlRenderer):
self.photo_handler = photo_handler
self.include_handler = include_handler
# Figure numbering context
self.edition = edition
self.chapter = chapter
self.section = section
# Figure map: stores ref -> hierarchical number mapping
self.figure_map = {}
# Single unified counter for all figure types (pictures, photos, tables)
self.figure_counter = 0
def render_dash(self, token):
return " – "
@@ -175,10 +195,56 @@ class FiftyOhmHtmlRenderer(HtmlRenderer):
lookup = {"": "", " ": " "}
return f"{lookup[token.first]}{token.second}{lookup[token.third]}"
def collect_figures(self, document):
"""First pass: collect all figures and assign hierarchical numbers."""
self.figure_counter = 0
self.figure_map = {}
self._collect_figures_recursive(document)
def _collect_figures_recursive(self, token):
"""Recursively traverse the document tree to collect figures."""
if hasattr(token, "children") and token.children is not None:
for child in token.children:
# Check if this is a Picture token
if isinstance(child, Picture):
self.figure_counter += 1
hierarchical_num = self._format_figure_number(self.figure_counter)
self.figure_map[child.ref] = hierarchical_num
child.number = hierarchical_num
# Check if this is a Photo token
elif isinstance(child, Photo):
self.figure_counter += 1
hierarchical_num = self._format_figure_number(self.figure_counter)
self.figure_map[child.ref] = hierarchical_num
child.number = hierarchical_num
# Check if this is a Table token
elif isinstance(child, Table):
if child.name: # Only number tables with names
self.figure_counter += 1
hierarchical_num = self._format_figure_number(self.figure_counter)
self.figure_map[child.name] = hierarchical_num
child.number = hierarchical_num
else:
child.number = ""
# Recurse into children
self._collect_figures_recursive(child)
def _format_figure_number(self, counter):
"""Format the hierarchical figure number based on context."""
if self.edition and self.chapter and self.section:
return f"{self.edition}-{self.chapter}.{self.section}.{counter}"
else:
# Fallback for tests or when context is not provided
return str(counter)
def render_references(self, token):
# Look up the figure number from the map
figure_num = self.figure_map.get(token.first, "?")
return (
f'<a href="{self.section_url}#ref_{token.first}"'
f" onclick=\"highlightRef('{token.first}');\">{self.ref_id}</a>"
f" onclick=\"highlightRef('{token.first}');\">{figure_num}</a>"
)
def render_question(self, token):
@@ -222,10 +288,19 @@ class FiftyOhmHtmlRenderer(HtmlRenderer):
return self.render_photo_helper(token.id, token.ref, token.text, token.number)
def render_table(self, token: Table):
table = f'<table class="table table-hover">\n{self.render_inner(token)}'
# Add id and name attributes if table has a name
table_attrs = ""
if token.name:
table_attrs = f' id="ref_{token.name}" name="{token.name}"'
table = f'<table class="table table-hover"{table_attrs}>\n{self.render_inner(token)}'
if token.caption != "":
table += f"<caption>{token.caption}</caption>\n"
# Include hierarchical number in caption if available
caption_text = token.caption
if hasattr(token, "number") and token.number:
caption_text = f"Tabelle {token.number}: {token.caption}"
table += f"<caption>{caption_text}</caption>\n"
table += "</table>"