Merge branch 'release/0.2.0'
* release/0.2.0: Improve release metadata Add handling for multiple IP occurrences Format IP lists as tables Fix IP address sorting Bump version number Fix grammar mistake Don't add GPL to long_description
This commit is contained in:
		
						commit
						88ffa4fbeb
					
				
					 5 changed files with 108 additions and 31 deletions
				
			
		
							
								
								
									
										25
									
								
								README.rst
									
										
									
									
									
								
							
							
						
						
									
										25
									
								
								README.rst
									
										
									
									
									
								
							|  | @ -1,3 +1,4 @@ | ||||||
|  | ================== | ||||||
| jandd.sphinxext.ip | jandd.sphinxext.ip | ||||||
| ================== | ================== | ||||||
| 
 | 
 | ||||||
|  | @ -5,10 +6,30 @@ This is an IP address extension for `Sphinx`_. The extension provides a domain | ||||||
| *ip* that allows marking IPv4 and IPv6 addresses in documentation and contains | *ip* that allows marking IPv4 and IPv6 addresses in documentation and contains | ||||||
| directives to collect information regarding IP addresses in IP ranges. | directives to collect information regarding IP addresses in IP ranges. | ||||||
| 
 | 
 | ||||||
|  | .. _Sphinx: http://www.sphinx-doc.org/ | ||||||
|  | 
 | ||||||
|  | Development | ||||||
|  | =========== | ||||||
|  | 
 | ||||||
|  | The extension is developed in a git repository that can be cloned by running:: | ||||||
|  | 
 | ||||||
|  |     git clone https://git.dittberner.info/sphinxext-ip.git | ||||||
|  | 
 | ||||||
|  | A repository browser is available at | ||||||
|  | https://git.dittberner.info/?p=sphinxext-ip.git. | ||||||
|  | 
 | ||||||
| Contributors | Contributors | ||||||
| ------------ | ============ | ||||||
| 
 | 
 | ||||||
| * `Jan Dittberner`_ | * `Jan Dittberner`_ | ||||||
| 
 | 
 | ||||||
| .. _Jan Dittberner: https://jan.dittberner.info/ | .. _Jan Dittberner: https://jan.dittberner.info/ | ||||||
| .. _Sphinx: http://www.sphinx-doc.org/ | 
 | ||||||
|  | Changes | ||||||
|  | ======= | ||||||
|  | 
 | ||||||
|  | 0.2.0 - 2016-05-04 | ||||||
|  | ------------------ | ||||||
|  | 
 | ||||||
|  | * display IP address lists as tables | ||||||
|  | * sort IP address lists numericaly | ||||||
|  |  | ||||||
|  | @ -8,7 +8,6 @@ | ||||||
|     :copyright: Copyright (c) 2016 Jan Dittberner |     :copyright: Copyright (c) 2016 Jan Dittberner | ||||||
|     :license: GPLv3+, see COPYING file for details. |     :license: GPLv3+, see COPYING file for details. | ||||||
| """ | """ | ||||||
| __version__ = '0.1.1' |  | ||||||
| 
 | 
 | ||||||
| import re | import re | ||||||
| 
 | 
 | ||||||
|  | @ -24,15 +23,20 @@ from sphinx.locale import l_ | ||||||
| from sphinx.roles import XRefRole | from sphinx.roles import XRefRole | ||||||
| from sphinx.util.nodes import make_refnode | from sphinx.util.nodes import make_refnode | ||||||
| 
 | 
 | ||||||
|  | __version__ = '0.2.0' | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| def ip_object_anchor(typ, path): | def ip_object_anchor(typ, path): | ||||||
|     path = re.sub(r'[.:/]', '-', path) |     path = re.sub(r'[.:/]', '-', path) | ||||||
|     return typ.lower() + '-' + path |     return typ.lower() + '-' + path | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class ip_node(nodes.Inline, nodes.TextElement): pass | class ip_node(nodes.Inline, nodes.TextElement): | ||||||
|  |     pass | ||||||
| 
 | 
 | ||||||
| class ip_range(nodes.General, nodes.Element): pass | 
 | ||||||
|  | class ip_range(nodes.General, nodes.Element): | ||||||
|  |     pass | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class IPXRefRole(XRefRole): | class IPXRefRole(XRefRole): | ||||||
|  | @ -42,7 +46,7 @@ class IPXRefRole(XRefRole): | ||||||
|     def __init__(self, method, index_type, **kwargs): |     def __init__(self, method, index_type, **kwargs): | ||||||
|         self.method = method |         self.method = method | ||||||
|         self.index_type = index_type |         self.index_type = index_type | ||||||
|         innernodeclass=None |         innernodeclass = None | ||||||
|         if method in ('v4', 'v6'): |         if method in ('v4', 'v6'): | ||||||
|             innernodeclass = ip_node |             innernodeclass = ip_node | ||||||
|         super(IPXRefRole, self).__init__( |         super(IPXRefRole, self).__init__( | ||||||
|  | @ -230,36 +234,85 @@ def process_ips(app, doctree): | ||||||
|         node.replace_self(replacement) |         node.replace_self(replacement) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def sort_ip_info(item): | def sort_ip(item): | ||||||
|     return item['ip'] |     return Network(item).ip | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def create_table_row(rowdata): | ||||||
|  |     row = nodes.row() | ||||||
|  |     for cell in rowdata: | ||||||
|  |         entry = nodes.entry() | ||||||
|  |         row += entry | ||||||
|  |         entry += cell | ||||||
|  |     return row | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def process_ip_nodes(app, doctree, fromdocname): | def process_ip_nodes(app, doctree, fromdocname): | ||||||
|     env = app.builder.env |     env = app.builder.env | ||||||
|     domaindata = env.domaindata[IPDomain.name] |     domaindata = env.domaindata[IPDomain.name] | ||||||
| 
 | 
 | ||||||
|  |     header = (l_('IP address'), l_('Used by')) | ||||||
|  |     colwidths = (1, 3) | ||||||
|  | 
 | ||||||
|     for node in doctree.traverse(ip_range): |     for node in doctree.traverse(ip_range): | ||||||
|         content = [] |         content = [] | ||||||
|         net = Network(node['rangespec']) |         net = Network(node['rangespec']) | ||||||
|         for ip_info in sorted(domaindata['ips'], key=sort_ip_info): |         ips = {} | ||||||
|             if ip_info['ip'] in net: |         for key, value in [ | ||||||
|  |             (ip_info['ip'], ip_info) for ip_info in | ||||||
|  |             domaindata['ips'] if ip_info['ip'] in net | ||||||
|  |         ]: | ||||||
|  |             addrlist = ips.get(key, []) | ||||||
|  |             addrlist.append(value) | ||||||
|  |             ips[key] = addrlist | ||||||
|  |         if ips: | ||||||
|  |             table = nodes.table() | ||||||
|  |             tgroup = nodes.tgroup(cols=len(header)) | ||||||
|  |             table += tgroup | ||||||
|  |             for colwidth in colwidths: | ||||||
|  |                 tgroup += nodes.colspec(colwidth=colwidth) | ||||||
|  |             thead = nodes.thead() | ||||||
|  |             tgroup += thead | ||||||
|  |             thead += create_table_row([ | ||||||
|  |                 nodes.paragraph(text=label) for label in header]) | ||||||
|  |             tbody = nodes.tbody() | ||||||
|  |             tgroup += tbody | ||||||
|  |             for ip, ip_info in [ | ||||||
|  |                 (ip, ips[ip]) for ip in sorted(ips, key=sort_ip) | ||||||
|  |             ]: | ||||||
|                 para = nodes.paragraph() |                 para = nodes.paragraph() | ||||||
|                 para += nodes.literal('', ip_info['ip']) |                 para += nodes.literal('', ip) | ||||||
|                 ids = ip_object_anchor(ip_info['typ'], ip_info['ip']) |                 refnode = nodes.paragraph() | ||||||
|                 para['ids'].append(ids) |                 refuris = set() | ||||||
|                 domaindata[ip_info['typ']][ids] = (fromdocname, '') |                 refnodes = [] | ||||||
|                 newnode = nodes.reference('', '', internal=True) |                 for item in ip_info: | ||||||
|                 try: |                     ids = ip_object_anchor(item['typ'], item['ip']) | ||||||
|                     newnode['refuri'] = app.builder.get_relative_uri( |                     if ids not in para['ids']: | ||||||
|                         fromdocname, ip_info['docname']) |                         para['ids'].append(ids) | ||||||
|                 except NoUri: | 
 | ||||||
|                     pass |                     domaindata[item['typ']][ids] = (fromdocname, '') | ||||||
|                 title = env.titles[ip_info['docname']] |                     newnode = nodes.reference('', '', internal=True) | ||||||
|                 innernode = nodes.Text(title.astext()) |                     try: | ||||||
|                 newnode.append(innernode) |                         newnode['refuri'] = app.builder.get_relative_uri( | ||||||
|                 para += nodes.Text(" in ") |                             fromdocname, item['docname']) | ||||||
|                 para += newnode |                         if newnode['refuri'] in refuris: | ||||||
|                 content.append(para) |                             continue | ||||||
|  |                         refuris.add(newnode['refuri']) | ||||||
|  |                     except NoUri: | ||||||
|  |                         pass | ||||||
|  |                     title = env.titles[item['docname']] | ||||||
|  |                     innernode = nodes.Text(title.astext()) | ||||||
|  |                     newnode.append(innernode) | ||||||
|  |                     refnodes.append(newnode) | ||||||
|  |                 for count in range(len(refnodes)): | ||||||
|  |                     refnode.append(refnodes[count]) | ||||||
|  |                     if count < len(refnodes) - 1: | ||||||
|  |                         refnode.append(nodes.Text(", ")) | ||||||
|  |                 tbody += create_table_row([para, refnode]) | ||||||
|  |             content.append(table) | ||||||
|  |         else: | ||||||
|  |             para = nodes.paragraph(l_('No IP addresses in this range')) | ||||||
|  |             content.append(para) | ||||||
|         node.replace_self(content) |         node.replace_self(content) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										8
									
								
								setup.py
									
										
									
									
									
								
							
							
						
						
									
										8
									
								
								setup.py
									
										
									
									
									
								
							|  | @ -2,14 +2,11 @@ | ||||||
| 
 | 
 | ||||||
| from setuptools import setup, find_packages | from setuptools import setup, find_packages | ||||||
| 
 | 
 | ||||||
| version = '0.1.1' | version = '0.2.0' | ||||||
| 
 | 
 | ||||||
| with open('README.rst') as readme: | with open('README.rst') as readme: | ||||||
|     description = readme.read() + "\n\n" |     description = readme.read() + "\n\n" | ||||||
| 
 | 
 | ||||||
| with open('COPYING') as license: |  | ||||||
|     description += license.read() |  | ||||||
| 
 |  | ||||||
| requires = ['Sphinx>=1.4', 'ipcalc>=1.99'] | requires = ['Sphinx>=1.4', 'ipcalc>=1.99'] | ||||||
| tests_requires = ['path.py>=8.2.1'] | tests_requires = ['path.py>=8.2.1'] | ||||||
| 
 | 
 | ||||||
|  | @ -17,12 +14,13 @@ tests_requires = ['path.py>=8.2.1'] | ||||||
| setup( | setup( | ||||||
|     author="Jan Dittberner", |     author="Jan Dittberner", | ||||||
|     author_email="jan@dittberner.info", |     author_email="jan@dittberner.info", | ||||||
|     description="IP address extensions for Sphinx", |     description="IP address extension for Sphinx", | ||||||
|     long_description=description, |     long_description=description, | ||||||
|     include_package_data=True, |     include_package_data=True, | ||||||
|     install_requires=requires, |     install_requires=requires, | ||||||
|     keywords="sphinx extension IP", |     keywords="sphinx extension IP", | ||||||
|     license="GPLv3+", |     license="GPLv3+", | ||||||
|  |     url="https://pypi.python.org/pypi/jandd.sphinxext.ip", | ||||||
|     name="jandd.sphinxext.ip", |     name="jandd.sphinxext.ip", | ||||||
|     namespace_packages=['jandd', 'jandd.sphinxext'], |     namespace_packages=['jandd', 'jandd.sphinxext'], | ||||||
|     packages=find_packages(), |     packages=find_packages(), | ||||||
|  |  | ||||||
|  | @ -13,6 +13,7 @@ Contents: | ||||||
| 
 | 
 | ||||||
|    testpage1 |    testpage1 | ||||||
|    testpage2 |    testpage2 | ||||||
|  |    testpage3 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| Indices and tables | Indices and tables | ||||||
|  |  | ||||||
							
								
								
									
										4
									
								
								tests/root/testpage3.rst
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								tests/root/testpage3.rst
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,4 @@ | ||||||
|  | Test page 3 | ||||||
|  | =========== | ||||||
|  | 
 | ||||||
|  | This page contains :ip:v6:`2001:dead:beef::1` like :doc:`testpage2` does. | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue