From 321dcd538729c63366d9f320ea250ccb7716d105 Mon Sep 17 00:00:00 2001 From: Chris Sewell Date: Thu, 31 Aug 2023 14:47:10 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20Fix=20adding=20sections=20to=20h?= =?UTF-8?q?idden=20needs=20(#995)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, hidden needs would not be added to the doctree. However, this meant that the `add_sections` transform did not add section related fields to the needs data. This caused errors in the docs builds when filters required these fields. The needs node is now created in the doctree, but marked with a `hidden` attribute, and these nodes are removed before rendering. --- sphinx_needs/api/need.py | 7 ++++--- sphinx_needs/directives/need.py | 16 ++++++++++++++-- sphinx_needs/needs.py | 4 +++- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/sphinx_needs/api/need.py b/sphinx_needs/api/need.py index 989487aaf..cff05e3eb 100644 --- a/sphinx_needs/api/need.py +++ b/sphinx_needs/api/need.py @@ -429,9 +429,6 @@ def run(): if needs_info["is_external"]: return [] - if needs_info["hide"]: - return [target_node] - # Adding of basic Need node. ############################ # Title and meta data information gets added alter during event handling via process_need_nodes() @@ -445,6 +442,10 @@ def run(): # Add lineno to node node_need.line = needs_info["lineno"] + if needs_info["hide"]: + node_need["hidden"] = True + return [target_node, node_need] + node_need_content = _render_template(content, docname, lineno, state) # Extract plantuml diagrams and store needumls with keys in arch, e.g. need_info['arch']['diagram'] diff --git a/sphinx_needs/directives/need.py b/sphinx_needs/directives/need.py index 3b42e5d00..fae4210d5 100644 --- a/sphinx_needs/directives/need.py +++ b/sphinx_needs/directives/need.py @@ -389,6 +389,8 @@ def process_need_nodes(app: Sphinx, doctree: nodes.document, fromdocname: str) - # Used to store needs in the docs, which are needed again later found_needs_nodes = [] for node_need in doctree.findall(Need): + if node_need.get("hidden"): + continue need_id = node_need.attributes["ids"][0] found_needs_nodes.append(node_need) need_data = needs[need_id] @@ -542,6 +544,15 @@ def _fix_list_dyn_func(list: List[str]) -> List[str]: return new_list +def remove_hidden_needs(app: Sphinx, doctree: nodes.document, fromdocname: str) -> None: + """Remove hidden needs from the doctree, before it is rendered.""" + if fromdocname not in SphinxNeedsData(app.env).get_or_create_docs().get("all", []): + return + for node_need in doctree.findall(Need): + if node_need.get("hidden"): + node_need.parent.remove(node_need) # type: ignore + + ##################### # Visitor functions # ##################### @@ -559,12 +570,13 @@ def html_visit(self: Any, node: nodes.Node) -> None: def html_depart(self: Any, node: nodes.Node) -> None: + """Visitor method for departing Need-node of builder 'html' (closes extra div)""" self.body.append("") def latex_visit(self: Any, node: nodes.Node) -> None: - pass + """Visitor method for entering Need-node of builder 'latex' (no-op)""" def latex_depart(self: Any, node: nodes.Node) -> None: - pass + """Visitor method for departing Need-node of builder 'latex' (no-op)""" diff --git a/sphinx_needs/needs.py b/sphinx_needs/needs.py index 03831baee..fbe8340d8 100644 --- a/sphinx_needs/needs.py +++ b/sphinx_needs/needs.py @@ -34,6 +34,7 @@ latex_visit, process_need_nodes, purge_needs, + remove_hidden_needs, ) from sphinx_needs.directives.needbar import Needbar, NeedbarDirective, process_needbar from sphinx_needs.directives.needextend import Needextend, NeedextendDirective @@ -226,9 +227,10 @@ def setup(app: Sphinx) -> Dict[str, Any]: # doctree-read. So manipulating the doctree may result in conflicts, as e.g. images get not # registered for sphinx. So some sphinx-internal tasks/functions may be called by hand again... # See also https://github.com/sphinx-doc/sphinx/issues/7054#issuecomment-578019701 for an example - app.connect("doctree-resolved", process_need_nodes) app.connect("doctree-resolved", process_creator(NODE_TYPES_PRIO, "needextract"), priority=100) + app.connect("doctree-resolved", process_need_nodes) app.connect("doctree-resolved", process_creator(NODE_TYPES)) + app.connect("doctree-resolved", remove_hidden_needs, priority=1000) app.connect("build-finished", process_warnings) app.connect("build-finished", build_needs_json)