Merge remote-tracking branch 'upstream/master'

Conflicts:
	tests/test_build_html.py
This commit is contained in:
Jellby
2016-09-29 20:21:50 +02:00
535 changed files with 22065 additions and 11859 deletions

View File

@@ -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

View File

@@ -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
View File

@@ -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)
=====================================

View File

@@ -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/

View File

@@ -13,6 +13,7 @@ include sphinx-build.py
include sphinx-quickstart.py
include sphinx-apidoc.py
recursive-include sphinx/templates *
recursive-include sphinx/texinputs *
recursive-include sphinx/themes *
recursive-include sphinx/locale *
@@ -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

View File

@@ -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

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 27 KiB

BIN
doc/_static/pocoo.png vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
doc/_static/sphinx.png vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 33 KiB

View File

@@ -5,17 +5,16 @@
<div class="quotebar">
<p><em>{%trans%}What users say:{%endtrans%}</em></p>
<p>{%trans%}&ldquo;Cheers for a great tool that actually makes programmers <b>want</b>
to write documentation!&rdquo;{%endtrans%}</p>
<p>{%trans%}&#8220;Cheers for a great tool that actually makes programmers <b>want</b>
to write documentation!&#8220;{%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>

View File

@@ -57,8 +57,8 @@
{% endblock %}
{% block rootrellink %}
<li><a href="{{ pathto('index') }}">Sphinx home</a>&nbsp;|</li>
<li><a href="{{ pathto('contents') }}">Documentation</a> &raquo;</li>
<li><a href="{{ pathto('index') }}">Sphinx home</a>&#160;|</li>
<li><a href="{{ pathto('contents') }}">Documentation</a> &#187;</li>
{% endblock %}
{% block header %}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 513 B

After

Width:  |  Height:  |  Size: 429 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 220 B

After

Width:  |  Height:  |  Size: 180 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 230 B

After

Width:  |  Height:  |  Size: 189 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 207 B

After

Width:  |  Height:  |  Size: 149 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 223 B

After

Width:  |  Height:  |  Size: 183 B

View File

@@ -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;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -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

View File

@@ -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)]

View File

@@ -56,7 +56,7 @@ General configuration
.. confval:: extensions
A list of strings that are module names of Sphinx extensions. These can be
A list of strings that are module names of :ref:`extensions`. These can be
extensions coming with Sphinx (named ``sphinx.ext.*``) or custom ones.
Note that you can extend :data:`sys.path` within the conf file if your
@@ -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

View File

@@ -1,3 +1,4 @@
.. _contents:
Sphinx documentation contents
@@ -17,6 +18,7 @@ Sphinx documentation contents
intl
theming
templating
latex
extensions
extdev/index
websupport
@@ -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`

View File

@@ -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::

View File

@@ -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
View 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

View File

@@ -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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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

View File

@@ -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:

View File

@@ -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.

View File

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

View File

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

View File

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

View File

@@ -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*.

View File

@@ -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)

View File

@@ -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

View File

@@ -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:

View File

@@ -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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View File

@@ -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.

View File

@@ -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
View 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

View File

@@ -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.

View File

@@ -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::

View File

@@ -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.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 150 KiB

After

Width:  |  Height:  |  Size: 146 KiB

View File

@@ -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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 26 KiB

BIN
doc/themes/classic.png vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 KiB

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 KiB

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 87 KiB

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 KiB

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 KiB

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 89 KiB

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 97 KiB

After

Width:  |  Height:  |  Size: 90 KiB

BIN
doc/themes/haiku.png vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 42 KiB

BIN
doc/themes/nature.png vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 28 KiB

BIN
doc/themes/pyramid.png vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 38 KiB

BIN
doc/themes/scrolls.png vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 32 KiB

View File

@@ -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.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

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

View File

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

View File

@@ -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__,

View File

@@ -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

View File

@@ -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.
"""

View File

@@ -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')

View File

@@ -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

View File

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

View File

@@ -13,14 +13,16 @@ from __future__ import print_function
import codecs
import pipes
from os import path
from os import path, environ
import shlex
from sphinx.builders.html import StandaloneHTMLBuilder
from sphinx.util import copy_static_entry
from sphinx.util.osutil import copyfile, ensuredir
from sphinx.config import string_classes
from sphinx.util.osutil import copyfile, ensuredir, make_filename
from sphinx.util.console import bold
from sphinx.util.fileutil import copy_asset
from sphinx.util.pycompat import htmlescape
from sphinx.util.matching import compile_matchers
from sphinx.util.matching import Matcher
from sphinx.errors import SphinxError
import plistlib
@@ -84,6 +86,7 @@ class AppleHelpBuilder(StandaloneHTMLBuilder):
super(AppleHelpBuilder, self).init()
# the output files for HTML help must be .html only
self.out_suffix = '.html'
self.link_suffix = '.html'
if self.config.applehelp_bundle_id is None:
raise SphinxError('You must set applehelp_bundle_id before '
@@ -104,17 +107,15 @@ class AppleHelpBuilder(StandaloneHTMLBuilder):
self.finish_tasks.add_task(self.build_helpbook)
def copy_localized_files(self):
source_dir = path.join(self.confdir,
self.config.applehelp_locale + '.lproj')
source_dir = path.join(self.confdir, self.config.applehelp_locale + '.lproj')
target_dir = self.outdir
if path.isdir(source_dir):
self.info(bold('copying localized files... '), nonl=True)
ctx = self.globalcontext.copy()
matchers = compile_matchers(self.config.exclude_patterns)
copy_static_entry(source_dir, target_dir, self, ctx,
exclude_matchers=matchers)
excluded = Matcher(self.config.exclude_patterns + ['**/.*'])
copy_asset(source_dir, target_dir, excluded,
context=self.globalcontext, renderer=self.templates)
self.info('done')
@@ -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)

View File

@@ -15,12 +15,12 @@ from os import path
from six import iteritems
from sphinx import package_dir
from sphinx.util import copy_static_entry
from sphinx.locale import _
from sphinx.theming import Theme
from sphinx.builders import Builder
from sphinx.util.osutil import ensuredir, os_path
from sphinx.util.console import bold
from sphinx.util.fileutil import copy_asset_file
from sphinx.util.pycompat import htmlescape
@@ -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)

View File

@@ -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)

View File

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

View File

@@ -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')

View File

@@ -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)

View File

@@ -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')

View File

@@ -27,13 +27,15 @@ from docutils.frontend import OptionParser
from docutils.readers.doctree import Reader as DoctreeReader
from sphinx import package_dir, __display_version__
from sphinx.util import jsonimpl, copy_static_entry, copy_extra_entry
from sphinx.util import jsonimpl
from sphinx.util.i18n import format_date
from sphinx.util.osutil import SEP, os_path, relative_uri, ensuredir, \
movefile, copyfile
from sphinx.util.nodes import inline_all_toctrees
from sphinx.util.matching import patmatch, compile_matchers
from sphinx.locale import _
from sphinx.util.fileutil import copy_asset
from sphinx.util.matching import patmatch, Matcher, DOTFILES
from sphinx.config import string_classes
from sphinx.locale import _, l_
from sphinx.search import js_index
from sphinx.theming import Theme
from sphinx.builders import Builder
@@ -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')

View File

@@ -18,6 +18,7 @@ from os import path
from docutils import nodes
from sphinx import addnodes
from sphinx.util.osutil import make_filename
from sphinx.builders.html import StandaloneHTMLBuilder
from sphinx.util.pycompat import htmlescape
@@ -63,7 +64,7 @@ Binary Index=No
Compiled file=%(outname)s.chm
Contents file=%(outname)s.hhc
Default Window=%(outname)s
Default topic=index.html
Default topic=%(master_doc)s
Display compile progress=No
Full text search stop list file=%(outname)s.stp
Full-text search=Yes
@@ -73,7 +74,7 @@ Title=%(title)s
[WINDOWS]
%(outname)s="%(title)s","%(outname)s.hhc","%(outname)s.hhk",\
"index.html","index.html",,,,,0x63520,220,0x10384e,[0,0,1024,768],,,,,,,0
"%(master_doc)s","%(master_doc)s",,,,,0x63520,220,0x10384e,[0,0,1024,768],,,,,,,0
[FILES]
'''
@@ -183,6 +184,7 @@ class HTMLHelpBuilder(StandaloneHTMLBuilder):
StandaloneHTMLBuilder.init(self)
# the output files for HTML help must be .html only
self.out_suffix = '.html'
self.link_suffix = '.html'
# determine the correct locale setting
locale = chm_locales.get(self.config.language)
if locale is not None:
@@ -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)

View File

@@ -11,7 +11,6 @@
import os
from os import path
import warnings
from six import iteritems
from docutils import nodes
@@ -19,14 +18,16 @@ from docutils.io import FileOutput
from docutils.utils import new_document
from docutils.frontend import OptionParser
from sphinx import package_dir, addnodes
from sphinx import package_dir, addnodes, highlighting
from sphinx.util import texescape
from sphinx.config import string_classes, ENUM
from sphinx.errors import SphinxError
from sphinx.locale import _
from sphinx.builders import Builder
from sphinx.environment import NoUri
from sphinx.util.nodes import inline_all_toctrees
from sphinx.util.osutil import SEP, copyfile
from sphinx.util.fileutil import copy_asset_file
from sphinx.util.osutil import SEP, make_filename
from sphinx.util.console import bold, darkgreen
from sphinx.writers.latex import LaTeXWriter
@@ -38,27 +39,12 @@ class LaTeXBuilder(Builder):
name = 'latex'
format = 'latex'
supported_image_types = ['application/pdf', 'image/png', 'image/jpeg']
usepackages = []
def init(self):
self.docnames = []
self.document_data = []
self.usepackages = []
texescape.init()
self.check_options()
def check_options(self):
if self.config.latex_toplevel_sectioning not in (None, 'part', 'chapter', 'section'):
self.warn('invalid latex_toplevel_sectioning, ignored: %s' %
self.config.latex_top_sectionlevel)
self.config.latex_top_sectionlevel = None
if self.config.latex_use_parts:
warnings.warn('latex_use_parts will be removed at Sphinx-1.5. '
'Use latex_toplevel_sectioning instead.',
DeprecationWarning)
if self.config.latex_toplevel_sectioning:
self.warn('latex_use_parts conflicts with latex_toplevel_sectioning, ignored.')
def get_outdated_docs(self):
return 'all documents' # for now
@@ -92,6 +78,16 @@ class LaTeXBuilder(Builder):
docname = docname[:-5]
self.titles.append((docname, entry[2]))
def write_stylesheet(self):
highlighter = highlighting.PygmentsBridge(
'latex', self.config.pygments_style, self.config.trim_doctest_flags)
stylesheet = path.join(self.outdir, 'sphinxhighlight.sty')
with open(stylesheet, 'w') as f:
f.write('\\NeedsTeXFormat{LaTeX2e}[1995/12/01]\n')
f.write('\\ProvidesPackage{sphinxhighlight}'
'[2016/05/29 stylesheet for highlighting with pygments]\n\n')
f.write(highlighter.get_stylesheet())
def write(self, *ignored):
docwriter = LaTeXWriter(self)
docsettings = OptionParser(
@@ -100,6 +96,7 @@ class LaTeXBuilder(Builder):
read_config_files=True).get_default_values()
self.init_document_data()
self.write_stylesheet()
for entry in self.document_data:
docname, targetname, title, author, docclass = entry[:5]
@@ -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)

View File

@@ -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)

View File

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

View File

@@ -21,6 +21,7 @@ from docutils import nodes
from sphinx import addnodes
from sphinx.builders.html import StandaloneHTMLBuilder
from sphinx.util import force_decode
from sphinx.util.osutil import make_filename
from sphinx.util.pycompat import htmlescape
@@ -104,15 +105,25 @@ class QtHelpBuilder(StandaloneHTMLBuilder):
# don't add links
add_permalinks = False
# don't add sidebar etc.
embedded = True
# disable download role
download_support = False
# don't generate the search index or include the search page
search = False
def init(self):
StandaloneHTMLBuilder.init(self)
# the output files for HTML help must be .html only
self.out_suffix = '.html'
self.link_suffix = '.html'
# self.config.html_style = 'traditional.css'
def get_theme_config(self):
return self.config.qthelp_theme, self.config.qthelp_theme_options
def handle_finish(self):
self.build_qhp(self.outdir, self.config.qthelp_basename)
@@ -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')

View File

@@ -22,7 +22,7 @@ from sphinx.locale import _
from sphinx.builders import Builder
from sphinx.environment import NoUri
from sphinx.util.nodes import inline_all_toctrees
from sphinx.util.osutil import SEP, copyfile
from sphinx.util.osutil import SEP, copyfile, make_filename
from sphinx.util.console import bold, darkgreen
from sphinx.writers.texinfo import TexinfoWriter
@@ -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)

View File

@@ -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')

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