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