Merge branch 'master' into cpp-concepts

This commit is contained in:
Jakob Lykke Andersen 2016-08-07 18:37:31 +02:00
commit 1b251797bb
301 changed files with 10852 additions and 8262 deletions

View File

@ -13,16 +13,24 @@ python:
- "pypy"
env:
global:
- TEST=-v
- TEST='-v --with-timer --timer-top-n 25'
matrix:
- DOCUTILS=0.11
- DOCUTILS=0.12
addons:
apt:
packages:
- graphviz
- texlive-latex-recommended
- texlive-latex-extra
- texlive-fonts-recommended
- texlive-fonts-extra
install:
- pip install -U pip
- pip install -U pip setuptools
- pip install docutils==$DOCUTILS
- pip install -r test-reqs.txt
before_script: flake8
before_script:
- if [[ $TRAVIS_PYTHON_VERSION != '2.6' ]]; then flake8; fi
script:
- if [[ $TRAVIS_PYTHON_VERSION == '3.5' ]]; then make test-async; fi
- if [[ $TRAVIS_PYTHON_VERSION == '3.5' ]]; then make style-check test-async; fi
- if [[ $TRAVIS_PYTHON_VERSION != '3.5' ]]; then make test; fi

View File

@ -41,6 +41,7 @@ Other contributors, listed alphabetically, are:
* Martin Mahner -- nature theme
* Will Maier -- directory HTML builder
* Jacob Mason -- websupport library (GSOC project)
* Glenn Matthews -- python domain signature improvements
* Roland Meister -- epub builder
* Ezio Melotti -- collapsible sidebar JavaScript
* Daniel Neuhäuser -- JavaScript domain, Python 3 support (GSOC)

211
CHANGES
View File

@ -4,32 +4,230 @@ Release 1.5 (in development)
Incompatible changes
--------------------
* LaTeX package fancybox is not longer a dependency of sphinx.sty
* latex, package fancybox is not longer a dependency of sphinx.sty
* Use ``'locales'`` as a default value of `locale_dirs`
* latex, package ifthen is not any longer a dependency of sphinx.sty
* latex, style file does not modify fancyvrb's Verbatim (also available as
OriginalVerbatim) but uses sphinxVerbatim for name of custom wrapper.
* latex, package newfloat is no longer a dependency of sphinx.sty (ref #2660;
it was shipped with Sphinx since 1.3.4).
* latex, literal blocks in tables do not use OriginalVerbatim but
sphinxVerbatimintable which handles captions and wraps lines(ref #2704).
* latex, replace ``pt`` by TeX equivalent ``bp`` if found in ``width`` or
``height`` attribute of an image.
* latex, if ``width`` or ``height`` attribute of an image is given with no unit,
use ``px`` rather than ignore it.
* latex: Separate stylesheets of pygments to independent .sty file
* #2454: The filename of sourcelink is now changed. The value of
`html_sourcelink_suffix` will be appended to the original filename (like
``index.rst.txt``).
* ``sphinx.util.copy_static_entry()`` is now deprecated.
Use ``sphinx.util.fileutil.copy_asset()`` instead.
* ``sphinx.util.osutil.filecopy()`` skips copying if the file has not been changed
(ref: #2510, #2753)
* Internet Explorer 6-8, Opera 12.1x or Safari 5.1+ support is dropped
because jQuery version is updated from 1.11.0 to 3.1.0 (ref: #2634, #2773)
* QtHelpBuilder doens't generate search page (ref: #2352)
* QtHelpBuilder uses ``nonav`` theme instead of default one
to improve readability.
* latex: To provide good default settings to Japanese docs, Sphinx uses ``jsbooks``
as a docclass by default if the ``language`` is ``ja``.
* latex: To provide good default settings to Japanese docs, Sphinx uses
``jreport`` and ``jsbooks`` as a docclass by default if the ``language`` is
``ja``.
* ``sphinx-quickstart`` now allows a project version is empty
* Fix :download: role on epub/qthelp builder. They ignore the role because they don't support it.
* ``sphinx.ext.viewcode`` doesn't work on epub building by default. ``viewcode_enable_epub`` option
* ``sphinx.ext.viewcode`` disabled on singlehtml builder.
Features added
--------------
* Add ``:caption:`` option for sphinx.ext.inheritance_diagram.
* #894: Add ``lualatexpdf`` and ``xelatexpdf`` as a make target to build PDF using lualatex or xelatex
* #2471: Add config variable for default doctest flags.
* Convert linkcheck builder to requests for better encoding handling
* #2463, #2516: Add keywords of "meta" directive to search index
* ``:maxdepth:`` option of toctree affects ``secnumdepth`` (ref: #2547)
* #2575: Now ``sphinx.ext.graphviz`` allows ``:align:`` option
* Show warnings if unknown key is specified to `latex_elements`
* Show warnings if no domains match with `primary_domain` (ref: #2001)
* C++, show warnings when the kind of role is misleading for the kind
of target it refers to (e.g., using the `class` role for a function).
* latex, writer abstracts more of text styling into customizable macros, e.g.
the ``visit_emphasis`` will output ``\sphinxstyleemphasis`` rather than
``\emph`` (which may be in use elsewhere or in an added LaTeX package). See
list at end of ``sphinx.sty`` (ref: #2686)
* latex, public names for environments and parameters used by note, warning,
and other admonition types, allowing full customizability from the
``'preamble'`` key or an input file (ref: feature request #2674, #2685)
* latex, better computes column widths of some tables (as a result, there will
be slight changes as tables now correctly fill the line width; ref: #2708)
* latex, sphinxVerbatim environment is more easily customizable (ref: #2704).
In addition to already existing VerbatimColor and VerbatimBorderColor:
- two lengths ``\sphinxverbatimsep`` and ``\sphinxverbatimborder``,
- booleans ``\ifsphinxverbatimwithframe`` and ``\ifsphinxverbatimwrapslines``.
* latex, captions for literal blocks inside tables are handled, and long code
lines wrapped to fit table cell (ref: #2704)
* #2597: Show warning messages as darkred
* latex, allow image dimensions using px unit (default is 96px=1in)
* Show warnings if invalid dimension units found
* #2650: Add ``--pdb`` option to setup.py command
* latex, make the use of ``\small`` for code listings customizable (ref #2721)
* #2663: Add ``--warning-is-error`` option to setup.py command
* Show warnings if deprecated latex options are used
* Add sphinx.config.ENUM to check the config values is in candidates
* math: Add hyperlink marker to each equations in HTML output
* Add new theme ``nonav`` that doesn't include any navigation links.
This is for any help generator like qthelp.
* #2680: `sphinx.ext.todo` now emits warnings if `todo_emit_warnings` enabled.
Also, it emits an additional event named `todo-defined` to handle the TODO
entries in 3rd party extensions.
* Python domain signature parser now uses the xref mixin for 'exceptions',
allowing exception classes to be autolinked.
* #2513: Add `latex_engine` to switch the LaTeX engine by conf.py
* #2682: C++, basic support for attributes (C++11 style and GNU style).
The new configuration variables 'cpp_id_attributes' and 'cpp_paren_attributes'
can be used to introduce custom attributes.
* #1958: C++, add configuration variable 'cpp_index_common_prefix' for removing
prefixes from the index text of C++ objects.
* C++, added concept directive. Thanks to mickk-on-cpp.
* C++, added support for template introduction syntax. Thanks to mickk-on-cpp.
Bugs fixed
----------
* #2707: (latex) the column width is badly computed for tabular
* #2799: Sphinx installs roles and directives automatically on importing sphinx
module. Now Sphinx installs them on running application.
Documentation
-------------
Release 1.4.2 (in development)
Release 1.4.6 (in development)
==============================
Bugs fixed
----------
* applehelp: Sphinx crashes if ``hiutil`` or ``codesign`` commands not found
* Fix ``make clean`` abort issue when build dir contains regular files like ``DS_Store``.
* Reduce epubcheck warnings/errors:
* Fix DOCTYPE to html5
* Change extension from .html to .xhtml.
* Disable search page on epub results
* #2778: Fix autodoc crashes if obj.__dict__ is a property method and raises exception
* Fix duplicated toc in epub3 output.
* #2775: Fix failing linkcheck with servers not supporting identidy encoding
* #2833: Fix formatting instance annotations in ext.autodoc.
* #1911: ``-D`` option of `sphinx-build` does not override the ``extensions`` variable
Release 1.4.5 (released Jul 13, 2016)
=====================================
Incompatible changes
--------------------
* latex, inclusion of non-inline images from image directive resulted in
non-coherent whitespaces depending on original image width; new behaviour
by necessity differs from earlier one in some cases. (ref: #2672)
* latex, use of ``\includegraphics`` to refer to Sphinx custom variant is
deprecated; in future it will revert to original LaTeX macro, custom one
already has alternative name ``\sphinxincludegraphics``.
Features added
--------------
* new config option ``latex_keep_old_macro_names``, defaults to True. If False,
lets macros (for text styling) be defined only with ``\sphinx``-prefixed names.
* latex writer allows user customization of "shadowed" boxes (topics), via
three length variables.
* woff-format web font files now supported by the epub builder.
Bugs fixed
----------
* jsdump fix for python 3: fixes the HTML search on python > 3
* #2676: (latex) Error with verbatim text in captions since Sphinx 1.4.4
* #2629: memoir class crashes LaTeX. Fixed ``by latex_keep_old_macro_names=False`` (ref 2675)
* #2684: `sphinx.ext.intersphinx` crashes with six-1.4.1
* #2679: ``float`` package needed for ``'figure_align': 'H'`` latex option
* #2671: image directive may lead to inconsistent spacing in pdf
* #2705: ``toctree`` generates empty bullet_list if ``:titlesonly:`` specified
* #2479: `sphinx.ext.viewcode` uses python2 highlighter by default
* #2700: HtmlHelp builder has hard coded index.html
* latex, since 1.4.4 inline literal text is followed by spurious space
* #2722: C++, fix id generation for var/member declarations to include namespaces.
* latex, images (from image directive) in lists or quoted blocks did not obey
indentation (fixed together with #2671)
* #2733: since Sphinx-1.4.4 ``make latexpdf`` generates lots of hyperref warnings
* #2731: `sphinx.ext.autodoc` does not access propertymethods which raises any
exceptions
* #2666: C++, properly look up nested names involving constructors.
* #2579: Could not refer a label including both spaces and colons via
`sphinx.ext.intersphinx`
* #2718: Sphinx crashes if the document file is not readable
* #2699: hyperlinks in help HTMLs are broken if `html_file_suffix` is set
* #2723: extra spaces in latex pdf output from multirow cell
* #2735: latexpdf ``Underfull \hbox (badness 10000)`` warnings from title page
* #2667: latex crashes if resized images appeared in section title
* #2763: (html) Provide default value for required ``alt`` attribute for image
tags of SVG source, required to validate and now consistent w/ other formats.
Release 1.4.4 (released Jun 12, 2016)
=====================================
Bugs fixed
----------
* #2630: Latex sphinx.sty Notice Enviroment formatting problem
* #2632: Warning directives fail in quote environment latex build
* #2633: Sphinx crashes with old styled indices
* Fix a ``\begin{\minipage}`` typo in sphinx.sty from 1.4.2 (ref: 68becb1)
* #2622: Latex produces empty pages after title and table of contents
* #2640: 1.4.2 LaTeX crashes if code-block inside warning directive
* Let LaTeX use straight quotes also in inline code (ref #2627)
* #2351: latex crashes if enumerated lists are placed on footnotes
* #2646: latex crashes if math contains twice empty lines
* #2480: `sphinx.ext.autodoc`: memory addresses were shown
* latex: allow code-blocks appearing inside lists and quotes at maximal nesting
depth (ref #777, #2624, #2651)
* #2635: Latex code directives produce inconsistent frames based on viewing
resolution
* #2639: Sphinx now bundles iftex.sty
* Failed to build PDF with framed.sty 0.95
* Sphinx now bundles needspace.sty
Release 1.4.3 (released Jun 5, 2016)
====================================
Bugs fixed
----------
* #2530: got "Counter too large" error on building PDF if large numbered
footnotes existed in admonitions
* ``width`` option of figure directive does not work if ``align`` option specified at same time (ref: #2595)
* #2590: The ``inputenc`` package breaks compiling under lualatex and xelatex
* #2540: date on latex front page use different font
* Suppress "document isn't included in any toctree" warning if the document is included (ref: #2603)
* #2614: Some tables in PDF output will end up shifted if user sets non zero
\parindent in preamble
* #2602: URL redirection breaks the hyperlinks generated by `sphinx.ext.intersphinx`
* #2613: Show warnings if merged extensions are loaded
* #2619: make sure amstext LaTeX package always loaded (ref: d657225, 488ee52,
9d82cad and #2615)
* #2593: latex crashes if any figures in the table
Release 1.4.2 (released May 29, 2016)
=====================================
Features added
--------------
@ -64,7 +262,8 @@ Bugs fixed
* #2397: Setup shorthandoff for turkish documents
* #2447: VerbatimBorderColor wrongly used also for captions of PDF
* #2456: C++, fix crash related to document merging (e.g., singlehtml and Latex builders).
* #2446: latex(pdf) sets local tables of contents (or more generally topic nodes) in unbreakable boxes, causes overflow at bottom
* #2446: latex(pdf) sets local tables of contents (or more generally topic
nodes) in unbreakable boxes, causes overflow at bottom
* #2476: Omit MathJax markers if :nowrap: is given
* #2465: latex builder fails in case no caption option is provided to toctree directive
* Sphinx crashes if self referenced toctree found
@ -100,6 +299,7 @@ Bugs fixed
* #2581: The search doesn't work if language="es" (spanish)
* #2382: Adjust spacing after abbreviations on figure numbers in LaTeX writer
* #2383: The generated footnote by `latex_show_urls` overflows lines
* #2497, #2552: The label of search button does not fit for the button itself
Release 1.4.1 (released Apr 12, 2016)
@ -272,7 +472,8 @@ Bugs fixed
is highlighted as Python 3 (which is mostly a superset of Python 2) if possible.
To get the old behavior back, add ``highlight_language = "python"`` to conf.py.
* #2329: Refresh environment forcely if source directory has changed.
* #2331: Fix code-blocks are filled by block in dvi; remove ``xcdraw`` option from xcolor package
* #2331: Fix code-blocks are filled by block in dvi; remove ``xcdraw`` option from
xcolor package
* Fix the confval type checker emits warnings if unicode is given to confvals which expects string value
* #2360: Fix numref in LaTeX output is broken
* #2361: Fix additional paragraphs inside the "compound" directive are indented

View File

@ -61,6 +61,7 @@ Documentation using the classic theme
* Quex: http://quex.sourceforge.net/doc/html/main.html
* Ring programming language: http://ring-lang.sourceforge.net/doc/index.html
* Scapy: http://www.secdev.org/projects/scapy/doc/
* Seaborn: https://stanford.edu/~mwaskom/software/seaborn/
* Segway: http://noble.gs.washington.edu/proj/segway/doc/1.1.0/segway.html
* SimPy: http://simpy.readthedocs.org/en/latest/
* SymPy: http://docs.sympy.org/

View File

@ -13,6 +13,7 @@ include sphinx-build.py
include sphinx-quickstart.py
include sphinx-apidoc.py
recursive-include sphinx/templates *
recursive-include sphinx/texinputs *
recursive-include sphinx/themes *
recursive-include sphinx/locale *

View File

@ -6,10 +6,11 @@ PYTHON ?= python
DONT_CHECK = -i build -i dist -i sphinx/style/jquery.js \
-i sphinx/pycode/pgen2 -i sphinx/util/smartypants.py \
-i .ropeproject -i doc/_build -i tests/path.py \
-i tests/coverage.py -i env -i utils/convert.py \
-i tests/coverage.py -i utils/convert.py \
-i tests/typing_test_data.py \
-i tests/test_autodoc_py35.py \
-i tests/build \
-i tests/roots/test-warnings/undecodable.rst \
-i sphinx/search/da.py \
-i sphinx/search/de.py \
-i sphinx/search/en.py \
@ -33,12 +34,15 @@ all: clean-pyc clean-backupfiles style-check test
style-check:
@$(PYTHON) utils/check_sources.py $(DONT_CHECK) .
clean: clean-pyc clean-patchfiles clean-backupfiles clean-generated
clean: clean-pyc clean-pycache clean-patchfiles clean-backupfiles clean-generated clean-testfiles
clean-pyc:
find . -name '*.pyc' -exec rm -f {} +
find . -name '*.pyo' -exec rm -f {} +
clean-pycache:
find . -name __pycache__ -exec rm -rf {} +
clean-patchfiles:
find . -name '*.orig' -exec rm -f {} +
find . -name '*.rej' -exec rm -f {} +
@ -50,6 +54,10 @@ clean-backupfiles:
clean-generated:
rm -f utils/*3.py*
clean-testfiles:
rm -rf tests/build
rm -rf .tox/
pylint:
@pylint --rcfile utils/pylintrc sphinx

View File

@ -33,6 +33,12 @@ Install from cloned source as editable::
pip install -e .
Release signatures
==================
Releases are signed with `498D6B9E <https://pgp.mit.edu/pks/lookup?op=vindex&search=0x102C2C17498D6B9E>`_
Reading the docs
================

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 27 KiB

BIN
doc/_static/pocoo.png vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
doc/_static/sphinx.png vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 513 B

After

Width:  |  Height:  |  Size: 429 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 220 B

After

Width:  |  Height:  |  Size: 180 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 230 B

After

Width:  |  Height:  |  Size: 189 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 207 B

After

Width:  |  Height:  |  Size: 149 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 223 B

After

Width:  |  Height:  |  Size: 183 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -47,7 +47,7 @@ epub_fix_images = False
epub_max_image_width = 0
epub_show_urls = 'inline'
epub_use_index = False
epub_guide = (('toc', 'contents.html', u'Table of Contents'),)
epub_guide = (('toc', 'contents.xhtml', u'Table of Contents'),)
latex_documents = [('contents', 'sphinx.tex', 'Sphinx Documentation',
'Georg Brandl', 'manual', 1)]

View File

@ -56,7 +56,7 @@ General configuration
.. confval:: extensions
A list of strings that are module names of Sphinx extensions. These can be
A list of strings that are module names of :ref:`extensions`. These can be
extensions coming with Sphinx (named ``sphinx.ext.*``) or custom ones.
Note that you can extend :data:`sys.path` within the conf file if your
@ -870,6 +870,13 @@ that use Sphinx's HTMLWriter class.
.. versionadded:: 0.6
.. confval:: html_sourcelink_suffix
Suffix to be appended to source links (see :confval:`html_show_sourcelink`),
unless they have this suffix already. Default is ``'.txt'``.
.. versionadded:: 1.5
.. confval:: html_use_opensearch
If nonempty, an `OpenSearch <http://www.opensearch.org/Home>`_ description file will be
@ -1460,7 +1467,17 @@ the `Dublin Core metadata <http://dublincore.org/>`_.
Options for LaTeX output
------------------------
These options influence LaTeX output.
These options influence LaTeX output. See further :doc:`latex`.
.. confval:: latex_engine
The LaTeX engine to build the docs. The setting can have the following
values:
* pdflatex -- PDFLaTeX (default)
* xelatex -- XeLaTeX
* lualatex -- LuaLaTeX
* platex -- pLaTeX (default if `language` is 'ja')
.. confval:: latex_documents
@ -1568,6 +1585,21 @@ These options influence LaTeX output.
value selected the ``'inline'`` display. For backwards compatibility,
``True`` is still accepted.
.. confval:: latex_keep_old_macro_names
If ``True`` (default) the ``\strong``, ``\code``, ``\bfcode``, ``\email``,
``\tablecontinued``, ``\titleref``, ``\menuselection``, ``\accelerator``,
``\crossref``, ``\termref``, and ``\optional`` text styling macros are
pre-defined by Sphinx and may be user-customized by some
``\renewcommand``'s inserted either via ``'preamble'`` key or :dudir:`raw
<raw-data-pass-through>` directive. If ``False``, only ``\sphinxstrong``,
etc... macros are defined (and may be redefined by user). Setting to
``False`` may help solve macro name conflicts caused by user-added latex
packages.
.. versionadded:: 1.4.5
.. confval:: latex_elements
.. versionadded:: 0.5
@ -1586,6 +1618,15 @@ These options influence LaTeX output.
``'pointsize'``
Point size option of the document class (``'10pt'``, ``'11pt'`` or
``'12pt'``), default ``'10pt'``.
``'pxunit'``
the value of the ``px`` when used in image attributes ``width`` and
``height``. The default value is ``'49336sp'`` which achieves
``96px=1in`` (``1in = 72.27*65536 = 4736286.72sp``, and all dimensions
in TeX are internally integer multiples of ``sp``). To obtain for
example ``100px=1in``, one can use ``'0.01in'`` but it is more precise
to use ``'47363sp'``. To obtain ``72px=1in``, use ``'1bp'``.
.. versionadded:: 1.5
``'babel'``
"babel" package inclusion, default ``'\\usepackage{babel}'``.
``'fontpkg'``
@ -1608,7 +1649,7 @@ These options influence LaTeX output.
.. versionadded:: 1.4
``'preamble'``
Additional preamble content, default empty.
Additional preamble content, default empty. See :doc:`latex`.
``'figure_align'``
Latex figure float alignment, default 'htbp' (here, top, bottom, page).
Whenever an image doesn't fit into the current page, it will be
@ -1627,7 +1668,7 @@ These options influence LaTeX output.
``'\\usepackage[utf8]{inputenc}'`` when using pdflatex.
Otherwise unset.
.. versionchanged:: 1.5
.. versionchanged:: 1.4.3
Previously ``'\\usepackage[utf8]{inputenc}'`` was used for all
compilers.
``'cmappkg'``
@ -1678,6 +1719,11 @@ These options influence LaTeX output.
.. versionadded:: 1.0
.. versionchanged:: 1.5
In Japanese docs(`language` is ``ja``), ``'jreport'`` is used for
``'howto'`` and ``'jsbooks'`` is used for ``'manual'`` by default.
.. confval:: latex_additional_files
A list of file names, relative to the configuration directory, to copy to the
@ -1953,3 +1999,33 @@ Options for the XML builder
constructs ``*``, ``?``, ``[...]`` and ``[!...]`` with the feature that
these all don't match slashes. A double star ``**`` can be used to match
any sequence of characters *including* slashes.
.. _cpp-config:
Options for the C++ domain
--------------------------
.. confval:: cpp_index_common_prefix
A list of prefixes that will be ignored when sorting C++ objects in the global index.
For example ``['awesome_lib::']``.
.. versionadded:: 1.5
.. confval:: cpp_id_attributes
A list of strings that the parser additionally should accept as attributes.
This can for example be used when attributes have been ``#define`` d for portability.
.. versionadded:: 1.5
.. confval:: cpp_paren_attributes
A list of strings that the parser additionally should accept as attributes with one argument.
That is, if ``my_align_as`` is in the list, then ``my_align_as(X)`` is parsed as an attribute
for all strings ``X`` that have balanced brances (``()``, ``[]``, and ``{}``).
This can for example be used when attributes have been ``#define`` d for portability.
.. versionadded:: 1.5

View File

@ -1,3 +1,4 @@
.. _contents:
Sphinx documentation contents
@ -17,6 +18,7 @@ Sphinx documentation contents
intl
theming
templating
latex
extensions
extdev/index
websupport

View File

@ -359,6 +359,18 @@ single word, like this::
:param int priority: The priority of the message, can be a number 1-5
.. versionadded:: 1.5
Container types such as lists and dictionaries can be linked automatically
using the following syntax::
:type priorities: list(int)
:type priorities: list[int]
:type mapping: dict(str, int)
:type mapping: dict[str, int]
:type point: tuple(float, float)
:type point: tuple[float, float]
.. _python-roles:
Cross-referencing Python objects
@ -545,10 +557,10 @@ a visibility statement (``public``, ``private`` or ``protected``).
Full and partial template specialisations can be declared::
.. cpp::class:: template<> \
.. cpp:class:: template<> \
std::array<bool, 256>
.. cpp::class:: template<typename T> \
.. cpp:class:: template<typename T> \
std::array<T, 42>
@ -680,9 +692,9 @@ a visibility statement (``public``, ``private`` or ``protected``).
Describe an enumerator, optionally with its value defined, e.g.,::
.. cpp::enumerator:: MyEnum::myEnumerator
.. cpp:enumerator:: MyEnum::myEnumerator
.. cpp::enumerator:: MyEnum::myOtherEnumerator = 42
.. cpp:enumerator:: MyEnum::myOtherEnumerator = 42
.. rst:directive:: .. cpp:concept:: template-parameter-list name
@ -972,6 +984,12 @@ References to partial specialisations must always include the template parameter
Currently the lookup only succeed if the template parameter identifiers are equal strings.
Configuration Variables
~~~~~~~~~~~~~~~~~~~~~~~
See :ref:`cpp-config`.
The Standard Domain
-------------------

View File

@ -182,7 +182,7 @@ The doctest extension uses the following configuration values:
.. confval:: doctest_default_flags
By default, these options are enabled:
- ``ELLIPSIS``, allowing you to put ellipses in the expected output that
match anything in the actual output;
- ``IGNORE_EXCEPTION_DETAIL``, causing everything following the leftmost

View File

@ -43,6 +43,39 @@ on the first line, separated by a colon.
"""
def function_with_types_in_docstring(param1, param2):
"""Example function with types documented in the docstring.
`PEP 484`_ type annotations are supported. If attribute, parameter, and
return types are annotated according to `PEP 484`_, they do not need to be
included in the docstring:
Args:
param1 (int): The first parameter.
param2 (str): The second parameter.
Returns:
bool: The return value. True for success, False otherwise.
.. _PEP 484:
https://www.python.org/dev/peps/pep-0484/
"""
def function_with_pep484_type_annotations(param1: int, param2: str) -> bool:
"""Example function with PEP 484 type annotations.
Args:
param1: The first parameter.
param2: The second parameter.
Returns:
The return value. True for success, False otherwise.
"""
def module_level_function(param1, param2=None, *args, **kwargs):
"""This is an example of a module level function.
@ -50,9 +83,6 @@ def module_level_function(param1, param2=None, *args, **kwargs):
of each parameter is required. The type and description of each parameter
is optional, but should be included if not obvious.
Parameter types -- if given -- should be specified according to
`PEP 484`_, though `PEP 484`_ conformance isn't required or enforced.
If \*args or \*\*kwargs are accepted,
they should be listed as ``*args`` and ``**kwargs``.
@ -67,7 +97,7 @@ def module_level_function(param1, param2=None, *args, **kwargs):
Args:
param1 (int): The first parameter.
param2 (Optional[str]): The second parameter. Defaults to None.
param2 (:obj:`str`, optional): The second parameter. Defaults to None.
Second line of description should be indented.
*args: Variable length argument list.
**kwargs: Arbitrary keyword arguments.
@ -94,10 +124,6 @@ def module_level_function(param1, param2=None, *args, **kwargs):
that are relevant to the interface.
ValueError: If `param2` is equal to `param1`.
.. _PEP 484:
https://www.python.org/dev/peps/pep-0484/
"""
if param1 == param2:
raise ValueError('param1 may not be equal to param2')
@ -139,7 +165,7 @@ class ExampleError(Exception):
Args:
msg (str): Human readable string describing the exception.
code (Optional[int]): Error code.
code (:obj:`int`, optional): Error code.
Attributes:
msg (str): Human readable string describing the exception.
@ -163,16 +189,9 @@ class ExampleClass(object):
Properties created with the ``@property`` decorator should be documented
in the property's getter method.
Attribute and property types -- if given -- should be specified according
to `PEP 484`_, though `PEP 484`_ conformance isn't required or enforced.
Attributes:
attr1 (str): Description of `attr1`.
attr2 (Optional[int]): Description of `attr2`.
.. _PEP 484:
https://www.python.org/dev/peps/pep-0484/
attr2 (:obj:`int`, optional): Description of `attr2`.
"""
@ -190,20 +209,20 @@ class ExampleClass(object):
Args:
param1 (str): Description of `param1`.
param2 (Optional[int]): Description of `param2`. Multiple
param2 (:obj:`int`, optional): Description of `param2`. Multiple
lines are supported.
param3 (List[str]): Description of `param3`.
param3 (list(str)): Description of `param3`.
"""
self.attr1 = param1
self.attr2 = param2
self.attr3 = param3 #: Doc comment *inline* with attribute
#: List[str]: Doc comment *before* attribute, with type specified
#: list(str): Doc comment *before* attribute, with type specified
self.attr4 = ['attr4']
self.attr5 = None
"""Optional[str]: Docstring *after* attribute, with type specified."""
"""str: Docstring *after* attribute, with type specified."""
@property
def readonly_property(self):
@ -212,8 +231,8 @@ class ExampleClass(object):
@property
def readwrite_property(self):
"""List[str]: Properties with both a getter and setter should only
be documented in their getter method.
"""list(str): Properties with both a getter and setter
should only be documented in their getter method.
If the setter method contains notable behavior, it should be
mentioned here.

View File

@ -9,7 +9,9 @@ Example Google Style Python Docstrings
:ref:`example_numpy`
Download: :download:`example_google.py <example_google.py>`
.. only:: builder_html
Download: :download:`example_google.py <example_google.py>`
.. literalinclude:: example_google.py
:language: python

View File

@ -37,6 +37,7 @@ module_level_variable1 : int
one convention to document module level variables and be consistent
with it.
.. _NumPy Documentation HOWTO:
https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt
@ -52,6 +53,52 @@ on the first line, separated by a colon.
"""
def function_with_types_in_docstring(param1, param2):
"""Example function with types documented in the docstring.
`PEP 484`_ type annotations are supported. If attribute, parameter, and
return types are annotated according to `PEP 484`_, they do not need to be
included in the docstring:
Parameters
----------
param1 : int
The first parameter.
param2 : str
The second parameter.
Returns
-------
bool
True if successful, False otherwise.
.. _PEP 484:
https://www.python.org/dev/peps/pep-0484/
"""
def function_with_pep484_type_annotations(param1: int, param2: str) -> bool:
"""Example function with PEP 484 type annotations.
The return type must be duplicated in the docstring to comply
with the NumPy docstring style.
Parameters
----------
param1
The first parameter.
param2
The second parameter.
Returns
-------
bool
True if successful, False otherwise.
"""
def module_level_function(param1, param2=None, *args, **kwargs):
"""This is an example of a module level function.
@ -59,9 +106,6 @@ def module_level_function(param1, param2=None, *args, **kwargs):
The name of each parameter is required. The type and description of each
parameter is optional, but should be included if not obvious.
Parameter types -- if given -- should be specified according to
`PEP 484`_, though `PEP 484`_ conformance isn't required or enforced.
If \*args or \*\*kwargs are accepted,
they should be listed as ``*args`` and ``**kwargs``.
@ -81,7 +125,7 @@ def module_level_function(param1, param2=None, *args, **kwargs):
----------
param1 : int
The first parameter.
param2 : Optional[str]
param2 : :obj:`str`, optional
The second parameter.
*args
Variable length argument list.
@ -113,10 +157,6 @@ def module_level_function(param1, param2=None, *args, **kwargs):
ValueError
If `param2` is equal to `param1`.
.. _PEP 484:
https://www.python.org/dev/peps/pep-0484/
"""
if param1 == param2:
raise ValueError('param1 may not be equal to param2')
@ -166,7 +206,7 @@ class ExampleError(Exception):
----------
msg : str
Human readable string describing the exception.
code : Optional[int]
code : :obj:`int`, optional
Numeric error code.
Attributes
@ -194,20 +234,13 @@ class ExampleClass(object):
Properties created with the ``@property`` decorator should be documented
in the property's getter method.
Attribute and property types -- if given -- should be specified according
to `PEP 484`_, though `PEP 484`_ conformance isn't required or enforced.
Attributes
----------
attr1 : str
Description of `attr1`.
attr2 : Optional[int]
attr2 : :obj:`int`, optional
Description of `attr2`.
.. _PEP 484:
https://www.python.org/dev/peps/pep-0484/
"""
def __init__(self, param1, param2, param3):
@ -227,10 +260,10 @@ class ExampleClass(object):
----------
param1 : str
Description of `param1`.
param2 : List[str]
param2 : list(str)
Description of `param2`. Multiple
lines are supported.
param3 : Optional[int]
param3 : :obj:`int`, optional
Description of `param3`.
"""
@ -238,11 +271,11 @@ class ExampleClass(object):
self.attr2 = param2
self.attr3 = param3 #: Doc comment *inline* with attribute
#: List[str]: Doc comment *before* attribute, with type specified
#: list(str): Doc comment *before* attribute, with type specified
self.attr4 = ["attr4"]
self.attr5 = None
"""Optional[str]: Docstring *after* attribute, with type specified."""
"""str: Docstring *after* attribute, with type specified."""
@property
def readonly_property(self):
@ -251,8 +284,8 @@ class ExampleClass(object):
@property
def readwrite_property(self):
"""List[str]: Properties with both a getter and setter should only
be documented in their getter method.
"""list(str): Properties with both a getter and setter
should only be documented in their getter method.
If the setter method contains notable behavior, it should be
mentioned here.

View File

@ -9,7 +9,9 @@ Example NumPy Style Python Docstrings
:ref:`example_google`
Download: :download:`example_numpy.py <example_numpy.py>`
.. only:: builder_html
Download: :download:`example_numpy.py <example_numpy.py>`
.. literalinclude:: example_numpy.py
:language: python

View File

@ -40,7 +40,7 @@ It adds this directive:
included.
.. versionchanged:: 1.5
Added ``caption`` option
Added ``caption`` option
New config values are:

View File

@ -186,11 +186,60 @@ not be mixed. Choose one style for your project and be consistent with it.
* :ref:`example_google`
* :ref:`example_numpy`
For Python type annotations, see `PEP 484`_.
Type Annotations
----------------
`PEP 484`_ introduced a standard way to express types in Python code.
This is an alternative to expressing types directly in docstrings.
One benefit of expressing types according to `PEP 484`_ is that
type checkers and IDEs can take advantage of them for static code
analysis.
Google style with Python 3 type annotations::
def func(arg1: int, arg2: str) -> bool:
"""Summary line.
Extended description of function.
Args:
arg1: Description of arg1
arg2: Description of arg2
Returns:
Description of return value
"""
return True
Google style with types in docstrings::
def func(arg1, arg2):
"""Summary line.
Extended description of function.
Args:
arg1 (int): Description of arg1
arg2 (str): Description of arg2
Returns:
bool: Description of return value
"""
return True
.. Note::
`Python 2/3 compatible annotations`_ aren't currently
supported by Sphinx and won't show up in the docs.
.. _PEP 484:
https://www.python.org/dev/peps/pep-0484/
.. _Python 2/3 compatible annotations:
https://www.python.org/dev/peps/pep-0484/#suggested-syntax-for-python-2-7-and-straddling-code
Configuration
=============
@ -208,6 +257,7 @@ enabled in `conf.py`::
# Napoleon settings
napoleon_google_docstring = True
napoleon_numpy_docstring = True
napoleon_include_init_with_doc = False
napoleon_include_private_with_doc = False
napoleon_include_special_with_doc = True
napoleon_use_admonition_for_examples = False
@ -234,6 +284,23 @@ enabled in `conf.py`::
True to parse `NumPy style`_ docstrings. False to disable support
for NumPy style docstrings. *Defaults to True.*
.. confval:: napoleon_include_init_with_doc
True to list ``__init___`` docstrings separately from the class
docstring. False to fall back to Sphinx's default behavior, which
considers the ``__init___`` docstring as part of the class
documentation. *Defaults to False.*
**If True**::
def __init__(self):
\"\"\"
This will be included in the docs because it has a docstring
\"\"\"
def __init__(self):
# This will NOT be included in the docs
.. confval:: napoleon_include_private_with_doc
True to include private members (like ``_membername``) with docstrings

View File

@ -34,6 +34,13 @@ There is also an additional config value:
If this is ``True``, :rst:dir:`todo` and :rst:dir:`todolist` produce output,
else they produce nothing. The default is ``False``.
.. confval:: todo_emit_warnings
If this is ``True``, :rst:dir:`todo` emits a warning for each TODO entries.
The default is ``False``.
.. versionadded:: 1.5
.. confval:: todo_link_only
If this is ``True``, :rst:dir:`todolist` produce output without file path and line,
@ -41,3 +48,11 @@ There is also an additional config value:
.. versionadded:: 1.4
autodoc provides the following an additional event:
.. event:: todo-defined (app, node)
.. versionadded:: 1.5
Emitted when a todo is defined. *node* is the defined ``sphinx.ext.todo.todo_node``
node.

View File

@ -15,6 +15,11 @@ a highlighted version of the source code, and a link will be added to all object
descriptions that leads to the source code of the described object. A link back
from the source to the description will also be inserted.
This extension works only on HTML related builders like ``html``,
``applehelp``, ``devhelp``, ``htmlhelp``, ``qthelp`` and so on except
``singlehtml``. By default ``epub`` builder doesn't
support this extension (see :confval:`viewcode_enable_epub`).
There is an additional config value:
.. confval:: viewcode_import
@ -34,3 +39,26 @@ There is an additional config value:
main routine is protected by a ``if __name__ == '__main__'`` condition.
.. versionadded:: 1.3
.. confval:: viewcode_enable_epub
If this is ``True``, viewcode extension is also enabled even if you use
epub builders. This extension generates pages outside toctree, but this
is not preferred as epub format.
Until 1.4.x, this extension is always enabled. If you want to generate
epub as same as 1.4.x, you should set ``True``, but epub format checker's
score becomes worse.
The default is ``False``.
.. versionadded:: 1.5
.. warning::
Not all epub readers support pages generated by viewcode extension.
These readers ignore links to pages are not under toctree.
Some reader's rendering result are corrupted and
`epubcheck <https://github.com/IDPF/epubcheck>`_'s score
becomes worse even if the reader supports.

View File

@ -135,7 +135,7 @@ install.
.. note::
``pip`` has been contained in the Python official installation after version
of Python-3.4.0 or Python-2.7.9.
of Python-3.4.0 or Python-2.7.9.
Installing Sphinx with pip

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 25 KiB

151
doc/latex.rst Normal file
View File

@ -0,0 +1,151 @@
.. highlightlang:: python
.. _latex:
LaTeX customization
===================
.. module:: latex
:synopsis: LaTeX specifics.
The *latex* target does not (yet) benefit from pre-prepared themes like the
*html* target does (see :doc:`theming`).
There are two principal means of setting up customization:
#. usage of the :ref:`latex-options` as described in :doc:`config`, particularly the
various keys of :confval:`latex_elements`, to modify the loaded packages,
for example::
'fontpkg': '\\usepackage{times}', # can load other font
'fncychap': '\\usepackage[Bjarne]{fncychap}', # can use other option
.. tip::
It is not mandatory to load *fncychap*. Naturally, without it and in
absence of further customizations, the chapter headings will revert to
LaTeX's default for the *report* class.
#. usage of LaTeX ``\renewcommand``, ``\renewenvironment``, ``\setlength``,
``\definecolor`` to modify the defaults from package file :file:`sphinx.sty`
and class files :file:`sphinxhowto.cls` and :file:`sphinxmanual.cls`. If such
definitions are few, they can be located inside the ``'preamble'`` key of
:confval:`latex_elements`. In case of many it may prove more convenient to
assemble them into a specialized file :file:`customizedmacros.tex` and use::
'preamble': '\\makeatletter\\input{customizedmacros.tex}\\makeatother',
More advanced LaTeX users will set up a style file
:file:`customizedmacros.sty`, which can then be loaded via::
'preamble': '\\usepackage{customizedmacros}',
The :ref:`build configuration file <build-config>` file will then have its variable
:confval:`latex_additional_files` appropriately configured, for example::
latex_additional_files = ["customizedmacros.sty"]
Such *LaTeX Sphinx theme* files could possibly be contributed in the
future by advanced users for wider use.
Let us illustrate here what can be modified by the second method.
- text styling commands (they have one argument): ``\sphinx<foo>`` with
``<foo>`` being one of ``strong``, ``bfcode``, ``email``, ``tablecontinued``,
``titleref``, ``menuselection``, ``accelerator``, ``crossref``, ``termref``,
``optional``. By default and for backwards compatibility the ``\sphinx<foo>``
expands to ``\<foo>`` hence the user can choose to customize rather the latter
(the non-prefixed macros will be left undefined if option
:confval:`latex_keep_old_macro_names` is set to ``False`` in :file:`conf.py`.)
.. versionchanged:: 1.4.5
use of ``\sphinx`` prefixed macro names to limit possibilities of conflict
with user added packages. The LaTeX writer uses always the prefixed names.
- more text styling commands: ``\sphinxstyle<bar>`` with ``<bar>`` one of
``indexentry``, ``indexextra``, ``indexpageref``, ``topictitle``,
``sidebartitle``, ``othertitle``, ``sidebarsubtitle``, ``thead``,
``emphasis``, ``literalemphasis``, ``strong``, ``literalstrong``,
``abbreviation``, ``literalintitle``.
.. versionadded:: 1.5
earlier, the LaTeX writer used hard-coded ``\texttt``, ``\emph``, etc...
- parameters for paragraph level environments: with ``<foo>`` one of
:dudir:`warning`, :dudir:`caution`, :dudir:`attention`,
:dudir:`danger`, :dudir:`error`, the colours
*sphinx<foo>bordercolor* and *sphinx<foo>bgcolor* can be
re-defined using ``\definecolor`` command. The
``\sphinx<foo>border`` is a command (not a LaTeX length) which
specifies the thickness of the frame (default ``1pt``) and can be
``\renewcommand`` 'd. The same applies with ``<foo>`` one of
:dudir:`note`, :dudir:`hint`, :dudir:`important`, :dudir:`tip`, but
the background colour is not implemented by the default environments
and the top and bottom rule thickness default is ``0.5pt``.
.. versionchanged:: 1.5
customizability of the parameters for each type of admonition.
- paragraph level environments: for each admonition as in the previous item, the
used environment is named ``sphinx<foo>``. They may be ``\renewenvironment``
'd individually, and must then be defined with one argument (it is the heading
of the notice, for example ``Warning:`` for :dudir:`warning` directive, if
English is the document language). Their default definitions use either the
*sphinxheavybox* (for the first listed directives) or the *sphinxlightbox*
environments, configured to use the parameters (colours, border thickness)
specific to each type, as mentioned in the previous item.
.. versionchanged:: 1.5
use of public environment names, separate customizability of the parameters.
- the :dudir:`contents` directive (with ``:local:`` option) and the
:dudir:`topic` directive are implemented by environment ``sphinxShadowBox``.
Its default definition obeys three LaTeX lengths (not commands) as parameters:
``\sphinxshadowsep`` (distance from contents), ``\sphinxshadowsize`` (width of
lateral shadow), ``\sphinxshadowrule`` (thickness of the frame).
.. versionchanged:: 1.5
use of public names for the three lengths. The environment itself was
redefined to allow page breaks at release 1.4.2.
- the literal blocks (:rst:dir:`code-block` directives, etc ...), are
implemented using ``sphinxVerbatim`` environment which is a wrapper of
``Verbatim`` environment from package ``fancyvrb.sty``. It adds the handling
of the top caption and the wrapping of long lines, and a frame which allows
pagebreaks. The LaTeX lengths (not commands) ``\sphinxverbatimsep`` and
``\sphinxverbatimborder`` customize the framing. Inside tables the used
environment is ``sphinxVerbatimintable`` (it does not draw a frame, but
allows a caption).
.. versionchanged:: 1.5
``Verbatim`` keeps exact same meaning as in ``fancyvrb.sty`` (meaning
which is the one of ``OriginalVerbatim`` too), and custom one is called
``sphinxVerbatim``. Also, earlier version of Sphinx used
``OriginalVerbatim`` inside tables (captions were lost, long code lines
were not wrapped), they now use ``sphinxVerbatimintable``.
.. versionadded:: 1.5
the two customizable lengths, the ``sphinxVerbatimintable``.
- by default the Sphinx style file ``sphinx.sty`` includes the command
``\fvset{fontsize=\small}`` as part of its configuration of
``fancyvrb.sty``. The user may override this for example via
``\fvset{fontsize=auto}`` which will use for listings the ambient
font size. Refer to ``fancyvrb.sty``'s documentation for further keys.
.. versionadded:: 1.5
formerly, the use of ``\small`` for code listings was not customizable.
- miscellaneous colours: *TitleColor*, *InnerLinkColor*, *OuterLinkColor*,
*VerbatimColor* (this is a background colour), *VerbatimBorderColor*.
- the ``\sphinxAtStartFootnote`` is inserted between footnote numbers and their
texts, by default it does ``\mbox{ }``.
- use ``\sphinxSetHeaderFamily`` to set the font used by headings
(default is ``\sffamily\bfseries``).
.. versionadded:: 1.5
- the section, subsection, ... headings are set using *titlesec*'s
``\titleformat`` command.
- for the ``'manual'`` class, the chapter headings can be customized using
*fncychap*'s commands ``\ChNameVar``, ``\ChNumVar``, ``\ChTitleVar``. Or, if
the loading of this package has been removed from ``'fncychap'`` key, one can
use the *titlesec* ``\titleformat`` command.
.. note::
It is impossible to revert or prevent the loading of a package that results
from a ``\usepackage`` executed from inside the :file:`sphinx.sty` style
file. Sphinx aims at loading as few packages as are really needed for its
default design.

View File

@ -200,6 +200,12 @@ Referencing downloadable files
The ``example.py`` file will be copied to the output directory, and a
suitable link generated to it.
Not to show unavailable download links, you should wrap whole paragraphs that
have this role::
.. only:: builder_html
See :download:`this example script <../example.py>`.
Cross-referencing figures by figure number
------------------------------------------

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 150 KiB

After

Width:  |  Height:  |  Size: 146 KiB

View File

@ -363,8 +363,9 @@ directory on building (e.g. the ``_static`` directory for HTML output.)
Interpretation of image size options (``width`` and ``height``) is as follows:
if the size has no unit or the unit is pixels, the given size will only be
respected for output channels that support pixels (i.e. not in LaTeX output).
Other units (like ``pt`` for points) will be used for HTML and LaTeX output.
respected for output channels that support pixels. Other units (like ``pt``
for points) will be used for HTML and LaTeX output (the latter replaces ``pt``
by ``bp`` as this is the TeX unit such that ``72bp=1in``).
Sphinx extends the standard docutils behavior by allowing an asterisk for the
extension::
@ -386,6 +387,9 @@ Note that image file names should not contain spaces.
.. versionchanged:: 0.6
Image paths can now be absolute.
.. versionchanged:: 1.5
latex target supports pixels (default is ``96px=1in``).
Footnotes
---------

BIN
doc/themes/agogo.png vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 26 KiB

BIN
doc/themes/classic.png vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 KiB

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 KiB

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 87 KiB

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 KiB

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 KiB

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 89 KiB

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 97 KiB

After

Width:  |  Height:  |  Size: 90 KiB

BIN
doc/themes/haiku.png vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 42 KiB

BIN
doc/themes/nature.png vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 28 KiB

BIN
doc/themes/pyramid.png vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 38 KiB

BIN
doc/themes/scrolls.png vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 32 KiB

View File

@ -81,6 +81,8 @@ that has to return the directory with themes in it::
Builtin themes
--------------
.. cssclass:: longtable
+--------------------+--------------------+
| **Theme overview** | |
+--------------------+--------------------+

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -300,12 +300,17 @@ features of intersphinx.
More topics to be covered
-------------------------
- Other extensions (math, viewcode, doctest)
- :doc:`Other extensions <extensions>`:
* :doc:`ext/math`,
* :doc:`ext/viewcode`,
* :doc:`ext/doctest`,
* ...
- Static files
- Selecting a theme
- Templating
- :doc:`Selecting a theme <theming>`
- :ref:`Templating <templating>`
- Using extensions
- Writing extensions
- :ref:`Writing extensions <dev-extensions>`
.. rubric:: Footnotes

View File

@ -25,5 +25,5 @@ universal = 1
[flake8]
max-line-length=95
ignore=E113,E116,E221,E226,E241,E251
exclude=ez_setup.py,utils/*,tests/*,build/*,sphinx/search/*,sphinx/pycode/pgen2/*
ignore=E113,E116,E221,E226,E241,E251,E901
exclude=tests/*,build/*,sphinx/search/*,sphinx/pycode/pgen2/*,doc/ext/example*.py

View File

@ -64,6 +64,7 @@ extras_require = {
'nose',
'mock', # it would be better for 'test:python_version in "2.6,2.7"'
'simplejson', # better: 'test:platform_python_implementation=="PyPy"'
'html5lib',
],
}
@ -137,11 +138,8 @@ else:
domain + '.js'))
for js_file, (locale, po_file) in zip(js_files, po_files):
infile = open(po_file, 'r')
try:
with open(po_file, 'r') as infile:
catalog = read_po(infile, locale)
finally:
infile.close()
if catalog.fuzzy and not self.use_fuzzy:
continue
@ -158,8 +156,7 @@ else:
msgid = msgid[0]
jscatalog[msgid] = message.string
outfile = open(js_file, 'wb')
try:
with open(js_file, 'wb') as outfile:
outfile.write('Documentation.addTranslations(')
dump(dict(
messages=jscatalog,
@ -167,8 +164,6 @@ else:
locale=str(catalog.locale)
), outfile, sort_keys=True)
outfile.write(');')
finally:
outfile.close()
cmdclass['compile_catalog'] = compile_catalog_plusjs

View File

@ -32,17 +32,16 @@ from sphinx.roles import XRefRole
from sphinx.config import Config
from sphinx.errors import SphinxError, SphinxWarning, ExtensionError, \
VersionRequirementError, ConfigError
from sphinx.domains import ObjType, BUILTIN_DOMAINS
from sphinx.domains import ObjType
from sphinx.domains.std import GenericObject, Target, StandardDomain
from sphinx.builders import BUILTIN_BUILDERS
from sphinx.environment import BuildEnvironment
from sphinx.io import SphinxStandaloneReader
from sphinx.util import pycompat # noqa: imported for side-effects
from sphinx.util import pycompat # noqa: F401
from sphinx.util import import_object
from sphinx.util.tags import Tags
from sphinx.util.osutil import ENOENT
from sphinx.util.logging import is_suppressed_warning
from sphinx.util.console import bold, lightgray, darkgray, darkgreen, \
from sphinx.util.console import bold, lightgray, darkgray, darkred, darkgreen, \
term_width_line
from sphinx.util.i18n import find_catalog_source_files
@ -65,10 +64,44 @@ events = {
'html-page-context': 'pagename, context, doctree or None',
'build-finished': 'exception',
}
builtin_extensions = (
'sphinx.builders.applehelp',
'sphinx.builders.changes',
'sphinx.builders.epub',
'sphinx.builders.epub3',
'sphinx.builders.devhelp',
'sphinx.builders.dummy',
'sphinx.builders.gettext',
'sphinx.builders.html',
'sphinx.builders.htmlhelp',
'sphinx.builders.latex',
'sphinx.builders.linkcheck',
'sphinx.builders.manpage',
'sphinx.builders.qthelp',
'sphinx.builders.texinfo',
'sphinx.builders.text',
'sphinx.builders.websupport',
'sphinx.builders.xml',
'sphinx.domains.c',
'sphinx.domains.cpp',
'sphinx.domains.javascript',
'sphinx.domains.python',
'sphinx.domains.rst',
'sphinx.domains.std',
'sphinx.directives',
'sphinx.directives.code',
'sphinx.directives.other',
'sphinx.directives.patches',
'sphinx.roles',
)
CONFIG_FILENAME = 'conf.py'
ENV_PICKLE_FILENAME = 'environment.pickle'
# list of deprecated extensions. Keys are extension name.
# Values are Sphinx version that merge the extension.
EXTENSION_BLACKLIST = {"sphinxjp.themecore": "1.2"}
class Sphinx(object):
@ -83,9 +116,9 @@ class Sphinx(object):
self._additional_source_parsers = {}
self._listeners = {}
self._setting_up_extension = ['?']
self.domains = BUILTIN_DOMAINS.copy()
self.domains = {}
self.buildername = buildername
self.builderclasses = BUILTIN_BUILDERS.copy()
self.builderclasses = {}
self.builder = None
self.env = None
self.enumerable_nodes = {}
@ -148,6 +181,10 @@ class Sphinx(object):
if self.confdir is None:
self.confdir = self.srcdir
# load all built-in extension modules
for extension in builtin_extensions:
self.setup_extension(extension)
# extension loading support for alabaster theme
# self.config.html_theme is not set from conf.py at here
# for now, sphinx always load a 'alabaster' extension.
@ -188,6 +225,10 @@ class Sphinx(object):
'version %s and therefore cannot be built with the '
'loaded version (%s).' % (extname, needs_ver, has_ver))
# check primary_domain if requested
if self.config.primary_domain and self.config.primary_domain not in self.domains:
self.warn('primary_domain %r not found, ignored.' % self.config.primary_domain)
# set up translation infrastructure
self._init_i18n()
# check all configuration values for permissible types
@ -235,8 +276,8 @@ class Sphinx(object):
def _init_env(self, freshenv):
if freshenv:
self.env = BuildEnvironment(self.srcdir, self.doctreedir,
self.config)
self.env = BuildEnvironment(self.srcdir, self.doctreedir, self.config)
self.env.set_warnfunc(self.warn)
self.env.find_files(self.config)
for domain in self.domains.keys():
self.env.domains[domain] = self.domains[domain](self.env)
@ -245,6 +286,7 @@ class Sphinx(object):
self.info(bold('loading pickled environment... '), nonl=True)
self.env = BuildEnvironment.frompickle(
self.srcdir, self.config, path.join(self.doctreedir, ENV_PICKLE_FILENAME))
self.env.set_warnfunc(self.warn)
self.env.domains = {}
for domain in self.domains.keys():
# this can raise if the data version doesn't fit
@ -257,8 +299,6 @@ class Sphinx(object):
self.info('failed: %s' % err)
return self._init_env(freshenv=True)
self.env.set_warnfunc(self.warn)
def _init_builder(self, buildername):
if buildername is None:
print('No builder selected, using default: html', file=self._status)
@ -267,11 +307,6 @@ class Sphinx(object):
raise SphinxError('Builder name %s not registered' % buildername)
builderclass = self.builderclasses[buildername]
if isinstance(builderclass, tuple):
# builtin builder
mod, cls = builderclass
builderclass = getattr(
__import__('sphinx.builders.' + mod, None, None, [cls]), cls)
self.builder = builderclass(self)
self.emit('builder-inited')
@ -326,7 +361,8 @@ class Sphinx(object):
wfile.flush()
self.messagelog.append(message)
def warn(self, message, location=None, prefix='WARNING: ', type=None, subtype=None):
def warn(self, message, location=None, prefix='WARNING: ',
type=None, subtype=None, colorfunc=darkred):
"""Emit a warning.
If *location* is given, it should either be a tuple of (docname, lineno)
@ -356,7 +392,7 @@ class Sphinx(object):
if self.warningiserror:
raise SphinxWarning(warntext)
self._warncount += 1
self._log(warntext, self._warning, True)
self._log(colorfunc(warntext), self._warning, True)
def info(self, message='', nonl=False):
"""Emit an informational message.
@ -460,6 +496,11 @@ class Sphinx(object):
self.debug('[app] setting up extension: %r', extension)
if extension in self._extensions:
return
if extension in EXTENSION_BLACKLIST:
self.warn('the extension %r was already merged with Sphinx since version %s; '
'this extension is ignored.' % (
extension, EXTENSION_BLACKLIST[extension]))
return
self._setting_up_extension.append(extension)
try:
mod = __import__(extension, None, None, ['setup'])
@ -557,13 +598,9 @@ class Sphinx(object):
raise ExtensionError('Builder class %s has no "name" attribute'
% builder)
if builder.name in self.builderclasses:
if isinstance(self.builderclasses[builder.name], tuple):
raise ExtensionError('Builder %r is a builtin builder' %
builder.name)
else:
raise ExtensionError(
'Builder %r already exists (in module %s)' % (
builder.name, self.builderclasses[builder.name].__module__))
raise ExtensionError(
'Builder %r already exists (in module %s)' % (
builder.name, self.builderclasses[builder.name].__module__))
self.builderclasses[builder.name] = builder
def add_config_value(self, name, default, rebuild, types=()):
@ -764,8 +801,7 @@ class Sphinx(object):
def add_latex_package(self, packagename, options=None):
self.debug('[app] adding latex package: %r', packagename)
from sphinx.builders.latex import LaTeXBuilder
LaTeXBuilder.usepackages.append((packagename, options))
self.builder.usepackages.append((packagename, options))
def add_lexer(self, alias, lexer):
self.debug('[app] adding lexer: %r', (alias, lexer))

View File

@ -451,29 +451,3 @@ class Builder(object):
except AttributeError:
optname = '%s_%s' % (default, option)
return getattr(self.config, optname)
BUILTIN_BUILDERS = {
'dummy': ('dummy', 'DummyBuilder'),
'html': ('html', 'StandaloneHTMLBuilder'),
'dirhtml': ('html', 'DirectoryHTMLBuilder'),
'singlehtml': ('html', 'SingleFileHTMLBuilder'),
'pickle': ('html', 'PickleHTMLBuilder'),
'json': ('html', 'JSONHTMLBuilder'),
'web': ('html', 'PickleHTMLBuilder'),
'htmlhelp': ('htmlhelp', 'HTMLHelpBuilder'),
'devhelp': ('devhelp', 'DevhelpBuilder'),
'qthelp': ('qthelp', 'QtHelpBuilder'),
'applehelp': ('applehelp', 'AppleHelpBuilder'),
'epub': ('epub', 'EpubBuilder'),
'epub3': ('epub3', 'Epub3Builder'),
'latex': ('latex', 'LaTeXBuilder'),
'text': ('text', 'TextBuilder'),
'man': ('manpage', 'ManualPageBuilder'),
'texinfo': ('texinfo', 'TexinfoBuilder'),
'changes': ('changes', 'ChangesBuilder'),
'linkcheck': ('linkcheck', 'CheckExternalLinksBuilder'),
'websupport': ('websupport', 'WebSupportBuilder'),
'gettext': ('gettext', 'MessageCatalogBuilder'),
'xml': ('xml', 'XMLBuilder'),
'pseudoxml': ('xml', 'PseudoXMLBuilder'),
}

View File

@ -13,14 +13,16 @@ from __future__ import print_function
import codecs
import pipes
from os import path
from os import path, environ
import shlex
from sphinx.builders.html import StandaloneHTMLBuilder
from sphinx.util import copy_static_entry
from sphinx.util.osutil import copyfile, ensuredir
from sphinx.config import string_classes
from sphinx.util.osutil import copyfile, ensuredir, make_filename
from sphinx.util.console import bold
from sphinx.util.fileutil import copy_asset
from sphinx.util.pycompat import htmlescape
from sphinx.util.matching import compile_matchers
from sphinx.util.matching import Matcher
from sphinx.errors import SphinxError
import plistlib
@ -84,6 +86,7 @@ class AppleHelpBuilder(StandaloneHTMLBuilder):
super(AppleHelpBuilder, self).init()
# the output files for HTML help must be .html only
self.out_suffix = '.html'
self.link_suffix = '.html'
if self.config.applehelp_bundle_id is None:
raise SphinxError('You must set applehelp_bundle_id before '
@ -104,17 +107,15 @@ class AppleHelpBuilder(StandaloneHTMLBuilder):
self.finish_tasks.add_task(self.build_helpbook)
def copy_localized_files(self):
source_dir = path.join(self.confdir,
self.config.applehelp_locale + '.lproj')
source_dir = path.join(self.confdir, self.config.applehelp_locale + '.lproj')
target_dir = self.outdir
if path.isdir(source_dir):
self.info(bold('copying localized files... '), nonl=True)
ctx = self.globalcontext.copy()
matchers = compile_matchers(self.config.exclude_patterns)
copy_static_entry(source_dir, target_dir, self, ctx,
exclude_matchers=matchers)
excluded = Matcher(self.config.exclude_patterns + ['**/.*'])
copy_asset(source_dir, target_dir, excluded,
context=self.globalcontext, renderer=self.templates)
self.info('done')
@ -213,16 +214,19 @@ class AppleHelpBuilder(StandaloneHTMLBuilder):
self.warn('you will need to index this help book with:\n %s'
% (' '.join([pipes.quote(arg) for arg in args])))
else:
p = subprocess.Popen(args,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
try:
p = subprocess.Popen(args,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
output = p.communicate()[0]
output = p.communicate()[0]
if p.returncode != 0:
raise AppleHelpIndexerFailed(output)
else:
self.info('done')
if p.returncode != 0:
raise AppleHelpIndexerFailed(output)
else:
self.info('done')
except OSError:
raise AppleHelpIndexerFailed('Command not found: %s' % args[0])
# If we've been asked to, sign the bundle
if self.config.applehelp_codesign_identity:
@ -244,13 +248,48 @@ class AppleHelpBuilder(StandaloneHTMLBuilder):
self.warn('you will need to sign this help book with:\n %s'
% (' '.join([pipes.quote(arg) for arg in args])))
else:
p = subprocess.Popen(args,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
try:
p = subprocess.Popen(args,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
output = p.communicate()[0]
output = p.communicate()[0]
if p.returncode != 0:
raise AppleHelpCodeSigningFailed(output)
else:
self.info('done')
if p.returncode != 0:
raise AppleHelpCodeSigningFailed(output)
else:
self.info('done')
except OSError:
raise AppleHelpCodeSigningFailed('Command not found: %s' % args[0])
def setup(app):
app.setup_extension('sphinx.builders.html')
app.add_builder(AppleHelpBuilder)
app.add_config_value('applehelp_bundle_name',
lambda self: make_filename(self.project), 'applehelp')
app.add_config_value('applehelp_bundle_id', None, 'applehelp', string_classes)
app.add_config_value('applehelp_dev_region', 'en-us', 'applehelp')
app.add_config_value('applehelp_bundle_version', '1', 'applehelp')
app.add_config_value('applehelp_icon', None, 'applehelp', string_classes)
app.add_config_value('applehelp_kb_product',
lambda self: '%s-%s' % (make_filename(self.project), self.release),
'applehelp')
app.add_config_value('applehelp_kb_url', None, 'applehelp', string_classes)
app.add_config_value('applehelp_remote_url', None, 'applehelp', string_classes)
app.add_config_value('applehelp_index_anchors', False, 'applehelp', string_classes)
app.add_config_value('applehelp_min_term_length', None, 'applehelp', string_classes)
app.add_config_value('applehelp_stopwords',
lambda self: self.language or 'en', 'applehelp')
app.add_config_value('applehelp_locale', lambda self: self.language or 'en', 'applehelp')
app.add_config_value('applehelp_title', lambda self: self.project + ' Help', 'applehelp')
app.add_config_value('applehelp_codesign_identity',
lambda self: environ.get('CODE_SIGN_IDENTITY', None),
'applehelp'),
app.add_config_value('applehelp_codesign_flags',
lambda self: shlex.split(environ.get('OTHER_CODE_SIGN_FLAGS', '')),
'applehelp'),
app.add_config_value('applehelp_indexer_path', '/usr/bin/hiutil', 'applehelp')
app.add_config_value('applehelp_codesign_path', '/usr/bin/codesign', 'applehelp')
app.add_config_value('applehelp_disable_external_tools', False, None)

View File

@ -15,12 +15,12 @@ from os import path
from six import iteritems
from sphinx import package_dir
from sphinx.util import copy_static_entry
from sphinx.locale import _
from sphinx.theming import Theme
from sphinx.builders import Builder
from sphinx.util.osutil import ensuredir, os_path
from sphinx.util.console import bold
from sphinx.util.fileutil import copy_asset_file
from sphinx.util.pycompat import htmlescape
@ -138,12 +138,10 @@ class ChangesBuilder(Builder):
f.write(self.templates.render('changes/rstsource.html', ctx))
themectx = dict(('theme_' + key, val) for (key, val) in
iteritems(self.theme.get_options({})))
copy_static_entry(path.join(package_dir, 'themes', 'default',
'static', 'default.css_t'),
self.outdir, self, themectx)
copy_static_entry(path.join(package_dir, 'themes', 'basic',
'static', 'basic.css'),
self.outdir, self)
copy_asset_file(path.join(package_dir, 'themes', 'default', 'static', 'default.css_t'),
self.outdir, context=themectx, renderer=self.templates)
copy_asset_file(path.join(package_dir, 'themes', 'basic', 'static', 'basic.css'),
self.outdir)
def hl(self, text, version):
text = htmlescape(text)
@ -154,3 +152,7 @@ class ChangesBuilder(Builder):
def finish(self):
pass
def setup(app):
app.add_builder(ChangesBuilder)

View File

@ -18,6 +18,7 @@ from os import path
from docutils import nodes
from sphinx import addnodes
from sphinx.util.osutil import make_filename
from sphinx.builders.html import StandaloneHTMLBuilder
try:
@ -59,6 +60,7 @@ class DevhelpBuilder(StandaloneHTMLBuilder):
def init(self):
StandaloneHTMLBuilder.init(self)
self.out_suffix = '.html'
self.link_suffix = '.html'
def handle_finish(self):
self.build_devhelp(self.outdir, self.config.devhelp_basename)
@ -129,3 +131,10 @@ class DevhelpBuilder(StandaloneHTMLBuilder):
# Dump the XML file
with comp_open(path.join(outdir, outname + '.devhelp'), 'w') as f:
tree.write(f, 'utf-8')
def setup(app):
app.setup_extension('sphinx.builders.html')
app.add_builder(DevhelpBuilder)
app.add_config_value('devhelp_basename', lambda self: make_filename(self.project), None)

View File

@ -34,3 +34,7 @@ class DummyBuilder(Builder):
def finish(self):
pass
def setup(app):
app.add_builder(DummyBuilder)

View File

@ -29,7 +29,7 @@ from docutils import nodes
from sphinx import addnodes
from sphinx.builders.html import StandaloneHTMLBuilder
from sphinx.util.i18n import format_date
from sphinx.util.osutil import ensuredir, copyfile, EEXIST
from sphinx.util.osutil import ensuredir, copyfile, make_filename, EEXIST
from sphinx.util.smartypants import sphinx_smarty_pants as ssp
from sphinx.util.console import brown
@ -113,7 +113,7 @@ COVER_TEMPLATE = u'''\
<meta name="cover" content="%(cover)s"/>
'''
COVERPAGE_NAME = u'epub-cover.html'
COVERPAGE_NAME = u'epub-cover.xhtml'
FILE_TEMPLATE = u'''\
<item id="%(id)s"
@ -128,6 +128,10 @@ GUIDE_TEMPLATE = u'''\
TOCTREE_TEMPLATE = u'toctree-l%d'
DOCTYPE = u'''<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
'''
LINK_TARGET_TEMPLATE = u' [%(uri)s]'
FOOTNOTE_LABEL_TEMPLATE = u'#%d'
@ -143,7 +147,7 @@ GUIDE_TITLES = {
}
MEDIA_TYPES = {
'.html': 'application/xhtml+xml',
'.xhtml': 'application/xhtml+xml',
'.css': 'text/css',
'.png': 'image/png',
'.gif': 'image/gif',
@ -152,6 +156,7 @@ MEDIA_TYPES = {
'.jpeg': 'image/jpeg',
'.otf': 'application/x-font-otf',
'.ttf': 'application/x-font-ttf',
'.woff': 'application/font-woff',
}
VECTOR_GRAPHICS_EXTENSIONS = ('.svg',)
@ -183,6 +188,11 @@ class EpubBuilder(StandaloneHTMLBuilder):
add_permalinks = False
# don't add sidebar etc.
embedded = True
# disable download role
download_support = False
# don't generate search index or include search page
search = False
mimetype_template = MIMETYPE_TEMPLATE
container_template = CONTAINER_TEMPLATE
@ -197,6 +207,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
spine_template = SPINE_TEMPLATE
guide_template = GUIDE_TEMPLATE
toctree_template = TOCTREE_TEMPLATE
doctype = DOCTYPE
link_target_template = LINK_TARGET_TEMPLATE
css_link_target_class = CSS_LINK_TARGET_CLASS
guide_titles = GUIDE_TITLES
@ -206,7 +217,8 @@ class EpubBuilder(StandaloneHTMLBuilder):
def init(self):
StandaloneHTMLBuilder.init(self)
# the output files for epub must be .html only
self.out_suffix = '.html'
self.out_suffix = '.xhtml'
self.link_suffix = '.xhtml'
self.playorder = 0
self.tocid = 0
@ -276,7 +288,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
"""
refnodes.insert(0, {
'level': 1,
'refuri': self.esc(self.config.master_doc + '.html'),
'refuri': self.esc(self.config.master_doc + self.out_suffix),
'text': ssp(self.esc(
self.env.titles[self.config.master_doc].astext()))
})
@ -471,6 +483,9 @@ class EpubBuilder(StandaloneHTMLBuilder):
else:
super(EpubBuilder, self).copy_image_files()
def copy_download_files(self):
pass
def handle_page(self, pagename, addctx, templatename='page.html',
outfilename=None, event_arg=None):
"""Create a rendered page.
@ -480,6 +495,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
"""
if pagename.startswith('genindex'):
self.fix_genindex(addctx['genindexentries'])
addctx['doctype'] = self.doctype
StandaloneHTMLBuilder.handle_page(self, pagename, addctx, templatename,
outfilename, event_arg)
@ -760,3 +776,33 @@ class EpubBuilder(StandaloneHTMLBuilder):
fp = path.join(outdir, file)
epub.write(fp, file, zipfile.ZIP_DEFLATED)
epub.close()
def setup(app):
app.setup_extension('sphinx.builders.html')
app.add_builder(EpubBuilder)
# config values
app.add_config_value('epub_basename', lambda self: make_filename(self.project), None)
app.add_config_value('epub_theme', 'epub', 'html')
app.add_config_value('epub_theme_options', {}, 'html')
app.add_config_value('epub_title', lambda self: self.html_title, 'html')
app.add_config_value('epub_author', 'unknown', 'html')
app.add_config_value('epub_language', lambda self: self.language or 'en', 'html')
app.add_config_value('epub_publisher', 'unknown', 'html')
app.add_config_value('epub_copyright', lambda self: self.copyright, 'html')
app.add_config_value('epub_identifier', 'unknown', 'html')
app.add_config_value('epub_scheme', 'unknown', 'html')
app.add_config_value('epub_uid', 'unknown', 'env')
app.add_config_value('epub_cover', (), 'env')
app.add_config_value('epub_guide', (), 'env')
app.add_config_value('epub_pre_files', [], 'env')
app.add_config_value('epub_post_files', [], 'env')
app.add_config_value('epub_exclude_files', [], 'env')
app.add_config_value('epub_tocdepth', 3, 'env')
app.add_config_value('epub_tocdup', True, 'env')
app.add_config_value('epub_tocscope', 'default', 'env')
app.add_config_value('epub_fix_images', False, 'env')
app.add_config_value('epub_max_image_width', 0, 'env')
app.add_config_value('epub_show_urls', 'inline', 'html')
app.add_config_value('epub_use_index', lambda self: self.html_use_index, 'html')

View File

@ -13,6 +13,7 @@
import codecs
from os import path
from sphinx.config import string_classes
from sphinx.builders.epub import EpubBuilder
@ -73,7 +74,6 @@ PACKAGE_DOC_TEMPLATE = u'''\
%(files)s
</manifest>
<spine toc="ncx" page-progression-direction="%(page_progression_direction)s">
<itemref idref="nav" />
%(spine)s
</spine>
<guide>
@ -82,6 +82,9 @@ PACKAGE_DOC_TEMPLATE = u'''\
</package>
'''
DOCTYPE = u'''<!DOCTYPE html>
'''
# The epub3 publisher
@ -99,6 +102,7 @@ class Epub3Builder(EpubBuilder):
navlist_template = NAVLIST_TEMPLATE
navlist_indent = NAVLIST_INDENT
content_template = PACKAGE_DOC_TEMPLATE
doctype = DOCTYPE
# Finish by building the epub file
def handle_finish(self):
@ -209,3 +213,12 @@ class Epub3Builder(EpubBuilder):
# Add nav.xhtml to epub file
self.files.append(outname)
def setup(app):
app.setup_extension('sphinx.builders.epub')
app.add_builder(Epub3Builder)
app.add_config_value('epub3_description', '', 'epub3', string_classes)
app.add_config_value('epub3_contributor', 'unknown', 'epub3', string_classes)
app.add_config_value('epub3_page_progression_direction', 'ltr', 'epub3', string_classes)

View File

@ -135,7 +135,7 @@ tzdelta = datetime.fromtimestamp(timestamp) - \
source_date_epoch = getenv('SOURCE_DATE_EPOCH')
if source_date_epoch is not None:
timestamp = float(source_date_epoch)
tzdelta = 0
tzdelta = timedelta(0)
class LocalTimeZone(tzinfo):
@ -233,3 +233,13 @@ class MessageCatalogBuilder(I18nBuilder):
replace('"', r'\"'). \
replace('\n', '\\n"\n"')
pofile.write('msgid "%s"\nmsgstr ""\n\n' % message)
def setup(app):
app.add_builder(MessageCatalogBuilder)
app.add_config_value('gettext_compact', True, 'gettext')
app.add_config_value('gettext_location', True, 'gettext')
app.add_config_value('gettext_uuid', False, 'gettext')
app.add_config_value('gettext_auto_build', True, 'env')
app.add_config_value('gettext_additional_targets', [], 'env')

View File

@ -27,13 +27,15 @@ from docutils.frontend import OptionParser
from docutils.readers.doctree import Reader as DoctreeReader
from sphinx import package_dir, __display_version__
from sphinx.util import jsonimpl, copy_static_entry, copy_extra_entry
from sphinx.util import jsonimpl
from sphinx.util.i18n import format_date
from sphinx.util.osutil import SEP, os_path, relative_uri, ensuredir, \
movefile, copyfile
from sphinx.util.nodes import inline_all_toctrees
from sphinx.util.matching import patmatch, compile_matchers
from sphinx.locale import _
from sphinx.util.fileutil import copy_asset
from sphinx.util.matching import patmatch, Matcher, DOTFILES
from sphinx.config import string_classes
from sphinx.locale import _, l_
from sphinx.search import js_index
from sphinx.theming import Theme
from sphinx.builders import Builder
@ -80,6 +82,7 @@ class StandaloneHTMLBuilder(Builder):
add_permalinks = True
embedded = False # for things like HTML help or Qt help: suppresses sidebar
search = True # for things like HTML help and Apple help: suppress search
download_support = True # enable download role
# This is a class attribute because it is mutated by Sphinx.add_javascript.
script_files = ['_static/jquery.js', '_static/underscore.js',
@ -339,6 +342,7 @@ class StandaloneHTMLBuilder(Builder):
show_sphinx = self.config.html_show_sphinx,
has_source = self.config.html_copy_source,
show_source = self.config.html_show_sourcelink,
sourcelink_suffix = self.config.html_sourcelink_suffix,
file_suffix = self.out_suffix,
script_files = self.script_files,
language = self.config.language,
@ -402,15 +406,21 @@ class StandaloneHTMLBuilder(Builder):
# title rendered as HTML
title = self.env.longtitles.get(docname)
title = title and self.render_partial(title)['title'] or ''
# Suffix for the document
source_suffix = path.splitext(self.env.doc2path(docname))[1]
# the name for the copied source
sourcename = self.config.html_copy_source and docname + '.txt' or ''
if self.config.html_copy_source:
sourcename = docname + source_suffix
if source_suffix != self.config.html_sourcelink_suffix:
sourcename += self.config.html_sourcelink_suffix
else:
sourcename = ''
# metadata for the document
meta = self.env.metadata.get(docname)
# Suffix for the document
source_suffix = '.' + self.env.doc2path(docname).split('.')[-1]
# local TOC and global TOC tree
self_toc = self.env.get_toc_for(docname, self)
toc = self.render_partial(self_toc)['fragment']
@ -581,9 +591,8 @@ class StandaloneHTMLBuilder(Builder):
self.info(bold('copying static files... '), nonl=True)
ensuredir(path.join(self.outdir, '_static'))
# first, create pygments style file
f = open(path.join(self.outdir, '_static', 'pygments.css'), 'w')
f.write(self.highlighter.get_stylesheet())
f.close()
with open(path.join(self.outdir, '_static', 'pygments.css'), 'w') as f:
f.write(self.highlighter.get_stylesheet())
# then, copy translations JavaScript file
if self.config.language is not None:
jsfile = self._get_translations_js()
@ -605,21 +614,19 @@ class StandaloneHTMLBuilder(Builder):
# then, copy over theme-supplied static files
if self.theme:
themeentries = [path.join(themepath, 'static')
for themepath in self.theme.get_dirchain()[::-1]]
for entry in themeentries:
copy_static_entry(entry, path.join(self.outdir, '_static'),
self, ctx)
for theme_path in self.theme.get_dirchain()[::-1]:
entry = path.join(theme_path, 'static')
copy_asset(entry, path.join(self.outdir, '_static'), excluded=DOTFILES,
context=ctx, renderer=self.templates)
# then, copy over all user-supplied static files
staticentries = [path.join(self.confdir, spath)
for spath in self.config.html_static_path]
matchers = compile_matchers(self.config.exclude_patterns)
for entry in staticentries:
excluded = Matcher(self.config.exclude_patterns + ["**/.*"])
for static_path in self.config.html_static_path:
entry = path.join(self.confdir, static_path)
if not path.exists(entry):
self.warn('html_static_path entry %r does not exist' % entry)
continue
copy_static_entry(entry, path.join(self.outdir, '_static'), self,
ctx, exclude_matchers=matchers)
copy_asset(entry, path.join(self.outdir, '_static'), excluded,
context=ctx, renderer=self.templates)
# copy logo and favicon files if not already in static path
if self.config.html_logo:
logobase = path.basename(self.config.html_logo)
@ -642,14 +649,15 @@ class StandaloneHTMLBuilder(Builder):
def copy_extra_files(self):
# copy html_extra_path files
self.info(bold('copying extra files... '), nonl=True)
extraentries = [path.join(self.confdir, epath)
for epath in self.config.html_extra_path]
matchers = compile_matchers(self.config.exclude_patterns)
for entry in extraentries:
excluded = Matcher(self.config.exclude_patterns)
for extra_path in self.config.html_extra_path:
entry = path.join(self.confdir, extra_path)
if not path.exists(entry):
self.warn('html_extra_path entry %r does not exist' % entry)
continue
copy_extra_entry(entry, self.outdir, matchers)
copy_asset(entry, self.outdir, excluded)
self.info('done')
def write_buildinfo(self):
@ -712,7 +720,12 @@ class StandaloneHTMLBuilder(Builder):
def index_page(self, pagename, doctree, title):
# only index pages with title
if self.indexer is not None and title:
self.indexer.feed(pagename, title, doctree)
filename = self.env.doc2path(pagename, base=None)
try:
self.indexer.feed(pagename, filename, title, doctree)
except TypeError:
# fallback for old search-adapters
self.indexer.feed(pagename, title, doctree)
def _get_local_toctree(self, docname, collapse=True, **kwds):
if 'includehidden' not in kwds:
@ -1056,6 +1069,7 @@ class SerializingHTMLBuilder(StandaloneHTMLBuilder):
self.theme = None # no theme necessary
self.templates = None # no template bridge necessary
self.init_translator_class()
self.init_templates()
self.init_highlighter()
def get_target_uri(self, docname, typ=None):
@ -1148,3 +1162,52 @@ class JSONHTMLBuilder(SerializingHTMLBuilder):
def init(self):
SerializingHTMLBuilder.init(self)
def setup(app):
# builders
app.add_builder(StandaloneHTMLBuilder)
app.add_builder(DirectoryHTMLBuilder)
app.add_builder(SingleFileHTMLBuilder)
app.add_builder(PickleHTMLBuilder)
app.add_builder(JSONHTMLBuilder)
# config values
app.add_config_value('html_theme', 'alabaster', 'html')
app.add_config_value('html_theme_path', [], 'html')
app.add_config_value('html_theme_options', {}, 'html')
app.add_config_value('html_title',
lambda self: l_('%s %s documentation') % (self.project, self.release),
'html', string_classes)
app.add_config_value('html_short_title', lambda self: self.html_title, 'html')
app.add_config_value('html_style', None, 'html', string_classes)
app.add_config_value('html_logo', None, 'html', string_classes)
app.add_config_value('html_favicon', None, 'html', string_classes)
app.add_config_value('html_static_path', [], 'html')
app.add_config_value('html_extra_path', [], 'html')
app.add_config_value('html_last_updated_fmt', None, 'html', string_classes)
app.add_config_value('html_use_smartypants', True, 'html')
app.add_config_value('html_translator_class', None, 'html', string_classes)
app.add_config_value('html_sidebars', {}, 'html')
app.add_config_value('html_additional_pages', {}, 'html')
app.add_config_value('html_use_modindex', True, 'html') # deprecated
app.add_config_value('html_domain_indices', True, 'html', [list])
app.add_config_value('html_add_permalinks', u'\u00B6', 'html')
app.add_config_value('html_use_index', True, 'html')
app.add_config_value('html_split_index', False, 'html')
app.add_config_value('html_copy_source', True, 'html')
app.add_config_value('html_show_sourcelink', True, 'html')
app.add_config_value('html_sourcelink_suffix', '.txt', 'html')
app.add_config_value('html_use_opensearch', '', 'html')
app.add_config_value('html_file_suffix', None, 'html', string_classes)
app.add_config_value('html_link_suffix', None, 'html', string_classes)
app.add_config_value('html_show_copyright', True, 'html')
app.add_config_value('html_show_sphinx', True, 'html')
app.add_config_value('html_context', {}, 'html')
app.add_config_value('html_output_encoding', 'utf-8', 'html')
app.add_config_value('html_compact_lists', True, 'html')
app.add_config_value('html_secnumber_suffix', '. ', 'html')
app.add_config_value('html_search_language', None, 'html', string_classes)
app.add_config_value('html_search_options', {}, 'html')
app.add_config_value('html_search_scorer', '', None)
app.add_config_value('html_scaled_image_link', True, 'html')

View File

@ -18,6 +18,7 @@ from os import path
from docutils import nodes
from sphinx import addnodes
from sphinx.util.osutil import make_filename
from sphinx.builders.html import StandaloneHTMLBuilder
from sphinx.util.pycompat import htmlescape
@ -63,7 +64,7 @@ Binary Index=No
Compiled file=%(outname)s.chm
Contents file=%(outname)s.hhc
Default Window=%(outname)s
Default topic=index.html
Default topic=%(master_doc)s
Display compile progress=No
Full text search stop list file=%(outname)s.stp
Full-text search=Yes
@ -73,7 +74,7 @@ Title=%(title)s
[WINDOWS]
%(outname)s="%(title)s","%(outname)s.hhc","%(outname)s.hhk",\
"index.html","index.html",,,,,0x63520,220,0x10384e,[0,0,1024,768],,,,,,,0
"%(master_doc)s","%(master_doc)s",,,,,0x63520,220,0x10384e,[0,0,1024,768],,,,,,,0
[FILES]
'''
@ -183,6 +184,7 @@ class HTMLHelpBuilder(StandaloneHTMLBuilder):
StandaloneHTMLBuilder.init(self)
# the output files for HTML help must be .html only
self.out_suffix = '.html'
self.link_suffix = '.html'
# determine the correct locale setting
locale = chm_locales.get(self.config.language)
if locale is not None:
@ -204,11 +206,14 @@ class HTMLHelpBuilder(StandaloneHTMLBuilder):
self.info('writing project file...')
with self.open_file(outdir, outname+'.hhp') as f:
f.write(project_template % {'outname': outname,
'title': self.config.html_title,
'version': self.config.version,
'project': self.config.project,
'lcid': self.lcid})
f.write(project_template % {
'outname': outname,
'title': self.config.html_title,
'version': self.config.version,
'project': self.config.project,
'lcid': self.lcid,
'master_doc': self.config.master_doc + self.out_suffix
})
if not outdir.endswith(os.sep):
outdir += os.sep
olen = len(outdir)
@ -225,7 +230,7 @@ class HTMLHelpBuilder(StandaloneHTMLBuilder):
f.write(contents_header)
# special books
f.write('<LI> ' + object_sitemap % (self.config.html_short_title,
'index.html'))
self.config.master_doc + self.out_suffix))
for indexname, indexcls, content, collapse in self.domain_indices:
f.write('<LI> ' + object_sitemap % (indexcls.localname,
'%s.html' % indexname))
@ -292,3 +297,10 @@ class HTMLHelpBuilder(StandaloneHTMLBuilder):
for title, (refs, subitems, key_) in group:
write_index(title, refs, subitems)
f.write('</UL>\n')
def setup(app):
app.setup_extension('sphinx.builders.html')
app.add_builder(HTMLHelpBuilder)
app.add_config_value('htmlhelp_basename', lambda self: make_filename(self.project), None)

View File

@ -11,7 +11,6 @@
import os
from os import path
import warnings
from six import iteritems
from docutils import nodes
@ -19,14 +18,16 @@ from docutils.io import FileOutput
from docutils.utils import new_document
from docutils.frontend import OptionParser
from sphinx import package_dir, addnodes
from sphinx import package_dir, addnodes, highlighting
from sphinx.util import texescape
from sphinx.config import string_classes, ENUM
from sphinx.errors import SphinxError
from sphinx.locale import _
from sphinx.builders import Builder
from sphinx.environment import NoUri
from sphinx.util.nodes import inline_all_toctrees
from sphinx.util.osutil import SEP, copyfile
from sphinx.util.fileutil import copy_asset_file
from sphinx.util.osutil import SEP, make_filename
from sphinx.util.console import bold, darkgreen
from sphinx.writers.latex import LaTeXWriter
@ -38,27 +39,12 @@ class LaTeXBuilder(Builder):
name = 'latex'
format = 'latex'
supported_image_types = ['application/pdf', 'image/png', 'image/jpeg']
usepackages = []
def init(self):
self.docnames = []
self.document_data = []
self.usepackages = []
texescape.init()
self.check_options()
def check_options(self):
if self.config.latex_toplevel_sectioning not in (None, 'part', 'chapter', 'section'):
self.warn('invalid latex_toplevel_sectioning, ignored: %s' %
self.config.latex_top_sectionlevel)
self.config.latex_top_sectionlevel = None
if self.config.latex_use_parts:
warnings.warn('latex_use_parts will be removed at Sphinx-1.5. '
'Use latex_toplevel_sectioning instead.',
DeprecationWarning)
if self.config.latex_toplevel_sectioning:
self.warn('latex_use_parts conflicts with latex_toplevel_sectioning, ignored.')
def get_outdated_docs(self):
return 'all documents' # for now
@ -92,6 +78,16 @@ class LaTeXBuilder(Builder):
docname = docname[:-5]
self.titles.append((docname, entry[2]))
def write_stylesheet(self):
highlighter = highlighting.PygmentsBridge(
'latex', self.config.pygments_style, self.config.trim_doctest_flags)
stylesheet = path.join(self.outdir, 'sphinxhighlight.sty')
with open(stylesheet, 'w') as f:
f.write('\\NeedsTeXFormat{LaTeX2e}[1995/12/01]\n')
f.write('\\ProvidesPackage{sphinxhighlight}'
'[2016/05/29 stylesheet for highlighting with pygments]\n\n')
f.write(highlighter.get_stylesheet())
def write(self, *ignored):
docwriter = LaTeXWriter(self)
docsettings = OptionParser(
@ -100,6 +96,7 @@ class LaTeXBuilder(Builder):
read_config_files=True).get_default_values()
self.init_document_data()
self.write_stylesheet()
for entry in self.document_data:
docname, targetname, title, author, docclass = entry[:5]
@ -192,33 +189,109 @@ class LaTeXBuilder(Builder):
self.info(bold('copying images...'), nonl=1)
for src, dest in iteritems(self.images):
self.info(' '+src, nonl=1)
copyfile(path.join(self.srcdir, src),
path.join(self.outdir, dest))
copy_asset_file(path.join(self.srcdir, src),
path.join(self.outdir, dest))
self.info()
# copy TeX support files from texinputs
context = {'latex_engine': self.config.latex_engine}
self.info(bold('copying TeX support files...'))
staticdirname = path.join(package_dir, 'texinputs')
for filename in os.listdir(staticdirname):
if not filename.startswith('.'):
copyfile(path.join(staticdirname, filename),
path.join(self.outdir, filename))
copy_asset_file(path.join(staticdirname, filename),
self.outdir, context=context)
# copy additional files
if self.config.latex_additional_files:
self.info(bold('copying additional files...'), nonl=1)
for filename in self.config.latex_additional_files:
self.info(' '+filename, nonl=1)
copyfile(path.join(self.confdir, filename),
path.join(self.outdir, path.basename(filename)))
copy_asset_file(path.join(self.confdir, filename), self.outdir)
self.info()
# the logo is handled differently
if self.config.latex_logo:
logobase = path.basename(self.config.latex_logo)
logotarget = path.join(self.outdir, logobase)
if not path.isfile(path.join(self.confdir, self.config.latex_logo)):
raise SphinxError('logo file %r does not exist' % self.config.latex_logo)
elif not path.isfile(logotarget):
copyfile(path.join(self.confdir, self.config.latex_logo), logotarget)
else:
copy_asset_file(path.join(self.confdir, self.config.latex_logo), self.outdir)
self.info('done')
def validate_config_values(app):
if app.config.latex_toplevel_sectioning not in (None, 'part', 'chapter', 'section'):
app.warn('invalid latex_toplevel_sectioning, ignored: %s' %
app.config.latex_toplevel_sectioning)
app.config.latex_toplevel_sectioning = None
if app.config.latex_use_parts:
if app.config.latex_toplevel_sectioning:
app.warn('latex_use_parts conflicts with latex_toplevel_sectioning, ignored.')
else:
app.warn('latex_use_parts is deprecated. Use latex_toplevel_sectioning instead.')
app.config.latex_toplevel_sectioning = 'parts'
if app.config.latex_use_modindex is not True: # changed by user
app.warn('latex_use_modeindex is deprecated. Use latex_domain_indices instead.')
if app.config.latex_preamble:
if app.config.latex_elements.get('preamble'):
app.warn("latex_preamble conflicts with latex_elements['preamble'], ignored.")
else:
app.warn("latex_preamble is deprecated. Use latex_elements['preamble'] instead.")
app.config.latex_elements['preamble'] = app.config.latex_preamble
if app.config.latex_paper_size != 'letter':
if app.config.latex_elements.get('papersize'):
app.warn("latex_paper_size conflicts with latex_elements['papersize'], ignored.")
else:
app.warn("latex_paper_size is deprecated. "
"Use latex_elements['papersize'] instead.")
if app.config.latex_paper_size:
app.config.latex_elements['papersize'] = app.config.latex_paper_size + 'paper'
if app.config.latex_font_size != '10pt':
if app.config.latex_elements.get('pointsize'):
app.warn("latex_font_size conflicts with latex_elements['pointsize'], ignored.")
else:
app.warn("latex_font_size is deprecated. Use latex_elements['pointsize'] instead.")
app.config.latex_elements['pointsize'] = app.config.latex_font_size
def setup(app):
app.add_builder(LaTeXBuilder)
app.connect('builder-inited', validate_config_values)
app.add_config_value('latex_engine',
lambda self: 'pdflatex' if self.language != 'ja' else 'platex',
None,
ENUM('pdflatex', 'xelatex', 'lualatex', 'platex'))
app.add_config_value('latex_documents',
lambda self: [(self.master_doc, make_filename(self.project) + '.tex',
self.project, '', 'manual')],
None)
app.add_config_value('latex_logo', None, None, string_classes)
app.add_config_value('latex_appendices', [], None)
app.add_config_value('latex_keep_old_macro_names', True, None)
# now deprecated - use latex_toplevel_sectioning
app.add_config_value('latex_use_parts', False, None)
app.add_config_value('latex_toplevel_sectioning', None, None, [str])
app.add_config_value('latex_use_modindex', True, None) # deprecated
app.add_config_value('latex_domain_indices', True, None, [list])
app.add_config_value('latex_show_urls', 'no', None)
app.add_config_value('latex_show_pagerefs', False, None)
# paper_size and font_size are still separate values
# so that you can give them easily on the command line
app.add_config_value('latex_paper_size', 'letter', None)
app.add_config_value('latex_font_size', '10pt', None)
app.add_config_value('latex_elements', {}, None)
app.add_config_value('latex_additional_files', [], None)
japanese_default = {'manual': 'jsbook',
'howto': 'jreport'}
app.add_config_value('latex_docclass',
lambda self: japanese_default if self.language == 'ja' else {},
None)
# now deprecated - use latex_elements
app.add_config_value('latex_preamble', '', None)

View File

@ -54,6 +54,13 @@ except pkg_resources.DistributionNotFound:
'install "requests[security]" as a dependency or upgrade to '
'a python version with SNI support (Python 3 and Python 2.7.9+).'
)
except pkg_resources.UnknownExtra:
warnings.warn(
'Some links may return broken results due to being unable to '
'check the Server Name Indication (SNI) in the returned SSL cert '
'against the hostname in the url requested. Recommended to '
'install requests-2.4.1+.'
)
requests_user_agent = [('User-agent', 'Mozilla/5.0 (X11; Linux x86_64; rv:25.0) '
'Gecko/20100101 Firefox/25.0')]
@ -300,3 +307,13 @@ class CheckExternalLinksBuilder(Builder):
def finish(self):
for worker in self.workers:
self.wqueue.put((None, None, None), False)
def setup(app):
app.add_builder(CheckExternalLinksBuilder)
app.add_config_value('linkcheck_ignore', [], None)
app.add_config_value('linkcheck_retries', 1, None)
app.add_config_value('linkcheck_timeout', None, None, [int])
app.add_config_value('linkcheck_workers', 5, None)
app.add_config_value('linkcheck_anchors', True, None)

View File

@ -19,6 +19,7 @@ from sphinx import addnodes
from sphinx.builders import Builder
from sphinx.environment import NoUri
from sphinx.util.nodes import inline_all_toctrees
from sphinx.util.osutil import make_filename
from sphinx.util.console import bold, darkgreen
from sphinx.writers.manpage import ManualPageWriter
@ -88,3 +89,13 @@ class ManualPageBuilder(Builder):
def finish(self):
pass
def setup(app):
app.add_builder(ManualPageBuilder)
app.add_config_value('man_pages',
lambda self: [(self.master_doc, make_filename(self.project).lower(),
'%s %s' % (self.project, self.release), [], 1)],
None)
app.add_config_value('man_show_urls', False, None)

View File

@ -21,6 +21,7 @@ from docutils import nodes
from sphinx import addnodes
from sphinx.builders.html import StandaloneHTMLBuilder
from sphinx.util import force_decode
from sphinx.util.osutil import make_filename
from sphinx.util.pycompat import htmlescape
@ -104,15 +105,25 @@ class QtHelpBuilder(StandaloneHTMLBuilder):
# don't add links
add_permalinks = False
# don't add sidebar etc.
embedded = True
# disable download role
download_support = False
# don't generate the search index or include the search page
search = False
def init(self):
StandaloneHTMLBuilder.init(self)
# the output files for HTML help must be .html only
self.out_suffix = '.html'
self.link_suffix = '.html'
# self.config.html_style = 'traditional.css'
def get_theme_config(self):
return self.config.qthelp_theme, self.config.qthelp_theme_options
def handle_finish(self):
self.build_qhp(self.outdir, self.config.qthelp_basename)
@ -290,3 +301,12 @@ class QtHelpBuilder(StandaloneHTMLBuilder):
keywords.extend(self.build_keywords(subitem[0], subitem[1], []))
return keywords
def setup(app):
app.setup_extension('sphinx.builders.html')
app.add_builder(QtHelpBuilder)
app.add_config_value('qthelp_basename', lambda self: make_filename(self.project), None)
app.add_config_value('qthelp_theme', 'nonav', 'html')
app.add_config_value('qthelp_theme_options', {}, 'html')

View File

@ -22,7 +22,7 @@ from sphinx.locale import _
from sphinx.builders import Builder
from sphinx.environment import NoUri
from sphinx.util.nodes import inline_all_toctrees
from sphinx.util.osutil import SEP, copyfile
from sphinx.util.osutil import SEP, copyfile, make_filename
from sphinx.util.console import bold, darkgreen
from sphinx.writers.texinfo import TexinfoWriter
@ -225,3 +225,20 @@ class TexinfoBuilder(Builder):
except (IOError, OSError) as err:
self.warn("error writing file %s: %s" % (fn, err))
self.info(' done')
def setup(app):
app.add_builder(TexinfoBuilder)
app.add_config_value('texinfo_documents',
lambda self: [(self.master_doc, make_filename(self.project).lower(),
self.project, '', make_filename(self.project),
'The %s reference manual.' %
make_filename(self.project),
'Python')],
None)
app.add_config_value('texinfo_appendices', [], None)
app.add_config_value('texinfo_elements', {}, None)
app.add_config_value('texinfo_domain_indices', True, None, [list])
app.add_config_value('texinfo_show_urls', 'footnote', None)
app.add_config_value('texinfo_no_detailmenu', False, None)

View File

@ -67,3 +67,10 @@ class TextBuilder(Builder):
def finish(self):
pass
def setup(app):
app.add_builder(TextBuilder)
app.add_config_value('text_sectionchars', '*=-~"+`', 'env')
app.add_config_value('text_newlines', 'unix', 'env')

View File

@ -165,3 +165,7 @@ class WebSupportBuilder(PickleHTMLBuilder):
def dump_search_index(self):
self.indexer.finish_indexing()
def setup(app):
app.add_builder(WebSupportBuilder)

View File

@ -95,3 +95,10 @@ class PseudoXMLBuilder(XMLBuilder):
out_suffix = '.pseudoxml'
_writer_class = PseudoXMLWriter
def setup(app):
app.add_builder(XMLBuilder)
app.add_builder(PseudoXMLBuilder)
app.add_config_value('xml_pretty', True, 'env')

View File

@ -10,14 +10,13 @@
"""
import re
from os import path, environ, getenv
import shlex
from os import path, getenv
from six import PY2, PY3, iteritems, string_types, binary_type, text_type, integer_types
from sphinx.errors import ConfigError
from sphinx.locale import l_
from sphinx.util.osutil import make_filename, cd
from sphinx.util.osutil import cd
from sphinx.util.pycompat import execfile_, NoneType
from sphinx.util.i18n import format_date
@ -29,10 +28,25 @@ if PY3:
CONFIG_SYNTAX_ERROR += "\nDid you change the syntax from 2.x to 3.x?"
CONFIG_EXIT_ERROR = "The configuration file (or one of the modules it imports) " \
"called sys.exit()"
CONFIG_ENUM_WARNING = "The config value `{name}` has to be a one of {candidates}, " \
"but `{current}` is given."
CONFIG_TYPE_WARNING = "The config value `{name}' has type `{current.__name__}', " \
"defaults to `{default.__name__}.'"
class ENUM:
"""represents the config value should be a one of candidates.
Example:
app.add_config_value('latex_show_urls', 'no', ENUM('no', 'footnote', 'inline'))
"""
def __init__(self, *candidates):
self.candidates = candidates
def match(self, value):
return value in self.candidates
string_classes = [text_type]
if PY2:
string_classes.append(binary_type) # => [str, unicode]
@ -94,192 +108,12 @@ class Config(object):
'table': l_('Table %s'),
'code-block': l_('Listing %s')},
'env'),
# HTML options
html_theme = ('alabaster', 'html'),
html_theme_path = ([], 'html'),
html_theme_options = ({}, 'html'),
html_title = (lambda self: l_('%s %s documentation') %
(self.project, self.release),
'html', string_classes),
html_short_title = (lambda self: self.html_title, 'html'),
html_style = (None, 'html', string_classes),
html_logo = (None, 'html', string_classes),
html_favicon = (None, 'html', string_classes),
html_static_path = ([], 'html'),
html_extra_path = ([], 'html'),
# the real default is locale-dependent
html_last_updated_fmt = (None, 'html', string_classes),
html_use_smartypants = (True, 'html'),
html_translator_class = (None, 'html', string_classes),
html_sidebars = ({}, 'html'),
html_additional_pages = ({}, 'html'),
html_use_modindex = (True, 'html'), # deprecated
html_domain_indices = (True, 'html', [list]),
html_add_permalinks = (u'\u00B6', 'html'),
html_use_index = (True, 'html'),
html_split_index = (False, 'html'),
html_copy_source = (True, 'html'),
html_show_sourcelink = (True, 'html'),
html_use_opensearch = ('', 'html'),
html_file_suffix = (None, 'html', string_classes),
html_link_suffix = (None, 'html', string_classes),
html_show_copyright = (True, 'html'),
html_show_sphinx = (True, 'html'),
html_context = ({}, 'html'),
html_output_encoding = ('utf-8', 'html'),
html_compact_lists = (True, 'html'),
html_secnumber_suffix = ('. ', 'html'),
html_search_language = (None, 'html', string_classes),
html_search_options = ({}, 'html'),
html_search_scorer = ('', None),
html_scaled_image_link = (True, 'html'),
# HTML help only options
htmlhelp_basename = (lambda self: make_filename(self.project), None),
# Qt help only options
qthelp_basename = (lambda self: make_filename(self.project), None),
# Devhelp only options
devhelp_basename = (lambda self: make_filename(self.project), None),
# Apple help options
applehelp_bundle_name = (lambda self: make_filename(self.project),
'applehelp'),
applehelp_bundle_id = (None, 'applehelp', string_classes),
applehelp_dev_region = ('en-us', 'applehelp'),
applehelp_bundle_version = ('1', 'applehelp'),
applehelp_icon = (None, 'applehelp', string_classes),
applehelp_kb_product = (lambda self: '%s-%s' %
(make_filename(self.project), self.release),
'applehelp'),
applehelp_kb_url = (None, 'applehelp', string_classes),
applehelp_remote_url = (None, 'applehelp', string_classes),
applehelp_index_anchors = (False, 'applehelp', string_classes),
applehelp_min_term_length = (None, 'applehelp', string_classes),
applehelp_stopwords = (lambda self: self.language or 'en', 'applehelp'),
applehelp_locale = (lambda self: self.language or 'en', 'applehelp'),
applehelp_title = (lambda self: self.project + ' Help', 'applehelp'),
applehelp_codesign_identity = (lambda self:
environ.get('CODE_SIGN_IDENTITY', None),
'applehelp'),
applehelp_codesign_flags = (lambda self:
shlex.split(
environ.get('OTHER_CODE_SIGN_FLAGS',
'')),
'applehelp'),
applehelp_indexer_path = ('/usr/bin/hiutil', 'applehelp'),
applehelp_codesign_path = ('/usr/bin/codesign', 'applehelp'),
applehelp_disable_external_tools = (False, None),
# Epub options
epub_basename = (lambda self: make_filename(self.project), None),
epub_theme = ('epub', 'html'),
epub_theme_options = ({}, 'html'),
epub_title = (lambda self: self.html_title, 'html'),
epub3_description = ('', 'epub3', string_classes),
epub_author = ('unknown', 'html'),
epub3_contributor = ('unknown', 'epub3', string_classes),
epub_language = (lambda self: self.language or 'en', 'html'),
epub_publisher = ('unknown', 'html'),
epub_copyright = (lambda self: self.copyright, 'html'),
epub_identifier = ('unknown', 'html'),
epub_scheme = ('unknown', 'html'),
epub_uid = ('unknown', 'env'),
epub_cover = ((), 'env'),
epub_guide = ((), 'env'),
epub_pre_files = ([], 'env'),
epub_post_files = ([], 'env'),
epub_exclude_files = ([], 'env'),
epub_tocdepth = (3, 'env'),
epub_tocdup = (True, 'env'),
epub_tocscope = ('default', 'env'),
epub_fix_images = (False, 'env'),
epub_max_image_width = (0, 'env'),
epub_show_urls = ('inline', 'html'),
epub_use_index = (lambda self: self.html_use_index, 'html'),
epub3_page_progression_direction = ('ltr', 'epub3', string_classes),
# LaTeX options
latex_documents = (lambda self: [(self.master_doc,
make_filename(self.project) + '.tex',
self.project,
'', 'manual')],
None),
latex_logo = (None, None, string_classes),
latex_appendices = ([], None),
# now deprecated - use latex_toplevel_sectioning
latex_use_parts = (False, None),
latex_toplevel_sectioning = (None, None, [str]),
latex_use_modindex = (True, None), # deprecated
latex_domain_indices = (True, None, [list]),
latex_show_urls = ('no', None),
latex_show_pagerefs = (False, None),
# paper_size and font_size are still separate values
# so that you can give them easily on the command line
latex_paper_size = ('letter', None),
latex_font_size = ('10pt', None),
latex_elements = ({}, None),
latex_additional_files = ([], None),
latex_docclass = ({}, None),
# now deprecated - use latex_elements
latex_preamble = ('', None),
# text options
text_sectionchars = ('*=-~"+`', 'env'),
text_newlines = ('unix', 'env'),
# manpage options
man_pages = (lambda self: [(self.master_doc,
make_filename(self.project).lower(),
'%s %s' % (self.project, self.release),
[], 1)],
None),
man_show_urls = (False, None),
# Texinfo options
texinfo_documents = (lambda self: [(self.master_doc,
make_filename(self.project).lower(),
self.project, '',
make_filename(self.project),
'The %s reference manual.' %
make_filename(self.project),
'Python')],
None),
texinfo_appendices = ([], None),
texinfo_elements = ({}, None),
texinfo_domain_indices = (True, None, [list]),
texinfo_show_urls = ('footnote', None),
texinfo_no_detailmenu = (False, None),
# linkcheck options
linkcheck_ignore = ([], None),
linkcheck_retries = (1, None),
linkcheck_timeout = (None, None, [int]),
linkcheck_workers = (5, None),
linkcheck_anchors = (True, None),
# gettext options
gettext_compact = (True, 'gettext'),
gettext_location = (True, 'gettext'),
gettext_uuid = (False, 'gettext'),
gettext_auto_build = (True, 'env'),
gettext_additional_targets = ([], 'env'),
# XML options
xml_pretty = (True, 'env'),
)
def __init__(self, dirname, filename, overrides, tags):
self.overrides = overrides
self.values = Config.config_values.copy()
config = {}
if 'extensions' in overrides: # XXX do we need this?
if isinstance(overrides['extensions'], string_types):
config['extensions'] = overrides.pop('extensions').split(',')
else:
config['extensions'] = overrides.pop('extensions')
if dirname is not None:
config_file = path.join(dirname, filename)
config['__file__'] = config_file
@ -298,6 +132,12 @@ class Config(object):
# these two must be preinitialized because extensions can add their
# own config values
self.setup = config.get('setup', None)
if 'extensions' in overrides:
if isinstance(overrides['extensions'], string_types):
config['extensions'] = overrides.pop('extensions').split(',')
else:
config['extensions'] = overrides.pop('extensions')
self.extensions = config.get('extensions', [])
# correct values of copyright year that are not coherent with
@ -326,19 +166,24 @@ class Config(object):
if default is None and not permitted:
continue # neither inferrable nor expliclitly permitted types
current = self[name]
if type(current) is type(default):
continue
if type(current) in permitted:
continue
if isinstance(permitted, ENUM):
if not permitted.match(current):
warn(CONFIG_ENUM_WARNING.format(
name=name, current=current, candidates=permitted.candidates))
else:
if type(current) is type(default):
continue
if type(current) in permitted:
continue
common_bases = (set(type(current).__bases__ + (type(current),)) &
set(type(default).__bases__))
common_bases.discard(object)
if common_bases:
continue # at least we share a non-trivial base class
common_bases = (set(type(current).__bases__ + (type(current),)) &
set(type(default).__bases__))
common_bases.discard(object)
if common_bases:
continue # at least we share a non-trivial base class
warn(CONFIG_TYPE_WARNING.format(
name=name, current=type(current), default=type(default)))
warn(CONFIG_TYPE_WARNING.format(
name=name, current=type(current), default=type(default)))
def check_unicode(self, warn):
# check all string values for non-ASCII characters in bytestrings,

View File

@ -17,11 +17,6 @@ from docutils.parsers.rst import Directive, directives, roles
from sphinx import addnodes
from sphinx.util.docfields import DocFieldTransformer
# import and register directives
from sphinx.directives.code import * # noqa
from sphinx.directives.other import * # noqa
from sphinx.directives.patches import * # noqa
# RE to strip backslash escapes
nl_escape_re = re.compile(r'\\\n')
@ -216,8 +211,9 @@ class DefaultDomain(Directive):
return []
directives.register_directive('default-role', DefaultRole)
directives.register_directive('default-domain', DefaultDomain)
directives.register_directive('describe', ObjectDescription)
# new, more consistent, name
directives.register_directive('object', ObjectDescription)
def setup(app):
directives.register_directive('default-role', DefaultRole)
directives.register_directive('default-domain', DefaultDomain)
directives.register_directive('describe', ObjectDescription)
# new, more consistent, name
directives.register_directive('object', ObjectDescription)

View File

@ -342,8 +342,9 @@ class LiteralInclude(Directive):
return [retnode]
directives.register_directive('highlight', Highlight)
directives.register_directive('highlightlang', Highlight) # old
directives.register_directive('code-block', CodeBlock)
directives.register_directive('sourcecode', CodeBlock)
directives.register_directive('literalinclude', LiteralInclude)
def setup(app):
directives.register_directive('highlight', Highlight)
directives.register_directive('highlightlang', Highlight) # old
directives.register_directive('code-block', CodeBlock)
directives.register_directive('sourcecode', CodeBlock)
directives.register_directive('literalinclude', LiteralInclude)

View File

@ -405,27 +405,29 @@ class Include(BaseInclude):
return BaseInclude.run(self)
rel_filename, filename = env.relfn2path(self.arguments[0])
self.arguments[0] = filename
env.note_included(filename)
return BaseInclude.run(self)
directives.register_directive('toctree', TocTree)
directives.register_directive('sectionauthor', Author)
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)
directives.register_directive('acks', Acks)
directives.register_directive('hlist', HList)
directives.register_directive('only', Only)
directives.register_directive('include', Include)
def setup(app):
directives.register_directive('toctree', TocTree)
directives.register_directive('sectionauthor', Author)
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)
directives.register_directive('acks', Acks)
directives.register_directive('hlist', HList)
directives.register_directive('only', Only)
directives.register_directive('include', Include)
# register the standard rst class directive under a different name
# only for backwards compatibility now
directives.register_directive('cssclass', Class)
# new standard name when default-domain with "class" is in effect
directives.register_directive('rst-class', Class)
# register the standard rst class directive under a different name
# only for backwards compatibility now
directives.register_directive('cssclass', Class)
# new standard name when default-domain with "class" is in effect
directives.register_directive('rst-class', Class)

View File

@ -35,4 +35,5 @@ class Figure(images.Figure):
return [figure_node]
directives.register_directive('figure', Figure)
def setup(app):
directives.register_directive('figure', Figure)

View File

@ -273,20 +273,3 @@ class Domain(object):
if primary:
return type.lname
return _('%s %s') % (self.label, type.lname)
from sphinx.domains.c import CDomain # noqa
from sphinx.domains.cpp import CPPDomain # noqa
from sphinx.domains.std import StandardDomain # noqa
from sphinx.domains.python import PythonDomain # noqa
from sphinx.domains.javascript import JavaScriptDomain # noqa
from sphinx.domains.rst import ReSTDomain # noqa
BUILTIN_DOMAINS = {
'std': StandardDomain,
'py': PythonDomain,
'c': CDomain,
'cpp': CPPDomain,
'js': JavaScriptDomain,
'rst': ReSTDomain,
}

View File

@ -279,6 +279,9 @@ class CDomain(Domain):
typ, target, node, contnode):
# strip pointer asterisk
target = target.rstrip(' *')
# becase TypedField can generate xrefs
if target in CObject.stopwords:
return contnode
if target not in self.data['objects']:
return None
obj = self.data['objects'][target]
@ -299,3 +302,7 @@ class CDomain(Domain):
def get_objects(self):
for refname, (docname, type) in list(self.data['objects'].items()):
yield (refname, refname, type, docname, 'c.' + refname, 1)
def setup(app):
app.add_domain(CDomain)

View File

@ -553,6 +553,80 @@ def _verify_description_mode(mode):
raise Exception("Description mode '%s' is invalid." % mode)
class ASTCPPAttribute(ASTBase):
def __init__(self, arg):
self.arg = arg
def __unicode__(self):
return "[[" + self.arg + "]]"
def describe_signature(self, signode):
txt = text_type(self)
signode.append(nodes.Text(txt, txt))
class ASTGnuAttribute(ASTBase):
def __init__(self, name, args):
self.name = name
self.args = args
def __unicode__(self):
res = [self.name]
if self.args:
res.append('(')
res.append(text_type(self.args))
res.append(')')
return ''.join(res)
class ASTGnuAttributeList(ASTBase):
def __init__(self, attrs):
self.attrs = attrs
def __unicode__(self):
res = ['__attribute__((']
first = True
for attr in self.attrs:
if not first:
res.append(', ')
first = False
res.append(text_type(attr))
res.append('))')
return ''.join(res)
def describe_signature(self, signode):
txt = text_type(self)
signode.append(nodes.Text(txt, txt))
class ASTIdAttribute(ASTBase):
"""For simple attributes defined by the user."""
def __init__(self, id):
self.id = id
def __unicode__(self):
return self.id
def describe_signature(self, signode):
signode.append(nodes.Text(self.id, self.id))
class ASTParenAttribute(ASTBase):
"""For paren attributes defined by the user."""
def __init__(self, id, arg):
self.id = id
self.arg = arg
def __unicode__(self):
return self.id + '(' + self.arg + ')'
def describe_signature(self, signode):
txt = text_type(self)
signode.append(nodes.Text(txt, txt))
class ASTIdentifier(ASTBase):
def __init__(self, identifier):
assert identifier is not None
@ -1341,7 +1415,7 @@ class ASTParametersQualifiers(ASTBase):
class ASTDeclSpecsSimple(ASTBase):
def __init__(self, storage, threadLocal, inline, virtual, explicit,
constexpr, volatile, const, friend):
constexpr, volatile, const, friend, attrs):
self.storage = storage
self.threadLocal = threadLocal
self.inline = inline
@ -1351,6 +1425,7 @@ class ASTDeclSpecsSimple(ASTBase):
self.volatile = volatile
self.const = const
self.friend = friend
self.attrs = attrs
def mergeWith(self, other):
if not other:
@ -1363,10 +1438,12 @@ class ASTDeclSpecsSimple(ASTBase):
self.constexpr or other.constexpr,
self.volatile or other.volatile,
self.const or other.const,
self.friend or other.friend)
self.friend or other.friend,
self.attrs + other.attrs)
def __unicode__(self):
res = []
res.extend(text_type(attr) for attr in self.attrs)
if self.storage:
res.append(self.storage)
if self.threadLocal:
@ -1392,6 +1469,10 @@ class ASTDeclSpecsSimple(ASTBase):
if len(modifiers) > 0:
modifiers.append(nodes.Text(' '))
modifiers.append(addnodes.desc_annotation(text, text))
for attr in self.attrs:
if len(modifiers) > 0:
modifiers.append(nodes.Text(' '))
modifiers.append(attr.describe_signature(modifiers))
if self.storage:
_add(modifiers, self.storage)
if self.threadLocal:
@ -2062,7 +2143,7 @@ class ASTTypeWithInit(ASTBase):
def get_id_v2(self, objectType=None, symbol=None):
if objectType == 'member':
return symbol.declaration.name.get_id_v2()
return symbol.get_full_nested_name().get_id_v2()
else:
return self.type.get_id_v2()
@ -2780,6 +2861,10 @@ class Symbol(object):
if symbol is None:
# TODO: maybe search without template args
return None
# We have now matched part of a nested name, and need to match more
# so even if we should matchSelf before, we definitely shouldn't
# even more. (see also issue #2666)
matchSelf = False
parentSymbol = symbol
assert False # should have returned in the loop
@ -2825,7 +2910,7 @@ class DefinitionParser(object):
_prefix_keys = ('class', 'struct', 'enum', 'union', 'typename')
def __init__(self, definition, warnEnv):
def __init__(self, definition, warnEnv, config):
self.definition = definition.strip()
self.pos = 0
self.end = len(self.definition)
@ -2833,6 +2918,7 @@ class DefinitionParser(object):
self._previous_state = (0, None)
self.warnEnv = warnEnv
self.config = config
def _make_multi_error(self, errors, header):
if len(errors) == 1:
@ -2901,6 +2987,12 @@ class DefinitionParser(object):
return True
return False
def skip_string_and_ws(self, string):
if self.skip_string(string):
self.skip_ws()
return True
return False
@property
def eof(self):
return self.pos >= self.end
@ -2927,6 +3019,85 @@ class DefinitionParser(object):
if not self.eof:
self.fail('Expected end of definition.')
def _parse_balanced_token_seq(self, end):
# TODO: add handling of string literals and similar
brackets = {'(': ')', '[': ']', '{': '}'}
startPos = self.pos
symbols = []
while not self.eof:
if len(symbols) == 0 and self.current_char in end:
break
if self.current_char in brackets.keys():
symbols.append(brackets[self.current_char])
elif len(symbols) > 0 and self.current_char == symbols[-1]:
symbols.pop()
elif self.current_char in ")]}":
self.fail("Unexpected '%s' in balanced-token-seq." % self.current_char)
self.pos += 1
if self.eof:
self.fail("Could not find end of balanced-token-seq starting at %d."
% startPos)
return self.definition[startPos:self.pos]
def _parse_attribute(self):
self.skip_ws()
# try C++11 style
startPos = self.pos
if self.skip_string_and_ws('['):
if not self.skip_string('['):
self.pos = startPos
else:
# TODO: actually implement the correct grammar
arg = self._parse_balanced_token_seq(end=[']'])
if not self.skip_string_and_ws(']'):
self.fail("Expected ']' in end of attribute.")
if not self.skip_string_and_ws(']'):
self.fail("Expected ']' in end of attribute after [[...]")
return ASTCPPAttribute(arg)
# try GNU style
if self.skip_word_and_ws('__attribute__'):
if not self.skip_string_and_ws('('):
self.fail("Expected '(' after '__attribute__'.")
if not self.skip_string_and_ws('('):
self.fail("Expected '(' after '__attribute__('.")
attrs = []
while 1:
if self.match(_identifier_re):
name = self.matched_text
self.skip_ws()
if self.skip_string_and_ws('('):
self.fail('Parameterized GNU style attribute not yet supported.')
attrs.append(ASTGnuAttribute(name, None))
# TODO: parse arguments for the attribute
if self.skip_string_and_ws(','):
continue
elif self.skip_string_and_ws(')'):
break
else:
self.fail("Expected identifier, ')', or ',' in __attribute__.")
if not self.skip_string_and_ws(')'):
self.fail("Expected ')' after '__attribute__((...)'")
return ASTGnuAttributeList(attrs)
# try the simple id attributes defined by the user
for id in self.config.cpp_id_attributes:
if self.skip_word_and_ws(id):
return ASTIdAttribute(id)
# try the paren attributes defined by the user
for id in self.config.cpp_paren_attributes:
if not self.skip_string_and_ws(id):
continue
if not self.skip_string('('):
self.fail("Expected '(' after user-defined paren-attribute.")
arg = self._parse_balanced_token_seq(end=[')'])
if not self.skip_string(')'):
self.fail("Expected ')' to end user-defined paren-attribute.")
return ASTParenAttribute(id, arg)
return None
def _parse_expression(self, end):
# Stupidly "parse" an expression.
# 'end' should be a list of characters which ends the expression.
@ -3127,10 +3298,9 @@ class DefinitionParser(object):
self.fail('Expected ")" after "..." in '
'parameters_and_qualifiers.')
break
if paramMode == 'function':
arg = self._parse_type_with_init(outer=None, named='single')
else:
arg = self._parse_type(named=False)
# note: it seems that function arguments can always sbe named,
# even in function pointers and similar.
arg = self._parse_type_with_init(outer=None, named='single')
# TODO: parse default parameters # TODO: didn't we just do that?
args.append(ASTFunctinoParameter(arg))
@ -3209,6 +3379,7 @@ class DefinitionParser(object):
volatile = None
const = None
friend = None
attrs = []
while 1: # accept any permutation of a subset of some decl-specs
self.skip_ws()
if not storage:
@ -3262,9 +3433,14 @@ class DefinitionParser(object):
const = self.skip_word('const')
if const:
continue
attr = self._parse_attribute()
if attr:
attrs.append(attr)
continue
break
return ASTDeclSpecsSimple(storage, threadLocal, inline, virtual,
explicit, constexpr, volatile, const, friend)
explicit, constexpr, volatile, const,
friend, attrs)
def _parse_decl_specs(self, outer, typed=True):
if outer:
@ -3921,7 +4097,7 @@ class CPPObject(ObjectDescription):
id_v1 = None
id_v2 = ast.get_id_v2()
# store them in reverse order, so the newest is first
ids = [id_v2, id_v1]
ids = [id_v2, id_v1]
newestId = ids[0]
assert newestId # shouldn't be None
@ -3930,7 +4106,12 @@ class CPPObject(ObjectDescription):
'report as bug (id=%s).' % (text_type(ast), newestId))
name = text_type(ast.symbol.get_full_nested_name()).lstrip(':')
indexText = self.get_index_text(name)
strippedName = name
for prefix in self.env.config.cpp_index_common_prefix:
if name.startswith(prefix):
strippedName = strippedName[len(prefix):]
break
indexText = self.get_index_text(strippedName)
self.indexnode['entries'].append(('single', indexText, newestId, '', None))
if newestId not in self.state.document.ids:
@ -3942,8 +4123,14 @@ class CPPObject(ObjectDescription):
else:
# print("[CPP] non-unique name:", name)
pass
for id in ids:
if id: # is None when the element didn't exist in that version
# always add the newest id
assert newestId
signode['ids'].append(newestId)
# only add compatibility ids when there are no conflicts
for id in ids[1:]:
if not id: # is None when the element didn't exist in that version
continue
if id not in self.state.document.ids:
signode['ids'].append(id)
signode['first'] = (not self.names) # hmm, what is this abound?
self.state.document.note_explicit_target(signode)
@ -3969,7 +4156,7 @@ class CPPObject(ObjectDescription):
self.env.ref_context['cpp:parent_symbol'] = root
parentSymbol = self.env.ref_context['cpp:parent_symbol']
parser = DefinitionParser(sig, self)
parser = DefinitionParser(sig, self, self.env.config)
try:
ast = self.parse_definition(parser)
parser.assert_end()
@ -3996,6 +4183,15 @@ class CPPObject(ObjectDescription):
self.describe_signature(signode, ast)
return ast
def before_content(self):
lastSymbol = self.env.ref_context['cpp:last_symbol']
assert lastSymbol
self.oldParentSymbol = self.env.ref_context['cpp:parent_symbol']
self.env.ref_context['cpp:parent_symbol'] = lastSymbol
def after_content(self):
self.env.ref_context['cpp:parent_symbol'] = self.oldParentSymbol
class CPPTypeObject(CPPObject):
def get_index_text(self, name):
@ -4106,7 +4302,7 @@ class CPPNamespaceObject(Directive):
symbol = rootSymbol
stack = []
else:
parser = DefinitionParser(self.arguments[0], self)
parser = DefinitionParser(self.arguments[0], self, env.config)
try:
ast = parser.parse_namespace_object()
parser.assert_end()
@ -4135,7 +4331,7 @@ class CPPNamespacePushObject(Directive):
env = self.state.document.settings.env
if self.arguments[0].strip() in ('NULL', '0', 'nullptr'):
return
parser = DefinitionParser(self.arguments[0], self)
parser = DefinitionParser(self.arguments[0], self, env.config)
try:
ast = parser.parse_namespace_object()
parser.assert_end()
@ -4285,7 +4481,7 @@ class CPPDomain(Domain):
if emitWarnings:
env.warn_node(msg, node)
warner = Warner()
parser = DefinitionParser(target, warner)
parser = DefinitionParser(target, warner, env.config)
try:
ast = parser.parse_xref_object()
parser.skip_ws()
@ -4315,6 +4511,31 @@ class CPPDomain(Domain):
matchSelf=True)
if s is None or s.declaration is None:
return None, None
if typ.startswith('cpp:'):
typ = typ[4:]
if typ == 'func':
typ = 'function'
declTyp = s.declaration.objectType
def checkType():
if typ == 'any':
return True
if declTyp == 'templateParam':
return True
if typ == 'var' or typ == 'member':
return declTyp in ['var', 'member']
if typ in ['enum', 'enumerator', 'function', 'class']:
return declTyp == typ
if typ == 'type':
return declTyp in ['enum', 'class', 'function', 'type']
print("Type is %s" % typ)
assert False
if not checkType():
warner.warn("cpp:%s targets a %s (%s)."
% (typ, s.declaration.objectType,
s.get_full_nested_name()))
declaration = s.declaration
fullNestedName = s.get_full_nested_name()
name = text_type(fullNestedName).lstrip(':')
@ -4354,3 +4575,10 @@ class CPPDomain(Domain):
docname = symbol.docname
newestId = symbol.declaration.get_newest_id()
yield (name, name, objectType, docname, newestId, 1)
def setup(app):
app.add_domain(CPPDomain)
app.add_config_value("cpp_index_common_prefix", [], 'env')
app.add_config_value("cpp_id_attributes", [], 'env')
app.add_config_value("cpp_paren_attributes", [], 'env')

View File

@ -234,3 +234,7 @@ class JavaScriptDomain(Domain):
for refname, (docname, type) in list(self.data['objects'].items()):
yield refname, refname, type, docname, \
refname.replace('$', '_S_'), 1
def setup(app):
app.add_domain(JavaScriptDomain)

View File

@ -101,11 +101,36 @@ class PyXrefMixin(object):
break
return result
def make_xrefs(self, rolename, domain, target, innernode=nodes.emphasis,
contnode=None):
delims = '(\s*[\[\]\(\),]\s*)'
delims_re = re.compile(delims)
sub_targets = re.split(delims, target)
split_contnode = bool(contnode and contnode.astext() == target)
results = []
for sub_target in sub_targets:
if split_contnode:
contnode = nodes.Text(sub_target)
if delims_re.match(sub_target):
results.append(contnode or innernode(sub_target, sub_target))
else:
results.append(self.make_xref(rolename, domain, sub_target,
innernode, contnode))
return results
class PyField(PyXrefMixin, Field):
pass
class PyGroupedField(PyXrefMixin, GroupedField):
pass
class PyTypedField(PyXrefMixin, TypedField):
pass
@ -130,9 +155,9 @@ class PyObject(ObjectDescription):
names=('var', 'ivar', 'cvar'),
typerolename='obj', typenames=('vartype',),
can_collapse=True),
GroupedField('exceptions', label=l_('Raises'), rolename='exc',
names=('raises', 'raise', 'exception', 'except'),
can_collapse=True),
PyGroupedField('exceptions', label=l_('Raises'), rolename='exc',
names=('raises', 'raise', 'exception', 'except'),
can_collapse=True),
Field('returnvalue', label=l_('Returns'), has_arg=False,
names=('returns', 'return')),
PyField('returntype', label=l_('Return type'), has_arg=False,
@ -771,3 +796,7 @@ class PythonDomain(Domain):
for refname, (docname, type) in iteritems(self.data['objects']):
if type != 'module': # modules are already handled
yield (refname, refname, type, docname, refname, 1)
def setup(app):
app.add_domain(PythonDomain)

View File

@ -156,3 +156,7 @@ class ReSTDomain(Domain):
def get_objects(self):
for (typ, name), docname in iteritems(self.data['objects']):
yield name, name, typ, docname, typ + '-' + name, 1
def setup(app):
app.add_domain(ReSTDomain)

View File

@ -14,7 +14,6 @@ import unicodedata
from six import iteritems
from docutils import nodes
from docutils.nodes import fully_normalize_name
from docutils.parsers.rst import directives
from docutils.statemachine import ViewList
@ -585,106 +584,119 @@ class StandardDomain(Domain):
newnode.append(innernode)
return newnode
def resolve_xref(self, env, fromdocname, builder,
typ, target, node, contnode):
def resolve_xref(self, env, fromdocname, builder, typ, target, node, contnode):
if typ == 'ref':
if node['refexplicit']:
# reference to anonymous label; the reference uses
# the supplied link caption
docname, labelid = self.data['anonlabels'].get(target, ('', ''))
sectname = node.astext()
else:
# reference to named label; the final node will
# contain the section name after the label
docname, labelid, sectname = self.data['labels'].get(target,
('', '', ''))
if not docname:
return None
return self.build_reference_node(fromdocname, builder,
docname, labelid, sectname, 'ref')
resolver = self._resolve_ref_xref
elif typ == 'numref':
resolver = self._resolve_numref_xref
elif typ == 'keyword':
resolver = self._resolve_keyword_xref
elif typ == 'option':
resolver = self._resolve_option_xref
else:
resolver = self._resolve_obj_xref
return resolver(env, fromdocname, builder, typ, target, node, contnode)
def _resolve_ref_xref(self, env, fromdocname, builder, typ, target, node, contnode):
if node['refexplicit']:
# reference to anonymous label; the reference uses
# the supplied link caption
docname, labelid = self.data['anonlabels'].get(target, ('', ''))
if not docname:
return None
sectname = node.astext()
else:
# reference to named label; the final node will
# contain the section name after the label
docname, labelid, sectname = self.data['labels'].get(target,
('', '', ''))
if not docname:
return None
if env.config.numfig is False:
env.warn(fromdocname, 'numfig is disabled. :numref: is ignored.',
lineno=node.line)
return contnode
return self.build_reference_node(fromdocname, builder,
docname, labelid, sectname, 'ref')
target_node = env.get_doctree(docname).ids.get(labelid)
figtype = self.get_figtype(target_node)
if figtype is None:
return None
def _resolve_numref_xref(self, env, fromdocname, builder, typ, target, node, contnode):
docname, labelid = self.data['anonlabels'].get(target, ('', ''))
if not docname:
return None
try:
figure_id = target_node['ids'][0]
fignumber = env.toc_fignumbers[docname][figtype][figure_id]
except (KeyError, IndexError):
# target_node is found, but fignumber is not assigned.
# Maybe it is defined in orphaned document.
env.warn(fromdocname, "no number is assigned for %s: %s" % (figtype, labelid),
lineno=node.line)
return contnode
if env.config.numfig is False:
env.warn_node('numfig is disabled. :numref: is ignored.', node)
return contnode
title = contnode.astext()
if target == fully_normalize_name(title):
target_node = env.get_doctree(docname).ids.get(labelid)
figtype = self.get_figtype(target_node)
if figtype is None:
return None
try:
figure_id = target_node['ids'][0]
fignumber = env.toc_fignumbers[docname][figtype][figure_id]
except (KeyError, IndexError):
# target_node is found, but fignumber is not assigned.
# Maybe it is defined in orphaned document.
env.warn_node("no number is assigned for %s: %s" % (figtype, labelid), node)
return contnode
try:
if node['refexplicit']:
title = contnode.astext()
else:
title = env.config.numfig_format.get(figtype, '')
try:
newtitle = title % '.'.join(map(str, fignumber))
except TypeError:
env.warn(fromdocname, 'invalid numfig_format: %s' % title,
lineno=node.line)
return None
newtitle = title % '.'.join(map(str, fignumber))
except TypeError:
env.warn_node('invalid numfig_format: %s' % title, node)
return None
return self.build_reference_node(fromdocname, builder,
docname, labelid, newtitle, 'numref',
nodeclass=addnodes.number_reference,
title=title)
elif typ == 'keyword':
# keywords are oddballs: they are referenced by named labels
docname, labelid, _ = self.data['labels'].get(target, ('', '', ''))
if not docname:
return None
return make_refnode(builder, fromdocname, docname,
labelid, contnode)
elif typ == 'option':
progname = node.get('std:program')
target = target.strip()
docname, labelid = self.data['progoptions'].get((progname, target), ('', ''))
if not docname:
commands = []
while ws_re.search(target):
subcommand, target = ws_re.split(target, 1)
commands.append(subcommand)
progname = "-".join(commands)
return self.build_reference_node(fromdocname, builder,
docname, labelid, newtitle, 'numref',
nodeclass=addnodes.number_reference,
title=title)
docname, labelid = self.data['progoptions'].get((progname, target),
('', ''))
if docname:
break
else:
return None
def _resolve_keyword_xref(self, env, fromdocname, builder, typ, target, node, contnode):
# keywords are oddballs: they are referenced by named labels
docname, labelid, _ = self.data['labels'].get(target, ('', '', ''))
if not docname:
return None
return make_refnode(builder, fromdocname, docname,
labelid, contnode)
return make_refnode(builder, fromdocname, docname,
labelid, contnode)
else:
objtypes = self.objtypes_for_role(typ) or []
for objtype in objtypes:
if (objtype, target) in self.data['objects']:
docname, labelid = self.data['objects'][objtype, target]
def _resolve_option_xref(self, env, fromdocname, builder, typ, target, node, contnode):
progname = node.get('std:program')
target = target.strip()
docname, labelid = self.data['progoptions'].get((progname, target), ('', ''))
if not docname:
commands = []
while ws_re.search(target):
subcommand, target = ws_re.split(target, 1)
commands.append(subcommand)
progname = "-".join(commands)
docname, labelid = self.data['progoptions'].get((progname, target),
('', ''))
if docname:
break
else:
docname, labelid = '', ''
if not docname:
return None
return make_refnode(builder, fromdocname, docname,
labelid, contnode)
def resolve_any_xref(self, env, fromdocname, builder, target,
node, contnode):
return make_refnode(builder, fromdocname, docname,
labelid, contnode)
def _resolve_obj_xref(self, env, fromdocname, builder, typ, target, node, contnode):
objtypes = self.objtypes_for_role(typ) or []
for objtype in objtypes:
if (objtype, target) in self.data['objects']:
docname, labelid = self.data['objects'][objtype, target]
break
else:
docname, labelid = '', ''
if not docname:
return None
return make_refnode(builder, fromdocname, docname,
labelid, contnode)
def resolve_any_xref(self, env, fromdocname, builder, target, node, contnode):
results = []
ltarget = target.lower() # :ref: lowercases its target automatically
for role in ('ref', 'option'): # do not try "keyword"
@ -755,3 +767,7 @@ class StandardDomain(Domain):
else:
figtype, _ = self.enumerable_nodes.get(node.__class__, (None, None))
return figtype
def setup(app):
app.add_domain(StandardDomain)

View File

@ -17,6 +17,7 @@ import types
import bisect
import codecs
import string
import fnmatch
import unicodedata
from os import path
from glob import glob
@ -75,7 +76,7 @@ default_settings = {
# or changed to properly invalidate pickle files.
#
# NOTE: increase base version by 2 to have distinct numbers for Py2 and 3
ENV_VERSION = 48 + (sys.version_info[0] - 2)
ENV_VERSION = 49 + (sys.version_info[0] - 2)
dummy_reporter = Reporter('', 4, 4)
@ -169,6 +170,7 @@ class BuildEnvironment:
# contains all read docnames
self.dependencies = {} # docname -> set of dependent file
# names, relative to documentation root
self.included = set() # docnames included from other documents
self.reread_always = set() # docnames to re-read unconditionally on
# next build
@ -328,6 +330,20 @@ class BuildEnvironment:
domain.merge_domaindata(docnames, other.domaindata[domainname])
app.emit('env-merge-info', self, docnames, other)
def path2doc(self, filename):
"""Return the docname for the filename if the file is document.
*filename* should be absolute or relative to the source directory.
"""
if filename.startswith(self.srcdir):
filename = filename[len(self.srcdir) + 1:]
for suffix in self.config.source_suffix:
if fnmatch.fnmatch(filename, '*' + suffix):
return filename[:-len(suffix)]
else:
# the file does not have docname
return None
def doc2path(self, docname, base=True, suffix=None):
"""Return the filename for the document name.
@ -387,8 +403,13 @@ class BuildEnvironment:
config.html_extra_path +
['**/_sources', '.#*', '**/.#*', '*.lproj/**']
)
self.found_docs = set(get_matching_docs(
self.srcdir, config.source_suffix, exclude_matchers=matchers))
self.found_docs = set()
for docname in get_matching_docs(self.srcdir, config.source_suffix,
exclude_matchers=matchers):
if os.access(self.doc2path(docname), os.R_OK):
self.found_docs.add(docname)
else:
self.warn(docname, "document not readable. Ignored.")
# add catalog mo file dependency
for docname in self.found_docs:
@ -820,6 +841,15 @@ class BuildEnvironment:
"""
self.dependencies.setdefault(self.docname, set()).add(filename)
def note_included(self, filename):
"""Add *filename* as a included from other document.
This means the document is not orphaned.
*filename* should be absolute or relative to the source directory.
"""
self.included.add(self.path2doc(filename))
def note_reread(self):
"""Add the current document to the list of documents that will
automatically be re-read at the next build.
@ -1413,7 +1443,10 @@ class BuildEnvironment:
# nodes with length 1 don't have any children anyway
if len(toplevel) > 1:
subtrees = toplevel.traverse(addnodes.toctree)
toplevel[1][:] = subtrees
if subtrees:
toplevel[1][:] = subtrees
else:
toplevel.pop(1)
# resolve all sub-toctrees
for subtocnode in toc.traverse(addnodes.toctree):
if not (subtocnode.get('hidden', False) and
@ -1459,6 +1492,9 @@ class BuildEnvironment:
_toctree_add_classes(newnode, 1)
self._toctree_prune(newnode, 1, prune and maxdepth or 0, collapse)
if len(newnode[-1]) == 0: # No titles found
return None
# set the target paths in the toctrees (they are not known at TOC
# generation time)
for refnode in newnode.traverse(nodes.reference):
@ -1488,9 +1524,9 @@ class BuildEnvironment:
typ, target, node, contnode)
# really hardwired reference types
elif typ == 'any':
newnode = self._resolve_any_reference(builder, node, contnode)
newnode = self._resolve_any_reference(builder, refdoc, node, contnode)
elif typ == 'doc':
newnode = self._resolve_doc_reference(builder, node, contnode)
newnode = self._resolve_doc_reference(builder, refdoc, node, contnode)
elif typ == 'citation':
newnode = self._resolve_citation(builder, refdoc, node, contnode)
# no new node found? try the missing-reference event
@ -1538,10 +1574,10 @@ class BuildEnvironment:
msg = '%r reference target not found: %%(target)s' % typ
self.warn_node(msg % {'target': target}, node, type='ref', subtype=typ)
def _resolve_doc_reference(self, builder, node, contnode):
def _resolve_doc_reference(self, builder, refdoc, node, contnode):
# directly reference to document by source name;
# can be absolute or relative
docname = docname_join(node['refdoc'], node['reftarget'])
docname = docname_join(refdoc, node['reftarget'])
if docname in self.all_docs:
if node['refexplicit']:
# reference with explicit title
@ -1551,7 +1587,7 @@ class BuildEnvironment:
innernode = nodes.inline(caption, caption)
innernode['classes'].append('doc')
newnode = nodes.reference('', '', internal=True)
newnode['refuri'] = builder.get_relative_uri(node['refdoc'], docname)
newnode['refuri'] = builder.get_relative_uri(refdoc, docname)
newnode.append(innernode)
return newnode
@ -1574,13 +1610,12 @@ class BuildEnvironment:
# transforms.CitationReference.apply.
del node['ids'][:]
def _resolve_any_reference(self, builder, node, contnode):
def _resolve_any_reference(self, builder, refdoc, node, contnode):
"""Resolve reference generated by the "any" role."""
refdoc = node['refdoc']
target = node['reftarget']
results = []
# first, try resolving as :doc:
doc_ref = self._resolve_doc_reference(builder, node, contnode)
doc_ref = self._resolve_doc_reference(builder, refdoc, node, contnode)
if doc_ref:
results.append(('doc', doc_ref))
# next, do the standard domain (makes this a priority)
@ -1931,6 +1966,9 @@ class BuildEnvironment:
if docname == self.config.master_doc:
# the master file is not included anywhere ;)
continue
if docname in self.included:
# the document is included from other documents
continue
if 'orphan' in self.metadata[docname]:
continue
self.warn(docname, 'document isn\'t included in any toctree')

View File

@ -67,7 +67,10 @@ class PycodeError(Exception):
return res
class SphinxParallelError(Exception):
class SphinxParallelError(SphinxError):
category = 'Sphinx parallel build error'
def __init__(self, orig_exc, traceback):
self.orig_exc = orig_exc
self.traceback = traceback

View File

@ -261,12 +261,13 @@ def format_annotation(annotation):
Displaying complex types from ``typing`` relies on its private API.
"""
if not isinstance(annotation, type):
return repr(annotation)
qualified_name = (annotation.__module__ + '.' + annotation.__qualname__
if annotation else repr(annotation))
if not isinstance(annotation, type):
return repr(annotation)
elif annotation.__module__ == 'builtins':
if annotation.__module__ == 'builtins':
return annotation.__qualname__
elif typing:
if isinstance(annotation, typing.TypeVar):

View File

@ -22,6 +22,7 @@ from six import text_type
from docutils import nodes
import sphinx
from sphinx.locale import _
from sphinx.errors import SphinxError, ExtensionError
from sphinx.util.png import read_png_depth, write_png_depth
from sphinx.util.osutil import ensuredir, ENOENT, cd
@ -253,7 +254,9 @@ def html_visit_displaymath(self, node):
self.body.append(self.starttag(node, 'div', CLASS='math'))
self.body.append('<p>')
if node['number']:
self.body.append('<span class="eqno">(%s)</span>' % node['number'])
self.body.append('<span class="eqno">(%s)' % node['number'])
self.add_permalink_ref(node, _('Permalink to this equation'))
self.body.append('</span>')
if fname is None:
# something failed -- use text-only as a bad substitute
self.body.append('<span class="math">%s</span></p>\n</div>' %

View File

@ -34,7 +34,8 @@ from os import path
import re
from six import iteritems, string_types
from six.moves.urllib import parse, request
from six.moves.urllib import request
from six.moves.urllib.parse import urlsplit, urlunsplit
from docutils import nodes
from docutils.utils import relative_path
@ -105,7 +106,7 @@ def read_inventory_v2(f, uri, join, bufsize=16*1024):
for line in split_lines(read_chunks()):
# be careful to handle names with embedded spaces correctly
m = re.match(r'(?x)(.+?)\s+(\S*:\S*)\s+(\S+)\s+(\S+)\s+(.*)',
m = re.match(r'(?x)(.+?)\s+(\S*:\S*)\s+(-?\d+)\s+(\S+)\s+(.*)',
line.rstrip())
if not m:
continue
@ -145,7 +146,7 @@ def _strip_basic_auth(url):
:rtype: ``tuple``
"""
url_parts = parse.urlsplit(url)
url_parts = urlsplit(url)
username = url_parts.username
password = url_parts.password
frags = list(url_parts)
@ -154,7 +155,7 @@ def _strip_basic_auth(url):
frags[1] = "%s:%s" % (url_parts.hostname, url_parts.port)
else:
frags[1] = url_parts.hostname
url = parse.urlunsplit(frags)
url = urlunsplit(frags)
return (url, username, password)
@ -208,12 +209,12 @@ def _get_safe_url(url):
url, username, _ = _strip_basic_auth(url)
if username is not None:
# case: url contained basic auth creds; obscure password
url_parts = parse.urlsplit(url)
url_parts = urlsplit(url)
safe_netloc = '{0}@{1}'.format(username, url_parts.hostname)
# replace original netloc w/ obscured version
frags = list(url_parts)
frags[1] = safe_netloc
safe_url = parse.urlunsplit(frags)
safe_url = urlunsplit(frags)
return safe_url
@ -237,6 +238,13 @@ def fetch_inventory(app, uri, inv):
'%s: %s' % (inv, err.__class__, err))
return
try:
if hasattr(f, 'geturl'):
newuri = f.geturl()
if newuri.endswith("/" + INVENTORY_FILENAME):
newuri = newuri[:-len(INVENTORY_FILENAME) - 1]
if uri != newuri and uri != newuri + "/":
app.info('intersphinx inventory has moved: %s -> %s' % (uri, newuri))
uri = newuri
line = f.readline().rstrip().decode('utf-8')
try:
if line == '# Sphinx inventory version 1':

View File

@ -13,6 +13,7 @@
from docutils import nodes
import sphinx
from sphinx.locale import _
from sphinx.application import ExtensionError
from sphinx.ext.mathbase import setup_math as mathbase_setup
@ -34,8 +35,9 @@ def html_visit_displaymath(self, node):
if i == 0:
# necessary to e.g. set the id property correctly
if node['number']:
self.body.append('<span class="eqno">(%s)</span>' %
node['number'])
self.body.append('<span class="eqno">(%s)' % node['number'])
self.add_permalink_ref(node, _('Permalink to this equation'))
self.body.append('</span>')
self.body.append(self.starttag(node, 'div', CLASS='math'))
else:
# but only once!

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