Merge branch 'master' into cpp-concepts
18
.travis.yml
@ -13,16 +13,24 @@ python:
|
|||||||
- "pypy"
|
- "pypy"
|
||||||
env:
|
env:
|
||||||
global:
|
global:
|
||||||
- TEST=-v
|
- TEST='-v --with-timer --timer-top-n 25'
|
||||||
matrix:
|
matrix:
|
||||||
- DOCUTILS=0.11
|
- DOCUTILS=0.11
|
||||||
- DOCUTILS=0.12
|
- DOCUTILS=0.12
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
packages:
|
||||||
|
- graphviz
|
||||||
|
- texlive-latex-recommended
|
||||||
|
- texlive-latex-extra
|
||||||
|
- texlive-fonts-recommended
|
||||||
|
- texlive-fonts-extra
|
||||||
install:
|
install:
|
||||||
- pip install -U pip
|
- pip install -U pip setuptools
|
||||||
- pip install docutils==$DOCUTILS
|
- pip install docutils==$DOCUTILS
|
||||||
- pip install -r test-reqs.txt
|
- pip install -r test-reqs.txt
|
||||||
before_script: flake8
|
before_script:
|
||||||
|
- if [[ $TRAVIS_PYTHON_VERSION != '2.6' ]]; then flake8; fi
|
||||||
script:
|
script:
|
||||||
|
- if [[ $TRAVIS_PYTHON_VERSION == '3.5' ]]; then make style-check test-async; fi
|
||||||
- if [[ $TRAVIS_PYTHON_VERSION == '3.5' ]]; then make test-async; fi
|
|
||||||
- if [[ $TRAVIS_PYTHON_VERSION != '3.5' ]]; then make test; fi
|
- if [[ $TRAVIS_PYTHON_VERSION != '3.5' ]]; then make test; fi
|
||||||
|
1
AUTHORS
@ -41,6 +41,7 @@ Other contributors, listed alphabetically, are:
|
|||||||
* Martin Mahner -- nature theme
|
* Martin Mahner -- nature theme
|
||||||
* Will Maier -- directory HTML builder
|
* Will Maier -- directory HTML builder
|
||||||
* Jacob Mason -- websupport library (GSOC project)
|
* Jacob Mason -- websupport library (GSOC project)
|
||||||
|
* Glenn Matthews -- python domain signature improvements
|
||||||
* Roland Meister -- epub builder
|
* Roland Meister -- epub builder
|
||||||
* Ezio Melotti -- collapsible sidebar JavaScript
|
* Ezio Melotti -- collapsible sidebar JavaScript
|
||||||
* Daniel Neuhäuser -- JavaScript domain, Python 3 support (GSOC)
|
* Daniel Neuhäuser -- JavaScript domain, Python 3 support (GSOC)
|
||||||
|
211
CHANGES
@ -4,32 +4,230 @@ Release 1.5 (in development)
|
|||||||
Incompatible changes
|
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`
|
* 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
|
Features added
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
* Add ``:caption:`` option for sphinx.ext.inheritance_diagram.
|
* 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.
|
* #2471: Add config variable for default doctest flags.
|
||||||
* Convert linkcheck builder to requests for better encoding handling
|
* Convert linkcheck builder to requests for better encoding handling
|
||||||
* #2463, #2516: Add keywords of "meta" directive to search index
|
* #2463, #2516: Add keywords of "meta" directive to search index
|
||||||
* ``:maxdepth:`` option of toctree affects ``secnumdepth`` (ref: #2547)
|
* ``:maxdepth:`` option of toctree affects ``secnumdepth`` (ref: #2547)
|
||||||
* #2575: Now ``sphinx.ext.graphviz`` allows ``:align:`` option
|
* #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 concept directive. Thanks to mickk-on-cpp.
|
||||||
* C++, added support for template introduction syntax. Thanks to mickk-on-cpp.
|
* C++, added support for template introduction syntax. Thanks to mickk-on-cpp.
|
||||||
|
|
||||||
Bugs fixed
|
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
|
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
|
Features added
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
@ -64,7 +262,8 @@ Bugs fixed
|
|||||||
* #2397: Setup shorthandoff for turkish documents
|
* #2397: Setup shorthandoff for turkish documents
|
||||||
* #2447: VerbatimBorderColor wrongly used also for captions of PDF
|
* #2447: VerbatimBorderColor wrongly used also for captions of PDF
|
||||||
* #2456: C++, fix crash related to document merging (e.g., singlehtml and Latex builders).
|
* #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
|
* #2476: Omit MathJax markers if :nowrap: is given
|
||||||
* #2465: latex builder fails in case no caption option is provided to toctree directive
|
* #2465: latex builder fails in case no caption option is provided to toctree directive
|
||||||
* Sphinx crashes if self referenced toctree found
|
* Sphinx crashes if self referenced toctree found
|
||||||
@ -100,6 +299,7 @@ Bugs fixed
|
|||||||
* #2581: The search doesn't work if language="es" (spanish)
|
* #2581: The search doesn't work if language="es" (spanish)
|
||||||
* #2382: Adjust spacing after abbreviations on figure numbers in LaTeX writer
|
* #2382: Adjust spacing after abbreviations on figure numbers in LaTeX writer
|
||||||
* #2383: The generated footnote by `latex_show_urls` overflows lines
|
* #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)
|
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.
|
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.
|
To get the old behavior back, add ``highlight_language = "python"`` to conf.py.
|
||||||
* #2329: Refresh environment forcely if source directory has changed.
|
* #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
|
* 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
|
* #2360: Fix numref in LaTeX output is broken
|
||||||
* #2361: Fix additional paragraphs inside the "compound" directive are indented
|
* #2361: Fix additional paragraphs inside the "compound" directive are indented
|
||||||
|
1
EXAMPLES
@ -61,6 +61,7 @@ Documentation using the classic theme
|
|||||||
* Quex: http://quex.sourceforge.net/doc/html/main.html
|
* Quex: http://quex.sourceforge.net/doc/html/main.html
|
||||||
* Ring programming language: http://ring-lang.sourceforge.net/doc/index.html
|
* Ring programming language: http://ring-lang.sourceforge.net/doc/index.html
|
||||||
* Scapy: http://www.secdev.org/projects/scapy/doc/
|
* 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
|
* Segway: http://noble.gs.washington.edu/proj/segway/doc/1.1.0/segway.html
|
||||||
* SimPy: http://simpy.readthedocs.org/en/latest/
|
* SimPy: http://simpy.readthedocs.org/en/latest/
|
||||||
* SymPy: http://docs.sympy.org/
|
* SymPy: http://docs.sympy.org/
|
||||||
|
@ -13,6 +13,7 @@ include sphinx-build.py
|
|||||||
include sphinx-quickstart.py
|
include sphinx-quickstart.py
|
||||||
include sphinx-apidoc.py
|
include sphinx-apidoc.py
|
||||||
|
|
||||||
|
recursive-include sphinx/templates *
|
||||||
recursive-include sphinx/texinputs *
|
recursive-include sphinx/texinputs *
|
||||||
recursive-include sphinx/themes *
|
recursive-include sphinx/themes *
|
||||||
recursive-include sphinx/locale *
|
recursive-include sphinx/locale *
|
||||||
|
12
Makefile
@ -6,10 +6,11 @@ PYTHON ?= python
|
|||||||
DONT_CHECK = -i build -i dist -i sphinx/style/jquery.js \
|
DONT_CHECK = -i build -i dist -i sphinx/style/jquery.js \
|
||||||
-i sphinx/pycode/pgen2 -i sphinx/util/smartypants.py \
|
-i sphinx/pycode/pgen2 -i sphinx/util/smartypants.py \
|
||||||
-i .ropeproject -i doc/_build -i tests/path.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/typing_test_data.py \
|
||||||
-i tests/test_autodoc_py35.py \
|
-i tests/test_autodoc_py35.py \
|
||||||
-i tests/build \
|
-i tests/build \
|
||||||
|
-i tests/roots/test-warnings/undecodable.rst \
|
||||||
-i sphinx/search/da.py \
|
-i sphinx/search/da.py \
|
||||||
-i sphinx/search/de.py \
|
-i sphinx/search/de.py \
|
||||||
-i sphinx/search/en.py \
|
-i sphinx/search/en.py \
|
||||||
@ -33,12 +34,15 @@ all: clean-pyc clean-backupfiles style-check test
|
|||||||
style-check:
|
style-check:
|
||||||
@$(PYTHON) utils/check_sources.py $(DONT_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:
|
clean-pyc:
|
||||||
find . -name '*.pyc' -exec rm -f {} +
|
find . -name '*.pyc' -exec rm -f {} +
|
||||||
find . -name '*.pyo' -exec rm -f {} +
|
find . -name '*.pyo' -exec rm -f {} +
|
||||||
|
|
||||||
|
clean-pycache:
|
||||||
|
find . -name __pycache__ -exec rm -rf {} +
|
||||||
|
|
||||||
clean-patchfiles:
|
clean-patchfiles:
|
||||||
find . -name '*.orig' -exec rm -f {} +
|
find . -name '*.orig' -exec rm -f {} +
|
||||||
find . -name '*.rej' -exec rm -f {} +
|
find . -name '*.rej' -exec rm -f {} +
|
||||||
@ -50,6 +54,10 @@ clean-backupfiles:
|
|||||||
clean-generated:
|
clean-generated:
|
||||||
rm -f utils/*3.py*
|
rm -f utils/*3.py*
|
||||||
|
|
||||||
|
clean-testfiles:
|
||||||
|
rm -rf tests/build
|
||||||
|
rm -rf .tox/
|
||||||
|
|
||||||
pylint:
|
pylint:
|
||||||
@pylint --rcfile utils/pylintrc sphinx
|
@pylint --rcfile utils/pylintrc sphinx
|
||||||
|
|
||||||
|
@ -33,6 +33,12 @@ Install from cloned source as editable::
|
|||||||
pip install -e .
|
pip install -e .
|
||||||
|
|
||||||
|
|
||||||
|
Release signatures
|
||||||
|
==================
|
||||||
|
|
||||||
|
Releases are signed with `498D6B9E <https://pgp.mit.edu/pks/lookup?op=vindex&search=0x102C2C17498D6B9E>`_
|
||||||
|
|
||||||
|
|
||||||
Reading the docs
|
Reading the docs
|
||||||
================
|
================
|
||||||
|
|
||||||
|
BIN
doc/_static/bookcover.png
vendored
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 27 KiB |
BIN
doc/_static/pocoo.png
vendored
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 1.5 KiB |
BIN
doc/_static/sphinx.png
vendored
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 33 KiB |
BIN
doc/_themes/sphinx13/static/bodybg.png
vendored
Before Width: | Height: | Size: 513 B After Width: | Height: | Size: 429 B |
BIN
doc/_themes/sphinx13/static/footerbg.png
vendored
Before Width: | Height: | Size: 220 B After Width: | Height: | Size: 180 B |
BIN
doc/_themes/sphinx13/static/headerbg.png
vendored
Before Width: | Height: | Size: 230 B After Width: | Height: | Size: 189 B |
BIN
doc/_themes/sphinx13/static/listitem.png
vendored
Before Width: | Height: | Size: 207 B After Width: | Height: | Size: 149 B |
BIN
doc/_themes/sphinx13/static/relbg.png
vendored
Before Width: | Height: | Size: 223 B After Width: | Height: | Size: 183 B |
BIN
doc/_themes/sphinx13/static/sphinxheader.png
vendored
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 11 KiB |
@ -47,7 +47,7 @@ epub_fix_images = False
|
|||||||
epub_max_image_width = 0
|
epub_max_image_width = 0
|
||||||
epub_show_urls = 'inline'
|
epub_show_urls = 'inline'
|
||||||
epub_use_index = False
|
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',
|
latex_documents = [('contents', 'sphinx.tex', 'Sphinx Documentation',
|
||||||
'Georg Brandl', 'manual', 1)]
|
'Georg Brandl', 'manual', 1)]
|
||||||
|
@ -56,7 +56,7 @@ General configuration
|
|||||||
|
|
||||||
.. confval:: extensions
|
.. 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.
|
extensions coming with Sphinx (named ``sphinx.ext.*``) or custom ones.
|
||||||
|
|
||||||
Note that you can extend :data:`sys.path` within the conf file if your
|
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
|
.. 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
|
.. confval:: html_use_opensearch
|
||||||
|
|
||||||
If nonempty, an `OpenSearch <http://www.opensearch.org/Home>`_ description file will be
|
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
|
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
|
.. confval:: latex_documents
|
||||||
|
|
||||||
@ -1568,6 +1585,21 @@ These options influence LaTeX output.
|
|||||||
value selected the ``'inline'`` display. For backwards compatibility,
|
value selected the ``'inline'`` display. For backwards compatibility,
|
||||||
``True`` is still accepted.
|
``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
|
.. confval:: latex_elements
|
||||||
|
|
||||||
.. versionadded:: 0.5
|
.. versionadded:: 0.5
|
||||||
@ -1586,6 +1618,15 @@ These options influence LaTeX output.
|
|||||||
``'pointsize'``
|
``'pointsize'``
|
||||||
Point size option of the document class (``'10pt'``, ``'11pt'`` or
|
Point size option of the document class (``'10pt'``, ``'11pt'`` or
|
||||||
``'12pt'``), default ``'10pt'``.
|
``'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'``
|
||||||
"babel" package inclusion, default ``'\\usepackage{babel}'``.
|
"babel" package inclusion, default ``'\\usepackage{babel}'``.
|
||||||
``'fontpkg'``
|
``'fontpkg'``
|
||||||
@ -1608,7 +1649,7 @@ These options influence LaTeX output.
|
|||||||
|
|
||||||
.. versionadded:: 1.4
|
.. versionadded:: 1.4
|
||||||
``'preamble'``
|
``'preamble'``
|
||||||
Additional preamble content, default empty.
|
Additional preamble content, default empty. See :doc:`latex`.
|
||||||
``'figure_align'``
|
``'figure_align'``
|
||||||
Latex figure float alignment, default 'htbp' (here, top, bottom, page).
|
Latex figure float alignment, default 'htbp' (here, top, bottom, page).
|
||||||
Whenever an image doesn't fit into the current page, it will be
|
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.
|
``'\\usepackage[utf8]{inputenc}'`` when using pdflatex.
|
||||||
Otherwise unset.
|
Otherwise unset.
|
||||||
|
|
||||||
.. versionchanged:: 1.5
|
.. versionchanged:: 1.4.3
|
||||||
Previously ``'\\usepackage[utf8]{inputenc}'`` was used for all
|
Previously ``'\\usepackage[utf8]{inputenc}'`` was used for all
|
||||||
compilers.
|
compilers.
|
||||||
``'cmappkg'``
|
``'cmappkg'``
|
||||||
@ -1678,6 +1719,11 @@ These options influence LaTeX output.
|
|||||||
|
|
||||||
.. versionadded:: 1.0
|
.. 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
|
.. confval:: latex_additional_files
|
||||||
|
|
||||||
A list of file names, relative to the configuration directory, to copy to the
|
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
|
constructs ``*``, ``?``, ``[...]`` and ``[!...]`` with the feature that
|
||||||
these all don't match slashes. A double star ``**`` can be used to match
|
these all don't match slashes. A double star ``**`` can be used to match
|
||||||
any sequence of characters *including* slashes.
|
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
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
.. _contents:
|
.. _contents:
|
||||||
|
|
||||||
Sphinx documentation contents
|
Sphinx documentation contents
|
||||||
@ -17,6 +18,7 @@ Sphinx documentation contents
|
|||||||
intl
|
intl
|
||||||
theming
|
theming
|
||||||
templating
|
templating
|
||||||
|
latex
|
||||||
extensions
|
extensions
|
||||||
extdev/index
|
extdev/index
|
||||||
websupport
|
websupport
|
||||||
|
@ -359,6 +359,18 @@ single word, like this::
|
|||||||
:param int priority: The priority of the message, can be a number 1-5
|
: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:
|
.. _python-roles:
|
||||||
|
|
||||||
Cross-referencing Python objects
|
Cross-referencing Python objects
|
||||||
@ -545,10 +557,10 @@ a visibility statement (``public``, ``private`` or ``protected``).
|
|||||||
|
|
||||||
Full and partial template specialisations can be declared::
|
Full and partial template specialisations can be declared::
|
||||||
|
|
||||||
.. cpp::class:: template<> \
|
.. cpp:class:: template<> \
|
||||||
std::array<bool, 256>
|
std::array<bool, 256>
|
||||||
|
|
||||||
.. cpp::class:: template<typename T> \
|
.. cpp:class:: template<typename T> \
|
||||||
std::array<T, 42>
|
std::array<T, 42>
|
||||||
|
|
||||||
|
|
||||||
@ -680,9 +692,9 @@ a visibility statement (``public``, ``private`` or ``protected``).
|
|||||||
|
|
||||||
Describe an enumerator, optionally with its value defined, e.g.,::
|
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
|
.. 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.
|
Currently the lookup only succeed if the template parameter identifiers are equal strings.
|
||||||
|
|
||||||
|
|
||||||
|
Configuration Variables
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
See :ref:`cpp-config`.
|
||||||
|
|
||||||
|
|
||||||
The Standard Domain
|
The Standard Domain
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
|
@ -182,7 +182,7 @@ The doctest extension uses the following configuration values:
|
|||||||
.. confval:: doctest_default_flags
|
.. confval:: doctest_default_flags
|
||||||
|
|
||||||
By default, these options are enabled:
|
By default, these options are enabled:
|
||||||
|
|
||||||
- ``ELLIPSIS``, allowing you to put ellipses in the expected output that
|
- ``ELLIPSIS``, allowing you to put ellipses in the expected output that
|
||||||
match anything in the actual output;
|
match anything in the actual output;
|
||||||
- ``IGNORE_EXCEPTION_DETAIL``, causing everything following the leftmost
|
- ``IGNORE_EXCEPTION_DETAIL``, causing everything following the leftmost
|
||||||
|
@ -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):
|
def module_level_function(param1, param2=None, *args, **kwargs):
|
||||||
"""This is an example of a module level function.
|
"""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
|
of each parameter is required. The type and description of each parameter
|
||||||
is optional, but should be included if not obvious.
|
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,
|
If \*args or \*\*kwargs are accepted,
|
||||||
they should be listed as ``*args`` and ``**kwargs``.
|
they should be listed as ``*args`` and ``**kwargs``.
|
||||||
|
|
||||||
@ -67,7 +97,7 @@ def module_level_function(param1, param2=None, *args, **kwargs):
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
param1 (int): The first parameter.
|
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.
|
Second line of description should be indented.
|
||||||
*args: Variable length argument list.
|
*args: Variable length argument list.
|
||||||
**kwargs: Arbitrary keyword arguments.
|
**kwargs: Arbitrary keyword arguments.
|
||||||
@ -94,10 +124,6 @@ def module_level_function(param1, param2=None, *args, **kwargs):
|
|||||||
that are relevant to the interface.
|
that are relevant to the interface.
|
||||||
ValueError: If `param2` is equal to `param1`.
|
ValueError: If `param2` is equal to `param1`.
|
||||||
|
|
||||||
|
|
||||||
.. _PEP 484:
|
|
||||||
https://www.python.org/dev/peps/pep-0484/
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if param1 == param2:
|
if param1 == param2:
|
||||||
raise ValueError('param1 may not be equal to param2')
|
raise ValueError('param1 may not be equal to param2')
|
||||||
@ -139,7 +165,7 @@ class ExampleError(Exception):
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
msg (str): Human readable string describing the exception.
|
msg (str): Human readable string describing the exception.
|
||||||
code (Optional[int]): Error code.
|
code (:obj:`int`, optional): Error code.
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
msg (str): Human readable string describing the exception.
|
msg (str): Human readable string describing the exception.
|
||||||
@ -163,16 +189,9 @@ class ExampleClass(object):
|
|||||||
Properties created with the ``@property`` decorator should be documented
|
Properties created with the ``@property`` decorator should be documented
|
||||||
in the property's getter method.
|
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:
|
Attributes:
|
||||||
attr1 (str): Description of `attr1`.
|
attr1 (str): Description of `attr1`.
|
||||||
attr2 (Optional[int]): Description of `attr2`.
|
attr2 (:obj:`int`, optional): Description of `attr2`.
|
||||||
|
|
||||||
|
|
||||||
.. _PEP 484:
|
|
||||||
https://www.python.org/dev/peps/pep-0484/
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -190,20 +209,20 @@ class ExampleClass(object):
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
param1 (str): Description of `param1`.
|
param1 (str): Description of `param1`.
|
||||||
param2 (Optional[int]): Description of `param2`. Multiple
|
param2 (:obj:`int`, optional): Description of `param2`. Multiple
|
||||||
lines are supported.
|
lines are supported.
|
||||||
param3 (List[str]): Description of `param3`.
|
param3 (list(str)): Description of `param3`.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self.attr1 = param1
|
self.attr1 = param1
|
||||||
self.attr2 = param2
|
self.attr2 = param2
|
||||||
self.attr3 = param3 #: Doc comment *inline* with attribute
|
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.attr4 = ['attr4']
|
||||||
|
|
||||||
self.attr5 = None
|
self.attr5 = None
|
||||||
"""Optional[str]: Docstring *after* attribute, with type specified."""
|
"""str: Docstring *after* attribute, with type specified."""
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def readonly_property(self):
|
def readonly_property(self):
|
||||||
@ -212,8 +231,8 @@ class ExampleClass(object):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def readwrite_property(self):
|
def readwrite_property(self):
|
||||||
"""List[str]: Properties with both a getter and setter should only
|
"""list(str): Properties with both a getter and setter
|
||||||
be documented in their getter method.
|
should only be documented in their getter method.
|
||||||
|
|
||||||
If the setter method contains notable behavior, it should be
|
If the setter method contains notable behavior, it should be
|
||||||
mentioned here.
|
mentioned here.
|
||||||
|
@ -9,7 +9,9 @@ Example Google Style Python Docstrings
|
|||||||
|
|
||||||
:ref:`example_numpy`
|
: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
|
.. literalinclude:: example_google.py
|
||||||
:language: python
|
:language: python
|
||||||
|
@ -37,6 +37,7 @@ module_level_variable1 : int
|
|||||||
one convention to document module level variables and be consistent
|
one convention to document module level variables and be consistent
|
||||||
with it.
|
with it.
|
||||||
|
|
||||||
|
|
||||||
.. _NumPy Documentation HOWTO:
|
.. _NumPy Documentation HOWTO:
|
||||||
https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt
|
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):
|
def module_level_function(param1, param2=None, *args, **kwargs):
|
||||||
"""This is an example of a module level function.
|
"""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
|
The name of each parameter is required. The type and description of each
|
||||||
parameter is optional, but should be included if not obvious.
|
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,
|
If \*args or \*\*kwargs are accepted,
|
||||||
they should be listed as ``*args`` and ``**kwargs``.
|
they should be listed as ``*args`` and ``**kwargs``.
|
||||||
|
|
||||||
@ -81,7 +125,7 @@ def module_level_function(param1, param2=None, *args, **kwargs):
|
|||||||
----------
|
----------
|
||||||
param1 : int
|
param1 : int
|
||||||
The first parameter.
|
The first parameter.
|
||||||
param2 : Optional[str]
|
param2 : :obj:`str`, optional
|
||||||
The second parameter.
|
The second parameter.
|
||||||
*args
|
*args
|
||||||
Variable length argument list.
|
Variable length argument list.
|
||||||
@ -113,10 +157,6 @@ def module_level_function(param1, param2=None, *args, **kwargs):
|
|||||||
ValueError
|
ValueError
|
||||||
If `param2` is equal to `param1`.
|
If `param2` is equal to `param1`.
|
||||||
|
|
||||||
|
|
||||||
.. _PEP 484:
|
|
||||||
https://www.python.org/dev/peps/pep-0484/
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if param1 == param2:
|
if param1 == param2:
|
||||||
raise ValueError('param1 may not be equal to param2')
|
raise ValueError('param1 may not be equal to param2')
|
||||||
@ -166,7 +206,7 @@ class ExampleError(Exception):
|
|||||||
----------
|
----------
|
||||||
msg : str
|
msg : str
|
||||||
Human readable string describing the exception.
|
Human readable string describing the exception.
|
||||||
code : Optional[int]
|
code : :obj:`int`, optional
|
||||||
Numeric error code.
|
Numeric error code.
|
||||||
|
|
||||||
Attributes
|
Attributes
|
||||||
@ -194,20 +234,13 @@ class ExampleClass(object):
|
|||||||
Properties created with the ``@property`` decorator should be documented
|
Properties created with the ``@property`` decorator should be documented
|
||||||
in the property's getter method.
|
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
|
Attributes
|
||||||
----------
|
----------
|
||||||
attr1 : str
|
attr1 : str
|
||||||
Description of `attr1`.
|
Description of `attr1`.
|
||||||
attr2 : Optional[int]
|
attr2 : :obj:`int`, optional
|
||||||
Description of `attr2`.
|
Description of `attr2`.
|
||||||
|
|
||||||
|
|
||||||
.. _PEP 484:
|
|
||||||
https://www.python.org/dev/peps/pep-0484/
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, param1, param2, param3):
|
def __init__(self, param1, param2, param3):
|
||||||
@ -227,10 +260,10 @@ class ExampleClass(object):
|
|||||||
----------
|
----------
|
||||||
param1 : str
|
param1 : str
|
||||||
Description of `param1`.
|
Description of `param1`.
|
||||||
param2 : List[str]
|
param2 : list(str)
|
||||||
Description of `param2`. Multiple
|
Description of `param2`. Multiple
|
||||||
lines are supported.
|
lines are supported.
|
||||||
param3 : Optional[int]
|
param3 : :obj:`int`, optional
|
||||||
Description of `param3`.
|
Description of `param3`.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@ -238,11 +271,11 @@ class ExampleClass(object):
|
|||||||
self.attr2 = param2
|
self.attr2 = param2
|
||||||
self.attr3 = param3 #: Doc comment *inline* with attribute
|
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.attr4 = ["attr4"]
|
||||||
|
|
||||||
self.attr5 = None
|
self.attr5 = None
|
||||||
"""Optional[str]: Docstring *after* attribute, with type specified."""
|
"""str: Docstring *after* attribute, with type specified."""
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def readonly_property(self):
|
def readonly_property(self):
|
||||||
@ -251,8 +284,8 @@ class ExampleClass(object):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def readwrite_property(self):
|
def readwrite_property(self):
|
||||||
"""List[str]: Properties with both a getter and setter should only
|
"""list(str): Properties with both a getter and setter
|
||||||
be documented in their getter method.
|
should only be documented in their getter method.
|
||||||
|
|
||||||
If the setter method contains notable behavior, it should be
|
If the setter method contains notable behavior, it should be
|
||||||
mentioned here.
|
mentioned here.
|
||||||
|
@ -9,7 +9,9 @@ Example NumPy Style Python Docstrings
|
|||||||
|
|
||||||
:ref:`example_google`
|
: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
|
.. literalinclude:: example_numpy.py
|
||||||
:language: python
|
:language: python
|
||||||
|
@ -40,7 +40,7 @@ It adds this directive:
|
|||||||
included.
|
included.
|
||||||
|
|
||||||
.. versionchanged:: 1.5
|
.. versionchanged:: 1.5
|
||||||
Added ``caption`` option
|
Added ``caption`` option
|
||||||
|
|
||||||
|
|
||||||
New config values are:
|
New config values are:
|
||||||
|
@ -186,11 +186,60 @@ not be mixed. Choose one style for your project and be consistent with it.
|
|||||||
* :ref:`example_google`
|
* :ref:`example_google`
|
||||||
* :ref:`example_numpy`
|
* :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:
|
.. _PEP 484:
|
||||||
https://www.python.org/dev/peps/pep-0484/
|
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
|
Configuration
|
||||||
=============
|
=============
|
||||||
@ -208,6 +257,7 @@ enabled in `conf.py`::
|
|||||||
# Napoleon settings
|
# Napoleon settings
|
||||||
napoleon_google_docstring = True
|
napoleon_google_docstring = True
|
||||||
napoleon_numpy_docstring = True
|
napoleon_numpy_docstring = True
|
||||||
|
napoleon_include_init_with_doc = False
|
||||||
napoleon_include_private_with_doc = False
|
napoleon_include_private_with_doc = False
|
||||||
napoleon_include_special_with_doc = True
|
napoleon_include_special_with_doc = True
|
||||||
napoleon_use_admonition_for_examples = False
|
napoleon_use_admonition_for_examples = False
|
||||||
@ -234,6 +284,23 @@ enabled in `conf.py`::
|
|||||||
True to parse `NumPy style`_ docstrings. False to disable support
|
True to parse `NumPy style`_ docstrings. False to disable support
|
||||||
for NumPy style docstrings. *Defaults to True.*
|
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
|
.. confval:: napoleon_include_private_with_doc
|
||||||
|
|
||||||
True to include private members (like ``_membername``) with docstrings
|
True to include private members (like ``_membername``) with docstrings
|
||||||
|
@ -34,6 +34,13 @@ There is also an additional config value:
|
|||||||
If this is ``True``, :rst:dir:`todo` and :rst:dir:`todolist` produce output,
|
If this is ``True``, :rst:dir:`todo` and :rst:dir:`todolist` produce output,
|
||||||
else they produce nothing. The default is ``False``.
|
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
|
.. confval:: todo_link_only
|
||||||
|
|
||||||
If this is ``True``, :rst:dir:`todolist` produce output without file path and line,
|
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
|
.. 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.
|
||||||
|
@ -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
|
descriptions that leads to the source code of the described object. A link back
|
||||||
from the source to the description will also be inserted.
|
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:
|
There is an additional config value:
|
||||||
|
|
||||||
.. confval:: viewcode_import
|
.. confval:: viewcode_import
|
||||||
@ -34,3 +39,26 @@ There is an additional config value:
|
|||||||
main routine is protected by a ``if __name__ == '__main__'`` condition.
|
main routine is protected by a ``if __name__ == '__main__'`` condition.
|
||||||
|
|
||||||
.. versionadded:: 1.3
|
.. 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.
|
||||||
|
@ -135,7 +135,7 @@ install.
|
|||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
``pip`` has been contained in the Python official installation after version
|
``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
|
Installing Sphinx with pip
|
||||||
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 25 KiB |
151
doc/latex.rst
Normal 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.
|
@ -200,6 +200,12 @@ Referencing downloadable files
|
|||||||
The ``example.py`` file will be copied to the output directory, and a
|
The ``example.py`` file will be copied to the output directory, and a
|
||||||
suitable link generated to it.
|
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
|
Cross-referencing figures by figure number
|
||||||
------------------------------------------
|
------------------------------------------
|
||||||
|
BIN
doc/more.png
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 150 KiB After Width: | Height: | Size: 146 KiB |
@ -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:
|
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
|
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).
|
respected for output channels that support pixels. Other units (like ``pt``
|
||||||
Other units (like ``pt`` for points) will be used for HTML and LaTeX output.
|
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
|
Sphinx extends the standard docutils behavior by allowing an asterisk for the
|
||||||
extension::
|
extension::
|
||||||
@ -386,6 +387,9 @@ Note that image file names should not contain spaces.
|
|||||||
.. versionchanged:: 0.6
|
.. versionchanged:: 0.6
|
||||||
Image paths can now be absolute.
|
Image paths can now be absolute.
|
||||||
|
|
||||||
|
.. versionchanged:: 1.5
|
||||||
|
latex target supports pixels (default is ``96px=1in``).
|
||||||
|
|
||||||
|
|
||||||
Footnotes
|
Footnotes
|
||||||
---------
|
---------
|
||||||
|
BIN
doc/themes/agogo.png
vendored
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 25 KiB |
BIN
doc/themes/alabaster.png
vendored
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 32 KiB |
BIN
doc/themes/bizstyle.png
vendored
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 26 KiB |
BIN
doc/themes/classic.png
vendored
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 39 KiB |
BIN
doc/themes/fullsize/agogo.png
vendored
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 56 KiB |
BIN
doc/themes/fullsize/alabaster.png
vendored
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 39 KiB |
BIN
doc/themes/fullsize/bizstyle.png
vendored
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 73 KiB |
BIN
doc/themes/fullsize/classic.png
vendored
Before Width: | Height: | Size: 77 KiB After Width: | Height: | Size: 71 KiB |
BIN
doc/themes/fullsize/haiku.png
vendored
Before Width: | Height: | Size: 87 KiB After Width: | Height: | Size: 82 KiB |
BIN
doc/themes/fullsize/nature.png
vendored
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 32 KiB |
BIN
doc/themes/fullsize/pyramid.png
vendored
Before Width: | Height: | Size: 105 KiB After Width: | Height: | Size: 100 KiB |
BIN
doc/themes/fullsize/scrolls.png
vendored
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 86 KiB |
BIN
doc/themes/fullsize/sphinx_rtd_theme.png
vendored
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 38 KiB |
BIN
doc/themes/fullsize/sphinxdoc.png
vendored
Before Width: | Height: | Size: 89 KiB After Width: | Height: | Size: 82 KiB |
BIN
doc/themes/fullsize/traditional.png
vendored
Before Width: | Height: | Size: 97 KiB After Width: | Height: | Size: 90 KiB |
BIN
doc/themes/haiku.png
vendored
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 42 KiB |
BIN
doc/themes/nature.png
vendored
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 28 KiB |
BIN
doc/themes/pyramid.png
vendored
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 38 KiB |
BIN
doc/themes/scrolls.png
vendored
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 27 KiB |
BIN
doc/themes/sphinx_rtd_theme.png
vendored
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 28 KiB |
BIN
doc/themes/sphinxdoc.png
vendored
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 30 KiB |
BIN
doc/themes/traditional.png
vendored
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 32 KiB |
@ -81,6 +81,8 @@ that has to return the directory with themes in it::
|
|||||||
Builtin themes
|
Builtin themes
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
|
.. cssclass:: longtable
|
||||||
|
|
||||||
+--------------------+--------------------+
|
+--------------------+--------------------+
|
||||||
| **Theme overview** | |
|
| **Theme overview** | |
|
||||||
+--------------------+--------------------+
|
+--------------------+--------------------+
|
||||||
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
@ -300,12 +300,17 @@ features of intersphinx.
|
|||||||
More topics to be covered
|
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
|
- Static files
|
||||||
- Selecting a theme
|
- :doc:`Selecting a theme <theming>`
|
||||||
- Templating
|
- :ref:`Templating <templating>`
|
||||||
- Using extensions
|
- Using extensions
|
||||||
- Writing extensions
|
- :ref:`Writing extensions <dev-extensions>`
|
||||||
|
|
||||||
|
|
||||||
.. rubric:: Footnotes
|
.. rubric:: Footnotes
|
||||||
|
@ -25,5 +25,5 @@ universal = 1
|
|||||||
|
|
||||||
[flake8]
|
[flake8]
|
||||||
max-line-length=95
|
max-line-length=95
|
||||||
ignore=E113,E116,E221,E226,E241,E251
|
ignore=E113,E116,E221,E226,E241,E251,E901
|
||||||
exclude=ez_setup.py,utils/*,tests/*,build/*,sphinx/search/*,sphinx/pycode/pgen2/*
|
exclude=tests/*,build/*,sphinx/search/*,sphinx/pycode/pgen2/*,doc/ext/example*.py
|
||||||
|
11
setup.py
@ -64,6 +64,7 @@ extras_require = {
|
|||||||
'nose',
|
'nose',
|
||||||
'mock', # it would be better for 'test:python_version in "2.6,2.7"'
|
'mock', # it would be better for 'test:python_version in "2.6,2.7"'
|
||||||
'simplejson', # better: 'test:platform_python_implementation=="PyPy"'
|
'simplejson', # better: 'test:platform_python_implementation=="PyPy"'
|
||||||
|
'html5lib',
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,11 +138,8 @@ else:
|
|||||||
domain + '.js'))
|
domain + '.js'))
|
||||||
|
|
||||||
for js_file, (locale, po_file) in zip(js_files, po_files):
|
for js_file, (locale, po_file) in zip(js_files, po_files):
|
||||||
infile = open(po_file, 'r')
|
with open(po_file, 'r') as infile:
|
||||||
try:
|
|
||||||
catalog = read_po(infile, locale)
|
catalog = read_po(infile, locale)
|
||||||
finally:
|
|
||||||
infile.close()
|
|
||||||
|
|
||||||
if catalog.fuzzy and not self.use_fuzzy:
|
if catalog.fuzzy and not self.use_fuzzy:
|
||||||
continue
|
continue
|
||||||
@ -158,8 +156,7 @@ else:
|
|||||||
msgid = msgid[0]
|
msgid = msgid[0]
|
||||||
jscatalog[msgid] = message.string
|
jscatalog[msgid] = message.string
|
||||||
|
|
||||||
outfile = open(js_file, 'wb')
|
with open(js_file, 'wb') as outfile:
|
||||||
try:
|
|
||||||
outfile.write('Documentation.addTranslations(')
|
outfile.write('Documentation.addTranslations(')
|
||||||
dump(dict(
|
dump(dict(
|
||||||
messages=jscatalog,
|
messages=jscatalog,
|
||||||
@ -167,8 +164,6 @@ else:
|
|||||||
locale=str(catalog.locale)
|
locale=str(catalog.locale)
|
||||||
), outfile, sort_keys=True)
|
), outfile, sort_keys=True)
|
||||||
outfile.write(');')
|
outfile.write(');')
|
||||||
finally:
|
|
||||||
outfile.close()
|
|
||||||
|
|
||||||
cmdclass['compile_catalog'] = compile_catalog_plusjs
|
cmdclass['compile_catalog'] = compile_catalog_plusjs
|
||||||
|
|
||||||
|
@ -32,17 +32,16 @@ from sphinx.roles import XRefRole
|
|||||||
from sphinx.config import Config
|
from sphinx.config import Config
|
||||||
from sphinx.errors import SphinxError, SphinxWarning, ExtensionError, \
|
from sphinx.errors import SphinxError, SphinxWarning, ExtensionError, \
|
||||||
VersionRequirementError, ConfigError
|
VersionRequirementError, ConfigError
|
||||||
from sphinx.domains import ObjType, BUILTIN_DOMAINS
|
from sphinx.domains import ObjType
|
||||||
from sphinx.domains.std import GenericObject, Target, StandardDomain
|
from sphinx.domains.std import GenericObject, Target, StandardDomain
|
||||||
from sphinx.builders import BUILTIN_BUILDERS
|
|
||||||
from sphinx.environment import BuildEnvironment
|
from sphinx.environment import BuildEnvironment
|
||||||
from sphinx.io import SphinxStandaloneReader
|
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 import import_object
|
||||||
from sphinx.util.tags import Tags
|
from sphinx.util.tags import Tags
|
||||||
from sphinx.util.osutil import ENOENT
|
from sphinx.util.osutil import ENOENT
|
||||||
from sphinx.util.logging import is_suppressed_warning
|
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
|
term_width_line
|
||||||
from sphinx.util.i18n import find_catalog_source_files
|
from sphinx.util.i18n import find_catalog_source_files
|
||||||
|
|
||||||
@ -65,10 +64,44 @@ events = {
|
|||||||
'html-page-context': 'pagename, context, doctree or None',
|
'html-page-context': 'pagename, context, doctree or None',
|
||||||
'build-finished': 'exception',
|
'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'
|
CONFIG_FILENAME = 'conf.py'
|
||||||
ENV_PICKLE_FILENAME = 'environment.pickle'
|
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):
|
class Sphinx(object):
|
||||||
|
|
||||||
@ -83,9 +116,9 @@ class Sphinx(object):
|
|||||||
self._additional_source_parsers = {}
|
self._additional_source_parsers = {}
|
||||||
self._listeners = {}
|
self._listeners = {}
|
||||||
self._setting_up_extension = ['?']
|
self._setting_up_extension = ['?']
|
||||||
self.domains = BUILTIN_DOMAINS.copy()
|
self.domains = {}
|
||||||
self.buildername = buildername
|
self.buildername = buildername
|
||||||
self.builderclasses = BUILTIN_BUILDERS.copy()
|
self.builderclasses = {}
|
||||||
self.builder = None
|
self.builder = None
|
||||||
self.env = None
|
self.env = None
|
||||||
self.enumerable_nodes = {}
|
self.enumerable_nodes = {}
|
||||||
@ -148,6 +181,10 @@ class Sphinx(object):
|
|||||||
if self.confdir is None:
|
if self.confdir is None:
|
||||||
self.confdir = self.srcdir
|
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
|
# extension loading support for alabaster theme
|
||||||
# self.config.html_theme is not set from conf.py at here
|
# self.config.html_theme is not set from conf.py at here
|
||||||
# for now, sphinx always load a 'alabaster' extension.
|
# for now, sphinx always load a 'alabaster' extension.
|
||||||
@ -188,6 +225,10 @@ class Sphinx(object):
|
|||||||
'version %s and therefore cannot be built with the '
|
'version %s and therefore cannot be built with the '
|
||||||
'loaded version (%s).' % (extname, needs_ver, has_ver))
|
'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
|
# set up translation infrastructure
|
||||||
self._init_i18n()
|
self._init_i18n()
|
||||||
# check all configuration values for permissible types
|
# check all configuration values for permissible types
|
||||||
@ -235,8 +276,8 @@ class Sphinx(object):
|
|||||||
|
|
||||||
def _init_env(self, freshenv):
|
def _init_env(self, freshenv):
|
||||||
if freshenv:
|
if freshenv:
|
||||||
self.env = BuildEnvironment(self.srcdir, self.doctreedir,
|
self.env = BuildEnvironment(self.srcdir, self.doctreedir, self.config)
|
||||||
self.config)
|
self.env.set_warnfunc(self.warn)
|
||||||
self.env.find_files(self.config)
|
self.env.find_files(self.config)
|
||||||
for domain in self.domains.keys():
|
for domain in self.domains.keys():
|
||||||
self.env.domains[domain] = self.domains[domain](self.env)
|
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.info(bold('loading pickled environment... '), nonl=True)
|
||||||
self.env = BuildEnvironment.frompickle(
|
self.env = BuildEnvironment.frompickle(
|
||||||
self.srcdir, self.config, path.join(self.doctreedir, ENV_PICKLE_FILENAME))
|
self.srcdir, self.config, path.join(self.doctreedir, ENV_PICKLE_FILENAME))
|
||||||
|
self.env.set_warnfunc(self.warn)
|
||||||
self.env.domains = {}
|
self.env.domains = {}
|
||||||
for domain in self.domains.keys():
|
for domain in self.domains.keys():
|
||||||
# this can raise if the data version doesn't fit
|
# this can raise if the data version doesn't fit
|
||||||
@ -257,8 +299,6 @@ class Sphinx(object):
|
|||||||
self.info('failed: %s' % err)
|
self.info('failed: %s' % err)
|
||||||
return self._init_env(freshenv=True)
|
return self._init_env(freshenv=True)
|
||||||
|
|
||||||
self.env.set_warnfunc(self.warn)
|
|
||||||
|
|
||||||
def _init_builder(self, buildername):
|
def _init_builder(self, buildername):
|
||||||
if buildername is None:
|
if buildername is None:
|
||||||
print('No builder selected, using default: html', file=self._status)
|
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)
|
raise SphinxError('Builder name %s not registered' % buildername)
|
||||||
|
|
||||||
builderclass = self.builderclasses[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.builder = builderclass(self)
|
||||||
self.emit('builder-inited')
|
self.emit('builder-inited')
|
||||||
|
|
||||||
@ -326,7 +361,8 @@ class Sphinx(object):
|
|||||||
wfile.flush()
|
wfile.flush()
|
||||||
self.messagelog.append(message)
|
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.
|
"""Emit a warning.
|
||||||
|
|
||||||
If *location* is given, it should either be a tuple of (docname, lineno)
|
If *location* is given, it should either be a tuple of (docname, lineno)
|
||||||
@ -356,7 +392,7 @@ class Sphinx(object):
|
|||||||
if self.warningiserror:
|
if self.warningiserror:
|
||||||
raise SphinxWarning(warntext)
|
raise SphinxWarning(warntext)
|
||||||
self._warncount += 1
|
self._warncount += 1
|
||||||
self._log(warntext, self._warning, True)
|
self._log(colorfunc(warntext), self._warning, True)
|
||||||
|
|
||||||
def info(self, message='', nonl=False):
|
def info(self, message='', nonl=False):
|
||||||
"""Emit an informational message.
|
"""Emit an informational message.
|
||||||
@ -460,6 +496,11 @@ class Sphinx(object):
|
|||||||
self.debug('[app] setting up extension: %r', extension)
|
self.debug('[app] setting up extension: %r', extension)
|
||||||
if extension in self._extensions:
|
if extension in self._extensions:
|
||||||
return
|
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)
|
self._setting_up_extension.append(extension)
|
||||||
try:
|
try:
|
||||||
mod = __import__(extension, None, None, ['setup'])
|
mod = __import__(extension, None, None, ['setup'])
|
||||||
@ -557,13 +598,9 @@ class Sphinx(object):
|
|||||||
raise ExtensionError('Builder class %s has no "name" attribute'
|
raise ExtensionError('Builder class %s has no "name" attribute'
|
||||||
% builder)
|
% builder)
|
||||||
if builder.name in self.builderclasses:
|
if builder.name in self.builderclasses:
|
||||||
if isinstance(self.builderclasses[builder.name], tuple):
|
raise ExtensionError(
|
||||||
raise ExtensionError('Builder %r is a builtin builder' %
|
'Builder %r already exists (in module %s)' % (
|
||||||
builder.name)
|
builder.name, self.builderclasses[builder.name].__module__))
|
||||||
else:
|
|
||||||
raise ExtensionError(
|
|
||||||
'Builder %r already exists (in module %s)' % (
|
|
||||||
builder.name, self.builderclasses[builder.name].__module__))
|
|
||||||
self.builderclasses[builder.name] = builder
|
self.builderclasses[builder.name] = builder
|
||||||
|
|
||||||
def add_config_value(self, name, default, rebuild, types=()):
|
def add_config_value(self, name, default, rebuild, types=()):
|
||||||
@ -764,8 +801,7 @@ class Sphinx(object):
|
|||||||
|
|
||||||
def add_latex_package(self, packagename, options=None):
|
def add_latex_package(self, packagename, options=None):
|
||||||
self.debug('[app] adding latex package: %r', packagename)
|
self.debug('[app] adding latex package: %r', packagename)
|
||||||
from sphinx.builders.latex import LaTeXBuilder
|
self.builder.usepackages.append((packagename, options))
|
||||||
LaTeXBuilder.usepackages.append((packagename, options))
|
|
||||||
|
|
||||||
def add_lexer(self, alias, lexer):
|
def add_lexer(self, alias, lexer):
|
||||||
self.debug('[app] adding lexer: %r', (alias, lexer))
|
self.debug('[app] adding lexer: %r', (alias, lexer))
|
||||||
|
@ -451,29 +451,3 @@ class Builder(object):
|
|||||||
except AttributeError:
|
except AttributeError:
|
||||||
optname = '%s_%s' % (default, option)
|
optname = '%s_%s' % (default, option)
|
||||||
return getattr(self.config, optname)
|
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'),
|
|
||||||
}
|
|
||||||
|
@ -13,14 +13,16 @@ from __future__ import print_function
|
|||||||
import codecs
|
import codecs
|
||||||
import pipes
|
import pipes
|
||||||
|
|
||||||
from os import path
|
from os import path, environ
|
||||||
|
import shlex
|
||||||
|
|
||||||
from sphinx.builders.html import StandaloneHTMLBuilder
|
from sphinx.builders.html import StandaloneHTMLBuilder
|
||||||
from sphinx.util import copy_static_entry
|
from sphinx.config import string_classes
|
||||||
from sphinx.util.osutil import copyfile, ensuredir
|
from sphinx.util.osutil import copyfile, ensuredir, make_filename
|
||||||
from sphinx.util.console import bold
|
from sphinx.util.console import bold
|
||||||
|
from sphinx.util.fileutil import copy_asset
|
||||||
from sphinx.util.pycompat import htmlescape
|
from sphinx.util.pycompat import htmlescape
|
||||||
from sphinx.util.matching import compile_matchers
|
from sphinx.util.matching import Matcher
|
||||||
from sphinx.errors import SphinxError
|
from sphinx.errors import SphinxError
|
||||||
|
|
||||||
import plistlib
|
import plistlib
|
||||||
@ -84,6 +86,7 @@ class AppleHelpBuilder(StandaloneHTMLBuilder):
|
|||||||
super(AppleHelpBuilder, self).init()
|
super(AppleHelpBuilder, self).init()
|
||||||
# the output files for HTML help must be .html only
|
# the output files for HTML help must be .html only
|
||||||
self.out_suffix = '.html'
|
self.out_suffix = '.html'
|
||||||
|
self.link_suffix = '.html'
|
||||||
|
|
||||||
if self.config.applehelp_bundle_id is None:
|
if self.config.applehelp_bundle_id is None:
|
||||||
raise SphinxError('You must set applehelp_bundle_id before '
|
raise SphinxError('You must set applehelp_bundle_id before '
|
||||||
@ -104,17 +107,15 @@ class AppleHelpBuilder(StandaloneHTMLBuilder):
|
|||||||
self.finish_tasks.add_task(self.build_helpbook)
|
self.finish_tasks.add_task(self.build_helpbook)
|
||||||
|
|
||||||
def copy_localized_files(self):
|
def copy_localized_files(self):
|
||||||
source_dir = path.join(self.confdir,
|
source_dir = path.join(self.confdir, self.config.applehelp_locale + '.lproj')
|
||||||
self.config.applehelp_locale + '.lproj')
|
|
||||||
target_dir = self.outdir
|
target_dir = self.outdir
|
||||||
|
|
||||||
if path.isdir(source_dir):
|
if path.isdir(source_dir):
|
||||||
self.info(bold('copying localized files... '), nonl=True)
|
self.info(bold('copying localized files... '), nonl=True)
|
||||||
|
|
||||||
ctx = self.globalcontext.copy()
|
excluded = Matcher(self.config.exclude_patterns + ['**/.*'])
|
||||||
matchers = compile_matchers(self.config.exclude_patterns)
|
copy_asset(source_dir, target_dir, excluded,
|
||||||
copy_static_entry(source_dir, target_dir, self, ctx,
|
context=self.globalcontext, renderer=self.templates)
|
||||||
exclude_matchers=matchers)
|
|
||||||
|
|
||||||
self.info('done')
|
self.info('done')
|
||||||
|
|
||||||
@ -213,16 +214,19 @@ class AppleHelpBuilder(StandaloneHTMLBuilder):
|
|||||||
self.warn('you will need to index this help book with:\n %s'
|
self.warn('you will need to index this help book with:\n %s'
|
||||||
% (' '.join([pipes.quote(arg) for arg in args])))
|
% (' '.join([pipes.quote(arg) for arg in args])))
|
||||||
else:
|
else:
|
||||||
p = subprocess.Popen(args,
|
try:
|
||||||
stdout=subprocess.PIPE,
|
p = subprocess.Popen(args,
|
||||||
stderr=subprocess.STDOUT)
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.STDOUT)
|
||||||
|
|
||||||
output = p.communicate()[0]
|
output = p.communicate()[0]
|
||||||
|
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
raise AppleHelpIndexerFailed(output)
|
raise AppleHelpIndexerFailed(output)
|
||||||
else:
|
else:
|
||||||
self.info('done')
|
self.info('done')
|
||||||
|
except OSError:
|
||||||
|
raise AppleHelpIndexerFailed('Command not found: %s' % args[0])
|
||||||
|
|
||||||
# If we've been asked to, sign the bundle
|
# If we've been asked to, sign the bundle
|
||||||
if self.config.applehelp_codesign_identity:
|
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'
|
self.warn('you will need to sign this help book with:\n %s'
|
||||||
% (' '.join([pipes.quote(arg) for arg in args])))
|
% (' '.join([pipes.quote(arg) for arg in args])))
|
||||||
else:
|
else:
|
||||||
p = subprocess.Popen(args,
|
try:
|
||||||
stdout=subprocess.PIPE,
|
p = subprocess.Popen(args,
|
||||||
stderr=subprocess.STDOUT)
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.STDOUT)
|
||||||
|
|
||||||
output = p.communicate()[0]
|
output = p.communicate()[0]
|
||||||
|
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
raise AppleHelpCodeSigningFailed(output)
|
raise AppleHelpCodeSigningFailed(output)
|
||||||
else:
|
else:
|
||||||
self.info('done')
|
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)
|
||||||
|
@ -15,12 +15,12 @@ from os import path
|
|||||||
from six import iteritems
|
from six import iteritems
|
||||||
|
|
||||||
from sphinx import package_dir
|
from sphinx import package_dir
|
||||||
from sphinx.util import copy_static_entry
|
|
||||||
from sphinx.locale import _
|
from sphinx.locale import _
|
||||||
from sphinx.theming import Theme
|
from sphinx.theming import Theme
|
||||||
from sphinx.builders import Builder
|
from sphinx.builders import Builder
|
||||||
from sphinx.util.osutil import ensuredir, os_path
|
from sphinx.util.osutil import ensuredir, os_path
|
||||||
from sphinx.util.console import bold
|
from sphinx.util.console import bold
|
||||||
|
from sphinx.util.fileutil import copy_asset_file
|
||||||
from sphinx.util.pycompat import htmlescape
|
from sphinx.util.pycompat import htmlescape
|
||||||
|
|
||||||
|
|
||||||
@ -138,12 +138,10 @@ class ChangesBuilder(Builder):
|
|||||||
f.write(self.templates.render('changes/rstsource.html', ctx))
|
f.write(self.templates.render('changes/rstsource.html', ctx))
|
||||||
themectx = dict(('theme_' + key, val) for (key, val) in
|
themectx = dict(('theme_' + key, val) for (key, val) in
|
||||||
iteritems(self.theme.get_options({})))
|
iteritems(self.theme.get_options({})))
|
||||||
copy_static_entry(path.join(package_dir, 'themes', 'default',
|
copy_asset_file(path.join(package_dir, 'themes', 'default', 'static', 'default.css_t'),
|
||||||
'static', 'default.css_t'),
|
self.outdir, context=themectx, renderer=self.templates)
|
||||||
self.outdir, self, themectx)
|
copy_asset_file(path.join(package_dir, 'themes', 'basic', 'static', 'basic.css'),
|
||||||
copy_static_entry(path.join(package_dir, 'themes', 'basic',
|
self.outdir)
|
||||||
'static', 'basic.css'),
|
|
||||||
self.outdir, self)
|
|
||||||
|
|
||||||
def hl(self, text, version):
|
def hl(self, text, version):
|
||||||
text = htmlescape(text)
|
text = htmlescape(text)
|
||||||
@ -154,3 +152,7 @@ class ChangesBuilder(Builder):
|
|||||||
|
|
||||||
def finish(self):
|
def finish(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def setup(app):
|
||||||
|
app.add_builder(ChangesBuilder)
|
||||||
|
@ -18,6 +18,7 @@ from os import path
|
|||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
|
|
||||||
from sphinx import addnodes
|
from sphinx import addnodes
|
||||||
|
from sphinx.util.osutil import make_filename
|
||||||
from sphinx.builders.html import StandaloneHTMLBuilder
|
from sphinx.builders.html import StandaloneHTMLBuilder
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -59,6 +60,7 @@ class DevhelpBuilder(StandaloneHTMLBuilder):
|
|||||||
def init(self):
|
def init(self):
|
||||||
StandaloneHTMLBuilder.init(self)
|
StandaloneHTMLBuilder.init(self)
|
||||||
self.out_suffix = '.html'
|
self.out_suffix = '.html'
|
||||||
|
self.link_suffix = '.html'
|
||||||
|
|
||||||
def handle_finish(self):
|
def handle_finish(self):
|
||||||
self.build_devhelp(self.outdir, self.config.devhelp_basename)
|
self.build_devhelp(self.outdir, self.config.devhelp_basename)
|
||||||
@ -129,3 +131,10 @@ class DevhelpBuilder(StandaloneHTMLBuilder):
|
|||||||
# Dump the XML file
|
# Dump the XML file
|
||||||
with comp_open(path.join(outdir, outname + '.devhelp'), 'w') as f:
|
with comp_open(path.join(outdir, outname + '.devhelp'), 'w') as f:
|
||||||
tree.write(f, 'utf-8')
|
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)
|
||||||
|
@ -34,3 +34,7 @@ class DummyBuilder(Builder):
|
|||||||
|
|
||||||
def finish(self):
|
def finish(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def setup(app):
|
||||||
|
app.add_builder(DummyBuilder)
|
||||||
|
@ -29,7 +29,7 @@ from docutils import nodes
|
|||||||
from sphinx import addnodes
|
from sphinx import addnodes
|
||||||
from sphinx.builders.html import StandaloneHTMLBuilder
|
from sphinx.builders.html import StandaloneHTMLBuilder
|
||||||
from sphinx.util.i18n import format_date
|
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.smartypants import sphinx_smarty_pants as ssp
|
||||||
from sphinx.util.console import brown
|
from sphinx.util.console import brown
|
||||||
|
|
||||||
@ -113,7 +113,7 @@ COVER_TEMPLATE = u'''\
|
|||||||
<meta name="cover" content="%(cover)s"/>
|
<meta name="cover" content="%(cover)s"/>
|
||||||
'''
|
'''
|
||||||
|
|
||||||
COVERPAGE_NAME = u'epub-cover.html'
|
COVERPAGE_NAME = u'epub-cover.xhtml'
|
||||||
|
|
||||||
FILE_TEMPLATE = u'''\
|
FILE_TEMPLATE = u'''\
|
||||||
<item id="%(id)s"
|
<item id="%(id)s"
|
||||||
@ -128,6 +128,10 @@ GUIDE_TEMPLATE = u'''\
|
|||||||
|
|
||||||
TOCTREE_TEMPLATE = u'toctree-l%d'
|
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]'
|
LINK_TARGET_TEMPLATE = u' [%(uri)s]'
|
||||||
|
|
||||||
FOOTNOTE_LABEL_TEMPLATE = u'#%d'
|
FOOTNOTE_LABEL_TEMPLATE = u'#%d'
|
||||||
@ -143,7 +147,7 @@ GUIDE_TITLES = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MEDIA_TYPES = {
|
MEDIA_TYPES = {
|
||||||
'.html': 'application/xhtml+xml',
|
'.xhtml': 'application/xhtml+xml',
|
||||||
'.css': 'text/css',
|
'.css': 'text/css',
|
||||||
'.png': 'image/png',
|
'.png': 'image/png',
|
||||||
'.gif': 'image/gif',
|
'.gif': 'image/gif',
|
||||||
@ -152,6 +156,7 @@ MEDIA_TYPES = {
|
|||||||
'.jpeg': 'image/jpeg',
|
'.jpeg': 'image/jpeg',
|
||||||
'.otf': 'application/x-font-otf',
|
'.otf': 'application/x-font-otf',
|
||||||
'.ttf': 'application/x-font-ttf',
|
'.ttf': 'application/x-font-ttf',
|
||||||
|
'.woff': 'application/font-woff',
|
||||||
}
|
}
|
||||||
|
|
||||||
VECTOR_GRAPHICS_EXTENSIONS = ('.svg',)
|
VECTOR_GRAPHICS_EXTENSIONS = ('.svg',)
|
||||||
@ -183,6 +188,11 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
add_permalinks = False
|
add_permalinks = False
|
||||||
# don't add sidebar etc.
|
# don't add sidebar etc.
|
||||||
embedded = True
|
embedded = True
|
||||||
|
# disable download role
|
||||||
|
download_support = False
|
||||||
|
|
||||||
|
# don't generate search index or include search page
|
||||||
|
search = False
|
||||||
|
|
||||||
mimetype_template = MIMETYPE_TEMPLATE
|
mimetype_template = MIMETYPE_TEMPLATE
|
||||||
container_template = CONTAINER_TEMPLATE
|
container_template = CONTAINER_TEMPLATE
|
||||||
@ -197,6 +207,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
spine_template = SPINE_TEMPLATE
|
spine_template = SPINE_TEMPLATE
|
||||||
guide_template = GUIDE_TEMPLATE
|
guide_template = GUIDE_TEMPLATE
|
||||||
toctree_template = TOCTREE_TEMPLATE
|
toctree_template = TOCTREE_TEMPLATE
|
||||||
|
doctype = DOCTYPE
|
||||||
link_target_template = LINK_TARGET_TEMPLATE
|
link_target_template = LINK_TARGET_TEMPLATE
|
||||||
css_link_target_class = CSS_LINK_TARGET_CLASS
|
css_link_target_class = CSS_LINK_TARGET_CLASS
|
||||||
guide_titles = GUIDE_TITLES
|
guide_titles = GUIDE_TITLES
|
||||||
@ -206,7 +217,8 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
def init(self):
|
def init(self):
|
||||||
StandaloneHTMLBuilder.init(self)
|
StandaloneHTMLBuilder.init(self)
|
||||||
# the output files for epub must be .html only
|
# 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.playorder = 0
|
||||||
self.tocid = 0
|
self.tocid = 0
|
||||||
|
|
||||||
@ -276,7 +288,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
"""
|
"""
|
||||||
refnodes.insert(0, {
|
refnodes.insert(0, {
|
||||||
'level': 1,
|
'level': 1,
|
||||||
'refuri': self.esc(self.config.master_doc + '.html'),
|
'refuri': self.esc(self.config.master_doc + self.out_suffix),
|
||||||
'text': ssp(self.esc(
|
'text': ssp(self.esc(
|
||||||
self.env.titles[self.config.master_doc].astext()))
|
self.env.titles[self.config.master_doc].astext()))
|
||||||
})
|
})
|
||||||
@ -471,6 +483,9 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
else:
|
else:
|
||||||
super(EpubBuilder, self).copy_image_files()
|
super(EpubBuilder, self).copy_image_files()
|
||||||
|
|
||||||
|
def copy_download_files(self):
|
||||||
|
pass
|
||||||
|
|
||||||
def handle_page(self, pagename, addctx, templatename='page.html',
|
def handle_page(self, pagename, addctx, templatename='page.html',
|
||||||
outfilename=None, event_arg=None):
|
outfilename=None, event_arg=None):
|
||||||
"""Create a rendered page.
|
"""Create a rendered page.
|
||||||
@ -480,6 +495,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
"""
|
"""
|
||||||
if pagename.startswith('genindex'):
|
if pagename.startswith('genindex'):
|
||||||
self.fix_genindex(addctx['genindexentries'])
|
self.fix_genindex(addctx['genindexentries'])
|
||||||
|
addctx['doctype'] = self.doctype
|
||||||
StandaloneHTMLBuilder.handle_page(self, pagename, addctx, templatename,
|
StandaloneHTMLBuilder.handle_page(self, pagename, addctx, templatename,
|
||||||
outfilename, event_arg)
|
outfilename, event_arg)
|
||||||
|
|
||||||
@ -760,3 +776,33 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
fp = path.join(outdir, file)
|
fp = path.join(outdir, file)
|
||||||
epub.write(fp, file, zipfile.ZIP_DEFLATED)
|
epub.write(fp, file, zipfile.ZIP_DEFLATED)
|
||||||
epub.close()
|
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')
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
import codecs
|
import codecs
|
||||||
from os import path
|
from os import path
|
||||||
|
|
||||||
|
from sphinx.config import string_classes
|
||||||
from sphinx.builders.epub import EpubBuilder
|
from sphinx.builders.epub import EpubBuilder
|
||||||
|
|
||||||
|
|
||||||
@ -73,7 +74,6 @@ PACKAGE_DOC_TEMPLATE = u'''\
|
|||||||
%(files)s
|
%(files)s
|
||||||
</manifest>
|
</manifest>
|
||||||
<spine toc="ncx" page-progression-direction="%(page_progression_direction)s">
|
<spine toc="ncx" page-progression-direction="%(page_progression_direction)s">
|
||||||
<itemref idref="nav" />
|
|
||||||
%(spine)s
|
%(spine)s
|
||||||
</spine>
|
</spine>
|
||||||
<guide>
|
<guide>
|
||||||
@ -82,6 +82,9 @@ PACKAGE_DOC_TEMPLATE = u'''\
|
|||||||
</package>
|
</package>
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
DOCTYPE = u'''<!DOCTYPE html>
|
||||||
|
'''
|
||||||
|
|
||||||
# The epub3 publisher
|
# The epub3 publisher
|
||||||
|
|
||||||
|
|
||||||
@ -99,6 +102,7 @@ class Epub3Builder(EpubBuilder):
|
|||||||
navlist_template = NAVLIST_TEMPLATE
|
navlist_template = NAVLIST_TEMPLATE
|
||||||
navlist_indent = NAVLIST_INDENT
|
navlist_indent = NAVLIST_INDENT
|
||||||
content_template = PACKAGE_DOC_TEMPLATE
|
content_template = PACKAGE_DOC_TEMPLATE
|
||||||
|
doctype = DOCTYPE
|
||||||
|
|
||||||
# Finish by building the epub file
|
# Finish by building the epub file
|
||||||
def handle_finish(self):
|
def handle_finish(self):
|
||||||
@ -209,3 +213,12 @@ class Epub3Builder(EpubBuilder):
|
|||||||
|
|
||||||
# Add nav.xhtml to epub file
|
# Add nav.xhtml to epub file
|
||||||
self.files.append(outname)
|
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)
|
||||||
|
@ -135,7 +135,7 @@ tzdelta = datetime.fromtimestamp(timestamp) - \
|
|||||||
source_date_epoch = getenv('SOURCE_DATE_EPOCH')
|
source_date_epoch = getenv('SOURCE_DATE_EPOCH')
|
||||||
if source_date_epoch is not None:
|
if source_date_epoch is not None:
|
||||||
timestamp = float(source_date_epoch)
|
timestamp = float(source_date_epoch)
|
||||||
tzdelta = 0
|
tzdelta = timedelta(0)
|
||||||
|
|
||||||
|
|
||||||
class LocalTimeZone(tzinfo):
|
class LocalTimeZone(tzinfo):
|
||||||
@ -233,3 +233,13 @@ class MessageCatalogBuilder(I18nBuilder):
|
|||||||
replace('"', r'\"'). \
|
replace('"', r'\"'). \
|
||||||
replace('\n', '\\n"\n"')
|
replace('\n', '\\n"\n"')
|
||||||
pofile.write('msgid "%s"\nmsgstr ""\n\n' % message)
|
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')
|
||||||
|
@ -27,13 +27,15 @@ from docutils.frontend import OptionParser
|
|||||||
from docutils.readers.doctree import Reader as DoctreeReader
|
from docutils.readers.doctree import Reader as DoctreeReader
|
||||||
|
|
||||||
from sphinx import package_dir, __display_version__
|
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.i18n import format_date
|
||||||
from sphinx.util.osutil import SEP, os_path, relative_uri, ensuredir, \
|
from sphinx.util.osutil import SEP, os_path, relative_uri, ensuredir, \
|
||||||
movefile, copyfile
|
movefile, copyfile
|
||||||
from sphinx.util.nodes import inline_all_toctrees
|
from sphinx.util.nodes import inline_all_toctrees
|
||||||
from sphinx.util.matching import patmatch, compile_matchers
|
from sphinx.util.fileutil import copy_asset
|
||||||
from sphinx.locale import _
|
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.search import js_index
|
||||||
from sphinx.theming import Theme
|
from sphinx.theming import Theme
|
||||||
from sphinx.builders import Builder
|
from sphinx.builders import Builder
|
||||||
@ -80,6 +82,7 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
add_permalinks = True
|
add_permalinks = True
|
||||||
embedded = False # for things like HTML help or Qt help: suppresses sidebar
|
embedded = False # for things like HTML help or Qt help: suppresses sidebar
|
||||||
search = True # for things like HTML help and Apple help: suppress search
|
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.
|
# This is a class attribute because it is mutated by Sphinx.add_javascript.
|
||||||
script_files = ['_static/jquery.js', '_static/underscore.js',
|
script_files = ['_static/jquery.js', '_static/underscore.js',
|
||||||
@ -339,6 +342,7 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
show_sphinx = self.config.html_show_sphinx,
|
show_sphinx = self.config.html_show_sphinx,
|
||||||
has_source = self.config.html_copy_source,
|
has_source = self.config.html_copy_source,
|
||||||
show_source = self.config.html_show_sourcelink,
|
show_source = self.config.html_show_sourcelink,
|
||||||
|
sourcelink_suffix = self.config.html_sourcelink_suffix,
|
||||||
file_suffix = self.out_suffix,
|
file_suffix = self.out_suffix,
|
||||||
script_files = self.script_files,
|
script_files = self.script_files,
|
||||||
language = self.config.language,
|
language = self.config.language,
|
||||||
@ -402,15 +406,21 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
# title rendered as HTML
|
# title rendered as HTML
|
||||||
title = self.env.longtitles.get(docname)
|
title = self.env.longtitles.get(docname)
|
||||||
title = title and self.render_partial(title)['title'] or ''
|
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
|
# 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
|
# metadata for the document
|
||||||
meta = self.env.metadata.get(docname)
|
meta = self.env.metadata.get(docname)
|
||||||
|
|
||||||
# Suffix for the document
|
|
||||||
source_suffix = '.' + self.env.doc2path(docname).split('.')[-1]
|
|
||||||
|
|
||||||
# local TOC and global TOC tree
|
# local TOC and global TOC tree
|
||||||
self_toc = self.env.get_toc_for(docname, self)
|
self_toc = self.env.get_toc_for(docname, self)
|
||||||
toc = self.render_partial(self_toc)['fragment']
|
toc = self.render_partial(self_toc)['fragment']
|
||||||
@ -581,9 +591,8 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
self.info(bold('copying static files... '), nonl=True)
|
self.info(bold('copying static files... '), nonl=True)
|
||||||
ensuredir(path.join(self.outdir, '_static'))
|
ensuredir(path.join(self.outdir, '_static'))
|
||||||
# first, create pygments style file
|
# first, create pygments style file
|
||||||
f = open(path.join(self.outdir, '_static', 'pygments.css'), 'w')
|
with open(path.join(self.outdir, '_static', 'pygments.css'), 'w') as f:
|
||||||
f.write(self.highlighter.get_stylesheet())
|
f.write(self.highlighter.get_stylesheet())
|
||||||
f.close()
|
|
||||||
# then, copy translations JavaScript file
|
# then, copy translations JavaScript file
|
||||||
if self.config.language is not None:
|
if self.config.language is not None:
|
||||||
jsfile = self._get_translations_js()
|
jsfile = self._get_translations_js()
|
||||||
@ -605,21 +614,19 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
|
|
||||||
# then, copy over theme-supplied static files
|
# then, copy over theme-supplied static files
|
||||||
if self.theme:
|
if self.theme:
|
||||||
themeentries = [path.join(themepath, 'static')
|
for theme_path in self.theme.get_dirchain()[::-1]:
|
||||||
for themepath in self.theme.get_dirchain()[::-1]]
|
entry = path.join(theme_path, 'static')
|
||||||
for entry in themeentries:
|
copy_asset(entry, path.join(self.outdir, '_static'), excluded=DOTFILES,
|
||||||
copy_static_entry(entry, path.join(self.outdir, '_static'),
|
context=ctx, renderer=self.templates)
|
||||||
self, ctx)
|
|
||||||
# then, copy over all user-supplied static files
|
# then, copy over all user-supplied static files
|
||||||
staticentries = [path.join(self.confdir, spath)
|
excluded = Matcher(self.config.exclude_patterns + ["**/.*"])
|
||||||
for spath in self.config.html_static_path]
|
for static_path in self.config.html_static_path:
|
||||||
matchers = compile_matchers(self.config.exclude_patterns)
|
entry = path.join(self.confdir, static_path)
|
||||||
for entry in staticentries:
|
|
||||||
if not path.exists(entry):
|
if not path.exists(entry):
|
||||||
self.warn('html_static_path entry %r does not exist' % entry)
|
self.warn('html_static_path entry %r does not exist' % entry)
|
||||||
continue
|
continue
|
||||||
copy_static_entry(entry, path.join(self.outdir, '_static'), self,
|
copy_asset(entry, path.join(self.outdir, '_static'), excluded,
|
||||||
ctx, exclude_matchers=matchers)
|
context=ctx, renderer=self.templates)
|
||||||
# copy logo and favicon files if not already in static path
|
# copy logo and favicon files if not already in static path
|
||||||
if self.config.html_logo:
|
if self.config.html_logo:
|
||||||
logobase = path.basename(self.config.html_logo)
|
logobase = path.basename(self.config.html_logo)
|
||||||
@ -642,14 +649,15 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
def copy_extra_files(self):
|
def copy_extra_files(self):
|
||||||
# copy html_extra_path files
|
# copy html_extra_path files
|
||||||
self.info(bold('copying extra files... '), nonl=True)
|
self.info(bold('copying extra files... '), nonl=True)
|
||||||
extraentries = [path.join(self.confdir, epath)
|
excluded = Matcher(self.config.exclude_patterns)
|
||||||
for epath in self.config.html_extra_path]
|
|
||||||
matchers = compile_matchers(self.config.exclude_patterns)
|
for extra_path in self.config.html_extra_path:
|
||||||
for entry in extraentries:
|
entry = path.join(self.confdir, extra_path)
|
||||||
if not path.exists(entry):
|
if not path.exists(entry):
|
||||||
self.warn('html_extra_path entry %r does not exist' % entry)
|
self.warn('html_extra_path entry %r does not exist' % entry)
|
||||||
continue
|
continue
|
||||||
copy_extra_entry(entry, self.outdir, matchers)
|
|
||||||
|
copy_asset(entry, self.outdir, excluded)
|
||||||
self.info('done')
|
self.info('done')
|
||||||
|
|
||||||
def write_buildinfo(self):
|
def write_buildinfo(self):
|
||||||
@ -712,7 +720,12 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
def index_page(self, pagename, doctree, title):
|
def index_page(self, pagename, doctree, title):
|
||||||
# only index pages with title
|
# only index pages with title
|
||||||
if self.indexer is not None and 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):
|
def _get_local_toctree(self, docname, collapse=True, **kwds):
|
||||||
if 'includehidden' not in kwds:
|
if 'includehidden' not in kwds:
|
||||||
@ -1056,6 +1069,7 @@ class SerializingHTMLBuilder(StandaloneHTMLBuilder):
|
|||||||
self.theme = None # no theme necessary
|
self.theme = None # no theme necessary
|
||||||
self.templates = None # no template bridge necessary
|
self.templates = None # no template bridge necessary
|
||||||
self.init_translator_class()
|
self.init_translator_class()
|
||||||
|
self.init_templates()
|
||||||
self.init_highlighter()
|
self.init_highlighter()
|
||||||
|
|
||||||
def get_target_uri(self, docname, typ=None):
|
def get_target_uri(self, docname, typ=None):
|
||||||
@ -1148,3 +1162,52 @@ class JSONHTMLBuilder(SerializingHTMLBuilder):
|
|||||||
|
|
||||||
def init(self):
|
def init(self):
|
||||||
SerializingHTMLBuilder.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')
|
||||||
|
@ -18,6 +18,7 @@ from os import path
|
|||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
|
|
||||||
from sphinx import addnodes
|
from sphinx import addnodes
|
||||||
|
from sphinx.util.osutil import make_filename
|
||||||
from sphinx.builders.html import StandaloneHTMLBuilder
|
from sphinx.builders.html import StandaloneHTMLBuilder
|
||||||
from sphinx.util.pycompat import htmlescape
|
from sphinx.util.pycompat import htmlescape
|
||||||
|
|
||||||
@ -63,7 +64,7 @@ Binary Index=No
|
|||||||
Compiled file=%(outname)s.chm
|
Compiled file=%(outname)s.chm
|
||||||
Contents file=%(outname)s.hhc
|
Contents file=%(outname)s.hhc
|
||||||
Default Window=%(outname)s
|
Default Window=%(outname)s
|
||||||
Default topic=index.html
|
Default topic=%(master_doc)s
|
||||||
Display compile progress=No
|
Display compile progress=No
|
||||||
Full text search stop list file=%(outname)s.stp
|
Full text search stop list file=%(outname)s.stp
|
||||||
Full-text search=Yes
|
Full-text search=Yes
|
||||||
@ -73,7 +74,7 @@ Title=%(title)s
|
|||||||
|
|
||||||
[WINDOWS]
|
[WINDOWS]
|
||||||
%(outname)s="%(title)s","%(outname)s.hhc","%(outname)s.hhk",\
|
%(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]
|
[FILES]
|
||||||
'''
|
'''
|
||||||
@ -183,6 +184,7 @@ class HTMLHelpBuilder(StandaloneHTMLBuilder):
|
|||||||
StandaloneHTMLBuilder.init(self)
|
StandaloneHTMLBuilder.init(self)
|
||||||
# the output files for HTML help must be .html only
|
# the output files for HTML help must be .html only
|
||||||
self.out_suffix = '.html'
|
self.out_suffix = '.html'
|
||||||
|
self.link_suffix = '.html'
|
||||||
# determine the correct locale setting
|
# determine the correct locale setting
|
||||||
locale = chm_locales.get(self.config.language)
|
locale = chm_locales.get(self.config.language)
|
||||||
if locale is not None:
|
if locale is not None:
|
||||||
@ -204,11 +206,14 @@ class HTMLHelpBuilder(StandaloneHTMLBuilder):
|
|||||||
|
|
||||||
self.info('writing project file...')
|
self.info('writing project file...')
|
||||||
with self.open_file(outdir, outname+'.hhp') as f:
|
with self.open_file(outdir, outname+'.hhp') as f:
|
||||||
f.write(project_template % {'outname': outname,
|
f.write(project_template % {
|
||||||
'title': self.config.html_title,
|
'outname': outname,
|
||||||
'version': self.config.version,
|
'title': self.config.html_title,
|
||||||
'project': self.config.project,
|
'version': self.config.version,
|
||||||
'lcid': self.lcid})
|
'project': self.config.project,
|
||||||
|
'lcid': self.lcid,
|
||||||
|
'master_doc': self.config.master_doc + self.out_suffix
|
||||||
|
})
|
||||||
if not outdir.endswith(os.sep):
|
if not outdir.endswith(os.sep):
|
||||||
outdir += os.sep
|
outdir += os.sep
|
||||||
olen = len(outdir)
|
olen = len(outdir)
|
||||||
@ -225,7 +230,7 @@ class HTMLHelpBuilder(StandaloneHTMLBuilder):
|
|||||||
f.write(contents_header)
|
f.write(contents_header)
|
||||||
# special books
|
# special books
|
||||||
f.write('<LI> ' + object_sitemap % (self.config.html_short_title,
|
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:
|
for indexname, indexcls, content, collapse in self.domain_indices:
|
||||||
f.write('<LI> ' + object_sitemap % (indexcls.localname,
|
f.write('<LI> ' + object_sitemap % (indexcls.localname,
|
||||||
'%s.html' % indexname))
|
'%s.html' % indexname))
|
||||||
@ -292,3 +297,10 @@ class HTMLHelpBuilder(StandaloneHTMLBuilder):
|
|||||||
for title, (refs, subitems, key_) in group:
|
for title, (refs, subitems, key_) in group:
|
||||||
write_index(title, refs, subitems)
|
write_index(title, refs, subitems)
|
||||||
f.write('</UL>\n')
|
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)
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
from os import path
|
from os import path
|
||||||
import warnings
|
|
||||||
|
|
||||||
from six import iteritems
|
from six import iteritems
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
@ -19,14 +18,16 @@ from docutils.io import FileOutput
|
|||||||
from docutils.utils import new_document
|
from docutils.utils import new_document
|
||||||
from docutils.frontend import OptionParser
|
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.util import texescape
|
||||||
|
from sphinx.config import string_classes, ENUM
|
||||||
from sphinx.errors import SphinxError
|
from sphinx.errors import SphinxError
|
||||||
from sphinx.locale import _
|
from sphinx.locale import _
|
||||||
from sphinx.builders import Builder
|
from sphinx.builders import Builder
|
||||||
from sphinx.environment import NoUri
|
from sphinx.environment import NoUri
|
||||||
from sphinx.util.nodes import inline_all_toctrees
|
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.util.console import bold, darkgreen
|
||||||
from sphinx.writers.latex import LaTeXWriter
|
from sphinx.writers.latex import LaTeXWriter
|
||||||
|
|
||||||
@ -38,27 +39,12 @@ class LaTeXBuilder(Builder):
|
|||||||
name = 'latex'
|
name = 'latex'
|
||||||
format = 'latex'
|
format = 'latex'
|
||||||
supported_image_types = ['application/pdf', 'image/png', 'image/jpeg']
|
supported_image_types = ['application/pdf', 'image/png', 'image/jpeg']
|
||||||
usepackages = []
|
|
||||||
|
|
||||||
def init(self):
|
def init(self):
|
||||||
self.docnames = []
|
self.docnames = []
|
||||||
self.document_data = []
|
self.document_data = []
|
||||||
|
self.usepackages = []
|
||||||
texescape.init()
|
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):
|
def get_outdated_docs(self):
|
||||||
return 'all documents' # for now
|
return 'all documents' # for now
|
||||||
@ -92,6 +78,16 @@ class LaTeXBuilder(Builder):
|
|||||||
docname = docname[:-5]
|
docname = docname[:-5]
|
||||||
self.titles.append((docname, entry[2]))
|
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):
|
def write(self, *ignored):
|
||||||
docwriter = LaTeXWriter(self)
|
docwriter = LaTeXWriter(self)
|
||||||
docsettings = OptionParser(
|
docsettings = OptionParser(
|
||||||
@ -100,6 +96,7 @@ class LaTeXBuilder(Builder):
|
|||||||
read_config_files=True).get_default_values()
|
read_config_files=True).get_default_values()
|
||||||
|
|
||||||
self.init_document_data()
|
self.init_document_data()
|
||||||
|
self.write_stylesheet()
|
||||||
|
|
||||||
for entry in self.document_data:
|
for entry in self.document_data:
|
||||||
docname, targetname, title, author, docclass = entry[:5]
|
docname, targetname, title, author, docclass = entry[:5]
|
||||||
@ -192,33 +189,109 @@ class LaTeXBuilder(Builder):
|
|||||||
self.info(bold('copying images...'), nonl=1)
|
self.info(bold('copying images...'), nonl=1)
|
||||||
for src, dest in iteritems(self.images):
|
for src, dest in iteritems(self.images):
|
||||||
self.info(' '+src, nonl=1)
|
self.info(' '+src, nonl=1)
|
||||||
copyfile(path.join(self.srcdir, src),
|
copy_asset_file(path.join(self.srcdir, src),
|
||||||
path.join(self.outdir, dest))
|
path.join(self.outdir, dest))
|
||||||
self.info()
|
self.info()
|
||||||
|
|
||||||
# copy TeX support files from texinputs
|
# copy TeX support files from texinputs
|
||||||
|
context = {'latex_engine': self.config.latex_engine}
|
||||||
self.info(bold('copying TeX support files...'))
|
self.info(bold('copying TeX support files...'))
|
||||||
staticdirname = path.join(package_dir, 'texinputs')
|
staticdirname = path.join(package_dir, 'texinputs')
|
||||||
for filename in os.listdir(staticdirname):
|
for filename in os.listdir(staticdirname):
|
||||||
if not filename.startswith('.'):
|
if not filename.startswith('.'):
|
||||||
copyfile(path.join(staticdirname, filename),
|
copy_asset_file(path.join(staticdirname, filename),
|
||||||
path.join(self.outdir, filename))
|
self.outdir, context=context)
|
||||||
|
|
||||||
# copy additional files
|
# copy additional files
|
||||||
if self.config.latex_additional_files:
|
if self.config.latex_additional_files:
|
||||||
self.info(bold('copying additional files...'), nonl=1)
|
self.info(bold('copying additional files...'), nonl=1)
|
||||||
for filename in self.config.latex_additional_files:
|
for filename in self.config.latex_additional_files:
|
||||||
self.info(' '+filename, nonl=1)
|
self.info(' '+filename, nonl=1)
|
||||||
copyfile(path.join(self.confdir, filename),
|
copy_asset_file(path.join(self.confdir, filename), self.outdir)
|
||||||
path.join(self.outdir, path.basename(filename)))
|
|
||||||
self.info()
|
self.info()
|
||||||
|
|
||||||
# the logo is handled differently
|
# the logo is handled differently
|
||||||
if self.config.latex_logo:
|
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)):
|
if not path.isfile(path.join(self.confdir, self.config.latex_logo)):
|
||||||
raise SphinxError('logo file %r does not exist' % self.config.latex_logo)
|
raise SphinxError('logo file %r does not exist' % self.config.latex_logo)
|
||||||
elif not path.isfile(logotarget):
|
else:
|
||||||
copyfile(path.join(self.confdir, self.config.latex_logo), logotarget)
|
copy_asset_file(path.join(self.confdir, self.config.latex_logo), self.outdir)
|
||||||
self.info('done')
|
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)
|
||||||
|
@ -54,6 +54,13 @@ except pkg_resources.DistributionNotFound:
|
|||||||
'install "requests[security]" as a dependency or upgrade to '
|
'install "requests[security]" as a dependency or upgrade to '
|
||||||
'a python version with SNI support (Python 3 and Python 2.7.9+).'
|
'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) '
|
requests_user_agent = [('User-agent', 'Mozilla/5.0 (X11; Linux x86_64; rv:25.0) '
|
||||||
'Gecko/20100101 Firefox/25.0')]
|
'Gecko/20100101 Firefox/25.0')]
|
||||||
@ -300,3 +307,13 @@ class CheckExternalLinksBuilder(Builder):
|
|||||||
def finish(self):
|
def finish(self):
|
||||||
for worker in self.workers:
|
for worker in self.workers:
|
||||||
self.wqueue.put((None, None, None), False)
|
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)
|
||||||
|
@ -19,6 +19,7 @@ from sphinx import addnodes
|
|||||||
from sphinx.builders import Builder
|
from sphinx.builders import Builder
|
||||||
from sphinx.environment import NoUri
|
from sphinx.environment import NoUri
|
||||||
from sphinx.util.nodes import inline_all_toctrees
|
from sphinx.util.nodes import inline_all_toctrees
|
||||||
|
from sphinx.util.osutil import make_filename
|
||||||
from sphinx.util.console import bold, darkgreen
|
from sphinx.util.console import bold, darkgreen
|
||||||
from sphinx.writers.manpage import ManualPageWriter
|
from sphinx.writers.manpage import ManualPageWriter
|
||||||
|
|
||||||
@ -88,3 +89,13 @@ class ManualPageBuilder(Builder):
|
|||||||
|
|
||||||
def finish(self):
|
def finish(self):
|
||||||
pass
|
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)
|
||||||
|
@ -21,6 +21,7 @@ from docutils import nodes
|
|||||||
from sphinx import addnodes
|
from sphinx import addnodes
|
||||||
from sphinx.builders.html import StandaloneHTMLBuilder
|
from sphinx.builders.html import StandaloneHTMLBuilder
|
||||||
from sphinx.util import force_decode
|
from sphinx.util import force_decode
|
||||||
|
from sphinx.util.osutil import make_filename
|
||||||
from sphinx.util.pycompat import htmlescape
|
from sphinx.util.pycompat import htmlescape
|
||||||
|
|
||||||
|
|
||||||
@ -104,15 +105,25 @@ class QtHelpBuilder(StandaloneHTMLBuilder):
|
|||||||
|
|
||||||
# don't add links
|
# don't add links
|
||||||
add_permalinks = False
|
add_permalinks = False
|
||||||
|
|
||||||
# don't add sidebar etc.
|
# don't add sidebar etc.
|
||||||
embedded = True
|
embedded = True
|
||||||
|
# disable download role
|
||||||
|
download_support = False
|
||||||
|
|
||||||
|
# don't generate the search index or include the search page
|
||||||
|
search = False
|
||||||
|
|
||||||
def init(self):
|
def init(self):
|
||||||
StandaloneHTMLBuilder.init(self)
|
StandaloneHTMLBuilder.init(self)
|
||||||
# the output files for HTML help must be .html only
|
# the output files for HTML help must be .html only
|
||||||
self.out_suffix = '.html'
|
self.out_suffix = '.html'
|
||||||
|
self.link_suffix = '.html'
|
||||||
# self.config.html_style = 'traditional.css'
|
# 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):
|
def handle_finish(self):
|
||||||
self.build_qhp(self.outdir, self.config.qthelp_basename)
|
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], []))
|
keywords.extend(self.build_keywords(subitem[0], subitem[1], []))
|
||||||
|
|
||||||
return keywords
|
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')
|
||||||
|
@ -22,7 +22,7 @@ from sphinx.locale import _
|
|||||||
from sphinx.builders import Builder
|
from sphinx.builders import Builder
|
||||||
from sphinx.environment import NoUri
|
from sphinx.environment import NoUri
|
||||||
from sphinx.util.nodes import inline_all_toctrees
|
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.util.console import bold, darkgreen
|
||||||
from sphinx.writers.texinfo import TexinfoWriter
|
from sphinx.writers.texinfo import TexinfoWriter
|
||||||
|
|
||||||
@ -225,3 +225,20 @@ class TexinfoBuilder(Builder):
|
|||||||
except (IOError, OSError) as err:
|
except (IOError, OSError) as err:
|
||||||
self.warn("error writing file %s: %s" % (fn, err))
|
self.warn("error writing file %s: %s" % (fn, err))
|
||||||
self.info(' done')
|
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)
|
||||||
|
@ -67,3 +67,10 @@ class TextBuilder(Builder):
|
|||||||
|
|
||||||
def finish(self):
|
def finish(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def setup(app):
|
||||||
|
app.add_builder(TextBuilder)
|
||||||
|
|
||||||
|
app.add_config_value('text_sectionchars', '*=-~"+`', 'env')
|
||||||
|
app.add_config_value('text_newlines', 'unix', 'env')
|
||||||
|
@ -165,3 +165,7 @@ class WebSupportBuilder(PickleHTMLBuilder):
|
|||||||
|
|
||||||
def dump_search_index(self):
|
def dump_search_index(self):
|
||||||
self.indexer.finish_indexing()
|
self.indexer.finish_indexing()
|
||||||
|
|
||||||
|
|
||||||
|
def setup(app):
|
||||||
|
app.add_builder(WebSupportBuilder)
|
||||||
|
@ -95,3 +95,10 @@ class PseudoXMLBuilder(XMLBuilder):
|
|||||||
out_suffix = '.pseudoxml'
|
out_suffix = '.pseudoxml'
|
||||||
|
|
||||||
_writer_class = PseudoXMLWriter
|
_writer_class = PseudoXMLWriter
|
||||||
|
|
||||||
|
|
||||||
|
def setup(app):
|
||||||
|
app.add_builder(XMLBuilder)
|
||||||
|
app.add_builder(PseudoXMLBuilder)
|
||||||
|
|
||||||
|
app.add_config_value('xml_pretty', True, 'env')
|
||||||
|
233
sphinx/config.py
@ -10,14 +10,13 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import re
|
import re
|
||||||
from os import path, environ, getenv
|
from os import path, getenv
|
||||||
import shlex
|
|
||||||
|
|
||||||
from six import PY2, PY3, iteritems, string_types, binary_type, text_type, integer_types
|
from six import PY2, PY3, iteritems, string_types, binary_type, text_type, integer_types
|
||||||
|
|
||||||
from sphinx.errors import ConfigError
|
from sphinx.errors import ConfigError
|
||||||
from sphinx.locale import l_
|
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.pycompat import execfile_, NoneType
|
||||||
from sphinx.util.i18n import format_date
|
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_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) " \
|
CONFIG_EXIT_ERROR = "The configuration file (or one of the modules it imports) " \
|
||||||
"called sys.exit()"
|
"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__}', " \
|
CONFIG_TYPE_WARNING = "The config value `{name}' has type `{current.__name__}', " \
|
||||||
"defaults to `{default.__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]
|
string_classes = [text_type]
|
||||||
if PY2:
|
if PY2:
|
||||||
string_classes.append(binary_type) # => [str, unicode]
|
string_classes.append(binary_type) # => [str, unicode]
|
||||||
@ -94,192 +108,12 @@ class Config(object):
|
|||||||
'table': l_('Table %s'),
|
'table': l_('Table %s'),
|
||||||
'code-block': l_('Listing %s')},
|
'code-block': l_('Listing %s')},
|
||||||
'env'),
|
'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):
|
def __init__(self, dirname, filename, overrides, tags):
|
||||||
self.overrides = overrides
|
self.overrides = overrides
|
||||||
self.values = Config.config_values.copy()
|
self.values = Config.config_values.copy()
|
||||||
config = {}
|
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:
|
if dirname is not None:
|
||||||
config_file = path.join(dirname, filename)
|
config_file = path.join(dirname, filename)
|
||||||
config['__file__'] = config_file
|
config['__file__'] = config_file
|
||||||
@ -298,6 +132,12 @@ class Config(object):
|
|||||||
# these two must be preinitialized because extensions can add their
|
# these two must be preinitialized because extensions can add their
|
||||||
# own config values
|
# own config values
|
||||||
self.setup = config.get('setup', None)
|
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', [])
|
self.extensions = config.get('extensions', [])
|
||||||
|
|
||||||
# correct values of copyright year that are not coherent with
|
# correct values of copyright year that are not coherent with
|
||||||
@ -326,19 +166,24 @@ class Config(object):
|
|||||||
if default is None and not permitted:
|
if default is None and not permitted:
|
||||||
continue # neither inferrable nor expliclitly permitted types
|
continue # neither inferrable nor expliclitly permitted types
|
||||||
current = self[name]
|
current = self[name]
|
||||||
if type(current) is type(default):
|
if isinstance(permitted, ENUM):
|
||||||
continue
|
if not permitted.match(current):
|
||||||
if type(current) in permitted:
|
warn(CONFIG_ENUM_WARNING.format(
|
||||||
continue
|
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),)) &
|
common_bases = (set(type(current).__bases__ + (type(current),)) &
|
||||||
set(type(default).__bases__))
|
set(type(default).__bases__))
|
||||||
common_bases.discard(object)
|
common_bases.discard(object)
|
||||||
if common_bases:
|
if common_bases:
|
||||||
continue # at least we share a non-trivial base class
|
continue # at least we share a non-trivial base class
|
||||||
|
|
||||||
warn(CONFIG_TYPE_WARNING.format(
|
warn(CONFIG_TYPE_WARNING.format(
|
||||||
name=name, current=type(current), default=type(default)))
|
name=name, current=type(current), default=type(default)))
|
||||||
|
|
||||||
def check_unicode(self, warn):
|
def check_unicode(self, warn):
|
||||||
# check all string values for non-ASCII characters in bytestrings,
|
# check all string values for non-ASCII characters in bytestrings,
|
||||||
|
@ -17,11 +17,6 @@ from docutils.parsers.rst import Directive, directives, roles
|
|||||||
from sphinx import addnodes
|
from sphinx import addnodes
|
||||||
from sphinx.util.docfields import DocFieldTransformer
|
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
|
# RE to strip backslash escapes
|
||||||
nl_escape_re = re.compile(r'\\\n')
|
nl_escape_re = re.compile(r'\\\n')
|
||||||
@ -216,8 +211,9 @@ class DefaultDomain(Directive):
|
|||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
directives.register_directive('default-role', DefaultRole)
|
def setup(app):
|
||||||
directives.register_directive('default-domain', DefaultDomain)
|
directives.register_directive('default-role', DefaultRole)
|
||||||
directives.register_directive('describe', ObjectDescription)
|
directives.register_directive('default-domain', DefaultDomain)
|
||||||
# new, more consistent, name
|
directives.register_directive('describe', ObjectDescription)
|
||||||
directives.register_directive('object', ObjectDescription)
|
# new, more consistent, name
|
||||||
|
directives.register_directive('object', ObjectDescription)
|
||||||
|
@ -342,8 +342,9 @@ class LiteralInclude(Directive):
|
|||||||
return [retnode]
|
return [retnode]
|
||||||
|
|
||||||
|
|
||||||
directives.register_directive('highlight', Highlight)
|
def setup(app):
|
||||||
directives.register_directive('highlightlang', Highlight) # old
|
directives.register_directive('highlight', Highlight)
|
||||||
directives.register_directive('code-block', CodeBlock)
|
directives.register_directive('highlightlang', Highlight) # old
|
||||||
directives.register_directive('sourcecode', CodeBlock)
|
directives.register_directive('code-block', CodeBlock)
|
||||||
directives.register_directive('literalinclude', LiteralInclude)
|
directives.register_directive('sourcecode', CodeBlock)
|
||||||
|
directives.register_directive('literalinclude', LiteralInclude)
|
||||||
|
@ -405,27 +405,29 @@ class Include(BaseInclude):
|
|||||||
return BaseInclude.run(self)
|
return BaseInclude.run(self)
|
||||||
rel_filename, filename = env.relfn2path(self.arguments[0])
|
rel_filename, filename = env.relfn2path(self.arguments[0])
|
||||||
self.arguments[0] = filename
|
self.arguments[0] = filename
|
||||||
|
env.note_included(filename)
|
||||||
return BaseInclude.run(self)
|
return BaseInclude.run(self)
|
||||||
|
|
||||||
|
|
||||||
directives.register_directive('toctree', TocTree)
|
def setup(app):
|
||||||
directives.register_directive('sectionauthor', Author)
|
directives.register_directive('toctree', TocTree)
|
||||||
directives.register_directive('moduleauthor', Author)
|
directives.register_directive('sectionauthor', Author)
|
||||||
directives.register_directive('codeauthor', Author)
|
directives.register_directive('moduleauthor', Author)
|
||||||
directives.register_directive('index', Index)
|
directives.register_directive('codeauthor', Author)
|
||||||
directives.register_directive('deprecated', VersionChange)
|
directives.register_directive('index', Index)
|
||||||
directives.register_directive('versionadded', VersionChange)
|
directives.register_directive('deprecated', VersionChange)
|
||||||
directives.register_directive('versionchanged', VersionChange)
|
directives.register_directive('versionadded', VersionChange)
|
||||||
directives.register_directive('seealso', SeeAlso)
|
directives.register_directive('versionchanged', VersionChange)
|
||||||
directives.register_directive('tabularcolumns', TabularColumns)
|
directives.register_directive('seealso', SeeAlso)
|
||||||
directives.register_directive('centered', Centered)
|
directives.register_directive('tabularcolumns', TabularColumns)
|
||||||
directives.register_directive('acks', Acks)
|
directives.register_directive('centered', Centered)
|
||||||
directives.register_directive('hlist', HList)
|
directives.register_directive('acks', Acks)
|
||||||
directives.register_directive('only', Only)
|
directives.register_directive('hlist', HList)
|
||||||
directives.register_directive('include', Include)
|
directives.register_directive('only', Only)
|
||||||
|
directives.register_directive('include', Include)
|
||||||
|
|
||||||
# register the standard rst class directive under a different name
|
# register the standard rst class directive under a different name
|
||||||
# only for backwards compatibility now
|
# only for backwards compatibility now
|
||||||
directives.register_directive('cssclass', Class)
|
directives.register_directive('cssclass', Class)
|
||||||
# new standard name when default-domain with "class" is in effect
|
# new standard name when default-domain with "class" is in effect
|
||||||
directives.register_directive('rst-class', Class)
|
directives.register_directive('rst-class', Class)
|
||||||
|
@ -35,4 +35,5 @@ class Figure(images.Figure):
|
|||||||
return [figure_node]
|
return [figure_node]
|
||||||
|
|
||||||
|
|
||||||
directives.register_directive('figure', Figure)
|
def setup(app):
|
||||||
|
directives.register_directive('figure', Figure)
|
||||||
|
@ -273,20 +273,3 @@ class Domain(object):
|
|||||||
if primary:
|
if primary:
|
||||||
return type.lname
|
return type.lname
|
||||||
return _('%s %s') % (self.label, 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,
|
|
||||||
}
|
|
||||||
|
@ -279,6 +279,9 @@ class CDomain(Domain):
|
|||||||
typ, target, node, contnode):
|
typ, target, node, contnode):
|
||||||
# strip pointer asterisk
|
# strip pointer asterisk
|
||||||
target = target.rstrip(' *')
|
target = target.rstrip(' *')
|
||||||
|
# becase TypedField can generate xrefs
|
||||||
|
if target in CObject.stopwords:
|
||||||
|
return contnode
|
||||||
if target not in self.data['objects']:
|
if target not in self.data['objects']:
|
||||||
return None
|
return None
|
||||||
obj = self.data['objects'][target]
|
obj = self.data['objects'][target]
|
||||||
@ -299,3 +302,7 @@ class CDomain(Domain):
|
|||||||
def get_objects(self):
|
def get_objects(self):
|
||||||
for refname, (docname, type) in list(self.data['objects'].items()):
|
for refname, (docname, type) in list(self.data['objects'].items()):
|
||||||
yield (refname, refname, type, docname, 'c.' + refname, 1)
|
yield (refname, refname, type, docname, 'c.' + refname, 1)
|
||||||
|
|
||||||
|
|
||||||
|
def setup(app):
|
||||||
|
app.add_domain(CDomain)
|
||||||
|
@ -553,6 +553,80 @@ def _verify_description_mode(mode):
|
|||||||
raise Exception("Description mode '%s' is invalid." % 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):
|
class ASTIdentifier(ASTBase):
|
||||||
def __init__(self, identifier):
|
def __init__(self, identifier):
|
||||||
assert identifier is not None
|
assert identifier is not None
|
||||||
@ -1341,7 +1415,7 @@ class ASTParametersQualifiers(ASTBase):
|
|||||||
|
|
||||||
class ASTDeclSpecsSimple(ASTBase):
|
class ASTDeclSpecsSimple(ASTBase):
|
||||||
def __init__(self, storage, threadLocal, inline, virtual, explicit,
|
def __init__(self, storage, threadLocal, inline, virtual, explicit,
|
||||||
constexpr, volatile, const, friend):
|
constexpr, volatile, const, friend, attrs):
|
||||||
self.storage = storage
|
self.storage = storage
|
||||||
self.threadLocal = threadLocal
|
self.threadLocal = threadLocal
|
||||||
self.inline = inline
|
self.inline = inline
|
||||||
@ -1351,6 +1425,7 @@ class ASTDeclSpecsSimple(ASTBase):
|
|||||||
self.volatile = volatile
|
self.volatile = volatile
|
||||||
self.const = const
|
self.const = const
|
||||||
self.friend = friend
|
self.friend = friend
|
||||||
|
self.attrs = attrs
|
||||||
|
|
||||||
def mergeWith(self, other):
|
def mergeWith(self, other):
|
||||||
if not other:
|
if not other:
|
||||||
@ -1363,10 +1438,12 @@ class ASTDeclSpecsSimple(ASTBase):
|
|||||||
self.constexpr or other.constexpr,
|
self.constexpr or other.constexpr,
|
||||||
self.volatile or other.volatile,
|
self.volatile or other.volatile,
|
||||||
self.const or other.const,
|
self.const or other.const,
|
||||||
self.friend or other.friend)
|
self.friend or other.friend,
|
||||||
|
self.attrs + other.attrs)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
res = []
|
res = []
|
||||||
|
res.extend(text_type(attr) for attr in self.attrs)
|
||||||
if self.storage:
|
if self.storage:
|
||||||
res.append(self.storage)
|
res.append(self.storage)
|
||||||
if self.threadLocal:
|
if self.threadLocal:
|
||||||
@ -1392,6 +1469,10 @@ class ASTDeclSpecsSimple(ASTBase):
|
|||||||
if len(modifiers) > 0:
|
if len(modifiers) > 0:
|
||||||
modifiers.append(nodes.Text(' '))
|
modifiers.append(nodes.Text(' '))
|
||||||
modifiers.append(addnodes.desc_annotation(text, 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:
|
if self.storage:
|
||||||
_add(modifiers, self.storage)
|
_add(modifiers, self.storage)
|
||||||
if self.threadLocal:
|
if self.threadLocal:
|
||||||
@ -2062,7 +2143,7 @@ class ASTTypeWithInit(ASTBase):
|
|||||||
|
|
||||||
def get_id_v2(self, objectType=None, symbol=None):
|
def get_id_v2(self, objectType=None, symbol=None):
|
||||||
if objectType == 'member':
|
if objectType == 'member':
|
||||||
return symbol.declaration.name.get_id_v2()
|
return symbol.get_full_nested_name().get_id_v2()
|
||||||
else:
|
else:
|
||||||
return self.type.get_id_v2()
|
return self.type.get_id_v2()
|
||||||
|
|
||||||
@ -2780,6 +2861,10 @@ class Symbol(object):
|
|||||||
if symbol is None:
|
if symbol is None:
|
||||||
# TODO: maybe search without template args
|
# TODO: maybe search without template args
|
||||||
return None
|
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
|
parentSymbol = symbol
|
||||||
assert False # should have returned in the loop
|
assert False # should have returned in the loop
|
||||||
|
|
||||||
@ -2825,7 +2910,7 @@ class DefinitionParser(object):
|
|||||||
|
|
||||||
_prefix_keys = ('class', 'struct', 'enum', 'union', 'typename')
|
_prefix_keys = ('class', 'struct', 'enum', 'union', 'typename')
|
||||||
|
|
||||||
def __init__(self, definition, warnEnv):
|
def __init__(self, definition, warnEnv, config):
|
||||||
self.definition = definition.strip()
|
self.definition = definition.strip()
|
||||||
self.pos = 0
|
self.pos = 0
|
||||||
self.end = len(self.definition)
|
self.end = len(self.definition)
|
||||||
@ -2833,6 +2918,7 @@ class DefinitionParser(object):
|
|||||||
self._previous_state = (0, None)
|
self._previous_state = (0, None)
|
||||||
|
|
||||||
self.warnEnv = warnEnv
|
self.warnEnv = warnEnv
|
||||||
|
self.config = config
|
||||||
|
|
||||||
def _make_multi_error(self, errors, header):
|
def _make_multi_error(self, errors, header):
|
||||||
if len(errors) == 1:
|
if len(errors) == 1:
|
||||||
@ -2901,6 +2987,12 @@ class DefinitionParser(object):
|
|||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def skip_string_and_ws(self, string):
|
||||||
|
if self.skip_string(string):
|
||||||
|
self.skip_ws()
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def eof(self):
|
def eof(self):
|
||||||
return self.pos >= self.end
|
return self.pos >= self.end
|
||||||
@ -2927,6 +3019,85 @@ class DefinitionParser(object):
|
|||||||
if not self.eof:
|
if not self.eof:
|
||||||
self.fail('Expected end of definition.')
|
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):
|
def _parse_expression(self, end):
|
||||||
# Stupidly "parse" an expression.
|
# Stupidly "parse" an expression.
|
||||||
# 'end' should be a list of characters which ends the expression.
|
# 'end' should be a list of characters which ends the expression.
|
||||||
@ -3127,10 +3298,9 @@ class DefinitionParser(object):
|
|||||||
self.fail('Expected ")" after "..." in '
|
self.fail('Expected ")" after "..." in '
|
||||||
'parameters_and_qualifiers.')
|
'parameters_and_qualifiers.')
|
||||||
break
|
break
|
||||||
if paramMode == 'function':
|
# note: it seems that function arguments can always sbe named,
|
||||||
arg = self._parse_type_with_init(outer=None, named='single')
|
# even in function pointers and similar.
|
||||||
else:
|
arg = self._parse_type_with_init(outer=None, named='single')
|
||||||
arg = self._parse_type(named=False)
|
|
||||||
# TODO: parse default parameters # TODO: didn't we just do that?
|
# TODO: parse default parameters # TODO: didn't we just do that?
|
||||||
args.append(ASTFunctinoParameter(arg))
|
args.append(ASTFunctinoParameter(arg))
|
||||||
|
|
||||||
@ -3209,6 +3379,7 @@ class DefinitionParser(object):
|
|||||||
volatile = None
|
volatile = None
|
||||||
const = None
|
const = None
|
||||||
friend = None
|
friend = None
|
||||||
|
attrs = []
|
||||||
while 1: # accept any permutation of a subset of some decl-specs
|
while 1: # accept any permutation of a subset of some decl-specs
|
||||||
self.skip_ws()
|
self.skip_ws()
|
||||||
if not storage:
|
if not storage:
|
||||||
@ -3262,9 +3433,14 @@ class DefinitionParser(object):
|
|||||||
const = self.skip_word('const')
|
const = self.skip_word('const')
|
||||||
if const:
|
if const:
|
||||||
continue
|
continue
|
||||||
|
attr = self._parse_attribute()
|
||||||
|
if attr:
|
||||||
|
attrs.append(attr)
|
||||||
|
continue
|
||||||
break
|
break
|
||||||
return ASTDeclSpecsSimple(storage, threadLocal, inline, virtual,
|
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):
|
def _parse_decl_specs(self, outer, typed=True):
|
||||||
if outer:
|
if outer:
|
||||||
@ -3921,7 +4097,7 @@ class CPPObject(ObjectDescription):
|
|||||||
id_v1 = None
|
id_v1 = None
|
||||||
id_v2 = ast.get_id_v2()
|
id_v2 = ast.get_id_v2()
|
||||||
# store them in reverse order, so the newest is first
|
# store them in reverse order, so the newest is first
|
||||||
ids = [id_v2, id_v1]
|
ids = [id_v2, id_v1]
|
||||||
|
|
||||||
newestId = ids[0]
|
newestId = ids[0]
|
||||||
assert newestId # shouldn't be None
|
assert newestId # shouldn't be None
|
||||||
@ -3930,7 +4106,12 @@ class CPPObject(ObjectDescription):
|
|||||||
'report as bug (id=%s).' % (text_type(ast), newestId))
|
'report as bug (id=%s).' % (text_type(ast), newestId))
|
||||||
|
|
||||||
name = text_type(ast.symbol.get_full_nested_name()).lstrip(':')
|
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))
|
self.indexnode['entries'].append(('single', indexText, newestId, '', None))
|
||||||
|
|
||||||
if newestId not in self.state.document.ids:
|
if newestId not in self.state.document.ids:
|
||||||
@ -3942,8 +4123,14 @@ class CPPObject(ObjectDescription):
|
|||||||
else:
|
else:
|
||||||
# print("[CPP] non-unique name:", name)
|
# print("[CPP] non-unique name:", name)
|
||||||
pass
|
pass
|
||||||
for id in ids:
|
# always add the newest id
|
||||||
if id: # is None when the element didn't exist in that version
|
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['ids'].append(id)
|
||||||
signode['first'] = (not self.names) # hmm, what is this abound?
|
signode['first'] = (not self.names) # hmm, what is this abound?
|
||||||
self.state.document.note_explicit_target(signode)
|
self.state.document.note_explicit_target(signode)
|
||||||
@ -3969,7 +4156,7 @@ class CPPObject(ObjectDescription):
|
|||||||
self.env.ref_context['cpp:parent_symbol'] = root
|
self.env.ref_context['cpp:parent_symbol'] = root
|
||||||
parentSymbol = self.env.ref_context['cpp:parent_symbol']
|
parentSymbol = self.env.ref_context['cpp:parent_symbol']
|
||||||
|
|
||||||
parser = DefinitionParser(sig, self)
|
parser = DefinitionParser(sig, self, self.env.config)
|
||||||
try:
|
try:
|
||||||
ast = self.parse_definition(parser)
|
ast = self.parse_definition(parser)
|
||||||
parser.assert_end()
|
parser.assert_end()
|
||||||
@ -3996,6 +4183,15 @@ class CPPObject(ObjectDescription):
|
|||||||
self.describe_signature(signode, ast)
|
self.describe_signature(signode, ast)
|
||||||
return 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):
|
class CPPTypeObject(CPPObject):
|
||||||
def get_index_text(self, name):
|
def get_index_text(self, name):
|
||||||
@ -4106,7 +4302,7 @@ class CPPNamespaceObject(Directive):
|
|||||||
symbol = rootSymbol
|
symbol = rootSymbol
|
||||||
stack = []
|
stack = []
|
||||||
else:
|
else:
|
||||||
parser = DefinitionParser(self.arguments[0], self)
|
parser = DefinitionParser(self.arguments[0], self, env.config)
|
||||||
try:
|
try:
|
||||||
ast = parser.parse_namespace_object()
|
ast = parser.parse_namespace_object()
|
||||||
parser.assert_end()
|
parser.assert_end()
|
||||||
@ -4135,7 +4331,7 @@ class CPPNamespacePushObject(Directive):
|
|||||||
env = self.state.document.settings.env
|
env = self.state.document.settings.env
|
||||||
if self.arguments[0].strip() in ('NULL', '0', 'nullptr'):
|
if self.arguments[0].strip() in ('NULL', '0', 'nullptr'):
|
||||||
return
|
return
|
||||||
parser = DefinitionParser(self.arguments[0], self)
|
parser = DefinitionParser(self.arguments[0], self, env.config)
|
||||||
try:
|
try:
|
||||||
ast = parser.parse_namespace_object()
|
ast = parser.parse_namespace_object()
|
||||||
parser.assert_end()
|
parser.assert_end()
|
||||||
@ -4285,7 +4481,7 @@ class CPPDomain(Domain):
|
|||||||
if emitWarnings:
|
if emitWarnings:
|
||||||
env.warn_node(msg, node)
|
env.warn_node(msg, node)
|
||||||
warner = Warner()
|
warner = Warner()
|
||||||
parser = DefinitionParser(target, warner)
|
parser = DefinitionParser(target, warner, env.config)
|
||||||
try:
|
try:
|
||||||
ast = parser.parse_xref_object()
|
ast = parser.parse_xref_object()
|
||||||
parser.skip_ws()
|
parser.skip_ws()
|
||||||
@ -4315,6 +4511,31 @@ class CPPDomain(Domain):
|
|||||||
matchSelf=True)
|
matchSelf=True)
|
||||||
if s is None or s.declaration is None:
|
if s is None or s.declaration is None:
|
||||||
return None, 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
|
declaration = s.declaration
|
||||||
fullNestedName = s.get_full_nested_name()
|
fullNestedName = s.get_full_nested_name()
|
||||||
name = text_type(fullNestedName).lstrip(':')
|
name = text_type(fullNestedName).lstrip(':')
|
||||||
@ -4354,3 +4575,10 @@ class CPPDomain(Domain):
|
|||||||
docname = symbol.docname
|
docname = symbol.docname
|
||||||
newestId = symbol.declaration.get_newest_id()
|
newestId = symbol.declaration.get_newest_id()
|
||||||
yield (name, name, objectType, docname, newestId, 1)
|
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')
|
||||||
|
@ -234,3 +234,7 @@ class JavaScriptDomain(Domain):
|
|||||||
for refname, (docname, type) in list(self.data['objects'].items()):
|
for refname, (docname, type) in list(self.data['objects'].items()):
|
||||||
yield refname, refname, type, docname, \
|
yield refname, refname, type, docname, \
|
||||||
refname.replace('$', '_S_'), 1
|
refname.replace('$', '_S_'), 1
|
||||||
|
|
||||||
|
|
||||||
|
def setup(app):
|
||||||
|
app.add_domain(JavaScriptDomain)
|
||||||
|
@ -101,11 +101,36 @@ class PyXrefMixin(object):
|
|||||||
break
|
break
|
||||||
return result
|
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):
|
class PyField(PyXrefMixin, Field):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class PyGroupedField(PyXrefMixin, GroupedField):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class PyTypedField(PyXrefMixin, TypedField):
|
class PyTypedField(PyXrefMixin, TypedField):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -130,9 +155,9 @@ class PyObject(ObjectDescription):
|
|||||||
names=('var', 'ivar', 'cvar'),
|
names=('var', 'ivar', 'cvar'),
|
||||||
typerolename='obj', typenames=('vartype',),
|
typerolename='obj', typenames=('vartype',),
|
||||||
can_collapse=True),
|
can_collapse=True),
|
||||||
GroupedField('exceptions', label=l_('Raises'), rolename='exc',
|
PyGroupedField('exceptions', label=l_('Raises'), rolename='exc',
|
||||||
names=('raises', 'raise', 'exception', 'except'),
|
names=('raises', 'raise', 'exception', 'except'),
|
||||||
can_collapse=True),
|
can_collapse=True),
|
||||||
Field('returnvalue', label=l_('Returns'), has_arg=False,
|
Field('returnvalue', label=l_('Returns'), has_arg=False,
|
||||||
names=('returns', 'return')),
|
names=('returns', 'return')),
|
||||||
PyField('returntype', label=l_('Return type'), has_arg=False,
|
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']):
|
for refname, (docname, type) in iteritems(self.data['objects']):
|
||||||
if type != 'module': # modules are already handled
|
if type != 'module': # modules are already handled
|
||||||
yield (refname, refname, type, docname, refname, 1)
|
yield (refname, refname, type, docname, refname, 1)
|
||||||
|
|
||||||
|
|
||||||
|
def setup(app):
|
||||||
|
app.add_domain(PythonDomain)
|
||||||
|
@ -156,3 +156,7 @@ class ReSTDomain(Domain):
|
|||||||
def get_objects(self):
|
def get_objects(self):
|
||||||
for (typ, name), docname in iteritems(self.data['objects']):
|
for (typ, name), docname in iteritems(self.data['objects']):
|
||||||
yield name, name, typ, docname, typ + '-' + name, 1
|
yield name, name, typ, docname, typ + '-' + name, 1
|
||||||
|
|
||||||
|
|
||||||
|
def setup(app):
|
||||||
|
app.add_domain(ReSTDomain)
|
||||||
|
@ -14,7 +14,6 @@ import unicodedata
|
|||||||
|
|
||||||
from six import iteritems
|
from six import iteritems
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
from docutils.nodes import fully_normalize_name
|
|
||||||
from docutils.parsers.rst import directives
|
from docutils.parsers.rst import directives
|
||||||
from docutils.statemachine import ViewList
|
from docutils.statemachine import ViewList
|
||||||
|
|
||||||
@ -585,106 +584,119 @@ class StandardDomain(Domain):
|
|||||||
newnode.append(innernode)
|
newnode.append(innernode)
|
||||||
return newnode
|
return newnode
|
||||||
|
|
||||||
def resolve_xref(self, env, fromdocname, builder,
|
def resolve_xref(self, env, fromdocname, builder, typ, target, node, contnode):
|
||||||
typ, target, node, contnode):
|
|
||||||
if typ == 'ref':
|
if typ == 'ref':
|
||||||
if node['refexplicit']:
|
resolver = self._resolve_ref_xref
|
||||||
# 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')
|
|
||||||
elif typ == 'numref':
|
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, ('', ''))
|
docname, labelid = self.data['anonlabels'].get(target, ('', ''))
|
||||||
if not docname:
|
sectname = node.astext()
|
||||||
return None
|
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:
|
return self.build_reference_node(fromdocname, builder,
|
||||||
env.warn(fromdocname, 'numfig is disabled. :numref: is ignored.',
|
docname, labelid, sectname, 'ref')
|
||||||
lineno=node.line)
|
|
||||||
return contnode
|
|
||||||
|
|
||||||
target_node = env.get_doctree(docname).ids.get(labelid)
|
def _resolve_numref_xref(self, env, fromdocname, builder, typ, target, node, contnode):
|
||||||
figtype = self.get_figtype(target_node)
|
docname, labelid = self.data['anonlabels'].get(target, ('', ''))
|
||||||
if figtype is None:
|
if not docname:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
try:
|
if env.config.numfig is False:
|
||||||
figure_id = target_node['ids'][0]
|
env.warn_node('numfig is disabled. :numref: is ignored.', node)
|
||||||
fignumber = env.toc_fignumbers[docname][figtype][figure_id]
|
return contnode
|
||||||
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
|
|
||||||
|
|
||||||
title = contnode.astext()
|
target_node = env.get_doctree(docname).ids.get(labelid)
|
||||||
if target == fully_normalize_name(title):
|
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, '')
|
title = env.config.numfig_format.get(figtype, '')
|
||||||
|
|
||||||
try:
|
newtitle = title % '.'.join(map(str, fignumber))
|
||||||
newtitle = title % '.'.join(map(str, fignumber))
|
except TypeError:
|
||||||
except TypeError:
|
env.warn_node('invalid numfig_format: %s' % title, node)
|
||||||
env.warn(fromdocname, 'invalid numfig_format: %s' % title,
|
return None
|
||||||
lineno=node.line)
|
|
||||||
return None
|
|
||||||
|
|
||||||
return self.build_reference_node(fromdocname, builder,
|
return self.build_reference_node(fromdocname, builder,
|
||||||
docname, labelid, newtitle, 'numref',
|
docname, labelid, newtitle, 'numref',
|
||||||
nodeclass=addnodes.number_reference,
|
nodeclass=addnodes.number_reference,
|
||||||
title=title)
|
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)
|
|
||||||
|
|
||||||
docname, labelid = self.data['progoptions'].get((progname, target),
|
def _resolve_keyword_xref(self, env, fromdocname, builder, typ, target, node, contnode):
|
||||||
('', ''))
|
# keywords are oddballs: they are referenced by named labels
|
||||||
if docname:
|
docname, labelid, _ = self.data['labels'].get(target, ('', '', ''))
|
||||||
break
|
if not docname:
|
||||||
else:
|
return None
|
||||||
return None
|
return make_refnode(builder, fromdocname, docname,
|
||||||
|
labelid, contnode)
|
||||||
|
|
||||||
return make_refnode(builder, fromdocname, docname,
|
def _resolve_option_xref(self, env, fromdocname, builder, typ, target, node, contnode):
|
||||||
labelid, contnode)
|
progname = node.get('std:program')
|
||||||
else:
|
target = target.strip()
|
||||||
objtypes = self.objtypes_for_role(typ) or []
|
docname, labelid = self.data['progoptions'].get((progname, target), ('', ''))
|
||||||
for objtype in objtypes:
|
if not docname:
|
||||||
if (objtype, target) in self.data['objects']:
|
commands = []
|
||||||
docname, labelid = self.data['objects'][objtype, target]
|
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
|
break
|
||||||
else:
|
else:
|
||||||
docname, labelid = '', ''
|
|
||||||
if not docname:
|
|
||||||
return None
|
return None
|
||||||
return make_refnode(builder, fromdocname, docname,
|
|
||||||
labelid, contnode)
|
|
||||||
|
|
||||||
def resolve_any_xref(self, env, fromdocname, builder, target,
|
return make_refnode(builder, fromdocname, docname,
|
||||||
node, contnode):
|
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 = []
|
results = []
|
||||||
ltarget = target.lower() # :ref: lowercases its target automatically
|
ltarget = target.lower() # :ref: lowercases its target automatically
|
||||||
for role in ('ref', 'option'): # do not try "keyword"
|
for role in ('ref', 'option'): # do not try "keyword"
|
||||||
@ -755,3 +767,7 @@ class StandardDomain(Domain):
|
|||||||
else:
|
else:
|
||||||
figtype, _ = self.enumerable_nodes.get(node.__class__, (None, None))
|
figtype, _ = self.enumerable_nodes.get(node.__class__, (None, None))
|
||||||
return figtype
|
return figtype
|
||||||
|
|
||||||
|
|
||||||
|
def setup(app):
|
||||||
|
app.add_domain(StandardDomain)
|
||||||
|
@ -17,6 +17,7 @@ import types
|
|||||||
import bisect
|
import bisect
|
||||||
import codecs
|
import codecs
|
||||||
import string
|
import string
|
||||||
|
import fnmatch
|
||||||
import unicodedata
|
import unicodedata
|
||||||
from os import path
|
from os import path
|
||||||
from glob import glob
|
from glob import glob
|
||||||
@ -75,7 +76,7 @@ default_settings = {
|
|||||||
# or changed to properly invalidate pickle files.
|
# or changed to properly invalidate pickle files.
|
||||||
#
|
#
|
||||||
# NOTE: increase base version by 2 to have distinct numbers for Py2 and 3
|
# 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)
|
dummy_reporter = Reporter('', 4, 4)
|
||||||
@ -169,6 +170,7 @@ class BuildEnvironment:
|
|||||||
# contains all read docnames
|
# contains all read docnames
|
||||||
self.dependencies = {} # docname -> set of dependent file
|
self.dependencies = {} # docname -> set of dependent file
|
||||||
# names, relative to documentation root
|
# names, relative to documentation root
|
||||||
|
self.included = set() # docnames included from other documents
|
||||||
self.reread_always = set() # docnames to re-read unconditionally on
|
self.reread_always = set() # docnames to re-read unconditionally on
|
||||||
# next build
|
# next build
|
||||||
|
|
||||||
@ -328,6 +330,20 @@ class BuildEnvironment:
|
|||||||
domain.merge_domaindata(docnames, other.domaindata[domainname])
|
domain.merge_domaindata(docnames, other.domaindata[domainname])
|
||||||
app.emit('env-merge-info', self, docnames, other)
|
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):
|
def doc2path(self, docname, base=True, suffix=None):
|
||||||
"""Return the filename for the document name.
|
"""Return the filename for the document name.
|
||||||
|
|
||||||
@ -387,8 +403,13 @@ class BuildEnvironment:
|
|||||||
config.html_extra_path +
|
config.html_extra_path +
|
||||||
['**/_sources', '.#*', '**/.#*', '*.lproj/**']
|
['**/_sources', '.#*', '**/.#*', '*.lproj/**']
|
||||||
)
|
)
|
||||||
self.found_docs = set(get_matching_docs(
|
self.found_docs = set()
|
||||||
self.srcdir, config.source_suffix, exclude_matchers=matchers))
|
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
|
# add catalog mo file dependency
|
||||||
for docname in self.found_docs:
|
for docname in self.found_docs:
|
||||||
@ -820,6 +841,15 @@ class BuildEnvironment:
|
|||||||
"""
|
"""
|
||||||
self.dependencies.setdefault(self.docname, set()).add(filename)
|
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):
|
def note_reread(self):
|
||||||
"""Add the current document to the list of documents that will
|
"""Add the current document to the list of documents that will
|
||||||
automatically be re-read at the next build.
|
automatically be re-read at the next build.
|
||||||
@ -1413,7 +1443,10 @@ class BuildEnvironment:
|
|||||||
# nodes with length 1 don't have any children anyway
|
# nodes with length 1 don't have any children anyway
|
||||||
if len(toplevel) > 1:
|
if len(toplevel) > 1:
|
||||||
subtrees = toplevel.traverse(addnodes.toctree)
|
subtrees = toplevel.traverse(addnodes.toctree)
|
||||||
toplevel[1][:] = subtrees
|
if subtrees:
|
||||||
|
toplevel[1][:] = subtrees
|
||||||
|
else:
|
||||||
|
toplevel.pop(1)
|
||||||
# resolve all sub-toctrees
|
# resolve all sub-toctrees
|
||||||
for subtocnode in toc.traverse(addnodes.toctree):
|
for subtocnode in toc.traverse(addnodes.toctree):
|
||||||
if not (subtocnode.get('hidden', False) and
|
if not (subtocnode.get('hidden', False) and
|
||||||
@ -1459,6 +1492,9 @@ class BuildEnvironment:
|
|||||||
_toctree_add_classes(newnode, 1)
|
_toctree_add_classes(newnode, 1)
|
||||||
self._toctree_prune(newnode, 1, prune and maxdepth or 0, collapse)
|
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
|
# set the target paths in the toctrees (they are not known at TOC
|
||||||
# generation time)
|
# generation time)
|
||||||
for refnode in newnode.traverse(nodes.reference):
|
for refnode in newnode.traverse(nodes.reference):
|
||||||
@ -1488,9 +1524,9 @@ class BuildEnvironment:
|
|||||||
typ, target, node, contnode)
|
typ, target, node, contnode)
|
||||||
# really hardwired reference types
|
# really hardwired reference types
|
||||||
elif typ == 'any':
|
elif typ == 'any':
|
||||||
newnode = self._resolve_any_reference(builder, node, contnode)
|
newnode = self._resolve_any_reference(builder, refdoc, node, contnode)
|
||||||
elif typ == 'doc':
|
elif typ == 'doc':
|
||||||
newnode = self._resolve_doc_reference(builder, node, contnode)
|
newnode = self._resolve_doc_reference(builder, refdoc, node, contnode)
|
||||||
elif typ == 'citation':
|
elif typ == 'citation':
|
||||||
newnode = self._resolve_citation(builder, refdoc, node, contnode)
|
newnode = self._resolve_citation(builder, refdoc, node, contnode)
|
||||||
# no new node found? try the missing-reference event
|
# no new node found? try the missing-reference event
|
||||||
@ -1538,10 +1574,10 @@ class BuildEnvironment:
|
|||||||
msg = '%r reference target not found: %%(target)s' % typ
|
msg = '%r reference target not found: %%(target)s' % typ
|
||||||
self.warn_node(msg % {'target': target}, node, type='ref', subtype=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;
|
# directly reference to document by source name;
|
||||||
# can be absolute or relative
|
# 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 docname in self.all_docs:
|
||||||
if node['refexplicit']:
|
if node['refexplicit']:
|
||||||
# reference with explicit title
|
# reference with explicit title
|
||||||
@ -1551,7 +1587,7 @@ class BuildEnvironment:
|
|||||||
innernode = nodes.inline(caption, caption)
|
innernode = nodes.inline(caption, caption)
|
||||||
innernode['classes'].append('doc')
|
innernode['classes'].append('doc')
|
||||||
newnode = nodes.reference('', '', internal=True)
|
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)
|
newnode.append(innernode)
|
||||||
return newnode
|
return newnode
|
||||||
|
|
||||||
@ -1574,13 +1610,12 @@ class BuildEnvironment:
|
|||||||
# transforms.CitationReference.apply.
|
# transforms.CitationReference.apply.
|
||||||
del node['ids'][:]
|
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."""
|
"""Resolve reference generated by the "any" role."""
|
||||||
refdoc = node['refdoc']
|
|
||||||
target = node['reftarget']
|
target = node['reftarget']
|
||||||
results = []
|
results = []
|
||||||
# first, try resolving as :doc:
|
# 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:
|
if doc_ref:
|
||||||
results.append(('doc', doc_ref))
|
results.append(('doc', doc_ref))
|
||||||
# next, do the standard domain (makes this a priority)
|
# next, do the standard domain (makes this a priority)
|
||||||
@ -1931,6 +1966,9 @@ class BuildEnvironment:
|
|||||||
if docname == self.config.master_doc:
|
if docname == self.config.master_doc:
|
||||||
# the master file is not included anywhere ;)
|
# the master file is not included anywhere ;)
|
||||||
continue
|
continue
|
||||||
|
if docname in self.included:
|
||||||
|
# the document is included from other documents
|
||||||
|
continue
|
||||||
if 'orphan' in self.metadata[docname]:
|
if 'orphan' in self.metadata[docname]:
|
||||||
continue
|
continue
|
||||||
self.warn(docname, 'document isn\'t included in any toctree')
|
self.warn(docname, 'document isn\'t included in any toctree')
|
||||||
|
@ -67,7 +67,10 @@ class PycodeError(Exception):
|
|||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
class SphinxParallelError(Exception):
|
class SphinxParallelError(SphinxError):
|
||||||
|
|
||||||
|
category = 'Sphinx parallel build error'
|
||||||
|
|
||||||
def __init__(self, orig_exc, traceback):
|
def __init__(self, orig_exc, traceback):
|
||||||
self.orig_exc = orig_exc
|
self.orig_exc = orig_exc
|
||||||
self.traceback = traceback
|
self.traceback = traceback
|
||||||
|
@ -261,12 +261,13 @@ def format_annotation(annotation):
|
|||||||
|
|
||||||
Displaying complex types from ``typing`` relies on its private API.
|
Displaying complex types from ``typing`` relies on its private API.
|
||||||
"""
|
"""
|
||||||
|
if not isinstance(annotation, type):
|
||||||
|
return repr(annotation)
|
||||||
|
|
||||||
qualified_name = (annotation.__module__ + '.' + annotation.__qualname__
|
qualified_name = (annotation.__module__ + '.' + annotation.__qualname__
|
||||||
if annotation else repr(annotation))
|
if annotation else repr(annotation))
|
||||||
|
|
||||||
if not isinstance(annotation, type):
|
if annotation.__module__ == 'builtins':
|
||||||
return repr(annotation)
|
|
||||||
elif annotation.__module__ == 'builtins':
|
|
||||||
return annotation.__qualname__
|
return annotation.__qualname__
|
||||||
elif typing:
|
elif typing:
|
||||||
if isinstance(annotation, typing.TypeVar):
|
if isinstance(annotation, typing.TypeVar):
|
||||||
|
@ -22,6 +22,7 @@ from six import text_type
|
|||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
|
|
||||||
import sphinx
|
import sphinx
|
||||||
|
from sphinx.locale import _
|
||||||
from sphinx.errors import SphinxError, ExtensionError
|
from sphinx.errors import SphinxError, ExtensionError
|
||||||
from sphinx.util.png import read_png_depth, write_png_depth
|
from sphinx.util.png import read_png_depth, write_png_depth
|
||||||
from sphinx.util.osutil import ensuredir, ENOENT, cd
|
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(self.starttag(node, 'div', CLASS='math'))
|
||||||
self.body.append('<p>')
|
self.body.append('<p>')
|
||||||
if node['number']:
|
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:
|
if fname is None:
|
||||||
# something failed -- use text-only as a bad substitute
|
# something failed -- use text-only as a bad substitute
|
||||||
self.body.append('<span class="math">%s</span></p>\n</div>' %
|
self.body.append('<span class="math">%s</span></p>\n</div>' %
|
||||||
|
@ -34,7 +34,8 @@ from os import path
|
|||||||
import re
|
import re
|
||||||
|
|
||||||
from six import iteritems, string_types
|
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 import nodes
|
||||||
from docutils.utils import relative_path
|
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()):
|
for line in split_lines(read_chunks()):
|
||||||
# be careful to handle names with embedded spaces correctly
|
# 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())
|
line.rstrip())
|
||||||
if not m:
|
if not m:
|
||||||
continue
|
continue
|
||||||
@ -145,7 +146,7 @@ def _strip_basic_auth(url):
|
|||||||
|
|
||||||
:rtype: ``tuple``
|
:rtype: ``tuple``
|
||||||
"""
|
"""
|
||||||
url_parts = parse.urlsplit(url)
|
url_parts = urlsplit(url)
|
||||||
username = url_parts.username
|
username = url_parts.username
|
||||||
password = url_parts.password
|
password = url_parts.password
|
||||||
frags = list(url_parts)
|
frags = list(url_parts)
|
||||||
@ -154,7 +155,7 @@ def _strip_basic_auth(url):
|
|||||||
frags[1] = "%s:%s" % (url_parts.hostname, url_parts.port)
|
frags[1] = "%s:%s" % (url_parts.hostname, url_parts.port)
|
||||||
else:
|
else:
|
||||||
frags[1] = url_parts.hostname
|
frags[1] = url_parts.hostname
|
||||||
url = parse.urlunsplit(frags)
|
url = urlunsplit(frags)
|
||||||
return (url, username, password)
|
return (url, username, password)
|
||||||
|
|
||||||
|
|
||||||
@ -208,12 +209,12 @@ def _get_safe_url(url):
|
|||||||
url, username, _ = _strip_basic_auth(url)
|
url, username, _ = _strip_basic_auth(url)
|
||||||
if username is not None:
|
if username is not None:
|
||||||
# case: url contained basic auth creds; obscure password
|
# 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)
|
safe_netloc = '{0}@{1}'.format(username, url_parts.hostname)
|
||||||
# replace original netloc w/ obscured version
|
# replace original netloc w/ obscured version
|
||||||
frags = list(url_parts)
|
frags = list(url_parts)
|
||||||
frags[1] = safe_netloc
|
frags[1] = safe_netloc
|
||||||
safe_url = parse.urlunsplit(frags)
|
safe_url = urlunsplit(frags)
|
||||||
|
|
||||||
return safe_url
|
return safe_url
|
||||||
|
|
||||||
@ -237,6 +238,13 @@ def fetch_inventory(app, uri, inv):
|
|||||||
'%s: %s' % (inv, err.__class__, err))
|
'%s: %s' % (inv, err.__class__, err))
|
||||||
return
|
return
|
||||||
try:
|
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')
|
line = f.readline().rstrip().decode('utf-8')
|
||||||
try:
|
try:
|
||||||
if line == '# Sphinx inventory version 1':
|
if line == '# Sphinx inventory version 1':
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
|
|
||||||
import sphinx
|
import sphinx
|
||||||
|
from sphinx.locale import _
|
||||||
from sphinx.application import ExtensionError
|
from sphinx.application import ExtensionError
|
||||||
from sphinx.ext.mathbase import setup_math as mathbase_setup
|
from sphinx.ext.mathbase import setup_math as mathbase_setup
|
||||||
|
|
||||||
@ -34,8 +35,9 @@ def html_visit_displaymath(self, node):
|
|||||||
if i == 0:
|
if i == 0:
|
||||||
# necessary to e.g. set the id property correctly
|
# necessary to e.g. set the id property correctly
|
||||||
if node['number']:
|
if node['number']:
|
||||||
self.body.append('<span class="eqno">(%s)</span>' %
|
self.body.append('<span class="eqno">(%s)' % node['number'])
|
||||||
node['number'])
|
self.add_permalink_ref(node, _('Permalink to this equation'))
|
||||||
|
self.body.append('</span>')
|
||||||
self.body.append(self.starttag(node, 'div', CLASS='math'))
|
self.body.append(self.starttag(node, 'div', CLASS='math'))
|
||||||
else:
|
else:
|
||||||
# but only once!
|
# but only once!
|
||||||
|