Skip to content

Commit

Permalink
chrisjsewell updates
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisjsewell committed Oct 8, 2024
1 parent 4498ddd commit c8e04d0
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 56 deletions.
65 changes: 20 additions & 45 deletions sphinx_needs/directives/needuml.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from __future__ import annotations

import copy
import html
import os
import time
Expand All @@ -19,11 +18,9 @@
from sphinx_needs.directives.needflow._plantuml import make_entity_name
from sphinx_needs.filter_common import filter_needs_view
from sphinx_needs.logging import log_warning
from sphinx_needs.utils import add_doc, logger
from sphinx_needs.directives.needflow import make_entity_name
from sphinx_needs.filter_common import filter_needs
from sphinx_needs.roles.need_ref import transform_need_to_dict
from sphinx_needs.utils import add_doc, split_need_id
from sphinx_needs.roles.need_part import create_need_from_part
from sphinx_needs.roles.need_ref import value_to_string
from sphinx_needs.utils import add_doc, logger, split_need_id

if TYPE_CHECKING:
from sphinxcontrib.plantuml import plantuml
Expand Down Expand Up @@ -403,59 +400,37 @@ def flow(self, need_id: str) -> str:

return need_uml

def ref(self, need_id: str, option: str = "", text: str = "") -> str:
def ref(
self, need_id: str, option: None | str = None, text: None | str = None
) -> str:
need_id_main, need_id_part = split_need_id(need_id)

if need_id_main not in self.needs:
raise NeedumlException(
f"Jinja function ref is called with undefined need_id: '{need_id}'."
f"Jinja function ref is called with undefined need_id: '{need_id_main}'."
)

target_need = self.needs[need_id_main]

if option != "" and text != "":
if (option and text) and (not option and not text):
raise NeedumlException(
"Jinja function ref requires 'option' or 'text', not both"
"Jinja function ref requires exactly one entry 'option' or 'text'"
)

if option != "" and option not in target_need:
raise NeedumlException(
f"Jinja function ref is called with undefined option '{option}' for need '{need_id}'."
)
need_info = self.needs[need_id_main]

if need_id_part:
if need_id_part not in target_need["parts"]:
if need_id_part not in need_info["parts"]:
raise NeedumlException(
f"Jinja function ref is called with undefined need_id part: '{need_id}'."
)
# We are changing the target_need, so we need a deepcopy, to not change the original data.
target_need = copy.deepcopy(target_need)

# This algorithm is following the implementation of needref
target_need["id"] = need_id_part
target_need["title"] = target_need["parts"][need_id_part]["content"]
target_need["is_part"] = True
target_need["is_need"] = False

# needref is using a dict of {str, str} to parse it later with user input.
# Here we do the same.
dict_need = transform_need_to_dict(
target_need
) # Transform a dict in a dict of {str, str}

link = calculate_link(self.app, target_need, self.fromdocname)
link_text: str = dict_need.get(option, "") if option != "" else text
# We have to strip the link_text, as leading and following whitespace character
# will break the plantuml rendering.
link_text = link_text.strip(" \t\n\r")

need_uml = "[[{link}{seperator}{link_text}]]".format(
link=link,
seperator=" " if link_text != "" else "",
link_text=link_text,
)
need_info = create_need_from_part(
need_info, need_info["parts"][need_id_part]
)

return need_uml
link = calculate_link(self.app, need_info, self.fromdocname)
link_text = (
value_to_string(need_info.get(option, "")) if option else str(text or "")
).strip()

return f"[[{link}{' ' if link_text else ''}{link_text}]]"

def filter(self, filter_string: str) -> list[NeedsInfoType]:
"""
Expand Down
23 changes: 14 additions & 9 deletions sphinx_needs/roles/need_ref.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import contextlib
from collections.abc import Iterable
from typing import Any

from docutils import nodes
from sphinx.application import Sphinx
Expand Down Expand Up @@ -38,19 +39,23 @@ def transform_need_to_dict(need: NeedsInfoType) -> dict[str, str]:
dict_need = {}

for element, value in need.items():
if isinstance(value, str):
# As string are iterable, we have to handle strings first.
dict_need[element] = value
elif isinstance(value, dict):
dict_need[element] = ";".join([str(i) for i in value.items()])
elif isinstance(value, (Iterable, list, tuple)):
dict_need[element] = ";".join([str(i) for i in value])
else:
dict_need[element] = str(value)
dict_need[element] = value_to_string(value)

return dict_need


def value_to_string(value: Any) -> str:
if isinstance(value, str):
# As string are iterable, we have to handle strings first.
return value
elif isinstance(value, dict):
return ";".join([str(i) for i in value.items()])
elif isinstance(value, (Iterable, list, tuple)):
return ";".join([str(i) for i in value])

return str(value)


def process_need_ref(
app: Sphinx,
doctree: nodes.document,
Expand Down
2 changes: 1 addition & 1 deletion tests/__snapshots__/test_needuml.ambr
Original file line number Diff line number Diff line change
Expand Up @@ -1253,7 +1253,7 @@
Marvel --> DC: {{ref("ST_002", text="Different text to explain the story")}}

DC -> Marvel: {{ref("ST_001.np_id", option="id")}}
Marvel --> DC: {{ref("ST_001.np_id", option="title")}}
Marvel --> DC: {{ref("ST_001.np_id", option="content")}}

DC -> Marvel: {{ref("ST_001.np_id", text="Different text to explain the story 2")}}
''',
Expand Down
2 changes: 1 addition & 1 deletion tests/doc_test/doc_needuml_jinja_func_ref/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@ TEST DOCUMENT NEEDUML JINJA FUNCTION REF
Marvel --> DC: {{ref("ST_002", text="Different text to explain the story")}}

DC -> Marvel: {{ref("ST_001.np_id", option="id")}}
Marvel --> DC: {{ref("ST_001.np_id", option="title")}}
Marvel --> DC: {{ref("ST_001.np_id", option="content")}}

DC -> Marvel: {{ref("ST_001.np_id", text="Different text to explain the story 2")}}

0 comments on commit c8e04d0

Please sign in to comment.