From e94f2d983c156b633d2d0ad73e74c8d96a768fb5 Mon Sep 17 00:00:00 2001 From: Pierre Fournier Date: Tue, 4 Feb 2025 09:21:45 +0100 Subject: [PATCH 1/6] Update layout.py to add meta_rst() layout function --- sphinx_needs/layout.py | 69 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 59 insertions(+), 10 deletions(-) diff --git a/sphinx_needs/layout.py b/sphinx_needs/layout.py index d3652c2d5..8f0c5eef2 100644 --- a/sphinx_needs/layout.py +++ b/sphinx_needs/layout.py @@ -79,11 +79,12 @@ def build_need_repr( @lru_cache(1) -def _generate_inline_parser() -> tuple[Values, Inliner]: +def _generate_parsers() -> Tuple[Values, Inliner, Parser]: doc_settings = OptionParser(components=(Parser,)).get_default_values() inline_parser = Inliner() inline_parser.init_customizations(doc_settings) # type: ignore - return doc_settings, inline_parser + multiline_parser = Parser() + return doc_settings, inline_parser, multiline_parser class LayoutHandler: @@ -262,7 +263,7 @@ def __init__( } # Dummy Document setup - self.doc_settings, self.inline_parser = _generate_inline_parser() + self.doc_settings, self.inline_parser, self.multiline_parser = _generate_parsers() self.dummy_doc = new_document("dummy", self.doc_settings) self.doc_language = languages.get_language( self.dummy_doc.settings.language_code @@ -285,6 +286,7 @@ def __init__( "meta_links": self.meta_links, "meta_links_all": self.meta_links_all, # type: ignore[dict-item] "meta_id": self.meta_id, + "meta_rst": self.meta_rst, "image": self.image, # type: ignore[dict-item] "link": self.link, "collapse_button": self.collapse_button, @@ -339,14 +341,14 @@ def get_section(self, section: str) -> nodes.line_block | list[nodes.Element]: # line_block_node = nodes.line_block() line_node = nodes.line() - line_parsed = self._parse(line) + line_parsed = self._parse_inline(line) line_ready = self._func_replace(line_parsed) line_node += line_ready lines_container.append(line_node) return lines_container - def _parse(self, line: str) -> list[nodes.Node]: + def _parse_inline(self, line: str) -> list[nodes.Node]: """ Parses a single line/string for inline rst statements, like strong, emphasis, literal, ... @@ -485,7 +487,7 @@ def meta( """ data_container = nodes.inline(classes=["needs_" + name]) if prefix: - prefix_node = self._parse(prefix) + prefix_node = self._parse_inline(prefix) label_node = nodes.inline(classes=["needs_label"]) label_node += prefix_node data_container.append(label_node) @@ -707,7 +709,7 @@ def meta_links_all( outgoing_label = ( prefix + "{}:".format(link_type["outgoing"]) + postfix + " " ) - outgoing_line += self._parse(outgoing_label) + outgoing_line += self._parse_inline(outgoing_label) outgoing_line += self.meta_links(link_type["option"], incoming=False) data_container.append(outgoing_line) @@ -717,12 +719,59 @@ def meta_links_all( incoming_label = ( prefix + "{}:".format(link_type["incoming"]) + postfix + " " ) - incoming_line += self._parse(incoming_label) + incoming_line += self._parse_inline(incoming_label) incoming_line += self.meta_links(link_type["option"], incoming=True) data_container.append(incoming_line) return data_container +def meta_rst(self, name: str, prefix: Optional[str] = None, show_empty: bool = False) -> nodes.paragraph: + """ + Returns the specific metadata of a need inside docutils nodes. + Usage:: + + <> + + .. note:: + + You must escape all rst_content in your function strings! E.g. to get `**` one must use `\\\\*\\\\*`. + + :param name: name of the need item + :param prefix: string as rst-code, will be added infront of the value output + :param show_empty: If false and requested need-value is None or '', no output is returned. Default: false + :return: docutils node + """ + data_container = nodes.paragraph(classes=["needs_" + name]) + if prefix: + prefix_node = self._parse_inline(prefix) + label_node = nodes.inline(classes=["needs_label"]) + label_node += prefix_node + data_container.append(label_node) + try: + data = self.need[name] # type: ignore[literal-required] + except KeyError: + data = "" + + if data is None and not show_empty: + return [] + elif data is None and show_empty: + data = "" + + if isinstance(data, str): + if len(data) == 0 and not show_empty: + return [] + + dummy_doc = self.dummy_doc.deepcopy() + self.multiline_parser.parse(data,dummy_doc) + data_node = dummy_doc.children + + data_container += data_node + + else: + data_container.append(nodes.Text(data)) + + return data_container + def image( self, url: str, @@ -776,7 +825,7 @@ def image( data_container = nodes.inline() if prefix: - prefix_node = self._parse(prefix) + prefix_node = self._parse_inline(prefix) label_node = nodes.inline(classes=["needs_label"]) label_node += prefix_node data_container.append(label_node) @@ -901,7 +950,7 @@ def link( """ data_container = nodes.inline() if prefix: - prefix_node = self._parse(prefix) + prefix_node = self._parse_inline(prefix) label_node = nodes.inline(classes=["needs_label"]) label_node += prefix_node data_container.append(label_node) From 7ae64affbef9589de5dd4ff3c93525a843247867 Mon Sep 17 00:00:00 2001 From: Pierre Fournier Date: Tue, 4 Feb 2025 09:37:27 +0100 Subject: [PATCH 2/6] Add meta_rst() mention in layout_styles.rst --- docs/layout_styles.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/layout_styles.rst b/docs/layout_styles.rst index d4d3d9bce..759f84fb5 100644 --- a/docs/layout_styles.rst +++ b/docs/layout_styles.rst @@ -357,6 +357,7 @@ Available layout functions are: * :func:`meta_links ` * :func:`meta_links_all ` * :func:`meta_id ` +* :func:`meta_rst ` * :func:`image ` * :func:`link ` * :func:`permalink ` @@ -372,6 +373,8 @@ Available layout functions are: .. autofunction:: sphinx_needs.layout.LayoutHandler.meta_links_all(prefix='', postfix='', exclude=None) +.. autofunction:: sphinx_needs.layout.LayoutHandler.meta_rst(prefix='', postfix='', exclude=None) + .. autofunction:: sphinx_needs.layout.LayoutHandler.image(url, height=None, width=None, align=None, no_link=False, prefix="", is_external=False, img_class="") .. autofunction:: sphinx_needs.layout.LayoutHandler.link(url, text=None, image_url=None, image_height=None, image_width=None, prefix="", is_dynamic=False) From 129e84eaadc40335a38b958873174fa8c5a85435 Mon Sep 17 00:00:00 2001 From: Pierre Fournier Date: Tue, 4 Feb 2025 09:39:56 +0100 Subject: [PATCH 3/6] Fix meta_rst indent --- sphinx_needs/layout.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sphinx_needs/layout.py b/sphinx_needs/layout.py index 8f0c5eef2..aaf8e9a2f 100644 --- a/sphinx_needs/layout.py +++ b/sphinx_needs/layout.py @@ -725,7 +725,7 @@ def meta_links_all( return data_container -def meta_rst(self, name: str, prefix: Optional[str] = None, show_empty: bool = False) -> nodes.paragraph: + def meta_rst(self, name: str, prefix: Optional[str] = None, show_empty: bool = False) -> nodes.paragraph: """ Returns the specific metadata of a need inside docutils nodes. Usage:: From e993ab756002b29e474e3d1ff55fd603fc8b7a8e Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 4 Feb 2025 08:40:12 +0000 Subject: [PATCH 4/6] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- sphinx_needs/layout.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/sphinx_needs/layout.py b/sphinx_needs/layout.py index aaf8e9a2f..3080c9128 100644 --- a/sphinx_needs/layout.py +++ b/sphinx_needs/layout.py @@ -263,7 +263,9 @@ def __init__( } # Dummy Document setup - self.doc_settings, self.inline_parser, self.multiline_parser = _generate_parsers() + self.doc_settings, self.inline_parser, self.multiline_parser = ( + _generate_parsers() + ) self.dummy_doc = new_document("dummy", self.doc_settings) self.doc_language = languages.get_language( self.dummy_doc.settings.language_code @@ -725,7 +727,9 @@ def meta_links_all( return data_container - def meta_rst(self, name: str, prefix: Optional[str] = None, show_empty: bool = False) -> nodes.paragraph: + def meta_rst( + self, name: str, prefix: Optional[str] = None, show_empty: bool = False + ) -> nodes.paragraph: """ Returns the specific metadata of a need inside docutils nodes. Usage:: @@ -762,7 +766,7 @@ def meta_rst(self, name: str, prefix: Optional[str] = None, show_empty: bool = F return [] dummy_doc = self.dummy_doc.deepcopy() - self.multiline_parser.parse(data,dummy_doc) + self.multiline_parser.parse(data, dummy_doc) data_node = dummy_doc.children data_container += data_node @@ -771,7 +775,7 @@ def meta_rst(self, name: str, prefix: Optional[str] = None, show_empty: bool = F data_container.append(nodes.Text(data)) return data_container - + def image( self, url: str, From 07d5b8e24db16f6a33772c1d671f3ad63ca02d19 Mon Sep 17 00:00:00 2001 From: Pierre Fournier Date: Tue, 4 Feb 2025 09:41:26 +0100 Subject: [PATCH 5/6] Update description of meta_rst --- sphinx_needs/layout.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sphinx_needs/layout.py b/sphinx_needs/layout.py index 3080c9128..8dc97fe89 100644 --- a/sphinx_needs/layout.py +++ b/sphinx_needs/layout.py @@ -731,7 +731,7 @@ def meta_rst( self, name: str, prefix: Optional[str] = None, show_empty: bool = False ) -> nodes.paragraph: """ - Returns the specific metadata of a need inside docutils nodes. + Returns the specific metadata of a need inside docutils nodes, parsed as multiline rst. Usage:: <> From 16af020cc19aeae7a89aa948299fed2331affeb5 Mon Sep 17 00:00:00 2001 From: Pierre Fournier Date: Tue, 4 Feb 2025 09:46:37 +0100 Subject: [PATCH 6/6] Fix type-hints --- sphinx_needs/layout.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sphinx_needs/layout.py b/sphinx_needs/layout.py index 8dc97fe89..efdab4aeb 100644 --- a/sphinx_needs/layout.py +++ b/sphinx_needs/layout.py @@ -79,7 +79,7 @@ def build_need_repr( @lru_cache(1) -def _generate_parsers() -> Tuple[Values, Inliner, Parser]: +def _generate_parsers() -> tuple[Values, Inliner, Parser]: doc_settings = OptionParser(components=(Parser,)).get_default_values() inline_parser = Inliner() inline_parser.init_customizations(doc_settings) # type: ignore @@ -288,7 +288,7 @@ def __init__( "meta_links": self.meta_links, "meta_links_all": self.meta_links_all, # type: ignore[dict-item] "meta_id": self.meta_id, - "meta_rst": self.meta_rst, + "meta_rst": self.meta_rst, # type: ignore[dict-item] "image": self.image, # type: ignore[dict-item] "link": self.link, "collapse_button": self.collapse_button, @@ -728,8 +728,8 @@ def meta_links_all( return data_container def meta_rst( - self, name: str, prefix: Optional[str] = None, show_empty: bool = False - ) -> nodes.paragraph: + self, name: str, prefix: str | None = None, show_empty: bool = False + ) -> nodes.paragraph | list[nodes.Element]: """ Returns the specific metadata of a need inside docutils nodes, parsed as multiline rst. Usage::