2007-07-23 09:02:25 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
"""
|
|
|
|
|
sphinx.roles
|
|
|
|
|
~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
Handlers for additional ReST roles.
|
|
|
|
|
|
2017-03-22 20:21:12 +09:00
|
|
|
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
|
2008-12-27 12:19:17 +01:00
|
|
|
:license: BSD, see LICENSE for details.
|
2007-07-23 09:02:25 +00:00
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
import re
|
|
|
|
|
|
2014-04-29 21:20:56 +09:00
|
|
|
from six import iteritems
|
2007-07-23 09:02:25 +00:00
|
|
|
from docutils import nodes, utils
|
|
|
|
|
|
2008-01-16 20:27:25 +00:00
|
|
|
from sphinx import addnodes
|
2010-01-17 19:33:23 +01:00
|
|
|
from sphinx.locale import _
|
2014-09-19 12:21:38 +02:00
|
|
|
from sphinx.errors import SphinxError
|
2010-01-17 17:35:12 +01:00
|
|
|
from sphinx.util import ws_re
|
2011-09-23 11:03:23 +02:00
|
|
|
from sphinx.util.nodes import split_explicit_title, process_index_entry, \
|
2014-09-20 19:16:26 +02:00
|
|
|
set_role_source_info
|
2007-07-23 09:02:25 +00:00
|
|
|
|
2017-02-10 15:53:42 +09:00
|
|
|
if False:
|
|
|
|
|
# For type annotation
|
2017-03-03 12:19:09 +09:00
|
|
|
from typing import Any, Dict, List, Tuple, Type # NOQA
|
2017-02-10 15:53:42 +09:00
|
|
|
from docutils.parsers.rst.states import Inliner # NOQA
|
|
|
|
|
from sphinx.application import Sphinx # NOQA
|
|
|
|
|
from sphinx.environment import BuildEnvironment # NOQA
|
|
|
|
|
|
2007-07-23 09:02:25 +00:00
|
|
|
|
|
|
|
|
generic_docroles = {
|
2014-09-20 19:16:26 +02:00
|
|
|
'command': addnodes.literal_strong,
|
|
|
|
|
'dfn': nodes.emphasis,
|
|
|
|
|
'kbd': nodes.literal,
|
|
|
|
|
'mailheader': addnodes.literal_emphasis,
|
|
|
|
|
'makevar': addnodes.literal_strong,
|
2016-01-08 22:17:45 +09:00
|
|
|
'manpage': addnodes.manpage,
|
2014-09-20 19:16:26 +02:00
|
|
|
'mimetype': addnodes.literal_emphasis,
|
|
|
|
|
'newsgroup': addnodes.literal_emphasis,
|
|
|
|
|
'program': addnodes.literal_strong, # XXX should be an x-ref
|
|
|
|
|
'regexp': nodes.literal,
|
2007-07-23 09:02:25 +00:00
|
|
|
}
|
|
|
|
|
|
2014-09-20 19:16:26 +02:00
|
|
|
|
2009-09-09 19:35:50 +02:00
|
|
|
# -- generic cross-reference role ----------------------------------------------
|
2009-08-09 20:27:36 +02:00
|
|
|
|
|
|
|
|
class XRefRole(object):
|
2009-09-12 13:39:40 +00:00
|
|
|
"""
|
|
|
|
|
A generic cross-referencing role. To create a callable that can be used as
|
|
|
|
|
a role function, create an instance of this class.
|
|
|
|
|
|
|
|
|
|
The general features of this role are:
|
|
|
|
|
|
|
|
|
|
* Automatic creation of a reference and a content node.
|
|
|
|
|
* Optional separation of title and target with `title <target>`.
|
|
|
|
|
* The implementation is a class rather than a function to make
|
|
|
|
|
customization easier.
|
|
|
|
|
|
|
|
|
|
Customization can be done in two ways:
|
|
|
|
|
|
|
|
|
|
* Supplying constructor parameters:
|
|
|
|
|
* `fix_parens` to normalize parentheses (strip from target, and add to
|
|
|
|
|
title if configured)
|
|
|
|
|
* `lowercase` to lowercase the target
|
|
|
|
|
* `nodeclass` and `innernodeclass` select the node classes for
|
|
|
|
|
the reference and the content node
|
|
|
|
|
|
|
|
|
|
* Subclassing and overwriting `process_link()` and/or `result_nodes()`.
|
|
|
|
|
"""
|
2009-08-09 20:32:18 +02:00
|
|
|
|
2017-07-15 16:44:53 +09:00
|
|
|
nodeclass = addnodes.pending_xref # type: Type[nodes.Node]
|
2009-08-09 20:27:36 +02:00
|
|
|
innernodeclass = nodes.literal
|
|
|
|
|
|
|
|
|
|
def __init__(self, fix_parens=False, lowercase=False,
|
2011-01-08 16:41:15 +01:00
|
|
|
nodeclass=None, innernodeclass=None, warn_dangling=False):
|
2017-02-10 15:53:42 +09:00
|
|
|
# type: (bool, bool, Type[nodes.Node], Type[nodes.Node], bool) -> None
|
2009-08-09 20:27:36 +02:00
|
|
|
self.fix_parens = fix_parens
|
2009-09-08 00:49:52 +02:00
|
|
|
self.lowercase = lowercase
|
2011-01-08 16:41:15 +01:00
|
|
|
self.warn_dangling = warn_dangling
|
2009-08-09 20:27:36 +02:00
|
|
|
if nodeclass is not None:
|
|
|
|
|
self.nodeclass = nodeclass
|
|
|
|
|
if innernodeclass is not None:
|
|
|
|
|
self.innernodeclass = innernodeclass
|
|
|
|
|
|
2009-09-09 19:35:50 +02:00
|
|
|
def _fix_parens(self, env, has_explicit_title, title, target):
|
2017-02-10 15:53:42 +09:00
|
|
|
# type: (BuildEnvironment, bool, unicode, unicode) -> Tuple[unicode, unicode]
|
2009-08-09 20:27:36 +02:00
|
|
|
if not has_explicit_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 title, target
|
|
|
|
|
|
|
|
|
|
def __call__(self, typ, rawtext, text, lineno, inliner,
|
|
|
|
|
options={}, content=[]):
|
2017-02-10 15:53:42 +09:00
|
|
|
# type: (unicode, unicode, unicode, int, Inliner, Dict, List[unicode]) -> Tuple[List[nodes.Node], List[nodes.Node]] # NOQA
|
2009-08-09 20:27:36 +02:00
|
|
|
env = inliner.document.settings.env
|
|
|
|
|
if not typ:
|
2014-09-19 12:21:38 +02:00
|
|
|
typ = env.temp_data.get('default_role')
|
|
|
|
|
if not typ:
|
|
|
|
|
typ = env.config.default_role
|
|
|
|
|
if not typ:
|
|
|
|
|
raise SphinxError('cannot determine default role!')
|
2009-08-09 20:27:36 +02:00
|
|
|
else:
|
|
|
|
|
typ = typ.lower()
|
|
|
|
|
if ':' not in typ:
|
2017-02-10 15:53:42 +09:00
|
|
|
domain, role = '', typ # type: unicode, unicode
|
2010-02-28 10:19:36 +01:00
|
|
|
classes = ['xref', role]
|
2009-08-09 20:27:36 +02:00
|
|
|
else:
|
|
|
|
|
domain, role = typ.split(':', 1)
|
2010-02-28 10:19:36 +01:00
|
|
|
classes = ['xref', domain, '%s-%s' % (domain, role)]
|
2009-08-09 20:27:36 +02:00
|
|
|
# if the first character is a bang, don't cross-reference at all
|
|
|
|
|
if text[0:1] == '!':
|
2010-08-05 10:14:10 +02:00
|
|
|
text = utils.unescape(text)[1:]
|
2009-08-09 20:27:36 +02:00
|
|
|
if self.fix_parens:
|
2010-08-05 10:14:10 +02:00
|
|
|
text, tgt = self._fix_parens(env, False, text, "")
|
2010-02-28 10:17:59 +01:00
|
|
|
innernode = self.innernodeclass(rawtext, text, classes=classes)
|
2009-09-10 21:58:05 +02:00
|
|
|
return self.result_nodes(inliner.document, env, innernode,
|
|
|
|
|
is_ref=False)
|
2009-08-09 20:27:36 +02:00
|
|
|
# split title and target in role content
|
|
|
|
|
has_explicit_title, title, target = split_explicit_title(text)
|
2010-03-01 14:36:08 +01:00
|
|
|
title = utils.unescape(title)
|
2010-03-01 14:58:36 +01:00
|
|
|
target = utils.unescape(target)
|
2009-09-09 19:35:50 +02:00
|
|
|
# fix-up title and target
|
2009-09-08 00:49:52 +02:00
|
|
|
if self.lowercase:
|
|
|
|
|
target = target.lower()
|
|
|
|
|
if self.fix_parens:
|
2009-09-10 21:58:05 +02:00
|
|
|
title, target = self._fix_parens(
|
2009-09-09 19:35:50 +02:00
|
|
|
env, has_explicit_title, title, target)
|
|
|
|
|
# create the reference node
|
|
|
|
|
refnode = self.nodeclass(rawtext, reftype=role, refdomain=domain,
|
|
|
|
|
refexplicit=has_explicit_title)
|
|
|
|
|
# we may need the line number for warnings
|
2017-02-10 15:53:42 +09:00
|
|
|
set_role_source_info(inliner, lineno, refnode) # type: ignore
|
2009-09-09 19:35:50 +02:00
|
|
|
title, target = self.process_link(
|
|
|
|
|
env, refnode, has_explicit_title, title, target)
|
|
|
|
|
# now that the target and title are finally determined, set them
|
|
|
|
|
refnode['reftarget'] = target
|
2010-02-28 10:17:59 +01:00
|
|
|
refnode += self.innernodeclass(rawtext, title, classes=classes)
|
2010-01-07 19:17:45 +01:00
|
|
|
# we also need the source document
|
|
|
|
|
refnode['refdoc'] = env.docname
|
2011-01-08 16:41:15 +01:00
|
|
|
refnode['refwarn'] = self.warn_dangling
|
2009-09-09 19:35:50 +02:00
|
|
|
# result_nodes allow further modification of return values
|
2009-09-10 21:58:05 +02:00
|
|
|
return self.result_nodes(inliner.document, env, refnode, is_ref=True)
|
2009-09-09 19:35:50 +02:00
|
|
|
|
|
|
|
|
# methods that can be overwritten
|
|
|
|
|
|
|
|
|
|
def process_link(self, env, refnode, has_explicit_title, title, target):
|
2017-02-10 15:53:42 +09:00
|
|
|
# type: (BuildEnvironment, nodes.reference, bool, unicode, unicode) -> Tuple[unicode, unicode] # NOQA
|
2010-08-22 11:36:08 +02:00
|
|
|
"""Called after parsing title and target text, and creating the
|
|
|
|
|
reference node (given in *refnode*). This method can alter the
|
|
|
|
|
reference node and must return a new (or the same) ``(title, target)``
|
|
|
|
|
tuple.
|
2009-09-12 13:39:40 +00:00
|
|
|
"""
|
2009-09-09 19:35:50 +02:00
|
|
|
return title, ws_re.sub(' ', target)
|
2009-08-09 20:27:36 +02:00
|
|
|
|
2009-09-10 21:58:05 +02:00
|
|
|
def result_nodes(self, document, env, node, is_ref):
|
2017-02-10 15:53:42 +09:00
|
|
|
# type: (nodes.document, BuildEnvironment, nodes.Node, bool) -> Tuple[List[nodes.Node], List[nodes.Node]] # NOQA
|
2010-08-22 11:36:08 +02:00
|
|
|
"""Called before returning the finished nodes. *node* is the reference
|
2009-09-12 13:39:40 +00:00
|
|
|
node if one was created (*is_ref* is then true), else the content node.
|
|
|
|
|
This method can add other nodes and must return a ``(nodes, messages)``
|
|
|
|
|
tuple (the usual return value of a role function).
|
|
|
|
|
"""
|
2009-09-09 19:35:50 +02:00
|
|
|
return [node], []
|
2009-08-09 20:27:36 +02:00
|
|
|
|
|
|
|
|
|
2014-09-20 19:23:25 +02:00
|
|
|
class AnyXRefRole(XRefRole):
|
|
|
|
|
def process_link(self, env, refnode, has_explicit_title, title, target):
|
2017-02-10 15:53:42 +09:00
|
|
|
# type: (BuildEnvironment, nodes.reference, bool, unicode, unicode) -> Tuple[unicode, unicode] # NOQA
|
2014-09-20 19:23:25 +02:00
|
|
|
result = XRefRole.process_link(self, env, refnode, has_explicit_title,
|
|
|
|
|
title, target)
|
|
|
|
|
# add all possible context info (i.e. std:program, py:module etc.)
|
|
|
|
|
refnode.attributes.update(env.ref_context)
|
|
|
|
|
return result
|
|
|
|
|
|
|
|
|
|
|
2017-03-03 12:19:09 +09:00
|
|
|
def indexmarkup_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
|
2017-02-10 15:53:42 +09:00
|
|
|
# type: (unicode, unicode, unicode, int, Inliner, Dict, List[unicode]) -> Tuple[List[nodes.Node], List[nodes.Node]] # NOQA
|
2009-09-12 13:39:40 +00:00
|
|
|
"""Role for PEP/RFC references that generate an index entry."""
|
2007-07-23 09:02:25 +00:00
|
|
|
env = inliner.document.settings.env
|
2008-06-17 10:06:37 +00:00
|
|
|
if not typ:
|
2017-07-29 16:49:34 +09:00
|
|
|
assert env.temp_data['default_role']
|
|
|
|
|
typ = env.temp_data['default_role'].lower()
|
2008-10-16 20:41:05 +00:00
|
|
|
else:
|
|
|
|
|
typ = typ.lower()
|
2017-02-10 15:53:42 +09:00
|
|
|
has_explicit_title, title, target = split_explicit_title(text)
|
2014-08-20 12:27:08 +09:00
|
|
|
title = utils.unescape(title)
|
|
|
|
|
target = utils.unescape(target)
|
2009-09-07 22:52:26 +02:00
|
|
|
targetid = 'index-%s' % env.new_serialno('index')
|
2007-12-16 23:14:24 +00:00
|
|
|
indexnode = addnodes.index()
|
2007-07-23 09:02:25 +00:00
|
|
|
targetnode = nodes.target('', '', ids=[targetid])
|
|
|
|
|
inliner.document.note_explicit_target(targetnode)
|
2009-09-09 19:35:50 +02:00
|
|
|
if typ == 'pep':
|
2009-01-10 21:23:39 +01:00
|
|
|
indexnode['entries'] = [
|
2014-08-20 12:27:08 +09:00
|
|
|
('single', _('Python Enhancement Proposals; PEP %s') % target,
|
2016-02-13 22:30:06 +09:00
|
|
|
targetid, '', None)]
|
2016-11-08 14:05:58 +09:00
|
|
|
anchor = '' # type: unicode
|
2014-08-20 12:27:08 +09:00
|
|
|
anchorindex = target.find('#')
|
2010-08-05 15:42:15 +02:00
|
|
|
if anchorindex > 0:
|
2014-08-20 12:27:08 +09:00
|
|
|
target, anchor = target[:anchorindex], target[anchorindex:]
|
|
|
|
|
if not has_explicit_title:
|
|
|
|
|
title = "PEP " + utils.unescape(title)
|
2007-07-23 09:02:25 +00:00
|
|
|
try:
|
2014-08-20 12:27:08 +09:00
|
|
|
pepnum = int(target)
|
2007-07-23 09:02:25 +00:00
|
|
|
except ValueError:
|
2014-08-20 12:27:08 +09:00
|
|
|
msg = inliner.reporter.error('invalid PEP number %s' % target,
|
2009-01-10 21:23:39 +01:00
|
|
|
line=lineno)
|
2007-07-23 09:02:25 +00:00
|
|
|
prb = inliner.problematic(rawtext, rawtext, msg)
|
|
|
|
|
return [prb], [msg]
|
|
|
|
|
ref = inliner.document.settings.pep_base_url + 'pep-%04d' % pepnum
|
2014-08-20 12:27:08 +09:00
|
|
|
sn = nodes.strong(title, title)
|
2017-01-12 10:07:05 +09:00
|
|
|
rn = nodes.reference('', '', internal=False, refuri=ref + anchor,
|
2010-08-05 15:42:15 +02:00
|
|
|
classes=[typ])
|
2007-07-23 09:02:25 +00:00
|
|
|
rn += sn
|
2007-12-16 23:14:24 +00:00
|
|
|
return [indexnode, targetnode, rn], []
|
2007-07-23 09:02:25 +00:00
|
|
|
elif typ == 'rfc':
|
2016-02-13 22:30:06 +09:00
|
|
|
indexnode['entries'] = [
|
|
|
|
|
('single', 'RFC; RFC %s' % target, targetid, '', None)]
|
2010-08-05 15:42:15 +02:00
|
|
|
anchor = ''
|
2014-08-20 12:27:08 +09:00
|
|
|
anchorindex = target.find('#')
|
2010-08-05 15:42:15 +02:00
|
|
|
if anchorindex > 0:
|
2014-08-20 12:27:08 +09:00
|
|
|
target, anchor = target[:anchorindex], target[anchorindex:]
|
|
|
|
|
if not has_explicit_title:
|
|
|
|
|
title = "RFC " + utils.unescape(title)
|
2007-07-23 09:02:25 +00:00
|
|
|
try:
|
2014-08-20 12:27:08 +09:00
|
|
|
rfcnum = int(target)
|
2007-07-23 09:02:25 +00:00
|
|
|
except ValueError:
|
2014-08-20 12:27:08 +09:00
|
|
|
msg = inliner.reporter.error('invalid RFC number %s' % target,
|
2009-01-10 21:23:39 +01:00
|
|
|
line=lineno)
|
2007-07-23 09:02:25 +00:00
|
|
|
prb = inliner.problematic(rawtext, rawtext, msg)
|
|
|
|
|
return [prb], [msg]
|
|
|
|
|
ref = inliner.document.settings.rfc_base_url + inliner.rfc_url % rfcnum
|
2014-08-20 12:27:08 +09:00
|
|
|
sn = nodes.strong(title, title)
|
2017-01-12 10:07:05 +09:00
|
|
|
rn = nodes.reference('', '', internal=False, refuri=ref + anchor,
|
2010-08-05 15:42:15 +02:00
|
|
|
classes=[typ])
|
2007-07-23 09:02:25 +00:00
|
|
|
rn += sn
|
2007-12-16 23:14:24 +00:00
|
|
|
return [indexnode, targetnode, rn], []
|
2017-03-03 12:19:09 +09:00
|
|
|
else:
|
|
|
|
|
raise ValueError('unknown role type: %s' % typ)
|
2007-07-23 09:02:25 +00:00
|
|
|
|
|
|
|
|
|
2010-05-24 12:57:07 +02:00
|
|
|
_amp_re = re.compile(r'(?<!&)&(?![&\s])')
|
2007-08-01 14:09:18 +00:00
|
|
|
|
2014-09-21 20:21:43 +02:00
|
|
|
|
2010-04-26 23:02:18 -07:00
|
|
|
def menusel_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
|
2017-02-10 15:53:42 +09:00
|
|
|
# type: (unicode, unicode, unicode, int, Inliner, Dict, List[unicode]) -> Tuple[List[nodes.Node], List[nodes.Node]] # NOQA
|
2010-07-21 11:33:24 +01:00
|
|
|
text = utils.unescape(text)
|
2010-04-26 23:02:18 -07:00
|
|
|
if typ == 'menuselection':
|
2010-07-21 11:33:24 +01:00
|
|
|
text = text.replace('-->', u'\N{TRIANGULAR BULLET}')
|
2017-02-10 15:53:42 +09:00
|
|
|
spans = _amp_re.split(text) # type: ignore
|
2010-04-26 23:02:18 -07:00
|
|
|
|
2015-02-25 15:51:47 +01:00
|
|
|
node = nodes.inline(rawtext=rawtext)
|
2010-04-26 23:02:18 -07:00
|
|
|
for i, span in enumerate(spans):
|
|
|
|
|
span = span.replace('&&', '&')
|
|
|
|
|
if i == 0:
|
|
|
|
|
if len(span) > 0:
|
|
|
|
|
textnode = nodes.Text(span)
|
|
|
|
|
node += textnode
|
|
|
|
|
continue
|
2010-04-27 20:09:11 -07:00
|
|
|
accel_node = nodes.inline()
|
2010-04-26 23:02:18 -07:00
|
|
|
letter_node = nodes.Text(span[0])
|
2010-04-27 20:09:11 -07:00
|
|
|
accel_node += letter_node
|
|
|
|
|
accel_node['classes'].append('accelerator')
|
|
|
|
|
node += accel_node
|
2010-04-26 23:02:18 -07:00
|
|
|
textnode = nodes.Text(span[1:])
|
|
|
|
|
node += textnode
|
|
|
|
|
|
|
|
|
|
node['classes'].append(typ)
|
|
|
|
|
return [node], []
|
2007-08-01 14:09:18 +00:00
|
|
|
|
2014-09-20 19:16:26 +02:00
|
|
|
|
2007-08-06 10:49:52 +00:00
|
|
|
_litvar_re = re.compile('{([^}]+)}')
|
2007-08-01 14:09:18 +00:00
|
|
|
|
2014-09-21 20:21:43 +02:00
|
|
|
|
2009-01-10 21:23:39 +01:00
|
|
|
def emph_literal_role(typ, rawtext, text, lineno, inliner,
|
|
|
|
|
options={}, content=[]):
|
2017-02-10 15:53:42 +09:00
|
|
|
# type: (unicode, unicode, unicode, int, Inliner, Dict, List[unicode]) -> Tuple[List[nodes.Node], List[nodes.Node]] # NOQA
|
2007-08-01 14:09:18 +00:00
|
|
|
text = utils.unescape(text)
|
|
|
|
|
pos = 0
|
2010-02-28 10:17:59 +01:00
|
|
|
retnode = nodes.literal(role=typ.lower(), classes=[typ])
|
2017-02-10 15:53:42 +09:00
|
|
|
for m in _litvar_re.finditer(text): # type: ignore
|
2007-08-01 14:09:18 +00:00
|
|
|
if m.start() > pos:
|
|
|
|
|
txt = text[pos:m.start()]
|
Merged revisions 64808,65013,65076,65100-65101,65119,65121-65123 via svnmerge from
svn+ssh://pythondev@svn.python.org/doctools/branches/0.4.x
........
r64808 | georg.brandl | 2008-07-08 21:39:33 +0200 (Tue, 08 Jul 2008) | 2 lines
Allow relocation of source and doctree dir.
........
r65013 | georg.brandl | 2008-07-16 15:25:30 +0200 (Wed, 16 Jul 2008) | 2 lines
Remove curious quote.
........
r65076 | georg.brandl | 2008-07-17 22:43:01 +0200 (Thu, 17 Jul 2008) | 2 lines
Add a test for sphinx.quickstart.
........
r65100 | georg.brandl | 2008-07-18 14:41:54 +0200 (Fri, 18 Jul 2008) | 2 lines
Fix phony targets.
........
r65101 | georg.brandl | 2008-07-18 14:55:03 +0200 (Fri, 18 Jul 2008) | 2 lines
Fix problems in "make check".
........
r65119 | georg.brandl | 2008-07-18 23:06:42 +0200 (Fri, 18 Jul 2008) | 2 lines
Emit a more precise error message in autodoc.
........
r65121 | georg.brandl | 2008-07-18 23:41:35 +0200 (Fri, 18 Jul 2008) | 2 lines
Warn if a toctree-included document doesn't contain a title.
........
r65122 | georg.brandl | 2008-07-18 23:51:28 +0200 (Fri, 18 Jul 2008) | 2 lines
Don't use \samp{} for code with whitespaces, only for :samp:`code`.
........
r65123 | georg.brandl | 2008-07-19 00:49:46 +0200 (Sat, 19 Jul 2008) | 2 lines
Put inheritance info always on its own line.
........
2008-07-18 22:55:36 +00:00
|
|
|
retnode += nodes.Text(txt, txt)
|
|
|
|
|
retnode += nodes.emphasis(m.group(1), m.group(1))
|
2007-08-01 14:09:18 +00:00
|
|
|
pos = m.end()
|
|
|
|
|
if pos < len(text):
|
Merged revisions 64808,65013,65076,65100-65101,65119,65121-65123 via svnmerge from
svn+ssh://pythondev@svn.python.org/doctools/branches/0.4.x
........
r64808 | georg.brandl | 2008-07-08 21:39:33 +0200 (Tue, 08 Jul 2008) | 2 lines
Allow relocation of source and doctree dir.
........
r65013 | georg.brandl | 2008-07-16 15:25:30 +0200 (Wed, 16 Jul 2008) | 2 lines
Remove curious quote.
........
r65076 | georg.brandl | 2008-07-17 22:43:01 +0200 (Thu, 17 Jul 2008) | 2 lines
Add a test for sphinx.quickstart.
........
r65100 | georg.brandl | 2008-07-18 14:41:54 +0200 (Fri, 18 Jul 2008) | 2 lines
Fix phony targets.
........
r65101 | georg.brandl | 2008-07-18 14:55:03 +0200 (Fri, 18 Jul 2008) | 2 lines
Fix problems in "make check".
........
r65119 | georg.brandl | 2008-07-18 23:06:42 +0200 (Fri, 18 Jul 2008) | 2 lines
Emit a more precise error message in autodoc.
........
r65121 | georg.brandl | 2008-07-18 23:41:35 +0200 (Fri, 18 Jul 2008) | 2 lines
Warn if a toctree-included document doesn't contain a title.
........
r65122 | georg.brandl | 2008-07-18 23:51:28 +0200 (Fri, 18 Jul 2008) | 2 lines
Don't use \samp{} for code with whitespaces, only for :samp:`code`.
........
r65123 | georg.brandl | 2008-07-19 00:49:46 +0200 (Sat, 19 Jul 2008) | 2 lines
Put inheritance info always on its own line.
........
2008-07-18 22:55:36 +00:00
|
|
|
retnode += nodes.Text(text[pos:], text[pos:])
|
|
|
|
|
return [retnode], []
|
2007-07-23 09:02:25 +00:00
|
|
|
|
|
|
|
|
|
2017-02-13 02:02:51 +09:00
|
|
|
_abbr_re = re.compile(r'\((.*)\)$', re.S)
|
2009-03-05 09:48:55 +01:00
|
|
|
|
2014-09-21 20:21:43 +02:00
|
|
|
|
2009-03-05 09:48:55 +01:00
|
|
|
def abbr_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
|
2017-02-10 15:53:42 +09:00
|
|
|
# type: (unicode, unicode, unicode, int, Inliner, Dict, List[unicode]) -> Tuple[List[nodes.Node], List[nodes.Node]] # NOQA
|
2009-03-05 09:48:55 +01:00
|
|
|
text = utils.unescape(text)
|
2017-02-10 15:53:42 +09:00
|
|
|
m = _abbr_re.search(text) # type: ignore
|
2009-03-05 09:48:55 +01:00
|
|
|
if m is None:
|
2014-07-26 07:21:20 +02:00
|
|
|
return [addnodes.abbreviation(text, text, **options)], []
|
2009-03-05 09:48:55 +01:00
|
|
|
abbr = text[:m.start()].strip()
|
|
|
|
|
expl = m.group(1)
|
2014-07-26 07:21:20 +02:00
|
|
|
options = options.copy()
|
|
|
|
|
options['explanation'] = expl
|
|
|
|
|
return [addnodes.abbreviation(abbr, abbr, **options)], []
|
2009-03-05 09:48:55 +01:00
|
|
|
|
|
|
|
|
|
2010-08-25 11:33:30 +00:00
|
|
|
def index_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
|
2017-02-10 15:53:42 +09:00
|
|
|
# type: (unicode, unicode, unicode, int, Inliner, Dict, List[unicode]) -> Tuple[List[nodes.Node], List[nodes.Node]] # NOQA
|
2010-08-25 11:33:30 +00:00
|
|
|
# create new reference target
|
|
|
|
|
env = inliner.document.settings.env
|
|
|
|
|
targetid = 'index-%s' % env.new_serialno('index')
|
|
|
|
|
targetnode = nodes.target('', '', ids=[targetid])
|
|
|
|
|
# split text and target in role content
|
|
|
|
|
has_explicit_title, title, target = split_explicit_title(text)
|
|
|
|
|
title = utils.unescape(title)
|
|
|
|
|
target = utils.unescape(target)
|
|
|
|
|
# if an explicit target is given, we can process it as a full entry
|
|
|
|
|
if has_explicit_title:
|
|
|
|
|
entries = process_index_entry(target, targetid)
|
|
|
|
|
# otherwise we just create a "single" entry
|
|
|
|
|
else:
|
2011-01-07 19:00:29 +01:00
|
|
|
# but allow giving main entry
|
|
|
|
|
main = ''
|
|
|
|
|
if target.startswith('!'):
|
|
|
|
|
target = target[1:]
|
|
|
|
|
title = title[1:]
|
|
|
|
|
main = 'main'
|
2016-02-13 22:30:06 +09:00
|
|
|
entries = [('single', target, targetid, main, None)]
|
2010-08-25 11:33:30 +00:00
|
|
|
indexnode = addnodes.index()
|
|
|
|
|
indexnode['entries'] = entries
|
2017-02-10 15:53:42 +09:00
|
|
|
set_role_source_info(inliner, lineno, indexnode) # type: ignore
|
2010-08-25 11:33:30 +00:00
|
|
|
textnode = nodes.Text(title, title)
|
|
|
|
|
return [indexnode, targetnode, textnode], []
|
|
|
|
|
|
|
|
|
|
|
2007-07-23 09:02:25 +00:00
|
|
|
specific_docroles = {
|
2009-09-09 19:35:50 +02:00
|
|
|
# links to download references
|
|
|
|
|
'download': XRefRole(nodeclass=addnodes.download_reference),
|
2014-09-19 12:59:18 +02:00
|
|
|
# links to anything
|
2014-09-20 19:23:25 +02:00
|
|
|
'any': AnyXRefRole(warn_dangling=True),
|
2007-07-23 09:02:25 +00:00
|
|
|
|
2009-08-09 20:27:36 +02:00
|
|
|
'pep': indexmarkup_role,
|
|
|
|
|
'rfc': indexmarkup_role,
|
2010-04-26 23:02:18 -07:00
|
|
|
'guilabel': menusel_role,
|
2008-11-09 18:28:36 +01:00
|
|
|
'menuselection': menusel_role,
|
|
|
|
|
'file': emph_literal_role,
|
|
|
|
|
'samp': emph_literal_role,
|
2009-03-05 09:48:55 +01:00
|
|
|
'abbr': abbr_role,
|
2010-08-25 11:33:30 +00:00
|
|
|
'index': index_role,
|
2007-07-23 09:02:25 +00:00
|
|
|
}
|
|
|
|
|
|
2016-07-28 11:23:10 +09:00
|
|
|
|
|
|
|
|
def setup(app):
|
2017-02-10 15:53:42 +09:00
|
|
|
# type: (Sphinx) -> Dict[unicode, Any]
|
2016-07-28 11:23:10 +09:00
|
|
|
from docutils.parsers.rst import roles
|
|
|
|
|
|
|
|
|
|
for rolename, nodeclass in iteritems(generic_docroles):
|
|
|
|
|
generic = roles.GenericRole(rolename, nodeclass)
|
|
|
|
|
role = roles.CustomRole(rolename, generic, {'classes': [rolename]})
|
|
|
|
|
roles.register_local_role(rolename, role)
|
|
|
|
|
|
|
|
|
|
for rolename, func in iteritems(specific_docroles):
|
|
|
|
|
roles.register_local_role(rolename, func)
|
2016-12-12 21:22:16 +09:00
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
'version': 'builtin',
|
|
|
|
|
'parallel_read_safe': True,
|
|
|
|
|
'parallel_write_safe': True,
|
|
|
|
|
}
|