mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Refactored role registrations.
This commit is contained in:
parent
f82a4a4eab
commit
957be3bfa0
@ -20,7 +20,7 @@ from docutils import nodes
|
|||||||
from docutils.parsers.rst import directives, roles
|
from docutils.parsers.rst import directives, roles
|
||||||
|
|
||||||
import sphinx
|
import sphinx
|
||||||
from sphinx.roles import xfileref_role, innernodetypes
|
from sphinx.roles import make_xref_role, simple_link_func
|
||||||
from sphinx.config import Config
|
from sphinx.config import Config
|
||||||
from sphinx.errors import SphinxError, SphinxWarning, ExtensionError
|
from sphinx.errors import SphinxError, SphinxWarning, ExtensionError
|
||||||
from sphinx.domains import domains
|
from sphinx.domains import domains
|
||||||
@ -310,17 +310,15 @@ class Sphinx(object):
|
|||||||
parse_node)
|
parse_node)
|
||||||
directives.register_directive(directivename,
|
directives.register_directive(directivename,
|
||||||
directive_dwim(GenericDesc))
|
directive_dwim(GenericDesc))
|
||||||
roles.register_local_role(rolename, xfileref_role)
|
role_func = make_xref_role(simple_link_func, innernodeclass=ref_nodeclass)
|
||||||
if ref_nodeclass is not None:
|
roles.register_local_role(rolename, role_func)
|
||||||
innernodetypes[rolename] = ref_nodeclass
|
|
||||||
|
|
||||||
def add_crossref_type(self, directivename, rolename, indextemplate='',
|
def add_crossref_type(self, directivename, rolename, indextemplate='',
|
||||||
ref_nodeclass=None):
|
ref_nodeclass=None):
|
||||||
additional_xref_types[directivename] = (rolename, indextemplate, None)
|
additional_xref_types[directivename] = (rolename, indextemplate, None)
|
||||||
directives.register_directive(directivename, directive_dwim(Target))
|
directives.register_directive(directivename, directive_dwim(Target))
|
||||||
roles.register_local_role(rolename, xfileref_role)
|
role_func = make_xref_role(simple_link_func, innernodeclass=ref_nodeclass)
|
||||||
if ref_nodeclass is not None:
|
roles.register_local_role(rolename, role_func)
|
||||||
innernodetypes[rolename] = ref_nodeclass
|
|
||||||
|
|
||||||
def add_transform(self, transform):
|
def add_transform(self, transform):
|
||||||
SphinxStandaloneReader.transforms.append(transform)
|
SphinxStandaloneReader.transforms.append(transform)
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
class Domain(object):
|
class Domain(object):
|
||||||
name = ''
|
name = ''
|
||||||
directives = {}
|
directives = {}
|
||||||
|
roles = {}
|
||||||
label = ''
|
label = ''
|
||||||
|
|
||||||
domains = {}
|
domains = {}
|
||||||
|
263
sphinx/roles.py
263
sphinx/roles.py
@ -94,106 +94,40 @@ roles.register_local_role('pep', indexmarkup_role)
|
|||||||
roles.register_local_role('rfc', indexmarkup_role)
|
roles.register_local_role('rfc', indexmarkup_role)
|
||||||
|
|
||||||
|
|
||||||
# default is `literal`
|
def make_xref_role(link_func, nodeclass=None, innernodeclass=None):
|
||||||
innernodetypes = {
|
if nodeclass is None:
|
||||||
'ref': nodes.emphasis,
|
nodeclass = addnodes.pending_xref
|
||||||
'term': nodes.emphasis,
|
if innernodeclass is None:
|
||||||
'token': nodes.strong,
|
innernodeclass = nodes.literal
|
||||||
'envvar': nodes.strong,
|
|
||||||
'download': nodes.strong,
|
|
||||||
'option': addnodes.literal_emphasis,
|
|
||||||
}
|
|
||||||
|
|
||||||
def _fix_parens(typ, text, env):
|
def func(typ, rawtext, text, lineno, inliner, options={}, content=[]):
|
||||||
if typ in ('func', 'meth', 'cfunc'):
|
env = inliner.document.settings.env
|
||||||
if text.endswith('()'):
|
if not typ:
|
||||||
# remove parentheses
|
typ = env.config.default_role
|
||||||
text = text[:-2]
|
else:
|
||||||
if env.config.add_function_parentheses:
|
typ = typ.lower()
|
||||||
# add them back to all occurrences if configured
|
text = utils.unescape(text)
|
||||||
text += '()'
|
# if the first character is a bang, don't cross-reference at all
|
||||||
return text
|
if text[0:1] == '!':
|
||||||
|
text = _fix_parens(typ, text[1:], env)
|
||||||
|
return [innernodeclass(rawtext, text, classes=['xref'])], []
|
||||||
|
# we want a cross-reference, create the reference node
|
||||||
|
pnode = nodeclass(rawtext, reftype=typ, refcaption=False,
|
||||||
|
modname=env.currmodule, classname=env.currclass)
|
||||||
|
# we may need the line number for warnings
|
||||||
|
pnode.line = lineno
|
||||||
|
target, title = link_func(env, text, pnode)
|
||||||
|
pnode['reftarget'] = target
|
||||||
|
pnode += innernodeclass(rawtext, title, classes=['xref'])
|
||||||
|
return [pnode], []
|
||||||
|
return func
|
||||||
|
|
||||||
def xfileref_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
|
|
||||||
env = inliner.document.settings.env
|
def menusel_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
|
||||||
if not typ:
|
return [nodes.emphasis(
|
||||||
typ = env.config.default_role
|
rawtext,
|
||||||
else:
|
utils.unescape(text).replace('-->', u'\N{TRIANGULAR BULLET}'))], []
|
||||||
typ = typ.lower()
|
return role
|
||||||
text = utils.unescape(text)
|
|
||||||
# if the first character is a bang, don't cross-reference at all
|
|
||||||
if text[0:1] == '!':
|
|
||||||
text = _fix_parens(typ, text[1:], env)
|
|
||||||
return [innernodetypes.get(typ, nodes.literal)(
|
|
||||||
rawtext, text, classes=['xref'])], []
|
|
||||||
# we want a cross-reference, create the reference node
|
|
||||||
nodeclass = (typ == 'download') and addnodes.download_reference or \
|
|
||||||
addnodes.pending_xref
|
|
||||||
pnode = nodeclass(rawtext, reftype=typ, refcaption=False,
|
|
||||||
modname=env.currmodule, classname=env.currclass)
|
|
||||||
# we may need the line number for warnings
|
|
||||||
pnode.line = lineno
|
|
||||||
# look if explicit title and target are given with `foo <bar>` syntax
|
|
||||||
has_explicit_title, title, target = split_explicit_title(text)
|
|
||||||
if has_explicit_title:
|
|
||||||
pnode['refcaption'] = True
|
|
||||||
# special target for Python object cross-references
|
|
||||||
if typ in ('data', 'exc', 'func', 'class', 'const', 'attr',
|
|
||||||
'meth', 'mod', 'obj'):
|
|
||||||
# fix-up parentheses in link title
|
|
||||||
if not has_explicit_title:
|
|
||||||
title = title.lstrip('.') # only has a meaning for the target
|
|
||||||
target = target.lstrip('~') # only has a meaning for the title
|
|
||||||
title = _fix_parens(typ, title, env)
|
|
||||||
# if the first character is a tilde, don't display the module/class
|
|
||||||
# parts of the contents
|
|
||||||
if title[0:1] == '~':
|
|
||||||
title = title[1:]
|
|
||||||
dot = title.rfind('.')
|
|
||||||
if dot != -1:
|
|
||||||
title = title[dot+1:]
|
|
||||||
# remove parentheses from the target too
|
|
||||||
if target.endswith('()'):
|
|
||||||
target = target[:-2]
|
|
||||||
# if the first character is a dot, search more specific namespaces first
|
|
||||||
# else search builtins first
|
|
||||||
if target[0:1] == '.':
|
|
||||||
target = target[1:]
|
|
||||||
pnode['refspecific'] = True
|
|
||||||
# some other special cases for the target
|
|
||||||
elif typ == 'option':
|
|
||||||
program = env.currprogram
|
|
||||||
if not has_explicit_title:
|
|
||||||
if ' ' in title and not (title.startswith('/') or
|
|
||||||
title.startswith('-')):
|
|
||||||
program, target = re.split(' (?=-|--|/)', title, 1)
|
|
||||||
program = ws_re.sub('-', program)
|
|
||||||
target = target.strip()
|
|
||||||
elif ' ' in target:
|
|
||||||
program, target = re.split(' (?=-|--|/)', target, 1)
|
|
||||||
program = ws_re.sub('-', program)
|
|
||||||
pnode['refprogram'] = program
|
|
||||||
elif typ == 'term':
|
|
||||||
# normalize whitespace in definition terms (if the term reference is
|
|
||||||
# broken over a line, a newline will be in target)
|
|
||||||
target = ws_re.sub(' ', target).lower()
|
|
||||||
elif typ == 'ref':
|
|
||||||
# reST label names are always lowercased
|
|
||||||
target = ws_re.sub('', target).lower()
|
|
||||||
elif typ == 'cfunc':
|
|
||||||
# fix-up parens for C functions too
|
|
||||||
if not has_explicit_title:
|
|
||||||
title = _fix_parens(typ, title, env)
|
|
||||||
# remove parentheses from the target too
|
|
||||||
if target.endswith('()'):
|
|
||||||
target = target[:-2]
|
|
||||||
else:
|
|
||||||
# remove all whitespace to avoid referencing problems
|
|
||||||
target = ws_re.sub('', target)
|
|
||||||
pnode['reftarget'] = target
|
|
||||||
pnode += innernodetypes.get(typ, nodes.literal)(rawtext, title,
|
|
||||||
classes=['xref'])
|
|
||||||
return [pnode], []
|
|
||||||
|
|
||||||
|
|
||||||
def menusel_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
|
def menusel_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
|
||||||
@ -232,30 +166,121 @@ def abbr_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
|
|||||||
return [addnodes.abbreviation(abbr, abbr, explanation=expl)], []
|
return [addnodes.abbreviation(abbr, abbr, explanation=expl)], []
|
||||||
|
|
||||||
|
|
||||||
|
def normalize_func_parens(env, target, title):
|
||||||
|
if title.endswith('()'):
|
||||||
|
# remove parentheses
|
||||||
|
title = title[:-2]
|
||||||
|
if env.config.add_function_parentheses:
|
||||||
|
# add them back to all occurrences if configured
|
||||||
|
title += '()'
|
||||||
|
# remove parentheses from the target too
|
||||||
|
if target.endswith('()'):
|
||||||
|
target = target[:-2]
|
||||||
|
return target, title
|
||||||
|
|
||||||
|
|
||||||
|
def generic_link_func(env, text, pnode):
|
||||||
|
has_explicit_title, title, target = split_explicit_title(text)
|
||||||
|
if has_explicit_title:
|
||||||
|
pnode['refcaption'] = True
|
||||||
|
return target, title
|
||||||
|
|
||||||
|
|
||||||
|
def pyref_link_func(env, text, pnode):
|
||||||
|
has_explicit_title, title, target = split_explicit_title(text)
|
||||||
|
if has_explicit_title:
|
||||||
|
pnode['refcaption'] = True
|
||||||
|
# fix-up parentheses in link title
|
||||||
|
if not has_explicit_title:
|
||||||
|
title = title.lstrip('.') # only has a meaning for the target
|
||||||
|
target = target.lstrip('~') # only has a meaning for the title
|
||||||
|
# if the first character is a tilde, don't display the module/class
|
||||||
|
# parts of the contents
|
||||||
|
if title[0:1] == '~':
|
||||||
|
title = title[1:]
|
||||||
|
dot = title.rfind('.')
|
||||||
|
if dot != -1:
|
||||||
|
title = title[dot+1:]
|
||||||
|
# if the first character is a dot, search more specific namespaces first
|
||||||
|
# else search builtins first
|
||||||
|
if target[0:1] == '.':
|
||||||
|
target = target[1:]
|
||||||
|
pnode['refspecific'] = True
|
||||||
|
return target, title
|
||||||
|
|
||||||
|
|
||||||
|
def pyref_callable_link_func(env, text, pnode):
|
||||||
|
target, title = pyref_link_func(env, text, pnode)
|
||||||
|
target, title = normalize_func_parens(env, target, title)
|
||||||
|
return target, title
|
||||||
|
|
||||||
|
|
||||||
|
def option_link_func(env, text, pnode):
|
||||||
|
has_explicit_title, title, target = split_explicit_title(text)
|
||||||
|
program = env.currprogram
|
||||||
|
if not has_explicit_title:
|
||||||
|
if ' ' in title and not (title.startswith('/') or
|
||||||
|
title.startswith('-')):
|
||||||
|
program, target = re.split(' (?=-|--|/)', title, 1)
|
||||||
|
program = ws_re.sub('-', program)
|
||||||
|
target = target.strip()
|
||||||
|
elif ' ' in target:
|
||||||
|
program, target = re.split(' (?=-|--|/)', target, 1)
|
||||||
|
program = ws_re.sub('-', program)
|
||||||
|
pnode['refprogram'] = program
|
||||||
|
return target, title
|
||||||
|
|
||||||
|
|
||||||
|
def simple_link_func(env, text, pnode):
|
||||||
|
# normalize all whitespace to avoid referencing problems
|
||||||
|
has_explicit_title, title, target = split_explicit_title(text)
|
||||||
|
target = ws_re.sub(' ', target)
|
||||||
|
return target, title
|
||||||
|
|
||||||
|
|
||||||
|
def lowercase_link_func(env, text, pnode):
|
||||||
|
target, title = simple_link_func(env, text, pnode)
|
||||||
|
return target.lower(), title
|
||||||
|
|
||||||
|
|
||||||
|
def cfunc_link_func(env, text, pnode):
|
||||||
|
has_explicit_title, title, target = split_explicit_title(text)
|
||||||
|
if not has_explicit_title:
|
||||||
|
target, title = normalize_func_parens(env, target, title)
|
||||||
|
# remove parentheses from the target too
|
||||||
|
if target.endswith('()'):
|
||||||
|
target = target[:-2]
|
||||||
|
return target, title
|
||||||
|
|
||||||
|
|
||||||
|
generic_pyref_role = make_xref_role(pyref_link_func)
|
||||||
|
callable_pyref_role = make_xref_role(pyref_callable_link_func)
|
||||||
|
simple_xref_role = make_xref_role(simple_link_func)
|
||||||
|
|
||||||
specific_docroles = {
|
specific_docroles = {
|
||||||
'data': xfileref_role,
|
'data': generic_pyref_role,
|
||||||
'exc': xfileref_role,
|
'exc': generic_pyref_role,
|
||||||
'func': xfileref_role,
|
'func': callable_pyref_role,
|
||||||
'class': xfileref_role,
|
'class': generic_pyref_role,
|
||||||
'const': xfileref_role,
|
'const': generic_pyref_role,
|
||||||
'attr': xfileref_role,
|
'attr': generic_pyref_role,
|
||||||
'meth': xfileref_role,
|
'meth': callable_pyref_role,
|
||||||
'obj': xfileref_role,
|
'mod': generic_pyref_role,
|
||||||
'cfunc' : xfileref_role,
|
'obj': generic_pyref_role,
|
||||||
'cmember': xfileref_role,
|
|
||||||
'cdata': xfileref_role,
|
|
||||||
'ctype': xfileref_role,
|
|
||||||
'cmacro': xfileref_role,
|
|
||||||
|
|
||||||
'mod': xfileref_role,
|
'keyword': simple_xref_role,
|
||||||
|
'ref': make_xref_role(lowercase_link_func, None, nodes.emphasis),
|
||||||
|
'token': simple_xref_role,
|
||||||
|
'term': make_xref_role(lowercase_link_func, None, nodes.emphasis),
|
||||||
|
'option': make_xref_role(option_link_func, None, addnodes.literal_emphasis),
|
||||||
|
'doc': simple_xref_role,
|
||||||
|
'download': make_xref_role(simple_link_func, addnodes.download_reference),
|
||||||
|
|
||||||
'keyword': xfileref_role,
|
'cmember': simple_xref_role,
|
||||||
'ref': xfileref_role,
|
'cmacro': simple_xref_role,
|
||||||
'token': xfileref_role,
|
'cfunc' : make_xref_role(cfunc_link_func),
|
||||||
'term': xfileref_role,
|
'cdata': simple_xref_role,
|
||||||
'option': xfileref_role,
|
'ctype': simple_xref_role,
|
||||||
'doc': xfileref_role,
|
|
||||||
'download': xfileref_role,
|
|
||||||
|
|
||||||
'menuselection': menusel_role,
|
'menuselection': menusel_role,
|
||||||
'file': emph_literal_role,
|
'file': emph_literal_role,
|
||||||
|
Loading…
Reference in New Issue
Block a user