"""Glossary chapter (GLOSARIO) — always the last chapter, clickable terms. Renders one entry per glossary term that the other chapters registered during the document build through ``ctx['glossary'].add(key, label, definition)`` (see ``GlossaryCollector`` in ``model.py``). Each entry is a clickable destination: every in-text appearance a chapter marked with ``[[term:key]]texto[[/term]]`` becomes a real jump to its entry here — PDF link annotations (PyMuPDF) and PPTX native slide jumps, both wired by the renderers. Returns ``None`` when no term was registered (there is nothing to show), so the chapter simply disappears from documents that did not mark any term. Contract: build_(profile, ctx) -> Chapter | None ; CHAPTER_VERSION = "x.y.z". """ from __future__ import annotations from .. import model CHAPTER_VERSION = "1.0.0" CHAPTER_ID = "glosario" CHAPTER_TITLE = "Glosario" def build_glosario(profile: dict, ctx: dict): """Build the glossary Chapter from the shared collector, or None if empty.""" ctx = ctx or {} glossary = ctx.get("glossary") if not isinstance(glossary, model.GlossaryCollector) or not glossary: return None blocks = [ model.Heading(text="Glosario de términos", level=1), model.Markdown(text=( "Definición de los términos técnicos que aparecen en el informe. " "Cada término va resaltado en el texto y, al pulsarlo, salta a su " "definición en esta sección.")), ] # One clickable destination per term, alphabetically by visible label. for term in glossary.terms(by="label"): blocks.append(model.GlossaryEntry( key=model._safe_str(term.get("key")), label=model._safe_str(term.get("label")), definition=model._safe_str(term.get("definition")))) return model.Chapter(id=CHAPTER_ID, title=CHAPTER_TITLE, version=CHAPTER_VERSION, blocks=blocks)