Make docfield xref changes backwards compatible

This commit is contained in:
Jakob Lykke Andersen 2017-03-11 18:56:13 +09:00
parent 9ca5d990f6
commit 9249db2472
2 changed files with 30 additions and 29 deletions

View File

@ -85,10 +85,10 @@ def _pseudo_parse_arglist(signode, arglist):
# This override allows our inline type specifiers to behave like :class: link # This override allows our inline type specifiers to behave like :class: link
# when it comes to handling "." and "~" prefixes. # when it comes to handling "." and "~" prefixes.
class PyXrefMixin(object): class PyXrefMixin(object):
def make_xref(self, env, rolename, domain, target, innernode=nodes.emphasis, def make_xref(self, rolename, domain, target, innernode=nodes.emphasis,
contnode=None): contnode=None, env=None):
result = super(PyXrefMixin, self).make_xref(env, rolename, domain, target, result = super(PyXrefMixin, self).make_xref(rolename, domain, target,
innernode, contnode) innernode, contnode, env)
result['refspecific'] = True result['refspecific'] = True
if target.startswith(('.', '~')): if target.startswith(('.', '~')):
prefix, result['reftarget'] = target[0], target[1:] prefix, result['reftarget'] = target[0], target[1:]
@ -101,8 +101,8 @@ class PyXrefMixin(object):
break break
return result return result
def make_xrefs(self, env, rolename, domain, target, innernode=nodes.emphasis, def make_xrefs(self, rolename, domain, target, innernode=nodes.emphasis,
contnode=None): contnode=None, env=None):
delims = '(\s*[\[\]\(\),](?:\s*or\s)?\s*|\s+or\s+)' delims = '(\s*[\[\]\(\),](?:\s*or\s)?\s*|\s+or\s+)'
delims_re = re.compile(delims) delims_re = re.compile(delims)
sub_targets = re.split(delims, target) sub_targets = re.split(delims, target)
@ -117,8 +117,8 @@ class PyXrefMixin(object):
if delims_re.match(sub_target): if delims_re.match(sub_target):
results.append(contnode or innernode(sub_target, sub_target)) results.append(contnode or innernode(sub_target, sub_target))
else: else:
results.append(self.make_xref(env, rolename, domain, sub_target, results.append(self.make_xref(rolename, domain, sub_target,
innernode, contnode)) innernode, contnode, env))
return results return results

View File

@ -54,37 +54,38 @@ class Field(object):
self.rolename = rolename self.rolename = rolename
self.bodyrolename = bodyrolename self.bodyrolename = bodyrolename
def make_xref(self, env, rolename, domain, target, def make_xref(self, rolename, domain, target,
innernode=addnodes.literal_emphasis, contnode=None): innernode=addnodes.literal_emphasis, contnode=None, env=None):
if not rolename: if not rolename:
return contnode or innernode(target, target) return contnode or innernode(target, target)
refnode = addnodes.pending_xref('', refdomain=domain, refexplicit=False, refnode = addnodes.pending_xref('', refdomain=domain, refexplicit=False,
reftype=rolename, reftarget=target) reftype=rolename, reftarget=target)
refnode += contnode or innernode(target, target) refnode += contnode or innernode(target, target)
env.domains[domain].process_field_xref(refnode) if env:
env.domains[domain].process_field_xref(refnode)
return refnode return refnode
def make_xrefs(self, env, rolename, domain, target, def make_xrefs(self, rolename, domain, target,
innernode=addnodes.literal_emphasis, contnode=None): innernode=addnodes.literal_emphasis, contnode=None, env=None):
return [self.make_xref(env, rolename, domain, target, innernode, contnode)] return [self.make_xref(rolename, domain, target, innernode, contnode, env)]
def make_entry(self, fieldarg, content): def make_entry(self, fieldarg, content):
return (fieldarg, content) return (fieldarg, content)
def make_field(self, env, types, domain, item): def make_field(self, types, domain, item, env=None):
fieldarg, content = item fieldarg, content = item
fieldname = nodes.field_name('', self.label) fieldname = nodes.field_name('', self.label)
if fieldarg: if fieldarg:
fieldname += nodes.Text(' ') fieldname += nodes.Text(' ')
fieldname.extend(self.make_xrefs(env, self.rolename, domain, fieldname.extend(self.make_xrefs(self.rolename, domain,
fieldarg, nodes.Text)) fieldarg, nodes.Text, env=env))
if len(content) == 1 and ( if len(content) == 1 and (
isinstance(content[0], nodes.Text) or isinstance(content[0], nodes.Text) or
(isinstance(content[0], nodes.inline) and len(content[0]) == 1 and (isinstance(content[0], nodes.inline) and len(content[0]) == 1 and
isinstance(content[0][0], nodes.Text))): isinstance(content[0][0], nodes.Text))):
content = self.make_xrefs(env, self.bodyrolename, domain, content = self.make_xrefs(self.bodyrolename, domain,
content[0].astext(), contnode=content[0]) content[0].astext(), contnode=content[0], env=env)
fieldbody = nodes.field_body('', nodes.paragraph('', '', *content)) fieldbody = nodes.field_body('', nodes.paragraph('', '', *content))
return nodes.field('', fieldname, fieldbody) return nodes.field('', fieldname, fieldbody)
@ -110,13 +111,13 @@ class GroupedField(Field):
Field.__init__(self, name, names, label, True, rolename) Field.__init__(self, name, names, label, True, rolename)
self.can_collapse = can_collapse self.can_collapse = can_collapse
def make_field(self, env, types, domain, items): def make_field(self, types, domain, items, env=None):
fieldname = nodes.field_name('', self.label) fieldname = nodes.field_name('', self.label)
listnode = self.list_type() listnode = self.list_type()
for fieldarg, content in items: for fieldarg, content in items:
par = nodes.paragraph() par = nodes.paragraph()
par.extend(self.make_xrefs(env, self.rolename, domain, fieldarg, par.extend(self.make_xrefs(self.rolename, domain, fieldarg,
addnodes.literal_strong)) addnodes.literal_strong, env=env))
par += nodes.Text(' -- ') par += nodes.Text(' -- ')
par += content par += content
listnode += nodes.list_item('', par) listnode += nodes.list_item('', par)
@ -156,11 +157,11 @@ class TypedField(GroupedField):
self.typenames = typenames self.typenames = typenames
self.typerolename = typerolename self.typerolename = typerolename
def make_field(self, env, types, domain, items): def make_field(self, types, domain, items, env=None):
def handle_item(fieldarg, content): def handle_item(fieldarg, content):
par = nodes.paragraph() par = nodes.paragraph()
par.extend(self.make_xrefs(env, self.rolename, domain, fieldarg, par.extend(self.make_xrefs(self.rolename, domain, fieldarg,
addnodes.literal_strong)) addnodes.literal_strong, env=env))
if fieldarg in types: if fieldarg in types:
par += nodes.Text(' (') par += nodes.Text(' (')
# NOTE: using .pop() here to prevent a single type node to be # NOTE: using .pop() here to prevent a single type node to be
@ -169,8 +170,8 @@ class TypedField(GroupedField):
fieldtype = types.pop(fieldarg) fieldtype = types.pop(fieldarg)
if len(fieldtype) == 1 and isinstance(fieldtype[0], nodes.Text): if len(fieldtype) == 1 and isinstance(fieldtype[0], nodes.Text):
typename = u''.join(n.astext() for n in fieldtype) typename = u''.join(n.astext() for n in fieldtype)
par.extend(self.make_xrefs(env, self.typerolename, domain, par.extend(self.make_xrefs(self.typerolename, domain, typename,
typename, addnodes.literal_emphasis)) addnodes.literal_emphasis, env=env))
else: else:
par += fieldtype par += fieldtype
par += nodes.Text(')') par += nodes.Text(')')
@ -309,7 +310,7 @@ class DocFieldTransformer(object):
else: else:
fieldtype, content = entry fieldtype, content = entry
fieldtypes = types.get(fieldtype.name, {}) fieldtypes = types.get(fieldtype.name, {})
new_list += fieldtype.make_field(self.directive.env, fieldtypes, new_list += fieldtype.make_field(fieldtypes, self.directive.domain,
self.directive.domain, content) content, env=self.directive.env)
node.replace_self(new_list) node.replace_self(new_list)