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…
	
	Add table
		Add a link
		
	
		Reference in a new issue