From 0344d4505516271248259efe16f984839e143167 Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sat, 24 Oct 2026 19:29:50 +0200 Subject: [PATCH 1/5] Sphinx: reject footnotes without definitions Reject references whose definitions are absent from the rendered document, including bibliographic footnotes removed by conditions. Validation: footnote output probes in HTML, LaTeX and EPUB. Co-Authored-By: Codex --- frontend/sphinx/conf.py | 1 + frontend/sphinx/footnote_checks.py | 51 ++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 frontend/sphinx/footnote_checks.py diff --git a/frontend/sphinx/conf.py b/frontend/sphinx/conf.py index 84693db65..70d5bafc0 100644 --- a/frontend/sphinx/conf.py +++ b/frontend/sphinx/conf.py @@ -104,6 +104,7 @@ def get_file_from_conf_ini(path_to_file): 'sphinx.ext.graphviz', 'sphinx.ext.extlinks', 'widget_extension', + 'footnote_checks', 'sphinx_reredirects', 'sphinxcontrib.plantuml', ] diff --git a/frontend/sphinx/footnote_checks.py b/frontend/sphinx/footnote_checks.py new file mode 100644 index 000000000..a5ecbf692 --- /dev/null +++ b/frontend/sphinx/footnote_checks.py @@ -0,0 +1,51 @@ +"""Reject footnote references whose definitions are absent from the output.""" + +from docutils import nodes +from sphinx.errors import SphinxError +from sphinx.transforms.post_transforms import SphinxPostTransform + + +class CheckFootnoteDefinitions(SphinxPostTransform): + # Check after conditional content is removed, before LaTeX's URL-footnote + # numbering can make a missing definition look like a repeated reference. + default_priority = 390 + + def run(self, **kwargs): + current_docname = self.env.current_document.docname + definitions = { + (footnote.get('docname', current_docname), identifier) + for footnote in self.document.findall(nodes.footnote) + for identifier in footnote['ids'] + } + for reference in self.document.findall(nodes.footnote_reference): + identifier = reference.get('refid') + if identifier is None: + # Docutils reports references that could not resolve an ID. + continue + docname = reference.get('docname', current_docname) + if (docname, identifier) in definitions: + continue + + location = str(self.env.doc2path(docname)) + ancestor = reference + while ancestor is not None: + if ancestor.line is not None: + location += f':{ancestor.line}' + break + ancestor = ancestor.parent + raise SphinxError( + f"{location}: footnote reference {identifier!r} has no " + "definition in this document. Add the missing footnote " + "definition; for :footcite: citations, place " + "'.. footbibliography::' after the last citation in the " + "document." + ) + + +def setup(app): + app.add_post_transform(CheckFootnoteDefinitions) + return { + 'version': '1.0', + 'parallel_read_safe': True, + 'parallel_write_safe': True, + } From f61f4a6724f2d7de1c22968b9b1da3ce03082188 Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sat, 24 Oct 2026 19:29:58 +0200 Subject: [PATCH 2/5] Makefile: include footnote checks in coverage Measure `footnote_checks` alongside the existing parser modules when running `test_parser`. Validation: coverage source list reviewed. Co-Authored-By: Codex --- frontend/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/Makefile b/frontend/Makefile index 4b2b6a8c9..ce1af8324 100644 --- a/frontend/Makefile +++ b/frontend/Makefile @@ -212,7 +212,7 @@ test_engine: webpack-production # @echo "" test_parser: ## Test the parser. - @coverage run --source=widget,rst_code_example_pipeline.chop,rst_code_example_pipeline.resource -m unittest discover --start-directory sphinx + @coverage run --source=widget,footnote_checks,rst_code_example_pipeline.chop,rst_code_example_pipeline.resource -m unittest discover --start-directory sphinx @coverage report --fail-under=90 -m test_rst_pipeline: ## Test the rst_code_example_pipeline package (epub VM). From fa6f75e861ad6733d740a58cb45e49792ad33908 Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sat, 24 Oct 2026 19:30:16 +0200 Subject: [PATCH 3/5] Makefile: prepare complete-book output directories Call the defined preparation helpers before building complete books to create destination directories and clear stale EPUB staging files. Validation: fresh and previously populated output probes. Co-Authored-By: Codex --- frontend/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/Makefile b/frontend/Makefile index ce1af8324..b0df5236b 100644 --- a/frontend/Makefile +++ b/frontend/Makefile @@ -352,7 +352,7 @@ define build_complete_book $(eval TARGET_TYPE_LC := $(call lowercase_word,$(TARGET_TYPE))) @rm -rf "$(BUILDDIR)/doctrees" $(eval SPHINX_CONTENT_DIR := $(CONTENT_DIR)) - $(call build_book_complete_preps_$(TARGET_TYPE_LC)) + $(call build_complete_book_preps_$(TARGET_TYPE_LC)) $(call build_book_generic,$(TARGET_NAME),$(TARGET_TYPE),$(SPHINX_CONTENT_DIR)) endef From 74ce3e34382ec8d2dd1911d060e5b49270196f0a Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sat, 24 Oct 2026 19:30:23 +0200 Subject: [PATCH 4/5] Sphinx: include published booklets in complete books Remove the unpublished-only condition from the booklet toctree so complete PDFs include the booklets and EPUB navigation lists them. Validation: filtered and unfiltered contents builds. Co-Authored-By: Codex --- content/index.rst | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/content/index.rst b/content/index.rst index ecd6ca420..01e8d97d1 100644 --- a/content/index.rst +++ b/content/index.rst @@ -126,15 +126,13 @@ Introduction to Ada: Laboratories Bug Free Coding - .. only:: no_hidden_books - - .. toctree:: - :maxdepth: 1 - :caption: AdaCore Technologies Booklets + .. toctree:: + :maxdepth: 1 + :caption: AdaCore Technologies Booklets - AdaCore Technologies For Airborne Software - AdaCore Technologies For Railway Software - AdaCore Technologies For Space Systems Software + AdaCore Technologies For Airborne Software + AdaCore Technologies For Railway Software + AdaCore Technologies For Space Systems Software .. only:: builder_html From 249c3503c436701231bc0b45894fd950d6e3240e Mon Sep 17 00:00:00 2001 From: gusthoff Date: Sat, 24 Oct 2026 19:30:32 +0200 Subject: [PATCH 5/5] Correction: add the railway foreword's footnote bibliography Provide the footnote definition for the railway foreword's existing bibliographic citation. Validation: citation rendering cases in HTML, LaTeX and EPUB. Co-Authored-By: Codex --- .../adacore-technologies-for-railway-software/index.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/content/booklets/adacore-technologies-for-railway-software/index.rst b/content/booklets/adacore-technologies-for-railway-software/index.rst index cd6ee4dee..f7a541c6e 100644 --- a/content/booklets/adacore-technologies-for-railway-software/index.rst +++ b/content/booklets/adacore-technologies-for-railway-software/index.rst @@ -139,6 +139,8 @@ software, please visit :footcite:`Railway_SW_AdaCore_Web_Rail`. | Ben Brosgol, AdaCore | September 2025 +.. footbibliography:: + .. toctree:: :maxdepth: 4 :numbered: