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
|
||||
==================
|
||||
|
||||
|
@ -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
|
||||
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
|
||||
------------
|
||||
============
|
||||
|
||||
* `Jan Dittberner`_
|
||||
|
||||
.. _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
|
||||
:license: GPLv3+, see COPYING file for details.
|
||||
"""
|
||||
__version__ = '0.1.1'
|
||||
|
||||
import re
|
||||
|
||||
|
@ -24,15 +23,20 @@ from sphinx.locale import l_
|
|||
from sphinx.roles import XRefRole
|
||||
from sphinx.util.nodes import make_refnode
|
||||
|
||||
__version__ = '0.2.0'
|
||||
|
||||
|
||||
def ip_object_anchor(typ, path):
|
||||
path = re.sub(r'[.:/]', '-', 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):
|
||||
|
@ -42,7 +46,7 @@ class IPXRefRole(XRefRole):
|
|||
def __init__(self, method, index_type, **kwargs):
|
||||
self.method = method
|
||||
self.index_type = index_type
|
||||
innernodeclass=None
|
||||
innernodeclass = None
|
||||
if method in ('v4', 'v6'):
|
||||
innernodeclass = ip_node
|
||||
super(IPXRefRole, self).__init__(
|
||||
|
@ -230,36 +234,85 @@ def process_ips(app, doctree):
|
|||
node.replace_self(replacement)
|
||||
|
||||
|
||||
def sort_ip_info(item):
|
||||
return item['ip']
|
||||
def sort_ip(item):
|
||||
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):
|
||||
env = app.builder.env
|
||||
domaindata = env.domaindata[IPDomain.name]
|
||||
|
||||
header = (l_('IP address'), l_('Used by'))
|
||||
colwidths = (1, 3)
|
||||
|
||||
for node in doctree.traverse(ip_range):
|
||||
content = []
|
||||
net = Network(node['rangespec'])
|
||||
for ip_info in sorted(domaindata['ips'], key=sort_ip_info):
|
||||
if ip_info['ip'] in net:
|
||||
ips = {}
|
||||
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.literal('', ip_info['ip'])
|
||||
ids = ip_object_anchor(ip_info['typ'], ip_info['ip'])
|
||||
para['ids'].append(ids)
|
||||
domaindata[ip_info['typ']][ids] = (fromdocname, '')
|
||||
newnode = nodes.reference('', '', internal=True)
|
||||
try:
|
||||
newnode['refuri'] = app.builder.get_relative_uri(
|
||||
fromdocname, ip_info['docname'])
|
||||
except NoUri:
|
||||
pass
|
||||
title = env.titles[ip_info['docname']]
|
||||
innernode = nodes.Text(title.astext())
|
||||
newnode.append(innernode)
|
||||
para += nodes.Text(" in ")
|
||||
para += newnode
|
||||
content.append(para)
|
||||
para += nodes.literal('', ip)
|
||||
refnode = nodes.paragraph()
|
||||
refuris = set()
|
||||
refnodes = []
|
||||
for item in ip_info:
|
||||
ids = ip_object_anchor(item['typ'], item['ip'])
|
||||
if ids not in para['ids']:
|
||||
para['ids'].append(ids)
|
||||
|
||||
domaindata[item['typ']][ids] = (fromdocname, '')
|
||||
newnode = nodes.reference('', '', internal=True)
|
||||
try:
|
||||
newnode['refuri'] = app.builder.get_relative_uri(
|
||||
fromdocname, item['docname'])
|
||||
if newnode['refuri'] in refuris:
|
||||
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)
|
||||
|
||||
|
||||
|
|
8
setup.py
8
setup.py
|
@ -2,14 +2,11 @@
|
|||
|
||||
from setuptools import setup, find_packages
|
||||
|
||||
version = '0.1.1'
|
||||
version = '0.2.0'
|
||||
|
||||
with open('README.rst') as readme:
|
||||
description = readme.read() + "\n\n"
|
||||
|
||||
with open('COPYING') as license:
|
||||
description += license.read()
|
||||
|
||||
requires = ['Sphinx>=1.4', 'ipcalc>=1.99']
|
||||
tests_requires = ['path.py>=8.2.1']
|
||||
|
||||
|
@ -17,12 +14,13 @@ tests_requires = ['path.py>=8.2.1']
|
|||
setup(
|
||||
author="Jan Dittberner",
|
||||
author_email="jan@dittberner.info",
|
||||
description="IP address extensions for Sphinx",
|
||||
description="IP address extension for Sphinx",
|
||||
long_description=description,
|
||||
include_package_data=True,
|
||||
install_requires=requires,
|
||||
keywords="sphinx extension IP",
|
||||
license="GPLv3+",
|
||||
url="https://pypi.python.org/pypi/jandd.sphinxext.ip",
|
||||
name="jandd.sphinxext.ip",
|
||||
namespace_packages=['jandd', 'jandd.sphinxext'],
|
||||
packages=find_packages(),
|
||||
|
|
|
@ -13,6 +13,7 @@ Contents:
|
|||
|
||||
testpage1
|
||||
testpage2
|
||||
testpage3
|
||||
|
||||
|
||||
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…
Reference in a new issue