diff --git a/renderer/fifty_ohm_html_renderer.py b/renderer/fifty_ohm_html_renderer.py index 2e316bd..8817d14 100644 --- a/renderer/fifty_ohm_html_renderer.py +++ b/renderer/fifty_ohm_html_renderer.py @@ -1,3 +1,5 @@ +import re + from jinja2 import Environment, FileSystemLoader from mistletoe import Document, HtmlRenderer @@ -90,6 +92,9 @@ class FiftyOhmHtmlRenderer(HtmlRenderer): # Single unified counter for all figure types (pictures, photos, tables) self.figure_counter = 0 + # Keep track of index ids already emitted in this document. + self.index_anchor_ids = set() + def render_dash(self, token): return " – " @@ -335,6 +340,24 @@ class FiftyOhmHtmlRenderer(HtmlRenderer): def render_formula(self, token): return f"\n$${token.formula}$$\n" + @staticmethod + def _normalize_index_part(value: str) -> str: + normalized = value.strip().lower() + normalized = re.sub(r"\s+", "_", normalized) + normalized = re.sub(r"[^\w]", "_", normalized) + normalized = re.sub(r"_+", "_", normalized).strip("_") + return normalized or "index" + def render_index(self, token): - # For HTML just ignore the index - return "" + first = self._normalize_index_part(token.first) + if token.second: + second = self._normalize_index_part(token.second) + span_id = f"index_{first}__{second}" + else: + span_id = f"index_{first}" + + if span_id in self.index_anchor_ids: + return "" + + self.index_anchor_ids.add(span_id) + return f'' diff --git a/test/test_index.py b/test/test_index.py index 2c2e74b..ec538fd 100644 --- a/test/test_index.py +++ b/test/test_index.py @@ -9,11 +9,36 @@ from test.util import paragraph @pytest.mark.html def test_index_html(): assertions = { - "Im Betrieb werden Yagi-Antennen [index:Antenne:Yagi-Antenne] oft gedreht": "Im Betrieb werden Yagi-Antennen oft gedreht", # noqa: E501 - "Im Betrieb werden Yagi-Antennen[index:Antenne:Yagi-Antenne] oft gedreht": "Im Betrieb werden Yagi-Antennen oft gedreht", # noqa: E501 - "Im Betrieb werden Yagi-Antennen [index:Antenne] oft gedreht": "Im Betrieb werden Yagi-Antennen oft gedreht", - "Im Betrieb werden Yagi-Antennen[index:Antenne] oft gedreht": "Im Betrieb werden Yagi-Antennen oft gedreht", - "Im Betrieb werden Yagi-Antennen[index:Test Antenne] oft gedreht": "Im Betrieb werden Yagi-Antennen oft gedreht", # noqa: E501 + "Im Betrieb werden Yagi-Antennen [index:Antenne:Yagi-Antenne] oft gedreht": ( + "Im Betrieb werden Yagi-Antennen" + + '' + + " oft gedreht" + ), + "Im Betrieb werden Yagi-Antennen[index:Antenne:Yagi-Antenne] oft gedreht": ( + "Im Betrieb werden Yagi-Antennen" + + '' + + " oft gedreht" + ), + "Im Betrieb werden Yagi-Antennen [index:Antenne] oft gedreht": ( + "Im Betrieb werden Yagi-Antennen" + + '' + + " oft gedreht" + ), + "Im Betrieb werden Yagi-Antennen[index:Antenne] oft gedreht": ( + "Im Betrieb werden Yagi-Antennen" + + '' + + " oft gedreht" + ), + "Im Betrieb werden Yagi-Antennen[index:Test Antenne] oft gedreht": ( + "Im Betrieb werden Yagi-Antennen" + + '' + + " oft gedreht" + ), + "Im Betrieb [index:Antenne] und nochmals [index:Antenne] oft gedreht": ( + "Im Betrieb" + + '' + + " und nochmals oft gedreht" + ), } for key, value in assertions.items():