Merge branch 'master' into 1618-make-search-results-reader-friendly

This commit is contained in:
Timotheus Kampik 2018-08-27 21:34:43 +02:00
commit 26bd565dee
131 changed files with 11514 additions and 2375 deletions

View File

@ -7,8 +7,8 @@ environment:
matrix:
- PYTHON: 27
TEST_IGNORE: --ignore py35
- PYTHON: 36
- PYTHON: 36-x64
- PYTHON: 37
- PYTHON: 37-x64
install:
- C:\Python%PYTHON%\python.exe -m pip install -U pip setuptools

View File

@ -6,6 +6,6 @@ jobs:
working_directory: /sphinx
steps:
- checkout
- run: /python3.4/bin/pip install -U pip setuptools
- run: /python3.4/bin/pip install -U .[test,websupport]
- run: make test PYTHON=/python3.4/bin/python
- run: /python3.5/bin/pip install -U pip setuptools
- run: /python3.5/bin/pip install -U .[test,websupport]
- run: make test PYTHON=/python3.5/bin/python

2
.gitignore vendored
View File

@ -29,3 +29,5 @@ doc/locale/
tests/.coverage
tests/build/
utils/regression_test.js
node_modules/

View File

@ -7,6 +7,7 @@ env:
global:
- PYTHONFAULTHANDLER=x
- SKIP_LATEX_BUILD=1
- IS_PYTHON=true
matrix:
include:
@ -24,8 +25,14 @@ matrix:
env:
- TOXENV=py36
- PYTEST_ADDOPTS="--cov ./ --cov-append --cov-config setup.cfg"
- python: 'nightly'
- python: '3.7'
env: TOXENV=py37
dist: xenial
sudo: true
- python: 'nightly'
env: TOXENV=py38
dist: xenial
sudo: true
- python: '3.6'
env: TOXENV=docs
- python: '3.6'
@ -33,11 +40,21 @@ matrix:
- python: '3.6'
env: TOXENV=flake8
- language: node_js
node_js:
- 10.7
env: IS_PYTHON=false
before_script:
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start
install:
- pip install -U tox codecov
- if [ $IS_PYTHON = true ]; then pip install -U tox codecov; fi
- if [ $IS_PYTHON = false ]; then npm install; fi
script:
- tox -- -v
- if [ $IS_PYTHON = true ]; then tox -- -v; fi
- if [ $IS_PYTHON = false ]; then npm test; fi
after_success:
- if [[ -e .coverage ]]; then codecov -e $TOXENV; fi

View File

@ -14,6 +14,7 @@ Other co-maintainers:
* Takeshi Komiya <@tk0miya>
* Jean-François Burnol <@jfbu>
* Yoshiki Shibukawa <@shibu_jp>
* Timotheus Kampik - <@TimKam>
Other contributors, listed alphabetically, are:
@ -37,7 +38,6 @@ Other contributors, listed alphabetically, are:
* Zac Hatfield-Dodds -- doctest reporting improvements
* Doug Hellmann -- graphviz improvements
* Tim Hoffmann -- theme improvements
* Timotheus Kampik - JS theme & search enhancements
* Dave Kuhlman -- original LaTeX writer
* Blaise Laflamme -- pyramid theme
* Chris Lamb -- reproducibility fixes

155
CHANGES
View File

@ -1,9 +1,54 @@
Release 1.8.0 (in development)
Release 2.0.0 (in development)
==============================
Dependencies
------------
Incompatible changes
--------------------
Deprecated
----------
Features added
--------------
Bugs fixed
----------
Testing
--------
Release 1.8.0 beta2 (in development)
====================================
Dependencies
------------
Incompatible changes
--------------------
Deprecated
----------
Features added
--------------
Bugs fixed
----------
* html: search box overrides to other elements if scrolled
* #5325: latex: cross references has been broken by multiply labeled objects
Testing
--------
Release 1.8.0 beta1 (in development)
====================================
Dependencies
------------
* LaTeX: :confval:`latex_use_xindy`, if ``True`` (default for
``xelatex/lualatex``), instructs ``make latexpdf`` to use :program:`xindy`
for general index. Make sure your LaTeX distribution includes it.
@ -12,6 +57,9 @@ Dependencies
Incompatible changes
--------------------
* #5156: the :py:mod:`sphinx.ext.graphviz: extension runs `dot` in the
directory of the document being built instead of in the root directory of
the documentation.
* #4460: extensions which stores any data to environment should return the
version of its env data structure as metadata. In detail, please see
:ref:`ext-metadata`.
@ -48,15 +96,27 @@ Incompatible changes
UTF-8 able replacement of :program:`makeindex` (refs: #5134). After
upgrading Sphinx, please clean latex build repertory of existing project
before new build.
* #5163: html: hlist items are now aligned to top
* ``highlightlang`` directive is processed on resolving phase
* #4000: latex: LaTeX template has been chaned. Following elements are moved
into the template:
- ``\begin{document}``
- ``shorthandoff`` variable
- ``maketitle`` variable
- ``tableofcontents`` variable
Deprecated
----------
* :confval:`source_parsers` is deprecated
* :confval:`autodoc_default_flags` is deprecated
* quickstart: ``--epub`` option becomes default, so it is deprecated
* Drop function based directive support. For now, Sphinx only supports class
based directives.
* ``sphinx.util.docutils.directive_helper()`` is deprecated
* ``sphinx.cmdline`` is deprecated
* ``sphinx.make_mode`` is deprecated
* ``sphinx.locale.l_()`` is deprecated
* #2157: helper function ``warn()`` for HTML themes is deprecated
* ``app.override_domain()`` is deprecated
@ -81,9 +141,11 @@ Deprecated
* ``env._read_parallel()`` is deprecated
* ``env.write_doctree()`` is deprecated
* ``env._nitpick_ignore`` is deprecated
* ``env.versionchanges`` is deprecated
* ``env.dump()`` is deprecated
* ``env.dumps()`` is deprecated
* ``env.topickle()`` is deprecated
* ``env.note_versionchange()`` is deprecated
* ``sphinx.writers.latex.Table.caption_footnotetexts`` is deprecated
* ``sphinx.writers.latex.Table.header_footnotetexts`` is deprecated
* ``sphinx.writers.latex.LaTeXTranslator.footnotestack`` is deprecated
@ -94,13 +156,31 @@ Deprecated
* ``sphinx.writers.latex.LaTeXTranslator.unrestrict_footnote()`` is deprecated
* ``sphinx.writers.latex.LaTeXTranslator.push_hyperlink_ids()`` is deprecated
* ``sphinx.writers.latex.LaTeXTranslator.pop_hyperlink_ids()`` is deprecated
* ``sphinx.writers.latex.LaTeXTranslator.check_latex_elements()`` is deprecated
* ``sphinx.writers.latex.LaTeXTranslator.bibitems`` is deprecated
* ``sphinx.writers.latex.LaTeXTranslator.hlsettingstack`` is deprecated
* ``sphinx.writers.latex.ExtBabel.get_shorthandoff()`` is deprecated
* ``sphinx.writers.html.HTMLTranslator.highlightlang`` is deprecated
* ``sphinx.writers.html.HTMLTranslator.highlightlang_base`` is deprecated
* ``sphinx.writers.html.HTMLTranslator.highlightlangopts`` is deprecated
* ``sphinx.writers.html.HTMLTranslator.highlightlinenothreshold`` is deprecated
* ``sphinx.writers.html5.HTMLTranslator.highlightlang`` is deprecated
* ``sphinx.writers.html5.HTMLTranslator.highlightlang_base`` is deprecated
* ``sphinx.writers.html5.HTMLTranslator.highlightlangopts`` is deprecated
* ``sphinx.writers.html5.HTMLTranslator.highlightlinenothreshold`` is deprecated
* ``sphinx.ext.mathbase`` extension is deprecated
* ``sphinx.ext.mathbase.math`` node is deprecated
* ``sphinx.ext.mathbase.displaymath`` node is deprecated
* ``sphinx.ext.mathbase.eqref`` node is deprecated
* ``sphinx.ext.mathbase.is_in_section_title()`` is deprecated
* ``sphinx.ext.mathbase.MathDomain`` is deprecated
* ``sphinx.ext.mathbase.setup_math()`` is deprecated
* ``sphinx.directives.other.VersionChanges`` is deprecated
* ``sphinx.highlighting.PygmentsBridge.unhighlight()`` is deprecated
* ``sphinx.ext.mathbase.get_node_equation_number()`` is deprecated
* ``sphinx.ext.mathbase.wrap_displaymath()`` is deprecated
* The ``trim_doctest_flags`` argument of ``sphinx.highlighting.PygmentsBridge``
is deprecated
For more details, see `deprecation APIs list
<http://www.sphinx-doc.org/en/master/extdev/index.html#deprecated-apis>`_
@ -136,14 +216,22 @@ Features added
* Add ``Config.read()`` classmethod to create a new config object from
configuration file
* #4866: Wrap graphviz diagrams in ``<div>`` tag
* Add :event:`viewcode-find-source` event to viewcode extension.
* viewcode: Add :event:`viewcode-find-source` and
:event:`viewcode-follow-imported` to load source code without loading
* #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.
* C++, add support for anonymous entities using names staring with ``@``.
Fixes #3593 and #2683.
* C++:
- Add a ``cpp:texpr`` role as a sibling to ``cpp:expr``.
- Add support for unions.
- #3593, #2683: add support for anonymous entities using names staring with ``@``.
- #5147: add support for (most) character literals.
- Cross-referencing entities inside primary templates is supported,
and now properly documented.
- #1552: add new cross-referencing format for ``cpp:any`` and ``cpp:func`` roles,
for referencing specific function overloads.
* #3606: MathJax should be loaded with async attribute
* html: Output ``canonical_url`` metadata if :confval:`html_baseurl` set (refs:
#4193)
@ -153,8 +241,23 @@ Features added
* #4362: latex: Don't overwrite .tex file if document not changed
* #1431: latex: Add alphanumeric enumerated list support
* Add :confval:`latex_use_xindy` for UTF-8 savvy indexing, defaults to ``True``
if :confval:`latex_engine` is ``'xelatex'`` or ``'lualatex'``.
if :confval:`latex_engine` is ``'xelatex'`` or ``'lualatex'``. (refs: #5134,
#5192, #5212)
* #4976: ``SphinxLoggerAdapter.info()`` now supports ``location`` parameter
* #5122: setuptools: support nitpicky option
* #2820: autoclass directive supports nested class
* Add ``app.add_html_math_renderer()`` to register a math renderer for HTML
* Apply :confval:`trim_doctest_flags` to all builders (cf. text, manpages)
* #5140: linkcheck: Add better Accept header to HTTP client
* #4614: sphinx-build: Add ``--keep-going`` option to show all warnings
* Add :rst:role:`math:numref` role to refer equations (Same as :rst:role:`eq`)
* quickstart: epub builder is enabled by default
* #5246: Add :confval:`singlehtml_sidebars` to configure sidebars for singlehtml
builder
* #5273: doctest: Skip doctest conditionally
* #5306: autodoc: emit a warning for invalid typehints
* #4075, #5215: autodoc: Add :confval:`autodoc_default_options` which accepts
option values as dict
Bugs fixed
----------
@ -166,6 +269,14 @@ Bugs fixed
* #4983: productionlist directive generates invalid IDs for the tokens
* #5132: (lualatex) PDF build fails if indexed word starts with Unicode character
* #5133: latex: index headings "Symbols" and "Numbers" not internationalized
* #5114: sphinx-build: Handle errors on scanning documents
* epub: spine has been broken when "self" is listed on toctree (refs: #4611)
* #344: autosummary does not understand docstring of module level attributes
* #5191: C++, prevent nested declarations in functions to avoid lookup problems.
* #5126: C++, add missing isPack method for certain template parameter types.
* #5187: C++, parse attributes on declerators as well.
* C++, parse delete expressions and basic new expressions as well.
* #5002: graphviz: SVGs do not adapt to the column width
Testing
--------
@ -181,7 +292,7 @@ Documentation
* #5083: Fix wrong make.bat option for internationalization.
* #5115: napoleon: add admonitions added by #4613 to the docs.
Release 1.7.7 (in development)
Release 1.7.8 (in development)
==============================
Dependencies
@ -199,9 +310,37 @@ Features added
Bugs fixed
----------
* #5320: intersphinx: crashed if invalid url given
* #5326: manpage: crashed when invalid docname is specified as ``man_pages``
* #5322: autodoc: ``Any`` typehint causes formatting error
Testing
--------
Release 1.7.7 (released Aug 19, 2018)
=====================================
Bugs fixed
----------
* #5198: document not in toctree warning when including files only for parallel
builds
* LaTeX: reduce "Token not allowed in a PDF string" hyperref warnings in latex
console output (refs: #5236)
* LaTeX: suppress "remreset Warning: The remreset package is obsolete" in latex
console output with recent LaTeX (refs: #5237)
* #5234: PDF output: usage of PAPER environment variable is broken since Sphinx
1.5
* LaTeX: fix the :confval:`latex_engine` documentation regarding Latin Modern
font with XeLaTeX/LuaLateX (refs: #5251)
* #5280: autodoc: Fix wrong type annotations for complex typing
* autodoc: Optional types are wrongly rendered
* #5291: autodoc crashed by ForwardRef types
* #5211: autodoc: No docs generated for functools.partial functions
* #5306: autodoc: ``getargspec()`` raises NameError for invalid typehints
* #5298: imgmath: math_number_all causes equations to have two numbers in html
* #5294: sphinx-quickstart blank prompts in PowerShell
Release 1.7.6 (released Jul 17, 2018)
=====================================

View File

@ -154,6 +154,12 @@ These are the basic steps needed to start developing on Sphinx.
tox -e docs -- -b html,latexpdf
* To run JavaScript tests with `Karma <https://karma-runner.github.io>`_,
execute the following commands (requires `Node.js <https://nodejs.org>`_)::
npm install
npm run test
You can also test by installing dependencies in your local environment. ::
pip install .[test]
@ -302,8 +308,8 @@ Debugging Tips
in `this repository <https://github.com/shibukawa/snowball-stemmer.jsx>`_.
You can get the resulting JavaScript files using the following command::
$ npm install
$ node_modules/.bin/grunt build # -> dest/*.global.js
npm install
node_modules/.bin/grunt build # -> dest/*.global.js
Branch Model
@ -402,3 +408,6 @@ and other ``test_*.py`` files under ``tests`` directory.
.. versionadded:: 1.6
``sphinx.testing`` as a experimental.
.. versionadded:: 1.8
Sphinx also runs JavaScript tests.

1016
EXAMPLES

File diff suppressed because it is too large Load Diff

View File

@ -93,6 +93,8 @@ package.
.. automethod:: Sphinx.add_html_theme(name, theme_path)
.. automethod:: Sphinx.add_html_math_renderer(name, inline_renderers, block_renderers)
.. automethod:: Sphinx.add_message_catalog(catalog, locale_dir)
.. automethod:: Sphinx.is_parallel_allowed(typ)

View File

@ -131,16 +131,57 @@ The following is a list of deprecated interface.
- 4.0
- :meth:`~sphinx.application.Sphinx.add_js_file()`
* - :confval:`autodoc_default_flags`
- 1.8
- 4.0
- :confval:`autodoc_default_options`
* - ``sphinx.directives.other.VersionChanges``
- 1.8
- 3.0
- ``sphinx.domains.changeset.VersionChanges``
* - ``sphinx.highlighting.PygmentsBridge.unhighlight()``
- 1.8
- 3.0
- N/A
* - ``trim_doctest_flags`` arguments of
``sphinx.highlighting.PygmentsBridge``
- 1.8
- 3.0
- N/A
* - ``sphinx.ext.mathbase``
- 1.8
- 3.0
- N/A
* - ``sphinx.ext.mathbase.MathDomain``
- 1.8
- 3.0
- ``sphinx.domains.math.MathDomain``
* - ``sphinx.ext.mathbase.setup_math()``
- 1.8
- 3.0
- :meth:`~sphinx.application.Sphinx.add_html_math_renderer()`
* - ``sphinx.ext.mathbase.is_in_section_title()``
- 1.8
- 3.0
- N/A
* - ``sphinx.ext.mathbase.get_node_equation_number()``
- 1.8
- 3.0
- ``sphinx.util.math.get_node_equation_number()``
* - ``sphinx.ext.mathbase.wrap_displaymath()``
- 1.8
- 3.0
- ``sphinx.util.math.wrap_displaymath()``
* - ``sphinx.ext.mathbase.math`` (node)
- 1.8
- 3.0
@ -216,11 +257,61 @@ The following is a list of deprecated interface.
- 3.0
- N/A
* - ``sphinx.writers.latex.LaTeXTranslator.hlsettingstack``
- 1.8
- 3.0
- N/A
* - ``sphinx.writers.latex.ExtBabel.get_shorthandoff()``
- 1.8
- 3.0
- N/A
* - ``sphinx.writers.html.HTMLTranslator.highlightlang()``
- 1.8
- 3.0
- N/A
* - ``sphinx.writers.html.HTMLTranslator.highlightlang_base()``
- 1.8
- 3.0
- N/A
* - ``sphinx.writers.html.HTMLTranslator.highlightlangopts()``
- 1.8
- 3.0
- N/A
* - ``sphinx.writers.html.HTMLTranslator.highlightlinenothreshold()``
- 1.8
- 3.0
- N/A
* - ``sphinx.writers.html5.HTMLTranslator.highlightlang()``
- 1.8
- 3.0
- N/A
* - ``sphinx.writers.html5.HTMLTranslator.highlightlang_base()``
- 1.8
- 3.0
- N/A
* - ``sphinx.writers.html5.HTMLTranslator.highlightlangopts()``
- 1.8
- 3.0
- N/A
* - ``sphinx.writers.html5.HTMLTranslator.highlightlinenothreshold()``
- 1.8
- 3.0
- N/A
* - ``sphinx.writers.latex.LaTeXTranslator.check_latex_elements()``
- 1.8
- 3.0
- Nothing
* - ``sphinx.application.CONFIG_FILENAME``
- 1.8
- 3.0
@ -304,6 +395,11 @@ The following is a list of deprecated interface.
- 3.0
- :confval:`nitpick_ignore`
* - ``BuildEnvironment.versionchanges``
- 1.8
- 3.0
- N/A
* - ``BuildEnvironment.update()``
- 1.8
- 3.0
@ -329,6 +425,11 @@ The following is a list of deprecated interface.
- 3.0
- ``Builder.write_doctree()``
* - ``BuildEnvironment.note_versionchange()``
- 1.8
- 3.0
- ``ChangesDomain.note_changeset()``
* - ``warn()`` (template helper function)
- 1.8
- 3.0
@ -349,6 +450,11 @@ The following is a list of deprecated interface.
- 3.0
- ``sphinx.cmd.build``
* - ``sphinx.make_mode``
- 1.8
- 3.0
- ``sphinx.cmd.make_mode``
* - ``sphinx.locale.l_()``
- 1.8
- 3.0

View File

@ -12,7 +12,7 @@ __ http://docutils.sourceforge.net/docs/dev/hacking.html#parsing-the-document
In Sphinx, the parser modules works as same as docutils. The parsers are
registered to Sphinx by extensions using Application APIs;
:meth:`.Sphinx.add_source_suffix()` and :meth:`.Sphinx.add_source_parsers()`.
:meth:`.Sphinx.add_source_suffix()` and :meth:`.Sphinx.add_source_parser()`.
The *source suffix* is a mapping from file suffix to file type. For example,
``.rst`` file is mapped to ``'restructuredtext'`` type. Sphinx uses the

View File

@ -229,6 +229,13 @@ Options
Turn warnings into errors. This means that the build stops at the first
warning and ``sphinx-build`` exits with exit status 1.
.. option:: --keep-going
With -W option, keep going processing when getting warnings to the end
of build, and ``sphinx-build`` exits with exit status 1.
.. versionadded:: 1.8
.. option:: -T
Display the full traceback when an unhandled exception occurs. Otherwise,
@ -273,7 +280,16 @@ variables to customize behavior:
.. describe:: PAPER
The value for '"papersize"` key of :confval:`latex_elements`.
This sets the ``'papersize'`` key of :confval:`latex_elements`:
i.e. ``PAPER=a4`` sets it to ``'a4paper'`` and ``PAPER=letter`` to
``'letterpaper'``.
.. note::
Usage of this environment variable got broken at Sphinx 1.5 as
``a4`` or ``letter`` ended up as option to LaTeX document in
place of the needed ``a4paper``, resp. ``letterpaper``. Fixed at
1.7.7.
.. describe:: SPHINXBUILD

View File

@ -181,6 +181,14 @@ Options for setuptools integration
.. versionadded:: 1.3
.. confval:: nitpicky
Run in nit-picky mode. Currently, this generates warnings for all missing
references. See the config value :confval:`nitpick_ignore` for a way to
exclude some references as "known missing".
.. versionadded:: 1.8
.. confval:: pdb
A boolean to configure ``pdb`` on exception. Default is false.

View File

@ -150,7 +150,7 @@ These themes are:
- **collapsiblesidebar** (true or false): Add an *experimental* JavaScript
snippet that makes the sidebar collapsible via a button on its side.
*Doesn't work with "stickysidebar".* Defaults to ``False``.
Defaults to ``False``.
- **externalrefs** (true or false): Display external links differently from
internal links. Defaults to ``False``.

View File

@ -773,6 +773,35 @@ documentation on :ref:`intl` for details.
Added ``{path}`` and ``{basename}`` tokens.
.. _math-options:
Options for Math
----------------
These options influence Math notations.
.. confval:: math_number_all
Set this option to ``True`` if you want all displayed math to be numbered.
The default is ``False``.
.. confval:: math_eqref_format
A string that are used for format of label of references to equations.
As a special character, ``{number}`` will be replaced to equaition number.
Example: ``'Eq.{number}'`` is rendered as ``Eq.10``
.. confval:: math_numfig
If ``True``, displayed math equations are numbered across pages when
:confval:`numfig` is enabled. The :confval:`numfig_secnum_depth` setting
is respected. The :rst:role:`eq`, not :rst:role:`numref`, role
must be used to reference equation numbers. Default is ``True``.
.. versionadded:: 1.7
.. _html-options:
Options for HTML output
@ -1284,6 +1313,13 @@ that use Sphinx's HTMLWriter class.
.. versionadded:: 1.3
.. confval:: html_math_renderer
The name of math_renderer extension for HTML output. The default is
``'mathjax'``.
.. versionadded:: 1.8
.. confval:: html_experimental_html5_writer
Output is processed with HTML5 writer. This feature needs docutils 0.13 or
@ -1291,6 +1327,16 @@ that use Sphinx's HTMLWriter class.
.. versionadded:: 1.6
Options for Single HTML output
-------------------------------
.. confval:: singlehtml_sidebars
Custom sidebar templates, must be a dictionary that maps document names to
template names. And it only allows a key named `'index'`. All other keys
are ignored. For more information, refer to :confval:`html_sidebars`. By
default, it is same as :confval:`html_sidebars`.
.. _htmlhelp-options:
@ -1743,15 +1789,33 @@ information.
preamble.
If your project uses such extra Unicode characters, switching the engine to
XeLaTeX or LuaLaTeX often provides a quick fix. They only work with UTF-8
encoded sources and can (in fact, should) use OpenType fonts, either from
the system or the TeX install tree. Recent LaTeX releases will default with
these engines to the Latin Modern OpenType font, which has good coverage of
Latin and Cyrillic scripts (it is provided by standard LaTeX installation),
and Sphinx does not modify this default. Refer to the documentation of the
LaTeX ``polyglossia`` package to see how to instruct LaTeX to use some
other OpenType font if Unicode coverage proves insufficient (or use
directly ``\setmainfont`` et. al. as in :ref:`this example <latex-basic>`.)
XeLaTeX or LuaLaTeX and setting up the document to use an OpenType font
with wide-enough glyph coverage is often easier than sticking with PDFLaTeX
and trying to get it to work with the Unicode characters.
The :confval:`latex_elements` ``'fontpkg'`` key allows to set up the
document fonts, see :ref:`this example <latex-basic>`. Currently, for
XeLaTeX and LuaLaTeX, Sphinx leaves this key empty and LaTeX then defaults
to the `Latin Modern`_ font family (from the TeX distribution fonts). This
font family provides good coverage of Latin scripts (European languages,
Vietnamese) but Cyrillic requires some other OpenType font; for example
Computer Modern Unicode (see `babel-russian`_ documentation on how to load
it in the LaTeX document). In future, it is planned Sphinx will provide
another default choice of OpenType font than `Latin Modern`_, perhaps
`Libertinus`_, which is included in recent TeX distributions and supports
Latin and Cyrillic and also has an accompanying math font.
With XeLaTeX and LuaLaTeX, Sphinx configures the LaTeX document to use
`polyglossia`_. For some languages the `babel`_ support appears
preferable; Sphinx uses currently `babel`_ for French and perhaps will also
for some more languages in future. One can use the
:confval:`latex_elements` ``'babel'`` key to override Sphinx's default.
.. _`Latin Modern`: http://www.gust.org.pl/projects/e-foundry/latin-modern
.. _`polyglossia`: https://ctan.org/pkg/polyglossia
.. _`babel`: https://ctan.org/pkg/babel
.. _`babel-russian`: https://ctan.org/pkg/babel-russian
.. _`Libertinus`: https://ctan.org/pkg/libertinus
.. confval:: latex_documents
@ -1759,32 +1823,39 @@ information.
It must be a list of tuples ``(startdocname, targetname, title, author,
documentclass, toctree_only)``, where the items are:
* *startdocname*: document name that is the "root" of the LaTeX file. All
documents referenced by it in TOC trees will be included in the LaTeX file
too. (If you want only one LaTeX file, use your :confval:`master_doc`
here.)
* *targetname*: file name of the LaTeX file in the output directory.
* *title*: LaTeX document title. Can be empty to use the title of the
*startdoc*. This is inserted as LaTeX markup, so special characters like a
*startdocname*
String that specifies the :term:`document name` of the LaTeX file's master
document. All documents referenced by the *startdoc* document in TOC trees
will be included in the LaTeX file. (If you want to use the default master
document for your LaTeX build, provide your :confval:`master_doc` here.)
*targetname*
File name of the LaTeX file in the output directory.
*title*
LaTeX document title. Can be empty to use the title of the *startdoc*
document. This is inserted as LaTeX markup, so special characters like a
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'`` (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)
documents will not get appendices. Also they have a simpler title page.
Other document classes can be given. Independently of the document class,
the "sphinx" package is always loaded in order to define Sphinx's custom
LaTeX commands.
* *toctree_only*: Must be ``True`` or ``False``. If true, the *startdoc*
document itself is not included in the output, only the documents
referenced by it via TOC trees. With this option, you can put extra stuff
in the master document that shows up in the HTML, but not the LaTeX
output.
*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'`` (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) documents will not get
appendices. Also they have a simpler title page. Other document classes
can be given. Independently of the document class, the "sphinx" package is
always loaded in order to define Sphinx's custom LaTeX commands.
*toctree_only*
Must be ``True`` or ``False``. If true, the *startdoc* document itself is
not included in the output, only the documents referenced by it via TOC
trees. With this option, you can put extra stuff in the master document
that shows up in the HTML, but not the LaTeX output.
.. versionadded:: 1.2
In the past including your own document class required you to prepend the
@ -1877,26 +1948,23 @@ information.
__ http://xindy.sourceforge.net/
- This option is ignored if :confval:`latex_engine` is ``'platex'``
(Japanese documents) as :program:`mendex` is used in that case.
(Japanese documents; :program:`mendex` replaces :program:`makeindex`
then).
- The default is ``True`` for ``'xelatex'`` or ``'lualatex'`` as
:program:`makeindex`, if any indexed term starts with a non-ascii
character, creates ``.ind`` file containing invalid bytes for
character, creates ``.ind`` files containing invalid bytes for
UTF-8 encoding. With ``'lualatex'`` this then breaks the PDF
build. Notice that :program:`xindy` supports most but not
all European languages.
build.
- The default is ``False`` for ``'pdflatex'`` but ``True`` is
recommended for non-English documents as soon as some indexed
terms use non-ascii characters from the language script.
Cyrillic scripts are (transparently) supported with
``'pdflatex'`` thanks to a specific Sphinx-contributed ``xindy``
style file :file:`cyrLICRutf8.xdy`.
As :program:`xindy` does not support the same range of languages
as ``LaTeX/babel`` does, the default :program:`makeindex` for
``'pdflatex'`` may be preferred in some circumstances, although
the index will be ill-formed probably.
Sphinx adds to :program:`xindy` base distribution some dedicated support
for using ``'pdflatex'`` engine with Cyrillic scripts. And whether with
``'pdflatex'`` or Unicode engines, Cyrillic documents handle correctly the
indexing of Latin names, even with diacritics.
.. versionadded:: 1.8
@ -1954,19 +2022,14 @@ information.
is ``'\\usepackage{polyglossia}\n\\setmainlanguage{<language>}'``.
.. versionchanged:: 1.6
``'lualatex'`` uses same default setting as ``'xelatex'``
.. versionchanged:: 1.7.6
For French, ``xelatex`` and ``lualatex`` default to using
``babel``, not ``polyglossia``.
``'fontpkg'``
Font package inclusion, default ``'\\usepackage{times}'`` (which uses
Times for text, Helvetica for sans serif and Courier for code-blocks).
.. hint::
Courier is much wider than Times, and Sphinx emits LaTeX command
``\small`` in code-blocks to compensate. Since ``1.5`` this is not
hard-coded anymore: ``\fvset{fontsize=auto}`` can be added to
preamble to not change font size in code-blocks. Since ``1.8`` a
separate ``'fvset'`` key is provided for this.
.. versionchanged:: 1.2
Defaults to ``''`` when the :confval:`language` uses the Cyrillic
script.
@ -1974,8 +2037,7 @@ information.
Defaults to ``''`` when :confval:`latex_engine` is ``'xelatex'``.
.. versionchanged:: 1.6
Defaults to ``''`` also with ``'lualatex'``.
.. versionchanged:: 1.8
``'xelatex'`` and ``'lualatex'`` do ``\fvset{fontsize=auto}``.
``'fncychap'``
Inclusion of the "fncychap" package (which makes fancy chapter titles),
default ``'\\usepackage[Bjarne]{fncychap}'`` for English documentation
@ -2143,13 +2205,18 @@ information.
index is full of long entries.
``'fvset'``
Customization of ``fancyvrb`` LaTeX package. Defaults to
``'\\fvset{fontsize=\\small}'``, because default font (Courier) used in
code-blocks is wider and taller than default text font (Times).
Customization of ``fancyvrb`` LaTeX package. Currently, Sphinx uses
this key to set the fontsize in code-blocks according to the
:confval:`latex_engine`.
For ``'xelatex'`` and ``'lualatex'``, defaults to
``'\\fvset{fontsize=auto}'``, because the default fonts are part of
one unified typeface family (Latin Modern OpenType).
- ``'pdflatex'`` uses ``'fvset': '\\fvset{fontsize=\\small}'``,
to mitigate the size difference between the default monospaced font
(Courier) and the default text font (Times). You may need to modify
this if you use custom fonts.
- ``'xelatex'`` and ``'lualatex'`` use ``'\\fvset{fontsize=auto}'``,
as there is no size difference between the regular and the
monospaced fonts used by default by Sphinx with these engines.
.. versionadded:: 1.8
@ -2255,9 +2322,11 @@ These options influence manual page output.
section)``, where the items are:
*startdocname*
Document name that is the "root" of the manual page. All documents
referenced by it in TOC trees will be included in the manual file too.
(If you want one master manual page, use your :confval:`master_doc` here.)
String that specifies the :term:`document name` of the manual page's master
document. All documents referenced by the *startdoc* document in TOC trees
will be included in the manual file. (If you want to use the default
master document for your manual pages build, use your :confval:`master_doc`
here.)
*name*
Name of the manual page. This should be a short string without spaces or
@ -2300,17 +2369,19 @@ These options influence Texinfo output.
are:
*startdocname*
Document name that is the "root" of the Texinfo file. All documents
referenced by it in TOC trees will be included in the Texinfo file too.
(If you want only one Texinfo file, use your :confval:`master_doc` here.)
String that specifies the :term:`document name` of the the Texinfo file's
master document. All documents referenced by the *startdoc* document in
TOC trees will be included in the Texinfo file. (If you want to use the
default master document for your Texinfo build, provide your
:confval:`master_doc` here.)
*targetname*
File name (no extension) of the Texinfo file in the output directory.
*title*
Texinfo document title. Can be empty to use the title of the *startdoc*.
Inserted as Texinfo markup, so special characters like ``@`` and ``{}``
will need to be escaped to be inserted literally.
Texinfo document title. Can be empty to use the title of the *startdoc*
document. Inserted as Texinfo markup, so special characters like ``@`` and
``{}`` will need to be escaped to be inserted literally.
*author*
Author for the Texinfo document. Inserted as Texinfo markup. Use ``@*``
@ -2479,12 +2550,21 @@ Options for the linkcheck builder
.. confval:: linkcheck_anchors_ignore
A list of regular expressions that match URIs that should skip checking
the validity of anchors in links. This allows skipping entire sites, where
anchors are used to control dynamic pages, or just specific anchors within
a page, where JavaScript is used to add anchors dynamically, or use the
fragment as part of to trigger an internal REST request. Default is
``["/#!"]``.
A list of regular expressions that match anchors Sphinx should skip when
checking the validity of anchors in links. This allows skipping anchors that
a website's JavaScript adds to control dynamic pages or when triggering an
internal REST request. Default is ``["^!"]``.
.. note::
If you want to ignore anchors of a specific page or of pages that match a
specific pattern (but still check occurrences of the same page(s) that
don't have anchors), use :confval:`linkcheck_ignore` instead, for example
as follows::
linkcheck_ignore = [
'http://www.sphinx-doc.org/en/1.7/intro.html#'
]
.. versionadded:: 1.5

View File

@ -114,8 +114,17 @@ inserting them into the page source under a suitable :rst:dir:`py:module`,
.. autoclass:: Noodle
:members: eat, slurp
* If you want to make the ``members`` option (or other flag options described
below) the default, see :confval:`autodoc_default_flags`.
* If you want to make the ``members`` option (or other options described
below) the default, see :confval:`autodoc_default_options`.
.. tip::
You can use a negated form, :samp:`'no-{flag}'`, as an option of
autodoc directive, to disable it temporarily. For example::
.. automodule:: foo
:no-undoc-members:
* Members without docstrings will be left out, unless you give the
``undoc-members`` flag option::
@ -341,20 +350,38 @@ There are also new config values that you can set:
This value is a list of autodoc directive flags that should be automatically
applied to all autodoc directives. The supported flags are ``'members'``,
``'undoc-members'``, ``'private-members'``, ``'special-members'``,
``'inherited-members'``, ``'show-inheritance'`` and ``'ignore-module-all'``.
If you set one of these flags in this config value, you can use a negated
form, :samp:`'no-{flag}'`, in an autodoc directive, to disable it once.
For example, if ``autodoc_default_flags`` is set to ``['members',
'undoc-members']``, and you write a directive like this::
.. automodule:: foo
:no-undoc-members:
the directive will be interpreted as if only ``:members:`` was given.
``'inherited-members'``, ``'show-inheritance'``, ``'ignore-module-all'``
and ``'exclude-members'``.
.. versionadded:: 1.0
.. deprecated:: 1.8
Integrated into :confval:`autodoc_default_options`.
.. confval:: autodoc_default_options
The default options for autodoc directives. They are applied to all autodoc
directives automatically. It must be a dictionary which maps option names
to the values. For example::
autodoc_default_options = {
'members': 'var1, var2',
'member-order': 'bysource',
'special-members': '__init__',
'undoc-members': None,
'exclude-members': '__weakref__'
}
Setting ``None`` is equivalent to giving the option name in the list format
(i.e. it means "yes/true/on").
The supported options are ``'members'``, ``'undoc-members'``,
``'private-members'``, ``'special-members'``, ``'inherited-members'``,
``'show-inheritance'``, ``'ignore-module-all'`` and ``'exclude-members'``.
.. versionadded:: 1.8
.. confval:: autodoc_docstring_signature
Functions imported from C modules cannot be introspected, and therefore the

View File

@ -198,6 +198,81 @@ The following is an example for the usage of the directives. The test via
This parrot wouldn't voom if you put 3000 volts through it!
Skipping tests conditionally
----------------------------
``skipif``, a string option, can be used to skip directives conditionally. This
may be useful e.g. when a different set of tests should be run depending on the
environment (hardware, network/VPN, optional dependencies or different versions
of dependencies). The ``skipif`` option is supported by all of the doctest
directives. Below are typical use cases for ``skipif`` when used for different
directives:
- :rst:dir:`testsetup` and :rst:dir:`testcleanup`
- conditionally skip test setup and/or cleanup
- customize setup/cleanup code per environment
- :rst:dir:`doctest`
- conditionally skip both a test and its output verification
- :rst:dir:`testcode`
- conditionally skip a test
- customize test code per environment
- :rst:dir:`testoutput`
- conditionally skip output assertion for a skipped test
- expect different output depending on the environment
The value of the ``skipif`` option is evaluated as a Python expression. If the
result is a true value, the directive is omitted from the test run just as if
it wasn't present in the file at all.
Instead of repeating an expression, the :confval:`doctest_global_setup`
configuration option can be used to assign it to a variable which can then be
used instead.
Here's an example which skips some tests if Pandas is not installed:
.. code-block:: py
:caption: conf.py
extensions = ['sphinx.ext.doctest']
doctest_global_setup = '''
try:
import pandas as pd
except ImportError:
pd = None
'''
.. code-block:: rst
:caption: contents.rst
.. testsetup::
:skipif: pd is None
data = pd.Series([42])
.. doctest::
:skipif: pd is None
>>> data.iloc[0]
42
.. testcode::
:skipif: pd is None
print(data.iloc[-1])
.. testoutput::
:skipif: pd is None
42
Configuration
-------------

View File

@ -2,123 +2,20 @@
.. _math-support:
Math support in Sphinx
======================
Math support for HTML outputs in Sphinx
=======================================
.. module:: sphinx.ext.mathbase
:synopsis: Common math support for imgmath and mathjax / jsmath.
.. versionadded:: 0.5
.. versionchanged:: 1.8
Math support for non-HTML builders is integrated to sphinx-core.
So mathbase extension is no longer needed.
Since mathematical notation isn't natively supported by HTML in any way, Sphinx
supports math in documentation with several extensions.
The basic math support is contained in :mod:`sphinx.ext.mathbase`. Other math
support extensions should, if possible, reuse that support too.
.. note::
:mod:`.mathbase` is not meant to be added to the :confval:`extensions` config
value, instead, use either :mod:`sphinx.ext.imgmath` or
:mod:`sphinx.ext.mathjax` as described below.
The input language for mathematics is LaTeX markup. This is the de-facto
standard for plain-text math notation and has the added advantage that no
further translation is necessary when building LaTeX output.
Keep in mind that when you put math markup in **Python docstrings** read by
:mod:`autodoc <sphinx.ext.autodoc>`, you either have to double all backslashes,
or use Python raw strings (``r"raw"``).
:mod:`.mathbase` provides the following config values:
.. confval:: math_number_all
Set this option to ``True`` if you want all displayed math to be numbered.
The default is ``False``.
.. confval:: math_eqref_format
A string that are used for format of label of references to equations.
As a special character, ``{number}`` will be replaced to equaition number.
Example: ``'Eq.{number}'`` is rendered as ``Eq.10``
.. confval:: math_numfig
If ``True``, displayed math equations are numbered across pages when
:confval:`numfig` is enabled. The :confval:`numfig_secnum_depth` setting
is respected. The :rst:role:`eq`, not :rst:role:`numref`, role
must be used to reference equation numbers. Default is ``True``.
.. versionadded:: 1.7
:mod:`.mathbase` defines these new markup elements:
.. rst:role:: math
Role for inline math. Use like this::
Since Pythagoras, we know that :math:`a^2 + b^2 = c^2`.
.. rst:directive:: math
Directive for displayed math (math that takes the whole line for itself).
The directive supports multiple equations, which should be separated by a
blank line::
.. math::
(a + b)^2 = a^2 + 2ab + b^2
(a - b)^2 = a^2 - 2ab + b^2
In addition, each single equation is set within a ``split`` environment,
which means that you can have multiple aligned lines in an equation,
aligned at ``&`` and separated by ``\\``::
.. math::
(a + b)^2 &= (a + b)(a + b) \\
&= a^2 + 2ab + b^2
For more details, look into the documentation of the `AmSMath LaTeX
package`_.
When the math is only one line of text, it can also be given as a directive
argument::
.. math:: (a + b)^2 = a^2 + 2ab + b^2
Normally, equations are not numbered. If you want your equation to get a
number, use the ``label`` option. When given, it selects an internal label
for the equation, by which it can be cross-referenced, and causes an equation
number to be issued. See :rst:role:`eq` for an example. The numbering
style depends on the output format.
There is also an option ``nowrap`` that prevents any wrapping of the given
math in a math environment. When you give this option, you must make sure
yourself that the math is properly set up. For example::
.. math::
:nowrap:
\begin{eqnarray}
y & = & ax^2 + bx + c \\
f(x) & = & x^2 + 2xy + y^2
\end{eqnarray}
.. rst:role:: eq
Role for cross-referencing equations via their label. Example::
.. math:: e^{i\pi} + 1 = 0
:label: euler
Euler's identity, equation :eq:`euler`, was elected one of the most
beautiful mathematical formulas.
gives a math support to HTML document with several extensions.
:mod:`sphinx.ext.imgmath` -- Render math as images
--------------------------------------------------
@ -271,6 +168,23 @@ Sphinx.
The default is empty (``{}``).
.. confval:: mathjax_config
The inline configuration options for mathjax. The value is used as a
parameter of ``MathJax.Hub.Config()``. For more information, please
read `Using in-line configuration options`_.
For example::
mathjax_config = {
'extensions': ['tex2jax.js'],
'jax': ['input/TeX', 'output/HTML-CSS'],
}
The default is empty (not configured).
.. _Using in-line configuration options: http://docs.mathjax.org/en/latest/configuration.html#using-in-line-configuration-options
:mod:`sphinx.ext.jsmath` -- Render math via JavaScript
------------------------------------------------------
@ -299,4 +213,3 @@ package jsMath_. It provides this config value:
.. _MathJax: https://www.mathjax.org/
.. _jsMath: http://www.math.union.edu/~dpvc/jsmath/
.. _preview-latex package: https://www.gnu.org/software/auctex/preview-latex.html
.. _AmSMath LaTeX package: https://www.ams.org/publications/authors/tex/amslatex

View File

@ -25,7 +25,11 @@ from the source to the description will also be inserted.
In addition, if you don't want to import the modules by ``viewcode``,
you can tell the location of the location of source code to ``viewcode``
using :event:`viewcode-find-source` event.
using the :event:`viewcode-find-source` event.
If :confval:`viewcode_follow_imported_members` is enabled,
you will also need to resolve imported attributes
using the :event:`viewcode-follow-imported` event.
This extension works only on HTML related builders like ``html``,
``applehelp``, ``devhelp``, ``htmlhelp``, ``qthelp`` and so on except
@ -83,3 +87,13 @@ Configuration
:param app: The Sphinx application object.
:param modname: The name of the module to find source code for.
.. event:: viewcode-follow-imported (app, modname, attribute)
.. versionadded:: 1.8
Find the name of the original module for an attribute.
:param app: The Sphinx application object.
:param modname: The name of the module that the attribute belongs to.
:param attribute: The name of the member to follow.

View File

@ -1005,9 +1005,63 @@ this reason, the following directive exists:
Math
----
.. todo:: Move this in here.
The input language for mathematics is LaTeX markup. This is the de-facto
standard for plain-text math notation and has the added advantage that no
further translation is necessary when building LaTeX output.
See :ref:`math-support`.
Keep in mind that when you put math markup in **Python docstrings** read by
:mod:`autodoc <sphinx.ext.autodoc>`, you either have to double all backslashes,
or use Python raw strings (``r"raw"``).
.. rst:directive:: math
Directive for displayed math (math that takes the whole line for itself).
The directive supports multiple equations, which should be separated by a
blank line::
.. math::
(a + b)^2 = a^2 + 2ab + b^2
(a - b)^2 = a^2 - 2ab + b^2
In addition, each single equation is set within a ``split`` environment,
which means that you can have multiple aligned lines in an equation,
aligned at ``&`` and separated by ``\\``::
.. math::
(a + b)^2 &= (a + b)(a + b) \\
&= a^2 + 2ab + b^2
For more details, look into the documentation of the `AmSMath LaTeX
package`_.
When the math is only one line of text, it can also be given as a directive
argument::
.. math:: (a + b)^2 = a^2 + 2ab + b^2
Normally, equations are not numbered. If you want your equation to get a
number, use the ``label`` option. When given, it selects an internal label
for the equation, by which it can be cross-referenced, and causes an equation
number to be issued. See :rst:role:`eq` for an example. The numbering
style depends on the output format.
There is also an option ``nowrap`` that prevents any wrapping of the given
math in a math environment. When you give this option, you must make sure
yourself that the math is properly set up. For example::
.. math::
:nowrap:
\begin{eqnarray}
y & = & ax^2 + bx + c \\
f(x) & = & x^2 + 2xy + y^2
\end{eqnarray}
.. _AmSMath LaTeX package: https://www.ams.org/publications/authors/tex/amslatex
Grammar production displays

View File

@ -1005,20 +1005,46 @@ These roles link to the given declaration types:
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
It is currently impossible to link to a specific version of an overloaded
function. Currently the C++ domain is the first domain that has basic
support for overloaded functions and until there is more data for comparison
we don't want to select a bad syntax to reference a specific overload.
Currently Sphinx will link to the first overloaded version of the function.
Declarations without template parameters and template arguments
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
For linking to non-templated declarations the name must be a nested name, e.g.,
``f`` or ``MyClass::f``.
Overloaded (member) functions
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
When a (member) function is referenced using just its name, the reference
will point to an arbitrary matching overload.
The :rst:role:`cpp:any` and :rst:role:`cpp:func` roles will an alternative
format, which simply is a complete function declaration.
This will resolve to the exact matching overload.
As example, consider the following class declaration:
.. cpp:namespace-push:: overload_example
.. cpp:class:: C
.. cpp:function:: void f(double d) const
.. cpp:function:: void f(double d)
.. cpp:function:: void f(int i)
.. cpp:function:: void f()
References using the :rst:role:`cpp:func` role:
- Arbitrary overload: ``C::f``, :cpp:func:`C::f`
- Also arbitrary overload: ``C::f()``, :cpp:func:`C::f()`
- Specific overload: ``void C::f()``, :cpp:func:`void C::f()`
- Specific overload: ``void C::f(int)``, :cpp:func:`void C::f(int)`
- Specific overload: ``void C::f(double)``, :cpp:func:`void C::f(double)`
- Specific overload: ``void C::f(double) const``, :cpp:func:`void C::f(double) const`
Note that the :confval:`add_function_parentheses` configuration variable
does not influence specific overload references.
.. cpp:namespace-pop::
Templated declarations
^^^^^^^^^^^^^^^^^^^^^^
@ -1033,19 +1059,25 @@ Assume the following declarations.
Inner
In general the reference must include the template parameter declarations,
e.g., ``template\<typename TOuter> Wrapper::Outer``
(:cpp:class:`template\<typename TOuter> Wrapper::Outer`). Currently the lookup
only succeed if the template parameter identifiers are equal strings. That is,
``template\<typename UOuter> Wrapper::Outer`` will not work.
and template arguments for the prefix of qualified names. For example:
The inner class template cannot be directly referenced, unless the current
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
non-template, but not a partial template specialisation. This means the
following references work.
- ``template\<typename TOuter> Wrapper::Outer``
(:cpp:class:`template\<typename TOuter> Wrapper::Outer`)
- ``template\<typename TOuter> template\<typename TInner> Wrapper::Outer<TOuter>::Inner``
(:cpp:class:`template\<typename TOuter> template\<typename TInner> Wrapper::Outer<TOuter>::Inner`)
- ``Wrapper::Outer`` (:cpp:class:`Wrapper::Outer`)
- ``Wrapper::Outer::Inner`` (:cpp:class:`Wrapper::Outer::Inner`)
Currently the lookup only succeed if the template parameter identifiers are equal strings.
That is, ``template\<typename UOuter> Wrapper::Outer`` will not work.
As a shorthand notation, if a template parameter list is omitted,
then the lookup will assume either a primary template or a non-template,
but not a partial template specialisation.
This means the following references work as well:
- ``Wrapper::Outer``
(:cpp:class:`Wrapper::Outer`)
- ``Wrapper::Outer::Inner``
(:cpp:class:`Wrapper::Outer::Inner`)
- ``template\<typename TInner> Wrapper::Outer::Inner``
(:cpp:class:`template\<typename TInner> Wrapper::Outer::Inner`)
@ -1325,6 +1357,25 @@ These roles are provided to refer to the described objects:
.. rst:role:: rst:dir
rst:role
.. _math-domain:
The Math Domain
---------------
The math domain (name **math**) provides the following roles::
.. rst:role:: math:numref
Role for cross-referencing equations defined by :rst:dir:`math` directive
via their label. Example::
.. math:: e^{i\pi} + 1 = 0
:label: euler
Euler's identity, equation :math:numref:`euler`, was elected one of the
most beautiful mathematical formulas.
.. versionadded:: 1.8
More domains
------------

View File

@ -277,6 +277,20 @@ The following role creates a cross-reference to a term in a
during build.
Math
----
.. rst:role:: math
Role for inline math. Use like this::
Since Pythagoras, we know that :math:`a^2 + b^2 = c^2`.
.. rst:role:: eq
Same as :rst:role:`math:numref`.
Other semantic markup
---------------------

72
karma.conf.js Normal file
View File

@ -0,0 +1,72 @@
// Karma configuration
// Generated on Sat Jul 21 2018 22:01:48 GMT+0200 (CEST)
module.exports = function(config) {
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '',
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['jasmine'],
// list of files / patterns to load in the browser
files: [
'sphinx/themes/basic/static/underscore.js',
'sphinx/themes/basic/static/jquery.js',
'sphinx/themes/basic/static/doctools.js',
'tests/js/*.js'
],
// list of files / patterns to exclude
exclude: [
],
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
},
// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['progress'],
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: true,
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ['Chrome', 'Firefox'],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false,
// Concurrency level
// how many browser should be started simultaneous
concurrency: Infinity
})
}

2886
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

20
package.json Normal file
View File

@ -0,0 +1,20 @@
{
"name": "sphinx",
"scripts": {
"test": "./node_modules/.bin/karma start --browsers Firefox --single-run"
},
"repository": {
"type": "git",
"url": "git+https://github.com/sphinx-doc/sphinx.git"
},
"bugs": {
"url": "https://github.com/sphinx-doc/sphinx/issues"
},
"devDependencies": {
"jasmine-core": "^3.1.0",
"karma": "^3.0.0",
"karma-chrome-launcher": "^2.2.0",
"karma-firefox-launcher": "^1.1.0",
"karma-jasmine": "^1.1.2"
}
}

View File

@ -37,8 +37,8 @@ if 'PYTHONWARNINGS' not in os.environ:
warnings.filterwarnings('ignore', "'U' mode is deprecated",
DeprecationWarning, module='docutils.io')
__version__ = '1.8.0+'
__released__ = '1.8.0' # used when Sphinx builds its own docs
__version__ = '2.0.0+'
__released__ = '2.0.0' # used when Sphinx builds its own docs
#: Version info for better programmatic use.
#:
@ -48,7 +48,7 @@ __released__ = '1.8.0' # used when Sphinx builds its own docs
#:
#: .. versionadded:: 1.2
#: Before version 1.2, check the string ``sphinx.__version__``.
version_info = (1, 8, 0, 'beta', 0)
version_info = (2, 0, 0, 'beta', 0)
package_dir = path.abspath(path.dirname(__file__))

View File

@ -80,6 +80,7 @@ builtin_extensions = (
'sphinx.builders.xml',
'sphinx.config',
'sphinx.domains.c',
'sphinx.domains.changeset',
'sphinx.domains.cpp',
'sphinx.domains.javascript',
'sphinx.domains.math',
@ -96,6 +97,7 @@ builtin_extensions = (
'sphinx.registry',
'sphinx.roles',
'sphinx.transforms.post_transforms',
'sphinx.transforms.post_transforms.code',
'sphinx.transforms.post_transforms.images',
'sphinx.transforms.post_transforms.compat',
'sphinx.util.compat',
@ -128,8 +130,8 @@ class Sphinx(object):
def __init__(self, srcdir, confdir, outdir, doctreedir, buildername,
confoverrides=None, status=sys.stdout, warning=sys.stderr,
freshenv=False, warningiserror=False, tags=None, verbosity=0,
parallel=0):
# type: (unicode, unicode, unicode, unicode, unicode, Dict, IO, IO, bool, bool, List[unicode], int, int) -> None # NOQA
parallel=0, keep_going=False):
# type: (unicode, unicode, unicode, unicode, unicode, Dict, IO, IO, bool, bool, List[unicode], int, int, bool) -> None # NOQA
self.phase = BuildPhase.INITIALIZATION
self.verbosity = verbosity
self.extensions = {} # type: Dict[unicode, Extension]
@ -172,7 +174,11 @@ class Sphinx(object):
else:
self._warning = warning
self._warncount = 0
self.warningiserror = warningiserror
self.keep_going = warningiserror and keep_going
if self.keep_going:
self.warningiserror = False
else:
self.warningiserror = warningiserror
logging.setup(self, self._status, self._warning)
self.events = EventManager()
@ -334,6 +340,9 @@ class Sphinx(object):
self.builder.compile_update_catalogs()
self.builder.build_update()
if self._warncount and self.keep_going:
self.statuscode = 1
status = (self.statuscode == 0 and
__('succeeded') or __('finished with problems'))
if self._warncount:
@ -1220,6 +1229,20 @@ class Sphinx(object):
logger.debug('[app] adding HTML theme: %r, %r', name, theme_path)
self.html_themes[name] = theme_path
def add_html_math_renderer(self, name, inline_renderers=None, block_renderers=None):
# type: (unicode, Tuple[Callable, Callable], Tuple[Callable, Callable]) -> None
"""Register a math renderer for HTML.
The *name* is a name of the math renderer. Both *inline_renderers* and
*block_renderes* are used as visitor functions for HTML writer.
*inline_renderers* is used for inline math node (``nodes.math`)). The
another is used for block math node (``nodes.math_block``). About
visitor functions, see :meth:`add_node` for more details.
.. versionadded:: 1.8
"""
self.registry.add_html_math_renderer(name, inline_renderers, block_renderers)
def add_message_catalog(self, catalog, locale_dir):
# type: (unicode, unicode) -> None
"""Register a message catalog.

View File

@ -195,7 +195,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
"""Collect section titles, their depth in the toc and the refuri."""
# XXX: is there a better way than checking the attribute
# toctree-l[1-8] on the parent node?
if isinstance(doctree, nodes.reference) and 'refuri' in doctree:
if isinstance(doctree, nodes.reference) and doctree.get('refuri'):
refuri = doctree['refuri']
if refuri.startswith('http://') or refuri.startswith('https://') \
or refuri.startswith('irc:') or refuri.startswith('mailto:'):

View File

@ -11,11 +11,13 @@
import codecs
from os import path
from typing import cast
from six import iteritems
from sphinx import package_dir
from sphinx.builders import Builder
from sphinx.domains.changeset import ChangeSetDomain
from sphinx.locale import _, __
from sphinx.theming import HTMLThemeFactory
from sphinx.util import logging
@ -60,6 +62,7 @@ class ChangesBuilder(Builder):
def write(self, *ignored):
# type: (Any) -> None
version = self.config.version
domain = cast(ChangeSetDomain, self.env.get_domain('changeset'))
libchanges = {} # type: Dict[unicode, List[Tuple[unicode, unicode, int]]]
apichanges = [] # type: List[Tuple[unicode, unicode, int]]
otherchanges = {} # type: Dict[Tuple[unicode, unicode], List[Tuple[unicode, unicode, int]]] # NOQA
@ -67,21 +70,22 @@ class ChangesBuilder(Builder):
logger.info(bold(__('no changes in version %s.') % version))
return
logger.info(bold('writing summary file...'))
for type, docname, lineno, module, descname, content in \
self.env.versionchanges[version]:
if isinstance(descname, tuple):
descname = descname[0]
ttext = self.typemap[type]
context = content.replace('\n', ' ')
if descname and docname.startswith('c-api'):
for changeset in domain.get_changesets_for(version):
if isinstance(changeset.descname, tuple):
descname = changeset.descname[0]
else:
descname = changeset.descname
ttext = self.typemap[changeset.type]
context = changeset.content.replace('\n', ' ')
if descname and changeset.docname.startswith('c-api'):
if context:
entry = '<b>%s</b>: <i>%s:</i> %s' % (descname, ttext,
context)
else:
entry = '<b>%s</b>: <i>%s</i>.' % (descname, ttext)
apichanges.append((entry, docname, lineno))
elif descname or module:
if not module:
apichanges.append((entry, changeset.docname, changeset.lineno))
elif descname or changeset.module:
if not changeset.module:
module = _('Builtins')
if not descname:
descname = _('Module level')
@ -90,15 +94,15 @@ class ChangesBuilder(Builder):
context)
else:
entry = '<b>%s</b>: <i>%s</i>.' % (descname, ttext)
libchanges.setdefault(module, []).append((entry, docname,
lineno))
libchanges.setdefault(module, []).append((entry, changeset.docname,
changeset.lineno))
else:
if not context:
continue
entry = '<i>%s:</i> %s' % (ttext.capitalize(), context)
title = self.env.titles[docname].astext()
otherchanges.setdefault((docname, title), []).append(
(entry, docname, lineno))
title = self.env.titles[changeset.docname].astext()
otherchanges.setdefault((changeset.docname, title), []).append(
(entry, changeset.docname, changeset.lineno))
ctx = {
'project': self.config.project,

View File

@ -36,7 +36,7 @@ from sphinx.deprecation import RemovedInSphinx20Warning, RemovedInSphinx30Warnin
from sphinx.environment.adapters.asset import ImageAdapter
from sphinx.environment.adapters.indexentries import IndexEntries
from sphinx.environment.adapters.toctree import TocTree
from sphinx.errors import ThemeError
from sphinx.errors import ConfigError, ThemeError
from sphinx.highlighting import PygmentsBridge
from sphinx.locale import _, __
from sphinx.search import js_index
@ -386,8 +386,7 @@ class StandaloneHTMLBuilder(Builder):
style = self.theme.get_config('theme', 'pygments_style', 'none')
else:
style = 'sphinx'
self.highlighter = PygmentsBridge('html', style,
self.config.trim_doctest_flags)
self.highlighter = PygmentsBridge('html', style)
def init_css_files(self):
# type: () -> None
@ -421,7 +420,7 @@ class StandaloneHTMLBuilder(Builder):
def add_js_file(self, filename, **kwargs):
# type: (unicode, **unicode) -> None
if '://' not in filename:
if filename and '://' not in filename:
filename = posixpath.join('_static', filename)
self.script_files.append(JavaScript(filename, **kwargs)) # type: ignore
@ -438,6 +437,27 @@ class StandaloneHTMLBuilder(Builder):
else:
return HTMLTranslator
@property
def math_renderer_name(self):
# type: () -> unicode
name = self.get_builder_config('math_renderer', 'html')
if name is not None:
# use given name
return name
else:
# not given: choose a math_renderer from registered ones as possible
renderers = list(self.app.registry.html_inline_math_renderers)
if len(renderers) == 1:
# only default math_renderer (mathjax) is registered
return renderers[0]
elif len(renderers) == 2:
# default and another math_renderer are registered; prior the another
renderers.remove('mathjax')
return renderers[0]
else:
# many math_renderers are registered. can't choose automatically!
return None
def get_outdated_docs(self):
# type: () -> Iterator[unicode]
try:
@ -1046,7 +1066,8 @@ class StandaloneHTMLBuilder(Builder):
sidebars = [name.strip() for name in theme_default_sidebars.split(',')]
# user sidebar settings
for pattern, patsidebars in iteritems(self.config.html_sidebars):
html_sidebars = self.get_builder_config('sidebars', 'html')
for pattern, patsidebars in iteritems(html_sidebars):
if patmatch(pagename, pattern):
if matched:
if has_wildcard(pattern):
@ -1610,21 +1631,39 @@ def setup_js_tag_helper(app, pagename, templatexname, context, doctree):
def js_tag(js):
# type: (JavaScript) -> unicode
attrs = []
body = '' # type: unicode
if isinstance(js, JavaScript):
for key in sorted(js.attributes):
value = js.attributes[key]
if value is not None:
attrs.append('%s="%s"' % (key, htmlescape(value, True)))
attrs.append('src="%s"' % pathto(js.filename, resource=True))
if key == 'body':
body = value
else:
attrs.append('%s="%s"' % (key, htmlescape(value, True)))
if js.filename:
attrs.append('src="%s"' % pathto(js.filename, resource=True))
else:
# str value (old styled)
attrs.append('type="text/javascript"')
attrs.append('src="%s"' % pathto(js, resource=True))
return '<script %s></script>' % ' '.join(attrs)
return '<script %s>%s</script>' % (' '.join(attrs), body)
context['js_tag'] = js_tag
def validate_math_renderer(app):
# type: (Sphinx) -> None
if app.builder.format != 'html':
return
name = app.builder.math_renderer_name # type: ignore
if name is None:
raise ConfigError(__('Many math_renderers are registered. '
'But no math_renderer is selected.'))
elif name not in app.registry.html_inline_math_renderers:
raise ConfigError(__('Unknown math_renderer %r is given.') % name)
def setup(app):
# type: (Sphinx) -> Dict[unicode, Any]
# builders
@ -1674,12 +1713,19 @@ def setup(app):
app.add_config_value('html_scaled_image_link', True, 'html')
app.add_config_value('html_experimental_html5_writer', None, 'html')
app.add_config_value('html_baseurl', '', 'html')
app.add_config_value('html_math_renderer', None, 'env')
app.add_config_value('singlehtml_sidebars', lambda self: self.html_sidebars, 'html')
# event handlers
app.connect('config-inited', convert_html_css_files)
app.connect('config-inited', convert_html_js_files)
app.connect('builder-inited', validate_math_renderer)
app.connect('html-page-context', setup_js_tag_helper)
# load default math renderer
app.setup_extension('sphinx.ext.mathjax')
return {
'version': 'builtin',
'parallel_read_safe': True,

View File

@ -34,7 +34,7 @@ from sphinx.util.docutils import SphinxFileOutput, new_document
from sphinx.util.fileutil import copy_asset_file
from sphinx.util.nodes import inline_all_toctrees
from sphinx.util.osutil import SEP, make_filename
from sphinx.writers.latex import LaTeXWriter, LaTeXTranslator
from sphinx.writers.latex import DEFAULT_SETTINGS, LaTeXWriter, LaTeXTranslator
if False:
# For type annotation
@ -169,8 +169,7 @@ class LaTeXBuilder(Builder):
def write_stylesheet(self):
# type: () -> None
highlighter = highlighting.PygmentsBridge(
'latex', self.config.pygments_style, self.config.trim_doctest_flags)
highlighter = highlighting.PygmentsBridge('latex', self.config.pygments_style)
stylesheet = path.join(self.outdir, 'sphinxhighlight.sty')
with open(stylesheet, 'w') as f:
f.write('\\NeedsTeXFormat{LaTeX2e}[1995/12/01]\n')
@ -374,6 +373,12 @@ def validate_config_values(app, config):
'Please use u"..." notation instead): %r') % (document,)
)
for key in list(config.latex_elements):
if key not in DEFAULT_SETTINGS:
msg = __("Unknown configure key: latex_elements[%r]. ignored.")
logger.warning(msg % key)
config.latex_elements.pop(key)
def default_latex_engine(config):
# type: (Config) -> unicode

View File

@ -561,7 +561,7 @@ class MathReferenceTransform(SphinxTransform):
equations = self.env.get_domain('math').data['objects']
for node in self.document.traverse(addnodes.pending_xref):
if node['refdomain'] == 'math' and node['reftype'] == 'eq':
if node['refdomain'] == 'math' and node['reftype'] in ('eq', 'numref'):
docname, _ = equations.get(node['reftarget'], (None, None))
if docname:
refnode = math_reference('', docname=docname, target=node['reftarget'])

View File

@ -120,12 +120,15 @@ class CheckExternalLinksBuilder(Builder):
def check_thread(self):
# type: () -> None
kwargs = {}
kwargs = {
'allow_redirects': True,
'headers': {
'Accept': 'text/html,application/xhtml+xml;q=0.9,*/*;q=0.8'
},
}
if self.app.config.linkcheck_timeout:
kwargs['timeout'] = self.app.config.linkcheck_timeout
kwargs['allow_redirects'] = True
def check_uri():
# type: () -> Tuple[unicode, unicode, int]
# split off anchor

View File

@ -73,6 +73,10 @@ class ManualPageBuilder(Builder):
for info in self.config.man_pages:
docname, name, description, authors, section = info
if docname not in self.env.all_docs:
logger.warning(__('"man_pages" config value references unknown '
'document %s'), docname)
continue
if isinstance(authors, string_types):
if authors:
authors = [authors]

View File

@ -189,6 +189,8 @@ files can be built by specifying individual filenames.
help=__('write warnings (and errors) to given file'))
group.add_argument('-W', action='store_true', dest='warningiserror',
help=__('turn warnings into errors'))
group.add_argument('--keep-going', action='store_true', dest='keep_going',
help=__("With -W, Keep going when getting warnings"))
group.add_argument('-T', action='store_true', dest='traceback',
help=__('show full traceback on exception'))
group.add_argument('-P', action='store_true', dest='pdb',
@ -200,7 +202,7 @@ files can be built by specifying individual filenames.
def make_main(argv=sys.argv[1:]): # type: ignore
# type: (List[unicode]) -> int
"""Sphinx build "make mode" entry."""
from sphinx import make_mode
from sphinx.cmd import make_mode
return make_mode.run_make_mode(argv[1:])
@ -298,7 +300,7 @@ def build_main(argv=sys.argv[1:]): # type: ignore
app = Sphinx(args.sourcedir, args.confdir, args.outputdir,
args.doctreedir, args.builder, confoverrides, status,
warning, args.freshenv, args.warningiserror,
args.tags, args.verbosity, args.jobs)
args.tags, args.verbosity, args.jobs, args.keep_going)
app.build(args.force_all, filenames)
return app.statuscode
except (Exception, KeyboardInterrupt) as exc:

175
sphinx/cmd/make_mode.py Normal file
View File

@ -0,0 +1,175 @@
# -*- coding: utf-8 -*-
"""
sphinx.cmd.make_mode
~~~~~~~~~~~~~~~~~~~~
sphinx-build -M command-line handling.
This replaces the old, platform-dependent and once-generated content
of Makefile / make.bat.
This is in its own module so that importing it is fast. It should not
import the main Sphinx modules (like sphinx.applications, sphinx.builders).
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
from __future__ import print_function
import os
import subprocess
import sys
from os import path
import sphinx
from sphinx.cmd.build import build_main
from sphinx.util.console import color_terminal, nocolor, bold, blue # type: ignore
from sphinx.util.osutil import cd, rmtree
if False:
# For type annotation
from typing import List # NOQA
BUILDERS = [
("", "html", "to make standalone HTML files"),
("", "dirhtml", "to make HTML files named index.html in directories"),
("", "singlehtml", "to make a single large HTML file"),
("", "pickle", "to make pickle files"),
("", "json", "to make JSON files"),
("", "htmlhelp", "to make HTML files and an HTML help project"),
("", "qthelp", "to make HTML files and a qthelp project"),
("", "devhelp", "to make HTML files and a Devhelp project"),
("", "epub", "to make an epub"),
("", "latex", "to make LaTeX files, you can set PAPER=a4 or PAPER=letter"),
("posix", "latexpdf", "to make LaTeX and PDF files (default pdflatex)"),
("posix", "latexpdfja", "to make LaTeX files and run them through platex/dvipdfmx"),
("", "text", "to make text files"),
("", "man", "to make manual pages"),
("", "texinfo", "to make Texinfo files"),
("posix", "info", "to make Texinfo files and run them through makeinfo"),
("", "gettext", "to make PO message catalogs"),
("", "changes", "to make an overview of all changed/added/deprecated items"),
("", "xml", "to make Docutils-native XML files"),
("", "pseudoxml", "to make pseudoxml-XML files for display purposes"),
("", "linkcheck", "to check all external links for integrity"),
("", "doctest", "to run all doctests embedded in the documentation "
"(if enabled)"),
("", "coverage", "to run coverage check of the documentation (if enabled)"),
]
class Make(object):
def __init__(self, srcdir, builddir, opts):
# type: (unicode, unicode, List[unicode]) -> None
self.srcdir = srcdir
self.builddir = builddir
self.opts = opts
self.makecmd = os.environ.get('MAKE', 'make') # refer $MAKE to determine make command
def builddir_join(self, *comps):
# type: (unicode) -> unicode
return path.join(self.builddir, *comps)
def build_clean(self):
# type: () -> int
if not path.exists(self.builddir):
return 0
elif not path.isdir(self.builddir):
print("Error: %r is not a directory!" % self.builddir)
return 1
print("Removing everything under %r..." % self.builddir)
for item in os.listdir(self.builddir):
rmtree(self.builddir_join(item))
return 0
def build_help(self):
# type: () -> None
if not color_terminal():
nocolor()
print(bold("Sphinx v%s" % sphinx.__display_version__))
print("Please use `make %s' where %s is one of" % ((blue('target'),) * 2)) # type: ignore # NOQA
for osname, bname, description in BUILDERS:
if not osname or os.name == osname:
print(' %s %s' % (blue(bname.ljust(10)), description))
def build_latexpdf(self):
# type: () -> int
if self.run_generic_build('latex') > 0:
return 1
if sys.platform == 'win32':
makecmd = os.environ.get('MAKE', 'make.bat')
else:
makecmd = self.makecmd
try:
with cd(self.builddir_join('latex')):
return subprocess.call([makecmd, 'all-pdf'])
except OSError:
print('Error: Failed to run: %s' % makecmd)
return 1
def build_latexpdfja(self):
# type: () -> int
if self.run_generic_build('latex') > 0:
return 1
if sys.platform == 'win32':
makecmd = os.environ.get('MAKE', 'make.bat')
else:
makecmd = self.makecmd
try:
with cd(self.builddir_join('latex')):
return subprocess.call([makecmd, 'all-pdf'])
except OSError:
print('Error: Failed to run: %s' % makecmd)
return 1
def build_info(self):
# type: () -> int
if self.run_generic_build('texinfo') > 0:
return 1
try:
with cd(self.builddir_join('texinfo')):
return subprocess.call([self.makecmd, 'info'])
except OSError:
print('Error: Failed to run: %s' % self.makecmd)
return 1
def build_gettext(self):
# type: () -> int
dtdir = self.builddir_join('gettext', '.doctrees')
if self.run_generic_build('gettext', doctreedir=dtdir) > 0:
return 1
return 0
def run_generic_build(self, builder, doctreedir=None):
# type: (unicode, unicode) -> int
# compatibility with old Makefile
papersize = os.getenv('PAPER', '')
opts = self.opts
if papersize in ('a4', 'letter'):
opts.extend(['-D', 'latex_elements.papersize=' + papersize + 'paper'])
if doctreedir is None:
doctreedir = self.builddir_join('doctrees')
args = ['-b', builder,
'-d', doctreedir,
self.srcdir,
self.builddir_join(builder)]
return build_main(args + opts)
def run_make_mode(args):
# type: (List[unicode]) -> int
if len(args) < 3:
print('Error: at least 3 arguments (builder, source '
'dir, build dir) are required.', file=sys.stderr)
return 1
make = Make(args[1], args[2], args[3:])
run_method = 'build_' + args[0]
if hasattr(make, run_method):
return getattr(make, run_method)()
return make.run_generic_build(args[0])

View File

@ -74,13 +74,18 @@ DEFAULTS = {
'language': None,
'suffix': '.rst',
'master': 'index',
'epub': False,
'makefile': True,
'batchfile': True,
}
PROMPT_PREFIX = '> '
if sys.platform == 'win32':
# On Windows, show questions as bold because of color scheme of PowerShell (refs: #5294).
COLOR_QUESTION = 'bold'
else:
COLOR_QUESTION = 'purple'
# function to get input from terminal -- overridden by the test suite
def term_input(prompt):
@ -192,7 +197,7 @@ def do_prompt(text, default=None, validator=nonempty):
prompt = prompt.encode('utf-8')
except UnicodeEncodeError:
prompt = prompt.encode('latin1')
prompt = colorize('purple', prompt, input_mode=True)
prompt = colorize(COLOR_QUESTION, prompt, input_mode=True)
x = term_input(prompt).strip()
if default and not x:
x = default
@ -246,7 +251,6 @@ def ask_user(d):
* language: document language
* suffix: source file suffix
* master: master document name
* epub: use epub (bool)
* extensions: extensions to use (list)
* makefile: make Makefile
* batchfile: make command file
@ -347,12 +351,6 @@ document is a custom template, you can also set this to another filename.'''))
d['master'] = do_prompt(__('Please enter a new file name, or rename the '
'existing file and press Enter'), d['master'])
if 'epub' not in d:
print(__('''
Sphinx can also add configuration for epub output:'''))
d['epub'] = do_prompt(__('Do you want to use the epub builder (y/n)'),
'n', boolean)
if 'extensions' not in d:
print(__('Indicate which of the following Sphinx extensions should be '
'enabled:'))

View File

@ -49,10 +49,6 @@ ConfigValue = NamedTuple('ConfigValue', [('name', str),
('rebuild', Union[bool, unicode])])
#: represents the config value accepts any type of value.
Any = object()
class ENUM(object):
"""represents the config value should be a one of candidates.

View File

@ -17,8 +17,8 @@ from docutils.parsers.rst.directives.misc import Class
from docutils.parsers.rst.directives.misc import Include as BaseInclude
from six.moves import range
from sphinx import addnodes, locale
from sphinx.deprecation import DeprecatedDict, RemovedInSphinx30Warning
from sphinx import addnodes
from sphinx.domains.changeset import VersionChange # NOQA # for compatibility
from sphinx.locale import _
from sphinx.util import url_re, docname_join
from sphinx.util.docutils import SphinxDirective
@ -32,19 +32,6 @@ if False:
from sphinx.application import Sphinx # NOQA
versionlabels = {
'versionadded': _('New in version %s'),
'versionchanged': _('Changed in version %s'),
'deprecated': _('Deprecated since version %s'),
} # type: Dict[unicode, unicode]
locale.versionlabels = DeprecatedDict(
versionlabels,
'sphinx.locale.versionlabels is deprecated. '
'Please use sphinx.directives.other.versionlabels instead.',
RemovedInSphinx30Warning
)
glob_re = re.compile(r'.*[*?\[].*')
@ -218,54 +205,6 @@ class Index(SphinxDirective):
return [indexnode, targetnode]
class VersionChange(SphinxDirective):
"""
Directive to describe a change/addition/deprecation in a specific version.
"""
has_content = True
required_arguments = 1
optional_arguments = 1
final_argument_whitespace = True
option_spec = {} # type: Dict
def run(self):
# type: () -> List[nodes.Node]
node = addnodes.versionmodified()
node.document = self.state.document
set_source_info(self, node)
node['type'] = self.name
node['version'] = self.arguments[0]
text = versionlabels[self.name] % self.arguments[0]
if len(self.arguments) == 2:
inodes, messages = self.state.inline_text(self.arguments[1],
self.lineno + 1)
para = nodes.paragraph(self.arguments[1], '', *inodes, translatable=False)
set_source_info(self, para)
node.append(para)
else:
messages = []
if self.content:
self.state.nested_parse(self.content, self.content_offset, node)
if len(node):
if isinstance(node[0], nodes.paragraph) and node[0].rawsource:
content = nodes.inline(node[0].rawsource, translatable=True)
content.source = node[0].source
content.line = node[0].line
content += node[0].children
node[0].replace_self(nodes.paragraph('', '', content, translatable=False))
node[0].insert(0, nodes.inline('', '%s: ' % text,
classes=['versionmodified']))
else:
para = nodes.paragraph('', '',
nodes.inline('', '%s.' % text,
classes=['versionmodified']),
translatable=False)
node.append(para)
# XXX should record node.source as well
self.env.note_versionchange(node['type'], node['version'], node, node.line)
return [node] + messages
class SeeAlso(BaseAdmonition):
"""
An admonition mentioning things to look at as reference.
@ -475,9 +414,6 @@ def setup(app):
directives.register_directive('moduleauthor', Author)
directives.register_directive('codeauthor', Author)
directives.register_directive('index', Index)
directives.register_directive('deprecated', VersionChange)
directives.register_directive('versionadded', VersionChange)
directives.register_directive('versionchanged', VersionChange)
directives.register_directive('seealso', SeeAlso)
directives.register_directive('tabularcolumns', TabularColumns)
directives.register_directive('centered', Centered)

159
sphinx/domains/changeset.py Normal file
View File

@ -0,0 +1,159 @@
# -*- coding: utf-8 -*-
"""
sphinx.domains.changeset
~~~~~~~~~~~~~~~~~~~~~~~~
The changeset domain.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
from typing import NamedTuple
from docutils import nodes
from six import iteritems
from sphinx import addnodes
from sphinx import locale
from sphinx.deprecation import DeprecatedDict, RemovedInSphinx30Warning
from sphinx.domains import Domain
from sphinx.locale import _
from sphinx.util.docutils import SphinxDirective
from sphinx.util.nodes import set_source_info
if False:
# For type annotation
from typing import Any, Dict, List # NOQA
from sphinx.application import Sphinx # NOQA
from sphinx.environment import BuildEnvironment # NOQA
versionlabels = {
'versionadded': _('New in version %s'),
'versionchanged': _('Changed in version %s'),
'deprecated': _('Deprecated since version %s'),
} # type: Dict[unicode, unicode]
locale.versionlabels = DeprecatedDict(
versionlabels,
'sphinx.locale.versionlabels is deprecated. '
'Please use sphinx.domains.changeset.versionlabels instead.',
RemovedInSphinx30Warning
)
ChangeSet = NamedTuple('ChangeSet', [('type', str),
('docname', str),
('lineno', int),
('module', str),
('descname', str),
('content', str)])
class VersionChange(SphinxDirective):
"""
Directive to describe a change/addition/deprecation in a specific version.
"""
has_content = True
required_arguments = 1
optional_arguments = 1
final_argument_whitespace = True
option_spec = {} # type: Dict
def run(self):
# type: () -> List[nodes.Node]
node = addnodes.versionmodified()
node.document = self.state.document
set_source_info(self, node)
node['type'] = self.name
node['version'] = self.arguments[0]
text = versionlabels[self.name] % self.arguments[0]
if len(self.arguments) == 2:
inodes, messages = self.state.inline_text(self.arguments[1],
self.lineno + 1)
para = nodes.paragraph(self.arguments[1], '', *inodes, translatable=False)
set_source_info(self, para)
node.append(para)
else:
messages = []
if self.content:
self.state.nested_parse(self.content, self.content_offset, node)
if len(node):
if isinstance(node[0], nodes.paragraph) and node[0].rawsource:
content = nodes.inline(node[0].rawsource, translatable=True)
content.source = node[0].source
content.line = node[0].line
content += node[0].children
node[0].replace_self(nodes.paragraph('', '', content, translatable=False))
node[0].insert(0, nodes.inline('', '%s: ' % text,
classes=['versionmodified']))
else:
para = nodes.paragraph('', '',
nodes.inline('', '%s.' % text,
classes=['versionmodified']),
translatable=False)
node.append(para)
self.env.get_domain('changeset').note_changeset(node) # type: ignore
return [node] + messages
class ChangeSetDomain(Domain):
"""Domain for changesets."""
name = 'changeset'
label = 'changeset'
initial_data = {
'changes': {}, # version -> list of ChangeSet
} # type: Dict
def clear_doc(self, docname):
# type: (unicode) -> None
for version, changes in iteritems(self.data['changes']):
for changeset in changes[:]:
if changeset.docname == docname:
changes.remove(changeset)
def merge_domaindata(self, docnames, otherdata):
# type: (List[unicode], Dict) -> None
# XXX duplicates?
for version, otherchanges in iteritems(otherdata['changes']):
changes = self.data['changes'].setdefault(version, [])
for changeset in otherchanges:
if changeset.docname in docnames:
changes.append(changeset)
def process_doc(self, env, docname, document):
# type: (BuildEnvironment, unicode, nodes.Node) -> None
pass # nothing to do here. All changesets are registered on calling directive.
def note_changeset(self, node):
# type: (nodes.Node) -> None
version = node['version']
module = self.env.ref_context.get('py:module')
objname = self.env.temp_data.get('object')
changeset = ChangeSet(node['type'], self.env.docname, node.line, # type: ignore
module, objname, node.astext())
self.data['changes'].setdefault(version, []).append(changeset)
def get_changesets_for(self, version):
# type: (unicode) -> List[ChangeSet]
return self.data['changes'].get(version, [])
def setup(app):
# type: (Sphinx) -> Dict[unicode, Any]
app.add_domain(ChangeSetDomain)
app.add_directive('deprecated', VersionChange)
app.add_directive('versionadded', VersionChange)
app.add_directive('versionchanged', VersionChange)
return {
'version': 'builtin',
'env_version': 1,
'parallel_read_safe': True,
'parallel_write_safe': True,
}

File diff suppressed because it is too large Load Diff

View File

@ -21,10 +21,11 @@ from sphinx.util.nodes import make_refnode
if False:
# For type annotation
from typing import Any, Callable, Dict, Iterable, List, Tuple # NOQA
from typing import Any, Callable, Dict, Iterable, List, Tuple, Union # NOQA
from sphinx.application import Sphinx # NOQA
from sphinx.builders import Builder # NOQA
from sphinx.environment import BuildEnvironment # NOQA
from sphinx.util.typing import RoleFunction # NOQA
logger = logging.getLogger(__name__)
@ -51,6 +52,9 @@ class MathDomain(Domain):
displaymath: ('displaymath', None),
nodes.math_block: ('displaymath', None),
} # type: Dict[nodes.Node, Tuple[unicode, Callable]]
roles = {
'numref': MathReferenceRole(),
}
def clear_doc(self, docname):
# type: (unicode) -> None
@ -66,7 +70,7 @@ class MathDomain(Domain):
def resolve_xref(self, env, fromdocname, builder, typ, target, node, contnode):
# type: (BuildEnvironment, unicode, Builder, unicode, unicode, nodes.Node, nodes.Node) -> nodes.Node # NOQA
assert typ == 'eq'
assert typ in ('eq', 'numref')
docname, number = self.data['objects'].get(target, (None, None))
if docname:
# TODO: perhaps use rather a sphinx-core provided prefix here?

View File

@ -25,7 +25,7 @@ from sphinx import addnodes
from sphinx.deprecation import RemovedInSphinx20Warning, RemovedInSphinx30Warning
from sphinx.environment.adapters.indexentries import IndexEntries
from sphinx.environment.adapters.toctree import TocTree
from sphinx.errors import SphinxError, BuildEnvironmentError, ExtensionError
from sphinx.errors import SphinxError, BuildEnvironmentError, DocumentError, ExtensionError
from sphinx.locale import __
from sphinx.transforms import SphinxTransformer
from sphinx.util import get_matching_docs, FilenameUniqDict
@ -186,9 +186,6 @@ class BuildEnvironment(object):
self.indexentries = {} # type: Dict[unicode, List[Tuple[unicode, unicode, unicode, unicode, unicode]]] # NOQA
# docname -> list of
# (type, unicode, target, aliasname)
self.versionchanges = {} # type: Dict[unicode, List[Tuple[unicode, unicode, int, unicode, unicode, unicode]]] # NOQA
# version -> list of (type, docname,
# lineno, module, descname, content)
# these map absolute path -> (docnames, unique filename)
self.images = FilenameUniqDict() # type: FilenameUniqDict
@ -319,10 +316,7 @@ class BuildEnvironment(object):
if docname in self.all_docs:
self.all_docs.pop(docname, None)
self.reread_always.discard(docname)
for version, changes in self.versionchanges.items():
new = [change for change in changes if change[1] != docname]
changes[:] = new
self.included.discard(docname)
for domain in self.domains.values():
domain.clear_doc(docname)
@ -340,9 +334,8 @@ class BuildEnvironment(object):
if docname in other.reread_always:
self.reread_always.add(docname)
for version, changes in other.versionchanges.items():
self.versionchanges.setdefault(version, []).extend(
change for change in changes if change[1] in docnames)
for docname in other.included:
self.included.add(docname)
for domainname, domain in self.domains.items():
domain.merge_domaindata(docnames, other.domaindata[domainname])
@ -416,37 +409,40 @@ class BuildEnvironment(object):
"""Find all source files in the source dir and put them in
self.found_docs.
"""
matchers = compile_matchers(
config.exclude_patterns[:] +
config.templates_path +
builder.get_asset_paths() +
['**/_sources', '.#*', '**/.#*', '*.lproj/**']
)
self.found_docs = set()
for docname in get_matching_docs(self.srcdir, config.source_suffix, # type: ignore
exclude_matchers=matchers):
if os.access(self.doc2path(docname), os.R_OK):
self.found_docs.add(docname)
else:
logger.warning(__("document not readable. Ignored."), location=docname)
try:
matchers = compile_matchers(
config.exclude_patterns[:] +
config.templates_path +
builder.get_asset_paths() +
['**/_sources', '.#*', '**/.#*', '*.lproj/**']
)
self.found_docs = set()
for docname in get_matching_docs(self.srcdir, config.source_suffix, # type: ignore
exclude_matchers=matchers):
if os.access(self.doc2path(docname), os.R_OK):
self.found_docs.add(docname)
else:
logger.warning(__("document not readable. Ignored."), location=docname)
# Current implementation is applying translated messages in the reading
# phase.Therefore, in order to apply the updated message catalog, it is
# necessary to re-process from the reading phase. Here, if dependency
# is set for the doc source and the mo file, it is processed again from
# the reading phase when mo is updated. In the future, we would like to
# move i18n process into the writing phase, and remove these lines.
if builder.use_message_catalog:
# add catalog mo file dependency
for docname in self.found_docs:
catalog_files = find_catalog_files(
docname,
self.srcdir,
self.config.locale_dirs,
self.config.language,
self.config.gettext_compact)
for filename in catalog_files:
self.dependencies[docname].add(filename)
# Current implementation is applying translated messages in the reading
# phase.Therefore, in order to apply the updated message catalog, it is
# necessary to re-process from the reading phase. Here, if dependency
# is set for the doc source and the mo file, it is processed again from
# the reading phase when mo is updated. In the future, we would like to
# move i18n process into the writing phase, and remove these lines.
if builder.use_message_catalog:
# add catalog mo file dependency
for docname in self.found_docs:
catalog_files = find_catalog_files(
docname,
self.srcdir,
self.config.locale_dirs,
self.config.language,
self.config.gettext_compact)
for filename in catalog_files:
self.dependencies[docname].add(filename)
except EnvironmentError as exc:
raise DocumentError(__('Failed to scan documents in %s: %r') % (self.srcdir, exc))
def get_outdated_files(self, config_changed):
# type: (bool) -> Tuple[Set[unicode], Set[unicode], Set[unicode]]
@ -565,13 +561,6 @@ class BuildEnvironment(object):
"""
self.reread_always.add(self.docname)
def note_versionchange(self, type, version, node, lineno):
# type: (unicode, unicode, nodes.Node, int) -> None
self.versionchanges.setdefault(version, []).append(
(type, self.temp_data['docname'], lineno,
self.ref_context.get('py:module'),
self.temp_data.get('object'), node.astext()))
def note_toctree(self, docname, toctreenode):
# type: (unicode, addnodes.toctree) -> None
"""Note a TOC tree directive in a document and gather information about
@ -851,3 +840,21 @@ class BuildEnvironment(object):
RemovedInSphinx30Warning)
with open(filename, 'wb') as f:
self.dump(self, f)
@property
def versionchanges(self):
# type: () -> Dict[unicode, List[Tuple[unicode, unicode, int, unicode, unicode, unicode]]] # NOQA
warnings.warn('env.versionchanges() is deprecated. '
'Please use ChangeSetDomain instead.',
RemovedInSphinx30Warning)
return self.domaindata['changeset']['changes']
def note_versionchange(self, type, version, node, lineno):
# type: (unicode, unicode, nodes.Node, int) -> None
warnings.warn('env.note_versionchange() is deprecated. '
'Please use ChangeSetDomain.note_changeset() instead.',
RemovedInSphinx30Warning)
node['type'] = type
node['version'] = version
node.line = lineno
self.get_domain('changeset').note_changeset(node) # type: ignore

View File

@ -82,6 +82,11 @@ class ConfigError(SphinxError):
category = 'Configuration error'
class DocumentError(SphinxError):
"""Document error."""
category = 'Document error'
class ThemeError(SphinxError):
"""Theme error."""
category = 'Theme error'

View File

@ -15,6 +15,7 @@ import inspect
import re
import sys
import warnings
from typing import Any
from docutils.statemachine import ViewList
from six import iteritems, itervalues, text_type, class_types, string_types
@ -32,7 +33,7 @@ from sphinx.util import rpartition, force_decode
from sphinx.util.docstrings import prepare_docstring
from sphinx.util.inspect import Signature, isdescriptor, safe_getmembers, \
safe_getattr, object_description, is_builtin_class_method, \
isenumattribute, isclassmethod, isstaticmethod, getdoc
isenumattribute, isclassmethod, isstaticmethod, isfunction, isbuiltin, ispartial, getdoc
if False:
# For type annotation
@ -41,6 +42,7 @@ if False:
from docutils import nodes # NOQA
from docutils.utils import Reporter # NOQA
from sphinx.application import Sphinx # NOQA
from sphinx.config import Config # NOQA
from sphinx.environment import BuildEnvironment # NOQA
from sphinx.ext.autodoc.directive import DocumenterBridge # NOQA
@ -399,7 +401,9 @@ class Documenter(object):
return True
modname = self.get_attr(self.object, '__module__', None)
if modname and modname != self.modname:
if ispartial(self.object) and modname == '_functools': # for pypy
return True
elif modname and modname != self.modname:
return False
return True
@ -473,9 +477,8 @@ class Documenter(object):
def get_doc(self, encoding=None, ignore=1):
# type: (unicode, int) -> List[List[unicode]]
"""Decode and return lines of the docstring(s) for the object."""
docstring = self.get_attr(self.object, '__doc__', None)
if docstring is None and self.env.config.autodoc_inherit_docstrings:
docstring = getdoc(self.object)
docstring = getdoc(self.object, self.get_attr,
self.env.config.autodoc_inherit_docstrings)
# make sure we have Unicode docstrings, then sanitize and split
# into lines
if isinstance(docstring, text_type):
@ -599,9 +602,7 @@ class Documenter(object):
# if isattr is True, the member is documented as an attribute
isattr = False
doc = self.get_attr(member, '__doc__', None)
if doc is None and self.env.config.autodoc_inherit_docstrings:
doc = getdoc(member)
doc = getdoc(member, self.get_attr, self.env.config.autodoc_inherit_docstrings)
# if the member __doc__ is the same as self's __doc__, it's just
# inherited and therefore not the member's doc
@ -679,8 +680,13 @@ class Documenter(object):
# remove members given by exclude-members
if self.options.exclude_members:
members = [(membername, member) for (membername, member) in members
if membername not in self.options.exclude_members]
members = [
(membername, member) for (membername, member) in members
if (
self.options.exclude_members is ALL or
membername not in self.options.exclude_members
)
]
# document non-skipped members
memberdocumenters = [] # type: List[Tuple[Documenter, bool]]
@ -1022,12 +1028,11 @@ class FunctionDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # typ
@classmethod
def can_document_member(cls, member, membername, isattr, parent):
# type: (Any, unicode, bool, Any) -> bool
return inspect.isfunction(member) or inspect.isbuiltin(member)
return isfunction(member) or isbuiltin(member)
def format_args(self):
# type: () -> unicode
if inspect.isbuiltin(self.object) or \
inspect.ismethoddescriptor(self.object):
if isbuiltin(self.object) or inspect.ismethoddescriptor(self.object):
# cannot introspect arguments of a C function or method
return None
try:
@ -1095,7 +1100,7 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
# __init__ written in C?
if initmeth is None or \
is_builtin_class_method(self.object, '__init__') or \
not(inspect.ismethod(initmeth) or inspect.isfunction(initmeth)):
not(inspect.ismethod(initmeth) or isfunction(initmeth)):
return None
try:
return Signature(initmeth, bound_method=True, has_retval=False).format_args()
@ -1265,6 +1270,11 @@ class DataDocumenter(ModuleLevelDocumenter):
# type: (bool) -> None
pass
def get_real_modname(self):
# type: () -> str
return self.get_attr(self.parent or self.object, '__module__', None) \
or self.modname
class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type: ignore
"""
@ -1305,8 +1315,7 @@ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type:
def format_args(self):
# type: () -> unicode
if inspect.isbuiltin(self.object) or \
inspect.ismethoddescriptor(self.object):
if isbuiltin(self.object) or inspect.ismethoddescriptor(self.object):
# can never get arguments of a C function or method
return None
if isstaticmethod(self.object, cls=self.parent, name=self.object_name):
@ -1338,7 +1347,7 @@ class AttributeDocumenter(DocstringStripSignatureMixin, ClassLevelDocumenter):
@staticmethod
def is_function_or_method(obj):
# type: (Any) -> bool
return inspect.isfunction(obj) or inspect.isbuiltin(obj) or inspect.ismethod(obj)
return isfunction(obj) or isbuiltin(obj) or inspect.ismethod(obj)
@classmethod
def can_document_member(cls, member, membername, isattr, parent):
@ -1523,6 +1532,25 @@ def autodoc_attrgetter(app, obj, name, *defargs):
return safe_getattr(obj, name, *defargs)
def merge_autodoc_default_flags(app, config):
# type: (Sphinx, Config) -> None
"""This merges the autodoc_default_flags to autodoc_default_options."""
if not config.autodoc_default_flags:
return
logger.warning(__('autodoc_default_flags is now deprecated. '
'Please use autodoc_default_options instead.'))
for option in config.autodoc_default_flags:
if isinstance(option, string_types):
config.autodoc_default_options[option] = None
else:
logger.warning(
__("Ignoring invalid option in autodoc_default_flags: %r"),
option
)
def setup(app):
# type: (Sphinx) -> Dict[unicode, Any]
app.add_autodocumenter(ModuleDocumenter)
@ -1537,6 +1565,7 @@ def setup(app):
app.add_config_value('autoclass_content', 'class', True)
app.add_config_value('autodoc_member_order', 'alphabetic', True)
app.add_config_value('autodoc_default_flags', [], True)
app.add_config_value('autodoc_default_options', {}, True)
app.add_config_value('autodoc_docstring_signature', True, True)
app.add_config_value('autodoc_mock_imports', [], True)
app.add_config_value('autodoc_warningiserror', True, True)
@ -1545,4 +1574,6 @@ def setup(app):
app.add_event('autodoc-process-signature')
app.add_event('autodoc-skip-member')
app.connect('config-inited', merge_autodoc_default_flags)
return {'version': sphinx.__display_version__, 'parallel_read_safe': True}

View File

@ -31,7 +31,7 @@ logger = logging.getLogger(__name__)
# common option names for autodoc directives
AUTODOC_DEFAULT_OPTIONS = ['members', 'undoc-members', 'inherited-members',
'show-inheritance', 'private-members', 'special-members',
'ignore-module-all']
'ignore-module-all', 'exclude-members']
class DummyOptionSpec(object):
@ -67,8 +67,8 @@ def process_documenter_options(documenter, config, options):
continue
else:
negated = options.pop('no-' + name, True) is None
if name in config.autodoc_default_flags and not negated:
options[name] = None
if name in config.autodoc_default_options and not negated:
options[name] = config.autodoc_default_options[name]
return Options(assemble_option_dict(options.items(), documenter.option_spec))

View File

@ -167,8 +167,21 @@ def import_object(modname, objpath, objtype='', attrgetter=safe_getattr, warning
logger.debug('[autodoc] import %s', modname)
try:
module = import_module(modname, warningiserror=warningiserror)
logger.debug('[autodoc] => %r', module)
module = None
objpath = list(objpath)
while module is None:
try:
module = import_module(modname, warningiserror=warningiserror)
logger.debug('[autodoc] import %s => %r', modname, module)
except ImportError:
logger.debug('[autodoc] import %s => failed', modname)
if '.' in modname:
# retry with parent module
modname, name = modname.rsplit('.', 1)
objpath.insert(0, name)
else:
raise
obj = module
parent = None
object_name = None

View File

@ -130,8 +130,11 @@ def formatargspec(function, args, varargs=None, varkw=None, defaults=None,
else:
return value
introspected_hints = (typing.get_type_hints(function) # type: ignore
if typing and hasattr(function, '__code__') else {})
try:
introspected_hints = (typing.get_type_hints(function) # type: ignore
if typing and hasattr(function, '__code__') else {})
except Exception:
introspected_hints = {}
fd = StringIO()
fd.write('(')

View File

@ -90,6 +90,16 @@ class TestDirective(SphinxDirective):
def run(self):
# type: () -> List[nodes.Node]
if 'skipif' in self.options:
condition = self.options['skipif']
context = {} # type: Dict[str, Any]
if self.config.doctest_global_setup:
exec(self.config.doctest_global_setup, context)
should_skip = eval(condition, context)
if self.config.doctest_global_cleanup:
exec(self.config.doctest_global_cleanup, context)
if should_skip:
return []
# use ordinary docutils nodes for test code: they get special attributes
# so that our builder recognizes them, and the other builders are happy.
code = '\n'.join(self.content)
@ -155,11 +165,11 @@ class TestDirective(SphinxDirective):
class TestsetupDirective(TestDirective):
option_spec = {} # type: Dict
option_spec = {'skipif': directives.unchanged_required} # type: Dict
class TestcleanupDirective(TestDirective):
option_spec = {} # type: Dict
option_spec = {'skipif': directives.unchanged_required} # type: Dict
class DoctestDirective(TestDirective):
@ -167,6 +177,7 @@ class DoctestDirective(TestDirective):
'hide': directives.flag,
'options': directives.unchanged,
'pyversion': directives.unchanged_required,
'skipif': directives.unchanged_required,
}
@ -174,6 +185,7 @@ class TestcodeDirective(TestDirective):
option_spec = {
'hide': directives.flag,
'pyversion': directives.unchanged_required,
'skipif': directives.unchanged_required,
}
@ -182,6 +194,7 @@ class TestoutputDirective(TestDirective):
'hide': directives.flag,
'options': directives.unchanged,
'pyversion': directives.unchanged_required,
'skipif': directives.unchanged_required,
}

View File

@ -27,6 +27,7 @@ from sphinx.errors import SphinxError
from sphinx.locale import _, __
from sphinx.util import logging
from sphinx.util.docutils import SphinxDirective
from sphinx.util.fileutil import copy_asset_file
from sphinx.util.i18n import search_image_for_language
from sphinx.util.osutil import ensuredir, ENOENT, EPIPE, EINVAL
@ -155,7 +156,8 @@ class Graphviz(SphinxDirective):
line=self.lineno)]
node = graphviz()
node['code'] = dotcode
node['options'] = {}
node['options'] = {'docname': self.env.docname}
if 'graphviz_dot' in self.options:
node['options']['graphviz_dot'] = self.options['graphviz_dot']
if 'alt' in self.options:
@ -192,7 +194,9 @@ class GraphvizSimple(SphinxDirective):
node = graphviz()
node['code'] = '%s %s {\n%s\n}\n' % \
(self.name, self.arguments[0], '\n'.join(self.content))
node['options'] = {}
node['options'] = {
'docname': path.splitext(self.state.document.current_source)[0],
}
if 'graphviz_dot' in self.options:
node['options']['graphviz_dot'] = self.options['graphviz_dot']
if 'alt' in self.options:
@ -235,10 +239,14 @@ def render_dot(self, code, options, format, prefix='graphviz'):
dot_args = [graphviz_dot]
dot_args.extend(self.builder.config.graphviz_dot_args)
dot_args.extend(['-T' + format, '-o' + outfn])
docname = options.get('docname', 'index')
cwd = path.dirname(path.join(self.builder.srcdir, docname))
if format == 'png':
dot_args.extend(['-Tcmapx', '-o%s.map' % outfn])
try:
p = Popen(dot_args, stdout=PIPE, stdin=PIPE, stderr=PIPE)
p = Popen(dot_args, stdout=PIPE, stdin=PIPE, stderr=PIPE, cwd=cwd)
except OSError as err:
if err.errno != ENOENT: # No such file or directory
raise
@ -281,19 +289,23 @@ def render_dot_html(self, node, code, options, prefix='graphviz',
logger.warning(__('dot code %r: %s'), code, text_type(exc))
raise nodes.SkipNode
if imgcls:
imgcls += " graphviz"
else:
imgcls = "graphviz"
if fname is None:
self.body.append(self.encode(code))
else:
if alt is None:
alt = node.get('alt', self.encode(code).strip())
imgcss = imgcls and 'class="%s"' % imgcls or ''
if 'align' in node:
self.body.append('<div align="%s" class="align-%s">' %
(node['align'], node['align']))
if format == 'svg':
self.body.append('<div class="graphviz">')
self.body.append('<object data="%s" type="image/svg+xml" %s>\n' %
(fname, imgcss))
self.body.append('<object data="%s" type="image/svg+xml" class="%s">\n' %
(fname, imgcls))
self.body.append('<p class="warning">%s</p>' % alt)
self.body.append('</object></div>\n')
else:
@ -302,15 +314,15 @@ def render_dot_html(self, node, code, options, prefix='graphviz',
if imgmap.clickable:
# has a map
self.body.append('<div class="graphviz">')
self.body.append('<img src="%s" alt="%s" usemap="#%s" %s/>' %
(fname, alt, imgmap.id, imgcss))
self.body.append('<img src="%s" alt="%s" usemap="#%s" class="%s" />' %
(fname, alt, imgmap.id, imgcls))
self.body.append('</div>\n')
self.body.append(imgmap.generate_clickable_map())
else:
# nothing in image map
self.body.append('<div class="graphviz">')
self.body.append('<img src="%s" alt="%s" %s/>' %
(fname, alt, imgcss))
self.body.append('<img src="%s" alt="%s" class="%s" />' %
(fname, alt, imgcls))
self.body.append('</div>\n')
if 'align' in node:
self.body.append('</div>\n')
@ -396,6 +408,14 @@ def man_visit_graphviz(self, node):
raise nodes.SkipNode
def on_build_finished(app, exc):
# type: (Sphinx, Exception) -> None
if exc is None:
src = path.join(sphinx.package_dir, 'templates', 'graphviz', 'graphviz.css')
dst = path.join(app.outdir, '_static')
copy_asset_file(src, dst)
def setup(app):
# type: (Sphinx) -> Dict[unicode, Any]
app.add_node(graphviz,
@ -410,4 +430,6 @@ def setup(app):
app.add_config_value('graphviz_dot', 'dot', 'html')
app.add_config_value('graphviz_dot_args', [], 'html')
app.add_config_value('graphviz_output_format', 'png', 'html')
app.add_css_file('graphviz.css')
app.connect('build-finished', on_build_finished)
return {'version': sphinx.__display_version__, 'parallel_read_safe': True}

View File

@ -22,11 +22,10 @@ from docutils import nodes
from six import text_type
import sphinx
from sphinx.errors import SphinxError, ExtensionError
from sphinx.ext.mathbase import get_node_equation_number
from sphinx.ext.mathbase import setup_math as mathbase_setup, wrap_displaymath
from sphinx.errors import SphinxError
from sphinx.locale import _, __
from sphinx.util import logging
from sphinx.util.math import get_node_equation_number, wrap_displaymath
from sphinx.util.osutil import ensuredir, ENOENT, cd
from sphinx.util.png import read_png_depth, write_png_depth
from sphinx.util.pycompat import sys_encoding
@ -34,10 +33,10 @@ from sphinx.util.pycompat import sys_encoding
if False:
# For type annotation
from typing import Any, Dict, List, Tuple # NOQA
from sphinx.addnodes import displaymath # NOQA
from sphinx.application import Sphinx # NOQA
from sphinx.builders import Builder # NOQA
from sphinx.config import Config # NOQA
from sphinx.ext.mathbase import displaymath # NOQA
logger = logging.getLogger(__name__)
@ -315,12 +314,11 @@ def html_visit_math(self, node):
def html_visit_displaymath(self, node):
# type: (nodes.NodeVisitor, displaymath) -> None
# type: (nodes.NodeVisitor, nodes.math_block) -> None
if node['nowrap']:
latex = node.astext()
else:
latex = wrap_displaymath(node.astext(), None,
self.builder.config.math_number_all)
latex = wrap_displaymath(node.astext(), None, False)
try:
fname, depth = render_math(self, latex)
except MathExtError as exc:
@ -349,10 +347,9 @@ def html_visit_displaymath(self, node):
def setup(app):
# type: (Sphinx) -> Dict[unicode, Any]
try:
mathbase_setup(app, (html_visit_math, None), (html_visit_displaymath, None))
except ExtensionError:
raise ExtensionError('sphinx.ext.imgmath: other math package is already loaded')
app.add_html_math_renderer('imgmath',
(html_visit_math, None),
(html_visit_displaymath, None))
app.add_config_value('imgmath_image_format', 'png', 'html')
app.add_config_value('imgmath_dvipng', 'dvipng', 'html')

View File

@ -410,14 +410,19 @@ def inspect_main(argv):
# type: (unicode) -> None
print(msg, file=sys.stderr)
filename = argv[0]
invdata = fetch_inventory(MockApp(), '', filename) # type: ignore
for key in sorted(invdata or {}):
print(key)
for entry, einfo in sorted(invdata[key].items()):
print('\t%-40s %s%s' % (entry,
einfo[3] != '-' and '%-40s: ' % einfo[3] or '',
einfo[2]))
try:
filename = argv[0]
invdata = fetch_inventory(MockApp(), '', filename) # type: ignore
for key in sorted(invdata or {}):
print(key)
for entry, einfo in sorted(invdata[key].items()):
print('\t%-40s %s%s' % (entry,
einfo[3] != '-' and '%-40s: ' % einfo[3] or '',
einfo[2]))
except ValueError as exc:
print(exc.args[0] % exc.args[1:])
except Exception as exc:
print('Unknown error: %r' % exc)
if __name__ == '__main__':

View File

@ -14,9 +14,8 @@ from docutils import nodes
import sphinx
from sphinx.errors import ExtensionError
from sphinx.ext.mathbase import get_node_equation_number
from sphinx.ext.mathbase import setup_math as mathbase_setup
from sphinx.locale import _
from sphinx.util.math import get_node_equation_number
if False:
# For type annotation
@ -61,7 +60,9 @@ def html_visit_displaymath(self, node):
def builder_inited(app):
# type: (Sphinx) -> None
if not app.config.jsmath_path:
if app.builder.format != 'html' or app.builder.math_renderer_name != 'jsmath': # type: ignore # NOQA
pass
elif not app.config.jsmath_path:
raise ExtensionError('jsmath_path config value must be set for the '
'jsmath extension to work')
if app.builder.format == 'html':
@ -70,10 +71,9 @@ def builder_inited(app):
def setup(app):
# type: (Sphinx) -> Dict[unicode, Any]
try:
mathbase_setup(app, (html_visit_math, None), (html_visit_displaymath, None))
except ExtensionError:
raise ExtensionError('sphinx.ext.jsmath: other math package is already loaded')
app.add_html_math_renderer('jsmath',
(html_visit_math, None),
(html_visit_displaymath, None))
app.add_config_value('jsmath_path', '', False)
app.connect('builder-inited', builder_inited)

View File

@ -13,7 +13,7 @@ import warnings
from docutils import nodes
from sphinx.addnodes import math, math_block as displaymath
from sphinx.addnodes import math, math_block as displaymath # NOQA # to keep compatibility
from sphinx.builders.latex.nodes import math_reference as eqref # NOQA # to keep compatibility
from sphinx.deprecation import RemovedInSphinx30Warning
from sphinx.domains.math import MathDomain # NOQA # to keep compatibility
@ -28,57 +28,20 @@ if False:
def get_node_equation_number(writer, node):
# type: (Writer, nodes.Node) -> unicode
if writer.builder.config.math_numfig and writer.builder.config.numfig:
figtype = 'displaymath'
if writer.builder.name == 'singlehtml':
key = u"%s/%s" % (writer.docnames[-1], figtype)
else:
key = figtype
id = node['ids'][0]
number = writer.builder.fignumbers.get(key, {}).get(id, ())
number = '.'.join(map(str, number))
else:
number = node['number']
return number
warnings.warn('sphinx.ext.mathbase.get_node_equation_number() is moved to '
'sphinx.util.math package.',
RemovedInSphinx30Warning)
from sphinx.util.math import get_node_equation_number
return get_node_equation_number(writer, node)
def wrap_displaymath(math, label, numbering):
def wrap_displaymath(text, label, numbering):
# type: (unicode, unicode, bool) -> unicode
def is_equation(part):
# type: (unicode) -> unicode
return part.strip()
if label is None:
labeldef = ''
else:
labeldef = r'\label{%s}' % label
numbering = True
parts = list(filter(is_equation, math.split('\n\n')))
equations = []
if len(parts) == 0:
return ''
elif len(parts) == 1:
if numbering:
begin = r'\begin{equation}' + labeldef
end = r'\end{equation}'
else:
begin = r'\begin{equation*}' + labeldef
end = r'\end{equation*}'
equations.append('\\begin{split}%s\\end{split}\n' % parts[0])
else:
if numbering:
begin = r'\begin{align}%s\!\begin{aligned}' % labeldef
end = r'\end{aligned}\end{align}'
else:
begin = r'\begin{align*}%s\!\begin{aligned}' % labeldef
end = r'\end{aligned}\end{align*}'
for part in parts:
equations.append('%s\\\\\n' % part.strip())
return '%s\n%s%s' % (begin, ''.join(equations), end)
warnings.warn('sphinx.ext.mathbase.wrap_displaymath() is moved to '
'sphinx.util.math package.',
RemovedInSphinx30Warning)
from sphinx.util.math import wrap_displaymath
return wrap_displaymath(text, label, numbering)
def is_in_section_title(node):
@ -97,8 +60,9 @@ def is_in_section_title(node):
def setup_math(app, htmlinlinevisitors, htmldisplayvisitors):
# type: (Sphinx, Tuple[Callable, Any], Tuple[Callable, Any]) -> None
app.add_node(math, override=True,
html=htmlinlinevisitors)
app.add_node(displaymath, override=True,
html=htmldisplayvisitors)
# type: (Sphinx, Tuple[Callable, Callable], Tuple[Callable, Callable]) -> None
warnings.warn('setup_math() is deprecated. '
'Please use app.add_html_math_renderer() instead.',
RemovedInSphinx30Warning)
app.add_html_math_renderer('unknown', htmlinlinevisitors, htmldisplayvisitors)

View File

@ -11,13 +11,14 @@
:license: BSD, see LICENSE for details.
"""
import json
from docutils import nodes
import sphinx
from sphinx.errors import ExtensionError
from sphinx.ext.mathbase import get_node_equation_number
from sphinx.ext.mathbase import setup_math as mathbase_setup
from sphinx.locale import _
from sphinx.util.math import get_node_equation_number
if False:
# For type annotation
@ -69,7 +70,9 @@ def html_visit_displaymath(self, node):
def builder_inited(app):
# type: (Sphinx) -> None
if not app.config.mathjax_path:
if app.builder.format != 'html' or app.builder.math_renderer_name != 'mathjax': # type: ignore # NOQA
pass
elif not app.config.mathjax_path:
raise ExtensionError('mathjax_path config value must be set for the '
'mathjax extension to work')
if app.builder.format == 'html':
@ -78,13 +81,16 @@ def builder_inited(app):
options.update(app.config.mathjax_options)
app.builder.add_js_file(app.config.mathjax_path, **options) # type: ignore
if app.config.mathjax_config:
body = "MathJax.Hub.Config(%s)" % json.dumps(app.config.mathjax_config)
app.builder.add_js_file(None, type="text/x-mathjax-config", body=body) # type: ignore # NOQA
def setup(app):
# type: (Sphinx) -> Dict[unicode, Any]
try:
mathbase_setup(app, (html_visit_math, None), (html_visit_displaymath, None))
except ExtensionError:
raise ExtensionError('sphinx.ext.mathjax: other math package is already loaded')
app.add_html_math_renderer('mathjax',
(html_visit_math, None),
(html_visit_displaymath, None))
# more information for mathjax secure url is here:
# https://docs.mathjax.org/en/latest/start.html#secure-access-to-the-cdn
@ -94,6 +100,7 @@ def setup(app):
app.add_config_value('mathjax_options', {}, 'html')
app.add_config_value('mathjax_inline', [r'\(', r'\)'], 'html')
app.add_config_value('mathjax_display', [r'\[', r'\]'], 'html')
app.add_config_value('mathjax_config', None, 'html')
app.connect('builder-inited', builder_inited)
return {'version': sphinx.__display_version__, 'parallel_read_safe': True}

View File

@ -104,7 +104,12 @@ def doctree_read(app, doctree):
fullname = signode.get('fullname')
refname = modname
if env.config.viewcode_follow_imported_members:
modname = _get_full_modname(app, modname, fullname)
new_modname = app.emit_firstresult(
'viewcode-follow-imported', modname, fullname,
)
if not new_modname:
new_modname = _get_full_modname(app, modname, fullname)
modname = new_modname
if not modname:
continue
fullname = signode.get('fullname')
@ -262,6 +267,7 @@ def setup(app):
# app.add_config_value('viewcode_include_modules', [], 'env')
# app.add_config_value('viewcode_exclude_modules', [], 'env')
app.add_event('viewcode-find-source')
app.add_event('viewcode-follow-imported')
return {
'version': sphinx.__display_version__,
'env_version': 1,

View File

@ -9,6 +9,8 @@
:license: BSD, see LICENSE for details.
"""
import warnings
from pygments import highlight
from pygments.filters import ErrorToken
from pygments.formatters import HtmlFormatter, LatexFormatter
@ -20,6 +22,7 @@ from pygments.styles import get_style_by_name
from pygments.util import ClassNotFound
from six import text_type
from sphinx.deprecation import RemovedInSphinx30Warning
from sphinx.ext import doctest
from sphinx.locale import __
from sphinx.pygments_styles import SphinxStyle, NoneStyle
@ -65,7 +68,7 @@ class PygmentsBridge(object):
html_formatter = HtmlFormatter
latex_formatter = LatexFormatter
def __init__(self, dest='html', stylename='sphinx', trim_doctest_flags=False):
def __init__(self, dest='html', stylename='sphinx', trim_doctest_flags=None):
# type: (unicode, unicode, bool) -> None
self.dest = dest
if stylename is None or stylename == 'sphinx':
@ -78,7 +81,6 @@ class PygmentsBridge(object):
stylename)
else:
style = get_style_by_name(stylename)
self.trim_doctest_flags = trim_doctest_flags
self.formatter_args = {'style': style} # type: Dict[unicode, Any]
if dest == 'html':
self.formatter = self.html_formatter
@ -86,6 +88,11 @@ class PygmentsBridge(object):
self.formatter = self.latex_formatter
self.formatter_args['commandprefix'] = 'PYG'
self.trim_doctest_flags = trim_doctest_flags
if trim_doctest_flags is not None:
warnings.warn('trim_doctest_flags option for PygmentsBridge is now deprecated.',
RemovedInSphinx30Warning)
def get_formatter(self, **kwargs):
# type: (Any) -> Formatter
kwargs.update(self.formatter_args) # type: ignore
@ -93,6 +100,8 @@ class PygmentsBridge(object):
def unhighlighted(self, source):
# type: (unicode) -> unicode
warnings.warn('PygmentsBridge.unhighlighted() is now deprecated.',
RemovedInSphinx30Warning)
if self.dest == 'html':
return '<pre>' + htmlescape(source) + '</pre>\n'
else:
@ -161,8 +170,6 @@ class PygmentsBridge(object):
if self.dest == 'html':
return hlsource
else:
if not isinstance(hlsource, text_type): # Py2 / Pygments < 1.6
hlsource = hlsource.decode()
return hlsource.translate(tex_hl_escape_map_new)
def get_stylesheet(self):

File diff suppressed because it is too large Load Diff

View File

@ -14,152 +14,26 @@
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
from __future__ import print_function
import os
import subprocess
import sys
from os import path
import warnings
import sphinx
from sphinx.cmd.build import build_main
from sphinx.util.console import color_terminal, nocolor, bold, blue # type: ignore
from sphinx.util.osutil import cd, rmtree
if False:
# For type annotation
from typing import List # NOQA
from sphinx.cmd import make_mode
from sphinx.deprecation import RemovedInSphinx30Warning
BUILDERS = [
("", "html", "to make standalone HTML files"),
("", "dirhtml", "to make HTML files named index.html in directories"),
("", "singlehtml", "to make a single large HTML file"),
("", "pickle", "to make pickle files"),
("", "json", "to make JSON files"),
("", "htmlhelp", "to make HTML files and an HTML help project"),
("", "qthelp", "to make HTML files and a qthelp project"),
("", "devhelp", "to make HTML files and a Devhelp project"),
("", "epub", "to make an epub"),
("", "latex", "to make LaTeX files, you can set PAPER=a4 or PAPER=letter"),
("posix", "latexpdf", "to make LaTeX and PDF files (default pdflatex)"),
("posix", "latexpdfja", "to make LaTeX files and run them through platex/dvipdfmx"),
("", "text", "to make text files"),
("", "man", "to make manual pages"),
("", "texinfo", "to make Texinfo files"),
("posix", "info", "to make Texinfo files and run them through makeinfo"),
("", "gettext", "to make PO message catalogs"),
("", "changes", "to make an overview of all changed/added/deprecated items"),
("", "xml", "to make Docutils-native XML files"),
("", "pseudoxml", "to make pseudoxml-XML files for display purposes"),
("", "linkcheck", "to check all external links for integrity"),
("", "doctest", "to run all doctests embedded in the documentation "
"(if enabled)"),
("", "coverage", "to run coverage check of the documentation (if enabled)"),
]
BUILDERS = make_mode.BUILDERS
class Make(object):
def __init__(self, srcdir, builddir, opts):
# type: (unicode, unicode, List[unicode]) -> None
self.srcdir = srcdir
self.builddir = builddir
self.opts = opts
self.makecmd = os.environ.get('MAKE', 'make') # refer $MAKE to determine make command
def builddir_join(self, *comps):
# type: (unicode) -> unicode
return path.join(self.builddir, *comps)
def build_clean(self):
# type: () -> int
if not path.exists(self.builddir):
return 0
elif not path.isdir(self.builddir):
print("Error: %r is not a directory!" % self.builddir)
return 1
print("Removing everything under %r..." % self.builddir)
for item in os.listdir(self.builddir):
rmtree(self.builddir_join(item))
return 0
def build_help(self):
# type: () -> None
if not color_terminal():
nocolor()
print(bold("Sphinx v%s" % sphinx.__display_version__))
print("Please use `make %s' where %s is one of" % ((blue('target'),) * 2)) # type: ignore # NOQA
for osname, bname, description in BUILDERS:
if not osname or os.name == osname:
print(' %s %s' % (blue(bname.ljust(10)), description))
def build_latexpdf(self):
# type: () -> int
if self.run_generic_build('latex') > 0:
return 1
try:
with cd(self.builddir_join('latex')):
return subprocess.call([self.makecmd, 'all-pdf'])
except OSError:
print('Error: Failed to run: %s' % self.makecmd)
return 1
def build_latexpdfja(self):
# type: () -> int
if self.run_generic_build('latex') > 0:
return 1
try:
with cd(self.builddir_join('latex')):
return subprocess.call([self.makecmd, 'all-pdf-ja'])
except OSError:
print('Error: Failed to run: %s' % self.makecmd)
return 1
def build_info(self):
# type: () -> int
if self.run_generic_build('texinfo') > 0:
return 1
try:
with cd(self.builddir_join('texinfo')):
return subprocess.call([self.makecmd, 'info'])
except OSError:
print('Error: Failed to run: %s' % self.makecmd)
return 1
def build_gettext(self):
# type: () -> int
dtdir = self.builddir_join('gettext', '.doctrees')
if self.run_generic_build('gettext', doctreedir=dtdir) > 0:
return 1
return 0
def run_generic_build(self, builder, doctreedir=None):
# type: (unicode, unicode) -> int
# compatibility with old Makefile
papersize = os.getenv('PAPER', '')
opts = self.opts
if papersize in ('a4', 'letter'):
opts.extend(['-D', 'latex_elements.papersize=' + papersize])
if doctreedir is None:
doctreedir = self.builddir_join('doctrees')
args = ['-b', builder,
'-d', doctreedir,
self.srcdir,
self.builddir_join(builder)]
return build_main(args + opts)
class Make(make_mode.Make):
def __init__(self, *args):
warnings.warn('sphinx.make_mode.Make is deprecated. '
'Please use sphinx.cmd.make_mode.Make instead.',
RemovedInSphinx30Warning)
super(Make, self).__init__(*args)
def run_make_mode(args):
# type: (List[unicode]) -> int
if len(args) < 3:
print('Error: at least 3 arguments (builder, source '
'dir, build dir) are required.', file=sys.stderr)
return 1
make = Make(args[1], args[2], args[3:])
run_method = 'build_' + args[0]
if hasattr(make, run_method):
return getattr(make, run_method)()
return make.run_generic_build(args[0])
warnings.warn('sphinx.make_mode.run_make_mode() is deprecated. '
'Please use sphinx.cmd.make_mode.run_make_mode() instead.',
RemovedInSphinx30Warning)
return make_mode.run_make_mode(args)

View File

@ -39,6 +39,7 @@ if False:
from docutils.transforms import Transform # NOQA
from sphinx.application import Sphinx # NOQA
from sphinx.builders import Builder # NOQA
from sphinx.config import Config # NOQA
from sphinx.domains import Domain, Index # NOQA
from sphinx.environment import BuildEnvironment # NOQA
from sphinx.ext.autodoc import Documenter # NOQA
@ -91,6 +92,11 @@ class SphinxComponentRegistry(object):
#: a dict of node class -> tuple of figtype and title_getter function
self.enumerable_nodes = {} # type: Dict[nodes.Node, Tuple[unicode, TitleGetter]]
#: HTML inline and block math renderers
#: a dict of name -> tuple of visit function and depart function
self.html_inline_math_renderers = {} # type: Dict[unicode, Tuple[Callable, Callable]] # NOQA
self.html_block_math_renderers = {} # type: Dict[unicode, Tuple[Callable, Callable]] # NOQA
#: js_files; list of JS paths or URLs
self.js_files = [] # type: List[Tuple[unicode, Dict[unicode, unicode]]]
@ -270,7 +276,7 @@ class SphinxComponentRegistry(object):
# type: (unicode, unicode, bool) -> None
logger.debug('[app] adding source_suffix: %r, %r', suffix, filetype)
if suffix in self.source_suffix and not override:
raise ExtensionError(__('source_parser for %r is already registered') % suffix)
raise ExtensionError(__('source_suffix %r is already registered') % suffix)
else:
self.source_suffix[suffix] = filetype
@ -290,7 +296,7 @@ class SphinxComponentRegistry(object):
parser = args[1]
if suffix:
self.add_source_suffix(suffix, suffix)
self.add_source_suffix(suffix, suffix, override=True)
if len(parser.supported) == 0:
warnings.warn('Old source_parser has been detected. Please fill Parser.supported '
@ -438,6 +444,16 @@ class SphinxComponentRegistry(object):
raise ExtensionError(__('enumerable_node %r already registered') % node)
self.enumerable_nodes[node] = (figtype, title_getter)
def add_html_math_renderer(self, name, inline_renderers, block_renderers):
# type: (unicode, Tuple[Callable, Callable], Tuple[Callable, Callable]) -> None
logger.debug('[app] adding html_math_renderer: %s, %r, %r',
name, inline_renderers, block_renderers)
if name in self.html_inline_math_renderers:
raise ExtensionError(__('math renderer %s is already registred') % name)
self.html_inline_math_renderers[name] = inline_renderers
self.html_block_math_renderers[name] = block_renderers
def load_extension(self, app, extname):
# type: (Sphinx, unicode) -> None
"""Load a Sphinx extension."""
@ -493,8 +509,8 @@ class SphinxComponentRegistry(object):
return envversion
def merge_source_suffix(app):
# type: (Sphinx) -> None
def merge_source_suffix(app, config):
# type: (Sphinx, Config) -> None
"""Merge source_suffix which specified by user and added by extensions."""
for suffix, filetype in iteritems(app.registry.source_suffix):
if suffix not in app.config.source_suffix:
@ -510,7 +526,7 @@ def merge_source_suffix(app):
def setup(app):
# type: (Sphinx) -> Dict[unicode, Any]
app.connect('builder-inited', merge_source_suffix)
app.connect('config-inited', merge_source_suffix)
return {
'version': 'builtin',

View File

@ -331,13 +331,13 @@ class IndexBuilder(object):
for domainname, domain in sorted(iteritems(self.env.domains)):
for fullname, dispname, type, docname, anchor, prio in \
sorted(domain.get_objects()):
# XXX use dispname?
if docname not in fn2index:
continue
if prio < 0:
continue
fullname = htmlescape(fullname)
prefix, name = rpartition(fullname, '.')
dispname = htmlescape(dispname)
prefix, name = rpartition(dispname, '.')
pdict = rv.setdefault(prefix, {})
try:
typeindex = otypes[domainname, type]

View File

@ -21,14 +21,14 @@ from distutils.errors import DistutilsOptionError, DistutilsExecError
from six import StringIO, string_types
from sphinx.application import Sphinx
from sphinx.cmdline import handle_exception
from sphinx.cmd.build import handle_exception
from sphinx.util.console import nocolor, color_terminal
from sphinx.util.docutils import docutils_namespace, patch_docutils
from sphinx.util.osutil import abspath
if False:
# For type annotation
from typing import Any, List, Tuple # NOQA
from typing import Any, Dict, List, Tuple # NOQA
class BuildDoc(Command):
@ -87,9 +87,10 @@ class BuildDoc(Command):
('link-index', 'i', 'Link index.html to the master doc'),
('copyright', None, 'The copyright string'),
('pdb', None, 'Start pdb on exception'),
('nitpicky', 'n', 'nit-picky mode, warn about all missing references'),
]
boolean_options = ['fresh-env', 'all-files', 'warning-is-error',
'link-index']
'link-index', 'nitpicky']
def initialize_options(self):
# type: () -> None
@ -107,6 +108,7 @@ class BuildDoc(Command):
self.copyright = ''
self.verbosity = 0
self.traceback = False
self.nitpicky = False
def _guess_source_dir(self):
# type: () -> unicode
@ -163,7 +165,7 @@ class BuildDoc(Command):
status_stream = StringIO()
else:
status_stream = sys.stdout # type: ignore
confoverrides = {}
confoverrides = {} # type: Dict[unicode, Any]
if self.project:
confoverrides['project'] = self.project
if self.version:
@ -174,6 +176,8 @@ class BuildDoc(Command):
confoverrides['today'] = self.today
if self.copyright:
confoverrides['copyright'] = self.copyright
if self.nitpicky:
confoverrides['nitpicky'] = self.nitpicky
for builder, builder_target_dir in self.builder_target_dirs:
app = None

View File

@ -0,0 +1,19 @@
/*
* graphviz.css
* ~~~~~~~~~~~~
*
* Sphinx stylesheet -- graphviz extension.
*
* :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
img.graphviz {
border: 0;
max-width: 100%;
}
object.graphviz {
max-width: 100%;
}

View File

@ -49,6 +49,10 @@
\newcommand{\sphinxlogo}{<%= logo %>}
\renewcommand{\releasename}{<%= releasename %>}
<%= makeindex %>
\begin{document}
<%= shorthandoff %>
<%= maketitle %>
<%= tableofcontents %>
<%= body %>
<%= atendofbody %>
<%= indices %>

View File

@ -9,8 +9,8 @@ SOURCEDIR = {{ rsrcdir }}
BUILDDIR = {{ rbuilddir }}
# Internal variables.
PAPEROPT_a4 = -D latex_elements.papersize=a4
PAPEROPT_letter = -D latex_elements.papersize=letter
PAPEROPT_a4 = -D latex_elements.papersize=a4paper
PAPEROPT_letter = -D latex_elements.papersize=letterpaper
# $(O) is meant as a shortcut for $(SPHINXOPTS)
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) $(O) $(SOURCEDIR)
# the i18n builder cannot share the environment and doctrees with the others

View File

@ -165,16 +165,12 @@ texinfo_documents = [
author, '{{ project_fn }}', 'One line description of project.',
'Miscellaneous'),
]
{%- if epub %}
# -- Options for Epub output -------------------------------------------------
# Bibliographic Dublin Core info.
epub_title = project
epub_author = author
epub_publisher = author
epub_copyright = copyright
# The unique identifier of the text. This can be a ISBN number
# or the project homepage.
@ -187,7 +183,6 @@ epub_copyright = copyright
# A list of files that should not be packed into the epub file.
epub_exclude_files = ['search.html']
{%- endif %}
{%- if extensions %}

View File

@ -12,8 +12,8 @@ set SOURCEDIR={{ rsrcdir }}
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% %SOURCEDIR%
set I18NSPHINXOPTS=%SPHINXOPTS% %SOURCEDIR%
if NOT "%PAPER%" == "" (
set ALLSPHINXOPTS=-D latex_elements.papersize=%PAPER% %ALLSPHINXOPTS%
set I18NSPHINXOPTS=-D latex_elements.papersize=%PAPER% %I18NSPHINXOPTS%
set ALLSPHINXOPTS=-D latex_elements.papersize=%PAPER%paper %ALLSPHINXOPTS%
set I18NSPHINXOPTS=-D latex_elements.papersize=%PAPER%paper %I18NSPHINXOPTS%
)
if "%1" == "" goto help

View File

@ -1,6 +1,6 @@
;; -*- coding: utf-8; mode: Lisp; -*-
;; style file for xindy
;; filename: cyrLICRutf8.xdy
;; filename: LICRcyr2utf8.xdy
;; description: style file for xindy which maps back LaTeX Internal
;; Character Representation of Cyrillic to utf-8
;; usage: for use with pdflatex produced .idx files.

View File

@ -0,0 +1,236 @@
;; style file for xindy
;; filename: LICRlatin2utf8.xdy
;; description: style file for xindy which maps back LaTeX Internal
;; Character Representation of letters (as arising in .idx index
;; file) to UTF-8 encoding for correct sorting by xindy.
;; usage: for use with the pdflatex engine,
;; *not* for use with xelatex or lualatex.
;;
;; This is based upon xindy's distributed file tex/inputenc/utf8.xdy.
;; The modifications include:
;;
;; - Updates for compatibility with current LaTeX macro encoding.
;;
;; - Systematic usage of the \IeC {...} mark-up, because mark-up in
;; tex/inputenc/utf8.xdy was using it on seemingly random basis, and
;; Sphinx coercing of xindy usability for both Latin and Cyrillic scripts
;; with pdflatex requires its systematic presence here.
;;
;; - Support for some extra letters: Ÿ, Ŋ, ŋ, Œ, œ, IJ, ij, ȷ and ẞ.
;;
;; Indeed Sphinx needs to support for pdflatex engine all Unicode letters
;; available in TeX T1 font encoding. The above letters are found in
;; that encoding but not in the Latin1, 2, 3 charsets which are those
;; covered by original tex/inputenc/utf8.xdy.
;;
;; - There is a problem that ȷ is not supported out-of-the box by LaTeX
;; with inputenc, one must add explicitely
;; \DeclareUnicodeCharacter{0237}{\j}
;; to preamble of LaTeX document. However this character is not supported
;; by the TeX "times" font used by default by Sphinx for pdflatex engine.
;;
;; - ẞ needs \DeclareUnicodeCharacter{1E9E}{\SS} (but ß needs no extra set-up).
;;
;; - U+02DB (˛) and U+02D9 (˙) are also not supported by inputenc
;; out of the box and require
;; \DeclareUnicodeCharacter{02DB}{\k{}}
;; \DeclareUnicodeCharacter{02D9}{\.{}}
;; to be added to preamble.
;;
;; - U+0127 ħ and U+0126 Ħ are absent from TeX T1+TS1 font encodings.
;;
;; - Characters Ŋ and ŋ are not supported by TeX font "times" used by
;; default by Sphinx for pdflatex engine but they are supported by
;; some TeX fonts, in particular by the default LaTeX font for T1
;; encoding.
;;
;; - " and ~ must be escaped as ~" and resp. ~~ in xindy merge rules.
;;
;; Contributed by the Sphinx team, July 2018.
;;
;; See sphinx.xdy for superior figures, as they are escaped by LaTeX writer.
(merge-rule "\IeC {\textonesuperior }" "¹" :string)
(merge-rule "\IeC {\texttwosuperior }" "²" :string)
(merge-rule "\IeC {\textthreesuperior }" "³" :string)
(merge-rule "\IeC {\'a}" "á" :string)
(merge-rule "\IeC {\'A}" "Á" :string)
(merge-rule "\IeC {\`a}" "à" :string)
(merge-rule "\IeC {\`A}" "À" :string)
(merge-rule "\IeC {\^a}" "â" :string)
(merge-rule "\IeC {\^A}" "Â" :string)
(merge-rule "\IeC {\~"a}" "ä" :string)
(merge-rule "\IeC {\~"A}" "Ä" :string)
(merge-rule "\IeC {\~~a}" "ã" :string)
(merge-rule "\IeC {\~~A}" "Ã" :string)
(merge-rule "\IeC {\c c}" "ç" :string)
(merge-rule "\IeC {\c C}" "Ç" :string)
(merge-rule "\IeC {\'c}" "ć" :string)
(merge-rule "\IeC {\'C}" "Ć" :string)
(merge-rule "\IeC {\^c}" "ĉ" :string)
(merge-rule "\IeC {\^C}" "Ĉ" :string)
(merge-rule "\IeC {\.c}" "ċ" :string)
(merge-rule "\IeC {\.C}" "Ċ" :string)
(merge-rule "\IeC {\c s}" "ş" :string)
(merge-rule "\IeC {\c S}" "Ş" :string)
(merge-rule "\IeC {\c t}" "ţ" :string)
(merge-rule "\IeC {\c T}" "Ţ" :string)
(merge-rule "\IeC {\-}" "­" :string); soft hyphen
(merge-rule "\IeC {\textdiv }" "÷" :string)
(merge-rule "\IeC {\'e}" "é" :string)
(merge-rule "\IeC {\'E}" "É" :string)
(merge-rule "\IeC {\`e}" "è" :string)
(merge-rule "\IeC {\`E}" "È" :string)
(merge-rule "\IeC {\^e}" "ê" :string)
(merge-rule "\IeC {\^E}" "Ê" :string)
(merge-rule "\IeC {\~"e}" "ë" :string)
(merge-rule "\IeC {\~"E}" "Ë" :string)
(merge-rule "\IeC {\^g}" "ĝ" :string)
(merge-rule "\IeC {\^G}" "Ĝ" :string)
(merge-rule "\IeC {\.g}" "ġ" :string)
(merge-rule "\IeC {\.G}" "Ġ" :string)
(merge-rule "\IeC {\^h}" "ĥ" :string)
(merge-rule "\IeC {\^H}" "Ĥ" :string)
(merge-rule "\IeC {\H o}" "ő" :string)
(merge-rule "\IeC {\H O}" "Ő" :string)
(merge-rule "\IeC {\textacutedbl }" "˝" :string)
(merge-rule "\IeC {\H u}" "ű" :string)
(merge-rule "\IeC {\H U}" "Ű" :string)
(merge-rule "\IeC {\ae }" "æ" :string)
(merge-rule "\IeC {\AE }" "Æ" :string)
(merge-rule "\IeC {\textcopyright }" "©" :string)
(merge-rule "\IeC {\c \ }" "¸" :string)
(merge-rule "\IeC {\dh }" "ð" :string)
(merge-rule "\IeC {\DH }" "Ð" :string)
(merge-rule "\IeC {\dj }" "đ" :string)
(merge-rule "\IeC {\DJ }" "Đ" :string)
(merge-rule "\IeC {\guillemotleft }" "«" :string)
(merge-rule "\IeC {\guillemotright }" "»" :string)
(merge-rule "\IeC {\'\i }" "í" :string)
(merge-rule "\IeC {\`\i }" "ì" :string)
(merge-rule "\IeC {\^\i }" "î" :string)
(merge-rule "\IeC {\~"\i }" "ï" :string)
(merge-rule "\IeC {\i }" "ı" :string)
(merge-rule "\IeC {\^\j }" "ĵ" :string)
(merge-rule "\IeC {\k {}}" "˛" :string)
(merge-rule "\IeC {\l }" "ł" :string)
(merge-rule "\IeC {\L }" "Ł" :string)
(merge-rule "\IeC {\nobreakspace }" " " :string)
(merge-rule "\IeC {\o }" "ø" :string)
(merge-rule "\IeC {\O }" "Ø" :string)
(merge-rule "\IeC {\textsterling }" "£" :string)
(merge-rule "\IeC {\textparagraph }" "¶" :string)
(merge-rule "\IeC {\ss }" "ß" :string)
(merge-rule "\IeC {\textsection }" "§" :string)
(merge-rule "\IeC {\textbrokenbar }" "¦" :string)
(merge-rule "\IeC {\textcent }" "¢" :string)
(merge-rule "\IeC {\textcurrency }" "¤" :string)
(merge-rule "\IeC {\textdegree }" "°" :string)
(merge-rule "\IeC {\textexclamdown }" "¡" :string)
(merge-rule "\IeC {\texthbar }" "ħ" :string)
(merge-rule "\IeC {\textHbar }" "Ħ" :string)
(merge-rule "\IeC {\textonehalf }" "½" :string)
(merge-rule "\IeC {\textonequarter }" "¼" :string)
(merge-rule "\IeC {\textordfeminine }" "ª" :string)
(merge-rule "\IeC {\textordmasculine }" "º" :string)
(merge-rule "\IeC {\textperiodcentered }" "·" :string)
(merge-rule "\IeC {\textquestiondown }" "¿" :string)
(merge-rule "\IeC {\textregistered }" "®" :string)
(merge-rule "\IeC {\textthreequarters }" "¾" :string)
(merge-rule "\IeC {\textyen }" "¥" :string)
(merge-rule "\IeC {\th }" "þ" :string)
(merge-rule "\IeC {\TH }" "Þ" :string)
(merge-rule "\IeC {\'I}" "Í" :string)
(merge-rule "\IeC {\`I}" "Ì" :string)
(merge-rule "\IeC {\^I}" "Î" :string)
(merge-rule "\IeC {\~"I}" "Ï" :string)
(merge-rule "\IeC {\.I}" "İ" :string)
(merge-rule "\IeC {\^J}" "Ĵ" :string)
(merge-rule "\IeC {\k a}" "ą" :string)
(merge-rule "\IeC {\k A}" "Ą" :string)
(merge-rule "\IeC {\k e}" "ę" :string)
(merge-rule "\IeC {\k E}" "Ę" :string)
(merge-rule "\IeC {\'l}" "ĺ" :string)
(merge-rule "\IeC {\'L}" "Ĺ" :string)
(merge-rule "\IeC {\textlnot }" "¬" :string)
(merge-rule "\IeC {\textmu }" "µ" :string)
(merge-rule "\IeC {\'n}" "ń" :string)
(merge-rule "\IeC {\'N}" "Ń" :string)
(merge-rule "\IeC {\~~n}" "ñ" :string)
(merge-rule "\IeC {\~~N}" "Ñ" :string)
(merge-rule "\IeC {\'o}" "ó" :string)
(merge-rule "\IeC {\'O}" "Ó" :string)
(merge-rule "\IeC {\`o}" "ò" :string)
(merge-rule "\IeC {\`O}" "Ò" :string)
(merge-rule "\IeC {\^o}" "ô" :string)
(merge-rule "\IeC {\^O}" "Ô" :string)
(merge-rule "\IeC {\~"o}" "ö" :string)
(merge-rule "\IeC {\~"O}" "Ö" :string)
(merge-rule "\IeC {\~~o}" "õ" :string)
(merge-rule "\IeC {\~~O}" "Õ" :string)
(merge-rule "\IeC {\textpm }" "±" :string)
(merge-rule "\IeC {\r a}" "å" :string)
(merge-rule "\IeC {\r A}" "Å" :string)
(merge-rule "\IeC {\'r}" "ŕ" :string)
(merge-rule "\IeC {\'R}" "Ŕ" :string)
(merge-rule "\IeC {\r u}" "ů" :string)
(merge-rule "\IeC {\r U}" "Ů" :string)
(merge-rule "\IeC {\'s}" "ś" :string)
(merge-rule "\IeC {\'S}" "Ś" :string)
(merge-rule "\IeC {\^s}" "ŝ" :string)
(merge-rule "\IeC {\^S}" "Ŝ" :string)
(merge-rule "\IeC {\textasciidieresis }" "¨" :string)
(merge-rule "\IeC {\textasciimacron }" "¯" :string)
(merge-rule "\IeC {\.{}}" "˙" :string)
(merge-rule "\IeC {\textasciiacute }" "´" :string)
(merge-rule "\IeC {\texttimes }" "×" :string)
(merge-rule "\IeC {\u a}" "ă" :string)
(merge-rule "\IeC {\u A}" "Ă" :string)
(merge-rule "\IeC {\u g}" "ğ" :string)
(merge-rule "\IeC {\u G}" "Ğ" :string)
(merge-rule "\IeC {\textasciibreve }" "˘" :string)
(merge-rule "\IeC {\'u}" "ú" :string)
(merge-rule "\IeC {\'U}" "Ú" :string)
(merge-rule "\IeC {\`u}" "ù" :string)
(merge-rule "\IeC {\`U}" "Ù" :string)
(merge-rule "\IeC {\^u}" "û" :string)
(merge-rule "\IeC {\^U}" "Û" :string)
(merge-rule "\IeC {\~"u}" "ü" :string)
(merge-rule "\IeC {\~"U}" "Ü" :string)
(merge-rule "\IeC {\u u}" "ŭ" :string)
(merge-rule "\IeC {\u U}" "Ŭ" :string)
(merge-rule "\IeC {\v c}" "č" :string)
(merge-rule "\IeC {\v C}" "Č" :string)
(merge-rule "\IeC {\v d}" "ď" :string)
(merge-rule "\IeC {\v D}" "Ď" :string)
(merge-rule "\IeC {\v e}" "ě" :string)
(merge-rule "\IeC {\v E}" "Ě" :string)
(merge-rule "\IeC {\v l}" "ľ" :string)
(merge-rule "\IeC {\v L}" "Ľ" :string)
(merge-rule "\IeC {\v n}" "ň" :string)
(merge-rule "\IeC {\v N}" "Ň" :string)
(merge-rule "\IeC {\v r}" "ř" :string)
(merge-rule "\IeC {\v R}" "Ř" :string)
(merge-rule "\IeC {\v s}" "š" :string)
(merge-rule "\IeC {\v S}" "Š" :string)
(merge-rule "\IeC {\textasciicaron }" "ˇ" :string)
(merge-rule "\IeC {\v t}" "ť" :string)
(merge-rule "\IeC {\v T}" "Ť" :string)
(merge-rule "\IeC {\v z}" "ž" :string)
(merge-rule "\IeC {\v Z}" "Ž" :string)
(merge-rule "\IeC {\'y}" "ý" :string)
(merge-rule "\IeC {\'Y}" "Ý" :string)
(merge-rule "\IeC {\~"y}" "ÿ" :string)
(merge-rule "\IeC {\'z}" "ź" :string)
(merge-rule "\IeC {\'Z}" "Ź" :string)
(merge-rule "\IeC {\.z}" "ż" :string)
(merge-rule "\IeC {\.Z}" "Ż" :string)
;; letters not in Latin1, 2, 3 but available in TeX T1 font encoding
(merge-rule "\IeC {\~"Y}" "Ÿ" :string)
(merge-rule "\IeC {\NG }" "Ŋ" :string)
(merge-rule "\IeC {\ng }" "ŋ" :string)
(merge-rule "\IeC {\OE }" "Œ" :string)
(merge-rule "\IeC {\oe }" "œ" :string)
(merge-rule "\IeC {\IJ }" "IJ" :string)
(merge-rule "\IeC {\ij }" "ij" :string)
(merge-rule "\IeC {\j }" "ȷ" :string)
(merge-rule "\IeC {\SS }" "ẞ" :string)

View File

@ -0,0 +1,607 @@
;; style file for xindy
;; filename: LatinRules.xdy
;;
;; It is based upon xindy's files lang/general/utf8.xdy and
;; lang/general/utf8-lang.xdy which implement
;; "a general sorting order for Western European languages"
;;
;; The aim for Sphinx is to be able to index in a Cyrillic document
;; also terms using the Latin alphabets, inclusive of letters
;; with diacritics. To this effect the xindy rules from lang/general
;; got manually re-coded to avoid collisions with the encoding
;; done by xindy for sorting words in Cyrillic languages, which was
;; observed not to use bytes with octal encoding 0o266 or higher.
;;
;; So here we use only 0o266 or higher bytes.
;; (Ŋ, ŋ, IJ, and ij are absent from
;; lang/general/utf8.xdy and not included here)
;; Contributed by the Sphinx team, 2018.
(define-letter-group "A" :prefixes ("¶"))
(define-letter-group "B" :after "A" :prefixes ("·"))
(define-letter-group "C" :after "B" :prefixes ("¸"))
(define-letter-group "D" :after "C" :prefixes ("¹"))
(define-letter-group "E" :after "D" :prefixes ("º"))
(define-letter-group "F" :after "E" :prefixes ("»"))
(define-letter-group "G" :after "F" :prefixes ("¼"))
(define-letter-group "H" :after "G" :prefixes ("½"))
(define-letter-group "I" :after "H" :prefixes ("¾"))
(define-letter-group "J" :after "I" :prefixes ("¿"))
(define-letter-group "K" :after "J" :prefixes ("À"))
(define-letter-group "L" :after "K" :prefixes ("Á"))
(define-letter-group "M" :after "L" :prefixes ("Â"))
(define-letter-group "N" :after "M" :prefixes ("Ã"))
(define-letter-group "O" :after "N" :prefixes ("Ä"))
(define-letter-group "P" :after "O" :prefixes ("È"))
(define-letter-group "Q" :after "P" :prefixes ("Ê"))
(define-letter-group "R" :after "Q" :prefixes ("Ë"))
(define-letter-group "S" :after "R" :prefixes ("Ð"))
(define-letter-group "T" :after "S" :prefixes ("Ú"))
(define-letter-group "U" :after "T" :prefixes ("à"))
(define-letter-group "V" :after "U" :prefixes ("å"))
(define-letter-group "W" :after "V" :prefixes ("æ"))
(define-letter-group "X" :after "W" :prefixes ("ë"))
(define-letter-group "Y" :after "X" :prefixes ("í"))
(define-letter-group "Z" :after "Y" :prefixes ("ð"))
(define-rule-set "sphinx-xy-alphabetize"
:rules (("À" "¶" :string)
("Ä‚" "¶" :string)
("â" "¶" :string)
("Ä" "¶" :string)
("à" "¶" :string)
("Ã…" "¶" :string)
("Ã" "¶" :string)
("Ã<>" "¶" :string)
("á" "¶" :string)
("ã" "¶" :string)
("Â" "¶" :string)
("ă" "¶" :string)
("Ã¥" "¶" :string)
("Ä…" "¶" :string)
("ä" "¶" :string)
("Ä„" "¶" :string)
("æ" "¶º" :string)
("Æ" "¶º" :string)
("ć" "¸" :string)
("ĉ" "¸" :string)
("ç" "¸" :string)
("ÄŒ" "¸" :string)
("Ä<>" "¸" :string)
("Ĉ" "¸" :string)
("Ç" "¸" :string)
("Ć" "¸" :string)
("Ä<>" "¹" :string)
("Ä<>" "¹" :string)
("ÄŽ" "¹" :string)
("Ä‘" "¹" :string)
("ê" "º" :string)
("Ę" "º" :string)
("Äš" "º" :string)
("ë" "º" :string)
("Ä›" "º" :string)
("é" "º" :string)
("È" "º" :string)
("Ë" "º" :string)
("É" "º" :string)
("è" "º" :string)
("Ê" "º" :string)
("Ä™" "º" :string)
("Ä<>" "¼" :string)
("ÄŸ" "¼" :string)
("Äž" "¼" :string)
("Äœ" "¼" :string)
("Ä¥" "½" :string)
("Ĥ" "½" :string)
("Ã<>" "¾" :string)
("Ã<>" "¾" :string)
("ï" "¾" :string)
("ÃŽ" "¾" :string)
("î" "¾" :string)
("ı" "¾" :string)
("İ" "¾" :string)
("í" "¾" :string)
("ÃŒ" "¾" :string)
("ì" "¾" :string)
("Ä´" "¿" :string)
("ĵ" "¿" :string)
("Å‚" "Á" :string)
("Å<>" "Á" :string)
("ľ" "Á" :string)
("Ľ" "Á" :string)
("Å„" "Ã" :string)
("Ń" "Ã" :string)
("ñ" "Ã" :string)
("ň" "Ã" :string)
("Ñ" "Ã" :string)
("Ň" "Ã" :string)
("Õ" "Ä" :string)
("Å<>" "Ä" :string)
("ó" "Ä" :string)
("ö" "Ä" :string)
("ô" "Ä" :string)
("Å‘" "Ä" :string)
("Ø" "Ä" :string)
("Ö" "Ä" :string)
("õ" "Ä" :string)
("Ô" "Ä" :string)
("ø" "Ä" :string)
("Ó" "Ä" :string)
("Ã’" "Ä" :string)
("ò" "Ä" :string)
("œ" "ĺ" :string)
("Œ" "ĺ" :string)
("Ř" "Ë" :string)
("Å™" "Ë" :string)
("Å”" "Ë" :string)
("Å•" "Ë" :string)
("Å<>" "Ð" :string)
("Åš" "Ð" :string)
("È™" "Ð" :string)
("ÅŸ" "Ð" :string)
("Åœ" "Ð" :string)
("Å›" "Ð" :string)
("Ș" "Ð" :string)
("Å¡" "Ð" :string)
("Åž" "Ð" :string)
("Å " "Ð" :string)
("ß" "ÐÐ" :string)
("Èš" "Ú" :string)
("Ť" "Ú" :string)
("È›" "Ú" :string)
("Å¥" "Ú" :string)
("û" "à" :string)
("Å­" "à" :string)
("ů" "à" :string)
("ű" "à" :string)
("ù" "à" :string)
("Ŭ" "à" :string)
("Ù" "à" :string)
("Ű" "à" :string)
("Ü" "à" :string)
("Å®" "à" :string)
("ú" "à" :string)
("Ú" "à" :string)
("Û" "à" :string)
("ü" "à" :string)
("ÿ" "í" :string)
("Ã<>" "í" :string)
("Ÿ" "í" :string)
("ý" "í" :string)
("Å»" "ð" :string)
("Ž" "ð" :string)
("Ź" "ð" :string)
("ž" "ð" :string)
("ż" "ð" :string)
("ź" "ð" :string)
("a" "¶" :string)
("A" "¶" :string)
("b" "·" :string)
("B" "·" :string)
("c" "¸" :string)
("C" "¸" :string)
("d" "¹" :string)
("D" "¹" :string)
("e" "º" :string)
("E" "º" :string)
("F" "»" :string)
("f" "»" :string)
("G" "¼" :string)
("g" "¼" :string)
("H" "½" :string)
("h" "½" :string)
("i" "¾" :string)
("I" "¾" :string)
("J" "¿" :string)
("j" "¿" :string)
("K" "À" :string)
("k" "À" :string)
("L" "Á" :string)
("l" "Á" :string)
("M" "Â" :string)
("m" "Â" :string)
("n" "Ã" :string)
("N" "Ã" :string)
("O" "Ä" :string)
("o" "Ä" :string)
("p" "È" :string)
("P" "È" :string)
("Q" "Ê" :string)
("q" "Ê" :string)
("r" "Ë" :string)
("R" "Ë" :string)
("S" "Ð" :string)
("s" "Ð" :string)
("t" "Ú" :string)
("T" "Ú" :string)
("u" "à" :string)
("U" "à" :string)
("v" "å" :string)
("V" "å" :string)
("W" "æ" :string)
("w" "æ" :string)
("x" "ë" :string)
("X" "ë" :string)
("Y" "í" :string)
("y" "í" :string)
("z" "ð" :string)
("Z" "ð" :string)
))
(define-rule-set "sphinx-xy-resolve-diacritics"
:rules (("Ĥ" "£" :string)
("ó" "£" :string)
("ľ" "£" :string)
("Ř" "£" :string)
("Ä<>" "£" :string)
("Ä<>" "£" :string)
("Äš" "£" :string)
("Ä¥" "£" :string)
("ÄŒ" "£" :string)
("Ä´" "£" :string)
("Ä›" "£" :string)
("ž" "£" :string)
("ÄŽ" "£" :string)
("Å™" "£" :string)
("Ž" "£" :string)
("ı" "£" :string)
("Ť" "£" :string)
("á" "£" :string)
("Ä<>" "£" :string)
("Ã<>" "£" :string)
("ň" "£" :string)
("Å " "£" :string)
("Ň" "£" :string)
("ĵ" "£" :string)
("Å¥" "£" :string)
("Ó" "£" :string)
("ý" "£" :string)
("Äœ" "£" :string)
("Ú" "£" :string)
("Ľ" "£" :string)
("Å¡" "£" :string)
("Ã<>" "£" :string)
("ú" "£" :string)
("Åš" "¤" :string)
("ć" "¤" :string)
("Å<>" "¤" :string)
("Å‚" "¤" :string)
("Å„" "¤" :string)
("À" "¤" :string)
("Ź" "¤" :string)
("à" "¤" :string)
("Ń" "¤" :string)
("Ä<>" "¤" :string)
("ÿ" "¤" :string)
("Å›" "¤" :string)
("Äž" "¤" :string)
("ÄŸ" "¤" :string)
("Ù" "¤" :string)
("İ" "¤" :string)
("Ä‘" "¤" :string)
("ù" "¤" :string)
("Èš" "¤" :string)
("é" "¤" :string)
("Å•" "¤" :string)
("Ć" "¤" :string)
("È›" "¤" :string)
("ò" "¤" :string)
("ź" "¤" :string)
("Ã’" "¤" :string)
("Ÿ" "¤" :string)
("Å”" "¤" :string)
("É" "¤" :string)
("ĉ" "¥" :string)
("ô" "¥" :string)
("Ã<>" "¥" :string)
("Å<>" "¥" :string)
("Å»" "¥" :string)
("Ä‚" "¥" :string)
("Åœ" "¥" :string)
("ñ" "¥" :string)
("Å­" "¥" :string)
("í" "¥" :string)
("È" "¥" :string)
("Ô" "¥" :string)
("Ŭ" "¥" :string)
("ż" "¥" :string)
("Ñ" "¥" :string)
("è" "¥" :string)
("Ĉ" "¥" :string)
("ă" "¥" :string)
("â" "¦" :string)
("û" "¦" :string)
("ê" "¦" :string)
("Õ" "¦" :string)
("õ" "¦" :string)
("È™" "¦" :string)
("ç" "¦" :string)
("Â" "¦" :string)
("Ê" "¦" :string)
("Û" "¦" :string)
("Ç" "¦" :string)
("ì" "¦" :string)
("ÃŒ" "¦" :string)
("Ș" "¦" :string)
("ö" "§" :string)
("Ö" "§" :string)
("ÅŸ" "§" :string)
("ů" "§" :string)
("ë" "§" :string)
("ã" "§" :string)
("î" "§" :string)
("ÃŽ" "§" :string)
("Ã" "§" :string)
("Åž" "§" :string)
("Å®" "§" :string)
("Ë" "§" :string)
("ï" "¨" :string)
("Å<>" "¨" :string)
("Ã<>" "¨" :string)
("Ę" "¨" :string)
("Å‘" "¨" :string)
("Ü" "¨" :string)
("Ã…" "¨" :string)
("ü" "¨" :string)
("Ä™" "¨" :string)
("Ã¥" "¨" :string)
("Ä" "©" :string)
("ű" "©" :string)
("Ø" "©" :string)
("ø" "©" :string)
("Ű" "©" :string)
("ä" "©" :string)
("Ä„" "ª" :string)
("Ä…" "ª" :string)
("Å“" "ÿ" :string)
("ß" "ÿ" :string)
("Æ" "ÿ" :string)
("Å’" "ÿ" :string)
("æ" "ÿ" :string)
("e" "¢" :string)
("t" "¢" :string)
("L" "¢" :string)
("Y" "¢" :string)
("J" "¢" :string)
("a" "¢" :string)
("p" "¢" :string)
("u" "¢" :string)
("j" "¢" :string)
("b" "¢" :string)
("G" "¢" :string)
("U" "¢" :string)
("F" "¢" :string)
("H" "¢" :string)
("i" "¢" :string)
("z" "¢" :string)
("c" "¢" :string)
("l" "¢" :string)
("A" "¢" :string)
("Q" "¢" :string)
("w" "¢" :string)
("D" "¢" :string)
("R" "¢" :string)
("d" "¢" :string)
("s" "¢" :string)
("r" "¢" :string)
("k" "¢" :string)
("v" "¢" :string)
("m" "¢" :string)
("P" "¢" :string)
("y" "¢" :string)
("K" "¢" :string)
("q" "¢" :string)
("S" "¢" :string)
("I" "¢" :string)
("C" "¢" :string)
("M" "¢" :string)
("Z" "¢" :string)
("T" "¢" :string)
("W" "¢" :string)
("B" "¢" :string)
("h" "¢" :string)
("x" "¢" :string)
("X" "¢" :string)
("f" "¢" :string)
("E" "¢" :string)
("V" "¢" :string)
("N" "¢" :string)
("O" "¢" :string)
("o" "¢" :string)
("g" "¢" :string)
("n" "¢" :string)
))
(define-rule-set "sphinx-xy-resolve-case"
:rules (("Ú" "8" :string)
("Ÿ" "8" :string)
("Ç" "8" :string)
("Ĉ" "8" :string)
("Å”" "8" :string)
("Ľ" "8" :string)
("Å®" "8" :string)
("Ã<>" "8" :string)
("É" "8" :string)
("Ë" "8" :string)
("Ș" "8" :string)
("Ì" "8" :string)
("Ê" "8" :string)
("Ň" "8" :string)
("Ä„" "8" :string)
("Å " "8" :string)
("Û" "8" :string)
("Åž" "8" :string)
("Ć" "8" :string)
("Ã’" "8" :string)
("Ĝ" "8" :string)
("Ñ" "8" :string)
("Ó" "8" :string)
("ÃŽ" "8" :string)
("Ã<>" "8" :string)
("Ã" "8" :string)
("Èš" "8" :string)
("Ã…" "8" :string)
("Äž" "8" :string)
("Ü" "8" :string)
("È" "8" :string)
("Ô" "8" :string)
("İ" "8" :string)
("Ű" "8" :string)
("Ù" "8" :string)
("Ŭ" "8" :string)
("Â" "8" :string)
("Ť" "8" :string)
("Ń" "8" :string)
("ÄŽ" "8" :string)
("Ź" "8" :string)
("Ž" "8" :string)
("Ä<>" "8" :string)
("Ŝ" "8" :string)
("Č" "8" :string)
("Ä´" "8" :string)
("Ö" "8" :string)
("Ø" "8" :string)
("Å»" "8" :string)
("Å<>" "8" :string)
("Ä‚" "8" :string)
("Äš" "8" :string)
("Å<>" "8" :string)
("Õ" "8" :string)
("Ę" "8" :string)
("Ã<>" "8" :string)
("À" "8" :string)
("Ĥ" "8" :string)
("Ä" "8" :string)
("Åš" "8" :string)
("Ř" "8" :string)
("Ã<>" "8" :string)
("Å’" "89" :string)
("Æ" "89" :string)
("ì" "9" :string)
("è" "9" :string)
("Ä…" "9" :string)
("Å¡" "9" :string)
("ú" "9" :string)
("Ã¥" "9" :string)
("ă" "9" :string)
("Ä™" "9" :string)
("ü" "9" :string)
("ź" "9" :string)
("ò" "9" :string)
("Å¥" "9" :string)
("È›" "9" :string)
("ĵ" "9" :string)
("Å•" "9" :string)
("ż" "9" :string)
("ä" "9" :string)
("ý" "9" :string)
("ù" "9" :string)
("á" "9" :string)
("é" "9" :string)
("Ä<>" "9" :string)
("ň" "9" :string)
("Å›" "9" :string)
("ø" "9" :string)
("í" "9" :string)
("Ä‘" "9" :string)
("ı" "9" :string)
("ÄŸ" "9" :string)
("î" "9" :string)
("ã" "9" :string)
("à" "9" :string)
("Å™" "9" :string)
("Å‘" "9" :string)
("ů" "9" :string)
("È™" "9" :string)
("ÿ" "9" :string)
("ë" "9" :string)
("Å­" "9" :string)
("ç" "9" :string)
("ű" "9" :string)
("ñ" "9" :string)
("õ" "9" :string)
("Ä›" "9" :string)
("ÅŸ" "9" :string)
("ž" "9" :string)
("Ä<>" "9" :string)
("Å<>" "9" :string)
("Å„" "9" :string)
("û" "9" :string)
("Å‚" "9" :string)
("Ä<>" "9" :string)
("Ä¥" "9" :string)
("ê" "9" :string)
("ô" "9" :string)
("ĉ" "9" :string)
("â" "9" :string)
("ć" "9" :string)
("ï" "9" :string)
("ö" "9" :string)
("ľ" "9" :string)
("ó" "9" :string)
("æ" "99" :string)
("ß" "99" :string)
("Å“" "99" :string)
("N" "8" :string)
("V" "8" :string)
("O" "8" :string)
("X" "8" :string)
("E" "8" :string)
("P" "8" :string)
("K" "8" :string)
("T" "8" :string)
("Z" "8" :string)
("M" "8" :string)
("C" "8" :string)
("I" "8" :string)
("S" "8" :string)
("B" "8" :string)
("W" "8" :string)
("D" "8" :string)
("R" "8" :string)
("H" "8" :string)
("F" "8" :string)
("Q" "8" :string)
("A" "8" :string)
("G" "8" :string)
("U" "8" :string)
("J" "8" :string)
("Y" "8" :string)
("L" "8" :string)
("o" "9" :string)
("n" "9" :string)
("g" "9" :string)
("x" "9" :string)
("f" "9" :string)
("y" "9" :string)
("q" "9" :string)
("h" "9" :string)
("w" "9" :string)
("s" "9" :string)
("d" "9" :string)
("v" "9" :string)
("k" "9" :string)
("r" "9" :string)
("m" "9" :string)
("z" "9" :string)
("c" "9" :string)
("i" "9" :string)
("l" "9" :string)
("b" "9" :string)
("j" "9" :string)
("a" "9" :string)
("p" "9" :string)
("u" "9" :string)
("t" "9" :string)
("e" "9" :string)
))
(use-rule-set :run 0
:rule-set ("sphinx-xy-alphabetize"))
(use-rule-set :run 1
:rule-set ("sphinx-xy-resolve-diacritics"))
(use-rule-set :run 2
:rule-set ("sphinx-xy-resolve-case"))

View File

@ -24,13 +24,18 @@ export LATEXOPTS =
LATEXMKOPTS =
{% if xindy_use -%}
export XINDYOPTS = {{ xindy_lang_option }} -M sphinx.xdy
{% if latex_engine == 'pdflatex' and xindy_cyrillic -%}
XINDYOPTS += -M cyrLICRutf8.xdy
{% if latex_engine == 'pdflatex' -%}
XINDYOPTS += -M LICRlatin2utf8.xdy
{% if xindy_cyrillic -%}
XINDYOPTS += -M LICRcyr2utf8.xdy
{% endif -%}
{% if latex_engine == 'xelatex' or latex_engine == 'lualatex' -%}
{% endif -%}
{% if xindy_cyrillic -%}
XINDYOPTS += -M LatinRules.xdy
{% endif -%}
# also with pdflatex as LICRlatin2utf8.xdy replaces xindy's /tex/inputenc/utf8.xdy
XINDYOPTS += -I xelatex
{% endif -%}
{% endif -%}
# format: pdf or dvi (used only by archive targets)
FMT = pdf

View File

@ -1,6 +1,23 @@
$latex = 'platex ' . $ENV{'LATEXOPTS'} . ' -kanji=utf8 %O %S';
$dvipdf = 'dvipdfmx %O -o %D %S';
$makeindex = 'rm -f %D; mendex -U -f -d %B.dic -s python.ist %S || echo "mendex exited with error code $? (ignoring)" && : >> %D';
$makeindex = 'internal mendex %S %B %D';
sub mendex {
my ($source, $basename, $destination) = @_;
my $dictfile = $basename . ".dic";
unlink($destination);
if (-f $dictfile) {
system("mendex", "-U", "-f", "-d", $dictfile, "-s", "python.ist", $source);
if ($? > 0) {
print("mendex exited with error code $? (ignored)\n");
}
}
if (!-e $destination) {
# create an empty .ind file if nothing
open(FH, ">" . $destination);
close(FH);
}
return 0;
}
add_cus_dep( "glo", "gls", 0, "makeglo" );
sub makeglo {
return system( "mendex -J -f -s gglo.ist -o '$_[0].gls' '$_[0].glo'" );

View File

@ -11,7 +11,18 @@ $pdflatex = 'xelatex ' . $ENV{'LATEXOPTS'} . ' %O %S';
$lualatex = 'lualatex ' . $ENV{'LATEXOPTS'} . ' %O %S';
$xelatex = 'xelatex --no-pdf ' . $ENV{'LATEXOPTS'} . ' %O %S';
{% if xindy_use -%}
$makeindex = 'xindy ' . $ENV{'XINDYOPTS'} . ' %O -o %D %S';
$makeindex = 'internal xindy ' . $ENV{'XINDYOPTS'} . ' %O -o %D %S';
sub xindy {
my @args = @_;
if (-z $args[-1]) {
# create an empty .ind file if .idx is empty
open(FH, ">" . $args[-2]);
close(FH);
return 0;
} else {
return system("xindy", @args);
}
}
{% else -%}
$makeindex = 'makeindex -s python.ist %O -o %D %S';
{% endif -%}

View File

@ -0,0 +1,55 @@
@ECHO OFF
REM Command file for Sphinx documentation
pushd %~dp0
{% if latex_engine == 'platex' -%}
REM latexmkrc is read then overridden by latexmkjarc
set PDFLATEX=latexmk -r latexmkjarc -pdfdvi -dvi- -ps-
{% else -%}
set PDFLATEX=latexmk -pdf -dvi- -ps-
{% endif %}
set "LATEXOPTS= "
{% if xindy_use -%}
set XINDYOPTS={{ xindy_lang_option }} -M sphinx.xdy
{% if latex_engine == 'pdflatex' -%}
set XINDYOPTS=%XINDYOPTS% -M LICRlatin2utf8.xdy
{% if xindy_cyrillic -%}
set XINDYOPTS=%XINDYOPTS% -M LICRcyr2utf8.xdy
{% endif -%}
{% endif -%}
{% if xindy_cyrillic -%}
set XINDYOPTS=%XINDYOPTS% -M LatinRules.xdy
{% endif -%}
set XINDYOPTS=%XINDYOPTS% -I xelatex
{% endif -%}
if "%1" == "" goto all-pdf
if "%1" == "all-pdf" (
:all-pdf
{%- if latex_engine == 'platex' %}
for %%i in (*.png *.gif *.jpg *.jpeg *.pdf) do (
extractbb %%i
)
{%- endif %}
for %%i in (*.tex) do (
%PDFLATEX% %LATEXMKOPTS% %%i
)
goto end
)
if "%1" == "all-pdf-ja" (
goto all-pdf
)
if "%1" == "clean" (
del /q /s *.dvi *.log *.ind *.aux *.toc *.syn *.idx *.out *.ilg *.pla *.ps *.tar *.tar.gz *.tar.bz2 *.tar.xz *.fls *.fdb_latexmk
goto end
)
:end
popd

View File

@ -6,7 +6,7 @@
%
\NeedsTeXFormat{LaTeX2e}[1995/12/01]
\ProvidesPackage{sphinx}[2018/06/30 v1.8 LaTeX package (Sphinx markup)]
\ProvidesPackage{sphinx}[2018/07/18 v1.8 LaTeX package (Sphinx markup)]
% provides \ltx@ifundefined
% (many packages load ltxcmds: graphicx does for pdftex and lualatex but
@ -182,7 +182,10 @@
% control caption around literal-block
\RequirePackage{capt-of}
\RequirePackage{needspace}
\RequirePackage{remreset}% provides \@removefromreset
% LaTeX 2018-04-01 and later provides \@removefromreset
\ltx@ifundefined{@removefromreset}
{\RequirePackage{remreset}}
{}% avoid warning
% to make pdf with correct encoded bookmarks in Japanese
% this should precede the hyperref package
\ifx\kanjiskip\@undefined
@ -1619,6 +1622,23 @@
\newcommand*\sphinxstylecodecontinues[1]{\footnotesize(#1)}%
% figure legend comes after caption and may contain arbitrary body elements
\newenvironment{sphinxlegend}{\par\small}{\par}
% reduce hyperref "Token not allowed in a PDF string" warnings on PDF builds
\AtBeginDocument{\pdfstringdefDisableCommands{%
% all "protected" macros possibly ending up in section titles should be here
\let\sphinxstyleemphasis \@firstofone
\let\sphinxstyleliteralemphasis \@firstofone
\let\sphinxstylestrong \@firstofone
\let\sphinxstyleliteralstrong \@firstofone
\let\sphinxstyleabbreviation \@firstofone
\let\sphinxstyleliteralintitle \@firstofone
\let\sphinxupquote \@firstofone
\let\sphinxstrong \@firstofone
\let\sphinxcode \@firstofone
\let\sphinxbfcode \@firstofone
\let\sphinxemail \@firstofone
\let\sphinxcrossref \@firstofone
\let\sphinxtermref \@firstofone
}}
% For curly braces inside \index macro
\def\sphinxleftcurlybrace{\{}

View File

@ -26,7 +26,7 @@
;; man page says to use rather xelatex or lualatex in case of Cyrillic
;; scripts.
;; Sphinx contributes cyrLICRutf8.xdy to provide support for Cyrillic
;; Sphinx contributes LICRcyr2utf8.xdy to provide support for Cyrillic
;; scripts for the pdflatex engine.
;; Another issue caused by xindy ignoring all TeX macros except those
@ -42,6 +42,14 @@
;; Rather it incorporates some suitable extracts from latex.xdy and
;; tex.xdy with additional Sphinx contributed rules.
;; But, this means for pdflatex and Latin scripts that the xindy file
;; tex/inputenc/uf8.xdy is not usable because it refers to the macro
;; \IeC only sporadically, and as tex.xdy is not loaded, a rule such as
;; (merge-rule "\'e" "é" :string)
;; does not work, it must be
;; (merge-rule "\IeC {\'e}" "é" :string)
;; So Sphinx contributes LICRlatin2utf8.xdy to mitigate that problem.
;;;;;;;; extracts from tex.xdy (discarding most original comments):
;;;
@ -84,39 +92,100 @@
;;;;;;;; end of extracts from latex.xdy
;; Sphinx additions, cf sphinx.util.texescape for rationale
;;
;; The LaTeX \index command turns \ into normal character so the TeX macros
;; written to .idx files are not followed by a blank. This is different
;; from non-ascii letters which end up (with pdflatex) as \IeC macros in .idx
;; file, with a blank.
;; file, with a blank space after \IeC
(merge-rule "\\sphinxleftcurlybrace\{\}" "{")
(merge-rule "\\sphinxrightcurlybrace\{\}" "}")
(merge-rule "\\_" "_")
(merge-rule "\{\[\}" "[")
(merge-rule "\{\]\}" "]")
(merge-rule "\{\}`" "`")
(merge-rule "\\textbackslash\{\}" "\\")
(merge-rule "\\textasciitilde\{\}" "~~")
(merge-rule "\\textless\{\}" "<")
(merge-rule "\\textgreater\{\}" ">")
(merge-rule "\\textasciicircum\{\}" "^")
(merge-rule "\\P\{\}" "¶")
(merge-rule "\\S\{\}" "§")
(merge-rule "\\texteuro\{\}" "€")
(merge-rule "\\\(\\infty\\\)" "∞")
(merge-rule "\\\(\\pm\\\)" "±")
(merge-rule "\\\(\\rightarrow\\\)" "→")
(merge-rule "\\\(\\checkmark\\\)" "✓")
(merge-rule "\\textendash\{\}" "")
(merge-rule "\\textbar\{\}" "|")
;; Details of the syntax are explained at
;; http://xindy.sourceforge.net/doc/manual-3.html
;; In absence of :string, "xindy uses an auto-detection mechanism to decide,
;; if the pattern is a regular expression or not". But it is not obvious to
;; guess, for example "\\_" is not detected as RE but "\\P\{\}" is, so for
;; being sure we apply the :string switch everywhere and do not use \\ etc...
;; Go back from sphinx.util.texescape TeX macros to UTF-8
(merge-rule "\sphinxleftcurlybrace{}" "{" :string)
(merge-rule "\sphinxrightcurlybrace{}" "}" :string)
(merge-rule "\_" "_" :string)
(merge-rule "{[}" "[" :string)
(merge-rule "{]}" "]" :string)
(merge-rule "{}`" "`" :string)
(merge-rule "\textbackslash{}" "\" :string) ; " for Emacs syntax highlighting
(merge-rule "\textasciitilde{}" "~~" :string); the ~~ escape is needed here
(merge-rule "\textless{}" "<" :string)
(merge-rule "\textgreater{}" ">" :string)
(merge-rule "\textasciicircum{}" "^" :string)
(merge-rule "\P{}" "¶" :string)
(merge-rule "\S{}" "§" :string)
(merge-rule "\texteuro{}" "€" :string)
(merge-rule "\(\infty\)" "∞" :string)
(merge-rule "\(\pm\)" "±" :string)
(merge-rule "\(\rightarrow\)" "→" :string)
(merge-rule "\(\checkmark\)" "✓" :string)
(merge-rule "\textendash{}" "" :string)
(merge-rule "\textbar{}" "|" :string)
(merge-rule "\(\sp{\text{0}}\)" "⁰" :string)
(merge-rule "\(\sp{\text{1}}\)" "¹" :string)
(merge-rule "\(\sp{\text{2}}\)" "²" :string)
(merge-rule "\(\sp{\text{3}}\)" "³" :string)
(merge-rule "\(\sp{\text{4}}\)" "⁴" :string)
(merge-rule "\(\sp{\text{5}}\)" "⁵" :string)
(merge-rule "\(\sp{\text{6}}\)" "⁶" :string)
(merge-rule "\(\sp{\text{7}}\)" "⁷" :string)
(merge-rule "\(\sp{\text{8}}\)" "⁸" :string)
(merge-rule "\(\sp{\text{9}}\)" "⁹" :string)
(merge-rule "\(\sb{\text{0}}\)" "₀" :string)
(merge-rule "\(\sb{\text{1}}\)" "₁" :string)
(merge-rule "\(\sb{\text{2}}\)" "₂" :string)
(merge-rule "\(\sb{\text{3}}\)" "₃" :string)
(merge-rule "\(\sb{\text{4}}\)" "₄" :string)
(merge-rule "\(\sb{\text{5}}\)" "₅" :string)
(merge-rule "\(\sb{\text{6}}\)" "₆" :string)
(merge-rule "\(\sb{\text{7}}\)" "₇" :string)
(merge-rule "\(\sb{\text{8}}\)" "₈" :string)
(merge-rule "\(\sb{\text{9}}\)" "₉" :string)
(merge-rule "\(\alpha\)" "α" :string)
(merge-rule "\(\beta\)" "β" :string)
(merge-rule "\(\gamma\)" "γ" :string)
(merge-rule "\(\delta\)" "δ" :string)
(merge-rule "\(\epsilon\)" "ε" :string)
(merge-rule "\(\zeta\)" "ζ" :string)
(merge-rule "\(\eta\)" "η" :string)
(merge-rule "\(\theta\)" "θ" :string)
(merge-rule "\(\iota\)" "ι" :string)
(merge-rule "\(\kappa\)" "κ" :string)
(merge-rule "\(\lambda\)" "λ" :string)
(merge-rule "\(\mu\)" "μ" :string)
(merge-rule "\(\nu\)" "ν" :string)
(merge-rule "\(\xi\)" "ξ" :string)
(merge-rule "\(\pi\)" "π" :string)
(merge-rule "\(\rho\)" "ρ" :string)
(merge-rule "\(\sigma\)" "σ" :string)
(merge-rule "\(\tau\)" "τ" :string)
(merge-rule "\(\upsilon\)" "υ" :string)
(merge-rule "\(\phi\)" "φ" :string)
(merge-rule "\(\chi\)" "χ" :string)
(merge-rule "\(\psi\)" "ψ" :string)
(merge-rule "\(\omega\)" "ω" :string)
(merge-rule "\(\Gamma\)" "Γ" :string)
(merge-rule "\(\Delta\)" "Δ" :string)
(merge-rule "\(\Theta\)" "Θ" :string)
(merge-rule "\(\Lambda\)" "Λ" :string)
(merge-rule "\(\Xi\)" "Ξ" :string)
(merge-rule "\(\Pi\)" "Π" :string)
(merge-rule "\(\Sigma\)" "Σ" :string)
(merge-rule "\(\Upsilon\)" "Υ" :string)
(merge-rule "\(\Phi\)" "Φ" :string)
(merge-rule "\(\Psi\)" "Ψ" :string)
(merge-rule "\(\Omega\)" "Ω" :string)
;; This xindy module provides some basic support for "see"
(require "makeindex.xdy")
;; This creates one-letter headings and works fine with utf-8 letters.
;; For Cyrillic and pdflatex necessitates cyrLICRutf8.xdy to be loaded too.
;; For Cyrillic with pdflatex works thanks to LICRcyr2utf8.xdy
(require "latin-lettergroups.xdy")
;; currently we don't (know how to easily) separate "Numbers" from

View File

@ -43,7 +43,7 @@
</div>
<div class="sidebar">
{%- block sidebartoc %}
<h3>{{ _('Table Of Contents') }}</h3>
<h3>{{ _('Table of Contents') }}</h3>
{{ toctree() }}
{%- endblock %}
{%- block sidebarsearch %}

View File

@ -7,5 +7,5 @@
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
#}
<h3><a href="{{ pathto(master_doc) }}">{{ _('Table Of Contents') }}</a></h3>
<h3><a href="{{ pathto(master_doc) }}">{{ _('Table of Contents') }}</a></h3>
{{ toctree() }}

View File

@ -8,6 +8,6 @@
:license: BSD, see LICENSE for details.
#}
{%- if display_toc %}
<h3><a href="{{ pathto(master_doc) }}">{{ _('Table Of Contents') }}</a></h3>
<h3><a href="{{ pathto(master_doc) }}">{{ _('Table of Contents') }}</a></h3>
{{ toc }}
{%- endif %}

View File

@ -81,6 +81,10 @@ div.sphinxsidebar input {
font-size: 1em;
}
div.sphinxsidebar #searchbox form.search {
overflow: hidden;
}
div.sphinxsidebar #searchbox input[type="text"] {
float: left;
width: 80%;
@ -427,6 +431,13 @@ table.field-list td, table.field-list th {
hyphens: manual;
}
/* -- hlist styles ---------------------------------------------------------- */
table.hlist td {
vertical-align: top;
}
/* -- other body styles ----------------------------------------------------- */
ol.arabic {

View File

@ -150,9 +150,9 @@ var Documentation = {
this.fixFirefoxAnchorBug();
this.highlightSearchWords();
this.initIndexTable();
{% if theme_navigation_with_keys|tobool %}
this.initOnKeyListeners();
{% endif %}
if (DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) {
this.initOnKeyListeners();
}
},
/**

View File

@ -5,5 +5,20 @@ var DOCUMENTATION_OPTIONS = {
COLLAPSE_INDEX: false,
FILE_SUFFIX: '{{ '' if no_search_suffix else file_suffix }}',
HAS_SOURCE: {{ has_source|lower }},
SOURCELINK_SUFFIX: '{{ sourcelink_suffix }}'
SOURCELINK_SUFFIX: '{{ sourcelink_suffix }}',
NAVIGATION_WITH_KEYS: {{ 'true' if theme_navigation_with_keys|tobool else 'false'}},
SEARCH_LANGUAGE_STOP_WORDS: {{ search_language_stop_words }}
};
{% if search_language_stemming_code %}
/* Non-minified version JS is _stemmer.js if file is provided */ {% endif -%}
{{ search_language_stemming_code|safe }}
{% if search_scorer_tool %}
{{ search_scorer_tool|safe }}
{% endif -%}
{% if search_word_splitter_code %}
{{ search_word_splitter_code }}
{% endif -%}

View File

@ -1,5 +1,5 @@
/*
* searchtools.js_t
* searchtools.js
* ~~~~~~~~~~~~~~~~
*
* Sphinx JavaScript utilities for the full-text search.
@ -9,51 +9,43 @@
*
*/
{% if search_language_stemming_code %}
/* Non-minified version JS is _stemmer.js if file is provided */ {% endif -%}
{{ search_language_stemming_code|safe }}
if (!Scorer) {
/**
* Simple result scoring code.
*/
var Scorer = {
// Implement the following function to further tweak the score for each result
// The function takes a result array [filename, title, anchor, descr, score]
// and returns the new score.
/*
score: function(result) {
return result[4];
},
*/
{% if search_scorer_tool %}
{{ search_scorer_tool|safe }}
{% else %}
/**
* Simple result scoring code.
*/
var Scorer = {
// Implement the following function to further tweak the score for each result
// The function takes a result array [filename, title, anchor, descr, score]
// and returns the new score.
/*
score: function(result) {
return result[4];
},
*/
// query matches the full name of an object
objNameMatch: 11,
// or matches in the last dotted part of the object name
objPartialMatch: 6,
// Additive scores depending on the priority of the object
objPrio: {0: 15, // used to be importantResults
1: 5, // used to be objectResults
2: -5}, // used to be unimportantResults
// Used when the priority is not in the mapping.
objPrioDefault: 0,
// query matches the full name of an object
objNameMatch: 11,
// or matches in the last dotted part of the object name
objPartialMatch: 6,
// Additive scores depending on the priority of the object
objPrio: {0: 15, // used to be importantResults
1: 5, // used to be objectResults
2: -5}, // used to be unimportantResults
// Used when the priority is not in the mapping.
objPrioDefault: 0,
// query found in title
title: 15,
// query found in terms
term: 5
};
{% endif %}
{% if search_word_splitter_code %}
{{ search_word_splitter_code }}
{% else %}
function splitQuery(query) {
return query.split(/\s+/);
// query found in title
title: 15,
// query found in terms
term: 5
};
}
if (!splitQuery) {
function splitQuery(query) {
return query.split(/\s+/);
}
}
{% endif %}
/**
* Search Module
@ -154,7 +146,7 @@ var Search = {
*/
query : function(query) {
var i;
var stopwords = {{ search_language_stop_words }};
var stopwords = DOCUMENTATION_OPTIONS.SEARCH_LANGUAGE_STOP_WORDS;
// stem the searchterms and add them to the correct list
var stemmer = new Stemmer();

View File

@ -9,9 +9,9 @@
#}
{%- extends "basic/layout.html" %}
{% if theme_collapsiblesidebar|tobool %}
{%- block scripts %}
{{ super() }}
{% if theme_collapsiblesidebar|tobool %}
<script type="text/javascript" src="{{ pathto('_static/sidebar.js', 1) }}"></script>
{% endif %}
{%- endblock %}
{% endif %}

View File

@ -54,7 +54,7 @@
<div class="content">
{#{%- if display_toc %}
<div id="toc">
<h3>{{ _('Table Of Contents') }}</h3>
<h3>{{ _('Table of Contents') }}</h3>
{{ toc }}
</div>
{%- endif %}#}

View File

@ -38,7 +38,7 @@
<div id="contentwrapper">
{%- if display_toc %}
<div id="toc" role="navigation" aria-label="table of contents navigation">
<h3>{{ _('Table Of Contents') }}</h3>
<h3>{{ _('Table of Contents') }}</h3>
{{ toc }}
</div>
{%- endif %}

View File

@ -0,0 +1,150 @@
# -*- coding: utf-8 -*-
"""
sphinx.transforms.post_transforms.code
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
transforms for code-blocks.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import sys
from typing import NamedTuple
from docutils import nodes
from pygments.lexers import PythonConsoleLexer, guess_lexer
from six import text_type
from sphinx import addnodes
from sphinx.ext import doctest
from sphinx.transforms import SphinxTransform
if False:
# For type annotation
from typing import Any, Dict, List # NOQA
from sphinx.application import Sphinx # NOQA
HighlightSetting = NamedTuple('HighlightSetting', [('language', text_type),
('lineno_threshold', int)])
class HighlightLanguageTransform(SphinxTransform):
"""
Apply highlight_language to all literal_block nodes.
This refers both :confval:`highlight_language` setting and
:rst:dir:`highlightlang` directive. After processing, this transform
removes ``highlightlang`` node from doctree.
"""
default_priority = 400
def apply(self):
visitor = HighlightLanguageVisitor(self.document,
self.config.highlight_language)
self.document.walkabout(visitor)
for node in self.document.traverse(addnodes.highlightlang):
node.parent.remove(node)
class HighlightLanguageVisitor(nodes.NodeVisitor):
def __init__(self, document, default_language):
# type: (nodes.document, unicode) -> None
self.default_setting = HighlightSetting(default_language, sys.maxsize)
self.settings = [] # type: List[HighlightSetting]
nodes.NodeVisitor.__init__(self, document)
def unknown_visit(self, node):
# type: (nodes.Node) -> None
pass
def unknown_departure(self, node):
# type: (nodes.Node) -> None
pass
def visit_document(self, node):
# type: (nodes.Node) -> None
self.settings.append(self.default_setting)
def depart_document(self, node):
# type: (nodes.Node) -> None
self.settings.pop()
def visit_start_of_file(self, node):
# type: (nodes.Node) -> None
self.settings.append(self.default_setting)
def depart_start_of_file(self, node):
# type: (nodes.Node) -> None
self.settings.pop()
def visit_highlightlang(self, node):
# type: (addnodes.highlightlang) -> None
self.settings[-1] = HighlightSetting(node['lang'], node['linenothreshold'])
def visit_literal_block(self, node):
# type: (nodes.literal_block) -> None
setting = self.settings[-1]
if 'language' not in node:
node['language'] = setting.language
node['force_highlighting'] = False
else:
node['force_highlighting'] = True
if 'linenos' not in node:
lines = node.astext().count('\n')
node['linenos'] = (lines >= setting.lineno_threshold - 1)
class TrimDoctestFlagsTransform(SphinxTransform):
"""
Trim doctest flags like ``# doctest: +FLAG`` from python code-blocks.
see :confval:`trim_doctest_flags` for more information.
"""
default_priority = HighlightLanguageTransform.default_priority + 1
def apply(self):
if not self.config.trim_doctest_flags:
return
for node in self.document.traverse(nodes.literal_block):
if self.is_pyconsole(node):
source = node.rawsource
source = doctest.blankline_re.sub('', source)
source = doctest.doctestopt_re.sub('', source)
node.rawsource = source
node[:] = [nodes.Text(source)]
@staticmethod
def is_pyconsole(node):
# type: (nodes.literal_block) -> bool
if node.rawsource != node.astext():
return False # skip parsed-literal node
language = node.get('language')
if language in ('pycon', 'pycon3'):
return True
elif language in ('py', 'py3', 'python', 'python3', 'default'):
return node.rawsource.startswith('>>>')
elif language == 'guess':
try:
lexer = guess_lexer(node.rawsource)
return isinstance(lexer, PythonConsoleLexer)
except Exception:
pass
return False
def setup(app):
# type: (Sphinx) -> Dict[unicode, Any]
app.add_post_transform(HighlightLanguageTransform)
app.add_post_transform(TrimDoctestFlagsTransform)
return {
'version': 'builtin',
'parallel_read_safe': True,
'parallel_write_safe': True,
}

View File

@ -15,16 +15,21 @@ import re
import sys
import typing
from collections import OrderedDict
from functools import partial
from six import PY2, PY3, StringIO, binary_type, string_types, itervalues
from six.moves import builtins
from sphinx.util import force_decode
from sphinx.util import logging
from sphinx.util.pycompat import NoneType
if False:
# For type annotation
from typing import Any, Callable, Dict, List, Tuple, Type # NOQA
logger = logging.getLogger(__name__)
memory_address_re = re.compile(r' at 0x[0-9a-f]{8,16}(?=>)', re.IGNORECASE)
@ -98,8 +103,6 @@ if PY3:
kwonlyargs, kwdefaults, annotations)
else: # 2.7
from functools import partial
def getargspec(func):
# type: (Any) -> Any
"""Like inspect.getargspec but supports functools.partial as well."""
@ -154,6 +157,12 @@ def isenumattribute(x):
return isinstance(x, enum.Enum)
def ispartial(obj):
# type: (Any) -> bool
"""Check if the object is partial."""
return isinstance(obj, partial)
def isclassmethod(obj):
# type: (Any) -> bool
"""Check if the object is classmethod."""
@ -197,6 +206,18 @@ def isdescriptor(x):
return False
def isfunction(obj):
# type: (Any) -> bool
"""Check if the object is function."""
return inspect.isfunction(obj) or ispartial(obj) and inspect.isfunction(obj.func)
def isbuiltin(obj):
# type: (Any) -> bool
"""Check if the object is builtin."""
return inspect.isbuiltin(obj) or ispartial(obj) and inspect.isbuiltin(obj.func)
def safe_getattr(obj, name, *defargs):
# type: (Any, unicode, unicode) -> object
"""A getattr() that turns all exceptions into AttributeErrors."""
@ -338,8 +359,14 @@ class Signature(object):
try:
self.annotations = typing.get_type_hints(subject) # type: ignore
except Exception:
self.annotations = {}
except Exception as exc:
if (3, 5, 0) <= sys.version_info < (3, 5, 3) and isinstance(exc, AttributeError):
# python 3.5.2 raises ValueError for partial objects.
self.annotations = {}
else:
logger.warning('Invalid type annotation found on %r. Ingored: %r',
subject, exc)
self.annotations = {}
if bound_method:
# client gives a hint that the subject is a bound method
@ -444,8 +471,7 @@ class Signature(object):
if PY2 or self.return_annotation is inspect.Parameter.empty:
return '(%s)' % ', '.join(args)
else:
if isinstance(self.return_annotation, string_types) and \
'return' in self.annotations:
if 'return' in self.annotations:
annotation = self.format_annotation(self.annotations['return'])
else:
annotation = self.format_annotation(self.return_annotation)
@ -461,6 +487,19 @@ class Signature(object):
Displaying complex types from ``typing`` relies on its private API.
"""
if isinstance(annotation, string_types):
return annotation # type: ignore
elif isinstance(annotation, typing.TypeVar): # type: ignore
return annotation.__name__
elif not annotation:
return repr(annotation)
elif annotation is NoneType: # type: ignore
return 'None'
elif getattr(annotation, '__module__', None) == 'builtins':
return annotation.__qualname__
elif annotation is Ellipsis:
return '...'
if sys.version_info >= (3, 7): # py37+
return self.format_annotation_new(annotation)
else:
@ -470,22 +509,13 @@ class Signature(object):
# type: (Any) -> str
"""format_annotation() for py37+"""
module = getattr(annotation, '__module__', None)
if isinstance(annotation, string_types):
return annotation # type: ignore
elif isinstance(annotation, typing.TypeVar): # type: ignore
return annotation.__name__
elif not annotation:
return repr(annotation)
elif module == 'builtins':
return annotation.__qualname__
elif annotation is Ellipsis:
return '...'
if module == 'typing':
if getattr(annotation, '_name', None):
qualname = annotation._name
elif getattr(annotation, '__qualname__', None):
qualname = annotation.__qualname__
elif getattr(annotation, '__forward_arg__', None):
qualname = annotation.__forward_arg__
else:
qualname = self.format_annotation(annotation.__origin__) # ex. Union
elif hasattr(annotation, '__qualname__'):
@ -495,8 +525,11 @@ class Signature(object):
if getattr(annotation, '__args__', None):
if qualname == 'Union':
args = ', '.join(self.format_annotation(a) for a in annotation.__args__)
return '%s[%s]' % (qualname, args)
if len(annotation.__args__) == 2 and annotation.__args__[1] is NoneType: # type: ignore # NOQA
return 'Optional[%s]' % self.format_annotation(annotation.__args__[0])
else:
args = ', '.join(self.format_annotation(a) for a in annotation.__args__)
return '%s[%s]' % (qualname, args)
elif qualname == 'Callable':
args = ', '.join(self.format_annotation(a) for a in annotation.__args__[:-1])
returns = self.format_annotation(annotation.__args__[-1])
@ -510,35 +543,30 @@ class Signature(object):
def format_annotation_old(self, annotation):
# type: (Any) -> str
"""format_annotation() for py36 or below"""
if isinstance(annotation, string_types):
return annotation # type: ignore
if isinstance(annotation, typing.TypeVar): # type: ignore
return annotation.__name__
if annotation == Ellipsis:
return '...'
if not isinstance(annotation, type):
qualified_name = repr(annotation)
if qualified_name.startswith('typing.'): # for typing.Union
return qualified_name.split('.', 1)[1]
module = getattr(annotation, '__module__', None)
if module == 'typing':
if getattr(annotation, '_name', None):
qualname = annotation._name
elif getattr(annotation, '__qualname__', None):
qualname = annotation.__qualname__
elif getattr(annotation, '__forward_arg__', None):
qualname = annotation.__forward_arg__
elif getattr(annotation, '__origin__', None):
qualname = self.format_annotation(annotation.__origin__) # ex. Union
else:
return qualified_name
if not annotation:
qualified_name = repr(annotation)
elif annotation.__module__ == 'typing':
qualified_name = annotation.__qualname__ # type: ignore
qualname = repr(annotation).replace('typing.', '')
elif hasattr(annotation, '__qualname__'):
qualname = '%s.%s' % (module, annotation.__qualname__)
else:
qualified_name = (annotation.__module__ + '.' + annotation.__qualname__) # type: ignore # NOQA
qualname = repr(annotation)
if annotation.__module__ == 'builtins':
return annotation.__qualname__ # type: ignore
elif (hasattr(typing, 'TupleMeta') and
isinstance(annotation, typing.TupleMeta) and # type: ignore
not hasattr(annotation, '__tuple_params__')):
if (hasattr(typing, 'TupleMeta') and
isinstance(annotation, typing.TupleMeta) and # type: ignore
not hasattr(annotation, '__tuple_params__')):
# This is for Python 3.6+, 3.5 case is handled below
params = annotation.__args__
param_str = ', '.join(self.format_annotation(p) for p in params)
return '%s[%s]' % (qualified_name, param_str)
return '%s[%s]' % (qualname, param_str)
elif (hasattr(typing, 'GenericMeta') and # for py36 or below
isinstance(annotation, typing.GenericMeta)):
# In Python 3.5.2+, all arguments are stored in __args__,
@ -554,19 +582,32 @@ class Signature(object):
args = ', '.join(self.format_annotation(arg) for arg
in annotation.__args__[:-1]) # type: ignore
result = self.format_annotation(annotation.__args__[-1]) # type: ignore
return '%s[[%s], %s]' % (qualified_name, args, result)
return '%s[[%s], %s]' % (qualname, args, result)
elif hasattr(annotation, '__parameters__'):
params = annotation.__parameters__ # type: ignore
if params is not None:
param_str = ', '.join(self.format_annotation(p) for p in params)
return '%s[%s]' % (qualified_name, param_str)
return '%s[%s]' % (qualname, param_str)
elif (hasattr(typing, 'UnionMeta') and # for py35 or below
isinstance(annotation, typing.UnionMeta) and # type: ignore
hasattr(annotation, '__union_params__')):
params = annotation.__union_params__
if params is not None:
param_str = ', '.join(self.format_annotation(p) for p in params)
return '%s[%s]' % (qualified_name, param_str)
if len(params) == 2 and params[1] is NoneType: # type: ignore
return 'Optional[%s]' % self.format_annotation(params[0])
else:
param_str = ', '.join(self.format_annotation(p) for p in params)
return '%s[%s]' % (qualname, param_str)
elif (hasattr(typing, 'Union') and # for py36
hasattr(annotation, '__origin__') and
annotation.__origin__ is typing.Union):
params = annotation.__args__
if params is not None:
if len(params) == 2 and params[1] is NoneType: # type: ignore
return 'Optional[%s]' % self.format_annotation(params[0])
else:
param_str = ', '.join(self.format_annotation(p) for p in params)
return 'Union[%s]' % param_str
elif (hasattr(typing, 'CallableMeta') and # for py36 or below
isinstance(annotation, typing.CallableMeta) and # type: ignore
getattr(annotation, '__args__', None) is not None and
@ -574,13 +615,13 @@ class Signature(object):
# Skipped in the case of plain typing.Callable
args = annotation.__args__
if args is None:
return qualified_name
return qualname
elif args is Ellipsis:
args_str = '...'
else:
formatted_args = (self.format_annotation(a) for a in args)
args_str = '[%s]' % ', '.join(formatted_args)
return '%s[%s, %s]' % (qualified_name,
return '%s[%s, %s]' % (qualname,
args_str,
self.format_annotation(annotation.__result__))
elif (hasattr(typing, 'TupleMeta') and # for py36 or below
@ -592,14 +633,14 @@ class Signature(object):
param_strings = [self.format_annotation(p) for p in params]
if annotation.__tuple_use_ellipsis__:
param_strings.append('...')
return '%s[%s]' % (qualified_name,
return '%s[%s]' % (qualname,
', '.join(param_strings))
return qualified_name
return qualname
if sys.version_info >= (3, 5):
getdoc = inspect.getdoc
_getdoc = inspect.getdoc
else:
# code copied from the inspect.py module of the standard library
# of Python 3.5
@ -679,7 +720,7 @@ else:
return doc
return None
def getdoc(object):
def _getdoc(object):
# type: (Any) -> unicode
"""Get the documentation string for an object.
@ -698,3 +739,21 @@ else:
if not isinstance(doc, str):
return None
return inspect.cleandoc(doc)
def getdoc(obj, attrgetter=safe_getattr, allow_inherited=False):
# type: (Any, Callable, bool) -> unicode
"""Get the docstring for the object.
This tries to obtain the docstring for some kind of objects additionally:
* partial functions
* inherited docstring
"""
doc = attrgetter(obj, '__doc__', None)
if ispartial(obj) and doc == obj.__class__.__doc__:
return getdoc(obj.func)
elif doc is None and allow_inherited:
doc = _getdoc(obj)
return doc

71
sphinx/util/math.py Normal file
View File

@ -0,0 +1,71 @@
# -*- coding: utf-8 -*-
"""
sphinx.util.math
~~~~~~~~~~~~~~~~
Utility functions for math.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
if False:
# For type annotation
from docutils import nodes # NOQA
from docutils.writers.html4css1 import Writer # NOQA
def get_node_equation_number(writer, node):
# type: (Writer, nodes.Node) -> unicode
if writer.builder.config.math_numfig and writer.builder.config.numfig:
figtype = 'displaymath'
if writer.builder.name == 'singlehtml':
key = u"%s/%s" % (writer.docnames[-1], figtype)
else:
key = figtype
id = node['ids'][0]
number = writer.builder.fignumbers.get(key, {}).get(id, ())
number = '.'.join(map(str, number))
else:
number = node['number']
return number
def wrap_displaymath(text, label, numbering):
# type: (unicode, unicode, bool) -> unicode
def is_equation(part):
# type: (unicode) -> unicode
return part.strip()
if label is None:
labeldef = ''
else:
labeldef = r'\label{%s}' % label
numbering = True
parts = list(filter(is_equation, text.split('\n\n')))
equations = []
if len(parts) == 0:
return ''
elif len(parts) == 1:
if numbering:
begin = r'\begin{equation}' + labeldef
end = r'\end{equation}'
else:
begin = r'\begin{equation*}' + labeldef
end = r'\end{equation*}'
equations.append('\\begin{split}%s\\end{split}\n' % parts[0])
else:
if numbering:
begin = r'\begin{align}%s\!\begin{aligned}' % labeldef
end = r'\end{aligned}\end{align}'
else:
begin = r'\begin{align*}%s\!\begin{aligned}' % labeldef
end = r'\end{aligned}\end{align*}'
for part in parts:
equations.append('%s\\\\\n' % part.strip())
return '%s\n%s%s' % (begin, ''.join(equations), end)

View File

@ -56,7 +56,10 @@ def repr_domxml(node, length=80):
returns full of DOM XML representation.
:return: DOM XML representation
"""
text = node.asdom().toxml()
try:
text = node.asdom().toxml()
except Exception:
text = text_type(node)
if length and len(text) > length:
text = text[:length] + '...'
return text

View File

@ -8,6 +8,7 @@
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
from __future__ import absolute_import
import os
import time

View File

@ -13,12 +13,14 @@ import copy
import os
import posixpath
import sys
import warnings
from docutils import nodes
from docutils.writers.html4css1 import Writer, HTMLTranslator as BaseTranslator
from six import string_types
from sphinx import addnodes
from sphinx.deprecation import RemovedInSphinx30Warning
from sphinx.locale import admonitionlabels, _, __
from sphinx.util import logging
from sphinx.util.images import get_image_size
@ -74,10 +76,6 @@ class HTMLTranslator(BaseTranslator):
BaseTranslator.__init__(self, *args, **kwds)
self.highlighter = builder.highlighter
self.builder = builder
self.highlightlang = self.highlightlang_base = \
builder.config.highlight_language
self.highlightopts = builder.config.highlight_options
self.highlightlinenothreshold = sys.maxsize
self.docnames = [builder.current_docname] # for singlehtml builder
self.manpages_url = builder.config.manpages_url
self.protect_literal_text = 0
@ -423,19 +421,14 @@ class HTMLTranslator(BaseTranslator):
if node.rawsource != node.astext():
# most probably a parsed-literal block -- don't highlight
return BaseTranslator.visit_literal_block(self, node)
lang = self.highlightlang
linenos = node.rawsource.count('\n') >= \
self.highlightlinenothreshold - 1
lang = node.get('language', 'default')
linenos = node.get('linenos', False)
highlight_args = node.get('highlight_args', {})
if 'language' in node:
# code-block directives
lang = node['language']
highlight_args['force'] = True
if 'linenos' in node:
linenos = node['linenos']
if lang is self.highlightlang_base:
highlight_args['force'] = node.get('force_highlighting', False)
if lang is self.builder.config.highlight_language:
# only pass highlighter options for original language
opts = self.highlightopts
opts = self.builder.config.highlight_options
else:
opts = {}
@ -569,15 +562,6 @@ class HTMLTranslator(BaseTranslator):
# type: (nodes.Node) -> None
pass
def visit_highlightlang(self, node):
# type: (nodes.Node) -> None
self.highlightlang = node['lang']
self.highlightlinenothreshold = node['linenothreshold']
def depart_highlightlang(self, node):
# type: (nodes.Node) -> None
pass
def visit_download_reference(self, node):
# type: (nodes.Node) -> None
if self.builder.download_support and node.hasattr('filename'):
@ -874,12 +858,60 @@ class HTMLTranslator(BaseTranslator):
def visit_math(self, node, math_env=''):
# type: (nodes.Node, unicode) -> None
logger.warning(__('using "math" markup without a Sphinx math extension '
'active, please use one of the math extensions '
'described at http://sphinx-doc.org/en/master/ext/math.html'),
location=(self.builder.current_docname, node.line))
raise nodes.SkipNode
name = self.builder.math_renderer_name
visit, _ = self.builder.app.registry.html_inline_math_renderers[name]
visit(self, node)
def depart_math(self, node, math_env=''):
# type: (nodes.Node, unicode) -> None
name = self.builder.math_renderer_name
_, depart = self.builder.app.registry.html_inline_math_renderers[name]
if depart:
depart(self, node)
def visit_math_block(self, node, math_env=''):
# type: (nodes.Node, unicode) -> None
name = self.builder.math_renderer_name
visit, _ = self.builder.app.registry.html_block_math_renderers[name]
visit(self, node)
def depart_math_block(self, node, math_env=''):
# type: (nodes.Node, unicode) -> None
name = self.builder.math_renderer_name
_, depart = self.builder.app.registry.html_block_math_renderers[name]
if depart:
depart(self, node)
def unknown_visit(self, node):
# type: (nodes.Node) -> None
raise NotImplementedError('Unknown node: ' + node.__class__.__name__)
# --------- METHODS FOR COMPATIBILITY --------------------------------------
@property
def highlightlang(self):
# type: () -> unicode
warnings.warn('HTMLTranslator.highlightlang is deprecated.',
RemovedInSphinx30Warning)
return self.builder.config.highlight_language
@property
def highlightlang_base(self):
# type: () -> unicode
warnings.warn('HTMLTranslator.highlightlang_base is deprecated.',
RemovedInSphinx30Warning)
return self.builder.config.highlight_language
@property
def highlightopts(self):
# type: () -> unicode
warnings.warn('HTMLTranslator.highlightopts is deprecated.',
RemovedInSphinx30Warning)
return self.builder.config.highlight_options
@property
def highlightlinenothreshold(self):
# type: () -> int
warnings.warn('HTMLTranslator.highlightlinenothreshold is deprecated.',
RemovedInSphinx30Warning)
return sys.maxsize

View File

@ -12,12 +12,14 @@
import os
import posixpath
import sys
import warnings
from docutils import nodes
from docutils.writers.html5_polyglot import HTMLTranslator as BaseTranslator
from six import string_types
from sphinx import addnodes
from sphinx.deprecation import RemovedInSphinx30Warning
from sphinx.locale import admonitionlabels, _, __
from sphinx.util import logging
from sphinx.util.images import get_image_size
@ -44,10 +46,6 @@ class HTML5Translator(BaseTranslator):
BaseTranslator.__init__(self, *args, **kwds)
self.highlighter = builder.highlighter
self.builder = builder
self.highlightlang = self.highlightlang_base = \
builder.config.highlight_language
self.highlightopts = builder.config.highlight_options
self.highlightlinenothreshold = sys.maxsize
self.docnames = [builder.current_docname] # for singlehtml builder
self.manpages_url = builder.config.manpages_url
self.protect_literal_text = 0
@ -369,19 +367,14 @@ class HTML5Translator(BaseTranslator):
if node.rawsource != node.astext():
# most probably a parsed-literal block -- don't highlight
return BaseTranslator.visit_literal_block(self, node)
lang = self.highlightlang
linenos = node.rawsource.count('\n') >= \
self.highlightlinenothreshold - 1
lang = node.get('language', 'default')
linenos = node.get('linenos', False)
highlight_args = node.get('highlight_args', {})
if 'language' in node:
# code-block directives
lang = node['language']
highlight_args['force'] = True
if 'linenos' in node:
linenos = node['linenos']
if lang is self.highlightlang_base:
highlight_args['force'] = node.get('force_highlighting', False)
if lang is self.builder.config.highlight_language:
# only pass highlighter options for original language
opts = self.highlightopts
opts = self.builder.config.highlight_options
else:
opts = {}
@ -515,15 +508,6 @@ class HTML5Translator(BaseTranslator):
# type: (nodes.Node) -> None
pass
def visit_highlightlang(self, node):
# type: (nodes.Node) -> None
self.highlightlang = node['lang']
self.highlightlinenothreshold = node['linenothreshold']
def depart_highlightlang(self, node):
# type: (nodes.Node) -> None
pass
def visit_download_reference(self, node):
# type: (nodes.Node) -> None
if self.builder.download_support and node.hasattr('filename'):
@ -825,12 +809,60 @@ class HTML5Translator(BaseTranslator):
def visit_math(self, node, math_env=''):
# type: (nodes.Node, unicode) -> None
logger.warning(__('using "math" markup without a Sphinx math extension '
'active, please use one of the math extensions '
'described at http://sphinx-doc.org/en/master/ext/math.html'),
location=(self.builder.current_docname, node.line))
raise nodes.SkipNode
name = self.builder.math_renderer_name
visit, _ = self.builder.app.registry.html_inline_math_renderers[name]
visit(self, node)
def depart_math(self, node, math_env=''):
# type: (nodes.Node, unicode) -> None
name = self.builder.math_renderer_name
_, depart = self.builder.app.registry.html_inline_math_renderers[name]
if depart:
depart(self, node)
def visit_math_block(self, node, math_env=''):
# type: (nodes.Node, unicode) -> None
name = self.builder.math_renderer_name
visit, _ = self.builder.app.registry.html_block_math_renderers[name]
visit(self, node)
def depart_math_block(self, node, math_env=''):
# type: (nodes.Node, unicode) -> None
name = self.builder.math_renderer_name
_, depart = self.builder.app.registry.html_block_math_renderers[name]
if depart:
depart(self, node)
def unknown_visit(self, node):
# type: (nodes.Node) -> None
raise NotImplementedError('Unknown node: ' + node.__class__.__name__)
# --------- METHODS FOR COMPATIBILITY --------------------------------------
@property
def highlightlang(self):
# type: () -> unicode
warnings.warn('HTMLTranslator.highlightlang is deprecated.',
RemovedInSphinx30Warning)
return self.builder.config.highlight_language
@property
def highlightlang_base(self):
# type: () -> unicode
warnings.warn('HTMLTranslator.highlightlang_base is deprecated.',
RemovedInSphinx30Warning)
return self.builder.config.highlight_language
@property
def highlightopts(self):
# type: () -> unicode
warnings.warn('HTMLTranslator.highlightopts is deprecated.',
RemovedInSphinx30Warning)
return self.builder.config.highlight_options
@property
def highlightlinenothreshold(self):
# type: () -> int
warnings.warn('HTMLTranslator.highlightlinenothreshold is deprecated.',
RemovedInSphinx30Warning)
return sys.maxsize

View File

@ -47,13 +47,6 @@ if False:
logger = logging.getLogger(__name__)
BEGIN_DOC = r'''
\begin{document}
%(shorthandoff)s
%(maketitle)s
%(tableofcontents)s
'''
SHORTHANDOFF = r'''
\ifdefined\shorthandoff
\ifnum\catcode`\=\string=\active\shorthandoff{=}\fi
@ -137,21 +130,22 @@ ADDITIONAL_SETTINGS = {
'pdflatex': {
'inputenc': '\\usepackage[utf8]{inputenc}',
'utf8extra': ('\\ifdefined\\DeclareUnicodeCharacter\n'
' \\ifdefined\\DeclareUnicodeCharacterAsOptional\n'
' \\DeclareUnicodeCharacter{"00A0}{\\nobreakspace}\n'
' \\DeclareUnicodeCharacter{"2500}{\\sphinxunichar{2500}}\n'
' \\DeclareUnicodeCharacter{"2502}{\\sphinxunichar{2502}}\n'
' \\DeclareUnicodeCharacter{"2514}{\\sphinxunichar{2514}}\n'
' \\DeclareUnicodeCharacter{"251C}{\\sphinxunichar{251C}}\n'
' \\DeclareUnicodeCharacter{"2572}{\\textbackslash}\n'
' \\else\n'
' \\DeclareUnicodeCharacter{00A0}{\\nobreakspace}\n'
' \\DeclareUnicodeCharacter{2500}{\\sphinxunichar{2500}}\n'
' \\DeclareUnicodeCharacter{2502}{\\sphinxunichar{2502}}\n'
' \\DeclareUnicodeCharacter{2514}{\\sphinxunichar{2514}}\n'
' \\DeclareUnicodeCharacter{251C}{\\sphinxunichar{251C}}\n'
' \\DeclareUnicodeCharacter{2572}{\\textbackslash}\n'
' \\fi\n'
'% support both utf8 and utf8x syntaxes\n'
'\\edef\\sphinxdqmaybe{'
'\\ifdefined\\DeclareUnicodeCharacterAsOptional'
'\\string"\\fi}\n'
' \\DeclareUnicodeCharacter{\\sphinxdqmaybe00A0}'
'{\\nobreakspace}\n'
' \\DeclareUnicodeCharacter{\\sphinxdqmaybe2500}'
'{\\sphinxunichar{2500}}\n'
' \\DeclareUnicodeCharacter{\\sphinxdqmaybe2502}'
'{\\sphinxunichar{2502}}\n'
' \\DeclareUnicodeCharacter{\\sphinxdqmaybe2514}'
'{\\sphinxunichar{2514}}\n'
' \\DeclareUnicodeCharacter{\\sphinxdqmaybe251C}'
'{\\sphinxunichar{251C}}\n'
' \\DeclareUnicodeCharacter{\\sphinxdqmaybe2572}'
'{\\textbackslash}\n'
'\\fi'),
},
'xelatex': {
@ -176,6 +170,9 @@ ADDITIONAL_SETTINGS = {
},
'platex': {
'latex_engine': 'platex',
'babel': '',
'classoptions': ',dvipdfmx',
'fncychap': '',
'geometry': '\\usepackage[dvipdfm]{geometry}',
},
} # type: Dict[unicode, Dict[unicode, unicode]]
@ -494,7 +491,6 @@ class LaTeXTranslator(nodes.NodeVisitor):
'babel': '\\usepackage{babel}',
})
# allow the user to override them all
self.check_latex_elements()
self.elements.update(builder.config.latex_elements)
# but some have other interface in config file
@ -570,8 +566,8 @@ class LaTeXTranslator(nodes.NodeVisitor):
self.elements['logo'] = '\\sphinxincludegraphics{%s}\\par' % \
path.basename(builder.config.latex_logo)
if builder.config.language \
and 'fncychap' not in builder.config.latex_elements:
if (builder.config.language and builder.config.language != 'ja' and
'fncychap' not in builder.config.latex_elements):
# use Sonny style if any language specified
self.elements['fncychap'] = ('\\usepackage[Sonny]{fncychap}\n'
'\\ChNameVar{\\Large\\normalfont'
@ -586,13 +582,10 @@ class LaTeXTranslator(nodes.NodeVisitor):
logger.warning(__('no Babel option known for language %r'),
builder.config.language)
# simply use babel.get_language() always, as get_language() returns
# 'english' even if language is invalid or empty
self.elements['classoptions'] += ',' + self.babel.get_language()
# set up multilingual module...
# 'babel' key is public and user setting must be obeyed
if self.elements['babel']:
self.elements['classoptions'] += ',' + self.babel.get_language()
# this branch is not taken for xelatex/lualatex if default settings
self.elements['multilingual'] = self.elements['babel']
if builder.config.language:
@ -602,18 +595,8 @@ class LaTeXTranslator(nodes.NodeVisitor):
if self.babel.uses_cyrillic() \
and 'fontpkg' not in builder.config.latex_elements:
self.elements['fontpkg'] = ''
# pTeX (Japanese TeX) for support
if builder.config.language == 'ja':
# use dvipdfmx as default class option in Japanese
self.elements['classoptions'] = ',dvipdfmx'
# disable babel which has not publishing quality in Japanese
self.elements['babel'] = ''
self.elements['shorthandoff'] = ''
self.elements['multilingual'] = ''
# disable fncychap in Japanese documents
self.elements['fncychap'] = ''
elif self.elements['polyglossia']:
self.elements['classoptions'] += ',' + self.babel.get_language()
options = self.babel.get_mainlanguage_options()
if options:
mainlanguage = r'\setmainlanguage[%s]{%s}' % (options,
@ -697,19 +680,11 @@ class LaTeXTranslator(nodes.NodeVisitor):
self.babel_defmacro('\\pageautorefname', self.encode(_('page')))
self.elements['numfig_format'] = self.generate_numfig_format(builder)
self.highlighter = highlighting.PygmentsBridge(
'latex',
builder.config.pygments_style, builder.config.trim_doctest_flags)
self.highlighter = highlighting.PygmentsBridge('latex', builder.config.pygments_style)
self.context = [] # type: List[Any]
self.descstack = [] # type: List[unicode]
self.table = None # type: Table
self.next_table_colspec = None # type: unicode
# stack of [language, linenothreshold] settings per file
# the first item here is the default and must not be changed
# the second item is the default for the master file and can be changed
# by .. highlight:: directive in the master file
self.hlsettingstack = 2 * [[builder.config.highlight_language,
sys.maxsize]]
self.bodystack = [] # type: List[List[unicode]]
self.footnote_restricted = False
self.pending_footnotes = [] # type: List[nodes.footnote_reference]
@ -727,13 +702,6 @@ class LaTeXTranslator(nodes.NodeVisitor):
self.body = self.bodystack.pop()
return body
def check_latex_elements(self):
# type: () -> None
for key in self.builder.config.latex_elements:
if key not in self.elements:
msg = __("Unknown configure key: latex_elements[%r] is ignored.")
logger.warning(msg % key)
def restrict_footnote(self, node):
# type: (nodes.Node) -> None
warnings.warn('LaTeXWriter.restrict_footnote() is deprecated.',
@ -755,13 +723,6 @@ class LaTeXTranslator(nodes.NodeVisitor):
footnode.walkabout(self)
self.pending_footnotes = []
@property
def footnotestack(self):
# type: () -> List[Dict[unicode, List[Union[collected_footnote, bool]]]]
warnings.warn('LaTeXWriter.footnotestack is deprecated.',
RemovedInSphinx30Warning)
return []
def format_docclass(self, docclass):
# type: (unicode) -> unicode
""" prepends prefix to sphinx document classes
@ -927,7 +888,6 @@ class LaTeXTranslator(nodes.NodeVisitor):
self.curfilestack.append(node.get('docname', ''))
if self.first_document == 1:
# the first document is all the regular content ...
self.body.append(BEGIN_DOC % self.elements)
self.first_document = 0
elif self.first_document == 0:
# ... and all others are the appendices
@ -945,8 +905,6 @@ class LaTeXTranslator(nodes.NodeVisitor):
def visit_start_of_file(self, node):
# type: (nodes.Node) -> None
self.curfilestack.append(node['docname'])
# use default highlight settings for new file
self.hlsettingstack.append(self.hlsettingstack[0])
def collect_footnotes(self, node):
# type: (nodes.Node) -> Dict[unicode, List[Union[collected_footnote, bool]]]
@ -971,12 +929,6 @@ class LaTeXTranslator(nodes.NodeVisitor):
def depart_start_of_file(self, node):
# type: (nodes.Node) -> None
self.curfilestack.pop()
self.hlsettingstack.pop()
def visit_highlightlang(self, node):
# type: (nodes.Node) -> None
self.hlsettingstack[-1] = [node['lang'], node['linenothreshold']]
raise nodes.SkipNode
def visit_section(self, node):
# type: (nodes.Node) -> None
@ -1906,8 +1858,11 @@ class LaTeXTranslator(nodes.NodeVisitor):
self.body.append(self.hypertarget(id, anchor=anchor))
# skip if visitor for next node supports hyperlink
next_node = node
while isinstance(next_node, nodes.target):
next_node = next_node.next_node(ascend=True)
domain = self.builder.env.get_domain('std')
next_node = node.next_node(ascend=True)
if isinstance(next_node, HYPERLINK_SUPPORT_NODES):
return
elif domain.get_enumerable_node_type(next_node) and domain.get_numfig_title(next_node):
@ -2246,26 +2201,18 @@ class LaTeXTranslator(nodes.NodeVisitor):
if labels and not self.in_footnote:
self.body.append('\n\\def\\sphinxLiteralBlockLabel{' + labels + '}')
code = node.astext()
lang = self.hlsettingstack[-1][0]
linenos = code.count('\n') >= self.hlsettingstack[-1][1] - 1
lang = node.get('language', 'default')
linenos = node.get('linenos', False)
highlight_args = node.get('highlight_args', {})
hllines = '\\fvset{hllines={, %s,}}%%' %\
str(highlight_args.get('hl_lines', []))[1:-1]
if 'language' in node:
# code-block directives
lang = node['language']
highlight_args['force'] = True
if 'linenos' in node:
linenos = node['linenos']
if lang is self.hlsettingstack[0][0]:
highlight_args['force'] = node.get('force_highlighting', False)
if lang is self.builder.config.highlight_language:
# only pass highlighter options for original language
opts = self.builder.config.highlight_options
else:
opts = {}
hlcode = self.highlighter.highlight_block(
code, lang, opts=opts, linenos=linenos,
node.rawsource, lang, opts=opts, linenos=linenos,
location=(self.curfilestack[-1], node.line), **highlight_args
)
# workaround for Unicode issue
@ -2290,6 +2237,9 @@ class LaTeXTranslator(nodes.NodeVisitor):
hlcode += '\\end{sphinxVerbatimintable}'
else:
hlcode += '\\end{sphinxVerbatim}'
hllines = '\\fvset{hllines={, %s,}}%%' %\
str(highlight_args.get('hl_lines', []))[1:-1]
self.body.append('\n' + hllines + '\n' + hlcode + '\n')
raise nodes.SkipNode
@ -2565,11 +2515,7 @@ class LaTeXTranslator(nodes.NodeVisitor):
self.body.append(r'\label{%s}' % label)
self.body.append(node.astext())
else:
def is_equation(part):
# type: (unicode) -> unicode
return part.strip()
from sphinx.ext.mathbase import wrap_displaymath
from sphinx.util.math import wrap_displaymath
self.body.append(wrap_displaymath(node.astext(), label,
self.builder.config.math_number_all))
raise nodes.SkipNode
@ -2599,6 +2545,13 @@ class LaTeXTranslator(nodes.NodeVisitor):
# --------- METHODS FOR COMPATIBILITY --------------------------------------
@property
def footnotestack(self):
# type: () -> List[Dict[unicode, List[Union[collected_footnote, bool]]]]
warnings.warn('LaTeXWriter.footnotestack is deprecated.',
RemovedInSphinx30Warning)
return []
@property
def bibitems(self):
# type: () -> List[List[unicode]]
@ -2639,6 +2592,23 @@ class LaTeXTranslator(nodes.NodeVisitor):
RemovedInSphinx30Warning)
return set()
@property
def hlsettingstack(self):
# type: () -> List[List[Union[unicode, int]]]
warnings.warn('LaTeXTranslator.hlsettingstack is deprecated.',
RemovedInSphinx30Warning)
return [[self.builder.config.highlight_language, sys.maxsize]]
def check_latex_elements(self):
# type: () -> None
warnings.warn('check_latex_elements() is deprecated.',
RemovedInSphinx30Warning)
for key in self.builder.config.latex_elements:
if key not in self.elements:
msg = __("Unknown configure key: latex_elements[%r] is ignored.")
logger.warning(msg % key)
# Import old modules here for compatibility
# They should be imported after `LaTeXTranslator` to avoid recursive import.

View File

@ -378,14 +378,6 @@ class ManualPageTranslator(BaseTranslator):
# type: (nodes.Node) -> None
pass
def visit_highlightlang(self, node):
# type: (nodes.Node) -> None
pass
def depart_highlightlang(self, node):
# type: (nodes.Node) -> None
pass
def visit_download_reference(self, node):
# type: (nodes.Node) -> None
pass

View File

@ -1533,14 +1533,6 @@ class TexinfoTranslator(nodes.NodeVisitor):
self.body.append('\n\n')
raise nodes.SkipNode
def visit_highlightlang(self, node):
# type: (nodes.Node) -> None
pass
def depart_highlightlang(self, node):
# type: (nodes.Node) -> None
pass
# -- Desc
def visit_desc(self, node):

View File

@ -251,10 +251,6 @@ class TextTranslator(nodes.NodeVisitor):
for line in lines)
# XXX header/footer?
def visit_highlightlang(self, node):
# type: (nodes.Node) -> None
raise nodes.SkipNode
def visit_section(self, node):
# type: (nodes.Node) -> None
self._title_char = self.sectionchars[self.sectionlevel]

32
tests/js/doctools.js Normal file
View File

@ -0,0 +1,32 @@
var DOCUMENTATION_OPTIONS = {};
describe('urldecode', function() {
it('should correctly decode URLs and replace `+`s with a spaces', function() {
var test_encoded_string =
'%D1%88%D0%B5%D0%BB%D0%BB%D1%8B+%D1%88%D0%B5%D0%BB%D0%BB%D1%8B';
var test_decoded_string = 'шеллы шеллы';
expect(jQuery.urldecode(test_encoded_string)).toEqual(test_decoded_string);
});
});
describe('getQueryParameters', function() {
var paramString = '?q=test+this&check_keywords=yes&area=default';
var queryParamObject = {
area: ['default'],
check_keywords: ['yes'],
q: ['test this']
};
it('should correctly create query parameter object from string', function() {
expect(jQuery.getQueryParameters(paramString)).toEqual(queryParamObject);
});
it('should correctly create query param object from URL params', function() {
history.pushState({}, '_', window.location + paramString);
expect(jQuery.getQueryParameters()).toEqual(queryParamObject);
});
});

View File

@ -234,3 +234,18 @@ class EnumCls(enum.Enum):
val3 = 34
"""doc for val3"""
val4 = 34
class CustomIter(object):
def __init__(self):
"""Create a new `CustomIter`."""
self.values = range(10)
def __iter__(self):
"""Iterate squares of each value."""
for i in self.values:
yield i ** 2
def snafucate(self):
"""Makes this snafucated."""
print("snafucated")

View File

@ -0,0 +1,11 @@
from functools import partial
def func1():
"""docstring of func1"""
pass
func2 = partial(func1)
func3 = partial(func1)
func3.__doc__ = "docstring of func3"

Some files were not shown because too many files have changed in this diff Show More