Merge remote-tracking branch 'upstream/master'
Conflicts: tests/test_build_html.py
26
.travis.yml
@@ -4,21 +4,31 @@ cache:
|
||||
directories:
|
||||
- $HOME/.cache/pip
|
||||
python:
|
||||
- "2.6"
|
||||
- "2.7"
|
||||
- "3.3"
|
||||
- "3.4"
|
||||
- "3.5"
|
||||
- "3.5-dev"
|
||||
- "pypy"
|
||||
env:
|
||||
- DOCUTILS=0.11
|
||||
- DOCUTILS=0.12
|
||||
global:
|
||||
- TEST='-v --with-timer --timer-top-n 25'
|
||||
matrix:
|
||||
- DOCUTILS=0.11
|
||||
- DOCUTILS=0.12
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- graphviz
|
||||
- texlive-latex-recommended
|
||||
- texlive-latex-extra
|
||||
- texlive-fonts-recommended
|
||||
- texlive-fonts-extra
|
||||
install:
|
||||
- pip install -U pip
|
||||
- pip install -U pip setuptools
|
||||
- pip install docutils==$DOCUTILS
|
||||
- pip install -r test-reqs.txt
|
||||
before_script: flake8
|
||||
before_script:
|
||||
- if [[ $TRAVIS_PYTHON_VERSION != '2.6' ]]; then flake8; fi
|
||||
script:
|
||||
|
||||
- if [[ $TRAVIS_PYTHON_VERSION == '3.5' ]]; then make test-async; fi
|
||||
- if [[ $TRAVIS_PYTHON_VERSION == '3.5' ]]; then make style-check test-async; fi
|
||||
- if [[ $TRAVIS_PYTHON_VERSION != '3.5' ]]; then make test; fi
|
||||
|
||||
9
AUTHORS
@@ -11,6 +11,7 @@ Other co-maintainers:
|
||||
* Rob Ruana <@RobRuana>
|
||||
* Robert Lehmann <@lehmannro>
|
||||
* Roland Meister <@rolmei>
|
||||
* Takeshi Komiya <@tk0miya>
|
||||
|
||||
Other contributors, listed alphabetically, are:
|
||||
|
||||
@@ -29,8 +30,7 @@ Other contributors, listed alphabetically, are:
|
||||
* Horst Gutmann -- internationalization support
|
||||
* Martin Hans -- autodoc improvements
|
||||
* Doug Hellmann -- graphviz improvements
|
||||
* Timotheus Kampik - JS enhancements, stop words language fix
|
||||
* Takeshi Komiya -- numref feature
|
||||
* Timotheus Kampik - JS theme & search enhancements
|
||||
* Dave Kuhlman -- original LaTeX writer
|
||||
* Blaise Laflamme -- pyramid theme
|
||||
* Thomas Lamb -- linkcheck builder
|
||||
@@ -41,6 +41,7 @@ Other contributors, listed alphabetically, are:
|
||||
* Martin Mahner -- nature theme
|
||||
* Will Maier -- directory HTML builder
|
||||
* Jacob Mason -- websupport library (GSOC project)
|
||||
* Glenn Matthews -- python domain signature improvements
|
||||
* Roland Meister -- epub builder
|
||||
* Ezio Melotti -- collapsible sidebar JavaScript
|
||||
* Daniel Neuhäuser -- JavaScript domain, Python 3 support (GSOC)
|
||||
@@ -50,7 +51,8 @@ Other contributors, listed alphabetically, are:
|
||||
* Jeppe Pihl -- literalinclude improvements
|
||||
* Rob Ruana -- napoleon extension
|
||||
* Stefan Seefeld -- toctree improvements
|
||||
* Shibukawa Yoshiki -- pluggable search API and Japanese search
|
||||
* Gregory Szorc -- performance improvements
|
||||
* Shibukawa Yoshiki -- pluggable search API and Japanese search, epub3 builder improvements
|
||||
* Taku Shimizu -- epub3 builder
|
||||
* Antonio Valentino -- qthelp builder
|
||||
* Filip Vavera -- napoleon todo directive
|
||||
@@ -63,6 +65,7 @@ Other contributors, listed alphabetically, are:
|
||||
* Michael Wilson -- Intersphinx HTTP basic auth support
|
||||
* Joel Wurtz -- cellspanning support in LaTeX
|
||||
* Hong Xu -- svg support in imgmath extension and various bug fixes
|
||||
* Bruce Mitchener -- Minor epub improvement
|
||||
|
||||
Many thanks for all contributions!
|
||||
|
||||
|
||||
513
CHANGES
@@ -1,58 +1,440 @@
|
||||
Release 1.4 alpha2 (in development)
|
||||
Release 1.5 alpha2 (in development)
|
||||
===================================
|
||||
|
||||
Incompatible changes
|
||||
--------------------
|
||||
* #2327: `latex_use_parts` is deprecated now. Use `latex_toplevel_sectioning` instead.
|
||||
* #2337: Use ``\url{URL}`` macro instead of ``\href{URL}{URL}`` in LaTeX writer.
|
||||
* #1498: manpage writer: don't make whole of item in definition list bold if it includes strong node.
|
||||
|
||||
Features added
|
||||
--------------
|
||||
* #2308: Define ``\tablecontinued`` macro to redefine the style of continued label for
|
||||
longtables.
|
||||
* Select an image by similarity if multiple images are globbed by ``.. image:: filename.*``
|
||||
* #1921: Support figure substitutions by :confval:`language` and :confval:`figure_language_filename`
|
||||
* #2245: Add ``latex_elements["passoptionstopackages"]`` option to call PassOptionsToPackages
|
||||
in early stage of preambles.
|
||||
* #2340: Math extension: support alignment of multiple equations for MathJAX.
|
||||
* #2338: Define ``\titleref`` macro to redefine the style of ``title-reference`` roles.
|
||||
* Define ``\menuselection`` and ``\accelerator`` macros to redefine the style of `menuselection` roles.
|
||||
* Define ``\crossref`` macro to redefine the style of references
|
||||
* #2301: Texts in the classic html theme should be hyphenated.
|
||||
* #2355: Define ``\termref`` macro to redefine the style of ``term`` roles.
|
||||
* Add :confval:`suppress_warnings` to suppress arbitrary warning message (experimental)
|
||||
* #2229: Fix no warning is given for unknown options
|
||||
* #2327: Add `latex_toplevel_sectioning` to switch the top level sectioning of LaTeX document.
|
||||
|
||||
Bugs fixed
|
||||
----------
|
||||
* Remove ``image/gif`` from supported_image_types of LaTeX writer (#2272)
|
||||
* Fix ValueError is raised if LANGUAGE is empty string
|
||||
* Fix unpack warning is shown when the directives generated from ``Sphinx.add_crossref_type`` is used
|
||||
* The default highlight language is now ``default``. This means that source code
|
||||
is highlighted as Python 3 (which is mostly a superset of Python 2) if possible.
|
||||
To get the old behavior back, add ``highlight_language = "python"`` to conf.py.
|
||||
* #2329: Refresh environment forcely if source directory has changed.
|
||||
* #2331: Fix code-blocks are filled by block in dvi; remove ``xcdraw`` option from xcolor package
|
||||
* Fix the confval type checker emits warnings if unicode is given to confvals which expects string value
|
||||
* #2360: Fix numref in LaTeX output is broken
|
||||
* #2361: Fix additional paragraphs inside the "compound" directive are indented
|
||||
* #2364: Fix KeyError 'rootSymbol' on Sphinx upgrade from older version.
|
||||
* #2348: Move amsmath and amssymb to before fontpkg on LaTeX writer.
|
||||
* #2368: Ignore emacs lock files like ``.#foo.rst`` by default.
|
||||
* #2262: literal_block and its caption has been separated by pagebreak in LaTeX output.
|
||||
* #2319: Fix table counter is overrided by code-block's in LaTeX. Thanks to jfbu.
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
Release 1.4 alpha1 (released Feb 14, 2016)
|
||||
|
||||
Release 1.5 alpha1 (released Sep 21, 2016)
|
||||
==========================================
|
||||
|
||||
Incompatible changes
|
||||
--------------------
|
||||
|
||||
* latex, package fancybox is not longer a dependency of sphinx.sty
|
||||
* Use ``'locales'`` as a default value of `locale_dirs`
|
||||
* latex, package ifthen is not any longer a dependency of sphinx.sty
|
||||
* latex, style file does not modify fancyvrb's Verbatim (also available as
|
||||
OriginalVerbatim) but uses sphinxVerbatim for name of custom wrapper.
|
||||
* latex, package newfloat is no longer a dependency of sphinx.sty (ref #2660;
|
||||
it was shipped with Sphinx since 1.3.4).
|
||||
* latex, literal blocks in tables do not use OriginalVerbatim but
|
||||
sphinxVerbatimintable which handles captions and wraps lines(ref #2704).
|
||||
* latex, replace ``pt`` by TeX equivalent ``bp`` if found in ``width`` or
|
||||
``height`` attribute of an image.
|
||||
* latex, if ``width`` or ``height`` attribute of an image is given with no unit,
|
||||
use ``px`` rather than ignore it.
|
||||
* latex: Separate stylesheets of pygments to independent .sty file
|
||||
* #2454: The filename of sourcelink is now changed. The value of
|
||||
`html_sourcelink_suffix` will be appended to the original filename (like
|
||||
``index.rst.txt``).
|
||||
* ``sphinx.util.copy_static_entry()`` is now deprecated.
|
||||
Use ``sphinx.util.fileutil.copy_asset()`` instead.
|
||||
* ``sphinx.util.osutil.filecopy()`` skips copying if the file has not been changed
|
||||
(ref: #2510, #2753)
|
||||
* Internet Explorer 6-8, Opera 12.1x or Safari 5.1+ support is dropped
|
||||
because jQuery version is updated from 1.11.0 to 3.1.0 (ref: #2634, #2773)
|
||||
* QtHelpBuilder doens't generate search page (ref: #2352)
|
||||
* QtHelpBuilder uses ``nonav`` theme instead of default one
|
||||
to improve readability.
|
||||
* latex: To provide good default settings to Japanese docs, Sphinx uses ``jsbooks``
|
||||
as a docclass by default if the ``language`` is ``ja``.
|
||||
* latex: To provide good default settings to Japanese docs, Sphinx uses
|
||||
``jreport`` and ``jsbooks`` as a docclass by default if the ``language`` is
|
||||
``ja``.
|
||||
* ``sphinx-quickstart`` now allows a project version is empty
|
||||
* Fix :download: role on epub/qthelp builder. They ignore the role because they don't support it.
|
||||
* ``sphinx.ext.viewcode`` doesn't work on epub building by default. ``viewcode_enable_epub`` option
|
||||
* ``sphinx.ext.viewcode`` disabled on singlehtml builder.
|
||||
* Use make-mode of ``sphinx-quickstart`` by default. To disable this, use
|
||||
``-M`` option
|
||||
* Fix ``genindex.html``, Sphinx's document template, link address to itself to satisfy xhtml standard.
|
||||
* Use epub3 builder by default. And the old epub builder is renamed to epub2.
|
||||
* Fix ``epub`` and ``epub3`` builders that contained links to ``genindex`` even if ``epub_use_index = False``.
|
||||
* `html_translator_class` is now deprecated.
|
||||
Use `Sphinx.set_translator()` API instead.
|
||||
* Drop python 2.6 and 3.3 support
|
||||
* Drop epub3 builder's ``epub3_page_progression_direction`` option (use ``epub3_writing_mode``).
|
||||
* #2877: Rename ``latex_elements['footer']`` to
|
||||
``latex_elements['postpreamble']``
|
||||
|
||||
Features added
|
||||
--------------
|
||||
|
||||
* #2951: Add ``--implicit-namespaces`` PEP-0420 support to apidoc.
|
||||
* Add ``:caption:`` option for sphinx.ext.inheritance_diagram.
|
||||
* #2471: Add config variable for default doctest flags.
|
||||
* Convert linkcheck builder to requests for better encoding handling
|
||||
* #2463, #2516: Add keywords of "meta" directive to search index
|
||||
* ``:maxdepth:`` option of toctree affects ``secnumdepth`` (ref: #2547)
|
||||
* #2575: Now ``sphinx.ext.graphviz`` allows ``:align:`` option
|
||||
* Show warnings if unknown key is specified to `latex_elements`
|
||||
* Show warnings if no domains match with `primary_domain` (ref: #2001)
|
||||
* C++, show warnings when the kind of role is misleading for the kind
|
||||
of target it refers to (e.g., using the `class` role for a function).
|
||||
* latex, writer abstracts more of text styling into customizable macros, e.g.
|
||||
the ``visit_emphasis`` will output ``\sphinxstyleemphasis`` rather than
|
||||
``\emph`` (which may be in use elsewhere or in an added LaTeX package). See
|
||||
list at end of ``sphinx.sty`` (ref: #2686)
|
||||
* latex, public names for environments and parameters used by note, warning,
|
||||
and other admonition types, allowing full customizability from the
|
||||
``'preamble'`` key or an input file (ref: feature request #2674, #2685)
|
||||
* latex, better computes column widths of some tables (as a result, there will
|
||||
be slight changes as tables now correctly fill the line width; ref: #2708)
|
||||
* latex, sphinxVerbatim environment is more easily customizable (ref: #2704).
|
||||
In addition to already existing VerbatimColor and VerbatimBorderColor:
|
||||
|
||||
- two lengths ``\sphinxverbatimsep`` and ``\sphinxverbatimborder``,
|
||||
- booleans ``\ifsphinxverbatimwithframe`` and ``\ifsphinxverbatimwrapslines``.
|
||||
|
||||
* latex, captions for literal blocks inside tables are handled, and long code
|
||||
lines wrapped to fit table cell (ref: #2704)
|
||||
* #2597: Show warning messages as darkred
|
||||
* latex, allow image dimensions using px unit (default is 96px=1in)
|
||||
* Show warnings if invalid dimension units found
|
||||
* #2650: Add ``--pdb`` option to setup.py command
|
||||
* latex, make the use of ``\small`` for code listings customizable (ref #2721)
|
||||
* #2663: Add ``--warning-is-error`` option to setup.py command
|
||||
* Show warnings if deprecated latex options are used
|
||||
* Add sphinx.config.ENUM to check the config values is in candidates
|
||||
* math: Add hyperlink marker to each equations in HTML output
|
||||
* Add new theme ``nonav`` that doesn't include any navigation links.
|
||||
This is for any help generator like qthelp.
|
||||
* #2680: `sphinx.ext.todo` now emits warnings if `todo_emit_warnings` enabled.
|
||||
Also, it emits an additional event named `todo-defined` to handle the TODO
|
||||
entries in 3rd party extensions.
|
||||
* Python domain signature parser now uses the xref mixin for 'exceptions',
|
||||
allowing exception classes to be autolinked.
|
||||
* #2513: Add `latex_engine` to switch the LaTeX engine by conf.py
|
||||
* #2682: C++, basic support for attributes (C++11 style and GNU style).
|
||||
The new configuration variables 'cpp_id_attributes' and 'cpp_paren_attributes'
|
||||
can be used to introduce custom attributes.
|
||||
* #1958: C++, add configuration variable 'cpp_index_common_prefix' for removing
|
||||
prefixes from the index text of C++ objects.
|
||||
* C++, added concept directive. Thanks to mickk-on-cpp.
|
||||
* C++, added support for template introduction syntax. Thanks to mickk-on-cpp.
|
||||
* #2725: latex builder: allow to use user-defined template file (experimental)
|
||||
* apidoc now avoids invalidating cached files by not writing to files whose
|
||||
content doesn't change. This can lead to significant performance wins if
|
||||
apidoc is run frequently.
|
||||
* #2851: ``sphinx.ext.math`` emits missing-reference event if equation not found
|
||||
* #1210: ``eqref`` role now supports cross reference
|
||||
* #2892: Added ``-a`` (``--append-syspath``) option to ``sphinx-apidoc``
|
||||
* #1604: epub3 builder: Obey font-related CSS when viewing in iBooks.
|
||||
* #646: ``option`` directive support '.' character as a part of options
|
||||
* Add document about kindlegen and fix document structure for it.
|
||||
* #2474: Add ``intersphinx_timeout`` option to ``sphinx.ext.intersphinx``
|
||||
* #2926: EPUB3 builder supports vertical mode (``epub3_writing_mode`` option)
|
||||
* #2695: ``build_sphinx`` subcommand for setuptools handles exceptions as same
|
||||
as ``sphinx-build`` does
|
||||
* #326: `numref` role can also refer sections
|
||||
* #2916: `numref` role can also refer caption as an its linktext
|
||||
|
||||
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.
|
||||
* `sphinx.ext.autodoc` crashes if target code imports * from mock modules
|
||||
by `autodoc_mock_imports`.
|
||||
* #1953: ``Sphinx.add_node`` does not add handlers the translator installed by
|
||||
`html_translator_class`
|
||||
* #1797: text builder inserts blank line on top
|
||||
* #2894: quickstart main() doesn't use argv argument
|
||||
* #2874: gettext builder could not extract all text under the ``only``
|
||||
directives
|
||||
* #2485: autosummary crashes with multiple source_suffix values
|
||||
* #1734: Could not translate the caption of toctree directive
|
||||
* Could not translate the content of meta directive (ref: #1734)
|
||||
* #2550: external links are opened in help viewer
|
||||
* #2687: Running Sphinx multiple times produces 'already registered' warnings
|
||||
|
||||
Release 1.4.7 (in development)
|
||||
==============================
|
||||
|
||||
Bugs fixed
|
||||
----------
|
||||
|
||||
* #2890: Quickstart should return an error consistently on all error conditions
|
||||
* #2870: flatten genindex columns' heights.
|
||||
* #2856: Search on generated HTML site doesnt find some symbols
|
||||
* #2882: Fall back to a GET request on 403 status in linkcheck
|
||||
* #2902: jsdump.loads fails to load search index if keywords starts with
|
||||
underscore
|
||||
* #2900: Fix epub content.opf: add auto generated orphan files to spine.
|
||||
* #2899: Fix ``hasdoc()`` function in Jinja2 template. It can detect ``genindex``, ``search`` collectly.
|
||||
* #2901: Fix epub result: skip creating links from image tags to original image files.
|
||||
* #2917: inline code is hyphenated on HTML
|
||||
* #1462: autosummary warns for namedtuple with attribute with trailing underscore
|
||||
* Could not reference equations if ``:nowrap:`` option specified
|
||||
* #2873: code-block overflow in latex (due to commas)
|
||||
* #1060, #2056: sphinx.ext.intersphinx: broken links are generated if relative
|
||||
paths are used in `intersphinx_mapping`
|
||||
* #2931: code-block directive with same :caption: causes warning of duplicate
|
||||
target. Now `code-block` and `literalinclude` does not define hyperlink
|
||||
target using its caption automatially.
|
||||
* #2962: latex: missing label of longtable
|
||||
* #2968: autodoc: show-inheritance option breaks docstrings
|
||||
|
||||
Release 1.4.6 (released Aug 20, 2016)
|
||||
=====================================
|
||||
|
||||
Incompatible changes
|
||||
--------------------
|
||||
|
||||
* #2867: linkcheck builder crashes with six-1.4. Now Sphinx depends on six-1.5 or
|
||||
later
|
||||
|
||||
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
|
||||
* #2789: `sphinx.ext.intersphinx` generates wrong hyperlinks if the inventory is given
|
||||
* parsing errors for caption of code-blocks are displayed in document (ref: #2845)
|
||||
* #2846: ``singlehtml`` builder does not include figure numbers
|
||||
* #2816: Fix data from builds cluttering the ``Domain.initial_data`` class attributes
|
||||
|
||||
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
|
||||
--------------
|
||||
|
||||
* Now :confval:`suppress_warnings` accepts following configurations (ref: #2451, #2466):
|
||||
|
||||
- ``app.add_node``
|
||||
- ``app.add_directive``
|
||||
- ``app.add_role``
|
||||
- ``app.add_generic_role``
|
||||
- ``app.add_source_parser``
|
||||
- ``image.data_uri``
|
||||
- ``image.nonlocal_uri``
|
||||
|
||||
* #2453: LaTeX writer allows page breaks in topic contents; and their
|
||||
horizontal extent now fits in the line width (with shadow in margin). Also
|
||||
warning-type admonitions allow page breaks and their vertical spacing has
|
||||
been made more coherent with the one for hint-type notices (ref #2446).
|
||||
|
||||
* #2459: the framing of literal code-blocks in LaTeX output (and not only the
|
||||
code lines themselves) obey the indentation in lists or quoted blocks.
|
||||
|
||||
* #2343: the long source lines in code-blocks are wrapped (without modifying
|
||||
the line numbering) in LaTeX output (ref #1534, #2304).
|
||||
|
||||
Bugs fixed
|
||||
----------
|
||||
|
||||
* #2370: the equations are slightly misaligned in LaTeX writer
|
||||
* #1817, #2077: suppress pep8 warnings on conf.py generated by sphinx-quickstart
|
||||
* #2407: building docs crash if document includes large data image URIs
|
||||
* #2436: Sphinx does not check version by :confval:`needs_sphinx` if loading extensions failed
|
||||
* #2397: Setup shorthandoff for turkish documents
|
||||
* #2447: VerbatimBorderColor wrongly used also for captions of PDF
|
||||
* #2456: C++, fix crash related to document merging (e.g., singlehtml and Latex builders).
|
||||
* #2446: latex(pdf) sets local tables of contents (or more generally topic
|
||||
nodes) in unbreakable boxes, causes overflow at bottom
|
||||
* #2476: Omit MathJax markers if :nowrap: is given
|
||||
* #2465: latex builder fails in case no caption option is provided to toctree directive
|
||||
* Sphinx crashes if self referenced toctree found
|
||||
* #2481: spelling mistake for mecab search splitter. Thanks to Naoki Sato.
|
||||
* #2309: Fix could not refer "indirect hyperlink targets" by ref-role
|
||||
* intersphinx fails if mapping URL contains any port
|
||||
* #2088: intersphinx crashes if the mapping URL requires basic auth
|
||||
* #2304: auto line breaks in latexpdf codeblocks
|
||||
* #1534: Word wrap long lines in Latex verbatim blocks
|
||||
* #2460: too much white space on top of captioned literal blocks in PDF output
|
||||
* Show error reason when multiple math extensions are loaded (ref: #2499)
|
||||
* #2483: any figure number was not assigned if figure title contains only non text objects
|
||||
* #2501: Unicode subscript numbers are normalized in LaTeX
|
||||
* #2492: Figure directive with :figwidth: generates incorrect Latex-code
|
||||
* The caption of figure is always put on center even if ``:align:`` was specified
|
||||
* #2526: LaTeX writer crashes if the section having only images
|
||||
* #2522: Sphinx touches mo files under installed directory that caused permission error.
|
||||
* #2536: C++, fix crash when an immediately nested scope has the same name as the current scope.
|
||||
* #2555: Fix crash on any-references with unicode.
|
||||
* #2517: wrong bookmark encoding in PDF if using LuaLaTeX
|
||||
* #2521: generated Makefile causes BSD make crashed if sphinx-build not found
|
||||
* #2470: ``typing`` backport package causes autodoc errors with python 2.7
|
||||
* ``sphinx.ext.intersphinx`` crashes if non-string value is used for key of `intersphinx_mapping`
|
||||
* #2518: `intersphinx_mapping` disallows non alphanumeric keys
|
||||
* #2558: unpack error on devhelp builder
|
||||
* #2561: Info builder crashes when a footnote contains a link
|
||||
* #2565: The descriptions of objects generated by ``sphinx.ext.autosummary`` overflow lines at LaTeX writer
|
||||
* Extend pdflatex config in sphinx.sty to subparagraphs (ref: #2551)
|
||||
* #2445: `rst_prolog` and `rst_epilog` affect to non reST sources
|
||||
* #2576: ``sphinx.ext.imgmath`` crashes if subprocess raises error
|
||||
* #2577: ``sphinx.ext.imgmath``: Invalid argument are passed to dvisvgm
|
||||
* #2556: Xapian search does not work with Python 3
|
||||
* #2581: The search doesn't work if language="es" (spanish)
|
||||
* #2382: Adjust spacing after abbreviations on figure numbers in LaTeX writer
|
||||
* #2383: The generated footnote by `latex_show_urls` overflows lines
|
||||
* #2497, #2552: The label of search button does not fit for the button itself
|
||||
|
||||
|
||||
Release 1.4.1 (released Apr 12, 2016)
|
||||
=====================================
|
||||
|
||||
Incompatible changes
|
||||
--------------------
|
||||
|
||||
* The default format of `today_fmt` and `html_last_updated_fmt` is back to
|
||||
strftime format again. Locale Date Markup Language is also supported for
|
||||
backward compatibility until Sphinx-1.5.
|
||||
|
||||
Translations
|
||||
------------
|
||||
|
||||
* Added Welsh translation, thanks to Geraint Palmer.
|
||||
* Added Greek translation, thanks to Stelios Vitalis.
|
||||
* Added Esperanto translation, thanks to Dinu Gherman.
|
||||
* Added Hindi translation, thanks to Purnank H. Ghumalia.
|
||||
* Added Romanian translation, thanks to Razvan Stefanescu.
|
||||
|
||||
Bugs fixed
|
||||
----------
|
||||
|
||||
* C++, added support for ``extern`` and ``thread_local``.
|
||||
* C++, type declarations are now using the prefixes ``typedef``, ``using``, and ``type``,
|
||||
depending on the style of declaration.
|
||||
* #2413: C++, fix crash on duplicate declarations
|
||||
* #2394: Sphinx crashes when html_last_updated_fmt is invalid
|
||||
* #2408: dummy builder not available in Makefile and make.bat
|
||||
* #2412: hyperlink targets are broken in LaTeX builder
|
||||
* figure directive crashes if non paragraph item is given as caption
|
||||
* #2418: time formats no longer allowed in today_fmt
|
||||
* #2395: Sphinx crashes if unicode character in image filename
|
||||
* #2396: "too many values to unpack" in genindex-single
|
||||
* #2405: numref link in PDF jumps to the wrong location
|
||||
* #2414: missing number in PDF hyperlinks to code listings
|
||||
* #2440: wrong import for gmtime. Thanks to Uwe L. Korn.
|
||||
|
||||
|
||||
Release 1.4 (released Mar 28, 2016)
|
||||
===================================
|
||||
|
||||
Incompatible changes
|
||||
--------------------
|
||||
* Drop ``PorterStemmer`` package support. Use ``PyStemmer`` instead of ``PorterStemmer``
|
||||
to accelerate stemming.
|
||||
* sphinx_rtd_theme has become optional. Please install it manually.
|
||||
@@ -84,10 +466,14 @@ Incompatible changes
|
||||
``"MMMM dd, YYYY"`` is default format for `today_fmt` and `html_last_updated_fmt`.
|
||||
However strftime format like ``"%B %d, %Y"`` is also supported for backward
|
||||
compatibility until Sphinx-1.5. Later format will be disabled from Sphinx-1.5.
|
||||
* #2327: `latex_use_parts` is deprecated now. Use `latex_toplevel_sectioning` instead.
|
||||
* #2337: Use ``\url{URL}`` macro instead of ``\href{URL}{URL}`` in LaTeX writer.
|
||||
* #1498: manpage writer: don't make whole of item in definition list bold if it includes strong node.
|
||||
* #582: Remove hint message from quick search box for html output.
|
||||
* #2378: Sphinx now bundles newfloat.sty
|
||||
|
||||
Features added
|
||||
--------------
|
||||
|
||||
* #2092: add todo directive support in napoleon package.
|
||||
* #1962: when adding directives, roles or nodes from an extension, warn if such
|
||||
an element is already present (built-in or added by another extension).
|
||||
@@ -130,10 +516,24 @@ Features added
|
||||
* #1853: support custom text splitter on html search with ``language='ja'``.
|
||||
* #2320: classifier of glossary terms can be used for index entries grouping key.
|
||||
The classifier also be used for translation. See also :ref:`glossary-directive`.
|
||||
* #2308: Define ``\tablecontinued`` macro to redefine the style of continued label for
|
||||
longtables.
|
||||
* Select an image by similarity if multiple images are globbed by ``.. image:: filename.*``
|
||||
* #1921: Support figure substitutions by :confval:`language` and :confval:`figure_language_filename`
|
||||
* #2245: Add ``latex_elements["passoptionstopackages"]`` option to call PassOptionsToPackages
|
||||
in early stage of preambles.
|
||||
* #2340: Math extension: support alignment of multiple equations for MathJAX.
|
||||
* #2338: Define ``\titleref`` macro to redefine the style of ``title-reference`` roles.
|
||||
* Define ``\menuselection`` and ``\accelerator`` macros to redefine the style of `menuselection` roles.
|
||||
* Define ``\crossref`` macro to redefine the style of references
|
||||
* #2301: Texts in the classic html theme should be hyphenated.
|
||||
* #2355: Define ``\termref`` macro to redefine the style of ``term`` roles.
|
||||
* Add :confval:`suppress_warnings` to suppress arbitrary warning message (experimental)
|
||||
* #2229: Fix no warning is given for unknown options
|
||||
* #2327: Add `latex_toplevel_sectioning` to switch the top level sectioning of LaTeX document.
|
||||
|
||||
Bugs fixed
|
||||
----------
|
||||
|
||||
* #1913: C++, fix assert bug for enumerators in next-to-global and global scope.
|
||||
* C++, fix parsing of 'signed char' and 'unsigned char' as types.
|
||||
* C++, add missing support for 'friend' functions.
|
||||
@@ -155,7 +555,30 @@ Bugs fixed
|
||||
* #2311: Fix sphinx.ext.inheritance_diagram raises AttributeError
|
||||
* #2251: Line breaks in .rst files are transferred to .pot files in a wrong way.
|
||||
* #794: Fix date formatting in latex output is not localized
|
||||
|
||||
* Remove ``image/gif`` from supported_image_types of LaTeX writer (#2272)
|
||||
* Fix ValueError is raised if LANGUAGE is empty string
|
||||
* Fix unpack warning is shown when the directives generated from ``Sphinx.add_crossref_type`` is used
|
||||
* The default highlight language is now ``default``. This means that source code
|
||||
is highlighted as Python 3 (which is mostly a superset of Python 2) if possible.
|
||||
To get the old behavior back, add ``highlight_language = "python"`` to conf.py.
|
||||
* #2329: Refresh environment forcely if source directory has changed.
|
||||
* #2331: Fix code-blocks are filled by block in dvi; remove ``xcdraw`` option from
|
||||
xcolor package
|
||||
* Fix the confval type checker emits warnings if unicode is given to confvals which expects string value
|
||||
* #2360: Fix numref in LaTeX output is broken
|
||||
* #2361: Fix additional paragraphs inside the "compound" directive are indented
|
||||
* #2364: Fix KeyError 'rootSymbol' on Sphinx upgrade from older version.
|
||||
* #2348: Move amsmath and amssymb to before fontpkg on LaTeX writer.
|
||||
* #2368: Ignore emacs lock files like ``.#foo.rst`` by default.
|
||||
* #2262: literal_block and its caption has been separated by pagebreak in LaTeX output.
|
||||
* #2319: Fix table counter is overrided by code-block's in LaTeX. Thanks to jfbu.
|
||||
* Fix unpack warning if combinated with 3rd party domain extensions.
|
||||
* #1153: Fix figures in sidebar causes latex build error.
|
||||
* #2358: Fix user-preamble could not override the tocdepth definition.
|
||||
* #2358: Redece tocdepth if ``part`` or ``chapter`` is used for top_sectionlevel.
|
||||
* #2351: Fix footnote spacing
|
||||
* #2363: Fix ``toctree()`` in templates generates broken links in SingleHTMLBuilder.
|
||||
* #2366: Fix empty hyperref is generated on toctree in HTML builder.
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
@@ -163,18 +586,6 @@ Documentation
|
||||
* #1757: Fix for usage of :confval:`html_last_updated_fmt`. Thanks to Ralf Hemmecke.
|
||||
|
||||
|
||||
Release 1.3.7 (in development)
|
||||
==============================
|
||||
|
||||
Bugs fixed
|
||||
----------
|
||||
|
||||
* #2358: Fix user-preamble could not override the tocdepth definition.
|
||||
* #2358: Redece tocdepth if ``part`` or ``chapter`` is used for top_sectionlevel.
|
||||
* #2351: Fix footnote spacing
|
||||
* #2363: Fix ``toctree()`` in templates generates broken links in SingleHTMLBuilder.
|
||||
|
||||
|
||||
Release 1.3.6 (released Feb 29, 2016)
|
||||
=====================================
|
||||
|
||||
|
||||
15
EXAMPLES
@@ -9,7 +9,12 @@ be included, please mail to `the Google group
|
||||
I've grouped the list into sections to make it easier to find
|
||||
interesting examples.
|
||||
|
||||
Documentation using the default theme
|
||||
Documentation using the alabaster theme
|
||||
---------------------------------------
|
||||
|
||||
* PyLangAcq: http://pylangacq.org/
|
||||
|
||||
Documentation using the classic theme
|
||||
-------------------------------------
|
||||
|
||||
* APSW: http://apidoc.apsw.googlecode.com/hg/index.html
|
||||
@@ -54,7 +59,9 @@ Documentation using the default theme
|
||||
* python-apt: http://apt.alioth.debian.org/python-apt-doc/
|
||||
* PyUblas: https://documen.tician.de/pyublas/
|
||||
* Quex: http://quex.sourceforge.net/doc/html/main.html
|
||||
* Ring programming language: http://ring-lang.sourceforge.net/doc/index.html
|
||||
* Scapy: http://www.secdev.org/projects/scapy/doc/
|
||||
* Seaborn: https://stanford.edu/~mwaskom/software/seaborn/
|
||||
* Segway: http://noble.gs.washington.edu/proj/segway/doc/1.1.0/segway.html
|
||||
* SimPy: http://simpy.readthedocs.org/en/latest/
|
||||
* SymPy: http://docs.sympy.org/
|
||||
@@ -62,11 +69,12 @@ Documentation using the default theme
|
||||
* z3c: http://www.ibiblio.org/paulcarduner/z3ctutorial/
|
||||
|
||||
|
||||
Documentation using a customized version of the default theme
|
||||
Documentation using a customized version of the classic theme
|
||||
-------------------------------------------------------------
|
||||
|
||||
* Advanced Generic Widgets:
|
||||
http://xoomer.virgilio.it/infinity77/AGW_Docs/index.html
|
||||
* Arb: http://fredrikj.net/arb/
|
||||
* Bazaar: http://doc.bazaar.canonical.com/en/
|
||||
* CakePHP: http://book.cakephp.org/2.0/en/index.html
|
||||
* Chaco: http://docs.enthought.com/chaco/
|
||||
@@ -121,9 +129,11 @@ Documentation using another builtin theme
|
||||
-----------------------------------------
|
||||
|
||||
* C/C++ Development with Eclipse: http://eclipsebook.in/ (agogo)
|
||||
* ESWP3 (http://eswp3.org) (sphinx_rtd_theme)
|
||||
* Jinja: http://jinja.pocoo.org/ (scrolls)
|
||||
* jsFiddle: http://doc.jsfiddle.net/ (nature)
|
||||
* libLAS: http://www.liblas.org/ (nature)
|
||||
* Linguistica: http://linguistica-uchicago.github.io/lxa5/ (sphinx_rtd_theme)
|
||||
* MPipe: http://vmlaker.github.io/mpipe/ (sphinx13)
|
||||
* pip: https://pip.pypa.io/en/latest/ (sphinx_rtd_theme)
|
||||
* Pyramid web framework:
|
||||
@@ -157,6 +167,7 @@ Documentation using a custom theme/integrated in a site
|
||||
* Flask-OpenID: http://pythonhosted.org/Flask-OpenID/
|
||||
* Gameduino: http://excamera.com/sphinx/gameduino/
|
||||
* GeoServer: http://docs.geoserver.org/
|
||||
* GHC - Glasgow Haskell Compiler: http://downloads.haskell.org/~ghc/master/users-guide/
|
||||
* Glashammer: http://glashammer.org/
|
||||
* Istihza (Turkish Python documentation project): http://belgeler.istihza.com/py2/
|
||||
* Lasso: http://lassoguide.com/
|
||||
|
||||
@@ -13,6 +13,7 @@ include sphinx-build.py
|
||||
include sphinx-quickstart.py
|
||||
include sphinx-apidoc.py
|
||||
|
||||
recursive-include sphinx/templates *
|
||||
recursive-include sphinx/texinputs *
|
||||
recursive-include sphinx/themes *
|
||||
recursive-include sphinx/locale *
|
||||
@@ -20,8 +21,7 @@ recursive-include sphinx/search/non-minified-js *.js
|
||||
recursive-include sphinx/ext/autosummary/templates *
|
||||
recursive-include tests *
|
||||
recursive-include utils *
|
||||
include sphinx/pycode/Grammar-py2.txt
|
||||
include sphinx/pycode/Grammar-py3.txt
|
||||
include sphinx/pycode/Grammar-py*
|
||||
|
||||
recursive-include doc *
|
||||
prune doc/_build
|
||||
|
||||
13
Makefile
@@ -6,10 +6,12 @@ PYTHON ?= python
|
||||
DONT_CHECK = -i build -i dist -i sphinx/style/jquery.js \
|
||||
-i sphinx/pycode/pgen2 -i sphinx/util/smartypants.py \
|
||||
-i .ropeproject -i doc/_build -i tests/path.py \
|
||||
-i tests/coverage.py -i env -i utils/convert.py \
|
||||
-i tests/coverage.py -i utils/convert.py \
|
||||
-i tests/typing_test_data.py \
|
||||
-i tests/test_autodoc_py35.py \
|
||||
-i tests/roots/test-warnings/undecodable.rst \
|
||||
-i tests/build \
|
||||
-i tests/roots/test-warnings/undecodable.rst \
|
||||
-i sphinx/search/da.py \
|
||||
-i sphinx/search/de.py \
|
||||
-i sphinx/search/en.py \
|
||||
@@ -33,12 +35,15 @@ all: clean-pyc clean-backupfiles style-check test
|
||||
style-check:
|
||||
@$(PYTHON) utils/check_sources.py $(DONT_CHECK) .
|
||||
|
||||
clean: clean-pyc clean-patchfiles clean-backupfiles clean-generated
|
||||
clean: clean-pyc clean-pycache clean-patchfiles clean-backupfiles clean-generated clean-testfiles
|
||||
|
||||
clean-pyc:
|
||||
find . -name '*.pyc' -exec rm -f {} +
|
||||
find . -name '*.pyo' -exec rm -f {} +
|
||||
|
||||
clean-pycache:
|
||||
find . -name __pycache__ -exec rm -rf {} +
|
||||
|
||||
clean-patchfiles:
|
||||
find . -name '*.orig' -exec rm -f {} +
|
||||
find . -name '*.rej' -exec rm -f {} +
|
||||
@@ -50,6 +55,10 @@ clean-backupfiles:
|
||||
clean-generated:
|
||||
rm -f utils/*3.py*
|
||||
|
||||
clean-testfiles:
|
||||
rm -rf tests/build
|
||||
rm -rf .tox/
|
||||
|
||||
pylint:
|
||||
@pylint --rcfile utils/pylintrc sphinx
|
||||
|
||||
|
||||
@@ -33,6 +33,12 @@ Install from cloned source as editable::
|
||||
pip install -e .
|
||||
|
||||
|
||||
Release signatures
|
||||
==================
|
||||
|
||||
Releases are signed with `498D6B9E <https://pgp.mit.edu/pks/lookup?op=vindex&search=0x102C2C17498D6B9E>`_
|
||||
|
||||
|
||||
Reading the docs
|
||||
================
|
||||
|
||||
|
||||
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 |
25
doc/_templates/index.html
vendored
@@ -5,17 +5,16 @@
|
||||
|
||||
<div class="quotebar">
|
||||
<p><em>{%trans%}What users say:{%endtrans%}</em></p>
|
||||
<p>{%trans%}“Cheers for a great tool that actually makes programmers <b>want</b>
|
||||
to write documentation!”{%endtrans%}</p>
|
||||
<p>{%trans%}“Cheers for a great tool that actually makes programmers <b>want</b>
|
||||
to write documentation!“{%endtrans%}</p>
|
||||
</div>
|
||||
|
||||
<p>{%trans%}
|
||||
Sphinx is a tool that makes it easy to create intelligent and beautiful
|
||||
documentation, written by Georg Brandl and licensed under the BSD license.{%endtrans%}</p>
|
||||
<p>{%trans%}It was originally created for <a href="https://docs.python.org/">the
|
||||
new Python documentation</a>, and it has excellent facilities for the
|
||||
documentation of Python projects, but C/C++ is already supported as well,
|
||||
and it is planned to add special support for other languages as well. Of
|
||||
Python documentation</a>, and it has excellent facilities for the
|
||||
documentation of software projects in a range of languages. Of
|
||||
course, this site is also created from reStructuredText sources using
|
||||
Sphinx! The following features should be highlighted:{%endtrans%}
|
||||
</p>
|
||||
@@ -31,7 +30,7 @@
|
||||
module indices{%endtrans%}</li>
|
||||
<li>{%trans%}<b>Code handling:</b> automatic highlighting using the <a
|
||||
href="http://pygments.org">Pygments</a> highlighter{%endtrans%}</li>
|
||||
<li>{%trans path=pathto('extensions')%}<b>Extensions:</b> automatic testing of code snippets, inclusion of
|
||||
<li>{%trans path=pathto('ext/builtins')%}<b>Extensions:</b> automatic testing of code snippets, inclusion of
|
||||
docstrings from Python modules (API docs), and
|
||||
<a href="{{ path }}#builtin-sphinx-extensions">more</a>{%endtrans%}</li>
|
||||
<li>{%trans path=pathto('develop')%}<b>Contributed extensions:</b> more than
|
||||
@@ -47,17 +46,17 @@
|
||||
|
||||
<h2 style="margin-bottom: 0">{%trans%}Documentation{%endtrans%}</h2>
|
||||
|
||||
<table class="contentstable" align="center" style="margin-left: 30px"><tr>
|
||||
<td width="50%">
|
||||
<table class="contentstable"><tr>
|
||||
<td>
|
||||
<p class="biglink"><a class="biglink" href="{{ pathto("tutorial") }}">{%trans%}First steps with Sphinx{%endtrans%}</a><br/>
|
||||
<span class="linkdescr">{%trans%}overview of basic tasks{%endtrans%}</span></p>
|
||||
<p class="biglink"><a class="biglink" href="{{ pathto("contents") }}">{%trans%}Contents{%endtrans%}</a><br/>
|
||||
<span class="linkdescr">{%trans%}for a complete overview{%endtrans%}</span></p>
|
||||
</td><td width="50%">
|
||||
<p class="biglink"><a class="biglink" href="{{ pathto("search") }}">{%trans%}Search page{%endtrans%}</a><br/>
|
||||
<span class="linkdescr">{%trans%}search the documentation{%endtrans%}</span></p>
|
||||
<p class="biglink"><a class="biglink" href="{{ pathto("genindex") }}">{%trans%}General Index{%endtrans%}</a><br/>
|
||||
<span class="linkdescr">{%trans%}all functions, classes, terms{%endtrans%}</span></p>
|
||||
</td><td>
|
||||
{%- if hasdoc('search') %}<p class="biglink"><a class="biglink" href="{{ pathto("search") }}">{%trans%}Search page{%endtrans%}</a><br/>
|
||||
<span class="linkdescr">{%trans%}search the documentation{%endtrans%}</span></p>{%- endif %}
|
||||
{%- if hasdoc('genindex') %}<p class="biglink"><a class="biglink" href="{{ pathto("genindex") }}">{%trans%}General Index{%endtrans%}</a><br/>
|
||||
<span class="linkdescr">{%trans%}all functions, classes, terms{%endtrans%}</span></p>{%- endif %}
|
||||
</td></tr>
|
||||
</table>
|
||||
|
||||
|
||||
4
doc/_themes/sphinx13/layout.html
vendored
@@ -57,8 +57,8 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block rootrellink %}
|
||||
<li><a href="{{ pathto('index') }}">Sphinx home</a> |</li>
|
||||
<li><a href="{{ pathto('contents') }}">Documentation</a> »</li>
|
||||
<li><a href="{{ pathto('index') }}">Sphinx home</a> |</li>
|
||||
<li><a href="{{ pathto('contents') }}">Documentation</a> »</li>
|
||||
{% endblock %}
|
||||
|
||||
{% block header %}
|
||||
|
||||
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 |
6
doc/_themes/sphinx13/static/sphinx13.css
vendored
@@ -394,3 +394,9 @@ div.viewcode-block:target {
|
||||
border-top: 1px solid #ac9;
|
||||
border-bottom: 1px solid #ac9;
|
||||
}
|
||||
|
||||
.contentstable {
|
||||
margin-left: 30px;
|
||||
margin: 0 auto;
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
BIN
doc/_themes/sphinx13/static/sphinxheader.png
vendored
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 11 KiB |
@@ -140,6 +140,11 @@ The builder's "name" must be given to the **-b** command-line option of
|
||||
|
||||
.. autoattribute:: supported_image_types
|
||||
|
||||
.. deprecated:: 1.5
|
||||
|
||||
Since Sphinx-1.5, the epub3 builder is used for the default builder of epub.
|
||||
Now EpubBuilder is renamed to epub2.
|
||||
|
||||
.. module:: sphinx.builders.epub3
|
||||
.. class:: Epub3Builder
|
||||
|
||||
@@ -149,9 +154,6 @@ The builder's "name" must be given to the **-b** command-line option of
|
||||
`<http://idpf.org/epub>`_ or `<https://en.wikipedia.org/wiki/EPUB>`_.
|
||||
The builder creates *EPUB 3* files.
|
||||
|
||||
This builder is still *experimental* because it can't generate valid EPUB 3
|
||||
files.
|
||||
|
||||
.. autoattribute:: name
|
||||
|
||||
.. autoattribute:: format
|
||||
@@ -160,6 +162,10 @@ The builder's "name" must be given to the **-b** command-line option of
|
||||
|
||||
.. versionadded:: 1.4
|
||||
|
||||
.. versionchanged:: 1.5
|
||||
|
||||
Since Sphinx-1.5, the epub3 builder is used for the default builder of epub.
|
||||
|
||||
.. module:: sphinx.builders.latex
|
||||
.. class:: LaTeXBuilder
|
||||
|
||||
@@ -271,8 +277,7 @@ for details.
|
||||
A module that implements `dump()`, `load()`, `dumps()` and `loads()`
|
||||
functions that conform to the functions with the same names from the
|
||||
pickle module. Known modules implementing this interface are
|
||||
`simplejson` (or `json` in Python 2.6), `phpserialize`, `plistlib`,
|
||||
and others.
|
||||
`simplejson`, `phpserialize`, `plistlib`, and others.
|
||||
|
||||
.. attribute:: out_suffix
|
||||
|
||||
|
||||
@@ -36,9 +36,9 @@ epub_author = 'Georg Brandl'
|
||||
epub_publisher = 'http://sphinx-doc.org/'
|
||||
epub_scheme = 'url'
|
||||
epub_identifier = epub_publisher
|
||||
epub_pre_files = [('index.html', 'Welcome')]
|
||||
epub_post_files = [('install.html', 'Installing Sphinx'),
|
||||
('develop.html', 'Sphinx development')]
|
||||
epub_pre_files = [('index.xhtml', 'Welcome')]
|
||||
epub_post_files = [('install.xhtml', 'Installing Sphinx'),
|
||||
('develop.xhtml', 'Sphinx development')]
|
||||
epub_exclude_files = ['_static/opensearch.xml', '_static/doctools.js',
|
||||
'_static/jquery.js', '_static/searchtools.js',
|
||||
'_static/underscore.js', '_static/basic.css',
|
||||
@@ -47,7 +47,8 @@ epub_fix_images = False
|
||||
epub_max_image_width = 0
|
||||
epub_show_urls = 'inline'
|
||||
epub_use_index = False
|
||||
epub_guide = (('toc', 'contents.html', u'Table of Contents'),)
|
||||
epub_guide = (('toc', 'contents.xhtml', u'Table of Contents'),)
|
||||
epub3_description = 'Sphinx documentation generator system manual'
|
||||
|
||||
latex_documents = [('contents', 'sphinx.tex', 'Sphinx Documentation',
|
||||
'Georg Brandl', 'manual', 1)]
|
||||
|
||||
200
doc/config.rst
@@ -56,7 +56,7 @@ General configuration
|
||||
|
||||
.. confval:: extensions
|
||||
|
||||
A list of strings that are module names of Sphinx extensions. These can be
|
||||
A list of strings that are module names of :ref:`extensions`. These can be
|
||||
extensions coming with Sphinx (named ``sphinx.ext.*``) or custom ones.
|
||||
|
||||
Note that you can extend :data:`sys.path` within the conf file if your
|
||||
@@ -218,6 +218,13 @@ General configuration
|
||||
|
||||
Sphinx supports following warning types:
|
||||
|
||||
* app.add_node
|
||||
* app.add_directive
|
||||
* app.add_role
|
||||
* app.add_generic_role
|
||||
* app.add_source_parser
|
||||
* image.data_uri
|
||||
* image.nonlocal_uri
|
||||
* ref.term
|
||||
* ref.ref
|
||||
* ref.numref
|
||||
@@ -276,19 +283,31 @@ General configuration
|
||||
.. confval:: numfig
|
||||
|
||||
If true, figures, tables and code-blocks are automatically numbered if they
|
||||
have a caption. For now, it works only with the HTML builder. Default is ``False``.
|
||||
have a caption. At same time, the `numref` role is enabled. For now, it
|
||||
works only with the HTML builder and LaTeX builder. Default is ``False``.
|
||||
|
||||
.. note::
|
||||
|
||||
LaTeX builder always assign numbers whether this option is enabled or not.
|
||||
|
||||
.. versionadded:: 1.3
|
||||
|
||||
.. confval:: numfig_format
|
||||
|
||||
A dictionary mapping ``'figure'``, ``'table'`` and ``'code-block'`` to
|
||||
strings that are used for format of figure numbers. Default is to use
|
||||
``'Fig. %s'`` for ``'figure'``, ``'Table %s'`` for ``'table'`` and
|
||||
``'Listing %s'`` for ``'code-block'``.
|
||||
A dictionary mapping ``'figure'``, ``'table'``, ``'code-block'`` and
|
||||
``'section'`` to strings that are used for format of figure numbers.
|
||||
As a special character, `%s` and `{number}` will be replaced to figure
|
||||
number. `{name}` will be replaced to figure caption.
|
||||
|
||||
Default is to use ``'Fig. %s'`` for ``'figure'``, ``'Table %s'`` for
|
||||
``'table'``, ``'Listing %s'`` for ``'code-block'`` and ``'Section'`` for
|
||||
``'section'``.
|
||||
|
||||
.. versionadded:: 1.3
|
||||
|
||||
.. versionchanged:: 1.5
|
||||
Support format of section. Allow to refer the caption of figures.
|
||||
|
||||
.. confval:: numfig_secnum_depth
|
||||
|
||||
The scope of figure numbers, that is, the numfig feature numbers figures
|
||||
@@ -330,13 +349,12 @@ Project information
|
||||
replacement for ``|today|``.
|
||||
|
||||
* If you set :confval:`today` to a non-empty value, it is used.
|
||||
* Otherwise, the current time is formatted using `Locale Data Markup Language
|
||||
<http://unicode.org/reports/tr35/tr35-dates.html#Date_Format_Patterns>`_
|
||||
and the format given in :confval:`today_fmt`.
|
||||
* Otherwise, the current time is formatted using :func:`time.strftime` and
|
||||
the format given in :confval:`today_fmt`.
|
||||
|
||||
The default is no :confval:`today` and a :confval:`today_fmt` of ``'MMMM dd,
|
||||
YYYY'`` (or, if translation is enabled with :confval:`language`, an
|
||||
equivalent %format for the selected locale).
|
||||
The default is no :confval:`today` and a :confval:`today_fmt` of ``'%B %d,
|
||||
%Y'`` (or, if translation is enabled with :confval:`language`, an equivalent
|
||||
format for the selected locale).
|
||||
|
||||
.. versionchanged:: 1.4
|
||||
|
||||
@@ -344,6 +362,12 @@ Project information
|
||||
Language. strftime format is also supported for backward compatibility
|
||||
until Sphinx-1.5.
|
||||
|
||||
.. versionchanged:: 1.4.1
|
||||
|
||||
Format specification was changed again from Locale Data Markup Language
|
||||
to strftime. LDML format is also supported for backward compatibility
|
||||
until Sphinx-1.5.
|
||||
|
||||
.. confval:: highlight_language
|
||||
|
||||
The default language to highlight source code in. The default is
|
||||
@@ -504,7 +528,10 @@ documentation on :ref:`intl` for details.
|
||||
:file:`./locale/{language}/LC_MESSAGES/sphinx.mo`. The text domain of
|
||||
individual documents depends on :confval:`gettext_compact`.
|
||||
|
||||
The default is ``[]``.
|
||||
The default is ``['locales']``.
|
||||
|
||||
.. versionchanged:: 1.5
|
||||
Use ``locales`` directory as a default value
|
||||
|
||||
.. confval:: gettext_compact
|
||||
|
||||
@@ -696,9 +723,8 @@ that use Sphinx's HTMLWriter class.
|
||||
.. confval:: html_last_updated_fmt
|
||||
|
||||
If this is not None, a 'Last updated on:' timestamp is inserted
|
||||
at every page bottom, using the given `Locale Data Markup Language
|
||||
<http://unicode.org/reports/tr35/tr35-dates.html#Date_Format_Patterns>`_
|
||||
format. The empty string is equivalent to ``'MMM dd, YYYY'`` (or a
|
||||
at every page bottom, using the given :func:`strftime` format.
|
||||
The empty string is equivalent to ``'%b %d, %Y'`` (or a
|
||||
locale-dependent equivalent).
|
||||
|
||||
.. versionchanged:: 1.4
|
||||
@@ -707,6 +733,13 @@ that use Sphinx's HTMLWriter class.
|
||||
Language. strftime format is also supported for backward compatibility
|
||||
until Sphinx-1.5.
|
||||
|
||||
.. versionchanged:: 1.4.1
|
||||
|
||||
Format specification was changed again from Locale Data Markup Language
|
||||
to strftime. LDML format is also supported for backward compatibility
|
||||
until Sphinx-1.5.
|
||||
|
||||
|
||||
.. confval:: html_use_smartypants
|
||||
|
||||
If true, `SmartyPants <http://daringfireball.net/projects/smartypants/>`_
|
||||
@@ -844,6 +877,13 @@ that use Sphinx's HTMLWriter class.
|
||||
|
||||
.. versionadded:: 0.6
|
||||
|
||||
.. confval:: html_sourcelink_suffix
|
||||
|
||||
Suffix to be appended to source links (see :confval:`html_show_sourcelink`),
|
||||
unless they have this suffix already. Default is ``'.txt'``.
|
||||
|
||||
.. versionadded:: 1.5
|
||||
|
||||
.. confval:: html_use_opensearch
|
||||
|
||||
If nonempty, an `OpenSearch <http://www.opensearch.org/Home>`_ description file will be
|
||||
@@ -877,6 +917,11 @@ that use Sphinx's HTMLWriter class.
|
||||
|
||||
.. seealso:: :meth:`~sphinx.application.Sphinx.set_translator`
|
||||
|
||||
.. deprecated:: 1.5
|
||||
|
||||
Implement your translator as extension and use `Sphinx.set_translator`
|
||||
instead.
|
||||
|
||||
.. confval:: html_show_copyright
|
||||
|
||||
If true, "(C) Copyright ..." is shown in the HTML footer. Default is
|
||||
@@ -1365,6 +1410,10 @@ the `Dublin Core metadata <http://dublincore.org/>`_.
|
||||
a chapter, but can be confusing because it mixes entries of different
|
||||
depth in one list. The default value is ``True``.
|
||||
|
||||
.. note::
|
||||
|
||||
``epub3`` builder ignores ``epub_tocdup`` option(always ``False``)
|
||||
|
||||
.. confval:: epub_tocscope
|
||||
|
||||
This setting control the scope of the epub table of contents. The setting
|
||||
@@ -1418,6 +1467,30 @@ the `Dublin Core metadata <http://dublincore.org/>`_.
|
||||
|
||||
.. versionadded:: 1.2
|
||||
|
||||
.. confval:: epub3_writing_mode
|
||||
|
||||
It specifies writing direction. It can accept ``'horizontal'`` (default) and
|
||||
``'vertical'``
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:stub-columns: 1
|
||||
|
||||
- * ``epub3_writing_mode``
|
||||
* ``'horizontal'``
|
||||
* ``'vertical'``
|
||||
- * writing-mode [#]_
|
||||
* ``horizontal-tb``
|
||||
* ``vertical-rl``
|
||||
- * page progression
|
||||
* left to right
|
||||
* right to left
|
||||
- * iBook's Scroll Theme support
|
||||
* scroll-axis is vertical.
|
||||
* scroll-axis is horizontal.
|
||||
|
||||
.. [#] https://developer.mozilla.org/en-US/docs/Web/CSS/writing-mode
|
||||
|
||||
.. confval:: epub3_page_progression_direction
|
||||
|
||||
The global direction in which the content flows.
|
||||
@@ -1429,12 +1502,25 @@ the `Dublin Core metadata <http://dublincore.org/>`_.
|
||||
|
||||
.. versionadded:: 1.4
|
||||
|
||||
.. deprecated:: 1.5
|
||||
Use ``epub3_writing_mode``.
|
||||
|
||||
.. _latex-options:
|
||||
|
||||
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
|
||||
|
||||
@@ -1542,6 +1628,21 @@ These options influence LaTeX output.
|
||||
value selected the ``'inline'`` display. For backwards compatibility,
|
||||
``True`` is still accepted.
|
||||
|
||||
.. confval:: latex_keep_old_macro_names
|
||||
|
||||
If ``True`` (default) the ``\strong``, ``\code``, ``\bfcode``, ``\email``,
|
||||
``\tablecontinued``, ``\titleref``, ``\menuselection``, ``\accelerator``,
|
||||
``\crossref``, ``\termref``, and ``\optional`` text styling macros are
|
||||
pre-defined by Sphinx and may be user-customized by some
|
||||
``\renewcommand``'s inserted either via ``'preamble'`` key or :dudir:`raw
|
||||
<raw-data-pass-through>` directive. If ``False``, only ``\sphinxstrong``,
|
||||
etc... macros are defined (and may be redefined by user). Setting to
|
||||
``False`` may help solve macro name conflicts caused by user-added latex
|
||||
packages.
|
||||
|
||||
.. versionadded:: 1.4.5
|
||||
|
||||
|
||||
.. confval:: latex_elements
|
||||
|
||||
.. versionadded:: 0.5
|
||||
@@ -1560,6 +1661,15 @@ These options influence LaTeX output.
|
||||
``'pointsize'``
|
||||
Point size option of the document class (``'10pt'``, ``'11pt'`` or
|
||||
``'12pt'``), default ``'10pt'``.
|
||||
``'pxunit'``
|
||||
the value of the ``px`` when used in image attributes ``width`` and
|
||||
``height``. The default value is ``'49336sp'`` which achieves
|
||||
``96px=1in`` (``1in = 72.27*65536 = 4736286.72sp``, and all dimensions
|
||||
in TeX are internally integer multiples of ``sp``). To obtain for
|
||||
example ``100px=1in``, one can use ``'0.01in'`` but it is more precise
|
||||
to use ``'47363sp'``. To obtain ``72px=1in``, use ``'1bp'``.
|
||||
|
||||
.. versionadded:: 1.5
|
||||
``'babel'``
|
||||
"babel" package inclusion, default ``'\\usepackage{babel}'``.
|
||||
``'fontpkg'``
|
||||
@@ -1582,7 +1692,9 @@ These options influence LaTeX output.
|
||||
|
||||
.. versionadded:: 1.4
|
||||
``'preamble'``
|
||||
Additional preamble content, default empty.
|
||||
Additional preamble content, default empty. See :doc:`latex`.
|
||||
``'postamble'``
|
||||
Additional postamble content (before the indices), default empty.
|
||||
``'figure_align'``
|
||||
Latex figure float alignment, default 'htbp' (here, top, bottom, page).
|
||||
Whenever an image doesn't fit into the current page, it will be
|
||||
@@ -1594,11 +1706,19 @@ These options influence LaTeX output.
|
||||
``'footer'``
|
||||
Additional footer content (before the indices), default empty.
|
||||
|
||||
.. deprecated:: 1.5
|
||||
User ``'postamble'`` key instead.
|
||||
|
||||
* Keys that don't need be overridden unless in special cases are:
|
||||
|
||||
``'inputenc'``
|
||||
"inputenc" package inclusion, default
|
||||
``'\\usepackage[utf8]{inputenc}'``.
|
||||
"inputenc" package inclusion, defaults to
|
||||
``'\\usepackage[utf8]{inputenc}'`` when using pdflatex.
|
||||
Otherwise unset.
|
||||
|
||||
.. versionchanged:: 1.4.3
|
||||
Previously ``'\\usepackage[utf8]{inputenc}'`` was used for all
|
||||
compilers.
|
||||
``'cmappkg'``
|
||||
"cmap" package inclusion, default ``'\\usepackage{cmap}'``.
|
||||
|
||||
@@ -1647,6 +1767,11 @@ These options influence LaTeX output.
|
||||
|
||||
.. versionadded:: 1.0
|
||||
|
||||
.. versionchanged:: 1.5
|
||||
|
||||
In Japanese docs(`language` is ``ja``), ``'jreport'`` is used for
|
||||
``'howto'`` and ``'jsbooks'`` is used for ``'manual'`` by default.
|
||||
|
||||
.. confval:: latex_additional_files
|
||||
|
||||
A list of file names, relative to the configuration directory, to copy to the
|
||||
@@ -1884,9 +2009,8 @@ Options for the linkcheck builder
|
||||
|
||||
.. confval:: linkcheck_timeout
|
||||
|
||||
A timeout value, in seconds, for the linkcheck builder. **Only works in
|
||||
Python 2.6 and higher.** The default is to use Python's global socket
|
||||
timeout.
|
||||
A timeout value, in seconds, for the linkcheck builder. The default is to
|
||||
use Python's global socket timeout.
|
||||
|
||||
.. versionadded:: 1.1
|
||||
|
||||
@@ -1922,3 +2046,33 @@ Options for the XML builder
|
||||
constructs ``*``, ``?``, ``[...]`` and ``[!...]`` with the feature that
|
||||
these all don't match slashes. A double star ``**`` can be used to match
|
||||
any sequence of characters *including* slashes.
|
||||
|
||||
|
||||
.. _cpp-config:
|
||||
|
||||
Options for the C++ domain
|
||||
--------------------------
|
||||
|
||||
.. confval:: cpp_index_common_prefix
|
||||
|
||||
A list of prefixes that will be ignored when sorting C++ objects in the global index.
|
||||
For example ``['awesome_lib::']``.
|
||||
|
||||
.. versionadded:: 1.5
|
||||
|
||||
.. confval:: cpp_id_attributes
|
||||
|
||||
A list of strings that the parser additionally should accept as attributes.
|
||||
This can for example be used when attributes have been ``#define`` d for portability.
|
||||
|
||||
.. versionadded:: 1.5
|
||||
|
||||
.. confval:: cpp_paren_attributes
|
||||
|
||||
A list of strings that the parser additionally should accept as attributes with one argument.
|
||||
That is, if ``my_align_as`` is in the list, then ``my_align_as(X)`` is parsed as an attribute
|
||||
for all strings ``X`` that have balanced brances (``()``, ``[]``, and ``{}``).
|
||||
This can for example be used when attributes have been ``#define`` d for portability.
|
||||
|
||||
.. versionadded:: 1.5
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
.. _contents:
|
||||
|
||||
Sphinx documentation contents
|
||||
@@ -17,6 +18,7 @@ Sphinx documentation contents
|
||||
intl
|
||||
theming
|
||||
templating
|
||||
latex
|
||||
extensions
|
||||
extdev/index
|
||||
websupport
|
||||
@@ -32,7 +34,14 @@ Sphinx documentation contents
|
||||
Indices and tables
|
||||
==================
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`modindex`
|
||||
* :ref:`search`
|
||||
* :ref:`glossary`
|
||||
.. only:: builder_html
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`modindex`
|
||||
* :ref:`search`
|
||||
* :ref:`glossary`
|
||||
|
||||
.. only:: not builder_html
|
||||
|
||||
* :ref:`modindex`
|
||||
* :ref:`glossary`
|
||||
|
||||
@@ -111,7 +111,7 @@ These are the basic steps needed to start developing on Sphinx.
|
||||
|
||||
* Run the unit tests::
|
||||
|
||||
pip install nose mock
|
||||
pip install -r test-reqs.txt
|
||||
make test
|
||||
|
||||
* Build the documentation and check the output for different builders::
|
||||
|
||||
135
doc/domains.rst
@@ -359,6 +359,25 @@ single word, like this::
|
||||
:param int priority: The priority of the message, can be a number 1-5
|
||||
|
||||
|
||||
.. versionadded:: 1.5
|
||||
|
||||
Container types such as lists and dictionaries can be linked automatically
|
||||
using the following syntax::
|
||||
|
||||
:type priorities: list(int)
|
||||
:type priorities: list[int]
|
||||
:type mapping: dict(str, int)
|
||||
:type mapping: dict[str, int]
|
||||
:type point: tuple(float, float)
|
||||
:type point: tuple[float, float]
|
||||
|
||||
Multiple types in a type field will be linked automatically if separated by
|
||||
the word "or"::
|
||||
|
||||
:type an_arg: int or None
|
||||
:vartype a_var: str or int
|
||||
:rtype: float or str
|
||||
|
||||
.. _python-roles:
|
||||
|
||||
Cross-referencing Python objects
|
||||
@@ -545,10 +564,10 @@ a visibility statement (``public``, ``private`` or ``protected``).
|
||||
|
||||
Full and partial template specialisations can be declared::
|
||||
|
||||
.. cpp::class:: template<> \
|
||||
.. cpp:class:: template<> \
|
||||
std::array<bool, 256>
|
||||
|
||||
.. cpp::class:: template<typename T> \
|
||||
.. cpp:class:: template<typename T> \
|
||||
std::array<T, 42>
|
||||
|
||||
|
||||
@@ -629,9 +648,26 @@ a visibility statement (``public``, ``private`` or ``protected``).
|
||||
|
||||
A type alias can also be templated::
|
||||
|
||||
.. cpp:type:: template<typename T>
|
||||
.. cpp:type:: template<typename T> \
|
||||
MyContainer = std::vector<T>
|
||||
|
||||
The example are rendered as follows.
|
||||
|
||||
.. cpp:type:: std::vector<int> MyList
|
||||
|
||||
A typedef-like declaration of a type.
|
||||
|
||||
.. cpp:type:: MyContainer::const_iterator
|
||||
|
||||
Declaration of a type alias with unspecified type.
|
||||
|
||||
.. cpp:type:: MyType = std::unordered_map<int, std::string>
|
||||
|
||||
Declaration of a type alias.
|
||||
|
||||
.. cpp:type:: template<typename T> \
|
||||
MyContainer = std::vector<T>
|
||||
|
||||
|
||||
.. rst:directive:: .. cpp:enum:: unscoped enum declaration
|
||||
.. cpp:enum-struct:: scoped enum declaration
|
||||
@@ -663,9 +699,92 @@ a visibility statement (``public``, ``private`` or ``protected``).
|
||||
|
||||
Describe an enumerator, optionally with its value defined, e.g.,::
|
||||
|
||||
.. cpp::enumerator:: MyEnum::myEnumerator
|
||||
.. cpp:enumerator:: MyEnum::myEnumerator
|
||||
|
||||
.. cpp::enumerator:: MyEnum::myOtherEnumerator = 42
|
||||
.. cpp:enumerator:: MyEnum::myOtherEnumerator = 42
|
||||
|
||||
|
||||
.. rst:directive:: .. cpp:concept:: template-parameter-list name
|
||||
.. cpp:concept:: template-parameter-list name()
|
||||
|
||||
.. warning:: The support for concepts is experimental. It is based on the
|
||||
Concepts Technical Specification, and the features may change as the TS evolves.
|
||||
|
||||
Describe a variable concept or a function concept. Both must have exactly 1
|
||||
template parameter list. The name may be a nested name. Examples::
|
||||
|
||||
.. cpp:concept:: template<typename It> std::Iterator
|
||||
|
||||
Proxy to an element of a notional sequence that can be compared,
|
||||
indirected, or incremented.
|
||||
|
||||
.. cpp:concept:: template<typename Cont> std::Container()
|
||||
|
||||
Holder of elements, to which it can provide access via
|
||||
:cpp:concept:`Iterator` s.
|
||||
|
||||
They will render as follows:
|
||||
|
||||
.. cpp:concept:: template<typename It> std::Iterator
|
||||
|
||||
Proxy to an element of a notional sequence that can be compared,
|
||||
indirected, or incremented.
|
||||
|
||||
.. cpp:concept:: template<typename Cont> std::Container()
|
||||
|
||||
Holder of elements, to which it can provide access via
|
||||
:cpp:concept:`Iterator` s.
|
||||
|
||||
Constrained Templates
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. warning:: The support for constrained templates is experimental. It is based on the
|
||||
Concepts Technical Specification, and the features may change as the TS evolves.
|
||||
|
||||
.. note:: Sphinx does not currently support ``requires`` clauses.
|
||||
|
||||
Placeholders
|
||||
............
|
||||
|
||||
Declarations may use the name of a concept to introduce constrained template
|
||||
parameters, or the keyword ``auto`` to introduce unconstrained template parameters::
|
||||
|
||||
.. cpp:function:: void f(auto &&arg)
|
||||
|
||||
A function template with a single unconstrained template parameter.
|
||||
|
||||
.. cpp:function:: void f(std::Iterator it)
|
||||
|
||||
A function template with a single template parameter, constrained by the
|
||||
Iterator concept.
|
||||
|
||||
Template Introductions
|
||||
......................
|
||||
|
||||
Simple constrained function or class templates can be declared with a
|
||||
`template introduction` instead of a template parameter list::
|
||||
|
||||
.. cpp:function:: std::Iterator{It} void advance(It &it)
|
||||
|
||||
A function template with a template parameter constrained to be an Iterator.
|
||||
|
||||
.. cpp:class:: std::LessThanComparable{T} MySortedContainer
|
||||
|
||||
A class template with a template parameter constrained to be LessThanComparable.
|
||||
|
||||
They are rendered as follows.
|
||||
|
||||
.. cpp:function:: std::Iterator{It} void advance(It &it)
|
||||
|
||||
A function template with a template parameter constrained to be an Iterator.
|
||||
|
||||
.. cpp:class:: std::LessThanComparable{T} MySortedContainer
|
||||
|
||||
A class template with a template parameter constrained to be LessThanComparable.
|
||||
|
||||
Note however that no checking is performed with respect to parameter
|
||||
compatibility. E.g., ``Iterator{A, B, C}`` will be accepted as an introduction
|
||||
even though it would not be valid C++.
|
||||
|
||||
|
||||
Namespacing
|
||||
@@ -773,6 +892,7 @@ These roles link to the given declaration types:
|
||||
cpp:member
|
||||
cpp:var
|
||||
cpp:type
|
||||
cpp:concept
|
||||
cpp:enum
|
||||
cpp:enumerator
|
||||
|
||||
@@ -871,6 +991,11 @@ References to partial specialisations must always include the template parameter
|
||||
Currently the lookup only succeed if the template parameter identifiers are equal strings.
|
||||
|
||||
|
||||
Configuration Variables
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
See :ref:`cpp-config`.
|
||||
|
||||
|
||||
The Standard Domain
|
||||
-------------------
|
||||
|
||||
24
doc/ext/builtins.rst
Normal file
@@ -0,0 +1,24 @@
|
||||
Builtin Sphinx extensions
|
||||
-------------------------
|
||||
|
||||
These extensions are built in and can be activated by respective entries in the
|
||||
:confval:`extensions` configuration value:
|
||||
|
||||
.. toctree::
|
||||
|
||||
autodoc
|
||||
autosectionlabel
|
||||
autosummary
|
||||
coverage
|
||||
doctest
|
||||
extlinks
|
||||
githubpages
|
||||
graphviz
|
||||
ifconfig
|
||||
inheritance
|
||||
intersphinx
|
||||
linkcode
|
||||
math
|
||||
napoleon
|
||||
todo
|
||||
viewcode
|
||||
@@ -33,11 +33,14 @@ There are two kinds of test blocks:
|
||||
* *code-output-style* blocks consist of an ordinary piece of Python code, and
|
||||
optionally, a piece of output for that code.
|
||||
|
||||
The doctest extension provides four directives. The *group* argument is
|
||||
interpreted as follows: if it is empty, the block is assigned to the group named
|
||||
``default``. If it is ``*``, the block is assigned to all groups (including the
|
||||
``default`` group). Otherwise, it must be a comma-separated list of group
|
||||
names.
|
||||
|
||||
Directives
|
||||
----------
|
||||
|
||||
The *group* argument below is interpreted as follows: if it is empty, the block
|
||||
is assigned to the group named ``default``. If it is ``*``, the block is
|
||||
assigned to all groups (including the ``default`` group). Otherwise, it must be
|
||||
a comma-separated list of group names.
|
||||
|
||||
.. rst:directive:: .. testsetup:: [group]
|
||||
|
||||
@@ -56,12 +59,9 @@ names.
|
||||
.. rst:directive:: .. doctest:: [group]
|
||||
|
||||
A doctest-style code block. You can use standard :mod:`doctest` flags for
|
||||
controlling how actual output is compared with what you give as output. By
|
||||
default, these options are enabled: ``ELLIPSIS`` (allowing you to put
|
||||
ellipses in the expected output that match anything in the actual output),
|
||||
``IGNORE_EXCEPTION_DETAIL`` (not comparing tracebacks),
|
||||
``DONT_ACCEPT_TRUE_FOR_1`` (by default, doctest accepts "True" in the output
|
||||
where "1" is given -- this is a relic of pre-Python 2.2 times).
|
||||
controlling how actual output is compared with what you give as output. The
|
||||
default set of flags is specified by the :confval:`doctest_default_flags`
|
||||
configuration variable.
|
||||
|
||||
This directive supports two options:
|
||||
|
||||
@@ -174,7 +174,24 @@ The following is an example for the usage of the directives. The test via
|
||||
This parrot wouldn't voom if you put 3000 volts through it!
|
||||
|
||||
|
||||
There are also these config values for customizing the doctest extension:
|
||||
Configuration
|
||||
-------------
|
||||
|
||||
The doctest extension uses the following configuration values:
|
||||
|
||||
.. confval:: doctest_default_flags
|
||||
|
||||
By default, these options are enabled:
|
||||
|
||||
- ``ELLIPSIS``, allowing you to put ellipses in the expected output that
|
||||
match anything in the actual output;
|
||||
- ``IGNORE_EXCEPTION_DETAIL``, causing everything following the leftmost
|
||||
colon and any module information in the exception name to be ignored;
|
||||
- ``DONT_ACCEPT_TRUE_FOR_1``, rejecting "True" in the output where "1" is
|
||||
given -- the default behavior of accepting this substitution is a relic of
|
||||
pre-Python 2.2 times.
|
||||
|
||||
.. versionadded:: 1.5
|
||||
|
||||
.. confval:: doctest_path
|
||||
|
||||
|
||||
@@ -43,6 +43,39 @@ on the first line, separated by a colon.
|
||||
"""
|
||||
|
||||
|
||||
def function_with_types_in_docstring(param1, param2):
|
||||
"""Example function with types documented in the docstring.
|
||||
|
||||
`PEP 484`_ type annotations are supported. If attribute, parameter, and
|
||||
return types are annotated according to `PEP 484`_, they do not need to be
|
||||
included in the docstring:
|
||||
|
||||
Args:
|
||||
param1 (int): The first parameter.
|
||||
param2 (str): The second parameter.
|
||||
|
||||
Returns:
|
||||
bool: The return value. True for success, False otherwise.
|
||||
|
||||
.. _PEP 484:
|
||||
https://www.python.org/dev/peps/pep-0484/
|
||||
|
||||
"""
|
||||
|
||||
|
||||
def function_with_pep484_type_annotations(param1: int, param2: str) -> bool:
|
||||
"""Example function with PEP 484 type annotations.
|
||||
|
||||
Args:
|
||||
param1: The first parameter.
|
||||
param2: The second parameter.
|
||||
|
||||
Returns:
|
||||
The return value. True for success, False otherwise.
|
||||
|
||||
"""
|
||||
|
||||
|
||||
def module_level_function(param1, param2=None, *args, **kwargs):
|
||||
"""This is an example of a module level function.
|
||||
|
||||
@@ -50,9 +83,6 @@ def module_level_function(param1, param2=None, *args, **kwargs):
|
||||
of each parameter is required. The type and description of each parameter
|
||||
is optional, but should be included if not obvious.
|
||||
|
||||
Parameter types -- if given -- should be specified according to
|
||||
`PEP 484`_, though `PEP 484`_ conformance isn't required or enforced.
|
||||
|
||||
If \*args or \*\*kwargs are accepted,
|
||||
they should be listed as ``*args`` and ``**kwargs``.
|
||||
|
||||
@@ -67,7 +97,7 @@ def module_level_function(param1, param2=None, *args, **kwargs):
|
||||
|
||||
Args:
|
||||
param1 (int): The first parameter.
|
||||
param2 (Optional[str]): The second parameter. Defaults to None.
|
||||
param2 (:obj:`str`, optional): The second parameter. Defaults to None.
|
||||
Second line of description should be indented.
|
||||
*args: Variable length argument list.
|
||||
**kwargs: Arbitrary keyword arguments.
|
||||
@@ -94,10 +124,6 @@ def module_level_function(param1, param2=None, *args, **kwargs):
|
||||
that are relevant to the interface.
|
||||
ValueError: If `param2` is equal to `param1`.
|
||||
|
||||
|
||||
.. _PEP 484:
|
||||
https://www.python.org/dev/peps/pep-0484/
|
||||
|
||||
"""
|
||||
if param1 == param2:
|
||||
raise ValueError('param1 may not be equal to param2')
|
||||
@@ -139,7 +165,7 @@ class ExampleError(Exception):
|
||||
|
||||
Args:
|
||||
msg (str): Human readable string describing the exception.
|
||||
code (Optional[int]): Error code.
|
||||
code (:obj:`int`, optional): Error code.
|
||||
|
||||
Attributes:
|
||||
msg (str): Human readable string describing the exception.
|
||||
@@ -163,16 +189,9 @@ class ExampleClass(object):
|
||||
Properties created with the ``@property`` decorator should be documented
|
||||
in the property's getter method.
|
||||
|
||||
Attribute and property types -- if given -- should be specified according
|
||||
to `PEP 484`_, though `PEP 484`_ conformance isn't required or enforced.
|
||||
|
||||
Attributes:
|
||||
attr1 (str): Description of `attr1`.
|
||||
attr2 (Optional[int]): Description of `attr2`.
|
||||
|
||||
|
||||
.. _PEP 484:
|
||||
https://www.python.org/dev/peps/pep-0484/
|
||||
attr2 (:obj:`int`, optional): Description of `attr2`.
|
||||
|
||||
"""
|
||||
|
||||
@@ -190,20 +209,20 @@ class ExampleClass(object):
|
||||
|
||||
Args:
|
||||
param1 (str): Description of `param1`.
|
||||
param2 (Optional[int]): Description of `param2`. Multiple
|
||||
param2 (:obj:`int`, optional): Description of `param2`. Multiple
|
||||
lines are supported.
|
||||
param3 (List[str]): Description of `param3`.
|
||||
param3 (list(str)): Description of `param3`.
|
||||
|
||||
"""
|
||||
self.attr1 = param1
|
||||
self.attr2 = param2
|
||||
self.attr3 = param3 #: Doc comment *inline* with attribute
|
||||
|
||||
#: List[str]: Doc comment *before* attribute, with type specified
|
||||
#: list(str): Doc comment *before* attribute, with type specified
|
||||
self.attr4 = ['attr4']
|
||||
|
||||
self.attr5 = None
|
||||
"""Optional[str]: Docstring *after* attribute, with type specified."""
|
||||
"""str: Docstring *after* attribute, with type specified."""
|
||||
|
||||
@property
|
||||
def readonly_property(self):
|
||||
@@ -212,8 +231,8 @@ class ExampleClass(object):
|
||||
|
||||
@property
|
||||
def readwrite_property(self):
|
||||
"""List[str]: Properties with both a getter and setter should only
|
||||
be documented in their getter method.
|
||||
"""list(str): Properties with both a getter and setter
|
||||
should only be documented in their getter method.
|
||||
|
||||
If the setter method contains notable behavior, it should be
|
||||
mentioned here.
|
||||
|
||||
@@ -9,7 +9,9 @@ Example Google Style Python Docstrings
|
||||
|
||||
:ref:`example_numpy`
|
||||
|
||||
Download: :download:`example_google.py <example_google.py>`
|
||||
.. only:: builder_html
|
||||
|
||||
Download: :download:`example_google.py <example_google.py>`
|
||||
|
||||
.. literalinclude:: example_google.py
|
||||
:language: python
|
||||
|
||||
@@ -37,6 +37,7 @@ module_level_variable1 : int
|
||||
one convention to document module level variables and be consistent
|
||||
with it.
|
||||
|
||||
|
||||
.. _NumPy Documentation HOWTO:
|
||||
https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt
|
||||
|
||||
@@ -52,6 +53,52 @@ on the first line, separated by a colon.
|
||||
"""
|
||||
|
||||
|
||||
def function_with_types_in_docstring(param1, param2):
|
||||
"""Example function with types documented in the docstring.
|
||||
|
||||
`PEP 484`_ type annotations are supported. If attribute, parameter, and
|
||||
return types are annotated according to `PEP 484`_, they do not need to be
|
||||
included in the docstring:
|
||||
|
||||
Parameters
|
||||
----------
|
||||
param1 : int
|
||||
The first parameter.
|
||||
param2 : str
|
||||
The second parameter.
|
||||
|
||||
Returns
|
||||
-------
|
||||
bool
|
||||
True if successful, False otherwise.
|
||||
|
||||
.. _PEP 484:
|
||||
https://www.python.org/dev/peps/pep-0484/
|
||||
|
||||
"""
|
||||
|
||||
|
||||
def function_with_pep484_type_annotations(param1: int, param2: str) -> bool:
|
||||
"""Example function with PEP 484 type annotations.
|
||||
|
||||
The return type must be duplicated in the docstring to comply
|
||||
with the NumPy docstring style.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
param1
|
||||
The first parameter.
|
||||
param2
|
||||
The second parameter.
|
||||
|
||||
Returns
|
||||
-------
|
||||
bool
|
||||
True if successful, False otherwise.
|
||||
|
||||
"""
|
||||
|
||||
|
||||
def module_level_function(param1, param2=None, *args, **kwargs):
|
||||
"""This is an example of a module level function.
|
||||
|
||||
@@ -59,9 +106,6 @@ def module_level_function(param1, param2=None, *args, **kwargs):
|
||||
The name of each parameter is required. The type and description of each
|
||||
parameter is optional, but should be included if not obvious.
|
||||
|
||||
Parameter types -- if given -- should be specified according to
|
||||
`PEP 484`_, though `PEP 484`_ conformance isn't required or enforced.
|
||||
|
||||
If \*args or \*\*kwargs are accepted,
|
||||
they should be listed as ``*args`` and ``**kwargs``.
|
||||
|
||||
@@ -81,7 +125,7 @@ def module_level_function(param1, param2=None, *args, **kwargs):
|
||||
----------
|
||||
param1 : int
|
||||
The first parameter.
|
||||
param2 : Optional[str]
|
||||
param2 : :obj:`str`, optional
|
||||
The second parameter.
|
||||
*args
|
||||
Variable length argument list.
|
||||
@@ -113,10 +157,6 @@ def module_level_function(param1, param2=None, *args, **kwargs):
|
||||
ValueError
|
||||
If `param2` is equal to `param1`.
|
||||
|
||||
|
||||
.. _PEP 484:
|
||||
https://www.python.org/dev/peps/pep-0484/
|
||||
|
||||
"""
|
||||
if param1 == param2:
|
||||
raise ValueError('param1 may not be equal to param2')
|
||||
@@ -166,7 +206,7 @@ class ExampleError(Exception):
|
||||
----------
|
||||
msg : str
|
||||
Human readable string describing the exception.
|
||||
code : Optional[int]
|
||||
code : :obj:`int`, optional
|
||||
Numeric error code.
|
||||
|
||||
Attributes
|
||||
@@ -194,20 +234,13 @@ class ExampleClass(object):
|
||||
Properties created with the ``@property`` decorator should be documented
|
||||
in the property's getter method.
|
||||
|
||||
Attribute and property types -- if given -- should be specified according
|
||||
to `PEP 484`_, though `PEP 484`_ conformance isn't required or enforced.
|
||||
|
||||
Attributes
|
||||
----------
|
||||
attr1 : str
|
||||
Description of `attr1`.
|
||||
attr2 : Optional[int]
|
||||
attr2 : :obj:`int`, optional
|
||||
Description of `attr2`.
|
||||
|
||||
|
||||
.. _PEP 484:
|
||||
https://www.python.org/dev/peps/pep-0484/
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, param1, param2, param3):
|
||||
@@ -227,10 +260,10 @@ class ExampleClass(object):
|
||||
----------
|
||||
param1 : str
|
||||
Description of `param1`.
|
||||
param2 : List[str]
|
||||
param2 : list(str)
|
||||
Description of `param2`. Multiple
|
||||
lines are supported.
|
||||
param3 : Optional[int]
|
||||
param3 : :obj:`int`, optional
|
||||
Description of `param3`.
|
||||
|
||||
"""
|
||||
@@ -238,11 +271,11 @@ class ExampleClass(object):
|
||||
self.attr2 = param2
|
||||
self.attr3 = param3 #: Doc comment *inline* with attribute
|
||||
|
||||
#: List[str]: Doc comment *before* attribute, with type specified
|
||||
#: list(str): Doc comment *before* attribute, with type specified
|
||||
self.attr4 = ["attr4"]
|
||||
|
||||
self.attr5 = None
|
||||
"""Optional[str]: Docstring *after* attribute, with type specified."""
|
||||
"""str: Docstring *after* attribute, with type specified."""
|
||||
|
||||
@property
|
||||
def readonly_property(self):
|
||||
@@ -251,8 +284,8 @@ class ExampleClass(object):
|
||||
|
||||
@property
|
||||
def readwrite_property(self):
|
||||
"""List[str]: Properties with both a getter and setter should only
|
||||
be documented in their getter method.
|
||||
"""list(str): Properties with both a getter and setter
|
||||
should only be documented in their getter method.
|
||||
|
||||
If the setter method contains notable behavior, it should be
|
||||
mentioned here.
|
||||
|
||||
@@ -9,7 +9,9 @@ Example NumPy Style Python Docstrings
|
||||
|
||||
:ref:`example_google`
|
||||
|
||||
Download: :download:`example_numpy.py <example_numpy.py>`
|
||||
.. only:: builder_html
|
||||
|
||||
Download: :download:`example_numpy.py <example_numpy.py>`
|
||||
|
||||
.. literalinclude:: example_numpy.py
|
||||
:language: python
|
||||
|
||||
@@ -96,6 +96,10 @@ It adds these directives:
|
||||
All three directives support a ``graphviz_dot`` option that can be switch the
|
||||
``dot`` command within the directive.
|
||||
|
||||
.. versionadded:: 1.5
|
||||
All three directives support a ``align`` option to align the graph horizontal.
|
||||
The values "left", "center", "right" are allowed.
|
||||
|
||||
There are also these new config values:
|
||||
|
||||
.. confval:: graphviz_dot
|
||||
|
||||
@@ -33,10 +33,15 @@ It adds this directive:
|
||||
It also supports a ``private-bases`` flag option; if given, private base
|
||||
classes (those whose name starts with ``_``) will be included.
|
||||
|
||||
You can use ``caption`` option to give a caption to the diagram.
|
||||
|
||||
.. versionchanged:: 1.1
|
||||
Added ``private-bases`` option; previously, all bases were always
|
||||
included.
|
||||
|
||||
.. versionchanged:: 1.5
|
||||
Added ``caption`` option
|
||||
|
||||
|
||||
New config values are:
|
||||
|
||||
|
||||
@@ -121,3 +121,14 @@ linking:
|
||||
The maximum number of days to cache remote inventories. The default is
|
||||
``5``, meaning five days. Set this to a negative value to cache inventories
|
||||
for unlimited time.
|
||||
|
||||
.. confval:: intersphinx_timeout
|
||||
|
||||
The number of seconds for timeout. The default is ``None``, meaning do not
|
||||
timeout.
|
||||
|
||||
.. note::
|
||||
|
||||
timeout is not a time limit on the entire response download; rather, an
|
||||
exception is raised if the server has not issued a response for timeout
|
||||
seconds.
|
||||
|
||||
@@ -186,11 +186,60 @@ not be mixed. Choose one style for your project and be consistent with it.
|
||||
* :ref:`example_google`
|
||||
* :ref:`example_numpy`
|
||||
|
||||
For Python type annotations, see `PEP 484`_.
|
||||
|
||||
Type Annotations
|
||||
----------------
|
||||
|
||||
`PEP 484`_ introduced a standard way to express types in Python code.
|
||||
This is an alternative to expressing types directly in docstrings.
|
||||
One benefit of expressing types according to `PEP 484`_ is that
|
||||
type checkers and IDEs can take advantage of them for static code
|
||||
analysis.
|
||||
|
||||
Google style with Python 3 type annotations::
|
||||
|
||||
def func(arg1: int, arg2: str) -> bool:
|
||||
"""Summary line.
|
||||
|
||||
Extended description of function.
|
||||
|
||||
Args:
|
||||
arg1: Description of arg1
|
||||
arg2: Description of arg2
|
||||
|
||||
Returns:
|
||||
Description of return value
|
||||
|
||||
"""
|
||||
return True
|
||||
|
||||
Google style with types in docstrings::
|
||||
|
||||
def func(arg1, arg2):
|
||||
"""Summary line.
|
||||
|
||||
Extended description of function.
|
||||
|
||||
Args:
|
||||
arg1 (int): Description of arg1
|
||||
arg2 (str): Description of arg2
|
||||
|
||||
Returns:
|
||||
bool: Description of return value
|
||||
|
||||
"""
|
||||
return True
|
||||
|
||||
.. Note::
|
||||
`Python 2/3 compatible annotations`_ aren't currently
|
||||
supported by Sphinx and won't show up in the docs.
|
||||
|
||||
.. _PEP 484:
|
||||
https://www.python.org/dev/peps/pep-0484/
|
||||
|
||||
.. _Python 2/3 compatible annotations:
|
||||
https://www.python.org/dev/peps/pep-0484/#suggested-syntax-for-python-2-7-and-straddling-code
|
||||
|
||||
|
||||
Configuration
|
||||
=============
|
||||
@@ -208,6 +257,7 @@ enabled in `conf.py`::
|
||||
# Napoleon settings
|
||||
napoleon_google_docstring = True
|
||||
napoleon_numpy_docstring = True
|
||||
napoleon_include_init_with_doc = False
|
||||
napoleon_include_private_with_doc = False
|
||||
napoleon_include_special_with_doc = True
|
||||
napoleon_use_admonition_for_examples = False
|
||||
@@ -234,6 +284,23 @@ enabled in `conf.py`::
|
||||
True to parse `NumPy style`_ docstrings. False to disable support
|
||||
for NumPy style docstrings. *Defaults to True.*
|
||||
|
||||
.. confval:: napoleon_include_init_with_doc
|
||||
|
||||
True to list ``__init___`` docstrings separately from the class
|
||||
docstring. False to fall back to Sphinx's default behavior, which
|
||||
considers the ``__init___`` docstring as part of the class
|
||||
documentation. *Defaults to False.*
|
||||
|
||||
**If True**::
|
||||
|
||||
def __init__(self):
|
||||
\"\"\"
|
||||
This will be included in the docs because it has a docstring
|
||||
\"\"\"
|
||||
|
||||
def __init__(self):
|
||||
# This will NOT be included in the docs
|
||||
|
||||
.. confval:: napoleon_include_private_with_doc
|
||||
|
||||
True to include private members (like ``_membername``) with docstrings
|
||||
@@ -371,6 +438,22 @@ enabled in `conf.py`::
|
||||
* **arg2** (*int, optional*) --
|
||||
Description of `arg2`, defaults to 0
|
||||
|
||||
.. confval:: napoleon_use_keyword
|
||||
|
||||
True to use a ``:keyword:`` role for each function keyword argument.
|
||||
False to use a single ``:keyword arguments:`` role for all the
|
||||
keywords.
|
||||
*Defaults to True.*
|
||||
|
||||
This behaves similarly to :attr:`napoleon_use_param`. Note unlike docutils,
|
||||
``:keyword:`` and ``:param:`` will not be treated the same way - there will
|
||||
be a separate "Keyword Arguments" section, rendered in the same fashion as
|
||||
"Parameters" section (type links created if possible)
|
||||
|
||||
.. seealso::
|
||||
|
||||
:attr:`napoleon_use_param`
|
||||
|
||||
.. confval:: napoleon_use_rtype
|
||||
|
||||
True to use the ``:rtype:`` role for the return type. False to output
|
||||
|
||||
35
doc/ext/thirdparty.rst
Normal file
@@ -0,0 +1,35 @@
|
||||
Third-party extensions
|
||||
----------------------
|
||||
|
||||
You can find several extensions contributed by users in the `Sphinx Contrib`_
|
||||
repository. It is open for anyone who wants to maintain an extension
|
||||
publicly; just send a short message asking for write permissions.
|
||||
|
||||
There are also several extensions hosted elsewhere. The `Sphinx extension
|
||||
survey <http://sphinxext-survey.readthedocs.org/en/latest/>`__ contains a
|
||||
comprehensive list.
|
||||
|
||||
If you write an extension that you think others will find useful or you think
|
||||
should be included as a part of Sphinx, please write to the project mailing
|
||||
list (`join here <https://groups.google.com/forum/#!forum/sphinx-dev>`_).
|
||||
|
||||
.. _Sphinx Contrib: https://bitbucket.org/birkenfeld/sphinx-contrib
|
||||
|
||||
|
||||
Where to put your own extensions?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Extensions local to a project should be put within the project's directory
|
||||
structure. Set Python's module search path, ``sys.path``, accordingly so that
|
||||
Sphinx can find them.
|
||||
E.g., if your extension ``foo.py`` lies in the ``exts`` subdirectory of the
|
||||
project root, put into :file:`conf.py`::
|
||||
|
||||
import sys, os
|
||||
|
||||
sys.path.append(os.path.abspath('exts'))
|
||||
|
||||
extensions = ['foo']
|
||||
|
||||
You can also install extensions anywhere else on ``sys.path``, e.g. in the
|
||||
``site-packages`` directory.
|
||||
@@ -34,6 +34,13 @@ There is also an additional config value:
|
||||
If this is ``True``, :rst:dir:`todo` and :rst:dir:`todolist` produce output,
|
||||
else they produce nothing. The default is ``False``.
|
||||
|
||||
.. confval:: todo_emit_warnings
|
||||
|
||||
If this is ``True``, :rst:dir:`todo` emits a warning for each TODO entries.
|
||||
The default is ``False``.
|
||||
|
||||
.. versionadded:: 1.5
|
||||
|
||||
.. confval:: todo_link_only
|
||||
|
||||
If this is ``True``, :rst:dir:`todolist` produce output without file path and line,
|
||||
@@ -41,3 +48,11 @@ There is also an additional config value:
|
||||
|
||||
.. versionadded:: 1.4
|
||||
|
||||
autodoc provides the following an additional event:
|
||||
|
||||
.. event:: todo-defined (app, node)
|
||||
|
||||
.. versionadded:: 1.5
|
||||
|
||||
Emitted when a todo is defined. *node* is the defined ``sphinx.ext.todo.todo_node``
|
||||
node.
|
||||
|
||||
@@ -15,6 +15,11 @@ a highlighted version of the source code, and a link will be added to all object
|
||||
descriptions that leads to the source code of the described object. A link back
|
||||
from the source to the description will also be inserted.
|
||||
|
||||
This extension works only on HTML related builders like ``html``,
|
||||
``applehelp``, ``devhelp``, ``htmlhelp``, ``qthelp`` and so on except
|
||||
``singlehtml``. By default ``epub`` builder doesn't
|
||||
support this extension (see :confval:`viewcode_enable_epub`).
|
||||
|
||||
There is an additional config value:
|
||||
|
||||
.. confval:: viewcode_import
|
||||
@@ -34,3 +39,26 @@ There is an additional config value:
|
||||
main routine is protected by a ``if __name__ == '__main__'`` condition.
|
||||
|
||||
.. versionadded:: 1.3
|
||||
|
||||
.. confval:: viewcode_enable_epub
|
||||
|
||||
If this is ``True``, viewcode extension is also enabled even if you use
|
||||
epub builders. This extension generates pages outside toctree, but this
|
||||
is not preferred as epub format.
|
||||
|
||||
Until 1.4.x, this extension is always enabled. If you want to generate
|
||||
epub as same as 1.4.x, you should set ``True``, but epub format checker's
|
||||
score becomes worse.
|
||||
|
||||
The default is ``False``.
|
||||
|
||||
.. versionadded:: 1.5
|
||||
|
||||
.. warning::
|
||||
|
||||
Not all epub readers support pages generated by viewcode extension.
|
||||
These readers ignore links to pages are not under toctree.
|
||||
|
||||
Some reader's rendering result are corrupted and
|
||||
`epubcheck <https://github.com/IDPF/epubcheck>`_'s score
|
||||
becomes worse even if the reader supports.
|
||||
|
||||
@@ -362,7 +362,7 @@ package.
|
||||
|
||||
.. versionadded:: 1.1
|
||||
|
||||
.. method:: Sphinx.add_source_parser(name, suffix, parser)
|
||||
.. method:: Sphinx.add_source_parser(suffix, parser)
|
||||
|
||||
Register a parser class for specified *suffix*.
|
||||
|
||||
|
||||
@@ -125,6 +125,8 @@ Both APIs parse the content into a given node. They are used like this::
|
||||
|
||||
node = docutils.nodes.paragraph()
|
||||
# either
|
||||
from sphinx.ext.autodoc import AutodocReporter
|
||||
self.state.memo.reporter = AutodocReporter(self.result, self.state.memo.reporter) # override reporter to avoid errors from "include" directive
|
||||
nested_parse_with_titles(self.state, self.result, node)
|
||||
# or
|
||||
self.state.nested_parse(self.result, 0, node)
|
||||
|
||||
@@ -10,64 +10,7 @@ any aspect of document processing.
|
||||
This chapter describes the extensions bundled with Sphinx. For the API
|
||||
documentation on writing your own extension, see :ref:`dev-extensions`.
|
||||
|
||||
Builtin Sphinx extensions
|
||||
-------------------------
|
||||
|
||||
These extensions are built in and can be activated by respective entries in the
|
||||
:confval:`extensions` configuration value:
|
||||
|
||||
.. toctree::
|
||||
|
||||
ext/autodoc
|
||||
ext/autosectionlabel
|
||||
ext/autosummary
|
||||
ext/coverage
|
||||
ext/doctest
|
||||
ext/extlinks
|
||||
ext/githubpages
|
||||
ext/graphviz
|
||||
ext/ifconfig
|
||||
ext/inheritance
|
||||
ext/intersphinx
|
||||
ext/linkcode
|
||||
ext/math
|
||||
ext/napoleon
|
||||
ext/todo
|
||||
ext/viewcode
|
||||
|
||||
|
||||
Third-party extensions
|
||||
----------------------
|
||||
|
||||
You can find several extensions contributed by users in the `Sphinx Contrib`_
|
||||
repository. It is open for anyone who wants to maintain an extension
|
||||
publicly; just send a short message asking for write permissions.
|
||||
|
||||
There are also several extensions hosted elsewhere. The `Sphinx extension
|
||||
survey <http://sphinxext-survey.readthedocs.org/en/latest/>`__ contains a
|
||||
comprehensive list.
|
||||
|
||||
If you write an extension that you think others will find useful or you think
|
||||
should be included as a part of Sphinx, please write to the project mailing
|
||||
list (`join here <https://groups.google.com/forum/#!forum/sphinx-dev>`_).
|
||||
|
||||
.. _Sphinx Contrib: https://bitbucket.org/birkenfeld/sphinx-contrib
|
||||
|
||||
|
||||
Where to put your own extensions?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Extensions local to a project should be put within the project's directory
|
||||
structure. Set Python's module search path, ``sys.path``, accordingly so that
|
||||
Sphinx can find them.
|
||||
E.g., if your extension ``foo.py`` lies in the ``exts`` subdirectory of the
|
||||
project root, put into :file:`conf.py`::
|
||||
|
||||
import sys, os
|
||||
|
||||
sys.path.append(os.path.abspath('exts'))
|
||||
|
||||
extensions = ['foo']
|
||||
|
||||
You can also install extensions anywhere else on ``sys.path``, e.g. in the
|
||||
``site-packages`` directory.
|
||||
ext/builtins
|
||||
ext/thirdparty
|
||||
|
||||
36
doc/faq.rst
@@ -167,11 +167,45 @@ The following list gives some hints for the creation of epub files:
|
||||
:confval:`html_static_path` directory and reference it with its full path in
|
||||
the :confval:`epub_cover` config option.
|
||||
|
||||
* kindlegen_ command can convert from epub3 resulting file to ``.mobi`` file
|
||||
for Kindle. You can get ``yourdoc.mobi`` under ``_build/epub`` after the
|
||||
following command:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ make epub
|
||||
$ kindlegen _build/epub/yourdoc.epub
|
||||
|
||||
kindlegen commands doesn't accept documents that have section
|
||||
titles surrounding ``toctree`` directive:
|
||||
|
||||
.. code-block:: rst
|
||||
|
||||
Section Title
|
||||
=============
|
||||
|
||||
.. toctree::
|
||||
|
||||
subdocument
|
||||
|
||||
Section After Toc Tree
|
||||
======================
|
||||
|
||||
kindlegen assumes all documents order in line, but resulting document
|
||||
has complecated order for kindlegen::
|
||||
|
||||
``parent.xhtml`` -> ``child.xhtml`` -> ``parent.xhtml``
|
||||
|
||||
If you got the following error, fix document structure::
|
||||
|
||||
Error(prcgen):E24011: TOC section scope is not included in the parent chapter:(title)
|
||||
Error(prcgen):E24001: The table of content could not be built.
|
||||
|
||||
.. _Epubcheck: https://code.google.com/archive/p/epubcheck
|
||||
.. _Calibre: http://calibre-ebook.com/
|
||||
.. _FBreader: https://fbreader.org/
|
||||
.. _Bookworm: http://www.oreilly.com/bookworm/index.html
|
||||
|
||||
.. _kindlegen: https://www.amazon.com/gp/feature.html?docId=1000765211
|
||||
|
||||
.. _texinfo-faq:
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ Installing Sphinx
|
||||
=================
|
||||
|
||||
Since Sphinx is written in the Python language, you need to install Python
|
||||
(the required version is at least 2.6) and Sphinx.
|
||||
(the required version is at least 2.7) and Sphinx.
|
||||
|
||||
Sphinx packages are available on the `Python Package Index
|
||||
<https://pypi.python.org/pypi/Sphinx>`_.
|
||||
@@ -80,8 +80,8 @@ sidebar and under "Quick Links", click "Windows Installer" to download.
|
||||
.. note::
|
||||
|
||||
Currently, Python offers two major versions, 2.x and 3.x. Sphinx 1.3 can run
|
||||
under Python 2.6, 2.7, 3.3, 3.4, with the recommended version being
|
||||
2.7. This chapter assumes you have installed Python 2.7.
|
||||
under Python 2.7, 3.4, 3.5, with the recommended version being 2.7. This
|
||||
chapter assumes you have installed Python 2.7.
|
||||
|
||||
Follow the Windows installer for Python.
|
||||
|
||||
@@ -135,7 +135,7 @@ install.
|
||||
.. note::
|
||||
|
||||
``pip`` has been contained in the Python official installation after version
|
||||
of Python-3.4.0 or Python-2.7.9.
|
||||
of Python-3.4.0 or Python-2.7.9.
|
||||
|
||||
|
||||
Installing Sphinx with pip
|
||||
|
||||
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 25 KiB |
@@ -54,7 +54,7 @@ See the :ref:`pertinent section in the FAQ list <usingwith>`.
|
||||
Prerequisites
|
||||
-------------
|
||||
|
||||
Sphinx needs at least **Python 2.6** or **Python 3.3** to run, as well as the
|
||||
Sphinx needs at least **Python 2.7** or **Python 3.4** to run, as well as the
|
||||
docutils_ and Jinja2_ libraries. Sphinx should work with docutils version 0.10
|
||||
or some (not broken) SVN trunk snapshot. If you like to have source code
|
||||
highlighting support, you must also install the Pygments_ library.
|
||||
|
||||
@@ -453,11 +453,24 @@ The :program:`sphinx-apidoc` script has several options:
|
||||
to default values, but you can influence the most important ones using the
|
||||
following options.
|
||||
|
||||
.. option:: --implicit-namespaces
|
||||
|
||||
By default sphinx-apidoc processes sys.path searching for modules only.
|
||||
Python 3.3 introduced :pep:`420` implicit namespaces that allow module path
|
||||
structures such as ``foo/bar/module.py`` or ``foo/bar/baz/__init__.py``
|
||||
(notice that ``bar`` and ``foo`` are namespaces, not modules).
|
||||
|
||||
Specifying this option interprets paths recursively according to PEP-0420.
|
||||
|
||||
.. option:: -M
|
||||
|
||||
This option makes sphinx-apidoc put module documentation before submodule
|
||||
documentation.
|
||||
|
||||
.. option:: -a
|
||||
|
||||
Append module_path to sys.path.
|
||||
|
||||
.. option:: -H project
|
||||
|
||||
Sets the project name to put in generated files (see :confval:`project`).
|
||||
|
||||
160
doc/latex.rst
Normal file
@@ -0,0 +1,160 @@
|
||||
.. 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.
|
||||
|
||||
.. hint::
|
||||
|
||||
As an experimental feature, Sphinx can use user-defined template file for
|
||||
LaTeX source if you have a file named ``_templates/latex.tex_t`` on your
|
||||
project. Now all template variables are unstable and undocumented. They
|
||||
will be changed in future version.
|
||||
|
||||
.. versionadded:: 1.5
|
||||
@@ -49,6 +49,7 @@ Options
|
||||
|
||||
These options are used with ``-F``:
|
||||
|
||||
-a Append module_path to sys.path.
|
||||
-H <project> Project name to put into the configuration.
|
||||
-A <author> Author name(s) to put into the configuration.
|
||||
-V <version> Project version.
|
||||
|
||||
@@ -21,8 +21,8 @@ an "unused" primary prompt; this is an example of what *not* to do::
|
||||
2
|
||||
>>>
|
||||
|
||||
Syntax highlighting is done with `Pygments <http://pygments.org>`_ (if it's
|
||||
installed) and handled in a smart way:
|
||||
Syntax highlighting is done with `Pygments <http://pygments.org>`_ and handled
|
||||
in a smart way:
|
||||
|
||||
* There is a "highlighting language" for each source file. Per default, this is
|
||||
``'python'`` as the majority of files will have to highlight Python snippets,
|
||||
@@ -77,7 +77,7 @@ installed) and handled in a smart way:
|
||||
Line numbers
|
||||
^^^^^^^^^^^^
|
||||
|
||||
If installed, Pygments can generate line numbers for code blocks. For
|
||||
Pygments can generate line numbers for code blocks. For
|
||||
automatically-highlighted blocks (those started by ``::``), line numbers must be
|
||||
switched on in a :rst:dir:`highlight` directive, with the ``linenothreshold``
|
||||
option::
|
||||
|
||||
@@ -200,21 +200,30 @@ Referencing downloadable files
|
||||
The ``example.py`` file will be copied to the output directory, and a
|
||||
suitable link generated to it.
|
||||
|
||||
Not to show unavailable download links, you should wrap whole paragraphs that
|
||||
have this role::
|
||||
|
||||
.. only:: builder_html
|
||||
|
||||
See :download:`this example script <../example.py>`.
|
||||
|
||||
Cross-referencing figures by figure number
|
||||
------------------------------------------
|
||||
|
||||
.. versionadded:: 1.3
|
||||
|
||||
.. versionchanged:: 1.5
|
||||
`numref` role can also refer sections.
|
||||
|
||||
.. rst:role:: numref
|
||||
|
||||
Link to the specified figures, tables and code-blocks; the standard reST
|
||||
labels are used. When you use this role, it will insert a reference to the
|
||||
figure with link text by its figure number like "Fig. 1.1".
|
||||
Link to the specified figures, tables, code-blocks and sections; the standard
|
||||
reST labels are used. When you use this role, it will insert a reference to
|
||||
the figure with link text by its figure number like "Fig. 1.1".
|
||||
|
||||
If an explicit link text is given (like usual: ``:numref:`Image of Sphinx (Fig.
|
||||
%s) <my-figure>```), the link caption will be the title of the reference.
|
||||
As a special character, `%s` will be replaced to figure number.
|
||||
The format of link text is same as :confval:`numfig_format`.
|
||||
|
||||
If :confval:`numfig` is ``False``, figures are not numbered.
|
||||
so this role inserts not a reference but labels or link text.
|
||||
|
||||
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 |
10
doc/rest.rst
@@ -196,6 +196,8 @@ Use ```Link text <http://example.com/>`_`` for inline web links. If the link
|
||||
text should be the web address, you don't need special markup at all, the parser
|
||||
finds links and mail addresses in ordinary text.
|
||||
|
||||
.. important:: There must be a space between the link text and the opening \< for the URL.
|
||||
|
||||
You can also separate the link and the target definition (:duref:`ref
|
||||
<hyperlink-targets>`), like this::
|
||||
|
||||
@@ -361,8 +363,9 @@ directory on building (e.g. the ``_static`` directory for HTML output.)
|
||||
|
||||
Interpretation of image size options (``width`` and ``height``) is as follows:
|
||||
if the size has no unit or the unit is pixels, the given size will only be
|
||||
respected for output channels that support pixels (i.e. not in LaTeX output).
|
||||
Other units (like ``pt`` for points) will be used for HTML and LaTeX output.
|
||||
respected for output channels that support pixels. Other units (like ``pt``
|
||||
for points) will be used for HTML and LaTeX output (the latter replaces ``pt``
|
||||
by ``bp`` as this is the TeX unit such that ``72bp=1in``).
|
||||
|
||||
Sphinx extends the standard docutils behavior by allowing an asterisk for the
|
||||
extension::
|
||||
@@ -384,6 +387,9 @@ Note that image file names should not contain spaces.
|
||||
.. versionchanged:: 0.6
|
||||
Image paths can now be absolute.
|
||||
|
||||
.. versionchanged:: 1.5
|
||||
latex target supports pixels (default is ``96px=1in``).
|
||||
|
||||
|
||||
Footnotes
|
||||
---------
|
||||
|
||||
BIN
doc/themes/agogo.png
vendored
|
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 |
@@ -51,7 +51,7 @@ The third form provides your theme path dynamically to Sphinx if the
|
||||
called ``sphinx_themes`` in your setup.py file and write a ``get_path`` function
|
||||
that has to return the directory with themes in it::
|
||||
|
||||
// in your 'setup.py'
|
||||
# 'setup.py'
|
||||
|
||||
setup(
|
||||
...
|
||||
@@ -63,7 +63,7 @@ that has to return the directory with themes in it::
|
||||
...
|
||||
)
|
||||
|
||||
// in 'your_package.py'
|
||||
# 'your_package.py'
|
||||
|
||||
from os import path
|
||||
package_dir = path.abspath(path.dirname(__file__))
|
||||
@@ -81,36 +81,33 @@ that has to return the directory with themes in it::
|
||||
Builtin themes
|
||||
--------------
|
||||
|
||||
.. cssclass:: longtable
|
||||
|
||||
+--------------------+--------------------+
|
||||
| **Theme overview** | |
|
||||
+--------------------+--------------------+
|
||||
| |alabaster| | |sphinx_rtd_theme| |
|
||||
| |alabaster| | |classic| |
|
||||
| | |
|
||||
| *alabaster* | *sphinx_rtd_theme* |
|
||||
| *alabaster* | *classic* |
|
||||
+--------------------+--------------------+
|
||||
| |classic| | |sphinxdoc| |
|
||||
| |sphinxdoc| | |scrolls| |
|
||||
| | |
|
||||
| *classic* | *sphinxdoc* |
|
||||
| *sphinxdoc* | *scrolls* |
|
||||
+--------------------+--------------------+
|
||||
| |scrolls| | |agogo| |
|
||||
| |agogo| | |traditional| |
|
||||
| | |
|
||||
| *scrolls* | *agogo* |
|
||||
| *agogo* | *traditional* |
|
||||
+--------------------+--------------------+
|
||||
| |traditional| | |nature| |
|
||||
| |nature| | |haiku| |
|
||||
| | |
|
||||
| *traditional* | *nature* |
|
||||
| *nature* | *haiku* |
|
||||
+--------------------+--------------------+
|
||||
| |haiku| | |pyramid| |
|
||||
| |pyramid| | |bizstyle| |
|
||||
| | |
|
||||
| *haiku* | *pyramid* |
|
||||
+--------------------+--------------------+
|
||||
| |bizstyle| | |
|
||||
| | |
|
||||
| *bizstyle* | |
|
||||
| *pyramid* | *bizstyle* |
|
||||
+--------------------+--------------------+
|
||||
|
||||
.. |alabaster| image:: themes/alabaster.png
|
||||
.. |sphinx_rtd_theme| image:: themes/sphinx_rtd_theme.png
|
||||
.. |classic| image:: themes/classic.png
|
||||
.. |sphinxdoc| image:: themes/sphinxdoc.png
|
||||
.. |scrolls| image:: themes/scrolls.png
|
||||
@@ -145,13 +142,6 @@ These themes are:
|
||||
|
||||
.. _Alabaster theme: https://pypi.python.org/pypi/alabaster
|
||||
|
||||
* **sphinx_rtd_theme** -- `Read the Docs Sphinx Theme`_.
|
||||
This is a mobile-friendly sphinx theme that was made for readthedocs.org.
|
||||
View a working demo over on readthedocs.org. You can get options information
|
||||
at `Read the Docs Sphinx Theme`_ page.
|
||||
|
||||
.. _Read the Docs Sphinx Theme: https://pypi.python.org/pypi/sphinx_rtd_theme
|
||||
|
||||
* **classic** -- This is the classic theme, which looks like `the Python 2
|
||||
documentation <https://docs.python.org/2/>`_. It can be customized via
|
||||
these options:
|
||||
@@ -273,7 +263,7 @@ These themes are:
|
||||
|
||||
.. versionchanged:: 1.3
|
||||
The 'default' theme has been renamed to 'classic'. 'default' is still
|
||||
available, however it will emit notice a recommendation that using new
|
||||
available, however it will emit a notice that it is an alias for the new
|
||||
'alabaster' theme.
|
||||
|
||||
Creating themes
|
||||
@@ -357,3 +347,28 @@ is built with the classic theme, the output directory will contain a
|
||||
.. [1] It is not an executable Python file, as opposed to :file:`conf.py`,
|
||||
because that would pose an unnecessary security risk if themes are
|
||||
shared.
|
||||
|
||||
Third Party Themes
|
||||
------------------
|
||||
|
||||
.. cssclass:: longtable
|
||||
|
||||
+--------------------+--------------------+
|
||||
| **Theme overview** | |
|
||||
+--------------------+--------------------+
|
||||
| |sphinx_rtd_theme| | |
|
||||
| | |
|
||||
| *sphinx_rtd_theme* | |
|
||||
+--------------------+--------------------+
|
||||
|
||||
.. |sphinx_rtd_theme| image:: themes/sphinx_rtd_theme.png
|
||||
|
||||
* **sphinx_rtd_theme** -- `Read the Docs Sphinx Theme`_.
|
||||
This is a mobile-friendly sphinx theme that was made for readthedocs.org.
|
||||
View a working demo over on readthedocs.org. You can get install and options
|
||||
information at `Read the Docs Sphinx Theme`_ page.
|
||||
|
||||
.. _Read the Docs Sphinx Theme: https://pypi.python.org/pypi/sphinx_rtd_theme
|
||||
|
||||
.. versionchanged:: 1.4
|
||||
**sphinx_rtd_theme** has become optional.
|
||||
|
||||
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
@@ -300,12 +300,17 @@ features of intersphinx.
|
||||
More topics to be covered
|
||||
-------------------------
|
||||
|
||||
- Other extensions (math, viewcode, doctest)
|
||||
- :doc:`Other extensions <extensions>`:
|
||||
|
||||
* :doc:`ext/math`,
|
||||
* :doc:`ext/viewcode`,
|
||||
* :doc:`ext/doctest`,
|
||||
* ...
|
||||
- Static files
|
||||
- Selecting a theme
|
||||
- Templating
|
||||
- :doc:`Selecting a theme <theming>`
|
||||
- :ref:`Templating <templating>`
|
||||
- Using extensions
|
||||
- Writing extensions
|
||||
- :ref:`Writing extensions <dev-extensions>`
|
||||
|
||||
|
||||
.. rubric:: Footnotes
|
||||
|
||||
@@ -25,5 +25,5 @@ universal = 1
|
||||
|
||||
[flake8]
|
||||
max-line-length=95
|
||||
ignore=E113,E116,E221,E226,E241,E251
|
||||
exclude=ez_setup.py,utils/*,tests/*,build/*,sphinx/search/*,sphinx/pycode/pgen2/*
|
||||
ignore=E113,E116,E221,E226,E241,E251,E901
|
||||
exclude=tests/*,build/*,sphinx/search/*,sphinx/pycode/pgen2/*,doc/ext/example*.py
|
||||
|
||||
63
setup.py
@@ -4,6 +4,7 @@ from setuptools import setup, find_packages
|
||||
import os
|
||||
import sys
|
||||
from distutils import log
|
||||
from distutils.cmd import Command
|
||||
|
||||
import sphinx
|
||||
|
||||
@@ -36,12 +37,12 @@ Among its features are the following:
|
||||
* Setuptools integration
|
||||
'''
|
||||
|
||||
if sys.version_info < (2, 6) or (3, 0) <= sys.version_info < (3, 3):
|
||||
print('ERROR: Sphinx requires at least Python 2.6 or 3.3 to run.')
|
||||
if sys.version_info < (2, 7) or (3, 0) <= sys.version_info < (3, 4):
|
||||
print('ERROR: Sphinx requires at least Python 2.7 or 3.4 to run.')
|
||||
sys.exit(1)
|
||||
|
||||
requires = [
|
||||
'six>=1.4',
|
||||
'six>=1.5',
|
||||
'Jinja2>=2.3',
|
||||
'Pygments>=2.0',
|
||||
'docutils>=0.11',
|
||||
@@ -49,6 +50,7 @@ requires = [
|
||||
'babel>=1.3,!=2.0',
|
||||
'alabaster>=0.7,<0.8',
|
||||
'imagesize',
|
||||
'requests',
|
||||
]
|
||||
extras_require = {
|
||||
# Environment Marker works for wheel 0.24 or later
|
||||
@@ -61,8 +63,9 @@ extras_require = {
|
||||
],
|
||||
'test': [
|
||||
'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.7'
|
||||
'simplejson', # better: 'test:platform_python_implementation=="PyPy"'
|
||||
'html5lib',
|
||||
],
|
||||
}
|
||||
|
||||
@@ -97,6 +100,13 @@ else:
|
||||
def run(self):
|
||||
compile_catalog.run(self)
|
||||
|
||||
if isinstance(self.domain, list):
|
||||
for domain in self.domain:
|
||||
self._run_domain_js(domain)
|
||||
else:
|
||||
self._run_domain_js(self.domain)
|
||||
|
||||
def _run_domain_js(self, domain):
|
||||
po_files = []
|
||||
js_files = []
|
||||
|
||||
@@ -105,20 +115,20 @@ else:
|
||||
po_files.append((self.locale,
|
||||
os.path.join(self.directory, self.locale,
|
||||
'LC_MESSAGES',
|
||||
self.domain + '.po')))
|
||||
domain + '.po')))
|
||||
js_files.append(os.path.join(self.directory, self.locale,
|
||||
'LC_MESSAGES',
|
||||
self.domain + '.js'))
|
||||
domain + '.js'))
|
||||
else:
|
||||
for locale in os.listdir(self.directory):
|
||||
po_file = os.path.join(self.directory, locale,
|
||||
'LC_MESSAGES',
|
||||
self.domain + '.po')
|
||||
domain + '.po')
|
||||
if os.path.exists(po_file):
|
||||
po_files.append((locale, po_file))
|
||||
js_files.append(os.path.join(self.directory, locale,
|
||||
'LC_MESSAGES',
|
||||
self.domain + '.js'))
|
||||
domain + '.js'))
|
||||
else:
|
||||
po_files.append((self.locale, self.input_file))
|
||||
if self.output_file:
|
||||
@@ -126,14 +136,11 @@ else:
|
||||
else:
|
||||
js_files.append(os.path.join(self.directory, self.locale,
|
||||
'LC_MESSAGES',
|
||||
self.domain + '.js'))
|
||||
domain + '.js'))
|
||||
|
||||
for js_file, (locale, po_file) in zip(js_files, po_files):
|
||||
infile = open(po_file, 'r')
|
||||
try:
|
||||
with open(po_file, 'r') as infile:
|
||||
catalog = read_po(infile, locale)
|
||||
finally:
|
||||
infile.close()
|
||||
|
||||
if catalog.fuzzy and not self.use_fuzzy:
|
||||
continue
|
||||
@@ -150,8 +157,7 @@ else:
|
||||
msgid = msgid[0]
|
||||
jscatalog[msgid] = message.string
|
||||
|
||||
outfile = open(js_file, 'wb')
|
||||
try:
|
||||
with open(js_file, 'wb') as outfile:
|
||||
outfile.write('Documentation.addTranslations(')
|
||||
dump(dict(
|
||||
messages=jscatalog,
|
||||
@@ -159,12 +165,35 @@ else:
|
||||
locale=str(catalog.locale)
|
||||
), outfile, sort_keys=True)
|
||||
outfile.write(');')
|
||||
finally:
|
||||
outfile.close()
|
||||
|
||||
cmdclass['compile_catalog'] = compile_catalog_plusjs
|
||||
|
||||
|
||||
class CompileGrammarCommand(Command):
|
||||
description = 'Compile python grammar file for pycode'
|
||||
user_options = []
|
||||
|
||||
def initialize_options(self):
|
||||
pass
|
||||
|
||||
def finalize_options(self):
|
||||
pass
|
||||
|
||||
def run(self):
|
||||
from sphinx.pycode.pgen2.driver import compile_grammar
|
||||
|
||||
compile_grammar('sphinx/pycode/Grammar-py2.txt')
|
||||
print('sphinx/pycode/Grammar-py2.txt ... done')
|
||||
|
||||
compile_grammar('sphinx/pycode/Grammar-py3.txt')
|
||||
print('sphinx/pycode/Grammar-py3.txt ... done')
|
||||
|
||||
def sub_commands(self):
|
||||
pass
|
||||
|
||||
cmdclass['compile_grammar'] = CompileGrammarCommand
|
||||
|
||||
|
||||
setup(
|
||||
name='Sphinx',
|
||||
version=sphinx.__version__,
|
||||
|
||||
@@ -15,13 +15,13 @@
|
||||
import sys
|
||||
from os import path
|
||||
|
||||
__version__ = '1.4a1+'
|
||||
__released__ = '1.4a1' # used when Sphinx builds its own docs
|
||||
__version__ = '1.5a2'
|
||||
__released__ = '1.5a2' # used when Sphinx builds its own docs
|
||||
|
||||
# version info for better programmatic use
|
||||
# possible values for 3rd element: 'alpha', 'beta', 'rc', 'final'
|
||||
# 'final' has 0 as the last element
|
||||
version_info = (1, 4, 0, 'alpha', 1)
|
||||
version_info = (1, 5, 0, 'alpha', 2)
|
||||
|
||||
package_dir = path.abspath(path.dirname(__file__))
|
||||
|
||||
@@ -53,9 +53,9 @@ def main(argv=sys.argv):
|
||||
|
||||
def build_main(argv=sys.argv):
|
||||
"""Sphinx build "main" command-line entry."""
|
||||
if (sys.version_info[:3] < (2, 6, 0) or
|
||||
(3, 0, 0) <= sys.version_info[:3] < (3, 3, 0)):
|
||||
sys.stderr.write('Error: Sphinx requires at least Python 2.6 or 3.3 to run.\n')
|
||||
if (sys.version_info[:3] < (2, 7, 0) or
|
||||
(3, 0, 0) <= sys.version_info[:3] < (3, 4, 0)):
|
||||
sys.stderr.write('Error: Sphinx requires at least Python 2.7 or 3.4 to run.\n')
|
||||
return 1
|
||||
try:
|
||||
from sphinx import cmdline
|
||||
|
||||
@@ -14,9 +14,53 @@ import warnings
|
||||
from docutils import nodes
|
||||
|
||||
|
||||
class toctree(nodes.General, nodes.Element):
|
||||
class translatable(object):
|
||||
"""Node which supports translation.
|
||||
|
||||
The translation goes forward with following steps:
|
||||
|
||||
1. Preserve original translatable messages
|
||||
2. Apply translated messages from message catalog
|
||||
3. Extract preserved messages (for gettext builder)
|
||||
|
||||
The translatable nodes MUST preserve original messages.
|
||||
And these messages should not be overridden at applying step.
|
||||
Because they are used at final step; extraction.
|
||||
"""
|
||||
|
||||
def preserve_original_messages(self):
|
||||
"""Preserve original translatable messages."""
|
||||
raise NotImplementedError
|
||||
|
||||
def apply_translated_message(self, original_message, translated_message):
|
||||
"""Apply translated message."""
|
||||
raise NotImplementedError
|
||||
|
||||
def extract_original_messages(self):
|
||||
"""Extract translation messages.
|
||||
|
||||
:returns: list of extracted messages or messages generator
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class toctree(nodes.General, nodes.Element, translatable):
|
||||
"""Node for inserting a "TOC tree"."""
|
||||
|
||||
def preserve_original_messages(self):
|
||||
if 'caption' in self:
|
||||
self['rawcaption'] = self['caption']
|
||||
|
||||
def apply_translated_message(self, original_message, translated_message):
|
||||
if self.get('rawcaption') == original_message:
|
||||
self['caption'] = translated_message
|
||||
|
||||
def extract_original_messages(self):
|
||||
if 'rawcaption' in self:
|
||||
return [self['rawcaption']]
|
||||
else:
|
||||
return []
|
||||
|
||||
|
||||
# domain-specific object descriptions (class, function etc.)
|
||||
|
||||
@@ -116,10 +160,14 @@ class index(nodes.Invisible, nodes.Inline, nodes.TextElement):
|
||||
"""Node for index entries.
|
||||
|
||||
This node is created by the ``index`` directive and has one attribute,
|
||||
``entries``. Its value is a list of 4-tuples of ``(entrytype, entryname,
|
||||
target, ignored)``.
|
||||
``entries``. Its value is a list of 5-tuples of ``(entrytype, entryname,
|
||||
target, ignored, key)``.
|
||||
|
||||
*entrytype* is one of "single", "pair", "double", "triple".
|
||||
|
||||
*key* is categolziation characters (usually it is single character) for
|
||||
general index page. For the detail of this, please see also:
|
||||
:rst:dir:`glossary` and issue #2320.
|
||||
"""
|
||||
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ import optparse
|
||||
from os import path
|
||||
from six import binary_type
|
||||
|
||||
from sphinx.util.osutil import walk
|
||||
from sphinx.util.osutil import FileAvoidWrite, walk
|
||||
from sphinx import __display_version__
|
||||
|
||||
# automodule options
|
||||
@@ -62,11 +62,8 @@ def write_file(name, text, opts):
|
||||
print('File %s already exists, skipping.' % fname)
|
||||
else:
|
||||
print('Creating file %s.' % fname)
|
||||
f = open(fname, 'w')
|
||||
try:
|
||||
with FileAvoidWrite(fname) as f:
|
||||
f.write(text)
|
||||
finally:
|
||||
f.close()
|
||||
|
||||
|
||||
def format_heading(level, text):
|
||||
@@ -94,11 +91,12 @@ def create_module_file(package, module, opts):
|
||||
write_file(makename(package, module), text, opts)
|
||||
|
||||
|
||||
def create_package_file(root, master_package, subroot, py_files, opts, subs):
|
||||
def create_package_file(root, master_package, subroot, py_files, opts, subs, is_namespace):
|
||||
"""Build the text of the file and write the file."""
|
||||
text = format_heading(1, '%s package' % makename(master_package, subroot))
|
||||
text = format_heading(1, ('%s package' if not is_namespace else "%s namespace")
|
||||
% makename(master_package, subroot))
|
||||
|
||||
if opts.modulefirst:
|
||||
if opts.modulefirst and not is_namespace:
|
||||
text += format_directive(subroot, master_package)
|
||||
text += '\n'
|
||||
|
||||
@@ -141,7 +139,7 @@ def create_package_file(root, master_package, subroot, py_files, opts, subs):
|
||||
text += '\n'
|
||||
text += '\n'
|
||||
|
||||
if not opts.modulefirst:
|
||||
if not opts.modulefirst and not is_namespace:
|
||||
text += format_heading(2, 'Module contents')
|
||||
text += format_directive(subroot, master_package)
|
||||
|
||||
@@ -168,9 +166,14 @@ def create_modules_toc_file(modules, opts, name='modules'):
|
||||
|
||||
def shall_skip(module, opts):
|
||||
"""Check if we want to skip this module."""
|
||||
# skip it if there is nothing (or just \n or \r\n) in the file
|
||||
if path.getsize(module) <= 2:
|
||||
# skip if the file doesn't exist and not using implicit namespaces
|
||||
if not opts.implicit_namespaces and not path.exists(module):
|
||||
return True
|
||||
|
||||
# skip it if there is nothing (or just \n or \r\n) in the file
|
||||
if path.exists(module) and path.getsize(module) <= 2:
|
||||
return True
|
||||
|
||||
# skip if it has a "private" name and this is selected
|
||||
filename = path.basename(module)
|
||||
if filename != '__init__.py' and filename.startswith('_') and \
|
||||
@@ -194,19 +197,22 @@ def recurse_tree(rootpath, excludes, opts):
|
||||
toplevels = []
|
||||
followlinks = getattr(opts, 'followlinks', False)
|
||||
includeprivate = getattr(opts, 'includeprivate', False)
|
||||
implicit_namespaces = getattr(opts, 'implicit_namespaces', False)
|
||||
for root, subs, files in walk(rootpath, followlinks=followlinks):
|
||||
# document only Python module files (that aren't excluded)
|
||||
py_files = sorted(f for f in files
|
||||
if path.splitext(f)[1] in PY_SUFFIXES and
|
||||
not is_excluded(path.join(root, f), excludes))
|
||||
is_pkg = INITPY in py_files
|
||||
is_namespace = INITPY not in py_files and implicit_namespaces
|
||||
if is_pkg:
|
||||
py_files.remove(INITPY)
|
||||
py_files.insert(0, INITPY)
|
||||
elif root != rootpath:
|
||||
# only accept non-package at toplevel
|
||||
del subs[:]
|
||||
continue
|
||||
# only accept non-package at toplevel unless using implicit namespaces
|
||||
if not implicit_namespaces:
|
||||
del subs[:]
|
||||
continue
|
||||
# remove hidden ('.') and private ('_') directories, as well as
|
||||
# excluded dirs
|
||||
if includeprivate:
|
||||
@@ -216,15 +222,17 @@ def recurse_tree(rootpath, excludes, opts):
|
||||
subs[:] = sorted(sub for sub in subs if not sub.startswith(exclude_prefixes) and
|
||||
not is_excluded(path.join(root, sub), excludes))
|
||||
|
||||
if is_pkg:
|
||||
if is_pkg or is_namespace:
|
||||
# we are in a package with something to document
|
||||
if subs or len(py_files) > 1 or not \
|
||||
shall_skip(path.join(root, INITPY), opts):
|
||||
if subs or len(py_files) > 1 or not shall_skip(path.join(root, INITPY), opts):
|
||||
subpackage = root[len(rootpath):].lstrip(path.sep).\
|
||||
replace(path.sep, '.')
|
||||
create_package_file(root, root_package, subpackage,
|
||||
py_files, opts, subs)
|
||||
toplevels.append(makename(root_package, subpackage))
|
||||
# if this is not a namespace or
|
||||
# a namespace and there is something there to document
|
||||
if not is_namespace or len(py_files) > 0:
|
||||
create_package_file(root, root_package, subpackage,
|
||||
py_files, opts, subs, is_namespace)
|
||||
toplevels.append(makename(root_package, subpackage))
|
||||
else:
|
||||
# if we are at the root level, we don't require it to be a package
|
||||
assert root == rootpath and root_package is None
|
||||
@@ -298,10 +306,17 @@ Note: By default this script will not overwrite already created files.""")
|
||||
dest='modulefirst',
|
||||
help='Put module documentation before submodule '
|
||||
'documentation')
|
||||
parser.add_option('--implicit-namespaces', action='store_true',
|
||||
dest='implicit_namespaces',
|
||||
help='Interpret module paths according to PEP-0420 '
|
||||
'implicit namespaces specification')
|
||||
parser.add_option('-s', '--suffix', action='store', dest='suffix',
|
||||
help='file suffix (default: rst)', default='rst')
|
||||
parser.add_option('-F', '--full', action='store_true', dest='full',
|
||||
help='Generate a full project with sphinx-quickstart')
|
||||
parser.add_option('-a', '--append-syspath', action='store_true',
|
||||
dest='append_syspath',
|
||||
help='Append module_path to sys.path, used when --full is given')
|
||||
parser.add_option('-H', '--doc-project', action='store', dest='header',
|
||||
help='Project name (default: root module name)')
|
||||
parser.add_option('-A', '--doc-author', action='store', dest='author',
|
||||
@@ -369,6 +384,8 @@ Note: By default this script will not overwrite already created files.""")
|
||||
mastertocmaxdepth = opts.maxdepth,
|
||||
mastertoctree = text,
|
||||
language = 'en',
|
||||
module_path = rootpath,
|
||||
append_syspath = opts.append_syspath,
|
||||
)
|
||||
if isinstance(opts.header, binary_type):
|
||||
d['project'] = d['project'].decode('utf-8')
|
||||
|
||||
@@ -32,18 +32,18 @@ from sphinx.roles import XRefRole
|
||||
from sphinx.config import Config
|
||||
from sphinx.errors import SphinxError, SphinxWarning, ExtensionError, \
|
||||
VersionRequirementError, ConfigError
|
||||
from sphinx.domains import ObjType, BUILTIN_DOMAINS
|
||||
from sphinx.domains import ObjType
|
||||
from sphinx.domains.std import GenericObject, Target, StandardDomain
|
||||
from sphinx.builders import BUILTIN_BUILDERS
|
||||
from sphinx.environment import BuildEnvironment
|
||||
from sphinx.io import SphinxStandaloneReader
|
||||
from sphinx.util import pycompat # noqa: imported for side-effects
|
||||
from sphinx.util import pycompat # noqa: F401
|
||||
from sphinx.util import import_object
|
||||
from sphinx.util.tags import Tags
|
||||
from sphinx.util.osutil import ENOENT
|
||||
from sphinx.util.logging import is_suppressed_warning
|
||||
from sphinx.util.console import bold, lightgray, darkgray, darkgreen, \
|
||||
from sphinx.util.console import bold, lightgray, darkgray, darkred, darkgreen, \
|
||||
term_width_line
|
||||
from sphinx.util.i18n import find_catalog_source_files
|
||||
|
||||
if hasattr(sys, 'intern'):
|
||||
intern = sys.intern
|
||||
@@ -64,10 +64,44 @@ events = {
|
||||
'html-page-context': 'pagename, context, doctree or None',
|
||||
'build-finished': 'exception',
|
||||
}
|
||||
builtin_extensions = (
|
||||
'sphinx.builders.applehelp',
|
||||
'sphinx.builders.changes',
|
||||
'sphinx.builders.epub',
|
||||
'sphinx.builders.epub3',
|
||||
'sphinx.builders.devhelp',
|
||||
'sphinx.builders.dummy',
|
||||
'sphinx.builders.gettext',
|
||||
'sphinx.builders.html',
|
||||
'sphinx.builders.htmlhelp',
|
||||
'sphinx.builders.latex',
|
||||
'sphinx.builders.linkcheck',
|
||||
'sphinx.builders.manpage',
|
||||
'sphinx.builders.qthelp',
|
||||
'sphinx.builders.texinfo',
|
||||
'sphinx.builders.text',
|
||||
'sphinx.builders.websupport',
|
||||
'sphinx.builders.xml',
|
||||
'sphinx.domains.c',
|
||||
'sphinx.domains.cpp',
|
||||
'sphinx.domains.javascript',
|
||||
'sphinx.domains.python',
|
||||
'sphinx.domains.rst',
|
||||
'sphinx.domains.std',
|
||||
'sphinx.directives',
|
||||
'sphinx.directives.code',
|
||||
'sphinx.directives.other',
|
||||
'sphinx.directives.patches',
|
||||
'sphinx.roles',
|
||||
)
|
||||
|
||||
CONFIG_FILENAME = 'conf.py'
|
||||
ENV_PICKLE_FILENAME = 'environment.pickle'
|
||||
|
||||
# list of deprecated extensions. Keys are extension name.
|
||||
# Values are Sphinx version that merge the extension.
|
||||
EXTENSION_BLACKLIST = {"sphinxjp.themecore": "1.2"}
|
||||
|
||||
|
||||
class Sphinx(object):
|
||||
|
||||
@@ -82,9 +116,9 @@ class Sphinx(object):
|
||||
self._additional_source_parsers = {}
|
||||
self._listeners = {}
|
||||
self._setting_up_extension = ['?']
|
||||
self.domains = BUILTIN_DOMAINS.copy()
|
||||
self.domains = {}
|
||||
self.buildername = buildername
|
||||
self.builderclasses = BUILTIN_BUILDERS.copy()
|
||||
self.builderclasses = {}
|
||||
self.builder = None
|
||||
self.env = None
|
||||
self.enumerable_nodes = {}
|
||||
@@ -133,11 +167,30 @@ class Sphinx(object):
|
||||
self.config.check_unicode(self.warn)
|
||||
# defer checking types until i18n has been initialized
|
||||
|
||||
# initialize some limited config variables before loading extensions
|
||||
self.config.pre_init_values(self.warn)
|
||||
|
||||
# check the Sphinx version if requested
|
||||
if self.config.needs_sphinx and self.config.needs_sphinx > sphinx.__display_version__:
|
||||
raise VersionRequirementError(
|
||||
'This project needs at least Sphinx v%s and therefore cannot '
|
||||
'be built with this version.' % self.config.needs_sphinx)
|
||||
|
||||
# force preload html_translator_class
|
||||
if self.config.html_translator_class:
|
||||
translator_class = self.import_object(self.config.html_translator_class,
|
||||
'html_translator_class setting')
|
||||
self.set_translator('html', translator_class)
|
||||
|
||||
# set confdir to srcdir if -C given (!= no confdir); a few pieces
|
||||
# of code expect a confdir to be set
|
||||
if self.confdir is None:
|
||||
self.confdir = self.srcdir
|
||||
|
||||
# load all built-in extension modules
|
||||
for extension in builtin_extensions:
|
||||
self.setup_extension(extension)
|
||||
|
||||
# extension loading support for alabaster theme
|
||||
# self.config.html_theme is not set from conf.py at here
|
||||
# for now, sphinx always load a 'alabaster' extension.
|
||||
@@ -163,13 +216,6 @@ class Sphinx(object):
|
||||
# now that we know all config values, collect them from conf.py
|
||||
self.config.init_values(self.warn)
|
||||
|
||||
# check the Sphinx version if requested
|
||||
if self.config.needs_sphinx and \
|
||||
self.config.needs_sphinx > sphinx.__display_version__:
|
||||
raise VersionRequirementError(
|
||||
'This project needs at least Sphinx v%s and therefore cannot '
|
||||
'be built with this version.' % self.config.needs_sphinx)
|
||||
|
||||
# check extension versions if requested
|
||||
if self.config.needs_extensions:
|
||||
for extname, needs_ver in self.config.needs_extensions.items():
|
||||
@@ -185,6 +231,10 @@ class Sphinx(object):
|
||||
'version %s and therefore cannot be built with the '
|
||||
'loaded version (%s).' % (extname, needs_ver, has_ver))
|
||||
|
||||
# check primary_domain if requested
|
||||
if self.config.primary_domain and self.config.primary_domain not in self.domains:
|
||||
self.warn('primary_domain %r not found, ignored.' % self.config.primary_domain)
|
||||
|
||||
# set up translation infrastructure
|
||||
self._init_i18n()
|
||||
# check all configuration values for permissible types
|
||||
@@ -205,13 +255,17 @@ class Sphinx(object):
|
||||
if self.config.language is not None:
|
||||
self.info(bold('loading translations [%s]... ' %
|
||||
self.config.language), nonl=True)
|
||||
locale_dirs = [None, path.join(package_dir, 'locale')] + \
|
||||
[path.join(self.srcdir, x) for x in self.config.locale_dirs]
|
||||
user_locale_dirs = [
|
||||
path.join(self.srcdir, x) for x in self.config.locale_dirs]
|
||||
# compile mo files if sphinx.po file in user locale directories are updated
|
||||
for catinfo in find_catalog_source_files(
|
||||
user_locale_dirs, self.config.language, domains=['sphinx'],
|
||||
charset=self.config.source_encoding):
|
||||
catinfo.write_mo(self.config.language)
|
||||
locale_dirs = [None, path.join(package_dir, 'locale')] + user_locale_dirs
|
||||
else:
|
||||
locale_dirs = []
|
||||
self.translator, has_translation = locale.init(locale_dirs,
|
||||
self.config.language,
|
||||
charset=self.config.source_encoding)
|
||||
self.translator, has_translation = locale.init(locale_dirs, self.config.language)
|
||||
if self.config.language is not None:
|
||||
if has_translation or self.config.language == 'en':
|
||||
# "en" never needs to be translated
|
||||
@@ -228,8 +282,8 @@ class Sphinx(object):
|
||||
|
||||
def _init_env(self, freshenv):
|
||||
if freshenv:
|
||||
self.env = BuildEnvironment(self.srcdir, self.doctreedir,
|
||||
self.config)
|
||||
self.env = BuildEnvironment(self.srcdir, self.doctreedir, self.config)
|
||||
self.env.set_warnfunc(self.warn)
|
||||
self.env.find_files(self.config)
|
||||
for domain in self.domains.keys():
|
||||
self.env.domains[domain] = self.domains[domain](self.env)
|
||||
@@ -238,6 +292,7 @@ class Sphinx(object):
|
||||
self.info(bold('loading pickled environment... '), nonl=True)
|
||||
self.env = BuildEnvironment.frompickle(
|
||||
self.srcdir, self.config, path.join(self.doctreedir, ENV_PICKLE_FILENAME))
|
||||
self.env.set_warnfunc(self.warn)
|
||||
self.env.domains = {}
|
||||
for domain in self.domains.keys():
|
||||
# this can raise if the data version doesn't fit
|
||||
@@ -250,8 +305,6 @@ class Sphinx(object):
|
||||
self.info('failed: %s' % err)
|
||||
return self._init_env(freshenv=True)
|
||||
|
||||
self.env.set_warnfunc(self.warn)
|
||||
|
||||
def _init_builder(self, buildername):
|
||||
if buildername is None:
|
||||
print('No builder selected, using default: html', file=self._status)
|
||||
@@ -260,11 +313,6 @@ class Sphinx(object):
|
||||
raise SphinxError('Builder name %s not registered' % buildername)
|
||||
|
||||
builderclass = self.builderclasses[buildername]
|
||||
if isinstance(builderclass, tuple):
|
||||
# builtin builder
|
||||
mod, cls = builderclass
|
||||
builderclass = getattr(
|
||||
__import__('sphinx.builders.' + mod, None, None, [cls]), cls)
|
||||
self.builder = builderclass(self)
|
||||
self.emit('builder-inited')
|
||||
|
||||
@@ -319,7 +367,8 @@ class Sphinx(object):
|
||||
wfile.flush()
|
||||
self.messagelog.append(message)
|
||||
|
||||
def warn(self, message, location=None, prefix='WARNING: ', type=None, subtype=None):
|
||||
def warn(self, message, location=None, prefix='WARNING: ',
|
||||
type=None, subtype=None, colorfunc=darkred):
|
||||
"""Emit a warning.
|
||||
|
||||
If *location* is given, it should either be a tuple of (docname, lineno)
|
||||
@@ -349,7 +398,7 @@ class Sphinx(object):
|
||||
if self.warningiserror:
|
||||
raise SphinxWarning(warntext)
|
||||
self._warncount += 1
|
||||
self._log(warntext, self._warning, True)
|
||||
self._log(colorfunc(warntext), self._warning, True)
|
||||
|
||||
def info(self, message='', nonl=False):
|
||||
"""Emit an informational message.
|
||||
@@ -453,6 +502,11 @@ class Sphinx(object):
|
||||
self.debug('[app] setting up extension: %r', extension)
|
||||
if extension in self._extensions:
|
||||
return
|
||||
if extension in EXTENSION_BLACKLIST:
|
||||
self.warn('the extension %r was already merged with Sphinx since version %s; '
|
||||
'this extension is ignored.' % (
|
||||
extension, EXTENSION_BLACKLIST[extension]))
|
||||
return
|
||||
self._setting_up_extension.append(extension)
|
||||
try:
|
||||
mod = __import__(extension, None, None, ['setup'])
|
||||
@@ -550,13 +604,9 @@ class Sphinx(object):
|
||||
raise ExtensionError('Builder class %s has no "name" attribute'
|
||||
% builder)
|
||||
if builder.name in self.builderclasses:
|
||||
if isinstance(self.builderclasses[builder.name], tuple):
|
||||
raise ExtensionError('Builder %r is a builtin builder' %
|
||||
builder.name)
|
||||
else:
|
||||
raise ExtensionError(
|
||||
'Builder %r already exists (in module %s)' % (
|
||||
builder.name, self.builderclasses[builder.name].__module__))
|
||||
raise ExtensionError(
|
||||
'Builder %r already exists (in module %s)' % (
|
||||
builder.name, self.builderclasses[builder.name].__module__))
|
||||
self.builderclasses[builder.name] = builder
|
||||
|
||||
def add_config_value(self, name, default, rebuild, types=()):
|
||||
@@ -584,7 +634,8 @@ class Sphinx(object):
|
||||
hasattr(nodes.GenericNodeVisitor, 'visit_' + node.__name__):
|
||||
self.warn('while setting up extension %s: node class %r is '
|
||||
'already registered, its visitors will be overridden' %
|
||||
(self._setting_up_extension, node.__name__))
|
||||
(self._setting_up_extension, node.__name__),
|
||||
type='app', subtype='add_node')
|
||||
nodes._add_node_class_names([node.__name__])
|
||||
for key, val in iteritems(kwds):
|
||||
try:
|
||||
@@ -636,7 +687,8 @@ class Sphinx(object):
|
||||
if name in directives._directives:
|
||||
self.warn('while setting up extension %s: directive %r is '
|
||||
'already registered, it will be overridden' %
|
||||
(self._setting_up_extension[-1], name))
|
||||
(self._setting_up_extension[-1], name),
|
||||
type='app', subtype='add_directive')
|
||||
directives.register_directive(
|
||||
name, self._directive_helper(obj, content, arguments, **options))
|
||||
|
||||
@@ -645,7 +697,8 @@ class Sphinx(object):
|
||||
if name in roles._roles:
|
||||
self.warn('while setting up extension %s: role %r is '
|
||||
'already registered, it will be overridden' %
|
||||
(self._setting_up_extension[-1], name))
|
||||
(self._setting_up_extension[-1], name),
|
||||
type='app', subtype='add_role')
|
||||
roles.register_local_role(name, role)
|
||||
|
||||
def add_generic_role(self, name, nodeclass):
|
||||
@@ -655,7 +708,8 @@ class Sphinx(object):
|
||||
if name in roles._roles:
|
||||
self.warn('while setting up extension %s: role %r is '
|
||||
'already registered, it will be overridden' %
|
||||
(self._setting_up_extension[-1], name))
|
||||
(self._setting_up_extension[-1], name),
|
||||
type='app', subtype='add_generic_role')
|
||||
role = roles.GenericRole(name, nodeclass)
|
||||
roles.register_local_role(name, role)
|
||||
|
||||
@@ -759,8 +813,7 @@ class Sphinx(object):
|
||||
|
||||
def add_latex_package(self, packagename, options=None):
|
||||
self.debug('[app] adding latex package: %r', packagename)
|
||||
from sphinx.builders.latex import LaTeXBuilder
|
||||
LaTeXBuilder.usepackages.append((packagename, options))
|
||||
self.builder.usepackages.append((packagename, options))
|
||||
|
||||
def add_lexer(self, alias, lexer):
|
||||
self.debug('[app] adding lexer: %r', (alias, lexer))
|
||||
@@ -788,6 +841,11 @@ class Sphinx(object):
|
||||
|
||||
def add_source_parser(self, suffix, parser):
|
||||
self.debug('[app] adding search source_parser: %r, %r', (suffix, parser))
|
||||
if suffix in self._additional_source_parsers:
|
||||
self.warn('while setting up extension %s: source_parser for %r is '
|
||||
'already registered, it will be overridden' %
|
||||
(self._setting_up_extension[-1], suffix),
|
||||
type='app', subtype='add_source_parser')
|
||||
self._additional_source_parsers[suffix] = parser
|
||||
|
||||
|
||||
|
||||
@@ -451,29 +451,3 @@ class Builder(object):
|
||||
except AttributeError:
|
||||
optname = '%s_%s' % (default, option)
|
||||
return getattr(self.config, optname)
|
||||
|
||||
BUILTIN_BUILDERS = {
|
||||
'dummy': ('dummy', 'DummyBuilder'),
|
||||
'html': ('html', 'StandaloneHTMLBuilder'),
|
||||
'dirhtml': ('html', 'DirectoryHTMLBuilder'),
|
||||
'singlehtml': ('html', 'SingleFileHTMLBuilder'),
|
||||
'pickle': ('html', 'PickleHTMLBuilder'),
|
||||
'json': ('html', 'JSONHTMLBuilder'),
|
||||
'web': ('html', 'PickleHTMLBuilder'),
|
||||
'htmlhelp': ('htmlhelp', 'HTMLHelpBuilder'),
|
||||
'devhelp': ('devhelp', 'DevhelpBuilder'),
|
||||
'qthelp': ('qthelp', 'QtHelpBuilder'),
|
||||
'applehelp': ('applehelp', 'AppleHelpBuilder'),
|
||||
'epub': ('epub', 'EpubBuilder'),
|
||||
'epub3': ('epub3', 'Epub3Builder'),
|
||||
'latex': ('latex', 'LaTeXBuilder'),
|
||||
'text': ('text', 'TextBuilder'),
|
||||
'man': ('manpage', 'ManualPageBuilder'),
|
||||
'texinfo': ('texinfo', 'TexinfoBuilder'),
|
||||
'changes': ('changes', 'ChangesBuilder'),
|
||||
'linkcheck': ('linkcheck', 'CheckExternalLinksBuilder'),
|
||||
'websupport': ('websupport', 'WebSupportBuilder'),
|
||||
'gettext': ('gettext', 'MessageCatalogBuilder'),
|
||||
'xml': ('xml', 'XMLBuilder'),
|
||||
'pseudoxml': ('xml', 'PseudoXMLBuilder'),
|
||||
}
|
||||
|
||||
@@ -13,14 +13,16 @@ from __future__ import print_function
|
||||
import codecs
|
||||
import pipes
|
||||
|
||||
from os import path
|
||||
from os import path, environ
|
||||
import shlex
|
||||
|
||||
from sphinx.builders.html import StandaloneHTMLBuilder
|
||||
from sphinx.util import copy_static_entry
|
||||
from sphinx.util.osutil import copyfile, ensuredir
|
||||
from sphinx.config import string_classes
|
||||
from sphinx.util.osutil import copyfile, ensuredir, make_filename
|
||||
from sphinx.util.console import bold
|
||||
from sphinx.util.fileutil import copy_asset
|
||||
from sphinx.util.pycompat import htmlescape
|
||||
from sphinx.util.matching import compile_matchers
|
||||
from sphinx.util.matching import Matcher
|
||||
from sphinx.errors import SphinxError
|
||||
|
||||
import plistlib
|
||||
@@ -84,6 +86,7 @@ class AppleHelpBuilder(StandaloneHTMLBuilder):
|
||||
super(AppleHelpBuilder, self).init()
|
||||
# the output files for HTML help must be .html only
|
||||
self.out_suffix = '.html'
|
||||
self.link_suffix = '.html'
|
||||
|
||||
if self.config.applehelp_bundle_id is None:
|
||||
raise SphinxError('You must set applehelp_bundle_id before '
|
||||
@@ -104,17 +107,15 @@ class AppleHelpBuilder(StandaloneHTMLBuilder):
|
||||
self.finish_tasks.add_task(self.build_helpbook)
|
||||
|
||||
def copy_localized_files(self):
|
||||
source_dir = path.join(self.confdir,
|
||||
self.config.applehelp_locale + '.lproj')
|
||||
source_dir = path.join(self.confdir, self.config.applehelp_locale + '.lproj')
|
||||
target_dir = self.outdir
|
||||
|
||||
if path.isdir(source_dir):
|
||||
self.info(bold('copying localized files... '), nonl=True)
|
||||
|
||||
ctx = self.globalcontext.copy()
|
||||
matchers = compile_matchers(self.config.exclude_patterns)
|
||||
copy_static_entry(source_dir, target_dir, self, ctx,
|
||||
exclude_matchers=matchers)
|
||||
excluded = Matcher(self.config.exclude_patterns + ['**/.*'])
|
||||
copy_asset(source_dir, target_dir, excluded,
|
||||
context=self.globalcontext, renderer=self.templates)
|
||||
|
||||
self.info('done')
|
||||
|
||||
@@ -178,14 +179,11 @@ class AppleHelpBuilder(StandaloneHTMLBuilder):
|
||||
|
||||
# Build the access page
|
||||
self.info(bold('building access page...'), nonl=True)
|
||||
f = codecs.open(path.join(language_dir, '_access.html'), 'w')
|
||||
try:
|
||||
with codecs.open(path.join(language_dir, '_access.html'), 'w') as f:
|
||||
f.write(access_page_template % {
|
||||
'toc': htmlescape(toc, quote=True),
|
||||
'title': htmlescape(self.config.applehelp_title)
|
||||
})
|
||||
finally:
|
||||
f.close()
|
||||
self.info('done')
|
||||
|
||||
# Generate the help index
|
||||
@@ -216,16 +214,19 @@ class AppleHelpBuilder(StandaloneHTMLBuilder):
|
||||
self.warn('you will need to index this help book with:\n %s'
|
||||
% (' '.join([pipes.quote(arg) for arg in args])))
|
||||
else:
|
||||
p = subprocess.Popen(args,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT)
|
||||
try:
|
||||
p = subprocess.Popen(args,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT)
|
||||
|
||||
output = p.communicate()[0]
|
||||
output = p.communicate()[0]
|
||||
|
||||
if p.returncode != 0:
|
||||
raise AppleHelpIndexerFailed(output)
|
||||
else:
|
||||
self.info('done')
|
||||
if p.returncode != 0:
|
||||
raise AppleHelpIndexerFailed(output)
|
||||
else:
|
||||
self.info('done')
|
||||
except OSError:
|
||||
raise AppleHelpIndexerFailed('Command not found: %s' % args[0])
|
||||
|
||||
# If we've been asked to, sign the bundle
|
||||
if self.config.applehelp_codesign_identity:
|
||||
@@ -247,13 +248,48 @@ class AppleHelpBuilder(StandaloneHTMLBuilder):
|
||||
self.warn('you will need to sign this help book with:\n %s'
|
||||
% (' '.join([pipes.quote(arg) for arg in args])))
|
||||
else:
|
||||
p = subprocess.Popen(args,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT)
|
||||
try:
|
||||
p = subprocess.Popen(args,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT)
|
||||
|
||||
output = p.communicate()[0]
|
||||
output = p.communicate()[0]
|
||||
|
||||
if p.returncode != 0:
|
||||
raise AppleHelpCodeSigningFailed(output)
|
||||
else:
|
||||
self.info('done')
|
||||
if p.returncode != 0:
|
||||
raise AppleHelpCodeSigningFailed(output)
|
||||
else:
|
||||
self.info('done')
|
||||
except OSError:
|
||||
raise AppleHelpCodeSigningFailed('Command not found: %s' % args[0])
|
||||
|
||||
|
||||
def setup(app):
|
||||
app.setup_extension('sphinx.builders.html')
|
||||
app.add_builder(AppleHelpBuilder)
|
||||
|
||||
app.add_config_value('applehelp_bundle_name',
|
||||
lambda self: make_filename(self.project), 'applehelp')
|
||||
app.add_config_value('applehelp_bundle_id', None, 'applehelp', string_classes)
|
||||
app.add_config_value('applehelp_dev_region', 'en-us', 'applehelp')
|
||||
app.add_config_value('applehelp_bundle_version', '1', 'applehelp')
|
||||
app.add_config_value('applehelp_icon', None, 'applehelp', string_classes)
|
||||
app.add_config_value('applehelp_kb_product',
|
||||
lambda self: '%s-%s' % (make_filename(self.project), self.release),
|
||||
'applehelp')
|
||||
app.add_config_value('applehelp_kb_url', None, 'applehelp', string_classes)
|
||||
app.add_config_value('applehelp_remote_url', None, 'applehelp', string_classes)
|
||||
app.add_config_value('applehelp_index_anchors', False, 'applehelp', string_classes)
|
||||
app.add_config_value('applehelp_min_term_length', None, 'applehelp', string_classes)
|
||||
app.add_config_value('applehelp_stopwords',
|
||||
lambda self: self.language or 'en', 'applehelp')
|
||||
app.add_config_value('applehelp_locale', lambda self: self.language or 'en', 'applehelp')
|
||||
app.add_config_value('applehelp_title', lambda self: self.project + ' Help', 'applehelp')
|
||||
app.add_config_value('applehelp_codesign_identity',
|
||||
lambda self: environ.get('CODE_SIGN_IDENTITY', None),
|
||||
'applehelp'),
|
||||
app.add_config_value('applehelp_codesign_flags',
|
||||
lambda self: shlex.split(environ.get('OTHER_CODE_SIGN_FLAGS', '')),
|
||||
'applehelp'),
|
||||
app.add_config_value('applehelp_indexer_path', '/usr/bin/hiutil', 'applehelp')
|
||||
app.add_config_value('applehelp_codesign_path', '/usr/bin/codesign', 'applehelp')
|
||||
app.add_config_value('applehelp_disable_external_tools', False, None)
|
||||
|
||||
@@ -15,12 +15,12 @@ from os import path
|
||||
from six import iteritems
|
||||
|
||||
from sphinx import package_dir
|
||||
from sphinx.util import copy_static_entry
|
||||
from sphinx.locale import _
|
||||
from sphinx.theming import Theme
|
||||
from sphinx.builders import Builder
|
||||
from sphinx.util.osutil import ensuredir, os_path
|
||||
from sphinx.util.console import bold
|
||||
from sphinx.util.fileutil import copy_asset_file
|
||||
from sphinx.util.pycompat import htmlescape
|
||||
|
||||
|
||||
@@ -101,16 +101,10 @@ class ChangesBuilder(Builder):
|
||||
'show_copyright': self.config.html_show_copyright,
|
||||
'show_sphinx': self.config.html_show_sphinx,
|
||||
}
|
||||
f = codecs.open(path.join(self.outdir, 'index.html'), 'w', 'utf8')
|
||||
try:
|
||||
with codecs.open(path.join(self.outdir, 'index.html'), 'w', 'utf8') as f:
|
||||
f.write(self.templates.render('changes/frameset.html', ctx))
|
||||
finally:
|
||||
f.close()
|
||||
f = codecs.open(path.join(self.outdir, 'changes.html'), 'w', 'utf8')
|
||||
try:
|
||||
with codecs.open(path.join(self.outdir, 'changes.html'), 'w', 'utf8') as f:
|
||||
f.write(self.templates.render('changes/versionchanges.html', ctx))
|
||||
finally:
|
||||
f.close()
|
||||
|
||||
hltext = ['.. versionadded:: %s' % version,
|
||||
'.. versionchanged:: %s' % version,
|
||||
@@ -126,35 +120,28 @@ class ChangesBuilder(Builder):
|
||||
|
||||
self.info(bold('copying source files...'))
|
||||
for docname in self.env.all_docs:
|
||||
f = codecs.open(self.env.doc2path(docname), 'r',
|
||||
self.env.config.source_encoding)
|
||||
try:
|
||||
lines = f.readlines()
|
||||
except UnicodeDecodeError:
|
||||
self.warn('could not read %r for changelog creation' % docname)
|
||||
continue
|
||||
finally:
|
||||
f.close()
|
||||
with codecs.open(self.env.doc2path(docname), 'r',
|
||||
self.env.config.source_encoding) as f:
|
||||
try:
|
||||
lines = f.readlines()
|
||||
except UnicodeDecodeError:
|
||||
self.warn('could not read %r for changelog creation' % docname)
|
||||
continue
|
||||
targetfn = path.join(self.outdir, 'rst', os_path(docname)) + '.html'
|
||||
ensuredir(path.dirname(targetfn))
|
||||
f = codecs.open(targetfn, 'w', 'utf-8')
|
||||
try:
|
||||
with codecs.open(targetfn, 'w', 'utf-8') as f:
|
||||
text = ''.join(hl(i+1, line) for (i, line) in enumerate(lines))
|
||||
ctx = {
|
||||
'filename': self.env.doc2path(docname, None),
|
||||
'text': text
|
||||
}
|
||||
f.write(self.templates.render('changes/rstsource.html', ctx))
|
||||
finally:
|
||||
f.close()
|
||||
themectx = dict(('theme_' + key, val) for (key, val) in
|
||||
iteritems(self.theme.get_options({})))
|
||||
copy_static_entry(path.join(package_dir, 'themes', 'default',
|
||||
'static', 'default.css_t'),
|
||||
self.outdir, self, themectx)
|
||||
copy_static_entry(path.join(package_dir, 'themes', 'basic',
|
||||
'static', 'basic.css'),
|
||||
self.outdir, self)
|
||||
copy_asset_file(path.join(package_dir, 'themes', 'default', 'static', 'default.css_t'),
|
||||
self.outdir, context=themectx, renderer=self.templates)
|
||||
copy_asset_file(path.join(package_dir, 'themes', 'basic', 'static', 'basic.css'),
|
||||
self.outdir)
|
||||
|
||||
def hl(self, text, version):
|
||||
text = htmlescape(text)
|
||||
@@ -165,3 +152,7 @@ class ChangesBuilder(Builder):
|
||||
|
||||
def finish(self):
|
||||
pass
|
||||
|
||||
|
||||
def setup(app):
|
||||
app.add_builder(ChangesBuilder)
|
||||
|
||||
@@ -13,32 +13,19 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
import re
|
||||
import gzip
|
||||
from os import path
|
||||
|
||||
from docutils import nodes
|
||||
|
||||
from sphinx import addnodes
|
||||
from sphinx.util.osutil import make_filename
|
||||
from sphinx.builders.html import StandaloneHTMLBuilder
|
||||
|
||||
try:
|
||||
import xml.etree.ElementTree as etree
|
||||
except ImportError:
|
||||
try:
|
||||
import lxml.etree as etree
|
||||
except ImportError:
|
||||
try:
|
||||
import elementtree.ElementTree as etree
|
||||
except ImportError:
|
||||
import cElementTree as etree
|
||||
|
||||
try:
|
||||
import gzip
|
||||
|
||||
def comp_open(filename, mode='rb'):
|
||||
return gzip.open(filename + '.gz', mode)
|
||||
except ImportError:
|
||||
def comp_open(filename, mode='rb'):
|
||||
return open(filename, mode)
|
||||
import lxml.etree as etree
|
||||
|
||||
|
||||
class DevhelpBuilder(StandaloneHTMLBuilder):
|
||||
@@ -59,6 +46,7 @@ class DevhelpBuilder(StandaloneHTMLBuilder):
|
||||
def init(self):
|
||||
StandaloneHTMLBuilder.init(self)
|
||||
self.out_suffix = '.html'
|
||||
self.link_suffix = '.html'
|
||||
|
||||
def handle_finish(self):
|
||||
self.build_devhelp(self.outdir, self.config.devhelp_basename)
|
||||
@@ -123,12 +111,17 @@ class DevhelpBuilder(StandaloneHTMLBuilder):
|
||||
subitem[1], [])
|
||||
|
||||
for (key, group) in index:
|
||||
for title, (refs, subitems) in group:
|
||||
for title, (refs, subitems, key) in group:
|
||||
write_index(title, refs, subitems)
|
||||
|
||||
# Dump the XML file
|
||||
f = comp_open(path.join(outdir, outname + '.devhelp'), 'w')
|
||||
try:
|
||||
xmlfile = path.join(outdir, outname + '.devhelp.gz')
|
||||
with gzip.open(xmlfile, 'w') as f:
|
||||
tree.write(f, 'utf-8')
|
||||
finally:
|
||||
f.close()
|
||||
|
||||
|
||||
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):
|
||||
pass
|
||||
|
||||
|
||||
def setup(app):
|
||||
app.add_builder(DummyBuilder)
|
||||
|
||||
@@ -15,6 +15,7 @@ import re
|
||||
import codecs
|
||||
import zipfile
|
||||
from os import path
|
||||
from datetime import datetime
|
||||
|
||||
try:
|
||||
from PIL import Image
|
||||
@@ -28,8 +29,7 @@ from docutils import nodes
|
||||
|
||||
from sphinx import addnodes
|
||||
from sphinx.builders.html import StandaloneHTMLBuilder
|
||||
from sphinx.util.i18n import format_date
|
||||
from sphinx.util.osutil import ensuredir, copyfile, EEXIST
|
||||
from sphinx.util.osutil import ensuredir, copyfile, make_filename, EEXIST
|
||||
from sphinx.util.smartypants import sphinx_smarty_pants as ssp
|
||||
from sphinx.util.console import brown
|
||||
|
||||
@@ -113,7 +113,7 @@ COVER_TEMPLATE = u'''\
|
||||
<meta name="cover" content="%(cover)s"/>
|
||||
'''
|
||||
|
||||
COVERPAGE_NAME = u'epub-cover.html'
|
||||
COVERPAGE_NAME = u'epub-cover.xhtml'
|
||||
|
||||
FILE_TEMPLATE = u'''\
|
||||
<item id="%(id)s"
|
||||
@@ -123,11 +123,17 @@ FILE_TEMPLATE = u'''\
|
||||
SPINE_TEMPLATE = u'''\
|
||||
<itemref idref="%(idref)s" />'''
|
||||
|
||||
NO_LINEAR_SPINE_TEMPLATE = u'''\
|
||||
<itemref idref="%(idref)s" linear="no" />'''
|
||||
|
||||
GUIDE_TEMPLATE = u'''\
|
||||
<reference type="%(type)s" title="%(title)s" href="%(uri)s" />'''
|
||||
|
||||
TOCTREE_TEMPLATE = u'toctree-l%d'
|
||||
|
||||
DOCTYPE = u'''<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
|
||||
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">'''
|
||||
|
||||
LINK_TARGET_TEMPLATE = u' [%(uri)s]'
|
||||
|
||||
FOOTNOTE_LABEL_TEMPLATE = u'#%d'
|
||||
@@ -143,7 +149,7 @@ GUIDE_TITLES = {
|
||||
}
|
||||
|
||||
MEDIA_TYPES = {
|
||||
'.html': 'application/xhtml+xml',
|
||||
'.xhtml': 'application/xhtml+xml',
|
||||
'.css': 'text/css',
|
||||
'.png': 'image/png',
|
||||
'.gif': 'image/gif',
|
||||
@@ -152,6 +158,7 @@ MEDIA_TYPES = {
|
||||
'.jpeg': 'image/jpeg',
|
||||
'.otf': 'application/x-font-otf',
|
||||
'.ttf': 'application/x-font-ttf',
|
||||
'.woff': 'application/font-woff',
|
||||
}
|
||||
|
||||
VECTOR_GRAPHICS_EXTENSIONS = ('.svg',)
|
||||
@@ -172,7 +179,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
||||
META-INF/container.xml. Afterwards, all necessary files are zipped to an
|
||||
epub file.
|
||||
"""
|
||||
name = 'epub'
|
||||
name = 'epub2'
|
||||
|
||||
# don't copy the reST source
|
||||
copysource = False
|
||||
@@ -181,8 +188,16 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
||||
|
||||
# don't add links
|
||||
add_permalinks = False
|
||||
# don't use # as current path. ePub check reject it.
|
||||
allow_sharp_as_current_path = False
|
||||
# don't add sidebar etc.
|
||||
embedded = True
|
||||
# disable download role
|
||||
download_support = False
|
||||
# dont' create links to original images from images
|
||||
html_scaled_image_link = False
|
||||
# don't generate search index or include search page
|
||||
search = False
|
||||
|
||||
mimetype_template = MIMETYPE_TEMPLATE
|
||||
container_template = CONTAINER_TEMPLATE
|
||||
@@ -195,8 +210,10 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
||||
coverpage_name = COVERPAGE_NAME
|
||||
file_template = FILE_TEMPLATE
|
||||
spine_template = SPINE_TEMPLATE
|
||||
no_linear_spine_template = NO_LINEAR_SPINE_TEMPLATE
|
||||
guide_template = GUIDE_TEMPLATE
|
||||
toctree_template = TOCTREE_TEMPLATE
|
||||
doctype = DOCTYPE
|
||||
link_target_template = LINK_TARGET_TEMPLATE
|
||||
css_link_target_class = CSS_LINK_TARGET_CLASS
|
||||
guide_titles = GUIDE_TITLES
|
||||
@@ -206,9 +223,11 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
||||
def init(self):
|
||||
StandaloneHTMLBuilder.init(self)
|
||||
# the output files for epub must be .html only
|
||||
self.out_suffix = '.html'
|
||||
self.out_suffix = '.xhtml'
|
||||
self.link_suffix = '.xhtml'
|
||||
self.playorder = 0
|
||||
self.tocid = 0
|
||||
self.use_index = self.get_builder_config('use_index', 'epub')
|
||||
|
||||
def get_theme_config(self):
|
||||
return self.config.epub_theme, self.config.epub_theme_options
|
||||
@@ -276,7 +295,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
||||
"""
|
||||
refnodes.insert(0, {
|
||||
'level': 1,
|
||||
'refuri': self.esc(self.config.master_doc + '.html'),
|
||||
'refuri': self.esc(self.config.master_doc + self.out_suffix),
|
||||
'text': ssp(self.esc(
|
||||
self.env.titles[self.config.master_doc].astext()))
|
||||
})
|
||||
@@ -471,6 +490,9 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
||||
else:
|
||||
super(EpubBuilder, self).copy_image_files()
|
||||
|
||||
def copy_download_files(self):
|
||||
pass
|
||||
|
||||
def handle_page(self, pagename, addctx, templatename='page.html',
|
||||
outfilename=None, event_arg=None):
|
||||
"""Create a rendered page.
|
||||
@@ -479,7 +501,10 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
||||
attributes.
|
||||
"""
|
||||
if pagename.startswith('genindex'):
|
||||
if not self.use_index:
|
||||
return
|
||||
self.fix_genindex(addctx['genindexentries'])
|
||||
addctx['doctype'] = self.doctype
|
||||
StandaloneHTMLBuilder.handle_page(self, pagename, addctx, templatename,
|
||||
outfilename, event_arg)
|
||||
|
||||
@@ -496,11 +521,8 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
||||
def build_mimetype(self, outdir, outname):
|
||||
"""Write the metainfo file mimetype."""
|
||||
self.info('writing %s file...' % outname)
|
||||
f = codecs.open(path.join(outdir, outname), 'w', 'utf-8')
|
||||
try:
|
||||
with codecs.open(path.join(outdir, outname), 'w', 'utf-8') as f:
|
||||
f.write(self.mimetype_template)
|
||||
finally:
|
||||
f.close()
|
||||
|
||||
def build_container(self, outdir, outname):
|
||||
"""Write the metainfo file META-INF/cointainer.xml."""
|
||||
@@ -511,11 +533,8 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
||||
except OSError as err:
|
||||
if err.errno != EEXIST:
|
||||
raise
|
||||
f = codecs.open(path.join(outdir, outname), 'w', 'utf-8')
|
||||
try:
|
||||
with codecs.open(path.join(outdir, outname), 'w', 'utf-8') as f:
|
||||
f.write(self.container_template)
|
||||
finally:
|
||||
f.close()
|
||||
|
||||
def content_metadata(self, files, spine, guide):
|
||||
"""Create a dictionary with all metadata for the content.opf
|
||||
@@ -530,7 +549,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
||||
metadata['copyright'] = self.esc(self.config.epub_copyright)
|
||||
metadata['scheme'] = self.esc(self.config.epub_scheme)
|
||||
metadata['id'] = self.esc(self.config.epub_identifier)
|
||||
metadata['date'] = self.esc(format_date('YYYY-MM-dd', language=self.config.language))
|
||||
metadata['date'] = self.esc(datetime.utcnow().strftime("%Y-%m-%d"))
|
||||
metadata['files'] = files
|
||||
metadata['spine'] = spine
|
||||
metadata['guide'] = guide
|
||||
@@ -550,8 +569,11 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
||||
self.files = []
|
||||
self.ignored_files = ['.buildinfo', 'mimetype', 'content.opf',
|
||||
'toc.ncx', 'META-INF/container.xml',
|
||||
'Thumbs.db', 'ehthumbs.db', '.DS_Store',
|
||||
self.config.epub_basename + '.epub'] + \
|
||||
self.config.epub_exclude_files
|
||||
if not self.use_index:
|
||||
self.ignored_files.append('genindex' + self.out_suffix)
|
||||
for root, dirs, files in os.walk(outdir):
|
||||
for fn in files:
|
||||
filename = path.join(root, fn)[olen:]
|
||||
@@ -574,6 +596,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
||||
|
||||
# spine
|
||||
spine = []
|
||||
spinefiles = set()
|
||||
for item in self.refnodes:
|
||||
if '#' in item['refuri']:
|
||||
continue
|
||||
@@ -582,14 +605,23 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
||||
spine.append(self.spine_template % {
|
||||
'idref': self.esc(self.make_id(item['refuri']))
|
||||
})
|
||||
spinefiles.add(item['refuri'])
|
||||
for info in self.domain_indices:
|
||||
spine.append(self.spine_template % {
|
||||
'idref': self.esc(self.make_id(info[0] + self.out_suffix))
|
||||
})
|
||||
if self.get_builder_config('use_index', 'epub'):
|
||||
spinefiles.add(info[0] + self.out_suffix)
|
||||
if self.use_index:
|
||||
spine.append(self.spine_template % {
|
||||
'idref': self.esc(self.make_id('genindex' + self.out_suffix))
|
||||
})
|
||||
spinefiles.add('genindex' + self.out_suffix)
|
||||
# add auto generated files
|
||||
for name in self.files:
|
||||
if name not in spinefiles and name.endswith(self.out_suffix):
|
||||
spine.append(self.no_linear_spine_template % {
|
||||
'idref': self.esc(self.make_id(name))
|
||||
})
|
||||
|
||||
# add the optional cover
|
||||
content_tmpl = self.content_template
|
||||
@@ -616,6 +648,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
||||
ctx = {'image': self.esc(image), 'title': self.config.project}
|
||||
self.handle_page(
|
||||
path.splitext(self.coverpage_name)[0], ctx, html_tmpl)
|
||||
spinefiles.add(self.coverpage_name)
|
||||
|
||||
guide = []
|
||||
auto_add_cover = True
|
||||
@@ -651,12 +684,9 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
||||
guide = '\n'.join(guide)
|
||||
|
||||
# write the project file
|
||||
f = codecs.open(path.join(outdir, outname), 'w', 'utf-8')
|
||||
try:
|
||||
with codecs.open(path.join(outdir, outname), 'w', 'utf-8') as f:
|
||||
f.write(content_tmpl %
|
||||
self.content_metadata(projectfiles, spine, guide))
|
||||
finally:
|
||||
f.close()
|
||||
|
||||
def new_navpoint(self, node, level, incr=True):
|
||||
"""Create a new entry in the toc from the node at given level."""
|
||||
@@ -748,11 +778,8 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
||||
navpoints = self.build_navpoints(refnodes)
|
||||
level = max(item['level'] for item in self.refnodes)
|
||||
level = min(level, self.config.epub_tocdepth)
|
||||
f = codecs.open(path.join(outdir, outname), 'w', 'utf-8')
|
||||
try:
|
||||
with codecs.open(path.join(outdir, outname), 'w', 'utf-8') as f:
|
||||
f.write(self.toc_template % self.toc_metadata(level, navpoints))
|
||||
finally:
|
||||
f.close()
|
||||
|
||||
def build_epub(self, outdir, outname):
|
||||
"""Write the epub file.
|
||||
@@ -771,3 +798,33 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
||||
fp = path.join(outdir, file)
|
||||
epub.write(fp, file, zipfile.ZIP_DEFLATED)
|
||||
epub.close()
|
||||
|
||||
|
||||
def setup(app):
|
||||
app.setup_extension('sphinx.builders.html')
|
||||
app.add_builder(EpubBuilder)
|
||||
|
||||
# config values
|
||||
app.add_config_value('epub_basename', lambda self: make_filename(self.project), None)
|
||||
app.add_config_value('epub_theme', 'epub', 'html')
|
||||
app.add_config_value('epub_theme_options', {}, 'html')
|
||||
app.add_config_value('epub_title', lambda self: self.html_title, 'html')
|
||||
app.add_config_value('epub_author', 'unknown', 'html')
|
||||
app.add_config_value('epub_language', lambda self: self.language or 'en', 'html')
|
||||
app.add_config_value('epub_publisher', 'unknown', 'html')
|
||||
app.add_config_value('epub_copyright', lambda self: self.copyright, 'html')
|
||||
app.add_config_value('epub_identifier', 'unknown', 'html')
|
||||
app.add_config_value('epub_scheme', 'unknown', 'html')
|
||||
app.add_config_value('epub_uid', 'unknown', 'env')
|
||||
app.add_config_value('epub_cover', (), 'env')
|
||||
app.add_config_value('epub_guide', (), 'env')
|
||||
app.add_config_value('epub_pre_files', [], 'env')
|
||||
app.add_config_value('epub_post_files', [], 'env')
|
||||
app.add_config_value('epub_exclude_files', [], 'env')
|
||||
app.add_config_value('epub_tocdepth', 3, 'env')
|
||||
app.add_config_value('epub_tocdup', True, 'env')
|
||||
app.add_config_value('epub_tocscope', 'default', 'env')
|
||||
app.add_config_value('epub_fix_images', False, 'env')
|
||||
app.add_config_value('epub_max_image_width', 0, 'env')
|
||||
app.add_config_value('epub_show_urls', 'inline', 'html')
|
||||
app.add_config_value('epub_use_index', lambda self: self.html_use_index, 'html')
|
||||
|
||||
@@ -12,7 +12,9 @@
|
||||
|
||||
import codecs
|
||||
from os import path
|
||||
from datetime import datetime
|
||||
|
||||
from sphinx.config import string_classes
|
||||
from sphinx.builders.epub import EpubBuilder
|
||||
|
||||
|
||||
@@ -41,18 +43,18 @@ NAVIGATION_DOC_TEMPLATE = u'''\
|
||||
</html>
|
||||
'''
|
||||
|
||||
NAVLIST_TEMPLATE = u'''\
|
||||
%(indent)s <li>
|
||||
%(indent)s <a href="%(refuri)s">%(text)s</a>
|
||||
%(indent)s </li>
|
||||
'''
|
||||
NAVLIST_INDENT = ' '
|
||||
|
||||
NAVLIST_TEMPLATE = u'''%(indent)s <li><a href="%(refuri)s">%(text)s</a></li>'''
|
||||
NAVLIST_TEMPLATE_HAS_CHILD = u'''%(indent)s <li><a href="%(refuri)s">%(text)s</a>'''
|
||||
NAVLIST_TEMPLATE_BEGIN_BLOCK = u'''%(indent)s <ol>'''
|
||||
NAVLIST_TEMPLATE_END_BLOCK = u'''%(indent)s </ol>
|
||||
%(indent)s </li>'''
|
||||
NAVLIST_INDENT = ' '
|
||||
|
||||
PACKAGE_DOC_TEMPLATE = u'''\
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<package xmlns="http://www.idpf.org/2007/opf" version="3.0" xml:lang="%(lang)s"
|
||||
unique-identifier="%(uid)s">
|
||||
unique-identifier="%(uid)s"
|
||||
prefix="ibooks: http://vocabulary.itunes.apple.com/rdf/ibooks/vocabulary-extensions-1.0/">
|
||||
<metadata xmlns:opf="http://www.idpf.org/2007/opf"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<dc:language>%(lang)s</dc:language>
|
||||
@@ -65,6 +67,10 @@ PACKAGE_DOC_TEMPLATE = u'''\
|
||||
<dc:identifier id="%(uid)s">%(id)s</dc:identifier>
|
||||
<dc:date>%(date)s</dc:date>
|
||||
<meta property="dcterms:modified">%(date)s</meta>
|
||||
<meta property="ibooks:version">%(version)s</meta>
|
||||
<meta property="ibooks:specified-fonts">true</meta>
|
||||
<meta property="ibooks:binding">true</meta>
|
||||
<meta property="ibooks:scroll-axis">%(ibook_scroll_axis)s</meta>
|
||||
</metadata>
|
||||
<manifest>
|
||||
<item id="ncx" href="toc.ncx" media-type="application/x-dtbncx+xml" />
|
||||
@@ -73,7 +79,6 @@ PACKAGE_DOC_TEMPLATE = u'''\
|
||||
%(files)s
|
||||
</manifest>
|
||||
<spine toc="ncx" page-progression-direction="%(page_progression_direction)s">
|
||||
<itemref idref="nav" />
|
||||
%(spine)s
|
||||
</spine>
|
||||
<guide>
|
||||
@@ -82,6 +87,8 @@ PACKAGE_DOC_TEMPLATE = u'''\
|
||||
</package>
|
||||
'''
|
||||
|
||||
DOCTYPE = u'''<!DOCTYPE html>'''
|
||||
|
||||
# The epub3 publisher
|
||||
|
||||
|
||||
@@ -93,12 +100,23 @@ class Epub3Builder(EpubBuilder):
|
||||
and META-INF/container.xml. Afterwards, all necessary files are zipped to
|
||||
an epub file.
|
||||
"""
|
||||
name = 'epub3'
|
||||
name = 'epub'
|
||||
|
||||
navigation_doc_template = NAVIGATION_DOC_TEMPLATE
|
||||
navlist_template = NAVLIST_TEMPLATE
|
||||
navlist_template_has_child = NAVLIST_TEMPLATE_HAS_CHILD
|
||||
navlist_template_begin_block = NAVLIST_TEMPLATE_BEGIN_BLOCK
|
||||
navlist_template_end_block = NAVLIST_TEMPLATE_END_BLOCK
|
||||
navlist_indent = NAVLIST_INDENT
|
||||
content_template = PACKAGE_DOC_TEMPLATE
|
||||
doctype = DOCTYPE
|
||||
|
||||
# Warning deprecated option
|
||||
def init(self):
|
||||
if self.config.epub3_page_progression_direction:
|
||||
self.warn('epub3_page_progression_direction option is deprecated'
|
||||
' from 1.5. Use epub3_writing_mode instead of this.')
|
||||
super(Epub3Builder, self).init()
|
||||
|
||||
# Finish by building the epub file
|
||||
def handle_finish(self):
|
||||
@@ -119,17 +137,58 @@ class Epub3Builder(EpubBuilder):
|
||||
files, spine, guide)
|
||||
metadata['description'] = self.esc(self.config.epub3_description)
|
||||
metadata['contributor'] = self.esc(self.config.epub3_contributor)
|
||||
metadata['page_progression_direction'] = self.esc(
|
||||
self.config.epub3_page_progression_direction) or 'default'
|
||||
metadata['page_progression_direction'] = self._page_progression_direction()
|
||||
metadata['ibook_scroll_axis'] = self._ibook_scroll_axis()
|
||||
metadata['date'] = self.esc(datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ"))
|
||||
metadata['version'] = self.esc(self.config.version)
|
||||
return metadata
|
||||
|
||||
def new_navlist(self, node, level):
|
||||
def _page_progression_direction(self):
|
||||
if self.config.epub3_writing_mode == 'horizontal':
|
||||
page_progression_direction = 'ltr'
|
||||
elif self.config.epub3_writing_mode == 'vertical':
|
||||
page_progression_direction = 'rtl'
|
||||
else:
|
||||
page_progression_direction = 'default'
|
||||
return page_progression_direction
|
||||
|
||||
def _ibook_scroll_axis(self):
|
||||
if self.config.epub3_writing_mode == 'horizontal':
|
||||
scroll_axis = 'vertical'
|
||||
elif self.config.epub3_writing_mode == 'vertical':
|
||||
scroll_axis = 'horizontal'
|
||||
else:
|
||||
scroll_axis = 'default'
|
||||
return scroll_axis
|
||||
|
||||
def _css_writing_mode(self):
|
||||
if self.config.epub3_writing_mode == 'vertical':
|
||||
editing_mode = 'vertical-rl'
|
||||
else:
|
||||
editing_mode = 'horizontal-tb'
|
||||
return editing_mode
|
||||
|
||||
def prepare_writing(self, docnames):
|
||||
super(Epub3Builder, self).prepare_writing(docnames)
|
||||
self.globalcontext['theme_writing_mode'] = self._css_writing_mode()
|
||||
|
||||
def new_navlist(self, node, level, has_child):
|
||||
"""Create a new entry in the toc from the node at given level."""
|
||||
# XXX Modifies the node
|
||||
self.tocid += 1
|
||||
node['indent'] = self.navlist_indent * level
|
||||
navpoint = self.navlist_template % node
|
||||
return navpoint
|
||||
if has_child:
|
||||
return self.navlist_template_has_child % node
|
||||
else:
|
||||
return self.navlist_template % node
|
||||
|
||||
def begin_navlist_block(self, level):
|
||||
return self.navlist_template_begin_block % {
|
||||
"indent": self.navlist_indent * level
|
||||
}
|
||||
|
||||
def end_navlist_block(self, level):
|
||||
return self.navlist_template_end_block % {"indent": self.navlist_indent * level}
|
||||
|
||||
def build_navlist(self, nodes):
|
||||
"""Create the toc navigation structure.
|
||||
@@ -141,10 +200,9 @@ class Epub3Builder(EpubBuilder):
|
||||
The difference from build_navpoints method is templates which are used
|
||||
when generating navigation documents.
|
||||
"""
|
||||
navstack = []
|
||||
navlist = []
|
||||
level = 1
|
||||
lastnode = None
|
||||
usenodes = []
|
||||
for node in nodes:
|
||||
if not node['text']:
|
||||
continue
|
||||
@@ -153,30 +211,23 @@ class Epub3Builder(EpubBuilder):
|
||||
continue
|
||||
if node['level'] > self.config.epub_tocdepth:
|
||||
continue
|
||||
if node['level'] == level:
|
||||
navlist.append(self.new_navlist(node, level))
|
||||
elif node['level'] == level + 1:
|
||||
navstack.append(navlist)
|
||||
navlist = []
|
||||
level += 1
|
||||
if lastnode and self.config.epub_tocdup:
|
||||
navlist.append(self.new_navlist(node, level))
|
||||
navlist[-1] = '<ol>\n' + navlist[-1]
|
||||
usenodes.append(node)
|
||||
for i, node in enumerate(usenodes):
|
||||
curlevel = node['level']
|
||||
if curlevel == level + 1:
|
||||
navlist.append(self.begin_navlist_block(level))
|
||||
while curlevel < level:
|
||||
level -= 1
|
||||
navlist.append(self.end_navlist_block(level))
|
||||
level = curlevel
|
||||
if i != len(usenodes) - 1 and usenodes[i + 1]['level'] > level:
|
||||
has_child = True
|
||||
else:
|
||||
while node['level'] < level:
|
||||
subnav = '\n'.join(navlist)
|
||||
navlist = navstack.pop()
|
||||
navlist[-1] = self.insert_subnav(navlist[-1], subnav)
|
||||
level -= 1
|
||||
navlist[-1] = navlist[-1] + '</ol>'
|
||||
navlist.append(self.new_navlist(node, level))
|
||||
lastnode = node
|
||||
has_child = False
|
||||
navlist.append(self.new_navlist(node, level, has_child))
|
||||
while level != 1:
|
||||
subnav = '\n'.join(navlist)
|
||||
navlist = navstack.pop()
|
||||
navlist[-1] = self.insert_subnav(navlist[-1], subnav)
|
||||
level -= 1
|
||||
navlist[-1] = navlist[-1] + '</ol>'
|
||||
navlist.append(self.end_navlist_block(level))
|
||||
return '\n'.join(navlist)
|
||||
|
||||
def navigation_doc_metadata(self, navlist):
|
||||
@@ -203,11 +254,20 @@ class Epub3Builder(EpubBuilder):
|
||||
# 'includehidden'
|
||||
refnodes = self.refnodes
|
||||
navlist = self.build_navlist(refnodes)
|
||||
f = codecs.open(path.join(outdir, outname), 'w', 'utf-8')
|
||||
try:
|
||||
with codecs.open(path.join(outdir, outname), 'w', 'utf-8') as f:
|
||||
f.write(self.navigation_doc_template %
|
||||
self.navigation_doc_metadata(navlist))
|
||||
finally:
|
||||
f.close()
|
||||
# Add nav.xhtml to epub file
|
||||
|
||||
# Add nav.xhtml to epub file
|
||||
if outname not in self.files:
|
||||
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_writing_mode', 'horizontal', 'epub3', string_classes)
|
||||
app.add_config_value('epub3_page_progression_direction', '', 'epub3', string_classes)
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from os import path, walk
|
||||
from os import path, walk, getenv
|
||||
from codecs import open
|
||||
from time import time
|
||||
from datetime import datetime, tzinfo, timedelta
|
||||
@@ -22,6 +22,7 @@ from six import iteritems
|
||||
|
||||
from sphinx.builders import Builder
|
||||
from sphinx.util import split_index_msg
|
||||
from sphinx.util.tags import Tags
|
||||
from sphinx.util.nodes import extract_messages, traverse_translatable_index
|
||||
from sphinx.util.osutil import safe_relpath, ensuredir, canon_path
|
||||
from sphinx.util.i18n import find_catalog
|
||||
@@ -79,6 +80,16 @@ class MsgOrigin(object):
|
||||
self.uid = uuid4().hex
|
||||
|
||||
|
||||
class I18nTags(Tags):
|
||||
"""Dummy tags module for I18nBuilder.
|
||||
|
||||
To translate all text inside of only nodes, this class
|
||||
always returns True value even if no tags are defined.
|
||||
"""
|
||||
def eval_condition(self, condition):
|
||||
return True
|
||||
|
||||
|
||||
class I18nBuilder(Builder):
|
||||
"""
|
||||
General i18n builder.
|
||||
@@ -93,6 +104,7 @@ class I18nBuilder(Builder):
|
||||
|
||||
def init(self):
|
||||
Builder.init(self)
|
||||
self.tags = I18nTags()
|
||||
self.catalogs = defaultdict(Catalog)
|
||||
|
||||
def get_target_uri(self, docname, typ=None):
|
||||
@@ -130,6 +142,12 @@ class I18nBuilder(Builder):
|
||||
timestamp = time()
|
||||
tzdelta = datetime.fromtimestamp(timestamp) - \
|
||||
datetime.utcfromtimestamp(timestamp)
|
||||
# set timestamp from SOURCE_DATE_EPOCH if set
|
||||
# see https://reproducible-builds.org/specs/source-date-epoch/
|
||||
source_date_epoch = getenv('SOURCE_DATE_EPOCH')
|
||||
if source_date_epoch is not None:
|
||||
timestamp = float(source_date_epoch)
|
||||
tzdelta = timedelta(0)
|
||||
|
||||
|
||||
class LocalTimeZone(tzinfo):
|
||||
@@ -205,8 +223,7 @@ class MessageCatalogBuilder(I18nBuilder):
|
||||
ensuredir(path.join(self.outdir, path.dirname(textdomain)))
|
||||
|
||||
pofn = path.join(self.outdir, textdomain + '.pot')
|
||||
pofile = open(pofn, 'w', encoding='utf-8')
|
||||
try:
|
||||
with open(pofn, 'w', encoding='utf-8') as pofile:
|
||||
pofile.write(POHEADER % data)
|
||||
|
||||
for message in catalog.messages:
|
||||
@@ -229,5 +246,12 @@ class MessageCatalogBuilder(I18nBuilder):
|
||||
replace('\n', '\\n"\n"')
|
||||
pofile.write('msgid "%s"\nmsgstr ""\n\n' % message)
|
||||
|
||||
finally:
|
||||
pofile.close()
|
||||
|
||||
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 sphinx import package_dir, __display_version__
|
||||
from sphinx.util import jsonimpl, copy_static_entry, copy_extra_entry
|
||||
from sphinx.util import jsonimpl
|
||||
from sphinx.util.i18n import format_date
|
||||
from sphinx.util.osutil import SEP, os_path, relative_uri, ensuredir, \
|
||||
movefile, copyfile
|
||||
from sphinx.util.nodes import inline_all_toctrees
|
||||
from sphinx.util.matching import patmatch, compile_matchers
|
||||
from sphinx.locale import _
|
||||
from sphinx.util.fileutil import copy_asset
|
||||
from sphinx.util.matching import patmatch, Matcher, DOTFILES
|
||||
from sphinx.config import string_classes
|
||||
from sphinx.locale import _, l_
|
||||
from sphinx.search import js_index
|
||||
from sphinx.theming import Theme
|
||||
from sphinx.builders import Builder
|
||||
@@ -74,12 +76,16 @@ class StandaloneHTMLBuilder(Builder):
|
||||
link_suffix = '.html' # defaults to matching out_suffix
|
||||
indexer_format = js_index
|
||||
indexer_dumps_unicode = True
|
||||
# create links to original images from images [True/False]
|
||||
html_scaled_image_link = True
|
||||
supported_image_types = ['image/svg+xml', 'image/png',
|
||||
'image/gif', 'image/jpeg']
|
||||
searchindex_filename = 'searchindex.js'
|
||||
add_permalinks = True
|
||||
allow_sharp_as_current_path = True
|
||||
embedded = False # for things like HTML help or Qt help: suppresses sidebar
|
||||
search = True # for things like HTML help and Apple help: suppress search
|
||||
download_support = True # enable download role
|
||||
|
||||
# This is a class attribute because it is mutated by Sphinx.add_javascript.
|
||||
script_files = ['_static/jquery.js', '_static/underscore.js',
|
||||
@@ -119,6 +125,7 @@ class StandaloneHTMLBuilder(Builder):
|
||||
if self.config.language is not None:
|
||||
if self._get_translations_js():
|
||||
self.script_files.append('_static/translations.js')
|
||||
self.use_index = self.get_builder_config('use_index', 'html')
|
||||
|
||||
def _get_translations_js(self):
|
||||
candidates = [path.join(package_dir, 'locale', self.config.language,
|
||||
@@ -157,16 +164,11 @@ class StandaloneHTMLBuilder(Builder):
|
||||
self.config.trim_doctest_flags)
|
||||
|
||||
def init_translator_class(self):
|
||||
if self.translator_class is not None:
|
||||
pass
|
||||
elif self.config.html_translator_class:
|
||||
self.translator_class = self.app.import_object(
|
||||
self.config.html_translator_class,
|
||||
'html_translator_class setting')
|
||||
elif self.config.html_use_smartypants:
|
||||
self.translator_class = SmartyPantsHTMLTranslator
|
||||
else:
|
||||
self.translator_class = HTMLTranslator
|
||||
if self.translator_class is None:
|
||||
if self.config.html_use_smartypants:
|
||||
self.translator_class = SmartyPantsHTMLTranslator
|
||||
else:
|
||||
self.translator_class = HTMLTranslator
|
||||
|
||||
def get_outdated_docs(self):
|
||||
cfgdict = dict((name, self.config[name])
|
||||
@@ -176,8 +178,7 @@ class StandaloneHTMLBuilder(Builder):
|
||||
self.tags_hash = get_stable_hash(sorted(self.tags))
|
||||
old_config_hash = old_tags_hash = ''
|
||||
try:
|
||||
fp = open(path.join(self.outdir, '.buildinfo'))
|
||||
try:
|
||||
with open(path.join(self.outdir, '.buildinfo')) as fp:
|
||||
version = fp.readline()
|
||||
if version.rstrip() != '# Sphinx build info version 1':
|
||||
raise ValueError
|
||||
@@ -188,8 +189,6 @@ class StandaloneHTMLBuilder(Builder):
|
||||
tag, old_tags_hash = fp.readline().strip().split(': ')
|
||||
if tag != 'tags':
|
||||
raise ValueError
|
||||
finally:
|
||||
fp.close()
|
||||
except ValueError:
|
||||
self.warn('unsupported build info format in %r, building all' %
|
||||
path.join(self.outdir, '.buildinfo'))
|
||||
@@ -293,8 +292,9 @@ class StandaloneHTMLBuilder(Builder):
|
||||
# typically doesn't include the time of day
|
||||
lufmt = self.config.html_last_updated_fmt
|
||||
if lufmt is not None:
|
||||
self.last_updated = format_date(lufmt or _('MMM dd, YYYY'),
|
||||
language=self.config.language)
|
||||
self.last_updated = format_date(lufmt or _('%b %d, %Y'),
|
||||
language=self.config.language,
|
||||
warn=self.warn)
|
||||
else:
|
||||
self.last_updated = None
|
||||
|
||||
@@ -312,7 +312,7 @@ class StandaloneHTMLBuilder(Builder):
|
||||
self.relations = self.env.collect_relations()
|
||||
|
||||
rellinks = []
|
||||
if self.get_builder_config('use_index', 'html'):
|
||||
if self.use_index:
|
||||
rellinks.append(('genindex', _('General Index'), 'I', _('index')))
|
||||
for indexname, indexcls, content, collapse in self.domain_indices:
|
||||
# if it has a short name
|
||||
@@ -342,6 +342,7 @@ class StandaloneHTMLBuilder(Builder):
|
||||
show_sphinx = self.config.html_show_sphinx,
|
||||
has_source = self.config.html_copy_source,
|
||||
show_source = self.config.html_show_sourcelink,
|
||||
sourcelink_suffix = self.config.html_sourcelink_suffix,
|
||||
file_suffix = self.out_suffix,
|
||||
script_files = self.script_files,
|
||||
language = self.config.language,
|
||||
@@ -406,15 +407,21 @@ class StandaloneHTMLBuilder(Builder):
|
||||
# title rendered as HTML
|
||||
title = self.env.longtitles.get(docname)
|
||||
title = title and self.render_partial(title)['title'] or ''
|
||||
|
||||
# Suffix for the document
|
||||
source_suffix = path.splitext(self.env.doc2path(docname))[1]
|
||||
|
||||
# the name for the copied source
|
||||
sourcename = self.config.html_copy_source and docname + '.txt' or ''
|
||||
if self.config.html_copy_source:
|
||||
sourcename = docname + source_suffix
|
||||
if source_suffix != self.config.html_sourcelink_suffix:
|
||||
sourcename += self.config.html_sourcelink_suffix
|
||||
else:
|
||||
sourcename = ''
|
||||
|
||||
# metadata for the document
|
||||
meta = self.env.metadata.get(docname)
|
||||
|
||||
# Suffix for the document
|
||||
source_suffix = '.' + self.env.doc2path(docname).split('.')[-1]
|
||||
|
||||
# local TOC and global TOC tree
|
||||
self_toc = self.env.get_toc_for(docname, self)
|
||||
toc = self.render_partial(self_toc)['fragment']
|
||||
@@ -475,7 +482,7 @@ class StandaloneHTMLBuilder(Builder):
|
||||
self.info(bold('generating indices...'), nonl=1)
|
||||
|
||||
# the global general index
|
||||
if self.get_builder_config('use_index', 'html'):
|
||||
if self.use_index:
|
||||
self.write_genindex()
|
||||
|
||||
# the global domain-specific indices
|
||||
@@ -585,9 +592,8 @@ class StandaloneHTMLBuilder(Builder):
|
||||
self.info(bold('copying static files... '), nonl=True)
|
||||
ensuredir(path.join(self.outdir, '_static'))
|
||||
# first, create pygments style file
|
||||
f = open(path.join(self.outdir, '_static', 'pygments.css'), 'w')
|
||||
f.write(self.highlighter.get_stylesheet())
|
||||
f.close()
|
||||
with open(path.join(self.outdir, '_static', 'pygments.css'), 'w') as f:
|
||||
f.write(self.highlighter.get_stylesheet())
|
||||
# then, copy translations JavaScript file
|
||||
if self.config.language is not None:
|
||||
jsfile = self._get_translations_js()
|
||||
@@ -609,21 +615,19 @@ class StandaloneHTMLBuilder(Builder):
|
||||
|
||||
# then, copy over theme-supplied static files
|
||||
if self.theme:
|
||||
themeentries = [path.join(themepath, 'static')
|
||||
for themepath in self.theme.get_dirchain()[::-1]]
|
||||
for entry in themeentries:
|
||||
copy_static_entry(entry, path.join(self.outdir, '_static'),
|
||||
self, ctx)
|
||||
for theme_path in self.theme.get_dirchain()[::-1]:
|
||||
entry = path.join(theme_path, 'static')
|
||||
copy_asset(entry, path.join(self.outdir, '_static'), excluded=DOTFILES,
|
||||
context=ctx, renderer=self.templates)
|
||||
# then, copy over all user-supplied static files
|
||||
staticentries = [path.join(self.confdir, spath)
|
||||
for spath in self.config.html_static_path]
|
||||
matchers = compile_matchers(self.config.exclude_patterns)
|
||||
for entry in staticentries:
|
||||
excluded = Matcher(self.config.exclude_patterns + ["**/.*"])
|
||||
for static_path in self.config.html_static_path:
|
||||
entry = path.join(self.confdir, static_path)
|
||||
if not path.exists(entry):
|
||||
self.warn('html_static_path entry %r does not exist' % entry)
|
||||
continue
|
||||
copy_static_entry(entry, path.join(self.outdir, '_static'), self,
|
||||
ctx, exclude_matchers=matchers)
|
||||
copy_asset(entry, path.join(self.outdir, '_static'), excluded,
|
||||
context=ctx, renderer=self.templates)
|
||||
# copy logo and favicon files if not already in static path
|
||||
if self.config.html_logo:
|
||||
logobase = path.basename(self.config.html_logo)
|
||||
@@ -646,27 +650,25 @@ class StandaloneHTMLBuilder(Builder):
|
||||
def copy_extra_files(self):
|
||||
# copy html_extra_path files
|
||||
self.info(bold('copying extra files... '), nonl=True)
|
||||
extraentries = [path.join(self.confdir, epath)
|
||||
for epath in self.config.html_extra_path]
|
||||
matchers = compile_matchers(self.config.exclude_patterns)
|
||||
for entry in extraentries:
|
||||
excluded = Matcher(self.config.exclude_patterns)
|
||||
|
||||
for extra_path in self.config.html_extra_path:
|
||||
entry = path.join(self.confdir, extra_path)
|
||||
if not path.exists(entry):
|
||||
self.warn('html_extra_path entry %r does not exist' % entry)
|
||||
continue
|
||||
copy_extra_entry(entry, self.outdir, matchers)
|
||||
|
||||
copy_asset(entry, self.outdir, excluded)
|
||||
self.info('done')
|
||||
|
||||
def write_buildinfo(self):
|
||||
# write build info file
|
||||
fp = open(path.join(self.outdir, '.buildinfo'), 'w')
|
||||
try:
|
||||
with open(path.join(self.outdir, '.buildinfo'), 'w') as fp:
|
||||
fp.write('# Sphinx build info version 1\n'
|
||||
'# This file hashes the configuration used when building'
|
||||
' these files. When it is not found, a full rebuild will'
|
||||
' be done.\nconfig: %s\ntags: %s\n' %
|
||||
(self.config_hash, self.tags_hash))
|
||||
finally:
|
||||
fp.close()
|
||||
|
||||
def cleanup(self):
|
||||
# clean up theme stuff
|
||||
@@ -679,7 +681,7 @@ class StandaloneHTMLBuilder(Builder):
|
||||
"""
|
||||
Builder.post_process_images(self, doctree)
|
||||
|
||||
if self.config.html_scaled_image_link:
|
||||
if self.config.html_scaled_image_link and self.html_scaled_image_link:
|
||||
for node in doctree.traverse(nodes.image):
|
||||
scale_keys = ('scale', 'width', 'height')
|
||||
if not any((key in node) for key in scale_keys) or \
|
||||
@@ -706,10 +708,8 @@ class StandaloneHTMLBuilder(Builder):
|
||||
f = codecs.open(searchindexfn, 'r', encoding='utf-8')
|
||||
else:
|
||||
f = open(searchindexfn, 'rb')
|
||||
try:
|
||||
with f:
|
||||
self.indexer.load(f, self.indexer_format)
|
||||
finally:
|
||||
f.close()
|
||||
except (IOError, OSError, ValueError):
|
||||
if keep:
|
||||
self.warn('search index couldn\'t be loaded, but not all '
|
||||
@@ -721,7 +721,12 @@ class StandaloneHTMLBuilder(Builder):
|
||||
def index_page(self, pagename, doctree, title):
|
||||
# only index pages with title
|
||||
if self.indexer is not None and title:
|
||||
self.indexer.feed(pagename, title, doctree)
|
||||
filename = self.env.doc2path(pagename, base=None)
|
||||
try:
|
||||
self.indexer.feed(pagename, filename, title, doctree)
|
||||
except TypeError:
|
||||
# fallback for old search-adapters
|
||||
self.indexer.feed(pagename, title, doctree)
|
||||
|
||||
def _get_local_toctree(self, docname, collapse=True, **kwds):
|
||||
if 'includehidden' not in kwds:
|
||||
@@ -784,9 +789,21 @@ class StandaloneHTMLBuilder(Builder):
|
||||
elif not resource:
|
||||
otheruri = self.get_target_uri(otheruri)
|
||||
uri = relative_uri(baseuri, otheruri) or '#'
|
||||
if uri == '#' and not self.allow_sharp_as_current_path:
|
||||
uri = baseuri
|
||||
return uri
|
||||
ctx['pathto'] = pathto
|
||||
ctx['hasdoc'] = lambda name: name in self.env.all_docs
|
||||
|
||||
def hasdoc(name):
|
||||
if name in self.env.all_docs:
|
||||
return True
|
||||
elif name == 'search' and self.search:
|
||||
return True
|
||||
elif name == 'genindex' and self.get_builder_config('use_index', 'html'):
|
||||
return True
|
||||
return False
|
||||
ctx['hasdoc'] = hasdoc
|
||||
|
||||
if self.name != 'htmlhelp':
|
||||
ctx['encoding'] = encoding = self.config.html_output_encoding
|
||||
else:
|
||||
@@ -813,11 +830,8 @@ class StandaloneHTMLBuilder(Builder):
|
||||
# outfilename's path is in general different from self.outdir
|
||||
ensuredir(path.dirname(outfilename))
|
||||
try:
|
||||
f = codecs.open(outfilename, 'w', encoding, 'xmlcharrefreplace')
|
||||
try:
|
||||
with codecs.open(outfilename, 'w', encoding, 'xmlcharrefreplace') as f:
|
||||
f.write(output)
|
||||
finally:
|
||||
f.close()
|
||||
except (IOError, OSError) as err:
|
||||
self.warn("error writing file %s: %s" % (outfilename, err))
|
||||
if self.copysource and ctx.get('sourcename'):
|
||||
@@ -834,8 +848,7 @@ class StandaloneHTMLBuilder(Builder):
|
||||
|
||||
def dump_inventory(self):
|
||||
self.info(bold('dumping object inventory... '), nonl=True)
|
||||
f = open(path.join(self.outdir, INVENTORY_FILENAME), 'wb')
|
||||
try:
|
||||
with open(path.join(self.outdir, INVENTORY_FILENAME), 'wb') as f:
|
||||
f.write((u'# Sphinx inventory version 2\n'
|
||||
u'# Project: %s\n'
|
||||
u'# Version: %s\n'
|
||||
@@ -857,8 +870,6 @@ class StandaloneHTMLBuilder(Builder):
|
||||
(u'%s %s:%s %s %s %s\n' % (name, domainname, type,
|
||||
prio, uri, dispname)).encode('utf-8')))
|
||||
f.write(compressor.flush())
|
||||
finally:
|
||||
f.close()
|
||||
self.info('done')
|
||||
|
||||
def dump_search_index(self):
|
||||
@@ -873,10 +884,8 @@ class StandaloneHTMLBuilder(Builder):
|
||||
f = codecs.open(searchindexfn + '.tmp', 'w', encoding='utf-8')
|
||||
else:
|
||||
f = open(searchindexfn + '.tmp', 'wb')
|
||||
try:
|
||||
with f:
|
||||
self.indexer.dump(f, self.indexer_format)
|
||||
finally:
|
||||
f.close()
|
||||
movefile(searchindexfn + '.tmp', searchindexfn)
|
||||
self.info('done')
|
||||
|
||||
@@ -982,6 +991,26 @@ class SingleFileHTMLBuilder(StandaloneHTMLBuilder):
|
||||
|
||||
return {self.config.master_doc: new_secnumbers}
|
||||
|
||||
def assemble_toc_fignumbers(self):
|
||||
# Assemble toc_fignumbers to resolve figure numbers on SingleHTML.
|
||||
# Merge all fignumbers to single fignumber.
|
||||
#
|
||||
# Note: current Sphinx has refid confliction in singlehtml mode.
|
||||
# To avoid the problem, it replaces key of secnumbers to
|
||||
# tuple of docname and refid.
|
||||
#
|
||||
# There are related codes in inline_all_toctres() and
|
||||
# HTMLTranslter#add_fignumber().
|
||||
new_fignumbers = {}
|
||||
# {u'foo': {'figure': {'id2': (2,), 'id1': (1,)}}, u'bar': {'figure': {'id1': (3,)}}}
|
||||
for docname, fignumlist in iteritems(self.env.toc_fignumbers):
|
||||
for figtype, fignums in iteritems(fignumlist):
|
||||
new_fignumbers.setdefault((docname, figtype), {})
|
||||
for id, fignum in iteritems(fignums):
|
||||
new_fignumbers[(docname, figtype)][id] = fignum
|
||||
|
||||
return {self.config.master_doc: new_fignumbers}
|
||||
|
||||
def get_doc_context(self, docname, body, metatags):
|
||||
# no relation links...
|
||||
toc = self.env.get_toctree_for(self.config.master_doc, self, False)
|
||||
@@ -1018,6 +1047,7 @@ class SingleFileHTMLBuilder(StandaloneHTMLBuilder):
|
||||
self.info(bold('assembling single document... '), nonl=True)
|
||||
doctree = self.assemble_doctree()
|
||||
self.env.toc_secnumbers = self.assemble_toc_secnumbers()
|
||||
self.env.toc_fignumbers = self.assemble_toc_fignumbers()
|
||||
self.info()
|
||||
self.info(bold('writing... '), nonl=True)
|
||||
self.write_doc_serialized(self.config.master_doc, doctree)
|
||||
@@ -1070,10 +1100,13 @@ class SerializingHTMLBuilder(StandaloneHTMLBuilder):
|
||||
self.config_hash = ''
|
||||
self.tags_hash = ''
|
||||
self.imagedir = '_images'
|
||||
self.current_docname = None
|
||||
self.theme = None # no theme necessary
|
||||
self.templates = None # no template bridge necessary
|
||||
self.init_translator_class()
|
||||
self.init_templates()
|
||||
self.init_highlighter()
|
||||
self.use_index = self.get_builder_config('use_index', 'html')
|
||||
|
||||
def get_target_uri(self, docname, typ=None):
|
||||
if docname == 'index':
|
||||
@@ -1087,10 +1120,8 @@ class SerializingHTMLBuilder(StandaloneHTMLBuilder):
|
||||
f = codecs.open(filename, 'w', encoding='utf-8')
|
||||
else:
|
||||
f = open(filename, 'wb')
|
||||
try:
|
||||
with f:
|
||||
self.implementation.dump(context, f, *self.additional_dump_args)
|
||||
finally:
|
||||
f.close()
|
||||
|
||||
def handle_page(self, pagename, ctx, templatename='page.html',
|
||||
outfilename=None, event_arg=None):
|
||||
@@ -1167,3 +1198,59 @@ class JSONHTMLBuilder(SerializingHTMLBuilder):
|
||||
|
||||
def init(self):
|
||||
SerializingHTMLBuilder.init(self)
|
||||
|
||||
|
||||
def validate_config_values(app):
|
||||
if app.config.html_translator_class:
|
||||
app.warn('html_translator_class is deprecated. '
|
||||
'Use Sphinx.set_translator() API instead.')
|
||||
|
||||
|
||||
def setup(app):
|
||||
# builders
|
||||
app.add_builder(StandaloneHTMLBuilder)
|
||||
app.add_builder(DirectoryHTMLBuilder)
|
||||
app.add_builder(SingleFileHTMLBuilder)
|
||||
app.add_builder(PickleHTMLBuilder)
|
||||
app.add_builder(JSONHTMLBuilder)
|
||||
|
||||
app.connect('builder-inited', validate_config_values)
|
||||
|
||||
# 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_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 sphinx import addnodes
|
||||
from sphinx.util.osutil import make_filename
|
||||
from sphinx.builders.html import StandaloneHTMLBuilder
|
||||
from sphinx.util.pycompat import htmlescape
|
||||
|
||||
@@ -63,7 +64,7 @@ Binary Index=No
|
||||
Compiled file=%(outname)s.chm
|
||||
Contents file=%(outname)s.hhc
|
||||
Default Window=%(outname)s
|
||||
Default topic=index.html
|
||||
Default topic=%(master_doc)s
|
||||
Display compile progress=No
|
||||
Full text search stop list file=%(outname)s.stp
|
||||
Full-text search=Yes
|
||||
@@ -73,7 +74,7 @@ Title=%(title)s
|
||||
|
||||
[WINDOWS]
|
||||
%(outname)s="%(title)s","%(outname)s.hhc","%(outname)s.hhk",\
|
||||
"index.html","index.html",,,,,0x63520,220,0x10384e,[0,0,1024,768],,,,,,,0
|
||||
"%(master_doc)s","%(master_doc)s",,,,,0x63520,220,0x10384e,[0,0,1024,768],,,,,,,0
|
||||
|
||||
[FILES]
|
||||
'''
|
||||
@@ -183,6 +184,7 @@ class HTMLHelpBuilder(StandaloneHTMLBuilder):
|
||||
StandaloneHTMLBuilder.init(self)
|
||||
# the output files for HTML help must be .html only
|
||||
self.out_suffix = '.html'
|
||||
self.link_suffix = '.html'
|
||||
# determine the correct locale setting
|
||||
locale = chm_locales.get(self.config.language)
|
||||
if locale is not None:
|
||||
@@ -196,23 +198,30 @@ class HTMLHelpBuilder(StandaloneHTMLBuilder):
|
||||
def handle_finish(self):
|
||||
self.build_hhx(self.outdir, self.config.htmlhelp_basename)
|
||||
|
||||
def write_doc(self, docname, doctree):
|
||||
for node in doctree.traverse(nodes.reference):
|
||||
# add ``target=_blank`` attributes to external links
|
||||
if node.get('internal') is None and 'refuri' in node:
|
||||
node['target'] = '_blank'
|
||||
|
||||
StandaloneHTMLBuilder.write_doc(self, docname, doctree)
|
||||
|
||||
def build_hhx(self, outdir, outname):
|
||||
self.info('dumping stopword list...')
|
||||
f = self.open_file(outdir, outname+'.stp')
|
||||
try:
|
||||
with self.open_file(outdir, outname+'.stp') as f:
|
||||
for word in sorted(stopwords):
|
||||
print(word, file=f)
|
||||
finally:
|
||||
f.close()
|
||||
|
||||
self.info('writing project file...')
|
||||
f = self.open_file(outdir, outname+'.hhp')
|
||||
try:
|
||||
f.write(project_template % {'outname': outname,
|
||||
'title': self.config.html_title,
|
||||
'version': self.config.version,
|
||||
'project': self.config.project,
|
||||
'lcid': self.lcid})
|
||||
with self.open_file(outdir, outname+'.hhp') as f:
|
||||
f.write(project_template % {
|
||||
'outname': outname,
|
||||
'title': self.config.html_title,
|
||||
'version': self.config.version,
|
||||
'project': self.config.project,
|
||||
'lcid': self.lcid,
|
||||
'master_doc': self.config.master_doc + self.out_suffix
|
||||
})
|
||||
if not outdir.endswith(os.sep):
|
||||
outdir += os.sep
|
||||
olen = len(outdir)
|
||||
@@ -223,16 +232,13 @@ class HTMLHelpBuilder(StandaloneHTMLBuilder):
|
||||
fn.endswith('.html'):
|
||||
print(path.join(root, fn)[olen:].replace(os.sep, '\\'),
|
||||
file=f)
|
||||
finally:
|
||||
f.close()
|
||||
|
||||
self.info('writing TOC file...')
|
||||
f = self.open_file(outdir, outname+'.hhc')
|
||||
try:
|
||||
with self.open_file(outdir, outname+'.hhc') as f:
|
||||
f.write(contents_header)
|
||||
# special books
|
||||
f.write('<LI> ' + object_sitemap % (self.config.html_short_title,
|
||||
'index.html'))
|
||||
self.config.master_doc + self.out_suffix))
|
||||
for indexname, indexcls, content, collapse in self.domain_indices:
|
||||
f.write('<LI> ' + object_sitemap % (indexcls.localname,
|
||||
'%s.html' % indexname))
|
||||
@@ -266,13 +272,10 @@ class HTMLHelpBuilder(StandaloneHTMLBuilder):
|
||||
for node in tocdoc.traverse(istoctree):
|
||||
write_toc(node)
|
||||
f.write(contents_footer)
|
||||
finally:
|
||||
f.close()
|
||||
|
||||
self.info('writing index file...')
|
||||
index = self.env.create_index(self)
|
||||
f = self.open_file(outdir, outname+'.hhk')
|
||||
try:
|
||||
with self.open_file(outdir, outname+'.hhk') as f:
|
||||
f.write('<UL>\n')
|
||||
|
||||
def write_index(title, refs, subitems):
|
||||
@@ -302,5 +305,10 @@ class HTMLHelpBuilder(StandaloneHTMLBuilder):
|
||||
for title, (refs, subitems, key_) in group:
|
||||
write_index(title, refs, subitems)
|
||||
f.write('</UL>\n')
|
||||
finally:
|
||||
f.close()
|
||||
|
||||
|
||||
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
|
||||
from os import path
|
||||
import warnings
|
||||
|
||||
from six import iteritems
|
||||
from docutils import nodes
|
||||
@@ -19,14 +18,16 @@ from docutils.io import FileOutput
|
||||
from docutils.utils import new_document
|
||||
from docutils.frontend import OptionParser
|
||||
|
||||
from sphinx import package_dir, addnodes
|
||||
from sphinx import package_dir, addnodes, highlighting
|
||||
from sphinx.util import texescape
|
||||
from sphinx.config import string_classes, ENUM
|
||||
from sphinx.errors import SphinxError
|
||||
from sphinx.locale import _
|
||||
from sphinx.builders import Builder
|
||||
from sphinx.environment import NoUri
|
||||
from sphinx.util.nodes import inline_all_toctrees
|
||||
from sphinx.util.osutil import SEP, copyfile
|
||||
from sphinx.util.fileutil import copy_asset_file
|
||||
from sphinx.util.osutil import SEP, make_filename
|
||||
from sphinx.util.console import bold, darkgreen
|
||||
from sphinx.writers.latex import LaTeXWriter
|
||||
|
||||
@@ -38,27 +39,12 @@ class LaTeXBuilder(Builder):
|
||||
name = 'latex'
|
||||
format = 'latex'
|
||||
supported_image_types = ['application/pdf', 'image/png', 'image/jpeg']
|
||||
usepackages = []
|
||||
|
||||
def init(self):
|
||||
self.docnames = []
|
||||
self.document_data = []
|
||||
self.usepackages = []
|
||||
texescape.init()
|
||||
self.check_options()
|
||||
|
||||
def check_options(self):
|
||||
if self.config.latex_toplevel_sectioning not in (None, 'part', 'chapter', 'section'):
|
||||
self.warn('invalid latex_toplevel_sectioning, ignored: %s' %
|
||||
self.config.latex_top_sectionlevel)
|
||||
self.config.latex_top_sectionlevel = None
|
||||
|
||||
if self.config.latex_use_parts:
|
||||
warnings.warn('latex_use_parts will be removed at Sphinx-1.5. '
|
||||
'Use latex_toplevel_sectioning instead.',
|
||||
DeprecationWarning)
|
||||
|
||||
if self.config.latex_toplevel_sectioning:
|
||||
self.warn('latex_use_parts conflicts with latex_toplevel_sectioning, ignored.')
|
||||
|
||||
def get_outdated_docs(self):
|
||||
return 'all documents' # for now
|
||||
@@ -92,6 +78,16 @@ class LaTeXBuilder(Builder):
|
||||
docname = docname[:-5]
|
||||
self.titles.append((docname, entry[2]))
|
||||
|
||||
def write_stylesheet(self):
|
||||
highlighter = highlighting.PygmentsBridge(
|
||||
'latex', self.config.pygments_style, self.config.trim_doctest_flags)
|
||||
stylesheet = path.join(self.outdir, 'sphinxhighlight.sty')
|
||||
with open(stylesheet, 'w') as f:
|
||||
f.write('\\NeedsTeXFormat{LaTeX2e}[1995/12/01]\n')
|
||||
f.write('\\ProvidesPackage{sphinxhighlight}'
|
||||
'[2016/05/29 stylesheet for highlighting with pygments]\n\n')
|
||||
f.write(highlighter.get_stylesheet())
|
||||
|
||||
def write(self, *ignored):
|
||||
docwriter = LaTeXWriter(self)
|
||||
docsettings = OptionParser(
|
||||
@@ -100,6 +96,7 @@ class LaTeXBuilder(Builder):
|
||||
read_config_files=True).get_default_values()
|
||||
|
||||
self.init_document_data()
|
||||
self.write_stylesheet()
|
||||
|
||||
for entry in self.document_data:
|
||||
docname, targetname, title, author, docclass = entry[:5]
|
||||
@@ -137,7 +134,7 @@ class LaTeXBuilder(Builder):
|
||||
tree = self.env.get_doctree(indexfile)
|
||||
contentsname = None
|
||||
for toctree in tree.traverse(addnodes.toctree):
|
||||
if toctree['caption']:
|
||||
if 'caption' in toctree:
|
||||
contentsname = toctree['caption']
|
||||
break
|
||||
|
||||
@@ -192,33 +189,118 @@ class LaTeXBuilder(Builder):
|
||||
self.info(bold('copying images...'), nonl=1)
|
||||
for src, dest in iteritems(self.images):
|
||||
self.info(' '+src, nonl=1)
|
||||
copyfile(path.join(self.srcdir, src),
|
||||
path.join(self.outdir, dest))
|
||||
copy_asset_file(path.join(self.srcdir, src),
|
||||
path.join(self.outdir, dest))
|
||||
self.info()
|
||||
|
||||
# copy TeX support files from texinputs
|
||||
context = {'latex_engine': self.config.latex_engine}
|
||||
self.info(bold('copying TeX support files...'))
|
||||
staticdirname = path.join(package_dir, 'texinputs')
|
||||
for filename in os.listdir(staticdirname):
|
||||
if not filename.startswith('.'):
|
||||
copyfile(path.join(staticdirname, filename),
|
||||
path.join(self.outdir, filename))
|
||||
copy_asset_file(path.join(staticdirname, filename),
|
||||
self.outdir, context=context)
|
||||
|
||||
# copy additional files
|
||||
if self.config.latex_additional_files:
|
||||
self.info(bold('copying additional files...'), nonl=1)
|
||||
for filename in self.config.latex_additional_files:
|
||||
self.info(' '+filename, nonl=1)
|
||||
copyfile(path.join(self.confdir, filename),
|
||||
path.join(self.outdir, path.basename(filename)))
|
||||
copy_asset_file(path.join(self.confdir, filename), self.outdir)
|
||||
self.info()
|
||||
|
||||
# the logo is handled differently
|
||||
if self.config.latex_logo:
|
||||
logobase = path.basename(self.config.latex_logo)
|
||||
logotarget = path.join(self.outdir, logobase)
|
||||
if not path.isfile(path.join(self.confdir, self.config.latex_logo)):
|
||||
raise SphinxError('logo file %r does not exist' % self.config.latex_logo)
|
||||
elif not path.isfile(logotarget):
|
||||
copyfile(path.join(self.confdir, self.config.latex_logo), logotarget)
|
||||
else:
|
||||
copy_asset_file(path.join(self.confdir, self.config.latex_logo), self.outdir)
|
||||
self.info('done')
|
||||
|
||||
|
||||
def validate_config_values(app):
|
||||
if app.config.latex_toplevel_sectioning not in (None, 'part', 'chapter', 'section'):
|
||||
app.warn('invalid latex_toplevel_sectioning, ignored: %s' %
|
||||
app.config.latex_toplevel_sectioning)
|
||||
app.config.latex_toplevel_sectioning = None
|
||||
|
||||
if app.config.latex_use_parts:
|
||||
if app.config.latex_toplevel_sectioning:
|
||||
app.warn('latex_use_parts conflicts with latex_toplevel_sectioning, ignored.')
|
||||
else:
|
||||
app.warn('latex_use_parts is deprecated. Use latex_toplevel_sectioning instead.')
|
||||
app.config.latex_toplevel_sectioning = 'parts'
|
||||
|
||||
if app.config.latex_use_modindex is not True: # changed by user
|
||||
app.warn('latex_use_modeindex is deprecated. Use latex_domain_indices instead.')
|
||||
|
||||
if app.config.latex_preamble:
|
||||
if app.config.latex_elements.get('preamble'):
|
||||
app.warn("latex_preamble conflicts with latex_elements['preamble'], ignored.")
|
||||
else:
|
||||
app.warn("latex_preamble is deprecated. Use latex_elements['preamble'] instead.")
|
||||
app.config.latex_elements['preamble'] = app.config.latex_preamble
|
||||
|
||||
if app.config.latex_paper_size != 'letter':
|
||||
if app.config.latex_elements.get('papersize'):
|
||||
app.warn("latex_paper_size conflicts with latex_elements['papersize'], ignored.")
|
||||
else:
|
||||
app.warn("latex_paper_size is deprecated. "
|
||||
"Use latex_elements['papersize'] instead.")
|
||||
if app.config.latex_paper_size:
|
||||
app.config.latex_elements['papersize'] = app.config.latex_paper_size + 'paper'
|
||||
|
||||
if app.config.latex_font_size != '10pt':
|
||||
if app.config.latex_elements.get('pointsize'):
|
||||
app.warn("latex_font_size conflicts with latex_elements['pointsize'], ignored.")
|
||||
else:
|
||||
app.warn("latex_font_size is deprecated. Use latex_elements['pointsize'] instead.")
|
||||
app.config.latex_elements['pointsize'] = app.config.latex_font_size
|
||||
|
||||
if 'footer' in app.config.latex_elements:
|
||||
if 'postamble' in app.config.latex_elements:
|
||||
app.warn("latex_elements['footer'] conflicts with "
|
||||
"latex_elements['postamble'], ignored.")
|
||||
else:
|
||||
app.warn("latex_elements['footer'] is deprecated. "
|
||||
"Use latex_elements['preamble'] instead.")
|
||||
app.config.latex_elements['postamble'] = app.config.latex_elements['footer']
|
||||
|
||||
|
||||
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)
|
||||
|
||||
@@ -15,10 +15,9 @@ import codecs
|
||||
import threading
|
||||
from os import path
|
||||
|
||||
from requests.exceptions import HTTPError
|
||||
from six.moves import queue
|
||||
from six.moves.urllib.request import build_opener, Request, HTTPRedirectHandler
|
||||
from six.moves.urllib.parse import unquote
|
||||
from six.moves.urllib.error import HTTPError
|
||||
from six.moves.html_parser import HTMLParser
|
||||
from docutils import nodes
|
||||
|
||||
@@ -36,28 +35,7 @@ from sphinx.builders import Builder
|
||||
from sphinx.util import encode_uri
|
||||
from sphinx.util.console import purple, red, darkgreen, darkgray, \
|
||||
darkred, turquoise
|
||||
from sphinx.util.pycompat import TextIOWrapper
|
||||
|
||||
|
||||
class RedirectHandler(HTTPRedirectHandler):
|
||||
"""A RedirectHandler that records the redirect code we got."""
|
||||
|
||||
def redirect_request(self, req, fp, code, msg, headers, newurl):
|
||||
new_req = HTTPRedirectHandler.redirect_request(self, req, fp, code,
|
||||
msg, headers, newurl)
|
||||
req.redirect_code = code
|
||||
return new_req
|
||||
|
||||
# create an opener that will simulate a browser user-agent
|
||||
opener = build_opener(RedirectHandler)
|
||||
opener.addheaders = [('User-agent', 'Mozilla/5.0 (X11; Linux x86_64; rv:25.0) '
|
||||
'Gecko/20100101 Firefox/25.0')]
|
||||
|
||||
|
||||
class HeadRequest(Request):
|
||||
"""Subclass of urllib2.Request that sends a HEAD request."""
|
||||
def get_method(self):
|
||||
return 'HEAD'
|
||||
from sphinx.util.requests import requests, useragent_header
|
||||
|
||||
|
||||
class AnchorCheckParser(HTMLParser):
|
||||
@@ -75,18 +53,18 @@ class AnchorCheckParser(HTMLParser):
|
||||
self.found = True
|
||||
|
||||
|
||||
def check_anchor(f, anchor):
|
||||
"""Reads HTML data from a filelike object 'f' searching for *anchor*.
|
||||
def check_anchor(response, anchor):
|
||||
"""Reads HTML data from a response object `response` searching for `anchor`.
|
||||
Returns True if anchor was found, False otherwise.
|
||||
"""
|
||||
parser = AnchorCheckParser(anchor)
|
||||
try:
|
||||
# Read file in chunks of 8192 bytes. If we find a matching anchor, we
|
||||
# break the loop early in hopes not to have to download the whole thing.
|
||||
chunk = f.read(8192)
|
||||
while chunk and not parser.found:
|
||||
# Read file in chunks. If we find a matching anchor, we break
|
||||
# the loop early in hopes not to have to download the whole thing.
|
||||
for chunk in response.iter_content():
|
||||
parser.feed(chunk)
|
||||
chunk = f.read(8192)
|
||||
if parser.found:
|
||||
break
|
||||
parser.close()
|
||||
except HTMLParseError:
|
||||
# HTMLParser is usually pretty good with sloppy HTML, but it tends to
|
||||
@@ -95,17 +73,6 @@ def check_anchor(f, anchor):
|
||||
return parser.found
|
||||
|
||||
|
||||
def get_content_charset(f):
|
||||
content_type = f.headers.get('content-type')
|
||||
if content_type:
|
||||
params = (p.strip() for p in content_type.split(';')[1:])
|
||||
for param in params:
|
||||
if param.startswith('charset='):
|
||||
return param[8:]
|
||||
|
||||
return None
|
||||
|
||||
|
||||
class CheckExternalLinksBuilder(Builder):
|
||||
"""
|
||||
Checks for broken external links.
|
||||
@@ -122,6 +89,9 @@ class CheckExternalLinksBuilder(Builder):
|
||||
# create output file
|
||||
open(path.join(self.outdir, 'output.txt'), 'w').close()
|
||||
|
||||
self.session = requests.Session()
|
||||
self.session.headers = dict(useragent_header)
|
||||
|
||||
# create queues and worker threads
|
||||
self.wqueue = queue.Queue()
|
||||
self.rqueue = queue.Queue()
|
||||
@@ -137,6 +107,8 @@ class CheckExternalLinksBuilder(Builder):
|
||||
if self.app.config.linkcheck_timeout:
|
||||
kwargs['timeout'] = self.app.config.linkcheck_timeout
|
||||
|
||||
kwargs['allow_redirects'] = True
|
||||
|
||||
def check_uri():
|
||||
# split off anchor
|
||||
if '#' in uri:
|
||||
@@ -157,16 +129,8 @@ class CheckExternalLinksBuilder(Builder):
|
||||
# Read the whole document and see if #anchor exists
|
||||
# (Anchors starting with ! are ignored since they are
|
||||
# commonly used for dynamic pages)
|
||||
req = Request(req_url)
|
||||
f = opener.open(req, **kwargs)
|
||||
encoding = 'utf-8'
|
||||
if hasattr(f.headers, 'get_content_charset'):
|
||||
encoding = f.headers.get_content_charset() or encoding
|
||||
else:
|
||||
encoding = get_content_charset(f) or encoding
|
||||
found = check_anchor(TextIOWrapper(f, encoding),
|
||||
unquote(anchor))
|
||||
f.close()
|
||||
response = self.session.get(req_url, stream=True, **kwargs)
|
||||
found = check_anchor(response, unquote(anchor))
|
||||
|
||||
if not found:
|
||||
raise Exception("Anchor '%s' not found" % anchor)
|
||||
@@ -174,32 +138,32 @@ class CheckExternalLinksBuilder(Builder):
|
||||
try:
|
||||
# try a HEAD request, which should be easier on
|
||||
# the server and the network
|
||||
req = HeadRequest(req_url)
|
||||
f = opener.open(req, **kwargs)
|
||||
f.close()
|
||||
response = self.session.head(req_url, **kwargs)
|
||||
response.raise_for_status()
|
||||
except HTTPError as err:
|
||||
if err.code != 405:
|
||||
if err.response.status_code not in (403, 405):
|
||||
raise
|
||||
# retry with GET if that fails, some servers
|
||||
# don't like HEAD requests and reply with 405
|
||||
req = Request(req_url)
|
||||
f = opener.open(req, **kwargs)
|
||||
f.close()
|
||||
# don't like HEAD requests and reply with 403 or 405
|
||||
response = self.session.get(req_url, stream=True, **kwargs)
|
||||
response.raise_for_status()
|
||||
except HTTPError as err:
|
||||
if err.code == 401:
|
||||
if err.response.status_code == 401:
|
||||
# We'll take "Unauthorized" as working.
|
||||
return 'working', ' - unauthorized', 0
|
||||
else:
|
||||
return 'broken', str(err), 0
|
||||
except Exception as err:
|
||||
return 'broken', str(err), 0
|
||||
if f.url.rstrip('/') == req_url.rstrip('/'):
|
||||
if response.url.rstrip('/') == req_url.rstrip('/'):
|
||||
return 'working', '', 0
|
||||
else:
|
||||
new_url = f.url
|
||||
new_url = response.url
|
||||
if anchor:
|
||||
new_url += '#' + anchor
|
||||
code = getattr(req, 'redirect_code', 0)
|
||||
# history contains any redirects, get last
|
||||
if response.history:
|
||||
code = response.history[-1].status_code
|
||||
return 'redirected', new_url, code
|
||||
|
||||
def check():
|
||||
@@ -258,7 +222,7 @@ class CheckExternalLinksBuilder(Builder):
|
||||
elif status == 'broken':
|
||||
self.write_entry('broken', docname, lineno, uri + ': ' + info)
|
||||
if self.app.quiet or self.app.warningiserror:
|
||||
self.warn('broken link: %s' % uri,
|
||||
self.warn('broken link: %s (%s)' % (uri, info),
|
||||
'%s:%s' % (self.env.doc2path(docname), lineno))
|
||||
else:
|
||||
self.info(red('broken ') + uri + red(' - ' + info))
|
||||
@@ -315,3 +279,13 @@ class CheckExternalLinksBuilder(Builder):
|
||||
def finish(self):
|
||||
for worker in self.workers:
|
||||
self.wqueue.put((None, None, None), False)
|
||||
|
||||
|
||||
def setup(app):
|
||||
app.add_builder(CheckExternalLinksBuilder)
|
||||
|
||||
app.add_config_value('linkcheck_ignore', [], None)
|
||||
app.add_config_value('linkcheck_retries', 1, None)
|
||||
app.add_config_value('linkcheck_timeout', None, None, [int])
|
||||
app.add_config_value('linkcheck_workers', 5, None)
|
||||
app.add_config_value('linkcheck_anchors', True, None)
|
||||
|
||||
@@ -19,6 +19,7 @@ from sphinx import addnodes
|
||||
from sphinx.builders import Builder
|
||||
from sphinx.environment import NoUri
|
||||
from sphinx.util.nodes import inline_all_toctrees
|
||||
from sphinx.util.osutil import make_filename
|
||||
from sphinx.util.console import bold, darkgreen
|
||||
from sphinx.writers.manpage import ManualPageWriter
|
||||
|
||||
@@ -88,3 +89,13 @@ class ManualPageBuilder(Builder):
|
||||
|
||||
def finish(self):
|
||||
pass
|
||||
|
||||
|
||||
def setup(app):
|
||||
app.add_builder(ManualPageBuilder)
|
||||
|
||||
app.add_config_value('man_pages',
|
||||
lambda self: [(self.master_doc, make_filename(self.project).lower(),
|
||||
'%s %s' % (self.project, self.release), [], 1)],
|
||||
None)
|
||||
app.add_config_value('man_show_urls', False, None)
|
||||
|
||||
@@ -21,6 +21,7 @@ from docutils import nodes
|
||||
from sphinx import addnodes
|
||||
from sphinx.builders.html import StandaloneHTMLBuilder
|
||||
from sphinx.util import force_decode
|
||||
from sphinx.util.osutil import make_filename
|
||||
from sphinx.util.pycompat import htmlescape
|
||||
|
||||
|
||||
@@ -104,15 +105,25 @@ class QtHelpBuilder(StandaloneHTMLBuilder):
|
||||
|
||||
# don't add links
|
||||
add_permalinks = False
|
||||
|
||||
# don't add sidebar etc.
|
||||
embedded = True
|
||||
# disable download role
|
||||
download_support = False
|
||||
|
||||
# don't generate the search index or include the search page
|
||||
search = False
|
||||
|
||||
def init(self):
|
||||
StandaloneHTMLBuilder.init(self)
|
||||
# the output files for HTML help must be .html only
|
||||
self.out_suffix = '.html'
|
||||
self.link_suffix = '.html'
|
||||
# self.config.html_style = 'traditional.css'
|
||||
|
||||
def get_theme_config(self):
|
||||
return self.config.qthelp_theme, self.config.qthelp_theme_options
|
||||
|
||||
def handle_finish(self):
|
||||
self.build_qhp(self.outdir, self.config.qthelp_basename)
|
||||
|
||||
@@ -179,8 +190,7 @@ class QtHelpBuilder(StandaloneHTMLBuilder):
|
||||
nspace = nspace.lower()
|
||||
|
||||
# write the project file
|
||||
f = codecs.open(path.join(outdir, outname+'.qhp'), 'w', 'utf-8')
|
||||
try:
|
||||
with codecs.open(path.join(outdir, outname+'.qhp'), 'w', 'utf-8') as f:
|
||||
f.write(project_template % {
|
||||
'outname': htmlescape(outname),
|
||||
'title': htmlescape(self.config.html_title),
|
||||
@@ -191,23 +201,18 @@ class QtHelpBuilder(StandaloneHTMLBuilder):
|
||||
'sections': sections,
|
||||
'keywords': keywords,
|
||||
'files': projectfiles})
|
||||
finally:
|
||||
f.close()
|
||||
|
||||
homepage = 'qthelp://' + posixpath.join(
|
||||
nspace, 'doc', self.get_target_uri(self.config.master_doc))
|
||||
startpage = 'qthelp://' + posixpath.join(nspace, 'doc', 'index.html')
|
||||
|
||||
self.info('writing collection project file...')
|
||||
f = codecs.open(path.join(outdir, outname+'.qhcp'), 'w', 'utf-8')
|
||||
try:
|
||||
with codecs.open(path.join(outdir, outname+'.qhcp'), 'w', 'utf-8') as f:
|
||||
f.write(collection_template % {
|
||||
'outname': htmlescape(outname),
|
||||
'title': htmlescape(self.config.html_short_title),
|
||||
'homepage': htmlescape(homepage),
|
||||
'startpage': htmlescape(startpage)})
|
||||
finally:
|
||||
f.close()
|
||||
|
||||
def isdocnode(self, node):
|
||||
if not isinstance(node, nodes.list_item):
|
||||
@@ -296,3 +301,12 @@ class QtHelpBuilder(StandaloneHTMLBuilder):
|
||||
keywords.extend(self.build_keywords(subitem[0], subitem[1], []))
|
||||
|
||||
return keywords
|
||||
|
||||
|
||||
def setup(app):
|
||||
app.setup_extension('sphinx.builders.html')
|
||||
app.add_builder(QtHelpBuilder)
|
||||
|
||||
app.add_config_value('qthelp_basename', lambda self: make_filename(self.project), None)
|
||||
app.add_config_value('qthelp_theme', 'nonav', 'html')
|
||||
app.add_config_value('qthelp_theme_options', {}, 'html')
|
||||
|
||||
@@ -22,7 +22,7 @@ from sphinx.locale import _
|
||||
from sphinx.builders import Builder
|
||||
from sphinx.environment import NoUri
|
||||
from sphinx.util.nodes import inline_all_toctrees
|
||||
from sphinx.util.osutil import SEP, copyfile
|
||||
from sphinx.util.osutil import SEP, copyfile, make_filename
|
||||
from sphinx.util.console import bold, darkgreen
|
||||
from sphinx.writers.texinfo import TexinfoWriter
|
||||
|
||||
@@ -220,11 +220,25 @@ class TexinfoBuilder(Builder):
|
||||
fn = path.join(self.outdir, 'Makefile')
|
||||
self.info(fn, nonl=1)
|
||||
try:
|
||||
mkfile = open(fn, 'w')
|
||||
try:
|
||||
with open(fn, 'w') as mkfile:
|
||||
mkfile.write(TEXINFO_MAKEFILE)
|
||||
finally:
|
||||
mkfile.close()
|
||||
except (IOError, OSError) as err:
|
||||
self.warn("error writing file %s: %s" % (fn, err))
|
||||
self.info(' done')
|
||||
|
||||
|
||||
def setup(app):
|
||||
app.add_builder(TexinfoBuilder)
|
||||
|
||||
app.add_config_value('texinfo_documents',
|
||||
lambda self: [(self.master_doc, make_filename(self.project).lower(),
|
||||
self.project, '', make_filename(self.project),
|
||||
'The %s reference manual.' %
|
||||
make_filename(self.project),
|
||||
'Python')],
|
||||
None)
|
||||
app.add_config_value('texinfo_appendices', [], None)
|
||||
app.add_config_value('texinfo_elements', {}, None)
|
||||
app.add_config_value('texinfo_domain_indices', True, None, [list])
|
||||
app.add_config_value('texinfo_show_urls', 'footnote', None)
|
||||
app.add_config_value('texinfo_no_detailmenu', False, None)
|
||||
|
||||
@@ -60,13 +60,17 @@ class TextBuilder(Builder):
|
||||
outfilename = path.join(self.outdir, os_path(docname) + self.out_suffix)
|
||||
ensuredir(path.dirname(outfilename))
|
||||
try:
|
||||
f = codecs.open(outfilename, 'w', 'utf-8')
|
||||
try:
|
||||
with codecs.open(outfilename, 'w', 'utf-8') as f:
|
||||
f.write(self.writer.output)
|
||||
finally:
|
||||
f.close()
|
||||
except (IOError, OSError) as err:
|
||||
self.warn("error writing file %s: %s" % (outfilename, err))
|
||||
|
||||
def finish(self):
|
||||
pass
|
||||
|
||||
|
||||
def setup(app):
|
||||
app.add_builder(TextBuilder)
|
||||
|
||||
app.add_config_value('text_sectionchars', '*=-~"+`', 'env')
|
||||
app.add_config_value('text_newlines', 'unix', 'env')
|
||||
|
||||