Fix anchor links
This commit is contained in:
parent
1451a5a1c0
commit
d1a151f8bd
2 changed files with 40 additions and 30 deletions
|
@ -62,12 +62,13 @@ class IPV4RangeDirective(IPRangeDirective):
|
|||
title_prefix = _("IPv4 range")
|
||||
|
||||
def add_target_and_index(self, name: T, sig: str, signode: desc_signature) -> None:
|
||||
signode["ids"].append("ip4_range" + "-" + sig)
|
||||
anchor = "ip-ipv4range-{0}".format(sig)
|
||||
signode["ids"].append(anchor)
|
||||
ips = self.env.get_domain("ip")
|
||||
ips.add_ip4_range(sig)
|
||||
idx_text = "{}; {}".format(self.title_prefix, name)
|
||||
self.indexnode["entries"] = [
|
||||
("single", idx_text, name, "", None),
|
||||
("single", idx_text, anchor, "", None),
|
||||
]
|
||||
|
||||
|
||||
|
@ -75,12 +76,13 @@ class IPV6RangeDirective(IPRangeDirective):
|
|||
title_prefix = _("IPv6 range")
|
||||
|
||||
def add_target_and_index(self, name: T, sig: str, signode: desc_signature) -> None:
|
||||
signode["ids"].append("ip6_range" + "-" + sig)
|
||||
anchor = "ip-ipv6range-{0}".format(sig)
|
||||
signode["ids"].append(anchor)
|
||||
ips = self.env.get_domain("ip")
|
||||
ips.add_ip6_range(sig)
|
||||
idx_text = "{}; {}".format(self.title_prefix, name)
|
||||
self.indexnode["entries"] = [
|
||||
("single", idx_text, name, "", None),
|
||||
("single", idx_text, anchor, "", None),
|
||||
]
|
||||
|
||||
|
||||
|
@ -121,7 +123,7 @@ class IPXRefRole(XRefRole):
|
|||
node_list, message = super().result_nodes(document, env, node, is_ref)
|
||||
|
||||
ip = env.get_domain("ip")
|
||||
if self.reftype in ["v4", "v6"] and self.target not in ip.data["ips"]:
|
||||
if self.reftype in ["v4", "v6"] and self.target not in ip.data["ip_dict"]:
|
||||
return node_list, message
|
||||
if (
|
||||
self.reftype in ["v4range", "v6range"]
|
||||
|
@ -130,7 +132,11 @@ class IPXRefRole(XRefRole):
|
|||
return node_list, message
|
||||
|
||||
index_node = addnodes.index()
|
||||
target_id = "index-{}".format(env.new_serialno("index"))
|
||||
target_id = "ip-{}-{}".format(self.reftype, env.new_serialno("index"))
|
||||
|
||||
if self.reftype in ["v4", "v6"]:
|
||||
ip.add_ip_address_anchor(self.target, env.docname, target_id)
|
||||
|
||||
target_node = nodes.target("", "", ids=[target_id])
|
||||
doc_title = next(d for d in document.traverse(nodes.title)).astext()
|
||||
|
||||
|
@ -175,10 +181,9 @@ class IPDomain(Domain):
|
|||
|
||||
initial_data = {
|
||||
"range_nodes": [],
|
||||
"ip_refs": [],
|
||||
"ip_refs": defaultdict(list),
|
||||
"range_refs": [],
|
||||
"ranges": defaultdict(list),
|
||||
"ips": defaultdict(list),
|
||||
"ip_dict": {},
|
||||
}
|
||||
|
||||
|
@ -218,23 +223,15 @@ class IPDomain(Domain):
|
|||
self._add_ip_address_reference("v6", ip_address)
|
||||
|
||||
def _add_ip_address_reference(self, family, sig):
|
||||
name = "ip{}.{}".format(family, sig)
|
||||
anchor = "ip-ip{}-{}".format(family, sig)
|
||||
try:
|
||||
self.data["ip_dict"][sig] = IP(sig)
|
||||
except ValueError as e:
|
||||
logger.error("invalid ip address '%s': %s", sig, e)
|
||||
|
||||
def add_ip_address_anchor(self, sig, docname, anchor):
|
||||
try:
|
||||
ip = IP(sig)
|
||||
self.data["ip_refs"].append(
|
||||
(
|
||||
name,
|
||||
sig,
|
||||
"IP{}".format(family),
|
||||
str(ip),
|
||||
self.env.docname,
|
||||
anchor,
|
||||
0,
|
||||
)
|
||||
)
|
||||
self.data["ips"][sig].append((ip, self.env.docname, anchor))
|
||||
self.data["ip_dict"][sig] = ip
|
||||
self.data["ip_refs"][sig].append((ip, docname, anchor))
|
||||
except ValueError as e:
|
||||
logger.error("invalid ip address '%s': %s", sig, e)
|
||||
|
||||
|
@ -276,13 +273,25 @@ class IPDomain(Domain):
|
|||
contnode: nodes.Element,
|
||||
) -> Optional[nodes.Element]:
|
||||
match = []
|
||||
|
||||
def address_tuple(docname, anchor, ip_range) -> Tuple[str, str, str]:
|
||||
return (
|
||||
docname,
|
||||
anchor,
|
||||
_(
|
||||
"IPv{0} range {1}".format(
|
||||
ip_range.version(), ip_range.to_compressed()
|
||||
)
|
||||
),
|
||||
)
|
||||
|
||||
if typ in ("v4", "v6"):
|
||||
# reference to IP range
|
||||
if target not in self.data["ip_dict"]:
|
||||
# invalid ip address
|
||||
raise NoUri(target)
|
||||
match = [
|
||||
(docname, anchor)
|
||||
address_tuple(docname, anchor, ip_range)
|
||||
for ip_range, docname, anchor in [
|
||||
r
|
||||
for range_nodes in self.data["ranges"].values()
|
||||
|
@ -293,7 +302,7 @@ class IPDomain(Domain):
|
|||
elif typ in ("v4range", "v6range"):
|
||||
if target in self.data["ranges"]:
|
||||
match = [
|
||||
(docname, anchor)
|
||||
address_tuple(docname, anchor, ip_range)
|
||||
for ip_range, docname, anchor in [
|
||||
range_nodes for range_nodes in self.data["ranges"][target]
|
||||
]
|
||||
|
@ -301,8 +310,9 @@ class IPDomain(Domain):
|
|||
if len(match) > 0:
|
||||
todocname = match[0][0]
|
||||
targ = match[0][1]
|
||||
title = match[0][2]
|
||||
|
||||
return make_refnode(builder, fromdocname, todocname, targ, contnode, targ)
|
||||
return make_refnode(builder, fromdocname, todocname, targ, contnode, title)
|
||||
else:
|
||||
logger.error("found no link target for %s", target)
|
||||
return None
|
||||
|
@ -319,7 +329,7 @@ def process_ip_nodes(app, doctree, fromdocname):
|
|||
content = []
|
||||
net = Network(node["range_spec"])
|
||||
addresses = defaultdict(list)
|
||||
for ip_address_sig, refs in ips.data["ips"].items():
|
||||
for ip_address_sig, refs in ips.data["ip_refs"].items():
|
||||
for ip_address, todocname, anchor in refs:
|
||||
if ip_address in net:
|
||||
addresses[ip_address_sig].append((ip_address, todocname, anchor))
|
||||
|
|
|
@ -32,7 +32,7 @@ class TestIPExtension(unittest.TestCase):
|
|||
self.assertIn("range_refs", ipdomdata)
|
||||
self.assertIn("range_nodes", ipdomdata)
|
||||
self.assertIn("ranges", ipdomdata)
|
||||
self.assertIn("ips", ipdomdata)
|
||||
self.assertIn("ip_dict", ipdomdata)
|
||||
|
||||
def find_in_index(self, entry):
|
||||
indexentries = self.app.env.get_domain("index").entries
|
||||
|
@ -43,14 +43,14 @@ class TestIPExtension(unittest.TestCase):
|
|||
self.fail("%s not found in index" % entry)
|
||||
|
||||
def test_ip4_addresses(self):
|
||||
ips = self.app.env.domaindata["ip"]["ips"]
|
||||
ips = self.app.env.domaindata["ip"]["ip_refs"]
|
||||
for ip in IP4_ADDRESSES:
|
||||
self.assertIn(ip, ips)
|
||||
self.find_in_index("IPv4 address; %s" % ip)
|
||||
self.find_in_index("%s; Test page 2" % ip)
|
||||
|
||||
def test_ip6_addresses(self):
|
||||
ips = self.app.env.domaindata["ip"]["ips"]
|
||||
ips = self.app.env.domaindata["ip"]["ip_refs"]
|
||||
for ip in IP6_ADDRESSES:
|
||||
self.assertIn(ip, ips)
|
||||
self.find_in_index("IPv6 address; %s" % ip)
|
||||
|
|
Loading…
Reference in a new issue