mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Add mypy annotations
This commit is contained in:
parent
82e011cae6
commit
da6f4c0019
@ -60,6 +60,7 @@ if __version__.endswith('+'):
|
||||
|
||||
|
||||
def main(argv=sys.argv):
|
||||
# type: (List[str]) -> None
|
||||
if sys.argv[1:2] == ['-M']:
|
||||
sys.exit(make_main(argv))
|
||||
else:
|
||||
@ -67,6 +68,7 @@ def main(argv=sys.argv):
|
||||
|
||||
|
||||
def build_main(argv=sys.argv):
|
||||
# type: (List[str]) -> int
|
||||
"""Sphinx build "main" command-line entry."""
|
||||
if (sys.version_info[:3] < (2, 7, 0) or
|
||||
(3, 0, 0) <= sys.version_info[:3] < (3, 4, 0)):
|
||||
@ -104,14 +106,15 @@ def build_main(argv=sys.argv):
|
||||
sys.stderr.write('Error: Sphinx requires at least Docutils 0.10 to '
|
||||
'run.\n')
|
||||
return 1
|
||||
return cmdline.main(argv)
|
||||
return cmdline.main(argv) # type: ignore
|
||||
|
||||
|
||||
def make_main(argv=sys.argv):
|
||||
# type: (List[str]) -> int
|
||||
"""Sphinx build "make mode" entry."""
|
||||
from sphinx import make_mode
|
||||
return make_mode.run_make_mode(argv[2:])
|
||||
return make_mode.run_make_mode(argv[2:]) # type: ignore
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main(sys.argv))
|
||||
sys.exit(main(sys.argv)) # type: ignore
|
||||
|
@ -621,7 +621,7 @@ class StandaloneHTMLBuilder(Builder):
|
||||
ensuredir(path.join(self.outdir, '_static'))
|
||||
# first, create pygments style file
|
||||
with open(path.join(self.outdir, '_static', 'pygments.css'), 'w') as f:
|
||||
f.write(self.highlighter.get_stylesheet())
|
||||
f.write(self.highlighter.get_stylesheet()) # type: ignore
|
||||
# then, copy translations JavaScript file
|
||||
if self.config.language is not None:
|
||||
jsfile = self._get_translations_js()
|
||||
|
@ -104,7 +104,7 @@ class LaTeXBuilder(Builder):
|
||||
f.write('\\NeedsTeXFormat{LaTeX2e}[1995/12/01]\n')
|
||||
f.write('\\ProvidesPackage{sphinxhighlight}'
|
||||
'[2016/05/29 stylesheet for highlighting with pygments]\n\n')
|
||||
f.write(highlighter.get_stylesheet())
|
||||
f.write(highlighter.get_stylesheet()) # type: ignore
|
||||
|
||||
def write(self, *ignored):
|
||||
# type: (Any) -> None
|
||||
|
@ -21,6 +21,7 @@ if False:
|
||||
# For type annotation
|
||||
from typing import Any, Callable, Iterable, Tuple, Type, Union # NOQA
|
||||
from docutils import nodes # NOQA
|
||||
from docutils.parsers.rst.states import Inliner # NOQA
|
||||
from sphinx.builders import Builder # NOQA
|
||||
from sphinx.environment import BuildEnvironment # NOQA
|
||||
|
||||
@ -189,8 +190,8 @@ class Domain(object):
|
||||
return None
|
||||
fullname = '%s:%s' % (self.name, name)
|
||||
|
||||
def role_adapter(typ, rawtext, text, lineno, inliner,
|
||||
options={}, content=[]):
|
||||
def role_adapter(typ, rawtext, text, lineno, inliner, options={}, content=[]):
|
||||
# type: (unicode, unicode, unicode, int, Inliner, Dict, List[unicode]) -> nodes.Node # NOQA
|
||||
return self.roles[name](fullname, rawtext, text, lineno,
|
||||
inliner, options, content)
|
||||
self._role_cache[name] = role_adapter
|
||||
@ -210,6 +211,7 @@ class Domain(object):
|
||||
|
||||
class DirectiveAdapter(BaseDirective): # type: ignore
|
||||
def run(self):
|
||||
# type: () -> List[nodes.Node]
|
||||
self.name = fullname
|
||||
return BaseDirective.run(self)
|
||||
self._directive_cache[name] = DirectiveAdapter
|
||||
|
@ -895,6 +895,7 @@ class StandardDomain(Domain):
|
||||
# type: (nodes.Node) -> unicode
|
||||
"""Get figure type of nodes."""
|
||||
def has_child(node, cls):
|
||||
# type: (nodes.Node, Type) -> bool
|
||||
return any(isinstance(child, cls) for child in node)
|
||||
|
||||
if isinstance(node, nodes.section):
|
||||
|
@ -746,7 +746,7 @@ class BuildEnvironment(object):
|
||||
|
||||
@property
|
||||
def currmodule(self):
|
||||
# type () -> None
|
||||
# type: () -> None
|
||||
"""Backwards compatible alias. Will be removed."""
|
||||
logger.warning('env.currmodule is being referenced by an '
|
||||
'extension; this API will be removed in the future',
|
||||
@ -1024,6 +1024,7 @@ class BuildEnvironment(object):
|
||||
traversed = set()
|
||||
|
||||
def traverse_toctree(parent, docname):
|
||||
# type: (unicode, unicode) -> Iterator[Tuple[unicode, unicode]]
|
||||
if parent == docname:
|
||||
logger.warning('self referenced toctree found. Ignored.', location=docname)
|
||||
return
|
||||
|
@ -42,6 +42,7 @@ class IndexEntries(object):
|
||||
new = {} # type: Dict[unicode, List]
|
||||
|
||||
def add_entry(word, subword, main, link=True, dic=new, key=None):
|
||||
# type: (unicode, unicode, unicode, bool, Dict, unicode) -> None
|
||||
# Force the word to be unicode if it's a ASCII bytestring.
|
||||
# This will solve problems with unicode normalization later.
|
||||
# For instance the RFC role will add bytestrings at the moment
|
||||
@ -96,6 +97,7 @@ class IndexEntries(object):
|
||||
# sort the index entries; put all symbols at the front, even those
|
||||
# following the letters in ASCII, this is where the chr(127) comes from
|
||||
def keyfunc(entry, lcletters=string.ascii_lowercase + '_'):
|
||||
# type: (Tuple[unicode, List], unicode) -> Tuple[unicode, unicode]
|
||||
key, (void, void, category_key) = entry
|
||||
if category_key:
|
||||
# using specified category key to sort
|
||||
@ -140,6 +142,7 @@ class IndexEntries(object):
|
||||
|
||||
# group the entries by letter
|
||||
def keyfunc2(item, letters=string.ascii_uppercase + '_'):
|
||||
# type: (Tuple[unicode, List], unicode) -> unicode
|
||||
# hack: mutating the subitems dicts to a list in the keyfunc
|
||||
k, v = item
|
||||
v[1] = sorted((si, se) for (si, (se, void, void)) in iteritems(v[1]))
|
||||
|
@ -85,6 +85,7 @@ class TocTree(object):
|
||||
toctree_ancestors = self.get_toctree_ancestors(docname)
|
||||
|
||||
def _toctree_add_classes(node, depth):
|
||||
# type: (nodes.Node, int) -> None
|
||||
"""Add 'toctree-l%d' and 'current' classes to the toctree."""
|
||||
for subnode in node.children:
|
||||
if isinstance(subnode, (addnodes.compact_paragraph,
|
||||
@ -114,8 +115,8 @@ class TocTree(object):
|
||||
subnode['iscurrent'] = True
|
||||
subnode = subnode.parent
|
||||
|
||||
def _entries_from_toctree(toctreenode, parents,
|
||||
separate=False, subtree=False):
|
||||
def _entries_from_toctree(toctreenode, parents, separate=False, subtree=False):
|
||||
# type: (addnodes.toctree, List[nodes.Node], bool, bool) -> List[nodes.Node]
|
||||
"""Return TOC entries for a toctree node."""
|
||||
refs = [(e[0], e[1]) for e in toctreenode['entries']]
|
||||
entries = []
|
||||
|
@ -975,6 +975,7 @@ class Documenter(object):
|
||||
tagorder = self.analyzer.tagorder
|
||||
|
||||
def keyfunc(entry):
|
||||
# type: (Tuple[Documenter, bool]) -> int
|
||||
fullname = entry[0].name.split('::')[1]
|
||||
return tagorder.get(fullname, len(tagorder))
|
||||
memberdocumenters.sort(key=keyfunc)
|
||||
@ -1828,7 +1829,9 @@ class testcls:
|
||||
"""test doc string"""
|
||||
|
||||
def __getattr__(self, x):
|
||||
# type: (Any) -> Any
|
||||
return x
|
||||
|
||||
def __setattr__(self, x, y):
|
||||
# type: (Any, Any) -> None
|
||||
"""Attr setter."""
|
||||
|
@ -58,6 +58,7 @@ else:
|
||||
|
||||
|
||||
def compare_version(ver1, ver2, operand):
|
||||
# type: (unicode, unicode, unicode) -> bool
|
||||
"""Compare `ver1` to `ver2`, relying on `operand`.
|
||||
|
||||
Some examples:
|
||||
|
@ -27,6 +27,12 @@ from pygments.styles import get_style_by_name
|
||||
from pygments.util import ClassNotFound
|
||||
from sphinx.pygments_styles import SphinxStyle, NoneStyle
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
from typing import Any # NOQA
|
||||
from pygments.formatter import Formatter # NOQA
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
lexers = dict(
|
||||
@ -59,8 +65,8 @@ class PygmentsBridge(object):
|
||||
html_formatter = HtmlFormatter
|
||||
latex_formatter = LatexFormatter
|
||||
|
||||
def __init__(self, dest='html', stylename='sphinx',
|
||||
trim_doctest_flags=False):
|
||||
def __init__(self, dest='html', stylename='sphinx', trim_doctest_flags=False):
|
||||
# type: (unicode, unicode, bool) -> None
|
||||
self.dest = dest
|
||||
if stylename is None or stylename == 'sphinx':
|
||||
style = SphinxStyle
|
||||
@ -73,7 +79,7 @@ class PygmentsBridge(object):
|
||||
else:
|
||||
style = get_style_by_name(stylename)
|
||||
self.trim_doctest_flags = trim_doctest_flags
|
||||
self.formatter_args = {'style': style}
|
||||
self.formatter_args = {'style': style} # type: Dict[unicode, Any]
|
||||
if dest == 'html':
|
||||
self.formatter = self.html_formatter
|
||||
else:
|
||||
@ -81,10 +87,12 @@ class PygmentsBridge(object):
|
||||
self.formatter_args['commandprefix'] = 'PYG'
|
||||
|
||||
def get_formatter(self, **kwargs):
|
||||
kwargs.update(self.formatter_args)
|
||||
# type: (Any) -> Formatter
|
||||
kwargs.update(self.formatter_args) # type: ignore
|
||||
return self.formatter(**kwargs)
|
||||
|
||||
def unhighlighted(self, source):
|
||||
# type: (unicode) -> unicode
|
||||
if self.dest == 'html':
|
||||
return '<pre>' + htmlescape(source) + '</pre>\n'
|
||||
else:
|
||||
@ -96,6 +104,7 @@ class PygmentsBridge(object):
|
||||
source + '\\end{Verbatim}\n'
|
||||
|
||||
def highlight_block(self, source, lang, opts=None, location=None, force=False, **kwargs):
|
||||
# type: (unicode, unicode, Any, Any, bool, Any) -> unicode
|
||||
if not isinstance(source, text_type):
|
||||
source = source.decode()
|
||||
|
||||
@ -131,8 +140,8 @@ class PygmentsBridge(object):
|
||||
|
||||
# trim doctest options if wanted
|
||||
if isinstance(lexer, PythonConsoleLexer) and self.trim_doctest_flags:
|
||||
source = doctest.blankline_re.sub('', source)
|
||||
source = doctest.doctestopt_re.sub('', source)
|
||||
source = doctest.blankline_re.sub('', source) # type: ignore
|
||||
source = doctest.doctestopt_re.sub('', source) # type: ignore
|
||||
|
||||
# highlight via Pygments
|
||||
formatter = self.get_formatter(**kwargs)
|
||||
@ -157,6 +166,7 @@ class PygmentsBridge(object):
|
||||
return hlsource.translate(tex_hl_escape_map_new)
|
||||
|
||||
def get_stylesheet(self):
|
||||
# type: () -> unicode
|
||||
formatter = self.get_formatter()
|
||||
if self.dest == 'html':
|
||||
return formatter.get_style_defs('.highlight')
|
||||
|
@ -113,6 +113,7 @@ class SphinxFileSystemLoader(FileSystemLoader):
|
||||
mtime = path.getmtime(filename)
|
||||
|
||||
def uptodate():
|
||||
# type: () -> bool
|
||||
try:
|
||||
return path.getmtime(filename) == mtime
|
||||
except OSError:
|
||||
|
@ -16,7 +16,7 @@ from six.moves import UserString
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
from typing import Any, Tuple # NOQA
|
||||
from typing import Any, Callable, Iterator, Tuple # NOQA
|
||||
|
||||
|
||||
class _TranslationProxy(UserString, object):
|
||||
@ -35,24 +35,31 @@ class _TranslationProxy(UserString, object):
|
||||
__slots__ = ('_func', '_args')
|
||||
|
||||
def __new__(cls, func, *args):
|
||||
# type: (Callable, unicode) -> object
|
||||
if not args:
|
||||
# not called with "function" and "arguments", but a plain string
|
||||
return text_type(func)
|
||||
return object.__new__(cls)
|
||||
return object.__new__(cls) # type: ignore
|
||||
|
||||
def __getnewargs__(self):
|
||||
return (self._func,) + self._args
|
||||
# type: () -> Tuple
|
||||
return (self._func,) + self._args # type: ignore
|
||||
|
||||
def __init__(self, func, *args):
|
||||
# type: (Callable, unicode) -> None
|
||||
self._func = func
|
||||
self._args = args
|
||||
|
||||
data = property(lambda x: x._func(*x._args))
|
||||
@property
|
||||
def data(self):
|
||||
# type: () -> unicode
|
||||
return self._func(*self._args)
|
||||
|
||||
# replace function from UserString; it instantiates a self.__class__
|
||||
# for the encoding result
|
||||
|
||||
def encode(self, encoding=None, errors=None):
|
||||
# type: (unicode, unicode) -> str
|
||||
if encoding:
|
||||
if errors:
|
||||
return self.data.encode(encoding, errors)
|
||||
@ -62,81 +69,106 @@ class _TranslationProxy(UserString, object):
|
||||
return self.data.encode()
|
||||
|
||||
def __contains__(self, key):
|
||||
# type: (Any) -> bool
|
||||
return key in self.data
|
||||
|
||||
def __bool__(self):
|
||||
# type: () -> bool
|
||||
return bool(self.data)
|
||||
__nonzero__ = __bool__ # for python2 compatibility
|
||||
|
||||
def __dir__(self):
|
||||
# type: () -> List[str]
|
||||
return dir(text_type)
|
||||
|
||||
def __iter__(self):
|
||||
# type: () -> Iterator[unicode]
|
||||
return iter(self.data)
|
||||
|
||||
def __len__(self):
|
||||
# type: () -> int
|
||||
return len(self.data)
|
||||
|
||||
def __str__(self):
|
||||
# type: () -> str
|
||||
return str(self.data)
|
||||
|
||||
def __unicode__(self):
|
||||
# type: () -> unicode
|
||||
return text_type(self.data)
|
||||
|
||||
def __add__(self, other):
|
||||
# type: (unicode) -> unicode
|
||||
return self.data + other
|
||||
|
||||
def __radd__(self, other):
|
||||
# type: (unicode) -> unicode
|
||||
return other + self.data
|
||||
|
||||
def __mod__(self, other):
|
||||
# type: (unicode) -> unicode
|
||||
return self.data % other
|
||||
|
||||
def __rmod__(self, other):
|
||||
# type: (unicode) -> unicode
|
||||
return other % self.data
|
||||
|
||||
def __mul__(self, other):
|
||||
# type: (Any) -> unicode
|
||||
return self.data * other
|
||||
|
||||
def __rmul__(self, other):
|
||||
# type: (Any) -> unicode
|
||||
return other * self.data
|
||||
|
||||
def __lt__(self, other):
|
||||
# type: (unicode) -> bool
|
||||
return self.data < other
|
||||
|
||||
def __le__(self, other):
|
||||
# type: (unicode) -> bool
|
||||
return self.data <= other
|
||||
|
||||
def __eq__(self, other):
|
||||
# type: (Any) -> bool
|
||||
return self.data == other
|
||||
|
||||
def __ne__(self, other):
|
||||
# type: (Any) -> bool
|
||||
return self.data != other
|
||||
|
||||
def __gt__(self, other):
|
||||
# type: (unicode) -> bool
|
||||
return self.data > other
|
||||
|
||||
def __ge__(self, other):
|
||||
# type: (unicode) -> bool
|
||||
return self.data >= other
|
||||
|
||||
def __getattr__(self, name):
|
||||
# type: (unicode) -> Any
|
||||
if name == '__members__':
|
||||
return self.__dir__()
|
||||
return getattr(self.data, name)
|
||||
|
||||
def __getstate__(self):
|
||||
# type: () -> Tuple[Callable, Tuple[unicode, ...]]
|
||||
return self._func, self._args
|
||||
|
||||
def __setstate__(self, tup):
|
||||
# type: (Tuple[Callable, Tuple[unicode]]) -> None
|
||||
self._func, self._args = tup
|
||||
|
||||
def __getitem__(self, key):
|
||||
# type: (Any) -> unicode
|
||||
return self.data[key]
|
||||
|
||||
def __copy__(self):
|
||||
# type: () -> _TranslationProxy
|
||||
return self
|
||||
|
||||
def __repr__(self):
|
||||
# type: () -> str
|
||||
try:
|
||||
return 'i' + repr(text_type(self.data))
|
||||
except:
|
||||
@ -173,13 +205,13 @@ admonitionlabels = {
|
||||
'seealso': l_('See also'),
|
||||
'tip': l_('Tip'),
|
||||
'warning': l_('Warning'),
|
||||
}
|
||||
} # type: Dict[unicode, unicode]
|
||||
|
||||
versionlabels = {
|
||||
'versionadded': l_('New in version %s'),
|
||||
'versionchanged': l_('Changed in version %s'),
|
||||
'deprecated': l_('Deprecated since version %s'),
|
||||
}
|
||||
} # type: Dict[unicode, unicode]
|
||||
|
||||
# XXX Python specific
|
||||
pairindextypes = {
|
||||
@ -242,6 +274,7 @@ def init(locale_dirs, language, catalog='sphinx'):
|
||||
|
||||
|
||||
def get_translator(catalog='sphinx'):
|
||||
# type: (unicode) -> gettext.NullTranslations
|
||||
global translators
|
||||
translator = translators.get(catalog)
|
||||
if translator is None:
|
||||
|
@ -42,6 +42,10 @@ from sphinx.util.console import ( # type: ignore
|
||||
from sphinx.util.template import SphinxRenderer
|
||||
from sphinx.util import texescape
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
from typing import Any, Callable, Pattern # NOQA
|
||||
|
||||
TERM_ENCODING = getattr(sys.stdin, 'encoding', None)
|
||||
|
||||
DEFAULT_VALUE = {
|
||||
@ -66,6 +70,7 @@ PROMPT_PREFIX = '> '
|
||||
|
||||
|
||||
def mkdir_p(dir):
|
||||
# type: (unicode) -> None
|
||||
if path.isdir(dir):
|
||||
return
|
||||
os.makedirs(dir)
|
||||
@ -73,6 +78,7 @@ def mkdir_p(dir):
|
||||
|
||||
# function to get input from terminal -- overridden by the test suite
|
||||
def term_input(prompt):
|
||||
# type: (unicode) -> unicode
|
||||
print(prompt, end='')
|
||||
return input('')
|
||||
|
||||
@ -82,6 +88,7 @@ class ValidationError(Exception):
|
||||
|
||||
|
||||
def is_path(x):
|
||||
# type: (unicode) -> unicode
|
||||
x = path.expanduser(x)
|
||||
if path.exists(x) and not path.isdir(x):
|
||||
raise ValidationError("Please enter a valid path name.")
|
||||
@ -89,30 +96,36 @@ def is_path(x):
|
||||
|
||||
|
||||
def allow_empty(x):
|
||||
# type: (unicode) -> unicode
|
||||
return x
|
||||
|
||||
|
||||
def nonempty(x):
|
||||
# type: (unicode) -> unicode
|
||||
if not x:
|
||||
raise ValidationError("Please enter some text.")
|
||||
return x
|
||||
|
||||
|
||||
def choice(*l):
|
||||
# type: (List[unicode]) -> Callable[[unicode], unicode]
|
||||
def val(x):
|
||||
# type: (unicode) -> unicode
|
||||
if x not in l:
|
||||
raise ValidationError('Please enter one of %s.' % ', '.join(l))
|
||||
raise ValidationError('Please enter one of %s.' % ', '.join(l)) # type: ignore
|
||||
return x
|
||||
return val
|
||||
|
||||
|
||||
def boolean(x):
|
||||
# type: (unicode) -> bool
|
||||
if x.upper() not in ('Y', 'YES', 'N', 'NO'):
|
||||
raise ValidationError("Please enter either 'y' or 'n'.")
|
||||
return x.upper() in ('Y', 'YES')
|
||||
|
||||
|
||||
def suffix(x):
|
||||
# type: (unicode) -> unicode
|
||||
if not (x[0:1] == '.' and len(x) > 1):
|
||||
raise ValidationError("Please enter a file suffix, "
|
||||
"e.g. '.rst' or '.txt'.")
|
||||
@ -120,10 +133,12 @@ def suffix(x):
|
||||
|
||||
|
||||
def ok(x):
|
||||
# type: (unicode) -> unicode
|
||||
return x
|
||||
|
||||
|
||||
def term_decode(text):
|
||||
# type: (unicode) -> unicode
|
||||
if isinstance(text, text_type):
|
||||
return text
|
||||
|
||||
@ -145,9 +160,10 @@ def term_decode(text):
|
||||
|
||||
|
||||
def do_prompt(d, key, text, default=None, validator=nonempty):
|
||||
# type: (Dict, unicode, unicode, unicode, Callable[[unicode], Any]) -> None
|
||||
while True:
|
||||
if default is not None:
|
||||
prompt = PROMPT_PREFIX + '%s [%s]: ' % (text, default)
|
||||
prompt = PROMPT_PREFIX + '%s [%s]: ' % (text, default) # type: unicode
|
||||
else:
|
||||
prompt = PROMPT_PREFIX + text + ': '
|
||||
if PY2:
|
||||
@ -179,6 +195,7 @@ def do_prompt(d, key, text, default=None, validator=nonempty):
|
||||
|
||||
|
||||
def convert_python_source(source, rex=re.compile(r"[uU]('.*?')")):
|
||||
# type: (unicode, Pattern) -> unicode
|
||||
# remove Unicode literal prefixes
|
||||
if PY3:
|
||||
return rex.sub('\\1', source)
|
||||
@ -188,10 +205,12 @@ def convert_python_source(source, rex=re.compile(r"[uU]('.*?')")):
|
||||
|
||||
class QuickstartRenderer(SphinxRenderer):
|
||||
def __init__(self, templatedir):
|
||||
# type: (unicode) -> None
|
||||
self.templatedir = templatedir or ''
|
||||
super(QuickstartRenderer, self).__init__()
|
||||
|
||||
def render(self, template_name, context):
|
||||
# type: (unicode, Dict) -> unicode
|
||||
user_template = path.join(self.templatedir, path.basename(template_name))
|
||||
if self.templatedir and path.exists(user_template):
|
||||
return self.render_from_file(user_template, context)
|
||||
@ -200,6 +219,7 @@ class QuickstartRenderer(SphinxRenderer):
|
||||
|
||||
|
||||
def ask_user(d):
|
||||
# type: (Dict) -> None
|
||||
"""Ask the user for quickstart values missing from *d*.
|
||||
|
||||
Values are:
|
||||
@ -375,6 +395,7 @@ directly.''')
|
||||
|
||||
|
||||
def generate(d, overwrite=True, silent=False, templatedir=None):
|
||||
# type: (Dict, bool, bool, unicode) -> None
|
||||
"""Generate project based on values in *d*."""
|
||||
template = QuickstartRenderer(templatedir=templatedir)
|
||||
|
||||
@ -432,6 +453,7 @@ def generate(d, overwrite=True, silent=False, templatedir=None):
|
||||
mkdir_p(path.join(srcdir, d['dot'] + 'static'))
|
||||
|
||||
def write_file(fpath, content, newline=None):
|
||||
# type: (unicode, unicode, unicode) -> None
|
||||
if overwrite or not path.isfile(fpath):
|
||||
print('Creating file %s.' % fpath)
|
||||
with open(fpath, 'wt', encoding='utf-8', newline=newline) as f:
|
||||
@ -488,6 +510,7 @@ where "builder" is one of the supported builders, e.g. html, latex or linkcheck.
|
||||
|
||||
|
||||
def usage(argv, msg=None):
|
||||
# type: (List[unicode], unicode) -> None
|
||||
if msg:
|
||||
print(msg, file=sys.stderr)
|
||||
print(file=sys.stderr)
|
||||
@ -504,6 +527,7 @@ For more information, visit <http://sphinx-doc.org/>.
|
||||
|
||||
|
||||
def valid_dir(d):
|
||||
# type: (Dict) -> bool
|
||||
dir = d['path']
|
||||
if not path.exists(dir):
|
||||
return True
|
||||
@ -534,6 +558,7 @@ def valid_dir(d):
|
||||
|
||||
class MyFormatter(optparse.IndentedHelpFormatter):
|
||||
def format_usage(self, usage):
|
||||
# type: (str) -> str
|
||||
return usage
|
||||
|
||||
def format_help(self, formatter):
|
||||
@ -546,6 +571,7 @@ class MyFormatter(optparse.IndentedHelpFormatter):
|
||||
|
||||
|
||||
def main(argv=sys.argv):
|
||||
# type: (List[str]) -> int
|
||||
if not color_terminal():
|
||||
nocolor()
|
||||
|
||||
|
@ -21,6 +21,13 @@ from sphinx.util import ws_re
|
||||
from sphinx.util.nodes import split_explicit_title, process_index_entry, \
|
||||
set_role_source_info
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
from typing import Any, Tuple, Type # NOQA
|
||||
from docutils.parsers.rst.states import Inliner # NOQA
|
||||
from sphinx.application import Sphinx # NOQA
|
||||
from sphinx.environment import BuildEnvironment # NOQA
|
||||
|
||||
|
||||
generic_docroles = {
|
||||
'command': addnodes.literal_strong,
|
||||
@ -67,6 +74,7 @@ class XRefRole(object):
|
||||
|
||||
def __init__(self, fix_parens=False, lowercase=False,
|
||||
nodeclass=None, innernodeclass=None, warn_dangling=False):
|
||||
# type: (bool, bool, Type[nodes.Node], Type[nodes.Node], bool) -> None
|
||||
self.fix_parens = fix_parens
|
||||
self.lowercase = lowercase
|
||||
self.warn_dangling = warn_dangling
|
||||
@ -76,6 +84,7 @@ class XRefRole(object):
|
||||
self.innernodeclass = innernodeclass
|
||||
|
||||
def _fix_parens(self, env, has_explicit_title, title, target):
|
||||
# type: (BuildEnvironment, bool, unicode, unicode) -> Tuple[unicode, unicode]
|
||||
if not has_explicit_title:
|
||||
if title.endswith('()'):
|
||||
# remove parentheses
|
||||
@ -90,6 +99,7 @@ class XRefRole(object):
|
||||
|
||||
def __call__(self, typ, rawtext, text, lineno, inliner,
|
||||
options={}, content=[]):
|
||||
# type: (unicode, unicode, unicode, int, Inliner, Dict, List[unicode]) -> Tuple[List[nodes.Node], List[nodes.Node]] # NOQA
|
||||
env = inliner.document.settings.env
|
||||
if not typ:
|
||||
typ = env.temp_data.get('default_role')
|
||||
@ -100,7 +110,7 @@ class XRefRole(object):
|
||||
else:
|
||||
typ = typ.lower()
|
||||
if ':' not in typ:
|
||||
domain, role = '', typ
|
||||
domain, role = '', typ # type: unicode, unicode
|
||||
classes = ['xref', role]
|
||||
else:
|
||||
domain, role = typ.split(':', 1)
|
||||
@ -127,7 +137,7 @@ class XRefRole(object):
|
||||
refnode = self.nodeclass(rawtext, reftype=role, refdomain=domain,
|
||||
refexplicit=has_explicit_title)
|
||||
# we may need the line number for warnings
|
||||
set_role_source_info(inliner, lineno, refnode)
|
||||
set_role_source_info(inliner, lineno, refnode) # type: ignore
|
||||
title, target = self.process_link(
|
||||
env, refnode, has_explicit_title, title, target)
|
||||
# now that the target and title are finally determined, set them
|
||||
@ -142,6 +152,7 @@ class XRefRole(object):
|
||||
# methods that can be overwritten
|
||||
|
||||
def process_link(self, env, refnode, has_explicit_title, title, target):
|
||||
# type: (BuildEnvironment, nodes.reference, bool, unicode, unicode) -> Tuple[unicode, unicode] # NOQA
|
||||
"""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)``
|
||||
@ -150,6 +161,7 @@ class XRefRole(object):
|
||||
return title, ws_re.sub(' ', target)
|
||||
|
||||
def result_nodes(self, document, env, node, is_ref):
|
||||
# type: (nodes.document, BuildEnvironment, nodes.Node, bool) -> Tuple[List[nodes.Node], List[nodes.Node]] # NOQA
|
||||
"""Called before returning the finished nodes. *node* is the reference
|
||||
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)``
|
||||
@ -160,6 +172,7 @@ class XRefRole(object):
|
||||
|
||||
class AnyXRefRole(XRefRole):
|
||||
def process_link(self, env, refnode, has_explicit_title, title, target):
|
||||
# type: (BuildEnvironment, nodes.reference, bool, unicode, unicode) -> Tuple[unicode, unicode] # NOQA
|
||||
result = XRefRole.process_link(self, env, refnode, has_explicit_title,
|
||||
title, target)
|
||||
# add all possible context info (i.e. std:program, py:module etc.)
|
||||
@ -169,13 +182,14 @@ class AnyXRefRole(XRefRole):
|
||||
|
||||
def indexmarkup_role(typ, rawtext, text, lineno, inliner,
|
||||
options={}, content=[]):
|
||||
# type: (unicode, unicode, unicode, int, Inliner, Dict, List[unicode]) -> Tuple[List[nodes.Node], List[nodes.Node]] # NOQA
|
||||
"""Role for PEP/RFC references that generate an index entry."""
|
||||
env = inliner.document.settings.env
|
||||
if not typ:
|
||||
typ = env.config.default_role
|
||||
else:
|
||||
typ = typ.lower()
|
||||
has_explicit_title, title, target = split_explicit_title(text) # type: bool, unicode, unicode # NOQA
|
||||
has_explicit_title, title, target = split_explicit_title(text)
|
||||
title = utils.unescape(title)
|
||||
target = utils.unescape(target)
|
||||
targetid = 'index-%s' % env.new_serialno('index')
|
||||
@ -233,10 +247,11 @@ _amp_re = re.compile(r'(?<!&)&(?![&\s])')
|
||||
|
||||
|
||||
def menusel_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
|
||||
# type: (unicode, unicode, unicode, int, Inliner, Dict, List[unicode]) -> Tuple[List[nodes.Node], List[nodes.Node]] # NOQA
|
||||
text = utils.unescape(text)
|
||||
if typ == 'menuselection':
|
||||
text = text.replace('-->', u'\N{TRIANGULAR BULLET}')
|
||||
spans = _amp_re.split(text)
|
||||
spans = _amp_re.split(text) # type: ignore
|
||||
|
||||
node = nodes.inline(rawtext=rawtext)
|
||||
for i, span in enumerate(spans):
|
||||
@ -263,10 +278,11 @@ _litvar_re = re.compile('{([^}]+)}')
|
||||
|
||||
def emph_literal_role(typ, rawtext, text, lineno, inliner,
|
||||
options={}, content=[]):
|
||||
# type: (unicode, unicode, unicode, int, Inliner, Dict, List[unicode]) -> Tuple[List[nodes.Node], List[nodes.Node]] # NOQA
|
||||
text = utils.unescape(text)
|
||||
pos = 0
|
||||
retnode = nodes.literal(role=typ.lower(), classes=[typ])
|
||||
for m in _litvar_re.finditer(text):
|
||||
for m in _litvar_re.finditer(text): # type: ignore
|
||||
if m.start() > pos:
|
||||
txt = text[pos:m.start()]
|
||||
retnode += nodes.Text(txt, txt)
|
||||
@ -281,8 +297,9 @@ _abbr_re = re.compile('\((.*)\)$', re.S)
|
||||
|
||||
|
||||
def abbr_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
|
||||
# type: (unicode, unicode, unicode, int, Inliner, Dict, List[unicode]) -> Tuple[List[nodes.Node], List[nodes.Node]] # NOQA
|
||||
text = utils.unescape(text)
|
||||
m = _abbr_re.search(text)
|
||||
m = _abbr_re.search(text) # type: ignore
|
||||
if m is None:
|
||||
return [addnodes.abbreviation(text, text, **options)], []
|
||||
abbr = text[:m.start()].strip()
|
||||
@ -293,6 +310,7 @@ def abbr_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
|
||||
|
||||
|
||||
def index_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
|
||||
# type: (unicode, unicode, unicode, int, Inliner, Dict, List[unicode]) -> Tuple[List[nodes.Node], List[nodes.Node]] # NOQA
|
||||
# create new reference target
|
||||
env = inliner.document.settings.env
|
||||
targetid = 'index-%s' % env.new_serialno('index')
|
||||
@ -315,7 +333,7 @@ def index_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
|
||||
entries = [('single', target, targetid, main, None)]
|
||||
indexnode = addnodes.index()
|
||||
indexnode['entries'] = entries
|
||||
set_role_source_info(inliner, lineno, indexnode)
|
||||
set_role_source_info(inliner, lineno, indexnode) # type: ignore
|
||||
textnode = nodes.Text(title, title)
|
||||
return [indexnode, targetnode, textnode], []
|
||||
|
||||
@ -338,6 +356,7 @@ specific_docroles = {
|
||||
|
||||
|
||||
def setup(app):
|
||||
# type: (Sphinx) -> Dict[unicode, Any]
|
||||
from docutils.parsers.rst import roles
|
||||
|
||||
for rolename, nodeclass in iteritems(generic_docroles):
|
||||
|
@ -304,6 +304,7 @@ class Locale(Transform):
|
||||
# * use translated refname for section refname.
|
||||
# * inline reference "`Python <...>`_" has no 'refname'.
|
||||
def is_refnamed_ref(node):
|
||||
# type: (nodes.Node) -> bool
|
||||
return isinstance(node, nodes.reference) and \
|
||||
'refname' in node
|
||||
old_refs = node.traverse(is_refnamed_ref)
|
||||
|
@ -239,9 +239,9 @@ def clean_astext(node):
|
||||
|
||||
|
||||
def split_explicit_title(text):
|
||||
# type: (str) -> Tuple[bool, unicode, unicode]
|
||||
# type: (unicode) -> Tuple[bool, unicode, unicode]
|
||||
"""Split role content into title and target, if given."""
|
||||
match = explicit_title_re.match(text)
|
||||
match = explicit_title_re.match(text) # type: ignore
|
||||
if match:
|
||||
return True, match.group(1), match.group(2)
|
||||
return False, text, text
|
||||
|
@ -24,6 +24,12 @@ from sphinx.util import logging
|
||||
from sphinx.util.images import get_image_size
|
||||
from sphinx.util.smartypants import sphinx_smarty_pants
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
from typing import Any # NOQA
|
||||
from sphinx.builders.html import StandaloneHTMLBuilder # NOQA
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# A good overview of the purpose behind these classes can be found here:
|
||||
@ -39,10 +45,12 @@ class HTMLWriter(Writer):
|
||||
_setting[2]['default'] = 0
|
||||
|
||||
def __init__(self, builder):
|
||||
# type: (StandaloneHTMLBuilder) -> None
|
||||
Writer.__init__(self)
|
||||
self.builder = builder
|
||||
|
||||
def translate(self):
|
||||
# type: () -> None
|
||||
# sadly, this is mostly copied from parent class
|
||||
self.visitor = visitor = self.builder.translator_class(self.builder,
|
||||
self.document)
|
||||
@ -63,6 +71,7 @@ class HTMLTranslator(BaseTranslator):
|
||||
"""
|
||||
|
||||
def __init__(self, builder, *args, **kwds):
|
||||
# type: (StandaloneHTMLBuilder, Any, Any) -> None
|
||||
BaseTranslator.__init__(self, *args, **kwds)
|
||||
self.highlighter = builder.highlighter
|
||||
self.no_smarty = 0
|
||||
@ -82,22 +91,28 @@ class HTMLTranslator(BaseTranslator):
|
||||
self.param_separator = ''
|
||||
self.optional_param_level = 0
|
||||
self._table_row_index = 0
|
||||
self.required_params_left = 0
|
||||
|
||||
def visit_start_of_file(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
# only occurs in the single-file builder
|
||||
self.docnames.append(node['docname'])
|
||||
self.body.append('<span id="document-%s"></span>' % node['docname'])
|
||||
|
||||
def depart_start_of_file(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.docnames.pop()
|
||||
|
||||
def visit_desc(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.body.append(self.starttag(node, 'dl', CLASS=node['objtype']))
|
||||
|
||||
def depart_desc(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.body.append('</dl>\n\n')
|
||||
|
||||
def visit_desc_signature(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
# the id is set automatically
|
||||
self.body.append(self.starttag(node, 'dt'))
|
||||
# anchor for per-desc interactive data
|
||||
@ -106,44 +121,56 @@ class HTMLTranslator(BaseTranslator):
|
||||
self.body.append('<!--[%s]-->' % node['ids'][0])
|
||||
|
||||
def depart_desc_signature(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
if not node.get('is_multiline'):
|
||||
self.add_permalink_ref(node, _('Permalink to this definition'))
|
||||
self.body.append('</dt>\n')
|
||||
|
||||
def visit_desc_signature_line(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
pass
|
||||
|
||||
def depart_desc_signature_line(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
if node.get('add_permalink'):
|
||||
# the permalink info is on the parent desc_signature node
|
||||
self.add_permalink_ref(node.parent, _('Permalink to this definition'))
|
||||
self.body.append('<br />')
|
||||
|
||||
def visit_desc_addname(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.body.append(self.starttag(node, 'code', '', CLASS='descclassname'))
|
||||
|
||||
def depart_desc_addname(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.body.append('</code>')
|
||||
|
||||
def visit_desc_type(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
pass
|
||||
|
||||
def depart_desc_type(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
pass
|
||||
|
||||
def visit_desc_returns(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.body.append(' → ')
|
||||
|
||||
def depart_desc_returns(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
pass
|
||||
|
||||
def visit_desc_name(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.body.append(self.starttag(node, 'code', '', CLASS='descname'))
|
||||
|
||||
def depart_desc_name(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.body.append('</code>')
|
||||
|
||||
def visit_desc_parameterlist(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.body.append('<span class="sig-paren">(</span>')
|
||||
self.first_param = 1
|
||||
self.optional_param_level = 0
|
||||
@ -153,6 +180,7 @@ class HTMLTranslator(BaseTranslator):
|
||||
self.param_separator = node.child_text_separator
|
||||
|
||||
def depart_desc_parameterlist(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.body.append('<span class="sig-paren">)</span>')
|
||||
|
||||
# If required parameters are still to come, then put the comma after
|
||||
@ -162,6 +190,7 @@ class HTMLTranslator(BaseTranslator):
|
||||
# foo([a, ]b, c[, d])
|
||||
#
|
||||
def visit_desc_parameter(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
if self.first_param:
|
||||
self.first_param = 0
|
||||
elif not self.required_params_left:
|
||||
@ -172,39 +201,49 @@ class HTMLTranslator(BaseTranslator):
|
||||
self.body.append('<em>')
|
||||
|
||||
def depart_desc_parameter(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
if not node.hasattr('noemph'):
|
||||
self.body.append('</em>')
|
||||
if self.required_params_left:
|
||||
self.body.append(self.param_separator)
|
||||
|
||||
def visit_desc_optional(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.optional_param_level += 1
|
||||
self.body.append('<span class="optional">[</span>')
|
||||
|
||||
def depart_desc_optional(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.optional_param_level -= 1
|
||||
self.body.append('<span class="optional">]</span>')
|
||||
|
||||
def visit_desc_annotation(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.body.append(self.starttag(node, 'em', '', CLASS='property'))
|
||||
|
||||
def depart_desc_annotation(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.body.append('</em>')
|
||||
|
||||
def visit_desc_content(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.body.append(self.starttag(node, 'dd', ''))
|
||||
|
||||
def depart_desc_content(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.body.append('</dd>')
|
||||
|
||||
def visit_versionmodified(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.body.append(self.starttag(node, 'div', CLASS=node['type']))
|
||||
|
||||
def depart_versionmodified(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.body.append('</div>\n')
|
||||
|
||||
# overwritten
|
||||
def visit_reference(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
atts = {'class': 'reference'}
|
||||
if node.get('internal') or 'refuri' not in node:
|
||||
atts['class'] += ' internal'
|
||||
@ -234,17 +273,21 @@ class HTMLTranslator(BaseTranslator):
|
||||
'.'.join(map(str, node['secnumber'])))
|
||||
|
||||
def visit_number_reference(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.visit_reference(node)
|
||||
|
||||
def depart_number_reference(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.depart_reference(node)
|
||||
|
||||
# overwritten -- we don't want source comments to show up in the HTML
|
||||
def visit_comment(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
raise nodes.SkipNode
|
||||
|
||||
# overwritten
|
||||
def visit_admonition(self, node, name=''):
|
||||
# type: (nodes.Node, unicode) -> None
|
||||
self.body.append(self.starttag(
|
||||
node, 'div', CLASS=('admonition ' + name)))
|
||||
if name:
|
||||
@ -252,12 +295,15 @@ class HTMLTranslator(BaseTranslator):
|
||||
self.set_first_last(node)
|
||||
|
||||
def visit_seealso(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.visit_admonition(node, 'seealso')
|
||||
|
||||
def depart_seealso(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.depart_admonition(node)
|
||||
|
||||
def add_secnumber(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
if node.get('secnumber'):
|
||||
self.body.append('.'.join(map(str, node['secnumber'])) +
|
||||
self.secnumber_suffix)
|
||||
@ -279,7 +325,9 @@ class HTMLTranslator(BaseTranslator):
|
||||
self.secnumber_suffix)
|
||||
|
||||
def add_fignumber(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
def append_fignumber(figtype, figure_id):
|
||||
# type: (unicode, unicode) -> None
|
||||
if self.builder.name == 'singlehtml':
|
||||
key = (self.docnames[-1], figtype)
|
||||
else:
|
||||
@ -296,7 +344,7 @@ class HTMLTranslator(BaseTranslator):
|
||||
self.body.append(prefix % '.'.join(map(str, numbers)) + ' ')
|
||||
self.body.append('</span>')
|
||||
|
||||
figtype = self.builder.env.domains['std'].get_figtype(node)
|
||||
figtype = self.builder.env.domains['std'].get_figtype(node) # type: ignore
|
||||
if figtype:
|
||||
if len(node['ids']) == 0:
|
||||
msg = 'Any IDs not assigned for %s node' % node.tagname
|
||||
@ -305,11 +353,13 @@ class HTMLTranslator(BaseTranslator):
|
||||
append_fignumber(figtype, node['ids'][0])
|
||||
|
||||
def add_permalink_ref(self, node, title):
|
||||
# type: (nodes.Node, unicode) -> None
|
||||
if node['ids'] and self.permalink_text and self.builder.add_permalinks:
|
||||
format = u'<a class="headerlink" href="#%s" title="%s">%s</a>'
|
||||
self.body.append(format % (node['ids'][0], title, self.permalink_text))
|
||||
|
||||
def generate_targets_for_listing(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
"""Generate hyperlink targets for listings.
|
||||
|
||||
Original visit_bullet_list(), visit_definition_list() and visit_enumerated_list()
|
||||
@ -325,6 +375,7 @@ class HTMLTranslator(BaseTranslator):
|
||||
|
||||
# overwritten
|
||||
def visit_bullet_list(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
if len(node) == 1 and node[0].tagname == 'toctree':
|
||||
# avoid emitting empty <ul></ul>
|
||||
raise nodes.SkipNode
|
||||
@ -333,11 +384,13 @@ class HTMLTranslator(BaseTranslator):
|
||||
|
||||
# overwritten
|
||||
def visit_enumerated_list(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.generate_targets_for_listing(node)
|
||||
BaseTranslator.visit_enumerated_list(self, node)
|
||||
|
||||
# overwritten
|
||||
def visit_title(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
BaseTranslator.visit_title(self, node)
|
||||
self.add_secnumber(node)
|
||||
self.add_fignumber(node.parent)
|
||||
@ -345,6 +398,7 @@ class HTMLTranslator(BaseTranslator):
|
||||
self.body.append('<span class="caption-text">')
|
||||
|
||||
def depart_title(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
close_tag = self.context[-1]
|
||||
if (self.permalink_text and self.builder.add_permalinks and
|
||||
node.parent.hasattr('ids') and node.parent['ids']):
|
||||
@ -367,6 +421,7 @@ class HTMLTranslator(BaseTranslator):
|
||||
|
||||
# overwritten
|
||||
def visit_literal_block(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
if node.rawsource != node.astext():
|
||||
# most probably a parsed-literal block -- don't highlight
|
||||
return BaseTranslator.visit_literal_block(self, node)
|
||||
@ -396,6 +451,7 @@ class HTMLTranslator(BaseTranslator):
|
||||
raise nodes.SkipNode
|
||||
|
||||
def visit_caption(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
if isinstance(node.parent, nodes.container) and node.parent.get('literal_block'):
|
||||
self.body.append('<div class="code-block-caption">')
|
||||
else:
|
||||
@ -404,6 +460,7 @@ class HTMLTranslator(BaseTranslator):
|
||||
self.body.append(self.starttag(node, 'span', '', CLASS='caption-text'))
|
||||
|
||||
def depart_caption(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.body.append('</span>')
|
||||
|
||||
# append permalink if available
|
||||
@ -422,26 +479,32 @@ class HTMLTranslator(BaseTranslator):
|
||||
BaseTranslator.depart_caption(self, node)
|
||||
|
||||
def visit_doctest_block(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.visit_literal_block(node)
|
||||
|
||||
# overwritten to add the <div> (for XHTML compliance)
|
||||
def visit_block_quote(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.body.append(self.starttag(node, 'blockquote') + '<div>')
|
||||
|
||||
def depart_block_quote(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.body.append('</div></blockquote>\n')
|
||||
|
||||
# overwritten
|
||||
def visit_literal(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.body.append(self.starttag(node, 'code', '',
|
||||
CLASS='docutils literal'))
|
||||
self.protect_literal_text += 1
|
||||
|
||||
def depart_literal(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.protect_literal_text -= 1
|
||||
self.body.append('</code>')
|
||||
|
||||
def visit_productionlist(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.body.append(self.starttag(node, 'pre'))
|
||||
names = []
|
||||
for production in node:
|
||||
@ -461,23 +524,29 @@ class HTMLTranslator(BaseTranslator):
|
||||
raise nodes.SkipNode
|
||||
|
||||
def depart_productionlist(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
pass
|
||||
|
||||
def visit_production(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
pass
|
||||
|
||||
def depart_production(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
pass
|
||||
|
||||
def visit_centered(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.body.append(self.starttag(node, 'p', CLASS="centered") +
|
||||
'<strong>')
|
||||
|
||||
def depart_centered(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.body.append('</strong></p>')
|
||||
|
||||
# overwritten
|
||||
def should_be_compact_paragraph(self, node):
|
||||
# type: (nodes.Node) -> bool
|
||||
"""Determine if the <p> tags around paragraph can be omitted."""
|
||||
if isinstance(node.parent, addnodes.desc_content):
|
||||
# Never compact desc_content items.
|
||||
@ -488,19 +557,24 @@ class HTMLTranslator(BaseTranslator):
|
||||
return BaseTranslator.should_be_compact_paragraph(self, node)
|
||||
|
||||
def visit_compact_paragraph(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
pass
|
||||
|
||||
def depart_compact_paragraph(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
pass
|
||||
|
||||
def visit_highlightlang(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.highlightlang = node['lang']
|
||||
self.highlightlinenothreshold = node['linenothreshold']
|
||||
|
||||
def depart_highlightlang(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
pass
|
||||
|
||||
def visit_download_reference(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
if self.builder.download_support and node.hasattr('filename'):
|
||||
self.body.append(
|
||||
'<a class="reference download internal" href="%s" download="">' %
|
||||
@ -510,10 +584,12 @@ class HTMLTranslator(BaseTranslator):
|
||||
self.context.append('')
|
||||
|
||||
def depart_download_reference(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.body.append(self.context.pop())
|
||||
|
||||
# overwritten
|
||||
def visit_image(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
olduri = node['uri']
|
||||
# rewrite the URI if the environment knows about it
|
||||
if olduri in self.builder.images:
|
||||
@ -555,51 +631,65 @@ class HTMLTranslator(BaseTranslator):
|
||||
|
||||
# overwritten
|
||||
def depart_image(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
if node['uri'].lower().endswith(('svg', 'svgz')):
|
||||
self.body.append(self.context.pop())
|
||||
else:
|
||||
BaseTranslator.depart_image(self, node)
|
||||
|
||||
def visit_toctree(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
# this only happens when formatting a toc from env.tocs -- in this
|
||||
# case we don't want to include the subtree
|
||||
raise nodes.SkipNode
|
||||
|
||||
def visit_index(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
raise nodes.SkipNode
|
||||
|
||||
def visit_tabular_col_spec(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
raise nodes.SkipNode
|
||||
|
||||
def visit_glossary(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
pass
|
||||
|
||||
def depart_glossary(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
pass
|
||||
|
||||
def visit_acks(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
pass
|
||||
|
||||
def depart_acks(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
pass
|
||||
|
||||
def visit_hlist(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.body.append('<table class="hlist"><tr>')
|
||||
|
||||
def depart_hlist(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.body.append('</tr></table>\n')
|
||||
|
||||
def visit_hlistcol(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.body.append('<td>')
|
||||
|
||||
def depart_hlistcol(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.body.append('</td>')
|
||||
|
||||
def bulk_text_processor(self, text):
|
||||
# type: (unicode) -> unicode
|
||||
return text
|
||||
|
||||
# overwritten
|
||||
def visit_Text(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
text = node.astext()
|
||||
encoded = self.encode(text)
|
||||
if self.protect_literal_text:
|
||||
@ -623,94 +713,122 @@ class HTMLTranslator(BaseTranslator):
|
||||
self.body.append(encoded)
|
||||
|
||||
def visit_note(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.visit_admonition(node, 'note')
|
||||
|
||||
def depart_note(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.depart_admonition(node)
|
||||
|
||||
def visit_warning(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.visit_admonition(node, 'warning')
|
||||
|
||||
def depart_warning(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.depart_admonition(node)
|
||||
|
||||
def visit_attention(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.visit_admonition(node, 'attention')
|
||||
|
||||
def depart_attention(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.depart_admonition()
|
||||
|
||||
def visit_caution(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.visit_admonition(node, 'caution')
|
||||
|
||||
def depart_caution(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.depart_admonition()
|
||||
|
||||
def visit_danger(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.visit_admonition(node, 'danger')
|
||||
|
||||
def depart_danger(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.depart_admonition()
|
||||
|
||||
def visit_error(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.visit_admonition(node, 'error')
|
||||
|
||||
def depart_error(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.depart_admonition()
|
||||
|
||||
def visit_hint(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.visit_admonition(node, 'hint')
|
||||
|
||||
def depart_hint(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.depart_admonition()
|
||||
|
||||
def visit_important(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.visit_admonition(node, 'important')
|
||||
|
||||
def depart_important(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.depart_admonition()
|
||||
|
||||
def visit_tip(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.visit_admonition(node, 'tip')
|
||||
|
||||
def depart_tip(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.depart_admonition()
|
||||
|
||||
# these are only handled specially in the SmartyPantsHTMLTranslator
|
||||
def visit_literal_emphasis(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
return self.visit_emphasis(node)
|
||||
|
||||
def depart_literal_emphasis(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
return self.depart_emphasis(node)
|
||||
|
||||
def visit_literal_strong(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
return self.visit_strong(node)
|
||||
|
||||
def depart_literal_strong(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
return self.depart_strong(node)
|
||||
|
||||
def visit_abbreviation(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
attrs = {}
|
||||
if node.hasattr('explanation'):
|
||||
attrs['title'] = node['explanation']
|
||||
self.body.append(self.starttag(node, 'abbr', '', **attrs))
|
||||
|
||||
def depart_abbreviation(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.body.append('</abbr>')
|
||||
|
||||
def visit_manpage(self, node):
|
||||
return self.visit_literal_emphasis(node)
|
||||
# type: (nodes.Node) -> None
|
||||
self.visit_literal_emphasis(node)
|
||||
|
||||
def depart_manpage(self, node):
|
||||
return self.depart_literal_emphasis(node)
|
||||
# type: (nodes.Node) -> None
|
||||
self.depart_literal_emphasis(node)
|
||||
|
||||
# overwritten to add even/odd classes
|
||||
|
||||
def visit_table(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self._table_row_index = 0
|
||||
return BaseTranslator.visit_table(self, node)
|
||||
|
||||
def visit_row(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self._table_row_index += 1
|
||||
if self._table_row_index % 2 == 0:
|
||||
node['classes'].append('row-even')
|
||||
@ -720,10 +838,12 @@ class HTMLTranslator(BaseTranslator):
|
||||
node.column = 0
|
||||
|
||||
def visit_field_list(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self._fieldlist_row_index = 0
|
||||
return BaseTranslator.visit_field_list(self, node)
|
||||
|
||||
def visit_field(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self._fieldlist_row_index += 1
|
||||
if self._fieldlist_row_index % 2 == 0:
|
||||
node['classes'].append('field-even')
|
||||
@ -732,6 +852,7 @@ class HTMLTranslator(BaseTranslator):
|
||||
self.body.append(self.starttag(node, 'tr', '', CLASS='field'))
|
||||
|
||||
def visit_math(self, node, math_env=''):
|
||||
# type: (nodes.Node, unicode) -> None
|
||||
logger.warning('using "math" markup without a Sphinx math extension '
|
||||
'active, please use one of the math extensions '
|
||||
'described at http://sphinx-doc.org/ext/math.html',
|
||||
@ -739,6 +860,7 @@ class HTMLTranslator(BaseTranslator):
|
||||
raise nodes.SkipNode
|
||||
|
||||
def unknown_visit(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
raise NotImplementedError('Unknown node: ' + node.__class__.__name__)
|
||||
|
||||
|
||||
@ -749,10 +871,12 @@ class SmartyPantsHTMLTranslator(HTMLTranslator):
|
||||
"""
|
||||
|
||||
def __init__(self, *args, **kwds):
|
||||
# type: (Any, Any) -> None
|
||||
self.no_smarty = 0
|
||||
HTMLTranslator.__init__(self, *args, **kwds)
|
||||
|
||||
def visit_literal(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.no_smarty += 1
|
||||
try:
|
||||
# this raises SkipNode
|
||||
@ -761,6 +885,7 @@ class SmartyPantsHTMLTranslator(HTMLTranslator):
|
||||
self.no_smarty -= 1
|
||||
|
||||
def visit_literal_block(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.no_smarty += 1
|
||||
try:
|
||||
HTMLTranslator.visit_literal_block(self, node)
|
||||
@ -771,34 +896,42 @@ class SmartyPantsHTMLTranslator(HTMLTranslator):
|
||||
raise
|
||||
|
||||
def depart_literal_block(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
HTMLTranslator.depart_literal_block(self, node)
|
||||
self.no_smarty -= 1
|
||||
|
||||
def visit_literal_emphasis(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.no_smarty += 1
|
||||
self.visit_emphasis(node)
|
||||
|
||||
def depart_literal_emphasis(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.depart_emphasis(node)
|
||||
self.no_smarty -= 1
|
||||
|
||||
def visit_literal_strong(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.no_smarty += 1
|
||||
self.visit_strong(node)
|
||||
|
||||
def depart_literal_strong(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.depart_strong(node)
|
||||
self.no_smarty -= 1
|
||||
|
||||
def visit_desc_signature(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.no_smarty += 1
|
||||
HTMLTranslator.visit_desc_signature(self, node)
|
||||
|
||||
def depart_desc_signature(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.no_smarty -= 1
|
||||
HTMLTranslator.depart_desc_signature(self, node)
|
||||
|
||||
def visit_productionlist(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.no_smarty += 1
|
||||
try:
|
||||
HTMLTranslator.visit_productionlist(self, node)
|
||||
@ -806,14 +939,17 @@ class SmartyPantsHTMLTranslator(HTMLTranslator):
|
||||
self.no_smarty -= 1
|
||||
|
||||
def visit_option(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.no_smarty += 1
|
||||
HTMLTranslator.visit_option(self, node)
|
||||
|
||||
def depart_option(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.no_smarty -= 1
|
||||
HTMLTranslator.depart_option(self, node)
|
||||
|
||||
def bulk_text_processor(self, text):
|
||||
# type: (unicode) -> unicode
|
||||
if self.no_smarty <= 0:
|
||||
return sphinx_smarty_pants(text)
|
||||
return text
|
||||
|
@ -1794,6 +1794,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
self.body.append('\\end{sphinxadmonition}\n')
|
||||
|
||||
def _make_visit_admonition(name):
|
||||
# type: (unicode) -> Callable[[LaTeXTranslator, nodes.Node], None]
|
||||
def visit_admonition(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.body.append(u'\n\\begin{sphinxadmonition}{%s}{%s:}' %
|
||||
|
@ -22,17 +22,24 @@ from sphinx.util import logging
|
||||
import sphinx.util.docutils
|
||||
from sphinx.util.i18n import format_date
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
from typing import Any # NOQA
|
||||
from sphinx.builders import Builder # NOQA
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ManualPageWriter(Writer):
|
||||
def __init__(self, builder):
|
||||
# type: (Builder) -> None
|
||||
Writer.__init__(self)
|
||||
self.builder = builder
|
||||
self.translator_class = (
|
||||
self.builder.translator_class or ManualPageTranslator)
|
||||
|
||||
def translate(self):
|
||||
# type: () -> None
|
||||
transform = NestedInlineTransform(self.document)
|
||||
transform.apply()
|
||||
visitor = self.translator_class(self.builder, self.document)
|
||||
@ -53,10 +60,13 @@ class NestedInlineTransform(object):
|
||||
<strong>&bar=</strong><emphasis>2</emphasis>
|
||||
"""
|
||||
def __init__(self, document):
|
||||
# type: (nodes.document) -> None
|
||||
self.document = document
|
||||
|
||||
def apply(self):
|
||||
# type: () -> None
|
||||
def is_inline(node):
|
||||
# type: (nodes.Node) -> bool
|
||||
return isinstance(node, (nodes.literal, nodes.emphasis, nodes.strong))
|
||||
|
||||
for node in self.document.traverse(is_inline):
|
||||
@ -77,6 +87,7 @@ class ManualPageTranslator(BaseTranslator):
|
||||
"""
|
||||
|
||||
def __init__(self, builder, *args, **kwds):
|
||||
# type: (Builder, Any, Any) -> None
|
||||
BaseTranslator.__init__(self, *args, **kwds)
|
||||
self.builder = builder
|
||||
|
||||
@ -114,6 +125,7 @@ class ManualPageTranslator(BaseTranslator):
|
||||
|
||||
# overwritten -- added quotes around all .TH arguments
|
||||
def header(self):
|
||||
# type: () -> unicode
|
||||
tmpl = (".TH \"%(title_upper)s\" \"%(manual_section)s\""
|
||||
" \"%(date)s\" \"%(version)s\" \"%(manual_group)s\"\n"
|
||||
".SH NAME\n"
|
||||
@ -121,96 +133,125 @@ class ManualPageTranslator(BaseTranslator):
|
||||
return tmpl % self._docinfo
|
||||
|
||||
def visit_start_of_file(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
pass
|
||||
|
||||
def depart_start_of_file(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
pass
|
||||
|
||||
def visit_desc(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.visit_definition_list(node)
|
||||
|
||||
def depart_desc(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.depart_definition_list(node)
|
||||
|
||||
def visit_desc_signature(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.visit_definition_list_item(node)
|
||||
self.visit_term(node)
|
||||
|
||||
def depart_desc_signature(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.depart_term(node)
|
||||
|
||||
def visit_desc_signature_line(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
pass
|
||||
|
||||
def depart_desc_signature_line(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.body.append(' ')
|
||||
|
||||
def visit_desc_addname(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
pass
|
||||
|
||||
def depart_desc_addname(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
pass
|
||||
|
||||
def visit_desc_type(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
pass
|
||||
|
||||
def depart_desc_type(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
pass
|
||||
|
||||
def visit_desc_returns(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.body.append(' -> ')
|
||||
|
||||
def depart_desc_returns(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
pass
|
||||
|
||||
def visit_desc_name(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
pass
|
||||
|
||||
def depart_desc_name(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
pass
|
||||
|
||||
def visit_desc_parameterlist(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.body.append('(')
|
||||
self.first_param = 1
|
||||
|
||||
def depart_desc_parameterlist(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.body.append(')')
|
||||
|
||||
def visit_desc_parameter(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
if not self.first_param:
|
||||
self.body.append(', ')
|
||||
else:
|
||||
self.first_param = 0
|
||||
|
||||
def depart_desc_parameter(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
pass
|
||||
|
||||
def visit_desc_optional(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.body.append('[')
|
||||
|
||||
def depart_desc_optional(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.body.append(']')
|
||||
|
||||
def visit_desc_annotation(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
pass
|
||||
|
||||
def depart_desc_annotation(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
pass
|
||||
|
||||
def visit_desc_content(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.visit_definition(node)
|
||||
|
||||
def depart_desc_content(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.depart_definition(node)
|
||||
|
||||
def visit_versionmodified(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.visit_paragraph(node)
|
||||
|
||||
def depart_versionmodified(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.depart_paragraph(node)
|
||||
|
||||
# overwritten -- don't make whole of term bold if it includes strong node
|
||||
def visit_term(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
if node.traverse(nodes.strong):
|
||||
self.body.append('\n')
|
||||
else:
|
||||
@ -218,15 +259,18 @@ class ManualPageTranslator(BaseTranslator):
|
||||
|
||||
# overwritten -- we don't want source comments to show up
|
||||
def visit_comment(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
raise nodes.SkipNode
|
||||
|
||||
# overwritten -- added ensure_eol()
|
||||
def visit_footnote(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.ensure_eol()
|
||||
BaseTranslator.visit_footnote(self, node)
|
||||
|
||||
# overwritten -- handle footnotes rubric
|
||||
def visit_rubric(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.ensure_eol()
|
||||
if len(node.children) == 1:
|
||||
rubtitle = node.children[0].astext()
|
||||
@ -238,15 +282,19 @@ class ManualPageTranslator(BaseTranslator):
|
||||
self.body.append('.sp\n')
|
||||
|
||||
def depart_rubric(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
pass
|
||||
|
||||
def visit_seealso(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.visit_admonition(node, 'seealso')
|
||||
|
||||
def depart_seealso(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.depart_admonition(node)
|
||||
|
||||
def visit_productionlist(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.ensure_eol()
|
||||
names = []
|
||||
self.in_productionlist += 1
|
||||
@ -271,13 +319,16 @@ class ManualPageTranslator(BaseTranslator):
|
||||
raise nodes.SkipNode
|
||||
|
||||
def visit_production(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
pass
|
||||
|
||||
def depart_production(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
pass
|
||||
|
||||
# overwritten -- don't emit a warning for images
|
||||
def visit_image(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
if 'alt' in node.attributes:
|
||||
self.body.append(_('[image: %s]') % node['alt'] + '\n')
|
||||
self.body.append(_('[image]') + '\n')
|
||||
@ -285,6 +336,7 @@ class ManualPageTranslator(BaseTranslator):
|
||||
|
||||
# overwritten -- don't visit inner marked up nodes
|
||||
def visit_reference(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.body.append(self.defs['reference'][0])
|
||||
# avoid repeating escaping code... fine since
|
||||
# visit_Text calls astext() and only works on that afterwards
|
||||
@ -306,51 +358,66 @@ class ManualPageTranslator(BaseTranslator):
|
||||
raise nodes.SkipNode
|
||||
|
||||
def visit_number_reference(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
text = nodes.Text(node.get('title', '#'))
|
||||
self.visit_Text(text)
|
||||
raise nodes.SkipNode
|
||||
|
||||
def visit_centered(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.ensure_eol()
|
||||
self.body.append('.sp\n.ce\n')
|
||||
|
||||
def depart_centered(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.body.append('\n.ce 0\n')
|
||||
|
||||
def visit_compact_paragraph(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
pass
|
||||
|
||||
def depart_compact_paragraph(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
pass
|
||||
|
||||
def visit_highlightlang(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
pass
|
||||
|
||||
def depart_highlightlang(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
pass
|
||||
|
||||
def visit_download_reference(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
pass
|
||||
|
||||
def depart_download_reference(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
pass
|
||||
|
||||
def visit_toctree(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
raise nodes.SkipNode
|
||||
|
||||
def visit_index(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
raise nodes.SkipNode
|
||||
|
||||
def visit_tabular_col_spec(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
raise nodes.SkipNode
|
||||
|
||||
def visit_glossary(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
pass
|
||||
|
||||
def depart_glossary(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
pass
|
||||
|
||||
def visit_acks(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.ensure_eol()
|
||||
self.body.append(', '.join(n.astext()
|
||||
for n in node.children[0].children) + '.')
|
||||
@ -358,43 +425,56 @@ class ManualPageTranslator(BaseTranslator):
|
||||
raise nodes.SkipNode
|
||||
|
||||
def visit_hlist(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.visit_bullet_list(node)
|
||||
|
||||
def depart_hlist(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.depart_bullet_list(node)
|
||||
|
||||
def visit_hlistcol(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
pass
|
||||
|
||||
def depart_hlistcol(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
pass
|
||||
|
||||
def visit_literal_emphasis(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
return self.visit_emphasis(node)
|
||||
|
||||
def depart_literal_emphasis(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
return self.depart_emphasis(node)
|
||||
|
||||
def visit_literal_strong(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
return self.visit_strong(node)
|
||||
|
||||
def depart_literal_strong(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
return self.depart_strong(node)
|
||||
|
||||
def visit_abbreviation(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
pass
|
||||
|
||||
def depart_abbreviation(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
pass
|
||||
|
||||
def visit_manpage(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
return self.visit_strong(node)
|
||||
|
||||
def depart_manpage(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
return self.depart_strong(node)
|
||||
|
||||
# overwritten: handle section titles better than in 0.6 release
|
||||
def visit_title(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
if isinstance(node.parent, addnodes.seealso):
|
||||
self.body.append('.IP "')
|
||||
return
|
||||
@ -409,26 +489,32 @@ class ManualPageTranslator(BaseTranslator):
|
||||
return BaseTranslator.visit_title(self, node)
|
||||
|
||||
def depart_title(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
if isinstance(node.parent, addnodes.seealso):
|
||||
self.body.append('"\n')
|
||||
return
|
||||
return BaseTranslator.depart_title(self, node)
|
||||
|
||||
def visit_raw(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
if 'manpage' in node.get('format', '').split():
|
||||
self.body.append(node.astext())
|
||||
raise nodes.SkipNode
|
||||
|
||||
def visit_meta(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
raise nodes.SkipNode
|
||||
|
||||
def visit_inline(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
pass
|
||||
|
||||
def depart_inline(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
pass
|
||||
|
||||
def visit_math(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
logger.warning('using "math" markup without a Sphinx math extension '
|
||||
'active, please use one of the math extensions '
|
||||
'described at http://sphinx-doc.org/ext/math.html')
|
||||
@ -437,4 +523,5 @@ class ManualPageTranslator(BaseTranslator):
|
||||
visit_math_block = visit_math
|
||||
|
||||
def unknown_visit(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
raise NotImplementedError('Unknown node: ' + node.__class__.__name__)
|
||||
|
@ -1055,6 +1055,7 @@ class TexinfoTranslator(nodes.NodeVisitor):
|
||||
pass
|
||||
|
||||
def visit_term(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
for id in node.get('ids'):
|
||||
self.add_anchor(id, node)
|
||||
# anchors and indexes need to go in front
|
||||
@ -1209,6 +1210,7 @@ class TexinfoTranslator(nodes.NodeVisitor):
|
||||
'@end cartouche\n')
|
||||
|
||||
def _make_visit_admonition(name):
|
||||
# type: (unicode) -> Callable[[TexinfoTranslator, nodes.Node], None]
|
||||
def visit(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.visit_admonition(node, admonitionlabels[name])
|
||||
|
@ -863,6 +863,7 @@ class TextTranslator(nodes.NodeVisitor):
|
||||
self.add_text(self.nl)
|
||||
|
||||
def _make_depart_admonition(name):
|
||||
# type: (unicode) -> Callable[[TextTranslator, nodes.Node], None]
|
||||
def depart_admonition(self, node):
|
||||
# type: (nodes.NodeVisitor, nodes.Node) -> None
|
||||
self.end_state(first=admonitionlabels[name] + ': ')
|
||||
|
Loading…
Reference in New Issue
Block a user