mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge branch 'master' into 4983_wrong_id_for_productionlist
This commit is contained in:
commit
af32786af1
21
CHANGES
21
CHANGES
@ -33,6 +33,7 @@ Incompatible changes
|
|||||||
:confval:`viewcode_follow_imported_members` (refs: #4035)
|
:confval:`viewcode_follow_imported_members` (refs: #4035)
|
||||||
* #1857: latex: :confval:`latex_show_pagerefs` does not add pagerefs for
|
* #1857: latex: :confval:`latex_show_pagerefs` does not add pagerefs for
|
||||||
citations
|
citations
|
||||||
|
* #4648: latex: Now "rubric" elements are rendered as unnumbered section title
|
||||||
* #4983: html: The URL for the productionlist has been changed
|
* #4983: html: The URL for the productionlist has been changed
|
||||||
|
|
||||||
Deprecated
|
Deprecated
|
||||||
@ -64,9 +65,14 @@ Deprecated
|
|||||||
* ``sphinx.writers.latex.Table.caption_footnotetexts`` is deprecated
|
* ``sphinx.writers.latex.Table.caption_footnotetexts`` is deprecated
|
||||||
* ``sphinx.writers.latex.Table.header_footnotetexts`` is deprecated
|
* ``sphinx.writers.latex.Table.header_footnotetexts`` is deprecated
|
||||||
* ``sphinx.writers.latex.LaTeXWriter.footnotestack`` is deprecated
|
* ``sphinx.writers.latex.LaTeXWriter.footnotestack`` is deprecated
|
||||||
|
* ``sphinx.writers.latex.LaTeXWriter.in_container_literal_block`` is deprecated
|
||||||
|
* ``sphinx.writers.latex.LaTeXWriter.next_section_ids`` is deprecated
|
||||||
|
* ``sphinx.writers.latex.LaTeXWriter.next_hyperlink_ids`` is deprecated
|
||||||
* ``sphinx.writers.latex.LaTeXWriter.restrict_footnote()`` is deprecated
|
* ``sphinx.writers.latex.LaTeXWriter.restrict_footnote()`` is deprecated
|
||||||
* ``sphinx.writers.latex.LaTeXWriter.unrestrict_footnote()`` is deprecated
|
* ``sphinx.writers.latex.LaTeXWriter.unrestrict_footnote()`` is deprecated
|
||||||
* ``LaTeXWriter.bibitems`` is deprecated
|
* ``sphinx.writers.latex.LaTeXWriter.push_hyperlink_ids()`` is deprecated
|
||||||
|
* ``sphinx.writers.latex.LaTeXWriter.pop_hyperlink_ids()`` is deprecated
|
||||||
|
* ``sphinx.writers.latex.LaTeXWriter.bibitems`` is deprecated
|
||||||
* ``BuildEnvironment.load()`` is deprecated
|
* ``BuildEnvironment.load()`` is deprecated
|
||||||
* ``BuildEnvironment.loads()`` is deprecated
|
* ``BuildEnvironment.loads()`` is deprecated
|
||||||
* ``BuildEnvironment.frompickle()`` is deprecated
|
* ``BuildEnvironment.frompickle()`` is deprecated
|
||||||
@ -113,6 +119,11 @@ Features added
|
|||||||
configuration file
|
configuration file
|
||||||
* #4866: Wrap graphviz diagrams in ``<div>`` tag
|
* #4866: Wrap graphviz diagrams in ``<div>`` tag
|
||||||
* Add :event:`viewcode-find-source` event to viewcode extension.
|
* Add :event:`viewcode-find-source` event to viewcode extension.
|
||||||
|
* #4785: napoleon: Add strings to translation file for localisation
|
||||||
|
* #4927: Display a warning when invalid values are passed to linenothreshold
|
||||||
|
option of highlight directive
|
||||||
|
* C++, add a ``cpp:texpr`` role as a sibling to ``cpp:expr``.
|
||||||
|
* C++, add support for unions.
|
||||||
|
|
||||||
Bugs fixed
|
Bugs fixed
|
||||||
----------
|
----------
|
||||||
@ -169,6 +180,14 @@ Bugs fixed
|
|||||||
* #4979: latex: Incorrect escaping of curly braces in index entries
|
* #4979: latex: Incorrect escaping of curly braces in index entries
|
||||||
* #4956: autodoc: Failed to extract document from a subclass of the class on
|
* #4956: autodoc: Failed to extract document from a subclass of the class on
|
||||||
mocked module
|
mocked module
|
||||||
|
* #4973: latex: glossary directive adds whitespace to each item
|
||||||
|
* #4980: latex: Explicit labels on code blocks are duplicated
|
||||||
|
* #4919: node.asdom() crashes if toctree has :numbered: option
|
||||||
|
* #4914: autodoc: Parsing error when using dataclasses without default values
|
||||||
|
* #4931: autodoc: crashed when handler for autodoc-skip-member raises an error
|
||||||
|
* #4931: autodoc: crashed when subclass of mocked class are processed by
|
||||||
|
napoleon module
|
||||||
|
* #5007: sphinx-build crashes when error log contains a "%" character
|
||||||
|
|
||||||
Testing
|
Testing
|
||||||
--------
|
--------
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
# You can set these variables from the command line.
|
# You can set these variables from the command line.
|
||||||
SPHINXOPTS =
|
SPHINXOPTS =
|
||||||
SPHINXBUILD = python ../sphinx/cmd/build.py
|
SPHINXBUILD = python3 ../sphinx/cmd/build.py
|
||||||
SPHINXPROJ = sphinx
|
SPHINXPROJ = sphinx
|
||||||
SOURCEDIR = .
|
SOURCEDIR = .
|
||||||
BUILDDIR = _build
|
BUILDDIR = _build
|
||||||
|
@ -73,7 +73,7 @@ package.
|
|||||||
|
|
||||||
.. automethod:: Sphinx.add_javascript(filename)
|
.. automethod:: Sphinx.add_javascript(filename)
|
||||||
|
|
||||||
.. automethod:: Sphinx.add_stylesheet(filename, alternate=None, title=None)
|
.. automethod:: Sphinx.add_css_file(filename, **kwargs)
|
||||||
|
|
||||||
.. automethod:: Sphinx.add_latex_package(packagename, options=None)
|
.. automethod:: Sphinx.add_latex_package(packagename, options=None)
|
||||||
|
|
||||||
|
@ -171,6 +171,21 @@ The following is a list of deprecated interface.
|
|||||||
- 3.0
|
- 3.0
|
||||||
- N/A
|
- N/A
|
||||||
|
|
||||||
|
* - ``sphinx.writers.latex.LaTeXWriter.in_container_literal_block``
|
||||||
|
- 1.8
|
||||||
|
- 3.0
|
||||||
|
- N/A
|
||||||
|
|
||||||
|
* - ``sphinx.writers.latex.LaTeXWriter.next_section_ids``
|
||||||
|
- 1.8
|
||||||
|
- 3.0
|
||||||
|
- N/A
|
||||||
|
|
||||||
|
* - ``sphinx.writers.latex.LaTeXWriter.next_hyperlink_ids``
|
||||||
|
- 1.8
|
||||||
|
- 3.0
|
||||||
|
- N/A
|
||||||
|
|
||||||
* - ``sphinx.writers.latex.LaTeXWriter.restrict_footnote()``
|
* - ``sphinx.writers.latex.LaTeXWriter.restrict_footnote()``
|
||||||
- 1.8
|
- 1.8
|
||||||
- 3.0
|
- 3.0
|
||||||
@ -181,6 +196,16 @@ The following is a list of deprecated interface.
|
|||||||
- 3.0
|
- 3.0
|
||||||
- N/A
|
- N/A
|
||||||
|
|
||||||
|
* - ``sphinx.writers.latex.LaTeXWriter.push_hyperlink_ids()``
|
||||||
|
- 1.8
|
||||||
|
- 3.0
|
||||||
|
- N/A
|
||||||
|
|
||||||
|
* - ``sphinx.writers.latex.LaTeXWriter.pop_hyperlink_ids()``
|
||||||
|
- 1.8
|
||||||
|
- 3.0
|
||||||
|
- N/A
|
||||||
|
|
||||||
* - ``sphinx.writers.latex.LaTeXWriter.bibitems``
|
* - ``sphinx.writers.latex.LaTeXWriter.bibitems``
|
||||||
- 1.8
|
- 1.8
|
||||||
- 3.0
|
- 3.0
|
||||||
|
@ -569,10 +569,10 @@ visibility statement (``public``, ``private`` or ``protected``).
|
|||||||
Full and partial template specialisations can be declared::
|
Full and partial template specialisations can be declared::
|
||||||
|
|
||||||
.. cpp:class:: template<> \
|
.. cpp:class:: template<> \
|
||||||
std::array<bool, 256>
|
std::array<bool, 256>
|
||||||
|
|
||||||
.. cpp:class:: template<typename T> \
|
.. cpp:class:: template<typename T> \
|
||||||
std::array<T, 42>
|
std::array<T, 42>
|
||||||
|
|
||||||
.. rst:directive:: .. cpp:function:: (member) function prototype
|
.. rst:directive:: .. cpp:function:: (member) function prototype
|
||||||
|
|
||||||
@ -702,6 +702,10 @@ visibility statement (``public``, ``private`` or ``protected``).
|
|||||||
|
|
||||||
.. cpp:enumerator:: MyEnum::myOtherEnumerator = 42
|
.. cpp:enumerator:: MyEnum::myOtherEnumerator = 42
|
||||||
|
|
||||||
|
.. rst:directive:: .. cpp:union:: name
|
||||||
|
|
||||||
|
Describe a union.
|
||||||
|
|
||||||
.. rst:directive:: .. cpp:concept:: template-parameter-list name
|
.. rst:directive:: .. cpp:concept:: template-parameter-list name
|
||||||
|
|
||||||
.. warning:: The support for concepts is experimental. It is based on the
|
.. warning:: The support for concepts is experimental. It is based on the
|
||||||
@ -815,24 +819,31 @@ Inline Expressions and Tpes
|
|||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
.. rst:role:: cpp:expr
|
.. rst:role:: cpp:expr
|
||||||
|
cpp:texpr
|
||||||
|
|
||||||
A role for inserting a C++ expression or type as inline text. For example::
|
Insert a C++ expression or type either as inline code (``cpp:expr``)
|
||||||
|
or inline text (``cpp:texpr``). For example::
|
||||||
|
|
||||||
.. cpp:var:: int a = 42
|
.. cpp:var:: int a = 42
|
||||||
|
|
||||||
.. cpp:function:: int f(int i)
|
.. cpp:function:: int f(int i)
|
||||||
|
|
||||||
An expression: :cpp:expr:`a * f(a)`.
|
An expression: :cpp:expr:`a * f(a)` (or as text: :cpp:texpr:`a * f(a)`).
|
||||||
A type: :cpp:expr:`const MySortedContainer<int>&`.
|
|
||||||
|
A type: :cpp:expr:`const MySortedContainer<int>&`
|
||||||
|
(or as text :cpp:texpr:`const MySortedContainer<int>&`).
|
||||||
|
|
||||||
will be rendered as follows:
|
will be rendered as follows:
|
||||||
|
|
||||||
.. cpp:var:: int a = 42
|
.. cpp:var:: int a = 42
|
||||||
|
|
||||||
.. cpp:function:: int f(int i)
|
.. cpp:function:: int f(int i)
|
||||||
|
|
||||||
|
An expression: :cpp:expr:`a * f(a)` (or as text: :cpp:texpr:`a * f(a)`).
|
||||||
|
|
||||||
|
A type: :cpp:expr:`const MySortedContainer<int>&`
|
||||||
|
(or as text :cpp:texpr:`const MySortedContainer<int>&`).
|
||||||
|
|
||||||
An expression: :cpp:expr:`a * f(a)`. A type: :cpp:expr:`const
|
|
||||||
MySortedContainer<int>&`.
|
|
||||||
|
|
||||||
Namespacing
|
Namespacing
|
||||||
~~~~~~~~~~~
|
~~~~~~~~~~~
|
||||||
@ -880,7 +891,7 @@ The ``cpp:namespace-pop`` directive undoes the most recent
|
|||||||
|
|
||||||
.. cpp:function:: std::size_t size() const
|
.. cpp:function:: std::size_t size() const
|
||||||
|
|
||||||
or:::
|
or::
|
||||||
|
|
||||||
.. cpp:class:: template<typename T> \
|
.. cpp:class:: template<typename T> \
|
||||||
std::vector
|
std::vector
|
||||||
@ -949,20 +960,23 @@ These roles link to the given declaration types:
|
|||||||
|
|
||||||
.. admonition:: Note on References with Templates Parameters/Arguments
|
.. admonition:: Note on References with Templates Parameters/Arguments
|
||||||
|
|
||||||
Sphinx's syntax to give references a custom title can interfere with linking
|
These roles follow the Sphinx :ref:`xref-syntax` rules. This means care must be
|
||||||
to class templates, if nothing follows the closing angle bracket, i.e. if
|
taken when referencing a (partial) template specialization, e.g. if the link looks like
|
||||||
the link looks like this: ``:cpp:class:`MyClass<int>```. This is
|
this: ``:cpp:class:`MyClass<int>```.
|
||||||
interpreted as a link to ``int`` with a title of ``MyClass``. In this case,
|
This is interpreted as a link to ``int`` with a title of ``MyClass``.
|
||||||
please escape the opening angle bracket with a backslash, like this:
|
In this case, escape the opening angle bracket with a backslash,
|
||||||
``:cpp:class:`MyClass\<int>```.
|
like this: ``:cpp:class:`MyClass\<int>```.
|
||||||
|
|
||||||
|
When a custom title is not needed it may be useful to use the roles for inline expressions,
|
||||||
|
:rst:role:`cpp:expr` and :rst:role:`cpp:texpr`, where angle brackets do not need escaping.
|
||||||
|
|
||||||
.. admonition:: Note on References to Overloaded Functions
|
.. admonition:: Note on References to Overloaded Functions
|
||||||
|
|
||||||
It is currently impossible to link to a specific version of an overloaded
|
It is currently impossible to link to a specific version of an overloaded
|
||||||
method. Currently the C++ domain is the first domain that has basic support
|
function. Currently the C++ domain is the first domain that has basic
|
||||||
for overloaded methods and until there is more data for comparison we don't
|
support for overloaded functions and until there is more data for comparison
|
||||||
want to select a bad syntax to reference a specific overload. Currently
|
we don't want to select a bad syntax to reference a specific overload.
|
||||||
Sphinx will link to the first overloaded version of the method / function.
|
Currently Sphinx will link to the first overloaded version of the function.
|
||||||
|
|
||||||
Declarations without template parameters and template arguments
|
Declarations without template parameters and template arguments
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
@ -983,13 +997,13 @@ Assume the following declarations.
|
|||||||
.. cpp:class:: template<typename TInner> \
|
.. cpp:class:: template<typename TInner> \
|
||||||
Inner
|
Inner
|
||||||
|
|
||||||
In general the reference must include the template paraemter declarations,
|
In general the reference must include the template parameter declarations,
|
||||||
e.g., ``template\<typename TOuter> Wrapper::Outer``
|
e.g., ``template\<typename TOuter> Wrapper::Outer``
|
||||||
(:cpp:class:`template\<typename TOuter> Wrapper::Outer`). Currently the lookup
|
(:cpp:class:`template\<typename TOuter> Wrapper::Outer`). Currently the lookup
|
||||||
only succeed if the template parameter identifiers are equal strings. That is,
|
only succeed if the template parameter identifiers are equal strings. That is,
|
||||||
``template\<typename UOuter> Wrapper::Outer`` will not work.
|
``template\<typename UOuter> Wrapper::Outer`` will not work.
|
||||||
|
|
||||||
The inner class template can not be directly referenced, unless the current
|
The inner class template cannot be directly referenced, unless the current
|
||||||
namespace is changed or the following shorthand is used. If a template
|
namespace is changed or the following shorthand is used. If a template
|
||||||
parameter list is omitted, then the lookup will assume either a template or a
|
parameter list is omitted, then the lookup will assume either a template or a
|
||||||
non-template, but not a partial template specialisation. This means the
|
non-template, but not a partial template specialisation. This means the
|
||||||
|
@ -20,7 +20,8 @@ from sphinx import package_dir, addnodes, highlighting
|
|||||||
from sphinx.builders import Builder
|
from sphinx.builders import Builder
|
||||||
from sphinx.builders.latex.transforms import (
|
from sphinx.builders.latex.transforms import (
|
||||||
BibliographyTransform, CitationReferenceTransform, MathReferenceTransform,
|
BibliographyTransform, CitationReferenceTransform, MathReferenceTransform,
|
||||||
FootnoteDocnameUpdater, LaTeXFootnoteTransform, ShowUrlsTransform
|
FootnoteDocnameUpdater, LaTeXFootnoteTransform, LiteralBlockTransform,
|
||||||
|
ShowUrlsTransform, DocumentTargetTransform,
|
||||||
)
|
)
|
||||||
from sphinx.config import string_classes, ENUM
|
from sphinx.config import string_classes, ENUM
|
||||||
from sphinx.environment import NoUri
|
from sphinx.environment import NoUri
|
||||||
@ -223,7 +224,9 @@ class LaTeXBuilder(Builder):
|
|||||||
transformer.set_environment(self.env)
|
transformer.set_environment(self.env)
|
||||||
transformer.add_transforms([BibliographyTransform,
|
transformer.add_transforms([BibliographyTransform,
|
||||||
ShowUrlsTransform,
|
ShowUrlsTransform,
|
||||||
LaTeXFootnoteTransform])
|
LaTeXFootnoteTransform,
|
||||||
|
LiteralBlockTransform,
|
||||||
|
DocumentTargetTransform])
|
||||||
transformer.apply_transforms()
|
transformer.apply_transforms()
|
||||||
|
|
||||||
def finish(self):
|
def finish(self):
|
||||||
|
@ -12,6 +12,11 @@
|
|||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
|
|
||||||
|
|
||||||
|
class captioned_literal_block(nodes.container):
|
||||||
|
"""A node for a container of literal_block having a caption."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class footnotemark(nodes.Inline, nodes.Referential, nodes.TextElement):
|
class footnotemark(nodes.Inline, nodes.Referential, nodes.TextElement):
|
||||||
"""A node represents ``\footnotemark``."""
|
"""A node represents ``\footnotemark``."""
|
||||||
pass
|
pass
|
||||||
|
@ -13,7 +13,7 @@ from docutils import nodes
|
|||||||
|
|
||||||
from sphinx import addnodes
|
from sphinx import addnodes
|
||||||
from sphinx.builders.latex.nodes import (
|
from sphinx.builders.latex.nodes import (
|
||||||
footnotemark, footnotetext, math_reference, thebibliography
|
captioned_literal_block, footnotemark, footnotetext, math_reference, thebibliography
|
||||||
)
|
)
|
||||||
from sphinx.transforms import SphinxTransform
|
from sphinx.transforms import SphinxTransform
|
||||||
|
|
||||||
@ -566,3 +566,33 @@ class MathReferenceTransform(SphinxTransform):
|
|||||||
if docname:
|
if docname:
|
||||||
refnode = math_reference('', docname=docname, target=node['reftarget'])
|
refnode = math_reference('', docname=docname, target=node['reftarget'])
|
||||||
node.replace_self(refnode)
|
node.replace_self(refnode)
|
||||||
|
|
||||||
|
|
||||||
|
class LiteralBlockTransform(SphinxTransform):
|
||||||
|
"""Replace container nodes for literal_block by captioned_literal_block."""
|
||||||
|
default_priority = 400
|
||||||
|
|
||||||
|
def apply(self):
|
||||||
|
# type: () -> None
|
||||||
|
if self.app.builder.name != 'latex':
|
||||||
|
return
|
||||||
|
|
||||||
|
for node in self.document.traverse(nodes.container):
|
||||||
|
if node['literal_block'] is True:
|
||||||
|
newnode = captioned_literal_block('', *node.children, **node.attributes)
|
||||||
|
node.replace_self(newnode)
|
||||||
|
|
||||||
|
|
||||||
|
class DocumentTargetTransform(SphinxTransform):
|
||||||
|
"""Add :doc label to the first section of each document."""
|
||||||
|
default_priority = 400
|
||||||
|
|
||||||
|
def apply(self):
|
||||||
|
# type: () -> None
|
||||||
|
if self.app.builder.name != 'latex':
|
||||||
|
return
|
||||||
|
|
||||||
|
for node in self.document.traverse(addnodes.start_of_file):
|
||||||
|
section = node.next_node(nodes.section)
|
||||||
|
if section:
|
||||||
|
section['ids'].append(':doc') # special label for :doc:
|
||||||
|
@ -45,18 +45,12 @@ class Highlight(SphinxDirective):
|
|||||||
optional_arguments = 0
|
optional_arguments = 0
|
||||||
final_argument_whitespace = False
|
final_argument_whitespace = False
|
||||||
option_spec = {
|
option_spec = {
|
||||||
'linenothreshold': directives.unchanged,
|
'linenothreshold': directives.positive_int,
|
||||||
}
|
}
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
# type: () -> List[nodes.Node]
|
# type: () -> List[nodes.Node]
|
||||||
if 'linenothreshold' in self.options:
|
linenothreshold = self.options.get('linenothreshold', sys.maxsize)
|
||||||
try:
|
|
||||||
linenothreshold = int(self.options['linenothreshold'])
|
|
||||||
except Exception:
|
|
||||||
linenothreshold = 10
|
|
||||||
else:
|
|
||||||
linenothreshold = sys.maxsize
|
|
||||||
return [addnodes.highlightlang(lang=self.arguments[0].strip(),
|
return [addnodes.highlightlang(lang=self.arguments[0].strip(),
|
||||||
linenothreshold=linenothreshold)]
|
linenothreshold=linenothreshold)]
|
||||||
|
|
||||||
|
@ -3196,6 +3196,27 @@ class ASTClass(ASTBase):
|
|||||||
signode.pop()
|
signode.pop()
|
||||||
|
|
||||||
|
|
||||||
|
class ASTUnion(ASTBase):
|
||||||
|
def __init__(self, name):
|
||||||
|
# type: (Any) -> None
|
||||||
|
self.name = name
|
||||||
|
|
||||||
|
def get_id(self, version, objectType, symbol):
|
||||||
|
# type: (int, unicode, Symbol) -> unicode
|
||||||
|
if version == 1:
|
||||||
|
raise NoOldIdError()
|
||||||
|
return symbol.get_full_nested_name().get_id(version)
|
||||||
|
|
||||||
|
def __unicode__(self):
|
||||||
|
# type: () -> unicode
|
||||||
|
return text_type(self.name)
|
||||||
|
|
||||||
|
def describe_signature(self, signode, mode, env, symbol):
|
||||||
|
# type: (addnodes.desc_signature, unicode, BuildEnvironment, Symbol) -> None
|
||||||
|
_verify_description_mode(mode)
|
||||||
|
self.name.describe_signature(signode, mode, env, symbol=symbol)
|
||||||
|
|
||||||
|
|
||||||
class ASTEnum(ASTBase):
|
class ASTEnum(ASTBase):
|
||||||
def __init__(self, name, scoped, underlyingType):
|
def __init__(self, name, scoped, underlyingType):
|
||||||
# type: (Any, unicode, Any) -> None
|
# type: (Any, unicode, Any) -> None
|
||||||
@ -3361,6 +3382,8 @@ class ASTDeclaration(ASTBase):
|
|||||||
pass
|
pass
|
||||||
elif self.objectType == 'class':
|
elif self.objectType == 'class':
|
||||||
mainDeclNode += addnodes.desc_annotation('class ', 'class ')
|
mainDeclNode += addnodes.desc_annotation('class ', 'class ')
|
||||||
|
elif self.objectType == 'union':
|
||||||
|
mainDeclNode += addnodes.desc_annotation('union ', 'union ')
|
||||||
elif self.objectType == 'enum':
|
elif self.objectType == 'enum':
|
||||||
prefix = 'enum '
|
prefix = 'enum '
|
||||||
if self.scoped: # type: ignore
|
if self.scoped: # type: ignore
|
||||||
@ -5259,6 +5282,11 @@ class DefinitionParser(object):
|
|||||||
break
|
break
|
||||||
return ASTClass(name, final, bases)
|
return ASTClass(name, final, bases)
|
||||||
|
|
||||||
|
def _parse_union(self):
|
||||||
|
# type: () -> ASTUnion
|
||||||
|
name = self._parse_nested_name()
|
||||||
|
return ASTUnion(name)
|
||||||
|
|
||||||
def _parse_enum(self):
|
def _parse_enum(self):
|
||||||
# type: () -> ASTEnum
|
# type: () -> ASTEnum
|
||||||
scoped = None # type: unicode # is set by CPPEnumObject
|
scoped = None # type: unicode # is set by CPPEnumObject
|
||||||
@ -5466,7 +5494,7 @@ class DefinitionParser(object):
|
|||||||
def parse_declaration(self, objectType):
|
def parse_declaration(self, objectType):
|
||||||
# type: (unicode) -> ASTDeclaration
|
# type: (unicode) -> ASTDeclaration
|
||||||
if objectType not in ('type', 'concept', 'member',
|
if objectType not in ('type', 'concept', 'member',
|
||||||
'function', 'class', 'enum', 'enumerator'):
|
'function', 'class', 'union', 'enum', 'enumerator'):
|
||||||
raise Exception('Internal error, unknown objectType "%s".' % objectType)
|
raise Exception('Internal error, unknown objectType "%s".' % objectType)
|
||||||
visibility = None
|
visibility = None
|
||||||
templatePrefix = None
|
templatePrefix = None
|
||||||
@ -5505,6 +5533,8 @@ class DefinitionParser(object):
|
|||||||
declaration = self._parse_type(named=True, outer='function')
|
declaration = self._parse_type(named=True, outer='function')
|
||||||
elif objectType == 'class':
|
elif objectType == 'class':
|
||||||
declaration = self._parse_class()
|
declaration = self._parse_class()
|
||||||
|
elif objectType == 'union':
|
||||||
|
declaration = self._parse_union()
|
||||||
elif objectType == 'enum':
|
elif objectType == 'enum':
|
||||||
declaration = self._parse_enum()
|
declaration = self._parse_enum()
|
||||||
elif objectType == 'enumerator':
|
elif objectType == 'enumerator':
|
||||||
@ -5807,6 +5837,16 @@ class CPPClassObject(CPPObject):
|
|||||||
return parser.parse_declaration("class")
|
return parser.parse_declaration("class")
|
||||||
|
|
||||||
|
|
||||||
|
class CPPUnionObject(CPPObject):
|
||||||
|
def get_index_text(self, name):
|
||||||
|
# type: (unicode) -> unicode
|
||||||
|
return _('%s (C++ union)') % name
|
||||||
|
|
||||||
|
def parse_definition(self, parser):
|
||||||
|
# type: (Any) -> Any
|
||||||
|
return parser.parse_declaration("union")
|
||||||
|
|
||||||
|
|
||||||
class CPPEnumObject(CPPObject):
|
class CPPEnumObject(CPPObject):
|
||||||
def get_index_text(self, name):
|
def get_index_text(self, name):
|
||||||
# type: (unicode) -> unicode
|
# type: (unicode) -> unicode
|
||||||
@ -5965,6 +6005,16 @@ class CPPXRefRole(XRefRole):
|
|||||||
|
|
||||||
|
|
||||||
class CPPExprRole(object):
|
class CPPExprRole(object):
|
||||||
|
def __init__(self, asCode):
|
||||||
|
if asCode:
|
||||||
|
# render the expression as inline code
|
||||||
|
self.class_type = 'cpp-expr'
|
||||||
|
self.node_type = nodes.literal
|
||||||
|
else:
|
||||||
|
# render the expression as inline text
|
||||||
|
self.class_type = 'cpp-texpr'
|
||||||
|
self.node_type = nodes.inline
|
||||||
|
|
||||||
def __call__(self, typ, rawtext, text, lineno, inliner, options={}, content=[]):
|
def __call__(self, typ, rawtext, text, lineno, inliner, options={}, content=[]):
|
||||||
class Warner(object):
|
class Warner(object):
|
||||||
def warn(self, msg):
|
def warn(self, msg):
|
||||||
@ -5972,18 +6022,23 @@ class CPPExprRole(object):
|
|||||||
text = utils.unescape(text).replace('\n', ' ')
|
text = utils.unescape(text).replace('\n', ' ')
|
||||||
env = inliner.document.settings.env
|
env = inliner.document.settings.env
|
||||||
parser = DefinitionParser(text, Warner(), env.config)
|
parser = DefinitionParser(text, Warner(), env.config)
|
||||||
|
# attempt to mimic XRefRole classes, except that...
|
||||||
|
classes = ['xref', 'cpp', self.class_type]
|
||||||
try:
|
try:
|
||||||
ast = parser.parse_expression()
|
ast = parser.parse_expression()
|
||||||
except DefinitionError as ex:
|
except DefinitionError as ex:
|
||||||
Warner().warn('Unparseable C++ expression: %r\n%s'
|
Warner().warn('Unparseable C++ expression: %r\n%s'
|
||||||
% (text, text_type(ex.description)))
|
% (text, text_type(ex.description)))
|
||||||
return [nodes.literal(text)], []
|
# see below
|
||||||
|
return [self.node_type(text, text, classes=classes)], []
|
||||||
parentSymbol = env.temp_data.get('cpp:parent_symbol', None)
|
parentSymbol = env.temp_data.get('cpp:parent_symbol', None)
|
||||||
if parentSymbol is None:
|
if parentSymbol is None:
|
||||||
parentSymbol = env.domaindata['cpp']['root_symbol']
|
parentSymbol = env.domaindata['cpp']['root_symbol']
|
||||||
p = nodes.literal()
|
# ...most if not all of these classes should really apply to the individual references,
|
||||||
ast.describe_signature(p, 'markType', env, parentSymbol)
|
# not the container node
|
||||||
return [p], []
|
signode = self.node_type(classes=classes)
|
||||||
|
ast.describe_signature(signode, 'markType', env, parentSymbol)
|
||||||
|
return [signode], []
|
||||||
|
|
||||||
|
|
||||||
class CPPDomain(Domain):
|
class CPPDomain(Domain):
|
||||||
@ -5992,6 +6047,7 @@ class CPPDomain(Domain):
|
|||||||
label = 'C++'
|
label = 'C++'
|
||||||
object_types = {
|
object_types = {
|
||||||
'class': ObjType(_('class'), 'class', 'type', 'identifier'),
|
'class': ObjType(_('class'), 'class', 'type', 'identifier'),
|
||||||
|
'union': ObjType(_('union'), 'union', 'type', 'identifier'),
|
||||||
'function': ObjType(_('function'), 'function', 'func', 'type', 'identifier'),
|
'function': ObjType(_('function'), 'function', 'func', 'type', 'identifier'),
|
||||||
'member': ObjType(_('member'), 'member', 'var'),
|
'member': ObjType(_('member'), 'member', 'var'),
|
||||||
'type': ObjType(_('type'), 'type', 'identifier'),
|
'type': ObjType(_('type'), 'type', 'identifier'),
|
||||||
@ -6002,6 +6058,7 @@ class CPPDomain(Domain):
|
|||||||
|
|
||||||
directives = {
|
directives = {
|
||||||
'class': CPPClassObject,
|
'class': CPPClassObject,
|
||||||
|
'union': CPPUnionObject,
|
||||||
'function': CPPFunctionObject,
|
'function': CPPFunctionObject,
|
||||||
'member': CPPMemberObject,
|
'member': CPPMemberObject,
|
||||||
'var': CPPMemberObject,
|
'var': CPPMemberObject,
|
||||||
@ -6018,6 +6075,7 @@ class CPPDomain(Domain):
|
|||||||
roles = {
|
roles = {
|
||||||
'any': CPPXRefRole(),
|
'any': CPPXRefRole(),
|
||||||
'class': CPPXRefRole(),
|
'class': CPPXRefRole(),
|
||||||
|
'union': CPPXRefRole(),
|
||||||
'func': CPPXRefRole(fix_parens=True),
|
'func': CPPXRefRole(fix_parens=True),
|
||||||
'member': CPPXRefRole(),
|
'member': CPPXRefRole(),
|
||||||
'var': CPPXRefRole(),
|
'var': CPPXRefRole(),
|
||||||
@ -6025,7 +6083,8 @@ class CPPDomain(Domain):
|
|||||||
'concept': CPPXRefRole(),
|
'concept': CPPXRefRole(),
|
||||||
'enum': CPPXRefRole(),
|
'enum': CPPXRefRole(),
|
||||||
'enumerator': CPPXRefRole(),
|
'enumerator': CPPXRefRole(),
|
||||||
'expr': CPPExprRole()
|
'expr': CPPExprRole(asCode=True),
|
||||||
|
'texpr': CPPExprRole(asCode=False)
|
||||||
}
|
}
|
||||||
initial_data = {
|
initial_data = {
|
||||||
'root_symbol': Symbol(None, None, None, None, None, None),
|
'root_symbol': Symbol(None, None, None, None, None, None),
|
||||||
|
@ -313,19 +313,6 @@ class BuildEnvironment(object):
|
|||||||
"""Like :meth:`warn`, but with source information taken from *node*."""
|
"""Like :meth:`warn`, but with source information taken from *node*."""
|
||||||
self._warnfunc(msg, '%s:%s' % get_source_line(node), **kwargs)
|
self._warnfunc(msg, '%s:%s' % get_source_line(node), **kwargs)
|
||||||
|
|
||||||
def need_refresh(self, app):
|
|
||||||
# type: (Sphinx) -> Tuple[bool, unicode]
|
|
||||||
"""Check refresh environment is needed.
|
|
||||||
|
|
||||||
If needed, this method returns the reason for refresh.
|
|
||||||
"""
|
|
||||||
if self.version != app.registry.get_envversion(app):
|
|
||||||
return True, __('build environment version not current')
|
|
||||||
elif self.srcdir != app.srcdir:
|
|
||||||
return True, __('source directory has changed')
|
|
||||||
else:
|
|
||||||
return False, None
|
|
||||||
|
|
||||||
def clear_doc(self, docname):
|
def clear_doc(self, docname):
|
||||||
# type: (unicode) -> None
|
# type: (unicode) -> None
|
||||||
"""Remove all traces of a source file in the inventory."""
|
"""Remove all traces of a source file in the inventory."""
|
||||||
|
@ -172,10 +172,10 @@ class TocTreeCollector(EnvironmentCollector):
|
|||||||
number = tuple(numstack)
|
number = tuple(numstack)
|
||||||
else:
|
else:
|
||||||
number = None
|
number = None
|
||||||
secnums[subnode[0]['anchorname']] = \
|
secnums[subnode[0]['anchorname']] = number
|
||||||
subnode[0]['secnumber'] = number
|
subnode[0]['secnumber'] = list(number)
|
||||||
if titlenode:
|
if titlenode:
|
||||||
titlenode['secnumber'] = number
|
titlenode['secnumber'] = list(number)
|
||||||
titlenode = None
|
titlenode = None
|
||||||
elif isinstance(subnode, addnodes.toctree):
|
elif isinstance(subnode, addnodes.toctree):
|
||||||
_walk_toctree(subnode, depth)
|
_walk_toctree(subnode, depth)
|
||||||
|
@ -643,11 +643,17 @@ class Documenter(object):
|
|||||||
# should be skipped
|
# should be skipped
|
||||||
if self.env.app:
|
if self.env.app:
|
||||||
# let extensions preprocess docstrings
|
# let extensions preprocess docstrings
|
||||||
skip_user = self.env.app.emit_firstresult(
|
try:
|
||||||
'autodoc-skip-member', self.objtype, membername, member,
|
skip_user = self.env.app.emit_firstresult(
|
||||||
not keep, self.options)
|
'autodoc-skip-member', self.objtype, membername, member,
|
||||||
if skip_user is not None:
|
not keep, self.options)
|
||||||
keep = not skip_user
|
if skip_user is not None:
|
||||||
|
keep = not skip_user
|
||||||
|
except Exception as exc:
|
||||||
|
logger.warning(__('autodoc: failed to determine %r to be documented.'
|
||||||
|
'the following exception was raised:\n%s'),
|
||||||
|
member, exc)
|
||||||
|
keep = False
|
||||||
|
|
||||||
if keep:
|
if keep:
|
||||||
ret.append((membername, member, isattr))
|
ret.append((membername, member, isattr))
|
||||||
|
@ -23,7 +23,7 @@ from sphinx.util.inspect import isenumclass, safe_getattr
|
|||||||
|
|
||||||
if False:
|
if False:
|
||||||
# For type annotation
|
# For type annotation
|
||||||
from typing import Any, Callable, Dict, Generator, List, Optional, Tuple # NOQA
|
from typing import Any, Callable, Dict, Generator, Iterator, List, Optional, Tuple # NOQA
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ class _MockObject(object):
|
|||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
# type: (Any, Any) -> None
|
# type: (Any, Any) -> None
|
||||||
pass
|
self.__qualname__ = ''
|
||||||
|
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
# type: () -> int
|
# type: () -> int
|
||||||
@ -52,8 +52,8 @@ class _MockObject(object):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
# type: () -> None
|
# type: () -> Iterator
|
||||||
pass
|
return iter([])
|
||||||
|
|
||||||
def __mro_entries__(self, bases):
|
def __mro_entries__(self, bases):
|
||||||
# type: (Tuple) -> Tuple
|
# type: (Tuple) -> Tuple
|
||||||
|
@ -20,6 +20,7 @@ from six import string_types, u
|
|||||||
from six.moves import range
|
from six.moves import range
|
||||||
|
|
||||||
from sphinx.ext.napoleon.iterators import modify_iter
|
from sphinx.ext.napoleon.iterators import modify_iter
|
||||||
|
from sphinx.locale import _
|
||||||
from sphinx.util.pycompat import UnicodeMixin
|
from sphinx.util.pycompat import UnicodeMixin
|
||||||
|
|
||||||
if False:
|
if False:
|
||||||
@ -614,8 +615,13 @@ class GoogleDocstring(UnicodeMixin):
|
|||||||
|
|
||||||
def _parse_examples_section(self, section):
|
def _parse_examples_section(self, section):
|
||||||
# type: (unicode) -> List[unicode]
|
# type: (unicode) -> List[unicode]
|
||||||
|
labels = {
|
||||||
|
'example': _('Example'),
|
||||||
|
'examples': _('Examples'),
|
||||||
|
} # type: Dict[unicode, unicode]
|
||||||
use_admonition = self._config.napoleon_use_admonition_for_examples
|
use_admonition = self._config.napoleon_use_admonition_for_examples
|
||||||
return self._parse_generic_section(section, use_admonition)
|
label = labels.get(section.lower(), section)
|
||||||
|
return self._parse_generic_section(label, use_admonition)
|
||||||
|
|
||||||
def _parse_custom_generic_section(self, section):
|
def _parse_custom_generic_section(self, section):
|
||||||
# for now, no admonition for simple custom sections
|
# for now, no admonition for simple custom sections
|
||||||
@ -652,12 +658,12 @@ class GoogleDocstring(UnicodeMixin):
|
|||||||
field_role="keyword",
|
field_role="keyword",
|
||||||
type_role="kwtype")
|
type_role="kwtype")
|
||||||
else:
|
else:
|
||||||
return self._format_fields('Keyword Arguments', fields)
|
return self._format_fields(_('Keyword Arguments'), fields)
|
||||||
|
|
||||||
def _parse_methods_section(self, section):
|
def _parse_methods_section(self, section):
|
||||||
# type: (unicode) -> List[unicode]
|
# type: (unicode) -> List[unicode]
|
||||||
lines = [] # type: List[unicode]
|
lines = [] # type: List[unicode]
|
||||||
for _name, _, _desc in self._consume_fields(parse_type=False):
|
for _name, _type, _desc in self._consume_fields(parse_type=False):
|
||||||
lines.append('.. method:: %s' % _name)
|
lines.append('.. method:: %s' % _name)
|
||||||
if _desc:
|
if _desc:
|
||||||
lines.extend([u''] + self._indent(_desc, 3))
|
lines.extend([u''] + self._indent(_desc, 3))
|
||||||
@ -667,11 +673,11 @@ class GoogleDocstring(UnicodeMixin):
|
|||||||
def _parse_notes_section(self, section):
|
def _parse_notes_section(self, section):
|
||||||
# type: (unicode) -> List[unicode]
|
# type: (unicode) -> List[unicode]
|
||||||
use_admonition = self._config.napoleon_use_admonition_for_notes
|
use_admonition = self._config.napoleon_use_admonition_for_notes
|
||||||
return self._parse_generic_section('Notes', use_admonition)
|
return self._parse_generic_section(_('Notes'), use_admonition)
|
||||||
|
|
||||||
def _parse_other_parameters_section(self, section):
|
def _parse_other_parameters_section(self, section):
|
||||||
# type: (unicode) -> List[unicode]
|
# type: (unicode) -> List[unicode]
|
||||||
return self._format_fields('Other Parameters', self._consume_fields())
|
return self._format_fields(_('Other Parameters'), self._consume_fields())
|
||||||
|
|
||||||
def _parse_parameters_section(self, section):
|
def _parse_parameters_section(self, section):
|
||||||
# type: (unicode) -> List[unicode]
|
# type: (unicode) -> List[unicode]
|
||||||
@ -679,7 +685,7 @@ class GoogleDocstring(UnicodeMixin):
|
|||||||
if self._config.napoleon_use_param:
|
if self._config.napoleon_use_param:
|
||||||
return self._format_docutils_params(fields)
|
return self._format_docutils_params(fields)
|
||||||
else:
|
else:
|
||||||
return self._format_fields('Parameters', fields)
|
return self._format_fields(_('Parameters'), fields)
|
||||||
|
|
||||||
def _parse_raises_section(self, section):
|
def _parse_raises_section(self, section):
|
||||||
# type: (unicode) -> List[unicode]
|
# type: (unicode) -> List[unicode]
|
||||||
@ -688,7 +694,7 @@ class GoogleDocstring(UnicodeMixin):
|
|||||||
padding = ' ' * len(field_type)
|
padding = ' ' * len(field_type)
|
||||||
multi = len(fields) > 1
|
multi = len(fields) > 1
|
||||||
lines = [] # type: List[unicode]
|
lines = [] # type: List[unicode]
|
||||||
for _, _type, _desc in fields:
|
for _name, _type, _desc in fields:
|
||||||
_desc = self._strip_empty(_desc)
|
_desc = self._strip_empty(_desc)
|
||||||
has_desc = any(_desc)
|
has_desc = any(_desc)
|
||||||
separator = has_desc and ' -- ' or ''
|
separator = has_desc and ' -- ' or ''
|
||||||
@ -723,7 +729,7 @@ class GoogleDocstring(UnicodeMixin):
|
|||||||
def _parse_references_section(self, section):
|
def _parse_references_section(self, section):
|
||||||
# type: (unicode) -> List[unicode]
|
# type: (unicode) -> List[unicode]
|
||||||
use_admonition = self._config.napoleon_use_admonition_for_references
|
use_admonition = self._config.napoleon_use_admonition_for_references
|
||||||
return self._parse_generic_section('References', use_admonition)
|
return self._parse_generic_section(_('References'), use_admonition)
|
||||||
|
|
||||||
def _parse_returns_section(self, section):
|
def _parse_returns_section(self, section):
|
||||||
# type: (unicode) -> List[unicode]
|
# type: (unicode) -> List[unicode]
|
||||||
@ -760,12 +766,12 @@ class GoogleDocstring(UnicodeMixin):
|
|||||||
|
|
||||||
def _parse_warns_section(self, section):
|
def _parse_warns_section(self, section):
|
||||||
# type: (unicode) -> List[unicode]
|
# type: (unicode) -> List[unicode]
|
||||||
return self._format_fields('Warns', self._consume_fields())
|
return self._format_fields(_('Warns'), self._consume_fields())
|
||||||
|
|
||||||
def _parse_yields_section(self, section):
|
def _parse_yields_section(self, section):
|
||||||
# type: (unicode) -> List[unicode]
|
# type: (unicode) -> List[unicode]
|
||||||
fields = self._consume_returns_section()
|
fields = self._consume_returns_section()
|
||||||
return self._format_fields('Yields', fields)
|
return self._format_fields(_('Yields'), fields)
|
||||||
|
|
||||||
def _partition_field_on_colon(self, line):
|
def _partition_field_on_colon(self, line):
|
||||||
# type: (unicode) -> Tuple[unicode, unicode, unicode]
|
# type: (unicode) -> Tuple[unicode, unicode, unicode]
|
||||||
|
@ -225,12 +225,13 @@ class AfterCommentParser(TokenProcessor):
|
|||||||
def parse(self):
|
def parse(self):
|
||||||
# type: () -> None
|
# type: () -> None
|
||||||
"""Parse the code and obtain comment after assignment."""
|
"""Parse the code and obtain comment after assignment."""
|
||||||
# skip lvalue (until '=' operator)
|
# skip lvalue (or whole of AnnAssign)
|
||||||
while self.fetch_token() != [OP, '=']:
|
while not self.fetch_token().match([OP, '='], NEWLINE, COMMENT):
|
||||||
assert self.current
|
assert self.current
|
||||||
|
|
||||||
# skip rvalue
|
# skip rvalue (if exists)
|
||||||
self.fetch_rvalue()
|
if self.current == [OP, '=']:
|
||||||
|
self.fetch_rvalue()
|
||||||
|
|
||||||
if self.current == COMMENT:
|
if self.current == COMMENT:
|
||||||
self.comment = self.current.value
|
self.comment = self.current.value
|
||||||
|
@ -392,7 +392,7 @@ class WarningIsErrorFilter(logging.Filter):
|
|||||||
location = getattr(record, 'location', '')
|
location = getattr(record, 'location', '')
|
||||||
try:
|
try:
|
||||||
message = record.msg % record.args
|
message = record.msg % record.args
|
||||||
except TypeError:
|
except (TypeError, ValueError):
|
||||||
message = record.msg # use record.msg itself
|
message = record.msg # use record.msg itself
|
||||||
|
|
||||||
if location:
|
if location:
|
||||||
|
@ -56,8 +56,7 @@ def repr_domxml(node, length=80):
|
|||||||
returns full of DOM XML representation.
|
returns full of DOM XML representation.
|
||||||
:return: DOM XML representation
|
:return: DOM XML representation
|
||||||
"""
|
"""
|
||||||
# text = node.asdom().toxml() # #4919 crush if node has secnumber with tuple value
|
text = node.asdom().toxml()
|
||||||
text = text_type(node) # workaround for #4919
|
|
||||||
if length and len(text) > length:
|
if length and len(text) > length:
|
||||||
text = text[:length] + '...'
|
text = text[:length] + '...'
|
||||||
return text
|
return text
|
||||||
@ -82,9 +81,8 @@ def apply_source_workaround(node):
|
|||||||
get_full_module_name(node), repr_domxml(node))
|
get_full_module_name(node), repr_domxml(node))
|
||||||
node.source, node.line = node.parent.source, node.parent.line
|
node.source, node.line = node.parent.source, node.parent.line
|
||||||
if isinstance(node, nodes.title) and node.source is None:
|
if isinstance(node, nodes.title) and node.source is None:
|
||||||
# Uncomment these lines after merging into master(1.8)
|
logger.debug('[i18n] PATCH: %r to have source: %s',
|
||||||
# logger.debug('[i18n] PATCH: %r to have source: %s',
|
get_full_module_name(node), repr_domxml(node))
|
||||||
# get_full_module_name(node), repr_domxml(node))
|
|
||||||
node.source, node.line = node.parent.source, node.parent.line
|
node.source, node.line = node.parent.source, node.parent.line
|
||||||
if isinstance(node, nodes.term):
|
if isinstance(node, nodes.term):
|
||||||
logger.debug('[i18n] PATCH: %r to have rawsource: %s',
|
logger.debug('[i18n] PATCH: %r to have rawsource: %s',
|
||||||
|
@ -25,7 +25,7 @@ from six import itervalues, text_type
|
|||||||
|
|
||||||
from sphinx import addnodes
|
from sphinx import addnodes
|
||||||
from sphinx import highlighting
|
from sphinx import highlighting
|
||||||
from sphinx.builders.latex.nodes import footnotetext
|
from sphinx.builders.latex.nodes import captioned_literal_block, footnotetext
|
||||||
from sphinx.deprecation import RemovedInSphinx30Warning
|
from sphinx.deprecation import RemovedInSphinx30Warning
|
||||||
from sphinx.errors import SphinxError
|
from sphinx.errors import SphinxError
|
||||||
from sphinx.locale import admonitionlabels, _, __
|
from sphinx.locale import admonitionlabels, _, __
|
||||||
@ -53,6 +53,13 @@ BEGIN_DOC = r'''
|
|||||||
MAX_CITATION_LABEL_LENGTH = 8
|
MAX_CITATION_LABEL_LENGTH = 8
|
||||||
LATEXSECTIONNAMES = ["part", "chapter", "section", "subsection",
|
LATEXSECTIONNAMES = ["part", "chapter", "section", "subsection",
|
||||||
"subsubsection", "paragraph", "subparagraph"]
|
"subsubsection", "paragraph", "subparagraph"]
|
||||||
|
HYPERLINK_SUPPORT_NODES = (
|
||||||
|
nodes.figure,
|
||||||
|
nodes.literal_block,
|
||||||
|
nodes.table,
|
||||||
|
nodes.section,
|
||||||
|
captioned_literal_block,
|
||||||
|
)
|
||||||
|
|
||||||
DEFAULT_SETTINGS = {
|
DEFAULT_SETTINGS = {
|
||||||
'latex_engine': 'pdflatex',
|
'latex_engine': 'pdflatex',
|
||||||
@ -459,7 +466,6 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
|||||||
self.in_production_list = 0
|
self.in_production_list = 0
|
||||||
self.in_footnote = 0
|
self.in_footnote = 0
|
||||||
self.in_caption = 0
|
self.in_caption = 0
|
||||||
self.in_container_literal_block = 0
|
|
||||||
self.in_term = 0
|
self.in_term = 0
|
||||||
self.needs_linetrimming = 0
|
self.needs_linetrimming = 0
|
||||||
self.in_minipage = 0
|
self.in_minipage = 0
|
||||||
@ -685,8 +691,6 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
|||||||
self.pending_footnotes = [] # type: List[nodes.footnote_reference]
|
self.pending_footnotes = [] # type: List[nodes.footnote_reference]
|
||||||
self.curfilestack = [] # type: List[unicode]
|
self.curfilestack = [] # type: List[unicode]
|
||||||
self.handled_abbrs = set() # type: Set[unicode]
|
self.handled_abbrs = set() # type: Set[unicode]
|
||||||
self.next_hyperlink_ids = {} # type: Dict[unicode, Set[unicode]]
|
|
||||||
self.next_section_ids = set() # type: Set[unicode]
|
|
||||||
|
|
||||||
def pushbody(self, newbody):
|
def pushbody(self, newbody):
|
||||||
# type: (List[unicode]) -> None
|
# type: (List[unicode]) -> None
|
||||||
@ -699,15 +703,6 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
|||||||
self.body = self.bodystack.pop()
|
self.body = self.bodystack.pop()
|
||||||
return body
|
return body
|
||||||
|
|
||||||
def push_hyperlink_ids(self, figtype, ids):
|
|
||||||
# type: (unicode, Set[unicode]) -> None
|
|
||||||
hyperlink_ids = self.next_hyperlink_ids.setdefault(figtype, set())
|
|
||||||
hyperlink_ids.update(ids)
|
|
||||||
|
|
||||||
def pop_hyperlink_ids(self, figtype):
|
|
||||||
# type: (unicode) -> Set[unicode]
|
|
||||||
return self.next_hyperlink_ids.pop(figtype, set())
|
|
||||||
|
|
||||||
def check_latex_elements(self):
|
def check_latex_elements(self):
|
||||||
# type: () -> None
|
# type: () -> None
|
||||||
for key in self.builder.config.latex_elements:
|
for key in self.builder.config.latex_elements:
|
||||||
@ -766,6 +761,14 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
|||||||
return (anchor and '\\phantomsection' or '') + \
|
return (anchor and '\\phantomsection' or '') + \
|
||||||
'\\label{%s}' % self.idescape(id)
|
'\\label{%s}' % self.idescape(id)
|
||||||
|
|
||||||
|
def hypertarget_to(self, node, anchor=False):
|
||||||
|
# type: (nodes.Node, bool) -> unicode
|
||||||
|
labels = ''.join(self.hypertarget(node_id, anchor=False) for node_id in node['ids'])
|
||||||
|
if anchor:
|
||||||
|
return r'\phantomsection' + labels
|
||||||
|
else:
|
||||||
|
return labels
|
||||||
|
|
||||||
def hyperlink(self, id):
|
def hyperlink(self, id):
|
||||||
# type: (unicode) -> unicode
|
# type: (unicode) -> unicode
|
||||||
return '{\\hyperref[%s]{' % self.idescape(id)
|
return '{\\hyperref[%s]{' % self.idescape(id)
|
||||||
@ -917,8 +920,6 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
|||||||
|
|
||||||
def visit_start_of_file(self, node):
|
def visit_start_of_file(self, node):
|
||||||
# type: (nodes.Node) -> None
|
# type: (nodes.Node) -> None
|
||||||
# also add a document target
|
|
||||||
self.next_section_ids.add(':doc')
|
|
||||||
self.curfilestack.append(node['docname'])
|
self.curfilestack.append(node['docname'])
|
||||||
# use default highlight settings for new file
|
# use default highlight settings for new file
|
||||||
self.hlsettingstack.append(self.hlsettingstack[0])
|
self.hlsettingstack.append(self.hlsettingstack[0])
|
||||||
@ -958,8 +959,6 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
|||||||
if not self.this_is_the_title:
|
if not self.this_is_the_title:
|
||||||
self.sectionlevel += 1
|
self.sectionlevel += 1
|
||||||
self.body.append('\n\n')
|
self.body.append('\n\n')
|
||||||
if node.get('ids'):
|
|
||||||
self.next_section_ids.update(node['ids'])
|
|
||||||
|
|
||||||
def depart_section(self, node):
|
def depart_section(self, node):
|
||||||
# type: (nodes.Node) -> None
|
# type: (nodes.Node) -> None
|
||||||
@ -1054,12 +1053,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
|||||||
except IndexError:
|
except IndexError:
|
||||||
# just use "subparagraph", it's not numbered anyway
|
# just use "subparagraph", it's not numbered anyway
|
||||||
self.body.append(r'\%s%s{' % (self.sectionnames[-1], short))
|
self.body.append(r'\%s%s{' % (self.sectionnames[-1], short))
|
||||||
self.context.append('}\n')
|
self.context.append('}\n' + self.hypertarget_to(node.parent))
|
||||||
|
|
||||||
if self.next_section_ids:
|
|
||||||
for id in self.next_section_ids:
|
|
||||||
self.context[-1] += self.hypertarget(id, anchor=False)
|
|
||||||
self.next_section_ids.clear()
|
|
||||||
elif isinstance(parent, nodes.topic):
|
elif isinstance(parent, nodes.topic):
|
||||||
self.body.append(r'\sphinxstyletopictitle{')
|
self.body.append(r'\sphinxstyletopictitle{')
|
||||||
self.context.append('}\n')
|
self.context.append('}\n')
|
||||||
@ -1252,7 +1246,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
|||||||
if len(node.children) == 1 and node.children[0].astext() in \
|
if len(node.children) == 1 and node.children[0].astext() in \
|
||||||
('Footnotes', _('Footnotes')):
|
('Footnotes', _('Footnotes')):
|
||||||
raise nodes.SkipNode
|
raise nodes.SkipNode
|
||||||
self.body.append('\\paragraph{')
|
self.body.append('\\subsubsection*{')
|
||||||
self.context.append('}\n')
|
self.context.append('}\n')
|
||||||
self.in_title = 1
|
self.in_title = 1
|
||||||
|
|
||||||
@ -1303,12 +1297,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
|||||||
|
|
||||||
def depart_table(self, node):
|
def depart_table(self, node):
|
||||||
# type: (nodes.Node) -> None
|
# type: (nodes.Node) -> None
|
||||||
labels = '' # type: unicode
|
labels = self.hypertarget_to(node)
|
||||||
for labelid in self.pop_hyperlink_ids('table'):
|
|
||||||
labels += self.hypertarget(labelid, anchor=False)
|
|
||||||
if node['ids']:
|
|
||||||
labels += self.hypertarget(node['ids'][0], anchor=False)
|
|
||||||
|
|
||||||
table_type = self.table.get_table_type()
|
table_type = self.table.get_table_type()
|
||||||
table = self.render(table_type + '.tex_t',
|
table = self.render(table_type + '.tex_t',
|
||||||
dict(table=self.table, labels=labels))
|
dict(table=self.table, labels=labels))
|
||||||
@ -1542,9 +1531,12 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
|||||||
def visit_term(self, node):
|
def visit_term(self, node):
|
||||||
# type: (nodes.Node) -> None
|
# type: (nodes.Node) -> None
|
||||||
self.in_term += 1
|
self.in_term += 1
|
||||||
ctx = '}] \\leavevmode' # type: unicode
|
ctx = '' # type: unicode
|
||||||
if node.get('ids'):
|
if node.get('ids'):
|
||||||
ctx += self.hypertarget(node['ids'][0])
|
ctx = '\\phantomsection'
|
||||||
|
for node_id in node['ids']:
|
||||||
|
ctx += self.hypertarget(node_id, anchor=False)
|
||||||
|
ctx += '}] \\leavevmode'
|
||||||
self.body.append('\\item[{')
|
self.body.append('\\item[{')
|
||||||
self.context.append(ctx)
|
self.context.append(ctx)
|
||||||
|
|
||||||
@ -1741,15 +1733,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
|||||||
|
|
||||||
def visit_figure(self, node):
|
def visit_figure(self, node):
|
||||||
# type: (nodes.Node) -> None
|
# type: (nodes.Node) -> None
|
||||||
ids = '' # type: unicode
|
labels = self.hypertarget_to(node)
|
||||||
for id in self.pop_hyperlink_ids('figure'):
|
|
||||||
ids += self.hypertarget(id, anchor=False)
|
|
||||||
if node['ids']:
|
|
||||||
ids += self.hypertarget(node['ids'][0], anchor=False)
|
|
||||||
if (len(node.children) and
|
|
||||||
isinstance(node.children[0], nodes.image) and
|
|
||||||
node.children[0]['ids']):
|
|
||||||
ids += self.hypertarget(node.children[0]['ids'][0], anchor=False)
|
|
||||||
if self.table:
|
if self.table:
|
||||||
# TODO: support align option
|
# TODO: support align option
|
||||||
if 'width' in node:
|
if 'width' in node:
|
||||||
@ -1761,7 +1745,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
|||||||
self.body.append('\\begin{sphinxfigure-in-table}\n\\centering\n')
|
self.body.append('\\begin{sphinxfigure-in-table}\n\\centering\n')
|
||||||
if any(isinstance(child, nodes.caption) for child in node):
|
if any(isinstance(child, nodes.caption) for child in node):
|
||||||
self.body.append('\\capstart')
|
self.body.append('\\capstart')
|
||||||
self.context.append(ids + '\\end{sphinxfigure-in-table}\\relax\n')
|
self.context.append(labels + '\\end{sphinxfigure-in-table}\\relax\n')
|
||||||
elif node.get('align', '') in ('left', 'right'):
|
elif node.get('align', '') in ('left', 'right'):
|
||||||
length = None
|
length = None
|
||||||
if 'width' in node:
|
if 'width' in node:
|
||||||
@ -1770,7 +1754,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
|||||||
length = self.latex_image_length(node[0]['width'])
|
length = self.latex_image_length(node[0]['width'])
|
||||||
self.body.append('\\begin{wrapfigure}{%s}{%s}\n\\centering' %
|
self.body.append('\\begin{wrapfigure}{%s}{%s}\n\\centering' %
|
||||||
(node['align'] == 'right' and 'r' or 'l', length or '0pt'))
|
(node['align'] == 'right' and 'r' or 'l', length or '0pt'))
|
||||||
self.context.append(ids + '\\end{wrapfigure}\n')
|
self.context.append(labels + '\\end{wrapfigure}\n')
|
||||||
elif self.in_minipage:
|
elif self.in_minipage:
|
||||||
self.body.append('\n\\begin{center}')
|
self.body.append('\n\\begin{center}')
|
||||||
self.context.append('\\end{center}\n')
|
self.context.append('\\end{center}\n')
|
||||||
@ -1779,7 +1763,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
|||||||
self.elements['figure_align'])
|
self.elements['figure_align'])
|
||||||
if any(isinstance(child, nodes.caption) for child in node):
|
if any(isinstance(child, nodes.caption) for child in node):
|
||||||
self.body.append('\\capstart\n')
|
self.body.append('\\capstart\n')
|
||||||
self.context.append(ids + '\\end{figure}\n')
|
self.context.append(labels + '\\end{figure}\n')
|
||||||
|
|
||||||
def depart_figure(self, node):
|
def depart_figure(self, node):
|
||||||
# type: (nodes.Node) -> None
|
# type: (nodes.Node) -> None
|
||||||
@ -1788,7 +1772,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
|||||||
def visit_caption(self, node):
|
def visit_caption(self, node):
|
||||||
# type: (nodes.Node) -> None
|
# type: (nodes.Node) -> None
|
||||||
self.in_caption += 1
|
self.in_caption += 1
|
||||||
if self.in_container_literal_block:
|
if isinstance(node.parent, captioned_literal_block):
|
||||||
self.body.append('\\sphinxSetupCaptionForVerbatim{')
|
self.body.append('\\sphinxSetupCaptionForVerbatim{')
|
||||||
elif self.in_minipage and isinstance(node.parent, nodes.figure):
|
elif self.in_minipage and isinstance(node.parent, nodes.figure):
|
||||||
self.body.append('\\captionof{figure}{')
|
self.body.append('\\captionof{figure}{')
|
||||||
@ -1880,37 +1864,14 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
|||||||
anchor = not self.in_title
|
anchor = not self.in_title
|
||||||
self.body.append(self.hypertarget(id, anchor=anchor))
|
self.body.append(self.hypertarget(id, anchor=anchor))
|
||||||
|
|
||||||
# postpone the labels until after the sectioning command
|
# skip if visitor for next node supports hyperlink
|
||||||
parindex = node.parent.index(node)
|
domain = self.builder.env.get_domain('std')
|
||||||
try:
|
next_node = node.next_node(ascend=True)
|
||||||
try:
|
if isinstance(next_node, HYPERLINK_SUPPORT_NODES):
|
||||||
next = node.parent[parindex + 1]
|
return
|
||||||
except IndexError:
|
elif domain.get_enumerable_node_type(next_node) and domain.get_numfig_title(next_node):
|
||||||
# last node in parent, look at next after parent
|
return
|
||||||
# (for section of equal level) if it exists
|
|
||||||
if node.parent.parent is not None:
|
|
||||||
next = node.parent.parent[
|
|
||||||
node.parent.parent.index(node.parent)]
|
|
||||||
else:
|
|
||||||
raise
|
|
||||||
if isinstance(next, nodes.section):
|
|
||||||
if node.get('refid'):
|
|
||||||
self.next_section_ids.add(node['refid'])
|
|
||||||
self.next_section_ids.update(node['ids'])
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
domain = self.builder.env.get_domain('std')
|
|
||||||
figtype = domain.get_enumerable_node_type(next)
|
|
||||||
if figtype and domain.get_numfig_title(next):
|
|
||||||
ids = set()
|
|
||||||
# labels for figures go in the figure body, not before
|
|
||||||
if node.get('refid'):
|
|
||||||
ids.add(node['refid'])
|
|
||||||
ids.update(node['ids'])
|
|
||||||
self.push_hyperlink_ids(figtype, ids)
|
|
||||||
return
|
|
||||||
except IndexError:
|
|
||||||
pass
|
|
||||||
if 'refuri' in node:
|
if 'refuri' in node:
|
||||||
return
|
return
|
||||||
if node.get('refid'):
|
if node.get('refid'):
|
||||||
@ -2220,6 +2181,14 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
|||||||
# the \ignorespaces in particular for after table header use
|
# the \ignorespaces in particular for after table header use
|
||||||
self.body.append('%\n\\end{footnotetext}\\ignorespaces ')
|
self.body.append('%\n\\end{footnotetext}\\ignorespaces ')
|
||||||
|
|
||||||
|
def visit_captioned_literal_block(self, node):
|
||||||
|
# type: (nodes.Node) -> None
|
||||||
|
pass
|
||||||
|
|
||||||
|
def depart_captioned_literal_block(self, node):
|
||||||
|
# type: (nodes.Node) -> None
|
||||||
|
pass
|
||||||
|
|
||||||
def visit_literal_block(self, node):
|
def visit_literal_block(self, node):
|
||||||
# type: (nodes.Node) -> None
|
# type: (nodes.Node) -> None
|
||||||
if node.rawsource != node.astext():
|
if node.rawsource != node.astext():
|
||||||
@ -2227,15 +2196,12 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
|||||||
self.in_parsed_literal += 1
|
self.in_parsed_literal += 1
|
||||||
self.body.append('\\begin{sphinxalltt}\n')
|
self.body.append('\\begin{sphinxalltt}\n')
|
||||||
else:
|
else:
|
||||||
ids = '' # type: unicode
|
labels = self.hypertarget_to(node)
|
||||||
for id in self.pop_hyperlink_ids('code-block'):
|
if isinstance(node.parent, captioned_literal_block):
|
||||||
ids += self.hypertarget(id, anchor=False)
|
labels += self.hypertarget_to(node.parent)
|
||||||
if node['ids']:
|
if labels and not self.in_footnote:
|
||||||
# suppress with anchor=False \phantomsection insertion
|
self.body.append('\n\\def\\sphinxLiteralBlockLabel{' + labels + '}')
|
||||||
ids += self.hypertarget(node['ids'][0], anchor=False)
|
|
||||||
# LaTeX code will insert \phantomsection prior to \label
|
|
||||||
if ids and not self.in_footnote:
|
|
||||||
self.body.append('\n\\def\\sphinxLiteralBlockLabel{' + ids + '}')
|
|
||||||
code = node.astext()
|
code = node.astext()
|
||||||
lang = self.hlsettingstack[-1][0]
|
lang = self.hlsettingstack[-1][0]
|
||||||
linenos = code.count('\n') >= self.hlsettingstack[-1][1] - 1
|
linenos = code.count('\n') >= self.hlsettingstack[-1][1] - 1
|
||||||
@ -2462,22 +2428,11 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
|||||||
|
|
||||||
def visit_container(self, node):
|
def visit_container(self, node):
|
||||||
# type: (nodes.Node) -> None
|
# type: (nodes.Node) -> None
|
||||||
if node.get('literal_block'):
|
pass
|
||||||
self.in_container_literal_block += 1
|
|
||||||
ids = '' # type: unicode
|
|
||||||
for id in self.pop_hyperlink_ids('code-block'):
|
|
||||||
ids += self.hypertarget(id, anchor=False)
|
|
||||||
if node['ids']:
|
|
||||||
# suppress with anchor=False \phantomsection insertion
|
|
||||||
ids += self.hypertarget(node['ids'][0], anchor=False)
|
|
||||||
# define label for use in caption.
|
|
||||||
if ids:
|
|
||||||
self.body.append('\n\\def\\sphinxLiteralBlockLabel{' + ids + '}\n')
|
|
||||||
|
|
||||||
def depart_container(self, node):
|
def depart_container(self, node):
|
||||||
# type: (nodes.Node) -> None
|
# type: (nodes.Node) -> None
|
||||||
if node.get('literal_block'):
|
pass
|
||||||
self.in_container_literal_block -= 1
|
|
||||||
|
|
||||||
def visit_decoration(self, node):
|
def visit_decoration(self, node):
|
||||||
# type: (nodes.Node) -> None
|
# type: (nodes.Node) -> None
|
||||||
@ -2607,6 +2562,39 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
|||||||
RemovedInSphinx30Warning)
|
RemovedInSphinx30Warning)
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
@property
|
||||||
|
def in_container_literal_block(self):
|
||||||
|
# type: () -> int
|
||||||
|
warnings.warn('LaTeXTranslator.in_container_literal_block is deprecated.',
|
||||||
|
RemovedInSphinx30Warning)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
@property
|
||||||
|
def next_section_ids(self):
|
||||||
|
# type: () -> Set[unicode]
|
||||||
|
warnings.warn('LaTeXTranslator.next_section_ids is deprecated.',
|
||||||
|
RemovedInSphinx30Warning)
|
||||||
|
return set()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def next_hyperlink_ids(self):
|
||||||
|
# type: () -> Dict
|
||||||
|
warnings.warn('LaTeXTranslator.next_hyperlink_ids is deprecated.',
|
||||||
|
RemovedInSphinx30Warning)
|
||||||
|
return {}
|
||||||
|
|
||||||
|
def push_hyperlink_ids(self, figtype, ids):
|
||||||
|
# type: (unicode, Set[unicode]) -> None
|
||||||
|
warnings.warn('LaTeXTranslator.push_hyperlink_ids() is deprecated.',
|
||||||
|
RemovedInSphinx30Warning)
|
||||||
|
pass
|
||||||
|
|
||||||
|
def pop_hyperlink_ids(self, figtype):
|
||||||
|
# type: (unicode) -> Set[unicode]
|
||||||
|
warnings.warn('LaTeXTranslator.pop_hyperlink_ids() is deprecated.',
|
||||||
|
RemovedInSphinx30Warning)
|
||||||
|
return set()
|
||||||
|
|
||||||
|
|
||||||
# Import old modules here for compatibility
|
# Import old modules here for compatibility
|
||||||
# They should be imported after `LaTeXTranslator` to avoid recursive import.
|
# They should be imported after `LaTeXTranslator` to avoid recursive import.
|
||||||
|
12
tests/roots/test-domain-cpp/xref_consistency.rst
Normal file
12
tests/roots/test-domain-cpp/xref_consistency.rst
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
xref consistency
|
||||||
|
----------------
|
||||||
|
|
||||||
|
.. cpp:namespace:: xref_consistency
|
||||||
|
|
||||||
|
.. cpp:class:: item
|
||||||
|
|
||||||
|
code-role: :code:`item`
|
||||||
|
any-role: :any:`item`
|
||||||
|
cpp-any-role: :cpp:any:`item`
|
||||||
|
cpp-expr-role: :cpp:expr:`item`
|
||||||
|
cpp-texpr-role: :cpp:texpr:`item`
|
7
tests/roots/test-glossary/conf.py
Normal file
7
tests/roots/test-glossary/conf.py
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
master_doc = 'index'
|
||||||
|
|
||||||
|
latex_documents = [
|
||||||
|
(master_doc, 'test.tex', 'The basic Sphinx documentation for testing', 'Sphinx', 'report')
|
||||||
|
]
|
22
tests/roots/test-glossary/index.rst
Normal file
22
tests/roots/test-glossary/index.rst
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
test-glossary
|
||||||
|
=============
|
||||||
|
|
||||||
|
.. glossary::
|
||||||
|
:sorted:
|
||||||
|
|
||||||
|
boson
|
||||||
|
Particle with integer spin.
|
||||||
|
|
||||||
|
*fermion*
|
||||||
|
Particle with half-integer spin.
|
||||||
|
|
||||||
|
tauon
|
||||||
|
myon
|
||||||
|
electron
|
||||||
|
Examples for fermions.
|
||||||
|
|
||||||
|
über
|
||||||
|
Gewisse
|
||||||
|
|
||||||
|
änhlich
|
||||||
|
Dinge
|
7
tests/roots/test-latex-labels/conf.py
Normal file
7
tests/roots/test-latex-labels/conf.py
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
master_doc = 'index'
|
||||||
|
|
||||||
|
latex_documents = [
|
||||||
|
(master_doc, 'test.tex', 'The basic Sphinx documentation for testing', 'Sphinx', 'report')
|
||||||
|
]
|
68
tests/roots/test-latex-labels/index.rst
Normal file
68
tests/roots/test-latex-labels/index.rst
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
latex-labels
|
||||||
|
============
|
||||||
|
|
||||||
|
figures
|
||||||
|
-------
|
||||||
|
|
||||||
|
.. _figure1:
|
||||||
|
.. _figure2:
|
||||||
|
|
||||||
|
.. figure:: logo.jpg
|
||||||
|
|
||||||
|
labeled figure
|
||||||
|
|
||||||
|
.. figure:: logo.jpg
|
||||||
|
:name: figure3
|
||||||
|
|
||||||
|
labeled figure
|
||||||
|
|
||||||
|
code-blocks
|
||||||
|
-----------
|
||||||
|
|
||||||
|
.. _codeblock1:
|
||||||
|
.. _codeblock2:
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
blah blah blah
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
:name: codeblock3
|
||||||
|
|
||||||
|
blah blah blah
|
||||||
|
|
||||||
|
tables
|
||||||
|
------
|
||||||
|
|
||||||
|
.. _table1:
|
||||||
|
.. _table2:
|
||||||
|
|
||||||
|
.. table:: table caption
|
||||||
|
|
||||||
|
==== ====
|
||||||
|
head head
|
||||||
|
cell cell
|
||||||
|
==== ====
|
||||||
|
|
||||||
|
.. table:: table caption
|
||||||
|
:name: table3
|
||||||
|
|
||||||
|
==== ====
|
||||||
|
head head
|
||||||
|
cell cell
|
||||||
|
==== ====
|
||||||
|
|
||||||
|
.. _section1:
|
||||||
|
.. _section2:
|
||||||
|
|
||||||
|
subsection
|
||||||
|
----------
|
||||||
|
|
||||||
|
.. _section3:
|
||||||
|
|
||||||
|
subsubsection
|
||||||
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
|
||||||
|
otherdoc
|
2
tests/roots/test-latex-labels/otherdoc.rst
Normal file
2
tests/roots/test-latex-labels/otherdoc.rst
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
otherdoc
|
||||||
|
========
|
@ -617,7 +617,7 @@ def test_reference_in_caption_and_codeblock_in_footnote(app, status, warning):
|
|||||||
assert '\\chapter{The section with a reference to {[}AuthorYear{]}}' in result
|
assert '\\chapter{The section with a reference to {[}AuthorYear{]}}' in result
|
||||||
assert ('\\sphinxcaption{The table title with a reference'
|
assert ('\\sphinxcaption{The table title with a reference'
|
||||||
' to {[}AuthorYear{]}}' in result)
|
' to {[}AuthorYear{]}}' in result)
|
||||||
assert '\\paragraph{The rubric title with a reference to {[}AuthorYear{]}}' in result
|
assert '\\subsubsection*{The rubric title with a reference to {[}AuthorYear{]}}' in result
|
||||||
assert ('\\chapter{The section with a reference to \\sphinxfootnotemark[5]}\n'
|
assert ('\\chapter{The section with a reference to \\sphinxfootnotemark[5]}\n'
|
||||||
'\\label{\\detokenize{index:the-section-with-a-reference-to}}'
|
'\\label{\\detokenize{index:the-section-with-a-reference-to}}'
|
||||||
'%\n\\begin{footnotetext}[5]\\sphinxAtStartFootnote\n'
|
'%\n\\begin{footnotetext}[5]\\sphinxAtStartFootnote\n'
|
||||||
@ -1247,3 +1247,69 @@ def test_latex_thebibliography(app, status, warning):
|
|||||||
'Author, Title, Year\n'
|
'Author, Title, Year\n'
|
||||||
'\\end{sphinxthebibliography}\n' in result)
|
'\\end{sphinxthebibliography}\n' in result)
|
||||||
assert '\\sphinxcite{index:authoryear}' in result
|
assert '\\sphinxcite{index:authoryear}' in result
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.sphinx('latex', testroot='glossary')
|
||||||
|
def test_latex_glossary(app, status, warning):
|
||||||
|
app.builder.build_all()
|
||||||
|
|
||||||
|
result = (app.outdir / 'test.tex').text(encoding='utf8')
|
||||||
|
assert (u'\\item[{änhlich\\index{änhlich|textbf}\\phantomsection'
|
||||||
|
r'\label{\detokenize{index:term-anhlich}}}] \leavevmode' in result)
|
||||||
|
assert (r'\item[{boson\index{boson|textbf}\phantomsection'
|
||||||
|
r'\label{\detokenize{index:term-boson}}}] \leavevmode' in result)
|
||||||
|
assert (r'\item[{\sphinxstyleemphasis{fermion}\index{fermion|textbf}'
|
||||||
|
r'\phantomsection'
|
||||||
|
r'\label{\detokenize{index:term-fermion}}}] \leavevmode' in result)
|
||||||
|
assert (r'\item[{tauon\index{tauon|textbf}\phantomsection'
|
||||||
|
r'\label{\detokenize{index:term-tauon}}}] \leavevmode'
|
||||||
|
r'\item[{myon\index{myon|textbf}\phantomsection'
|
||||||
|
r'\label{\detokenize{index:term-myon}}}] \leavevmode'
|
||||||
|
r'\item[{electron\index{electron|textbf}\phantomsection'
|
||||||
|
r'\label{\detokenize{index:term-electron}}}] \leavevmode' in result)
|
||||||
|
assert (u'\\item[{über\\index{über|textbf}\\phantomsection'
|
||||||
|
r'\label{\detokenize{index:term-uber}}}] \leavevmode' in result)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.sphinx('latex', testroot='latex-labels')
|
||||||
|
def test_latex_labels(app, status, warning):
|
||||||
|
app.builder.build_all()
|
||||||
|
|
||||||
|
result = (app.outdir / 'test.tex').text(encoding='utf8')
|
||||||
|
|
||||||
|
# figures
|
||||||
|
assert (r'\caption{labeled figure}'
|
||||||
|
r'\label{\detokenize{index:id1}}'
|
||||||
|
r'\label{\detokenize{index:figure2}}'
|
||||||
|
r'\label{\detokenize{index:figure1}}'
|
||||||
|
r'\end{figure}' in result)
|
||||||
|
assert (r'\caption{labeled figure}'
|
||||||
|
r'\label{\detokenize{index:figure3}}'
|
||||||
|
r'\end{figure}' in result)
|
||||||
|
|
||||||
|
# code-blocks
|
||||||
|
assert (r'\def\sphinxLiteralBlockLabel{'
|
||||||
|
r'\label{\detokenize{index:codeblock2}}'
|
||||||
|
r'\label{\detokenize{index:codeblock1}}}' in result)
|
||||||
|
assert (r'\def\sphinxLiteralBlockLabel{'
|
||||||
|
r'\label{\detokenize{index:codeblock3}}}' in result)
|
||||||
|
|
||||||
|
# tables
|
||||||
|
assert (r'\sphinxcaption{table caption}'
|
||||||
|
r'\label{\detokenize{index:id2}}'
|
||||||
|
r'\label{\detokenize{index:table2}}'
|
||||||
|
r'\label{\detokenize{index:table1}}' in result)
|
||||||
|
assert (r'\sphinxcaption{table caption}'
|
||||||
|
r'\label{\detokenize{index:table3}}' in result)
|
||||||
|
|
||||||
|
# sections
|
||||||
|
assert ('\\chapter{subsection}\n'
|
||||||
|
r'\label{\detokenize{index:subsection}}'
|
||||||
|
r'\label{\detokenize{index:section2}}'
|
||||||
|
r'\label{\detokenize{index:section1}}' in result)
|
||||||
|
assert ('\\section{subsubsection}\n'
|
||||||
|
r'\label{\detokenize{index:subsubsection}}'
|
||||||
|
r'\label{\detokenize{index:section3}}' in result)
|
||||||
|
assert ('\\subsection{otherdoc}\n'
|
||||||
|
r'\label{\detokenize{otherdoc:otherdoc}}'
|
||||||
|
r'\label{\detokenize{otherdoc::doc}}' in result)
|
||||||
|
@ -491,6 +491,10 @@ def test_class_definitions():
|
|||||||
{2: 'I0E7has_varI1TNSt6void_tIDTadN1T3varEEEEE'})
|
{2: 'I0E7has_varI1TNSt6void_tIDTadN1T3varEEEEE'})
|
||||||
|
|
||||||
|
|
||||||
|
def test_union_definitions():
|
||||||
|
check('union', 'A', {2: "1A"})
|
||||||
|
|
||||||
|
|
||||||
def test_enum_definitions():
|
def test_enum_definitions():
|
||||||
check('enum', 'A', {2: "1A"})
|
check('enum', 'A', {2: "1A"})
|
||||||
check('enum', 'A : std::underlying_type<B>::type', {2: "1A"})
|
check('enum', 'A : std::underlying_type<B>::type', {2: "1A"})
|
||||||
@ -735,3 +739,68 @@ def test_build_domain_cpp_with_add_function_parentheses_is_False(app, status, wa
|
|||||||
t = (app.outdir / f).text()
|
t = (app.outdir / f).text()
|
||||||
for s in parenPatterns:
|
for s in parenPatterns:
|
||||||
check(s, t, f)
|
check(s, t, f)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.sphinx(testroot='domain-cpp')
|
||||||
|
def test_xref_consistency(app, status, warning):
|
||||||
|
app.builder.build_all()
|
||||||
|
|
||||||
|
test = 'xref_consistency.html'
|
||||||
|
output = (app.outdir / test).text()
|
||||||
|
|
||||||
|
def classes(role, tag):
|
||||||
|
pattern = (r'{role}-role:.*?'
|
||||||
|
'<(?P<tag>{tag}) .*?class=["\'](?P<classes>.*?)["\'].*?>'
|
||||||
|
'.*'
|
||||||
|
'</(?P=tag)>').format(role=role, tag=tag)
|
||||||
|
result = re.search(pattern, output)
|
||||||
|
expect = '''\
|
||||||
|
Pattern for role `{role}` with tag `{tag}`
|
||||||
|
\t{pattern}
|
||||||
|
not found in `{test}`
|
||||||
|
'''.format(role=role, tag=tag, pattern=pattern, test=test)
|
||||||
|
assert result, expect
|
||||||
|
return set(result.group('classes').split())
|
||||||
|
|
||||||
|
class RoleClasses(object):
|
||||||
|
"""Collect the classes from the layout that was generated for a given role."""
|
||||||
|
|
||||||
|
def __init__(self, role, root, contents):
|
||||||
|
self.name = role
|
||||||
|
self.classes = classes(role, root)
|
||||||
|
self.content_classes = dict()
|
||||||
|
for tag in contents:
|
||||||
|
self.content_classes[tag] = classes(role, tag)
|
||||||
|
|
||||||
|
# not actually used as a reference point
|
||||||
|
#code_role = RoleClasses('code', 'code', [])
|
||||||
|
any_role = RoleClasses('any', 'a', ['code'])
|
||||||
|
cpp_any_role = RoleClasses('cpp-any', 'a', ['code'])
|
||||||
|
# NYI: consistent looks
|
||||||
|
#texpr_role = RoleClasses('cpp-texpr', 'span', ['a', 'code'])
|
||||||
|
expr_role = RoleClasses('cpp-expr', 'code', ['a'])
|
||||||
|
texpr_role = RoleClasses('cpp-texpr', 'span', ['a', 'span'])
|
||||||
|
|
||||||
|
# XRefRole-style classes
|
||||||
|
|
||||||
|
## any and cpp:any do not put these classes at the root
|
||||||
|
|
||||||
|
# n.b. the generic any machinery finds the specific 'cpp-class' object type
|
||||||
|
expect = 'any uses XRefRole classes'
|
||||||
|
assert {'xref', 'any', 'cpp', 'cpp-class'} <= any_role.content_classes['code'], expect
|
||||||
|
|
||||||
|
expect = 'cpp:any uses XRefRole classes'
|
||||||
|
assert {'xref', 'cpp-any', 'cpp'} <= cpp_any_role.content_classes['code'], expect
|
||||||
|
|
||||||
|
for role in (expr_role, texpr_role):
|
||||||
|
name = role.name
|
||||||
|
expect = '`{name}` puts the domain and role classes at its root'.format(name=name)
|
||||||
|
# NYI: xref should go in the references
|
||||||
|
assert {'xref', 'cpp', name} <= role.classes, expect
|
||||||
|
|
||||||
|
# reference classes
|
||||||
|
|
||||||
|
expect = 'the xref roles use the same reference classes'
|
||||||
|
assert any_role.classes == cpp_any_role.classes, expect
|
||||||
|
assert any_role.classes == expr_role.content_classes['a'], expect
|
||||||
|
assert any_role.classes == texpr_role.content_classes['a'], expect
|
||||||
|
@ -227,11 +227,11 @@ def test_get_toctree_for(app):
|
|||||||
[list_item, compact_paragraph, reference, "foo.1"],
|
[list_item, compact_paragraph, reference, "foo.1"],
|
||||||
[list_item, compact_paragraph, reference, "foo.2"]))
|
[list_item, compact_paragraph, reference, "foo.2"]))
|
||||||
|
|
||||||
assert_node(toctree[1][0][0][0], reference, refuri="foo", secnumber=(1,))
|
assert_node(toctree[1][0][0][0], reference, refuri="foo", secnumber=[1])
|
||||||
assert_node(toctree[1][0][1][0][0][0], reference, refuri="quux", secnumber=(1, 1))
|
assert_node(toctree[1][0][1][0][0][0], reference, refuri="quux", secnumber=[1, 1])
|
||||||
assert_node(toctree[1][0][1][1][0][0], reference, refuri="foo#foo-1", secnumber=(1, 2))
|
assert_node(toctree[1][0][1][1][0][0], reference, refuri="foo#foo-1", secnumber=[1, 2])
|
||||||
assert_node(toctree[1][0][1][2][0][0], reference, refuri="foo#foo-2", secnumber=(1, 3))
|
assert_node(toctree[1][0][1][2][0][0], reference, refuri="foo#foo-2", secnumber=[1, 3])
|
||||||
assert_node(toctree[1][1][0][0], reference, refuri="bar", secnumber=(2,))
|
assert_node(toctree[1][1][0][0], reference, refuri="bar", secnumber=[2])
|
||||||
assert_node(toctree[1][2][0][0], reference, refuri="http://sphinx-doc.org/")
|
assert_node(toctree[1][2][0][0], reference, refuri="http://sphinx-doc.org/")
|
||||||
|
|
||||||
assert_node(toctree[2],
|
assert_node(toctree[2],
|
||||||
@ -258,8 +258,8 @@ def test_get_toctree_for_collapse(app):
|
|||||||
([list_item, compact_paragraph, reference, "foo"],
|
([list_item, compact_paragraph, reference, "foo"],
|
||||||
[list_item, compact_paragraph, reference, "bar"],
|
[list_item, compact_paragraph, reference, "bar"],
|
||||||
[list_item, compact_paragraph, reference, "http://sphinx-doc.org/"]))
|
[list_item, compact_paragraph, reference, "http://sphinx-doc.org/"]))
|
||||||
assert_node(toctree[1][0][0][0], reference, refuri="foo", secnumber=(1,))
|
assert_node(toctree[1][0][0][0], reference, refuri="foo", secnumber=[1])
|
||||||
assert_node(toctree[1][1][0][0], reference, refuri="bar", secnumber=(2,))
|
assert_node(toctree[1][1][0][0], reference, refuri="bar", secnumber=[2])
|
||||||
assert_node(toctree[1][2][0][0], reference, refuri="http://sphinx-doc.org/")
|
assert_node(toctree[1][2][0][0], reference, refuri="http://sphinx-doc.org/")
|
||||||
|
|
||||||
assert_node(toctree[2],
|
assert_node(toctree[2],
|
||||||
@ -296,13 +296,13 @@ def test_get_toctree_for_maxdepth(app):
|
|||||||
assert_node(toctree[1][0][1][1][1],
|
assert_node(toctree[1][0][1][1][1],
|
||||||
[bullet_list, list_item, compact_paragraph, reference, "foo.1-1"])
|
[bullet_list, list_item, compact_paragraph, reference, "foo.1-1"])
|
||||||
|
|
||||||
assert_node(toctree[1][0][0][0], reference, refuri="foo", secnumber=(1,))
|
assert_node(toctree[1][0][0][0], reference, refuri="foo", secnumber=[1])
|
||||||
assert_node(toctree[1][0][1][0][0][0], reference, refuri="quux", secnumber=(1, 1))
|
assert_node(toctree[1][0][1][0][0][0], reference, refuri="quux", secnumber=[1, 1])
|
||||||
assert_node(toctree[1][0][1][1][0][0], reference, refuri="foo#foo-1", secnumber=(1, 2))
|
assert_node(toctree[1][0][1][1][0][0], reference, refuri="foo#foo-1", secnumber=[1, 2])
|
||||||
assert_node(toctree[1][0][1][1][1][0][0][0],
|
assert_node(toctree[1][0][1][1][1][0][0][0],
|
||||||
reference, refuri="foo#foo-1-1", secnumber=(1, 2, 1))
|
reference, refuri="foo#foo-1-1", secnumber=[1, 2, 1])
|
||||||
assert_node(toctree[1][0][1][2][0][0], reference, refuri="foo#foo-2", secnumber=(1, 3))
|
assert_node(toctree[1][0][1][2][0][0], reference, refuri="foo#foo-2", secnumber=[1, 3])
|
||||||
assert_node(toctree[1][1][0][0], reference, refuri="bar", secnumber=(2,))
|
assert_node(toctree[1][1][0][0], reference, refuri="bar", secnumber=[2])
|
||||||
assert_node(toctree[1][2][0][0], reference, refuri="http://sphinx-doc.org/")
|
assert_node(toctree[1][2][0][0], reference, refuri="http://sphinx-doc.org/")
|
||||||
|
|
||||||
assert_node(toctree[2],
|
assert_node(toctree[2],
|
||||||
@ -335,11 +335,11 @@ def test_get_toctree_for_includehidden(app):
|
|||||||
[list_item, compact_paragraph, reference, "foo.1"],
|
[list_item, compact_paragraph, reference, "foo.1"],
|
||||||
[list_item, compact_paragraph, reference, "foo.2"]))
|
[list_item, compact_paragraph, reference, "foo.2"]))
|
||||||
|
|
||||||
assert_node(toctree[1][0][0][0], reference, refuri="foo", secnumber=(1,))
|
assert_node(toctree[1][0][0][0], reference, refuri="foo", secnumber=[1])
|
||||||
assert_node(toctree[1][0][1][0][0][0], reference, refuri="quux", secnumber=(1, 1))
|
assert_node(toctree[1][0][1][0][0][0], reference, refuri="quux", secnumber=[1, 1])
|
||||||
assert_node(toctree[1][0][1][1][0][0], reference, refuri="foo#foo-1", secnumber=(1, 2))
|
assert_node(toctree[1][0][1][1][0][0], reference, refuri="foo#foo-1", secnumber=[1, 2])
|
||||||
assert_node(toctree[1][0][1][2][0][0], reference, refuri="foo#foo-2", secnumber=(1, 3))
|
assert_node(toctree[1][0][1][2][0][0], reference, refuri="foo#foo-2", secnumber=[1, 3])
|
||||||
assert_node(toctree[1][1][0][0], reference, refuri="bar", secnumber=(2,))
|
assert_node(toctree[1][1][0][0], reference, refuri="bar", secnumber=[2])
|
||||||
assert_node(toctree[1][2][0][0], reference, refuri="http://sphinx-doc.org/")
|
assert_node(toctree[1][2][0][0], reference, refuri="http://sphinx-doc.org/")
|
||||||
|
|
||||||
assert_node(toctree[2],
|
assert_node(toctree[2],
|
||||||
|
@ -100,11 +100,13 @@ def test_comment_picker_location():
|
|||||||
def test_annotated_assignment_py36():
|
def test_annotated_assignment_py36():
|
||||||
source = ('a: str = "Sphinx" #: comment\n'
|
source = ('a: str = "Sphinx" #: comment\n'
|
||||||
'b: int = 1\n'
|
'b: int = 1\n'
|
||||||
'"""string on next line"""')
|
'"""string on next line"""\n'
|
||||||
|
'c: int #: comment')
|
||||||
parser = Parser(source)
|
parser = Parser(source)
|
||||||
parser.parse()
|
parser.parse()
|
||||||
assert parser.comments == {('', 'a'): 'comment',
|
assert parser.comments == {('', 'a'): 'comment',
|
||||||
('', 'b'): 'string on next line'}
|
('', 'b'): 'string on next line',
|
||||||
|
('', 'c'): 'comment'}
|
||||||
assert parser.definitions == {}
|
assert parser.definitions == {}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user