/
need_incoming.py
89 lines (70 loc) · 3.54 KB
/
need_incoming.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
from typing import List
from docutils import nodes
from sphinx.application import Sphinx
from sphinx.util.nodes import make_refnode
from sphinx_needs.config import NeedsSphinxConfig
from sphinx_needs.data import SphinxNeedsData
from sphinx_needs.errors import NoUri
from sphinx_needs.utils import check_and_calc_base_url_rel_path, unwrap
class NeedIncoming(nodes.Inline, nodes.Element):
pass
def process_need_incoming(
app: Sphinx, doctree: nodes.document, fromdocname: str, found_nodes: List[nodes.Element]
) -> None:
builder = unwrap(app.builder)
env = unwrap(builder.env)
needs_config = NeedsSphinxConfig(env.config)
all_needs = SphinxNeedsData(env).get_or_create_needs()
# for node_need_backref in doctree.findall(NeedIncoming):
for node_need_backref in found_nodes:
node_link_container = nodes.inline()
ref_need = all_needs[node_need_backref["reftarget"]]
# Let's check if NeedIncoming shall follow a specific link type
if "link_type" in node_need_backref.attributes:
links_back = ref_need[node_need_backref.attributes["link_type"]]
# if not, follow back to default links
else:
links_back = ref_need["links_back"]
for index, back_link in enumerate(links_back):
# If need back_link target exists, let's create the reference
if back_link in all_needs:
try:
target_need = all_needs[back_link]
if needs_config.show_link_title:
link_text = f'{target_need["title"]}'
if needs_config.show_link_id:
link_text += f' ({target_need["id"]})'
else:
link_text = target_need["id"]
if needs_config.show_link_type:
link_text += " [{type}]".format(type=target_need["type_name"])
# if index + 1 < len(ref_need["links_back"]):
# link_text += ", "
node_need_backref[0] = nodes.Text(link_text)
if not target_need["is_external"]:
new_node_ref = make_refnode(
builder,
fromdocname,
target_need["docname"],
target_need["target_id"],
node_need_backref[0].deepcopy(),
node_need_backref["reftarget"],
)
else:
new_node_ref = nodes.reference(target_need["id"], target_need["id"])
new_node_ref["refuri"] = check_and_calc_base_url_rel_path(
target_need["external_url"], fromdocname
)
new_node_ref["classes"].append(target_need["external_css"])
node_link_container += new_node_ref
# If we have several links, we add an empty text between them
if index + 1 < len(links_back):
node_link_container += nodes.Text(", ")
except NoUri:
# If the given need id can not be found, we must pass here....
pass
else:
env.warn_node("need %s not found [needs]" % node_need_backref["reftarget"], node_need_backref)
if len(node_link_container.children) == 0:
node_link_container += nodes.Text("None")
node_need_backref.replace_self(node_link_container)