mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
53
CHANGES
53
CHANGES
@@ -8,6 +8,8 @@ Incompatible changes
|
||||
members by default. Thanks to Luc Saffre.
|
||||
* LaTeX ``\includegraphics`` command isn't overloaded: only ``\sphinxincludegraphics``
|
||||
has the custom code to fit image to available width if oversized.
|
||||
* The subclasses of ``sphinx.domains.Index`` should override ``generate()``
|
||||
method. The default implementation raises NotImplmentedError
|
||||
|
||||
Features removed
|
||||
----------------
|
||||
@@ -38,6 +40,8 @@ Features added
|
||||
* #3136: Add ``:name:`` option to the directives in ``sphinx.ext.graphviz``
|
||||
* #2336: Add ``imported_members`` option to ``sphinx-autogen`` command to document
|
||||
imported members.
|
||||
* C++, add ``:tparam-line-spec:`` option to templated declarations.
|
||||
When specified, each template parameter will be rendered on a separate line.
|
||||
|
||||
Bugs fixed
|
||||
----------
|
||||
@@ -55,9 +59,28 @@ Deprecated
|
||||
instead (as Sphinx does since 1.5.)
|
||||
* ``Sphinx.status_iterator()` and ``Sphinx.old_status_iterator()`` is now
|
||||
deprecated. Please use ``sphinx.util:status_iterator()`` intead.
|
||||
* ``BuildEnvironment.set_warnfunc()`` is now deprecated
|
||||
|
||||
Release 1.5.2 (in development)
|
||||
===============================
|
||||
Release 1.5.3 (in development)
|
||||
==============================
|
||||
|
||||
Incompatible changes
|
||||
--------------------
|
||||
|
||||
Deprecated
|
||||
----------
|
||||
|
||||
Features added
|
||||
--------------
|
||||
|
||||
Bugs fixed
|
||||
----------
|
||||
|
||||
Testing
|
||||
--------
|
||||
|
||||
Release 1.5.2 (released Jan 22, 2017)
|
||||
=====================================
|
||||
|
||||
Incompatible changes
|
||||
--------------------
|
||||
@@ -71,6 +94,8 @@ Features added
|
||||
* #3194: Refer the $MAKE environment variable to determine ``make`` command
|
||||
* Emit warning for nested numbered toctrees (refs: #3142)
|
||||
* #978: `intersphinx_mapping` also allows a list as a parameter
|
||||
* #3340: (LaTeX) long lines in :dudir:`parsed-literal` are wrapped like in
|
||||
:rst:dir:`code-block`, inline math and footnotes are fully functional.
|
||||
|
||||
Bugs fixed
|
||||
----------
|
||||
@@ -90,7 +115,25 @@ Bugs fixed
|
||||
unserializable exception
|
||||
* #3315: Bibliography crashes on latex build with docclass 'memoir'
|
||||
* #3328: Could not refer rubric implicitly
|
||||
* #3329: emit warnings if po file is invalid and can't read it. Also writing mo too.
|
||||
* #3329: emit warnings if po file is invalid and can't read it. Also writing mo too
|
||||
* #3337: Ugly rendering of definition list term's classifier
|
||||
* #3335: gettext does not extract field_name of a field in a field_list
|
||||
* #2952: C++, fix refs to operator() functions.
|
||||
* Fix Unicode super- and subscript digits in :rst:dir:`code-block` and
|
||||
parsed-literal LaTeX output (ref #3342)
|
||||
* LaTeX writer: leave ``"`` character inside parsed-literal as is (ref #3341)
|
||||
* #3234: intersphinx failed for encoded inventories
|
||||
* #3158: too much space after captions in PDF output
|
||||
* #3317: An URL in parsed-literal contents gets wrongly rendered in PDF if
|
||||
with hyphen
|
||||
* LaTeX crash if the filename of an image inserted in parsed-literal
|
||||
via a substitution contains an hyphen (ref #3340)
|
||||
* LaTeX rendering of inserted footnotes in parsed-literal is wrong (ref #3340)
|
||||
* Inline math in parsed-literal is not rendered well by LaTeX (ref #3340)
|
||||
* #3308: Parsed-literals don't wrap very long lines with pdf builder (ref #3340)
|
||||
* #3295: Could not import extension sphinx.builders.linkcheck
|
||||
* #3285: autosummary: asterisks are escaped twice
|
||||
* LaTeX, pass dvipdfm option to geometry package for Japanese documents (ref #3363)
|
||||
|
||||
|
||||
Release 1.5.1 (released Dec 13, 2016)
|
||||
@@ -133,8 +176,8 @@ Incompatible changes
|
||||
* latex, package ifthen is not any longer a dependency of sphinx.sty
|
||||
* latex, style file does not modify fancyvrb's Verbatim (also available as
|
||||
OriginalVerbatim) but uses sphinxVerbatim for name of custom wrapper.
|
||||
* latex, package newfloat is no longer a dependency of sphinx.sty (ref #2660;
|
||||
it was shipped with Sphinx since 1.3.4).
|
||||
* latex, package newfloat is not used (and not included) anymore (ref #2660;
|
||||
it was used since 1.3.4 and shipped with Sphinx since 1.4).
|
||||
* latex, literal blocks in tables do not use OriginalVerbatim but
|
||||
sphinxVerbatimintable which handles captions and wraps lines(ref #2704).
|
||||
* latex, replace ``pt`` by TeX equivalent ``bp`` if found in ``width`` or
|
||||
|
||||
11
MANIFEST.in
11
MANIFEST.in
@@ -2,21 +2,25 @@ include README.rst
|
||||
include LICENSE
|
||||
include AUTHORS
|
||||
include CHANGES
|
||||
include CHANGES.old
|
||||
include CONTRIBUTING.rst
|
||||
include EXAMPLES
|
||||
include TODO
|
||||
|
||||
include babel.cfg
|
||||
include Makefile
|
||||
include ez_setup.py
|
||||
include sphinx-autogen.py
|
||||
include sphinx-build.py
|
||||
include sphinx-quickstart.py
|
||||
include sphinx-apidoc.py
|
||||
include test-reqs.txt
|
||||
include tox.ini
|
||||
include sphinx/locale/.tx/config
|
||||
|
||||
recursive-include sphinx/templates *
|
||||
recursive-include sphinx/texinputs *
|
||||
recursive-include sphinx/themes *
|
||||
recursive-include sphinx/locale *
|
||||
recursive-include sphinx/pycode/pgen2 *.c *.pyx
|
||||
recursive-include sphinx/locale *.js *.pot *.po *.mo
|
||||
recursive-include sphinx/search/non-minified-js *.js
|
||||
recursive-include sphinx/ext/autosummary/templates *
|
||||
recursive-include tests *
|
||||
@@ -25,3 +29,4 @@ include sphinx/pycode/Grammar-py*
|
||||
|
||||
recursive-include doc *
|
||||
prune doc/_build
|
||||
prune sphinx/locale/.tx
|
||||
|
||||
7
Makefile
7
Makefile
@@ -54,11 +54,18 @@ clean-patchfiles:
|
||||
clean-backupfiles:
|
||||
find . -name '*~' -exec rm -f {} +
|
||||
find . -name '*.bak' -exec rm -f {} +
|
||||
find . -name '*.swp' -exec rm -f {} +
|
||||
find . -name '*.swo' -exec rm -f {} +
|
||||
|
||||
clean-generated:
|
||||
find . -name '.DS_Store' -exec rm -f {} +
|
||||
rm -f doc/_build/
|
||||
rm -f sphinx/pycode/*.pickle
|
||||
rm -f utils/*3.py*
|
||||
rm -f utils/regression_test.js
|
||||
|
||||
clean-testfiles:
|
||||
rm -rf tests/.coverage
|
||||
rm -rf tests/build
|
||||
rm -rf .tox/
|
||||
rm -rf .cache/
|
||||
|
||||
@@ -1523,8 +1523,8 @@ These options influence LaTeX output. See further :doc:`latex`.
|
||||
backslash or ampersand must be represented by the proper LaTeX commands if
|
||||
they are to be inserted literally.
|
||||
* *author*: Author for the LaTeX document. The same LaTeX markup caveat as
|
||||
for *title* applies. Use ``\and`` to separate multiple authors, as in:
|
||||
``'John \and Sarah'``.
|
||||
for *title* applies. Use ``\\and`` to separate multiple authors, as in:
|
||||
``'John \\and Sarah'`` (backslashes must be Python-escaped to reach LaTeX).
|
||||
* *documentclass*: Normally, one of ``'manual'`` or ``'howto'`` (provided
|
||||
by Sphinx and based on ``'report'``, resp. ``'article'``; Japanese
|
||||
documents use ``'jsbook'``, resp. ``'jreport'``.) "howto" (non-Japanese)
|
||||
@@ -1656,6 +1656,11 @@ These options influence LaTeX output. See further :doc:`latex`.
|
||||
``'\\usepackage[margin=1in,marginparwidth=0.5in]{geometry}'``.
|
||||
|
||||
.. versionadded:: 1.5
|
||||
|
||||
.. versionchanged:: 1.5.2
|
||||
For Japanese documents also ``dvipdfm`` option is passed to
|
||||
``geometry``.
|
||||
|
||||
``'babel'``
|
||||
"babel" package inclusion, default ``'\\usepackage{babel}'`` (the
|
||||
suitable document language string is passed as class option, and
|
||||
|
||||
@@ -545,6 +545,10 @@ The C++ Domain
|
||||
|
||||
The C++ domain (name **cpp**) supports documenting C++ projects.
|
||||
|
||||
|
||||
Directives
|
||||
~~~~~~~~~~
|
||||
|
||||
The following directives are available. All declarations can start with
|
||||
a visibility statement (``public``, ``private`` or ``protected``).
|
||||
|
||||
@@ -740,6 +744,16 @@ a visibility statement (``public``, ``private`` or ``protected``).
|
||||
Holder of elements, to which it can provide access via
|
||||
:cpp:concept:`Iterator` s.
|
||||
|
||||
Options
|
||||
.......
|
||||
|
||||
Some directives support options:
|
||||
|
||||
- ``:noindex:``, see :ref:`basic-domain-markup`.
|
||||
- ``:tparam-line-spec:``, for templated declarations.
|
||||
If specified, each template parameter will be rendered on a separate line.
|
||||
|
||||
|
||||
Constrained Templates
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
@@ -94,14 +94,14 @@ This section describe a easy way to translate with sphinx-intl.
|
||||
|
||||
$ make gettext
|
||||
|
||||
As a result, many pot files are generated under ``_build/locale``
|
||||
As a result, many pot files are generated under ``_build/gettext``
|
||||
directory.
|
||||
|
||||
#. Setup/Update your `locale_dir`:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ sphinx-intl update -p _build/locale -l de -l ja
|
||||
$ sphinx-intl update -p _build/gettext -l de -l ja
|
||||
|
||||
Done. You got these directories that contain po files:
|
||||
|
||||
|
||||
@@ -132,25 +132,33 @@ Here are the currently available options together with their default values.
|
||||
rendering by Sphinx; if in future Sphinx offers various *themes* for LaTeX,
|
||||
the interface may change.
|
||||
|
||||
.. attention::
|
||||
|
||||
LaTeX requires for keys with Boolean values to use **lowercase** ``true`` or
|
||||
``false``.
|
||||
|
||||
``verbatimwithframe``
|
||||
default ``true``. Boolean to specify if :rst:dir:`code-block`\ s and literal
|
||||
includes are framed. Setting it to ``false`` does not deactivate use of
|
||||
package "framed", because it is still in use for the optional background
|
||||
colour (see below).
|
||||
|
||||
.. attention::
|
||||
|
||||
LaTeX requires ``true`` or ``false`` to be specified in *lowercase*.
|
||||
|
||||
``verbatimwrapslines``
|
||||
default ``true``. Tells whether long lines in :rst:dir:`code-block`\ s
|
||||
should be wrapped.
|
||||
default ``true``. Tells whether long lines in :rst:dir:`code-block`\ 's
|
||||
contents should wrap.
|
||||
|
||||
.. (comment) It is theoretically possible to customize this even
|
||||
more and decide at which characters a line-break can occur and whether
|
||||
before or after, but this is accessible currently only by re-defining some
|
||||
macros with complicated LaTeX syntax from :file:`sphinx.sty`.
|
||||
|
||||
``parsedliteralwraps``
|
||||
default ``true``. Tells whether long lines in :dudir:`parsed-literal`\ 's
|
||||
contents should wrap.
|
||||
|
||||
.. versionadded:: 1.5.2
|
||||
set this option value to ``false`` to recover former behaviour.
|
||||
|
||||
``inlineliteralwraps``
|
||||
default ``true``. Allows linebreaks inside inline literals: but extra
|
||||
potential break-points (additionally to those allowed by LaTeX at spaces
|
||||
@@ -160,7 +168,7 @@ Here are the currently available options together with their default values.
|
||||
(or shrinked) in order to accomodate the linebreak.
|
||||
|
||||
.. versionadded:: 1.5
|
||||
set this option to ``false`` to recover former behaviour.
|
||||
set this option value to ``false`` to recover former behaviour.
|
||||
|
||||
``verbatimvisiblespace``
|
||||
default ``\textcolor{red}{\textvisiblespace}``. When a long code line is
|
||||
@@ -319,9 +327,10 @@ Here are the currently available options together with their default values.
|
||||
(non-breakable) space.
|
||||
|
||||
.. versionadded:: 1.5
|
||||
formerly, footnotes from explicit mark-up were
|
||||
preceded by a space (hence a linebreak there was possible), but
|
||||
automatically generated footnotes had no such space.
|
||||
formerly, footnotes from explicit mark-up (but not automatically
|
||||
generated ones) were preceded by a space in the output ``.tex`` file
|
||||
hence a linebreak in PDF was possible. To avoid insertion of this space
|
||||
one could use ``foo\ [#f1]`` mark-up, but this impacts all builders.
|
||||
|
||||
``HeaderFamily``
|
||||
default ``\sffamily\bfseries``. Sets the font used by headings.
|
||||
|
||||
@@ -26,4 +26,4 @@ universal = 1
|
||||
[flake8]
|
||||
max-line-length = 95
|
||||
ignore = E116,E241,E251
|
||||
exclude = .git,.tox,tests/*,build/*,sphinx/search/*,sphinx/pycode/pgen2/*,doc/ext/example*.py
|
||||
exclude = .git,.tox,tests/*,build/*,sphinx/search/*,sphinx/pycode/pgen2/*,doc/ext/example*.py
|
||||
@@ -292,7 +292,6 @@ class Sphinx(object):
|
||||
# type: (bool) -> None
|
||||
if freshenv:
|
||||
self.env = BuildEnvironment(self.srcdir, self.doctreedir, self.config)
|
||||
self.env.set_warnfunc(self.warn)
|
||||
self.env.find_files(self.config, self.buildername)
|
||||
for domain in self.domains.keys():
|
||||
self.env.domains[domain] = self.domains[domain](self.env)
|
||||
@@ -301,7 +300,6 @@ class Sphinx(object):
|
||||
logger.info(bold('loading pickled environment... '), nonl=True)
|
||||
self.env = BuildEnvironment.frompickle(
|
||||
self.srcdir, self.config, path.join(self.doctreedir, ENV_PICKLE_FILENAME))
|
||||
self.env.set_warnfunc(self.warn)
|
||||
self.env.init_managers()
|
||||
self.env.domains = {}
|
||||
for domain in self.domains.keys():
|
||||
@@ -582,11 +580,11 @@ class Sphinx(object):
|
||||
# type: (unicode, Any, Union[bool, unicode], Any) -> None
|
||||
logger.debug('[app] adding config value: %r',
|
||||
(name, default, rebuild) + ((types,) if types else ())) # type: ignore
|
||||
if name in self.config.values:
|
||||
if name in self.config:
|
||||
raise ExtensionError('Config value %r already present' % name)
|
||||
if rebuild in (False, True):
|
||||
rebuild = rebuild and 'env' or ''
|
||||
self.config.values[name] = (default, rebuild, types)
|
||||
self.config.add(name, default, rebuild, types)
|
||||
|
||||
def add_event(self, name):
|
||||
# type: (unicode) -> None
|
||||
|
||||
@@ -224,7 +224,7 @@ class MessageCatalogBuilder(I18nBuilder):
|
||||
|
||||
extract_translations = self.templates.environment.extract_translations
|
||||
|
||||
for template in status_iterator(files, 'reading templates... ', "purple",
|
||||
for template in status_iterator(files, 'reading templates... ', "purple", # type: ignore # NOQA
|
||||
len(files), self.app.verbosity):
|
||||
with open(template, 'r', encoding='utf-8') as f: # type: ignore
|
||||
context = f.read()
|
||||
@@ -247,7 +247,7 @@ class MessageCatalogBuilder(I18nBuilder):
|
||||
ctime = datetime.fromtimestamp( # type: ignore
|
||||
timestamp, ltz).strftime('%Y-%m-%d %H:%M%z'),
|
||||
)
|
||||
for textdomain, catalog in status_iterator(iteritems(self.catalogs),
|
||||
for textdomain, catalog in status_iterator(iteritems(self.catalogs), # type: ignore
|
||||
"writing message catalogs... ",
|
||||
"darkgreen", len(self.catalogs),
|
||||
self.app.verbosity,
|
||||
|
||||
@@ -48,7 +48,7 @@ from sphinx.writers.html import HTMLWriter, HTMLTranslator, \
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
from typing import Any, Iterable, Iterator, Tuple, Union # NOQA
|
||||
from typing import Any, Iterable, Iterator, Type, Tuple, Union # NOQA
|
||||
from sphinx.domains import Domain, Index # NOQA
|
||||
from sphinx.application import Sphinx # NOQA
|
||||
|
||||
@@ -105,7 +105,7 @@ class StandaloneHTMLBuilder(Builder):
|
||||
css_files = [] # type: List[unicode]
|
||||
|
||||
imgpath = None # type: unicode
|
||||
domain_indices = [] # type: List[Tuple[unicode, Index, unicode, bool]]
|
||||
domain_indices = [] # type: List[Tuple[unicode, Type[Index], List[Tuple[unicode, List[List[Union[unicode, int]]]]], bool]] # NOQA
|
||||
|
||||
default_sidebars = ['localtoc.html', 'relations.html',
|
||||
'sourcelink.html', 'searchbox.html']
|
||||
@@ -190,9 +190,7 @@ class StandaloneHTMLBuilder(Builder):
|
||||
|
||||
def get_outdated_docs(self): # type: ignore
|
||||
# type: () -> Iterator[unicode]
|
||||
cfgdict = dict((name, self.config[name])
|
||||
for (name, desc) in iteritems(self.config.values)
|
||||
if desc[1] == 'html')
|
||||
cfgdict = dict((confval.name, confval.value) for confval in self.config.filter('html'))
|
||||
self.config_hash = get_stable_hash(cfgdict)
|
||||
self.tags_hash = get_stable_hash(sorted(self.tags)) # type: ignore
|
||||
old_config_hash = old_tags_hash = ''
|
||||
@@ -297,7 +295,7 @@ class StandaloneHTMLBuilder(Builder):
|
||||
domain = None # type: Domain
|
||||
domain = self.env.domains[domain_name]
|
||||
for indexcls in domain.indices:
|
||||
indexname = '%s-%s' % (domain.name, indexcls.name)
|
||||
indexname = '%s-%s' % (domain.name, indexcls.name) # type: unicode
|
||||
if isinstance(indices_config, list):
|
||||
if indexname not in indices_config:
|
||||
continue
|
||||
@@ -328,10 +326,10 @@ class StandaloneHTMLBuilder(Builder):
|
||||
|
||||
self.relations = self.env.collect_relations()
|
||||
|
||||
rellinks = []
|
||||
rellinks = [] # type: List[Tuple[unicode, unicode, unicode, unicode]]
|
||||
if self.use_index:
|
||||
rellinks.append(('genindex', _('General Index'), 'I', _('index')))
|
||||
for indexname, indexcls, content, collapse in self.domain_indices: # type: ignore
|
||||
for indexname, indexcls, content, collapse in self.domain_indices:
|
||||
# if it has a short name
|
||||
if indexcls.shortname:
|
||||
rellinks.append((indexname, indexcls.localname,
|
||||
|
||||
@@ -16,9 +16,8 @@ import threading
|
||||
from os import path
|
||||
|
||||
from requests.exceptions import HTTPError
|
||||
from six.moves import queue # type: ignore
|
||||
from six.moves import queue, html_parser # type: ignore
|
||||
from six.moves.urllib.parse import unquote
|
||||
from six.moves.html_parser import HTMLParser
|
||||
from docutils import nodes
|
||||
|
||||
# 2015-06-25 barry@python.org. This exception was deprecated in Python 3.3 and
|
||||
@@ -48,18 +47,17 @@ if False:
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class AnchorCheckParser(HTMLParser):
|
||||
class AnchorCheckParser(html_parser.HTMLParser):
|
||||
"""Specialized HTML parser that looks for a specific anchor."""
|
||||
|
||||
def __init__(self, search_anchor):
|
||||
# type: (unicode) -> None
|
||||
HTMLParser.__init__(self)
|
||||
html_parser.HTMLParser.__init__(self)
|
||||
|
||||
self.search_anchor = search_anchor
|
||||
self.found = False
|
||||
|
||||
def handle_starttag(self, tag, attrs):
|
||||
# type: (Any, Dict[unicode, unicode]) -> None
|
||||
for key, value in attrs:
|
||||
if key in ('id', 'name') and value == self.search_anchor:
|
||||
self.found = True
|
||||
|
||||
@@ -13,6 +13,7 @@ import re
|
||||
from os import path, getenv
|
||||
|
||||
from six import PY2, PY3, iteritems, string_types, binary_type, text_type, integer_types
|
||||
from typing import Any, NamedTuple, Union
|
||||
|
||||
from sphinx.errors import ConfigError
|
||||
from sphinx.locale import l_
|
||||
@@ -23,7 +24,7 @@ from sphinx.util.pycompat import execfile_, NoneType
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
from typing import Any, Callable, Tuple # NOQA
|
||||
from typing import Any, Callable, Iterable, Iterator, Tuple # NOQA
|
||||
from sphinx.util.tags import Tags # NOQA
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -43,6 +44,13 @@ CONFIG_PERMITTED_TYPE_WARNING = "The config value `{name}' has type `{current.__
|
||||
CONFIG_TYPE_WARNING = "The config value `{name}' has type `{current.__name__}', " \
|
||||
"defaults to `{default.__name__}'."
|
||||
|
||||
if PY3:
|
||||
unicode = str # special alias for static typing...
|
||||
|
||||
ConfigValue = NamedTuple('ConfigValue', [('name', str),
|
||||
('value', Any),
|
||||
('rebuild', Union[bool, unicode])])
|
||||
|
||||
|
||||
class ENUM(object):
|
||||
"""represents the config value should be a one of candidates.
|
||||
@@ -307,3 +315,16 @@ class Config(object):
|
||||
def __contains__(self, name):
|
||||
# type: (unicode) -> bool
|
||||
return name in self.values
|
||||
|
||||
def __iter__(self):
|
||||
# type: () -> Iterable[ConfigValue]
|
||||
for name, value in iteritems(self.values):
|
||||
yield ConfigValue(name, getattr(self, name), value[1]) # type: ignore
|
||||
|
||||
def add(self, name, default, rebuild, types):
|
||||
# type: (unicode, Any, Union[bool, unicode], Any) -> None
|
||||
self.values[name] = (default, rebuild, types)
|
||||
|
||||
def filter(self, rebuild):
|
||||
# type: (str) -> Iterator[ConfigValue]
|
||||
return (value for value in self if value.rebuild == rebuild) # type: ignore
|
||||
|
||||
@@ -107,7 +107,7 @@ class Index(object):
|
||||
|
||||
Qualifier and description are not rendered e.g. in LaTeX output.
|
||||
"""
|
||||
return tuple()
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class Domain(object):
|
||||
|
||||
@@ -15,7 +15,7 @@ from copy import deepcopy
|
||||
from six import iteritems, text_type
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.parsers.rst import Directive
|
||||
from docutils.parsers.rst import Directive, directives
|
||||
|
||||
from sphinx import addnodes
|
||||
from sphinx.roles import XRefRole
|
||||
@@ -53,13 +53,17 @@ logger = logging.getLogger(__name__)
|
||||
the index. All of the versions should work as permalinks.
|
||||
|
||||
|
||||
Tagnames
|
||||
Signature Nodes and Tagnames
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
Each desc_signature node will have the attribute 'sphinx_cpp_tagname' set to
|
||||
- 'templateParams', if the line is on the form 'template<...>',
|
||||
- 'templateIntroduction, if the line is on the form 'conceptName{...}'
|
||||
Each signature is in a desc_signature node, where all children are
|
||||
desc_signature_line nodes. Each of these lines will have the attribute
|
||||
'sphinx_cpp_tagname' set to one of the following (prioritized):
|
||||
- 'declarator', if the line contains the name of the declared object.
|
||||
- 'templateParams', if the line starts a template parameter list,
|
||||
- 'templateParams', if the line has template parameters
|
||||
Note: such lines might get a new tag in the future.
|
||||
- 'templateIntroduction, if the line is on the form 'conceptName{...}'
|
||||
No other desc_signature nodes should exist (so far).
|
||||
|
||||
|
||||
@@ -892,6 +896,7 @@ class ASTTemplateParams(ASTBase):
|
||||
# type: (Any) -> None
|
||||
assert params is not None
|
||||
self.params = params
|
||||
self.isNested = False # whether it's a template template param
|
||||
|
||||
def get_id_v2(self):
|
||||
# type: () -> unicode
|
||||
@@ -910,17 +915,30 @@ class ASTTemplateParams(ASTBase):
|
||||
res.append(u"> ")
|
||||
return ''.join(res)
|
||||
|
||||
def describe_signature(self, signode, mode, env, symbol):
|
||||
# type: (addnodes.desc_signature, unicode, BuildEnvironment, Symbol) -> None
|
||||
signode.sphinx_cpp_tagname = 'templateParams'
|
||||
signode += nodes.Text("template<")
|
||||
def describe_signature(self, parentNode, mode, env, symbol, lineSpec=None):
|
||||
# type: (addnodes.desc_signature, unicode, BuildEnvironment, Symbol, bool) -> None
|
||||
# 'lineSpec' is defaulted becuase of template template parameters
|
||||
def makeLine(parentNode=parentNode):
|
||||
signode = addnodes.desc_signature_line()
|
||||
parentNode += signode
|
||||
signode.sphinx_cpp_tagname = 'templateParams'
|
||||
return signode
|
||||
if self.isNested:
|
||||
lineNode = parentNode
|
||||
else:
|
||||
lineNode = makeLine()
|
||||
lineNode += nodes.Text("template<")
|
||||
first = True
|
||||
for param in self.params:
|
||||
if not first:
|
||||
signode += nodes.Text(", ")
|
||||
lineNode += nodes.Text(", ")
|
||||
first = False
|
||||
param.describe_signature(signode, mode, env, symbol)
|
||||
signode += nodes.Text(">")
|
||||
if lineSpec:
|
||||
lineNode = makeLine()
|
||||
param.describe_signature(lineNode, mode, env, symbol)
|
||||
if lineSpec and not first:
|
||||
lineNode = makeLine()
|
||||
lineNode += nodes.Text(">")
|
||||
|
||||
|
||||
class ASTTemplateIntroductionParameter(ASTBase):
|
||||
@@ -1005,8 +1023,11 @@ class ASTTemplateIntroduction(ASTBase):
|
||||
res.append('} ')
|
||||
return ''.join(res)
|
||||
|
||||
def describe_signature(self, signode, mode, env, symbol):
|
||||
# type: (addnodes.desc_signature, unicode, BuildEnvironment, Symbol) -> None
|
||||
def describe_signature(self, parentNode, mode, env, symbol, lineSpec):
|
||||
# type: (addnodes.desc_signature, unicode, BuildEnvironment, Symbol, bool) -> None
|
||||
# Note: 'lineSpec' has no effect on template introductions.
|
||||
signode = addnodes.desc_signature_line()
|
||||
parentNode += signode
|
||||
signode.sphinx_cpp_tagname = 'templateIntroduction'
|
||||
self.concept.describe_signature(signode, 'markType', env, symbol)
|
||||
signode += nodes.Text('{')
|
||||
@@ -1043,13 +1064,11 @@ class ASTTemplateDeclarationPrefix(ASTBase):
|
||||
res.append(text_type(t))
|
||||
return u''.join(res)
|
||||
|
||||
def describe_signature(self, signode, mode, env, symbol):
|
||||
# type: (addnodes.desc_signature, unicode, BuildEnvironment, Symbol) -> None
|
||||
def describe_signature(self, signode, mode, env, symbol, lineSpec):
|
||||
# type: (addnodes.desc_signature, unicode, BuildEnvironment, Symbol, bool) -> None
|
||||
_verify_description_mode(mode)
|
||||
for t in self.templates:
|
||||
templateNode = addnodes.desc_signature_line()
|
||||
t.describe_signature(templateNode, 'lastIsName', env, symbol)
|
||||
signode += templateNode
|
||||
t.describe_signature(signode, 'lastIsName', env, symbol, lineSpec)
|
||||
|
||||
|
||||
class ASTOperatorBuildIn(ASTBase):
|
||||
@@ -2722,8 +2741,8 @@ class ASTDeclaration(ASTBase):
|
||||
res.append(text_type(self.declaration))
|
||||
return u''.join(res)
|
||||
|
||||
def describe_signature(self, signode, mode, env):
|
||||
# type: (addnodes.desc_signature, unicode, BuildEnvironment) -> None
|
||||
def describe_signature(self, signode, mode, env, options):
|
||||
# type: (addnodes.desc_signature, unicode, BuildEnvironment, Dict) -> None
|
||||
_verify_description_mode(mode)
|
||||
# The caller of the domain added a desc_signature node.
|
||||
# Always enable multiline:
|
||||
@@ -2736,7 +2755,8 @@ class ASTDeclaration(ASTBase):
|
||||
assert self.symbol
|
||||
if self.templatePrefix:
|
||||
self.templatePrefix.describe_signature(signode, mode, env,
|
||||
symbol=self.symbol)
|
||||
symbol=self.symbol,
|
||||
lineSpec=options.get('tparam-line-spec'))
|
||||
signode += mainDeclNode
|
||||
if self.visibility and self.visibility != "public":
|
||||
mainDeclNode += addnodes.desc_annotation(self.visibility + " ",
|
||||
@@ -4170,6 +4190,7 @@ class DefinitionParser(object):
|
||||
if self.skip_word('template'):
|
||||
# declare a tenplate template parameter
|
||||
nestedParams = self._parse_template_parameter_list()
|
||||
nestedParams.isNested = True
|
||||
else:
|
||||
nestedParams = None
|
||||
self.skip_ws()
|
||||
@@ -4390,6 +4411,9 @@ class DefinitionParser(object):
|
||||
# type: () -> ASTNamespace
|
||||
templatePrefix = self._parse_template_declaration_prefix(objectType="xref")
|
||||
name = self._parse_nested_name()
|
||||
# if there are '()' left, just skip them
|
||||
self.skip_ws()
|
||||
self.skip_string('()')
|
||||
templatePrefix = self._check_template_consistency(name, templatePrefix,
|
||||
fullSpecShorthand=True)
|
||||
res = ASTNamespace(name, templatePrefix)
|
||||
@@ -4420,6 +4444,9 @@ class CPPObject(ObjectDescription):
|
||||
names=('returns', 'return')),
|
||||
]
|
||||
|
||||
option_spec = dict(ObjectDescription.option_spec)
|
||||
option_spec['tparam-line-spec'] = directives.flag
|
||||
|
||||
def warn(self, msg):
|
||||
# type: (unicode) -> None
|
||||
self.state_machine.reporter.warning(msg, line=self.lineno)
|
||||
@@ -4517,9 +4544,9 @@ class CPPObject(ObjectDescription):
|
||||
# type: (Any) -> Any
|
||||
raise NotImplementedError()
|
||||
|
||||
def describe_signature(self, signode, ast, parentScope):
|
||||
# type: (addnodes.desc_signature, Any, Any) -> None
|
||||
raise NotImplementedError()
|
||||
def describe_signature(self, signode, ast, options): # type: ignore
|
||||
# type: (addnodes.desc_signature, Any, Dict) -> None
|
||||
ast.describe_signature(signode, 'lastIsName', self.env, options)
|
||||
|
||||
def handle_signature(self, sig, signode):
|
||||
# type: (unicode, addnodes.desc_signature) -> Any
|
||||
@@ -4552,7 +4579,8 @@ class CPPObject(ObjectDescription):
|
||||
if ast.objectType == 'enumerator':
|
||||
self._add_enumerator_to_parent(ast)
|
||||
|
||||
self.describe_signature(signode, ast)
|
||||
self.options['tparam-line-spec'] = 'tparam-line-spec' in self.options
|
||||
self.describe_signature(signode, ast, self.options)
|
||||
return ast
|
||||
|
||||
def before_content(self):
|
||||
@@ -4576,10 +4604,6 @@ class CPPTypeObject(CPPObject):
|
||||
# type: (Any) -> Any
|
||||
return parser.parse_declaration("type")
|
||||
|
||||
def describe_signature(self, signode, ast): # type: ignore
|
||||
# type: (addnodes.desc_signature, Any) -> None
|
||||
ast.describe_signature(signode, 'lastIsName', self.env)
|
||||
|
||||
|
||||
class CPPConceptObject(CPPObject):
|
||||
def get_index_text(self, name):
|
||||
@@ -4590,10 +4614,6 @@ class CPPConceptObject(CPPObject):
|
||||
# type: (Any) -> Any
|
||||
return parser.parse_declaration("concept")
|
||||
|
||||
def describe_signature(self, signode, ast): # type: ignore
|
||||
# type: (addnodes.desc_signature, Any) -> None
|
||||
ast.describe_signature(signode, 'lastIsName', self.env)
|
||||
|
||||
|
||||
class CPPMemberObject(CPPObject):
|
||||
def get_index_text(self, name):
|
||||
@@ -4604,10 +4624,6 @@ class CPPMemberObject(CPPObject):
|
||||
# type: (Any) -> Any
|
||||
return parser.parse_declaration("member")
|
||||
|
||||
def describe_signature(self, signode, ast): # type: ignore
|
||||
# type: (addnodes.desc_signature, Any) -> None
|
||||
ast.describe_signature(signode, 'lastIsName', self.env)
|
||||
|
||||
|
||||
class CPPFunctionObject(CPPObject):
|
||||
def get_index_text(self, name):
|
||||
@@ -4618,10 +4634,6 @@ class CPPFunctionObject(CPPObject):
|
||||
# type: (Any) -> Any
|
||||
return parser.parse_declaration("function")
|
||||
|
||||
def describe_signature(self, signode, ast): # type: ignore
|
||||
# type: (addnodes.desc_signature, Any) -> None
|
||||
ast.describe_signature(signode, 'lastIsName', self.env)
|
||||
|
||||
|
||||
class CPPClassObject(CPPObject):
|
||||
def get_index_text(self, name):
|
||||
@@ -4632,10 +4644,6 @@ class CPPClassObject(CPPObject):
|
||||
# type: (Any) -> Any
|
||||
return parser.parse_declaration("class")
|
||||
|
||||
def describe_signature(self, signode, ast): # type: ignore
|
||||
# type: (addnodes.desc_signature, Any) -> None
|
||||
ast.describe_signature(signode, 'lastIsName', self.env)
|
||||
|
||||
|
||||
class CPPEnumObject(CPPObject):
|
||||
def get_index_text(self, name):
|
||||
@@ -4656,10 +4664,6 @@ class CPPEnumObject(CPPObject):
|
||||
assert False
|
||||
return ast
|
||||
|
||||
def describe_signature(self, signode, ast): # type: ignore
|
||||
# type: (addnodes.desc_signature, Any) -> None
|
||||
ast.describe_signature(signode, 'lastIsName', self.env)
|
||||
|
||||
|
||||
class CPPEnumeratorObject(CPPObject):
|
||||
def get_index_text(self, name):
|
||||
@@ -4670,10 +4674,6 @@ class CPPEnumeratorObject(CPPObject):
|
||||
# type: (Any) -> Any
|
||||
return parser.parse_declaration("enumerator")
|
||||
|
||||
def describe_signature(self, signode, ast): # type: ignore
|
||||
# type: (addnodes.desc_signature, Any) -> None
|
||||
ast.describe_signature(signode, 'lastIsName', self.env)
|
||||
|
||||
|
||||
class CPPNamespaceObject(Directive):
|
||||
"""
|
||||
@@ -4887,10 +4887,12 @@ class CPPDomain(Domain):
|
||||
if emitWarnings:
|
||||
logger.warning(msg, location=node)
|
||||
warner = Warner()
|
||||
# add parens again for those that could be functions
|
||||
if typ == 'any' or typ == 'func':
|
||||
target += '()'
|
||||
parser = DefinitionParser(target, warner, env.config)
|
||||
try:
|
||||
ast = parser.parse_xref_object()
|
||||
parser.skip_ws()
|
||||
parser.assert_end()
|
||||
except DefinitionError as e:
|
||||
warner.warn('Unparseable C++ cross-reference: %r\n%s'
|
||||
@@ -4950,11 +4952,26 @@ class CPPDomain(Domain):
|
||||
name = text_type(fullNestedName).lstrip(':')
|
||||
docname = s.docname
|
||||
assert docname
|
||||
if typ == 'any' and declaration.objectType == 'function':
|
||||
if env.config.add_function_parentheses:
|
||||
if not node['refexplicit']:
|
||||
title = contnode.pop(0).astext()
|
||||
contnode += nodes.Text(title + '()')
|
||||
# If it's operator(), we need to add '()' if explicit function parens
|
||||
# are requested. Then the Sphinx machinery will add another pair.
|
||||
# Also, if it's an 'any' ref that resolves to a function, we need to add
|
||||
# parens as well.
|
||||
addParen = 0
|
||||
if not node.get('refexplicit', False) and declaration.objectType == 'function':
|
||||
# this is just the normal haxing for 'any' roles
|
||||
if env.config.add_function_parentheses and typ == 'any':
|
||||
addParen += 1
|
||||
# and now this stuff for operator()
|
||||
if (env.config.add_function_parentheses and typ == 'function' and
|
||||
contnode[-1].astext().endswith('operator()')):
|
||||
addParen += 1
|
||||
if ((typ == 'any' or typ == 'function') and
|
||||
contnode[-1].astext().endswith('operator') and
|
||||
name.endswith('operator()')):
|
||||
addParen += 1
|
||||
if addParen > 0:
|
||||
title = contnode.pop(0).astext()
|
||||
contnode += nodes.Text(title + '()' * addParen)
|
||||
return make_refnode(builder, fromdocname, docname,
|
||||
declaration.get_newest_id(), contnode, name
|
||||
), declaration.objectType
|
||||
|
||||
@@ -16,6 +16,7 @@ import time
|
||||
import types
|
||||
import codecs
|
||||
import fnmatch
|
||||
import warnings
|
||||
from os import path
|
||||
from glob import glob
|
||||
from collections import defaultdict
|
||||
@@ -49,6 +50,7 @@ from sphinx.util.websupport import is_commentable
|
||||
from sphinx.errors import SphinxError, ExtensionError
|
||||
from sphinx.versioning import add_uids, merge_doctrees
|
||||
from sphinx.transforms import SphinxContentsFilter
|
||||
from sphinx.deprecation import RemovedInSphinx20Warning
|
||||
from sphinx.environment.managers.indexentries import IndexEntries
|
||||
from sphinx.environment.managers.toctree import Toctree
|
||||
|
||||
@@ -122,8 +124,6 @@ class BuildEnvironment(object):
|
||||
def topickle(self, filename):
|
||||
# type: (unicode) -> None
|
||||
# remove unpicklable attributes
|
||||
warnfunc = self._warnfunc
|
||||
self.set_warnfunc(None)
|
||||
values = self.config.values
|
||||
del self.config.values
|
||||
domains = self.domains
|
||||
@@ -142,7 +142,6 @@ class BuildEnvironment(object):
|
||||
self.attach_managers(managers)
|
||||
self.domains = domains
|
||||
self.config.values = values
|
||||
self.set_warnfunc(warnfunc)
|
||||
|
||||
# --------- ENVIRONMENT INITIALIZATION -------------------------------------
|
||||
|
||||
@@ -272,8 +271,8 @@ class BuildEnvironment(object):
|
||||
|
||||
def set_warnfunc(self, func):
|
||||
# type: (Callable) -> None
|
||||
self._warnfunc = func
|
||||
self.settings['warning_stream'] = WarningStream(func)
|
||||
warnings.warn('env.set_warnfunc() is now deprecated. Use sphinx.util.logging instead.',
|
||||
RemovedInSphinx20Warning)
|
||||
|
||||
def set_versioning_method(self, method, compare):
|
||||
# type: (unicode, bool) -> None
|
||||
@@ -533,10 +532,8 @@ class BuildEnvironment(object):
|
||||
else:
|
||||
# check if a config value was changed that affects how
|
||||
# doctrees are read
|
||||
for key, descr in iteritems(config.values):
|
||||
if descr[1] != 'env':
|
||||
continue
|
||||
if self.config[key] != config[key]:
|
||||
for confval in config.filter('env'):
|
||||
if self.config[confval.name] != confval.value:
|
||||
msg = '[config changed] '
|
||||
config_changed = True
|
||||
break
|
||||
@@ -641,12 +638,9 @@ class BuildEnvironment(object):
|
||||
def read_process(docs):
|
||||
# type: (List[unicode]) -> BuildEnvironment
|
||||
self.app = app
|
||||
self.warnings = [] # type: List[Tuple]
|
||||
self.set_warnfunc(lambda *args, **kwargs: self.warnings.append((args, kwargs)))
|
||||
for docname in docs:
|
||||
self.read_doc(docname, app)
|
||||
# allow pickling self to send it back
|
||||
self.set_warnfunc(None)
|
||||
del self.app
|
||||
del self.domains
|
||||
del self.config.values
|
||||
@@ -655,13 +649,11 @@ class BuildEnvironment(object):
|
||||
|
||||
def merge(docs, otherenv):
|
||||
# type: (List[unicode], BuildEnvironment) -> None
|
||||
warnings.extend(otherenv.warnings)
|
||||
self.merge_info_from(docs, otherenv, app)
|
||||
|
||||
tasks = ParallelTasks(nproc)
|
||||
chunks = make_chunks(docnames, nproc)
|
||||
|
||||
warnings = [] # type: List[Tuple]
|
||||
for chunk in status_iterator(chunks, 'reading sources... ', "purple",
|
||||
len(chunks), self.app.verbosity):
|
||||
tasks.add_task(read_process, chunk, merge)
|
||||
@@ -670,9 +662,6 @@ class BuildEnvironment(object):
|
||||
logger.info(bold('waiting for workers...'))
|
||||
tasks.join()
|
||||
|
||||
for warning, kwargs in warnings:
|
||||
self._warnfunc(*warning, **kwargs)
|
||||
|
||||
def check_dependents(self, already):
|
||||
# type: (Set[unicode]) -> Iterator[unicode]
|
||||
to_rewrite = (self.toctree.assign_section_numbers() + # type: ignore
|
||||
|
||||
@@ -72,7 +72,7 @@ class Toctree(EnvironmentManager):
|
||||
self.numbered_toctrees.add(docname)
|
||||
|
||||
for subfn, fnset in other.files_to_rebuild.items():
|
||||
self.files_to_rebuild.setdefault(subfn, set()).update(fnset & docnames)
|
||||
self.files_to_rebuild.setdefault(subfn, set()).update(fnset & set(docnames))
|
||||
|
||||
def process_doc(self, docname, doctree):
|
||||
# type: (unicode, nodes.Node) -> None
|
||||
|
||||
@@ -319,7 +319,6 @@ class Autosummary(Directive):
|
||||
else:
|
||||
max_chars = max(10, max_item_chars - len(display_name))
|
||||
sig = mangle_signature(sig, max_chars=max_chars)
|
||||
sig = sig.replace('*', r'\*')
|
||||
|
||||
# -- Grab the summary
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ class IfConfig(Directive):
|
||||
|
||||
def process_ifconfig_nodes(app, doctree, docname):
|
||||
# type: (Sphinx, nodes.Node, unicode) -> None
|
||||
ns = dict((k, app.config[k]) for k in app.config.values)
|
||||
ns = dict((confval.name, confval.value) for confval in app.config) # type: ignore
|
||||
ns.update(app.config.__dict__.copy())
|
||||
ns['builder'] = app.builder.name
|
||||
for node in doctree.traverse(ifconfig):
|
||||
|
||||
@@ -29,6 +29,7 @@ from __future__ import print_function
|
||||
import time
|
||||
import zlib
|
||||
import codecs
|
||||
import functools
|
||||
import posixpath
|
||||
from os import path
|
||||
import re
|
||||
@@ -185,6 +186,9 @@ def _read_from_url(url, config=None):
|
||||
r = requests.get(url, stream=True, config=config, timeout=config.intersphinx_timeout)
|
||||
r.raise_for_status()
|
||||
r.raw.url = r.url
|
||||
# decode content-body based on the header.
|
||||
# ref: https://github.com/kennethreitz/requests/issues/2155
|
||||
r.raw.read = functools.partial(r.raw.read, decode_content=True)
|
||||
return r.raw
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
\NeedsTeXFormat{LaTeX2e}
|
||||
\ProvidesPackage{footnotehyper-sphinx}%
|
||||
[2016/10/27 v0.9f hyperref aware footnote.sty for sphinx (JFB)]
|
||||
[2017/01/16 v1.5.2 hyperref aware footnote.sty for sphinx (JFB)]
|
||||
%%
|
||||
%% Package: footnotehyper-sphinx
|
||||
%% Version: based on footnotehyper.sty v0.9f (2016/10/03)
|
||||
@@ -15,6 +15,7 @@
|
||||
%% 4. \sphinxfootnotemark, and use of \spx@opt@BeforeFootnote from sphinx.sty.
|
||||
%% Note: with \footnotemark[N]/\footnotetext[N] syntax, hyperref
|
||||
%% does not insert an hyperlink. This is _not_ improved here.
|
||||
%% 5. use of \sphinxunactivateextrasandspace for parsed literals
|
||||
%%
|
||||
\DeclareOption*{\PackageWarning{footnotehyper}{Option `\CurrentOption' is unknown}}%
|
||||
\ProcessOptions\relax
|
||||
@@ -92,7 +93,8 @@
|
||||
%% \spx@opt@BeforeFootnote is defined in sphinx.sty
|
||||
\def\FNH@fixed@footnote {\spx@opt@BeforeFootnote\ifx\@currenvir\fn@footnote
|
||||
\expandafter\FNH@footnoteenv\else\expandafter\fn@latex@@footnote\fi }%
|
||||
\def\FNH@footnoteenv {\@ifnextchar[\FNH@xfootnoteenv%]
|
||||
\def\FNH@footnoteenv {\catcode13=5\sphinxunactivateextrasandspace
|
||||
\@ifnextchar[\FNH@xfootnoteenv%]
|
||||
{\stepcounter\@mpfn
|
||||
\protected@xdef\@thefnmark{\thempfn}\@footnotemark
|
||||
\def\FNH@endfntext@next{\FNH@endfntext@link}\fn@startfntext}}%
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
%
|
||||
|
||||
\NeedsTeXFormat{LaTeX2e}[1995/12/01]
|
||||
\ProvidesPackage{sphinx}[2017/01/09 v1.6 LaTeX package (Sphinx markup)]
|
||||
\ProvidesPackage{sphinx}[2017/01/16 v1.6 LaTeX package (Sphinx markup)]
|
||||
|
||||
% we delay handling of options to after having loaded packages, because
|
||||
% of the need to use \definecolor.
|
||||
@@ -91,6 +91,8 @@
|
||||
\DeclareBoolOption[true]{verbatimwithframe}
|
||||
\DeclareBoolOption[true]{verbatimwrapslines}
|
||||
\DeclareBoolOption[true]{inlineliteralwraps}
|
||||
% parsed literal
|
||||
\DeclareBoolOption[true]{parsedliteralwraps}
|
||||
% \textvisiblespace for compatibility with fontspec+XeTeX/LuaTeX
|
||||
\DeclareStringOption[\textcolor{red}{\textvisiblespace}]{verbatimvisiblespace}
|
||||
\DeclareStringOption % must use braces to hide the brackets
|
||||
@@ -118,7 +120,7 @@
|
||||
% some font styling.
|
||||
\DeclareStringOption[\sffamily\bfseries]{HeaderFamily}
|
||||
% colours
|
||||
% same problems as for dimensions: we want the key handler to use \definecolor
|
||||
% same problems as for dimensions: we want the key handler to use \definecolor.
|
||||
% first, some colours with no prefix, for backwards compatibility
|
||||
\newcommand*{\sphinxDeclareColorOption}[2]{%
|
||||
\definecolor{#1}#2%
|
||||
@@ -160,8 +162,8 @@
|
||||
% user interface: options can be changed midway in a document!
|
||||
\newcommand\sphinxsetup[1]{\setkeys{sphinx}{#1}}
|
||||
|
||||
% this is the \ltx@ifundefined of ltxcmds.sty, which is loaded by
|
||||
% hyperref.sty, but we need it before, and the first release of
|
||||
% this is the \ltx@ifundefined of ltxcmds.sty, which was loaded by
|
||||
% kvoptions already, (and later by hyperref), but the first release of
|
||||
% ltxcmds.sty as in TL2009/Debian has wrong definition.
|
||||
\newcommand{\spx@ifundefined}[1]{%
|
||||
\ifcsname #1\endcsname
|
||||
@@ -209,7 +211,8 @@
|
||||
|
||||
\pagestyle{empty} % start this way
|
||||
|
||||
% Use this to set the font family for headers and other decor:
|
||||
% Since Sphinx 1.5, users should use HeaderFamily key to 'sphinxsetup' rather
|
||||
% than defining their own \py@HeaderFamily command (which is still possible).
|
||||
\newcommand{\py@HeaderFamily}{\spx@opt@HeaderFamily}
|
||||
|
||||
% Redefine the 'normal' header/footer style when using "fancyhdr" package:
|
||||
@@ -285,9 +288,9 @@
|
||||
% - with possibly of a top caption, non-separable by pagebreak.
|
||||
% - and usable inside tables or footnotes ("footnotehyper-sphinx").
|
||||
|
||||
% For maintaining compatibility with Sphinx < 1.5, we define and use these
|
||||
% when (unmodified) Verbatim will be needed. But Sphinx >= 1.5 does not modify
|
||||
% original Verbatim anyhow.
|
||||
% For extensions which use \OriginalVerbatim and compatibility with Sphinx <
|
||||
% 1.5, we define and use these when (unmodified) Verbatim will be needed. But
|
||||
% Sphinx >= 1.5 does not modify the \Verbatim macro anymore.
|
||||
\let\OriginalVerbatim \Verbatim
|
||||
\let\endOriginalVerbatim\endVerbatim
|
||||
|
||||
@@ -374,7 +377,7 @@
|
||||
% {, <, #, %, $, ' and ": go to next line.
|
||||
% _, }, ^, &, >, - and ~: stay at end of broken line.
|
||||
% Use of \textquotesingle for straight quote.
|
||||
% FIXME: convert this to package options
|
||||
% FIXME: convert this to package options ?
|
||||
\newcommand*\sphinxbreaksbeforelist {%
|
||||
\do\PYGZob\{\do\PYGZlt\<\do\PYGZsh\#\do\PYGZpc\%% {, <, #, %,
|
||||
\do\PYGZdl\$\do\PYGZdq\"% $, "
|
||||
@@ -396,7 +399,8 @@
|
||||
|
||||
\def\sphinx@verbatim@nolig@list {\do \`}%
|
||||
% Some characters . , ; ? ! / are not pygmentized.
|
||||
% This macro makes them "active" and they will insert potential linebreaks
|
||||
% This macro makes them "active" and they will insert potential linebreaks.
|
||||
% Not compatible with math mode (cf \sphinxunactivateextras).
|
||||
\newcommand*\sphinxbreaksbeforeactivelist {}% none
|
||||
\newcommand*\sphinxbreaksafteractivelist {\do\.\do\,\do\;\do\?\do\!\do\/}
|
||||
\newcommand*\sphinxbreaksviaactive {%
|
||||
@@ -411,6 +415,15 @@
|
||||
\lccode`\~`\~
|
||||
}
|
||||
|
||||
% If the linebreak is at a space, the latter will be displayed as visible
|
||||
% space at end of first line, and a continuation symbol starts next line.
|
||||
% Stretch/shrink are however usually zero for typewriter font.
|
||||
\def\spx@verbatim@space {%
|
||||
\nobreak\hskip\z@ plus\fontdimen3\font minus\fontdimen4\font
|
||||
\discretionary{\copy\sphinxvisiblespacebox}{\sphinxafterbreak}
|
||||
{\kern\fontdimen2\font}%
|
||||
}%
|
||||
|
||||
% needed to create wrapper environments of fancyvrb's Verbatim
|
||||
\newcommand*{\sphinxVerbatimEnvironment}{\gdef\FV@EnvironName{sphinxVerbatim}}
|
||||
% Sphinx <1.5 optional argument was in fact mandatory. It is now really
|
||||
@@ -466,14 +479,7 @@
|
||||
\doublehyphendemerits\z@\finalhyphendemerits\z@
|
||||
\strut ##1\strut}%
|
||||
}%
|
||||
% If the linebreak is at a space, the latter will be displayed as visible
|
||||
% space at end of first line, and a continuation symbol starts next line.
|
||||
% Stretch/shrink are however usually zero for typewriter font.
|
||||
\def\FV@Space {%
|
||||
\nobreak\hskip\z@ plus\fontdimen3\font minus\fontdimen4\font
|
||||
\discretionary{\copy\sphinxvisiblespacebox}{\sphinxafterbreak}
|
||||
{\kern\fontdimen2\font}%
|
||||
}%
|
||||
\let\FV@Space\spx@verbatim@space
|
||||
% Allow breaks at special characters using \PYG... macros.
|
||||
\sphinxbreaksatspecials
|
||||
% Breaks at punctuation characters . , ; ? ! and / (needs catcode activation)
|
||||
@@ -535,6 +541,72 @@
|
||||
\begin{sphinxVerbatim}}
|
||||
{\end{sphinxVerbatim}}
|
||||
|
||||
% Parsed literal: allow long lines to wrap like they do in code-blocks
|
||||
|
||||
% this should be kept in sync with definitions in sphinx.util.texescape
|
||||
\newcommand*\sphinxbreaksattexescapedchars{%
|
||||
\def\do##1##2% put potential break point before character
|
||||
{\def##1{\discretionary{}{\sphinxafterbreak\char`##2}{\char`##2}}}%
|
||||
\do\{\{\do\textless\<\do\#\#\do\%\%\do\$\$% {, <, #, %, $
|
||||
\def\do##1##2% put potential break point after character
|
||||
{\def##1{\discretionary{\char`##2}{\sphinxafterbreak}{\char`##2}}}%
|
||||
\do\_\_\do\}\}\do\textasciicircum\^\do\&\&% _, }, ^, &,
|
||||
\do\textgreater\>\do\textasciitilde\~% >, ~
|
||||
}
|
||||
\newcommand*\sphinxbreaksviaactiveinparsedliteral{%
|
||||
\sphinxbreaksviaactive % by default handles . , ; ? ! /
|
||||
\do\-% we need also the hyphen character (ends up "as is" in parsed-literal)
|
||||
\lccode`\~`\~ %
|
||||
% update \dospecials as it is used by \url
|
||||
% but deactivation will already have been done hence this is unneeded:
|
||||
% \expandafter\def\expandafter\dospecials\expandafter{\dospecials
|
||||
% \sphinxbreaksbeforeactivelist\sphinxbreaksafteractivelist\do\-}%
|
||||
}
|
||||
\newcommand*\sphinxbreaksatspaceinparsedliteral{%
|
||||
\lccode`~32 \lowercase{\let~}\spx@verbatim@space\lccode`\~`\~
|
||||
}
|
||||
% now the hack for \url to work (hyperref is assumed in use):
|
||||
% the aim it to deactivate - . , ; ? ! / in \url's argument.
|
||||
% also the space token, but not end of lines which we assume don't arise there.
|
||||
\def\spx@hack@hyper@normalise {%
|
||||
\expandafter\spx@hack@hyper@normalise@aux\hyper@normalise
|
||||
\spx@hack@hyper@normalise@aux\hyper@n@rmalise\relax\spx@undefined
|
||||
}%
|
||||
\long\def\spx@hack@hyper@normalise@aux#1\hyper@n@rmalise#2#3\spx@undefined{%
|
||||
\ifx\spx@hack@hyper@normalise@aux#2%
|
||||
\def\hyper@normalise{#1\sphinxunactivateextrasandspace\hyper@n@rmalise}%
|
||||
\else
|
||||
\PackageWarning{sphinx}{Could not patch \string\url\space command.%
|
||||
^^J Not using extra active characters in alltt environment}%
|
||||
\sphinxunactivateextras
|
||||
\fi
|
||||
}%
|
||||
\newcommand*{\sphinxunactivateextras}{\let\do\@makeother
|
||||
\sphinxbreaksbeforeactivelist\sphinxbreaksafteractivelist\do\-}%
|
||||
% the \catcode13=5\relax (deactivate end of input lines) is left to callers
|
||||
\newcommand*{\sphinxunactivateextrasandspace}{\catcode32=10\relax
|
||||
\sphinxunactivateextras}%
|
||||
% now for the modified alltt environment
|
||||
\newenvironment{sphinxalltt}
|
||||
{% at start of next line to work around Emacs/AUCTeX issue with this file
|
||||
\begin{alltt}%
|
||||
\ifspx@opt@parsedliteralwraps
|
||||
\sbox\sphinxcontinuationbox {\spx@opt@verbatimcontinued}%
|
||||
\sbox\sphinxvisiblespacebox {\spx@opt@verbatimvisiblespace}%
|
||||
\sphinxbreaksattexescapedchars
|
||||
\sphinxbreaksviaactiveinparsedliteral
|
||||
\sphinxbreaksatspaceinparsedliteral
|
||||
\spx@hack@hyper@normalise
|
||||
% alltt takes care of the ' as derivative ("prime") in math mode
|
||||
\everymath\expandafter{\the\everymath\sphinxunactivateextrasandspace
|
||||
\catcode`\<=12\catcode`\>=12\catcode`\^=7\catcode`\_=8 }%
|
||||
% not sure if displayed math (align,...) can end up in parsed-literal, anyway
|
||||
\everydisplay\expandafter{\the\everydisplay
|
||||
\catcode13=5\sphinxunactivateextrasandspace
|
||||
\catcode`\<=12\catcode`\>=12\catcode`\^=7\catcode`\_=8 }%
|
||||
\fi }
|
||||
{\end{alltt}}
|
||||
|
||||
% Topic boxes
|
||||
|
||||
% Again based on use of "framed.sty", this allows breakable framed boxes.
|
||||
|
||||
@@ -45,7 +45,7 @@ from sphinx.util.matching import patfilter # noqa
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
from typing import Any, Callable, Iterable, Iterator, Pattern, Sequence, Tuple # NOQA
|
||||
from typing import Any, Callable, Iterable, Iterator, Pattern, Sequence, Tuple, Union # NOQA
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -149,7 +149,7 @@ class FilenameUniqDict(dict):
|
||||
def merge_other(self, docnames, other):
|
||||
# type: (List[unicode], Dict[unicode, Tuple[Set[unicode], Any]]) -> None
|
||||
for filename, (docs, unique) in other.items():
|
||||
for doc in docs & docnames:
|
||||
for doc in docs & set(docnames):
|
||||
self.add_file(doc, filename)
|
||||
|
||||
def __getstate__(self):
|
||||
@@ -565,7 +565,7 @@ def old_status_iterator(iterable, summary, color="darkgreen", stringify_func=dis
|
||||
# new version with progress info
|
||||
def status_iterator(iterable, summary, color="darkgreen", length=0, verbosity=0,
|
||||
stringify_func=display_chunk):
|
||||
# type: (Iterable, unicode, str, int, int, Callable[[Any], unicode]) -> Iterable
|
||||
# type: (Iterable, unicode, str, int, int, Callable[[Any], unicode]) -> Iterable # NOQA
|
||||
if length == 0:
|
||||
for item in old_status_iterator(iterable, summary, color, stringify_func):
|
||||
yield item
|
||||
|
||||
@@ -299,6 +299,7 @@ class DocFieldTransformer(object):
|
||||
|
||||
translatable_content = nodes.inline(fieldbody.rawsource,
|
||||
translatable=True)
|
||||
translatable_content.document = fieldbody.parent.document
|
||||
translatable_content.source = fieldbody.parent.source
|
||||
translatable_content.line = fieldbody.parent.line
|
||||
translatable_content += content
|
||||
|
||||
@@ -75,17 +75,12 @@ def apply_source_workaround(node):
|
||||
if node.source and node.rawsource:
|
||||
return
|
||||
|
||||
# workaround: docutils-0.10.0 or older's nodes.caption for nodes.figure
|
||||
# and nodes.title for nodes.admonition doesn't have source, line.
|
||||
# this issue was filed to Docutils tracker:
|
||||
# sf.net/tracker/?func=detail&aid=3599485&group_id=38414&atid=422032
|
||||
# sourceforge.net/p/docutils/patches/108/
|
||||
# workaround: some docutils nodes doesn't have source, line.
|
||||
if (isinstance(node, (
|
||||
nodes.caption,
|
||||
nodes.title,
|
||||
nodes.rubric,
|
||||
nodes.line,
|
||||
nodes.image,
|
||||
nodes.rubric, # #1305 rubric directive
|
||||
nodes.line, # #1477 line node
|
||||
nodes.image, # #3093 image directive in substitution
|
||||
nodes.field_name, # #3335 field list syntax
|
||||
))):
|
||||
node.source = find_source_node(node)
|
||||
node.line = 0 # need fix docutils to get `node.line`
|
||||
|
||||
@@ -48,26 +48,26 @@ tex_replacements = [
|
||||
('│', r'\textbar{}'),
|
||||
('ℯ', r'e'),
|
||||
('ⅈ', r'i'),
|
||||
('⁰', r'$^\text{0}$'),
|
||||
('¹', r'$^\text{1}$'),
|
||||
('²', r'$^\text{2}$'),
|
||||
('³', r'$^\text{3}$'),
|
||||
('⁴', r'$^\text{4}$'),
|
||||
('⁵', r'$^\text{5}$'),
|
||||
('⁶', r'$^\text{6}$'),
|
||||
('⁷', r'$^\text{7}$'),
|
||||
('⁸', r'$^\text{8}$'),
|
||||
('⁹', r'$^\text{9}$'),
|
||||
('₀', r'$_\text{0}$'),
|
||||
('₁', r'$_\text{1}$'),
|
||||
('₂', r'$_\text{2}$'),
|
||||
('₃', r'$_\text{3}$'),
|
||||
('₄', r'$_\text{4}$'),
|
||||
('₅', r'$_\text{5}$'),
|
||||
('₆', r'$_\text{6}$'),
|
||||
('₇', r'$_\text{7}$'),
|
||||
('₈', r'$_\text{8}$'),
|
||||
('₉', r'$_\text{9}$'),
|
||||
('⁰', r'\(\sp{\text{0}}\)'),
|
||||
('¹', r'\(\sp{\text{1}}\)'),
|
||||
('²', r'\(\sp{\text{2}}\)'),
|
||||
('³', r'\(\sp{\text{3}}\)'),
|
||||
('⁴', r'\(\sp{\text{4}}\)'),
|
||||
('⁵', r'\(\sp{\text{5}}\)'),
|
||||
('⁶', r'\(\sp{\text{6}}\)'),
|
||||
('⁷', r'\(\sp{\text{7}}\)'),
|
||||
('⁸', r'\(\sp{\text{8}}\)'),
|
||||
('⁹', r'\(\sp{\text{9}}\)'),
|
||||
('₀', r'\(\sb{\text{0}}\)'),
|
||||
('₁', r'\(\sb{\text{1}}\)'),
|
||||
('₂', r'\(\sb{\text{2}}\)'),
|
||||
('₃', r'\(\sb{\text{3}}\)'),
|
||||
('₄', r'\(\sb{\text{4}}\)'),
|
||||
('₅', r'\(\sb{\text{5}}\)'),
|
||||
('₆', r'\(\sb{\text{6}}\)'),
|
||||
('₇', r'\(\sb{\text{7}}\)'),
|
||||
('₈', r'\(\sb{\text{8}}\)'),
|
||||
('₉', r'\(\sb{\text{9}}\)'),
|
||||
# map Greek alphabet
|
||||
('α', r'\(\alpha\)'),
|
||||
('β', r'\(\beta\)'),
|
||||
|
||||
@@ -698,24 +698,6 @@ class HTMLTranslator(BaseTranslator):
|
||||
def depart_abbreviation(self, node):
|
||||
self.body.append('</abbr>')
|
||||
|
||||
# overwritten (but not changed) to keep pair of visit/depart_term
|
||||
def visit_term(self, node):
|
||||
self.body.append(self.starttag(node, 'dt', ''))
|
||||
|
||||
# overwritten to add '</dt>' in 'depart_term' state.
|
||||
def depart_term(self, node):
|
||||
self.body.append('</dt>\n')
|
||||
|
||||
# overwritten to do not add '</dt>' in 'visit_definition' state.
|
||||
def visit_definition(self, node):
|
||||
self.generate_targets_for_listing(node)
|
||||
self.body.append(self.starttag(node, 'dd', ''))
|
||||
self.set_first_last(node)
|
||||
|
||||
# overwritten (but not changed) to keep pair of visit/depart_definition
|
||||
def depart_definition(self, node):
|
||||
self.body.append('</dd>\n')
|
||||
|
||||
def visit_manpage(self, node):
|
||||
return self.visit_literal_emphasis(node)
|
||||
|
||||
|
||||
@@ -126,6 +126,8 @@ ADDITIONAL_SETTINGS = {
|
||||
},
|
||||
'platex': {
|
||||
'latex_engine': 'platex',
|
||||
'geometry': ('\\usepackage[margin=1in,marginparwidth=0.5in,dvipdfm]'
|
||||
'{geometry}'),
|
||||
},
|
||||
} # type: Dict[unicode, Dict[unicode, unicode]]
|
||||
|
||||
@@ -379,6 +381,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
self.this_is_the_title = 1
|
||||
self.literal_whitespace = 0
|
||||
self.no_contractions = 0
|
||||
self.in_parsed_literal = 0
|
||||
self.compact_list = 0
|
||||
self.first_param = 0
|
||||
self.remember_multirow = {} # type: Dict[int, int]
|
||||
@@ -652,34 +655,34 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
figure = self.builder.config.numfig_format['figure'].split('%s', 1)
|
||||
if len(figure) == 1:
|
||||
ret.append('\\def\\fnum@figure{%s}\n' %
|
||||
escape_abbr(text_type(figure[0]).translate(tex_escape_map)))
|
||||
text_type(figure[0]).strip().translate(tex_escape_map))
|
||||
else:
|
||||
definition = escape_abbr(text_type(figure[0]).translate(tex_escape_map))
|
||||
definition = text_type(figure[0]).strip().translate(tex_escape_map)
|
||||
ret.append(self.babel_renewcommand('\\figurename', definition))
|
||||
if figure[1]:
|
||||
ret.append('\\makeatletter\n')
|
||||
ret.append('\\def\\fnum@figure{\\figurename\\thefigure%s}\n' %
|
||||
escape_abbr(text_type(figure[1]).translate(tex_escape_map)))
|
||||
text_type(figure[1]).strip().translate(tex_escape_map))
|
||||
ret.append('\\makeatother\n')
|
||||
|
||||
table = self.builder.config.numfig_format['table'].split('%s', 1)
|
||||
if len(table) == 1:
|
||||
ret.append('\\def\\fnum@table{%s}\n' %
|
||||
escape_abbr(text_type(table[0]).translate(tex_escape_map)))
|
||||
text_type(table[0]).strip().translate(tex_escape_map))
|
||||
else:
|
||||
definition = escape_abbr(text_type(table[0]).translate(tex_escape_map))
|
||||
definition = text_type(table[0]).strip().translate(tex_escape_map)
|
||||
ret.append(self.babel_renewcommand('\\tablename', definition))
|
||||
if table[1]:
|
||||
ret.append('\\makeatletter\n')
|
||||
ret.append('\\def\\fnum@table{\\tablename\\thetable%s}\n' %
|
||||
escape_abbr(text_type(table[1]).translate(tex_escape_map)))
|
||||
text_type(table[1]).strip().translate(tex_escape_map))
|
||||
ret.append('\\makeatother\n')
|
||||
|
||||
codeblock = self.builder.config.numfig_format['code-block'].split('%s', 1)
|
||||
if len(codeblock) == 1:
|
||||
pass # FIXME
|
||||
else:
|
||||
definition = escape_abbr(text_type(codeblock[0]).translate(tex_escape_map))
|
||||
definition = text_type(codeblock[0]).strip().translate(tex_escape_map)
|
||||
ret.append(self.babel_renewcommand('\\literalblockname', definition))
|
||||
if codeblock[1]:
|
||||
pass # FIXME
|
||||
@@ -1125,15 +1128,21 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
self.body.append('%%\n\\begin{footnotetext}[%s]'
|
||||
'\\sphinxAtStartFootnote\n' % node['number'])
|
||||
else:
|
||||
self.body.append('%%\n\\begin{footnote}[%s]'
|
||||
'\\sphinxAtStartFootnote\n' % node['number'])
|
||||
if self.in_parsed_literal:
|
||||
self.body.append('\\begin{footnote}[%s]' % node['number'])
|
||||
else:
|
||||
self.body.append('%%\n\\begin{footnote}[%s]' % node['number'])
|
||||
self.body.append('\\sphinxAtStartFootnote\n')
|
||||
|
||||
def depart_collected_footnote(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
if 'footnotetext' in node:
|
||||
self.body.append('%\n\\end{footnotetext}')
|
||||
else:
|
||||
self.body.append('%\n\\end{footnote}')
|
||||
if self.in_parsed_literal:
|
||||
self.body.append('\\end{footnote}')
|
||||
else:
|
||||
self.body.append('%\n\\end{footnote}')
|
||||
self.in_footnote -= 1
|
||||
|
||||
def visit_label(self, node):
|
||||
@@ -1568,8 +1577,12 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
def visit_image(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
attrs = node.attributes
|
||||
pre = [] # in reverse order
|
||||
post = []
|
||||
pre = [] # type: List[unicode]
|
||||
# in reverse order
|
||||
post = [] # type: List[unicode]
|
||||
if self.in_parsed_literal:
|
||||
pre = ['\\begingroup\\sphinxunactivateextrasandspace\\relax ']
|
||||
post = ['\\endgroup ']
|
||||
include_graphics_options = []
|
||||
is_inline = self.is_inline(node)
|
||||
if 'width' in attrs:
|
||||
@@ -2112,7 +2125,8 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
# type: (nodes.Node) -> None
|
||||
if node.rawsource != node.astext():
|
||||
# most probably a parsed-literal block -- don't highlight
|
||||
self.body.append('\\begin{alltt}\n')
|
||||
self.in_parsed_literal += 1
|
||||
self.body.append('\\begin{sphinxalltt}\n')
|
||||
else:
|
||||
ids = '' # type: unicode
|
||||
for id in self.pop_hyperlink_ids('code-block'):
|
||||
@@ -2172,7 +2186,8 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
|
||||
def depart_literal_block(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
self.body.append('\n\\end{alltt}\n')
|
||||
self.body.append('\n\\end{sphinxalltt}\n')
|
||||
self.in_parsed_literal -= 1
|
||||
visit_doctest_block = visit_literal_block
|
||||
depart_doctest_block = depart_literal_block
|
||||
|
||||
@@ -2416,7 +2431,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
||||
def visit_Text(self, node):
|
||||
# type: (nodes.Node) -> None
|
||||
text = self.encode(node.astext())
|
||||
if not self.no_contractions:
|
||||
if not self.no_contractions and not self.in_parsed_literal:
|
||||
text = educate_quotes_latex(text)
|
||||
self.body.append(text)
|
||||
|
||||
|
||||
@@ -71,5 +71,5 @@ class C:
|
||||
'''
|
||||
|
||||
|
||||
def func(arg_):
|
||||
def func(arg_, *args, **kwargs):
|
||||
"""Test function take an argument ended with underscore."""
|
||||
|
||||
@@ -11,3 +11,7 @@ any role
|
||||
* ref function with parens :cpp:any:`paren_2()`
|
||||
* ref function without parens, explicit title :cpp:any:`paren_3_title <paren_3>`
|
||||
* ref function with parens, explicit title :cpp:any:`paren_4_title <paren_4()>`
|
||||
* ref op call without parens :cpp:any:`paren_5::operator()`
|
||||
* ref op call with parens :cpp:any:`paren_6::operator()()`
|
||||
* ref op call without parens, explicit title :cpp:any:`paren_7_title <paren_7::operator()>`
|
||||
* ref op call with parens, explicit title :cpp:any:`paren_8_title <paren_8::operator()()>`
|
||||
|
||||
@@ -38,9 +38,10 @@ directives
|
||||
|
||||
|
||||
.. cpp:function:: void paren_1(int, float)
|
||||
|
||||
.. cpp:function:: void paren_2(int, float)
|
||||
|
||||
.. cpp:function:: void paren_3(int, float)
|
||||
|
||||
.. cpp:function:: void paren_4(int, float)
|
||||
.. cpp:function:: void paren_5::operator()(int)
|
||||
.. cpp:function:: void paren_6::operator()(int)
|
||||
.. cpp:function:: void paren_7::operator()(int)
|
||||
.. cpp:function:: void paren_8::operator()(int)
|
||||
|
||||
@@ -11,3 +11,7 @@ roles
|
||||
* ref function with parens :cpp:func:`paren_2()`
|
||||
* ref function without parens, explicit title :cpp:func:`paren_3_title <paren_3>`
|
||||
* ref function with parens, explicit title :cpp:func:`paren_4_title <paren_4()>`
|
||||
* ref op call without parens :cpp:func:`paren_5::operator()`
|
||||
* ref op call with parens :cpp:func:`paren_6::operator()()`
|
||||
* ref op call without parens, explicit title :cpp:func:`paren_7_title <paren_7::operator()>`
|
||||
* ref op call with parens, explicit title :cpp:func:`paren_8_title <paren_8::operator()()>`
|
||||
|
||||
@@ -178,9 +178,9 @@ def test_numref(app, status, warning):
|
||||
print(result)
|
||||
print(status.getvalue())
|
||||
print(warning.getvalue())
|
||||
assert '\\addto\\captionsenglish{\\renewcommand{\\figurename}{Fig.\\@ }}' in result
|
||||
assert '\\addto\\captionsenglish{\\renewcommand{\\tablename}{Table }}' in result
|
||||
assert '\\addto\\captionsenglish{\\renewcommand{\\literalblockname}{Listing }}' in result
|
||||
assert '\\addto\\captionsenglish{\\renewcommand{\\figurename}{Fig.}}' in result
|
||||
assert '\\addto\\captionsenglish{\\renewcommand{\\tablename}{Table}}' in result
|
||||
assert '\\addto\\captionsenglish{\\renewcommand{\\literalblockname}{Listing}}' in result
|
||||
assert ('\\hyperref[\\detokenize{index:fig1}]'
|
||||
'{Fig.\\@ \\ref{\\detokenize{index:fig1}}}') in result
|
||||
assert ('\\hyperref[\\detokenize{baz:fig22}]'
|
||||
@@ -261,7 +261,7 @@ def test_numref_with_prefix2(app, status, warning):
|
||||
print(status.getvalue())
|
||||
print(warning.getvalue())
|
||||
assert '\\addto\\captionsenglish{\\renewcommand{\\figurename}{Figure:}}' in result
|
||||
assert '\\def\\fnum@figure{\\figurename\\thefigure.\\@}' in result
|
||||
assert '\\def\\fnum@figure{\\figurename\\thefigure.}' in result
|
||||
assert '\\addto\\captionsenglish{\\renewcommand{\\tablename}{Tab\\_}}' in result
|
||||
assert '\\def\\fnum@table{\\tablename\\thetable:}' in result
|
||||
assert '\\addto\\captionsenglish{\\renewcommand{\\literalblockname}{Code-}}' in result
|
||||
@@ -296,9 +296,9 @@ def test_numref_with_language_ja(app, status, warning):
|
||||
print(result)
|
||||
print(status.getvalue())
|
||||
print(warning.getvalue())
|
||||
assert u'\\renewcommand{\\figurename}{\u56f3 }' in result
|
||||
assert '\\renewcommand{\\tablename}{TABLE }' in result
|
||||
assert '\\renewcommand{\\literalblockname}{LIST }' in result
|
||||
assert u'\\renewcommand{\\figurename}{\u56f3}' in result
|
||||
assert '\\renewcommand{\\tablename}{TABLE}' in result
|
||||
assert '\\renewcommand{\\literalblockname}{LIST}' in result
|
||||
assert (u'\\hyperref[\\detokenize{index:fig1}]'
|
||||
u'{\u56f3 \\ref{\\detokenize{index:fig1}}}') in result
|
||||
assert ('\\hyperref[\\detokenize{baz:fig22}]'
|
||||
@@ -344,8 +344,8 @@ def test_babel_with_no_language_settings(app, status, warning):
|
||||
assert '\\usepackage[Bjarne]{fncychap}' in result
|
||||
assert ('\\addto\\captionsenglish{\\renewcommand{\\contentsname}{Table of content}}\n'
|
||||
in result)
|
||||
assert '\\addto\\captionsenglish{\\renewcommand{\\figurename}{Fig.\\@ }}\n' in result
|
||||
assert '\\addto\\captionsenglish{\\renewcommand{\\tablename}{Table.\\@ }}\n' in result
|
||||
assert '\\addto\\captionsenglish{\\renewcommand{\\figurename}{Fig.}}\n' in result
|
||||
assert '\\addto\\captionsenglish{\\renewcommand{\\tablename}{Table.}}\n' in result
|
||||
assert '\\addto\\extrasenglish{\\def\\pageautorefname{page}}\n' in result
|
||||
assert '\\shorthandoff' not in result
|
||||
|
||||
@@ -365,8 +365,8 @@ def test_babel_with_language_de(app, status, warning):
|
||||
assert '\\usepackage[Sonny]{fncychap}' in result
|
||||
assert ('\\addto\\captionsngerman{\\renewcommand{\\contentsname}{Table of content}}\n'
|
||||
in result)
|
||||
assert '\\addto\\captionsngerman{\\renewcommand{\\figurename}{Fig.\\@ }}\n' in result
|
||||
assert '\\addto\\captionsngerman{\\renewcommand{\\tablename}{Table.\\@ }}\n' in result
|
||||
assert '\\addto\\captionsngerman{\\renewcommand{\\figurename}{Fig.}}\n' in result
|
||||
assert '\\addto\\captionsngerman{\\renewcommand{\\tablename}{Table.}}\n' in result
|
||||
assert '\\addto\\extrasngerman{\\def\\pageautorefname{Seite}}\n' in result
|
||||
assert '\\shorthandoff{"}' in result
|
||||
|
||||
@@ -386,8 +386,8 @@ def test_babel_with_language_ru(app, status, warning):
|
||||
assert '\\usepackage[Sonny]{fncychap}' in result
|
||||
assert ('\\addto\\captionsrussian{\\renewcommand{\\contentsname}{Table of content}}\n'
|
||||
in result)
|
||||
assert '\\addto\\captionsrussian{\\renewcommand{\\figurename}{Fig.\\@ }}\n' in result
|
||||
assert '\\addto\\captionsrussian{\\renewcommand{\\tablename}{Table.\\@ }}\n' in result
|
||||
assert '\\addto\\captionsrussian{\\renewcommand{\\figurename}{Fig.}}\n' in result
|
||||
assert '\\addto\\captionsrussian{\\renewcommand{\\tablename}{Table.}}\n' in result
|
||||
assert (u'\\addto\\extrasrussian{\\def\\pageautorefname'
|
||||
u'{\u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430}}\n' in result)
|
||||
assert '\\shorthandoff' not in result
|
||||
@@ -408,8 +408,8 @@ def test_babel_with_language_tr(app, status, warning):
|
||||
assert '\\usepackage[Sonny]{fncychap}' in result
|
||||
assert ('\\addto\\captionsturkish{\\renewcommand{\\contentsname}{Table of content}}\n'
|
||||
in result)
|
||||
assert '\\addto\\captionsturkish{\\renewcommand{\\figurename}{Fig.\\@ }}\n' in result
|
||||
assert '\\addto\\captionsturkish{\\renewcommand{\\tablename}{Table.\\@ }}\n' in result
|
||||
assert '\\addto\\captionsturkish{\\renewcommand{\\figurename}{Fig.}}\n' in result
|
||||
assert '\\addto\\captionsturkish{\\renewcommand{\\tablename}{Table.}}\n' in result
|
||||
assert '\\addto\\extrasturkish{\\def\\pageautorefname{sayfa}}\n' in result
|
||||
assert '\\shorthandoff{=}' in result
|
||||
|
||||
@@ -428,8 +428,8 @@ def test_babel_with_language_ja(app, status, warning):
|
||||
assert '\\usepackage{times}' in result
|
||||
assert '\\usepackage[Sonny]{fncychap}' not in result
|
||||
assert '\\renewcommand{\\contentsname}{Table of content}\n' in result
|
||||
assert '\\renewcommand{\\figurename}{Fig.\\@ }\n' in result
|
||||
assert '\\renewcommand{\\tablename}{Table.\\@ }\n' in result
|
||||
assert '\\renewcommand{\\figurename}{Fig.}\n' in result
|
||||
assert '\\renewcommand{\\tablename}{Table.}\n' in result
|
||||
assert u'\\def\\pageautorefname{ページ}\n' in result
|
||||
assert '\\shorthandoff' not in result
|
||||
|
||||
@@ -449,8 +449,8 @@ def test_babel_with_unknown_language(app, status, warning):
|
||||
assert '\\usepackage[Sonny]{fncychap}' in result
|
||||
assert ('\\addto\\captionsenglish{\\renewcommand{\\contentsname}{Table of content}}\n'
|
||||
in result)
|
||||
assert '\\addto\\captionsenglish{\\renewcommand{\\figurename}{Fig.\\@ }}\n' in result
|
||||
assert '\\addto\\captionsenglish{\\renewcommand{\\tablename}{Table.\\@ }}\n' in result
|
||||
assert '\\addto\\captionsenglish{\\renewcommand{\\figurename}{Fig.}}\n' in result
|
||||
assert '\\addto\\captionsenglish{\\renewcommand{\\tablename}{Table.}}\n' in result
|
||||
assert '\\addto\\extrasenglish{\\def\\pageautorefname{page}}\n' in result
|
||||
assert '\\shorthandoff' not in result
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ def check(name, input, idv1output=None, idv2output=None, output=None):
|
||||
parentNode = addnodes.desc()
|
||||
signode = addnodes.desc_signature(input, '')
|
||||
parentNode += signode
|
||||
ast.describe_signature(signode, 'lastIsName', symbol)
|
||||
ast.describe_signature(signode, 'lastIsName', symbol, options={})
|
||||
|
||||
if idv2output:
|
||||
idv2output = "_CPPv2" + idv2output
|
||||
@@ -524,7 +524,11 @@ def test_build_domain_cpp_with_add_function_parentheses_is_True(app, status, war
|
||||
('ref function without parens ', 'paren_1\(\)'),
|
||||
('ref function with parens ', 'paren_2\(\)'),
|
||||
('ref function without parens, explicit title ', 'paren_3_title'),
|
||||
('ref function with parens, explicit title ', 'paren_4_title')
|
||||
('ref function with parens, explicit title ', 'paren_4_title'),
|
||||
('ref op call without parens ', 'paren_5::operator\(\)\(\)'),
|
||||
('ref op call with parens ', 'paren_6::operator\(\)\(\)'),
|
||||
('ref op call without parens, explicit title ', 'paren_7_title'),
|
||||
('ref op call with parens, explicit title ', 'paren_8_title')
|
||||
]
|
||||
|
||||
f = 'roles.html'
|
||||
@@ -562,7 +566,11 @@ def test_build_domain_cpp_with_add_function_parentheses_is_False(app, status, wa
|
||||
('ref function without parens ', 'paren_1'),
|
||||
('ref function with parens ', 'paren_2'),
|
||||
('ref function without parens, explicit title ', 'paren_3_title'),
|
||||
('ref function with parens, explicit title ', 'paren_4_title')
|
||||
('ref function with parens, explicit title ', 'paren_4_title'),
|
||||
('ref op call without parens ', 'paren_5::operator\(\)'),
|
||||
('ref op call with parens ', 'paren_6::operator\(\)'),
|
||||
('ref op call without parens, explicit title ', 'paren_7_title'),
|
||||
('ref op call with parens, explicit title ', 'paren_8_title')
|
||||
]
|
||||
|
||||
f = 'roles.html'
|
||||
|
||||
@@ -95,3 +95,11 @@ def test_get_items_summary(app, status, warning):
|
||||
for key, expected in iteritems(expected_values):
|
||||
assert autosummary_items[key][2] == expected, 'Summary for %s was %r -'\
|
||||
' expected %r' % (key, autosummary_items[key], expected)
|
||||
|
||||
# check an item in detail
|
||||
assert 'func' in autosummary_items
|
||||
func_attrs = ('func',
|
||||
'(arg_, *args, **kwargs)',
|
||||
'Test function take an argument ended with underscore.',
|
||||
'dummy_module.func')
|
||||
assert autosummary_items['func'] == func_attrs
|
||||
|
||||
17
utils/CHANGES_template
Normal file
17
utils/CHANGES_template
Normal file
@@ -0,0 +1,17 @@
|
||||
Release x.y.z (in development)
|
||||
==============================
|
||||
|
||||
Incompatible changes
|
||||
--------------------
|
||||
|
||||
Deprecated
|
||||
----------
|
||||
|
||||
Features added
|
||||
--------------
|
||||
|
||||
Bugs fixed
|
||||
----------
|
||||
|
||||
Testing
|
||||
--------
|
||||
170
utils/bump_version.py
Executable file
170
utils/bump_version.py
Executable file
@@ -0,0 +1,170 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from datetime import datetime
|
||||
from contextlib import contextmanager
|
||||
|
||||
script_dir = os.path.dirname(__file__)
|
||||
package_dir = os.path.abspath(os.path.join(script_dir, '..'))
|
||||
|
||||
RELEASE_TYPE = {'a': 'alpha', 'b': 'beta'}
|
||||
|
||||
|
||||
def stringify_version(version_info):
|
||||
if version_info[2] == 0:
|
||||
return '.'.join(str(v) for v in version_info[:2])
|
||||
else:
|
||||
return '.'.join(str(v) for v in version_info[:3])
|
||||
|
||||
|
||||
def bump_version(path, version_info):
|
||||
version = stringify_version(version_info)
|
||||
release = version
|
||||
if version_info[3] != 'final':
|
||||
version += '+'
|
||||
|
||||
with open(path, 'r+') as f:
|
||||
body = f.read()
|
||||
body = re.sub("(?<=__version__ = ')[^']+", version, body)
|
||||
body = re.sub("(?<=__released__ = ')[^']+", release, body)
|
||||
body = re.sub("(?<=version_info = )\(.*\)", str(version_info), body)
|
||||
|
||||
f.seek(0)
|
||||
f.truncate(0)
|
||||
f.write(body)
|
||||
|
||||
|
||||
def parse_version(version):
|
||||
matched = re.search('^(\d+)\.(\d+)$', version)
|
||||
if matched:
|
||||
major, minor = matched.groups()
|
||||
return (int(major), int(minor), 0, 'final', 0)
|
||||
|
||||
matched = re.search('^(\d+)\.(\d+)\.(\d+)$', version)
|
||||
if matched:
|
||||
major, minor, rev = matched.groups()
|
||||
return (int(major), int(minor), int(rev), 'final', 0)
|
||||
|
||||
matched = re.search('^(\d+)\.(\d+)\s*(a|b|alpha|beta)(\d+)$', version)
|
||||
if matched:
|
||||
major, minor, typ, relver = matched.groups()
|
||||
release = RELEASE_TYPE.get(typ, typ)
|
||||
return (int(major), int(minor), 0, release, int(relver))
|
||||
|
||||
matched = re.search('^(\d+)\.(\d+)\.(\d+)\s*(a|b|alpha|beta)(\d+)$', version)
|
||||
if matched:
|
||||
major, minor, rev, typ, relver = matched.groups()
|
||||
release = RELEASE_TYPE.get(typ, typ)
|
||||
return (int(major), int(minor), int(rev), release, int(relver))
|
||||
|
||||
raise RuntimeError('Unknown vesion: %s' % version)
|
||||
|
||||
|
||||
class Skip(Exception):
|
||||
pass
|
||||
|
||||
|
||||
@contextmanager
|
||||
def processing(message):
|
||||
try:
|
||||
print(message + ' ... ', end='')
|
||||
yield
|
||||
except Skip as exc:
|
||||
print('skip: %s' % exc)
|
||||
except:
|
||||
print('error')
|
||||
raise
|
||||
else:
|
||||
print('done')
|
||||
|
||||
|
||||
class Changes(object):
|
||||
def __init__(self, path):
|
||||
self.path = path
|
||||
self.fetch_version()
|
||||
|
||||
def fetch_version(self):
|
||||
with open(self.path) as f:
|
||||
version = f.readline().strip()
|
||||
matched = re.search('^Release (.*) \((.*)\)$', version)
|
||||
if matched is None:
|
||||
raise RuntimeError('Unknown CHANGES format: %s' % version)
|
||||
|
||||
self.version, self.release_date = matched.groups()
|
||||
self.version_info = parse_version(self.version)
|
||||
if self.release_date == 'in development':
|
||||
self.in_development = True
|
||||
else:
|
||||
self.in_development = False
|
||||
|
||||
def finalize_release_date(self):
|
||||
release_date = datetime.now().strftime('%b %d, %Y')
|
||||
heading = 'Release %s (released %s)' % (self.version, release_date)
|
||||
|
||||
with open(self.path, 'r+') as f:
|
||||
f.readline() # skip first two lines
|
||||
f.readline()
|
||||
body = f.read()
|
||||
|
||||
f.seek(0)
|
||||
f.truncate(0)
|
||||
f.write(heading + '\n')
|
||||
f.write('=' * len(heading) + '\n')
|
||||
f.write(body)
|
||||
|
||||
def add_release(self, version_info):
|
||||
if version_info[-2:] in (('beta', 0), ('final', 0)):
|
||||
version = stringify_version(version_info)
|
||||
else:
|
||||
reltype = version_info[3]
|
||||
version = '%s %s%s' % (stringify_version(version_info),
|
||||
RELEASE_TYPE.get(reltype, reltype),
|
||||
version_info[4] or '')
|
||||
heading = 'Release %s (in development)' % version
|
||||
|
||||
with open(os.path.join(script_dir, 'CHANGES_template')) as f:
|
||||
f.readline() # skip first two lines
|
||||
f.readline()
|
||||
tmpl = f.read()
|
||||
|
||||
with open(self.path, 'r+') as f:
|
||||
body = f.read()
|
||||
|
||||
f.seek(0)
|
||||
f.truncate(0)
|
||||
f.write(heading + '\n')
|
||||
f.write('=' * len(heading) + '\n')
|
||||
f.write(tmpl)
|
||||
f.write('\n')
|
||||
f.write(body)
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) != 2:
|
||||
print("bump_version.py [version]")
|
||||
return -1
|
||||
|
||||
version_info = parse_version(sys.argv[-1])
|
||||
|
||||
with processing("Rewriting sphinx/__init__.py"):
|
||||
bump_version(os.path.join(package_dir, 'sphinx/__init__.py'), version_info)
|
||||
|
||||
with processing('Rewriting CHANGES'):
|
||||
changes = Changes(os.path.join(package_dir, 'CHANGES'))
|
||||
if changes.version_info == version_info:
|
||||
if changes.in_development:
|
||||
changes.finalize_release_date()
|
||||
else:
|
||||
raise Skip('version not changed')
|
||||
else:
|
||||
if changes.in_development:
|
||||
print('WARNING: last version is not released yet: %s' % changes.version)
|
||||
changes.add_release(version_info)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -9,19 +9,20 @@ Release checklist
|
||||
* Run `(cd sphinx/locale; tx pull -a -f)`
|
||||
* Run `python setup.py compile_catalog`
|
||||
|
||||
* Update version info in sphinx/__init__.py
|
||||
* Update release date in CHANGES
|
||||
* `python utils/bump_version.py x.y.z`
|
||||
* Check diff by `git diff`
|
||||
* `git commit -am 'Bump to x.y.z final'`
|
||||
* `make clean`
|
||||
* `python setup.py compile_grammar`
|
||||
* `python setup.py release bdist_wheel sdist upload --identity=[your key]`
|
||||
* Check PyPI release page for obvious errors
|
||||
* open https://pypi.python.org/pypi/Sphinx and check there are no obvious errors
|
||||
* `git tag x.y.z` with version number
|
||||
* Merge default into stable if final major release
|
||||
* `git push origin stable --tags`
|
||||
* open https://readthedocs.org/dashboard/sphinx/versions/ and enable the released version
|
||||
* Add new version/milestone to tracker categories
|
||||
* Update version info, add new CHANGES entry for next version
|
||||
* `python utils/bump_version.py a.b.cb0` (ex. 1.5.3b0)
|
||||
* Check diff by `git diff`
|
||||
* `git commit -am 'Bump version'`
|
||||
* `git push origin stable`
|
||||
* `git checkout master`
|
||||
|
||||
Reference in New Issue
Block a user