diff --git a/.travis.yml b/.travis.yml index c468867ae..d07531261 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,16 +13,24 @@ python: - "pypy" env: global: - - TEST=-v + - TEST='-v --with-timer --timer-top-n 25' matrix: - DOCUTILS=0.11 - DOCUTILS=0.12 +addons: + apt: + packages: + - graphviz + - texlive-latex-recommended + - texlive-latex-extra + - texlive-fonts-recommended + - texlive-fonts-extra install: - - pip install -U pip + - pip install -U pip setuptools - pip install docutils==$DOCUTILS - pip install -r test-reqs.txt -before_script: flake8 +before_script: + - if [[ $TRAVIS_PYTHON_VERSION != '2.6' ]]; then flake8; fi script: - - - if [[ $TRAVIS_PYTHON_VERSION == '3.5' ]]; then make test-async; fi + - if [[ $TRAVIS_PYTHON_VERSION == '3.5' ]]; then make style-check test-async; fi - if [[ $TRAVIS_PYTHON_VERSION != '3.5' ]]; then make test; fi diff --git a/AUTHORS b/AUTHORS index dc8e82482..677e814fc 100644 --- a/AUTHORS +++ b/AUTHORS @@ -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) diff --git a/CHANGES b/CHANGES index 87f983bf8..b3eb60219 100644 --- a/CHANGES +++ b/CHANGES @@ -4,32 +4,230 @@ Release 1.5 (in development) Incompatible changes -------------------- -* LaTeX package fancybox is not longer a dependency of sphinx.sty +* latex, package fancybox is not longer a dependency of sphinx.sty * Use ``'locales'`` as a default value of `locale_dirs` +* latex, package ifthen is not any longer a dependency of sphinx.sty +* latex, style file does not modify fancyvrb's Verbatim (also available as + OriginalVerbatim) but uses sphinxVerbatim for name of custom wrapper. +* latex, package newfloat is no longer a dependency of sphinx.sty (ref #2660; + it was shipped with Sphinx since 1.3.4). +* latex, literal blocks in tables do not use OriginalVerbatim but + sphinxVerbatimintable which handles captions and wraps lines(ref #2704). +* latex, replace ``pt`` by TeX equivalent ``bp`` if found in ``width`` or + ``height`` attribute of an image. +* latex, if ``width`` or ``height`` attribute of an image is given with no unit, + use ``px`` rather than ignore it. +* latex: Separate stylesheets of pygments to independent .sty file +* #2454: The filename of sourcelink is now changed. The value of + `html_sourcelink_suffix` will be appended to the original filename (like + ``index.rst.txt``). +* ``sphinx.util.copy_static_entry()`` is now deprecated. + Use ``sphinx.util.fileutil.copy_asset()`` instead. +* ``sphinx.util.osutil.filecopy()`` skips copying if the file has not been changed + (ref: #2510, #2753) +* Internet Explorer 6-8, Opera 12.1x or Safari 5.1+ support is dropped + because jQuery version is updated from 1.11.0 to 3.1.0 (ref: #2634, #2773) +* QtHelpBuilder doens't generate search page (ref: #2352) +* QtHelpBuilder uses ``nonav`` theme instead of default one + to improve readability. +* latex: To provide good default settings to Japanese docs, Sphinx uses ``jsbooks`` + as a docclass by default if the ``language`` is ``ja``. +* latex: To provide good default settings to Japanese docs, Sphinx uses + ``jreport`` and ``jsbooks`` as a docclass by default if the ``language`` is + ``ja``. +* ``sphinx-quickstart`` now allows a project version is empty +* Fix :download: role on epub/qthelp builder. They ignore the role because they don't support it. +* ``sphinx.ext.viewcode`` doesn't work on epub building by default. ``viewcode_enable_epub`` option +* ``sphinx.ext.viewcode`` disabled on singlehtml builder. Features added -------------- * Add ``:caption:`` option for sphinx.ext.inheritance_diagram. -* #894: Add ``lualatexpdf`` and ``xelatexpdf`` as a make target to build PDF using lualatex or xelatex * #2471: Add config variable for default doctest flags. * Convert linkcheck builder to requests for better encoding handling * #2463, #2516: Add keywords of "meta" directive to search index * ``:maxdepth:`` option of toctree affects ``secnumdepth`` (ref: #2547) * #2575: Now ``sphinx.ext.graphviz`` allows ``:align:`` option +* Show warnings if unknown key is specified to `latex_elements` +* Show warnings if no domains match with `primary_domain` (ref: #2001) +* C++, show warnings when the kind of role is misleading for the kind + of target it refers to (e.g., using the `class` role for a function). +* latex, writer abstracts more of text styling into customizable macros, e.g. + the ``visit_emphasis`` will output ``\sphinxstyleemphasis`` rather than + ``\emph`` (which may be in use elsewhere or in an added LaTeX package). See + list at end of ``sphinx.sty`` (ref: #2686) +* latex, public names for environments and parameters used by note, warning, + and other admonition types, allowing full customizability from the + ``'preamble'`` key or an input file (ref: feature request #2674, #2685) +* latex, better computes column widths of some tables (as a result, there will + be slight changes as tables now correctly fill the line width; ref: #2708) +* latex, sphinxVerbatim environment is more easily customizable (ref: #2704). + In addition to already existing VerbatimColor and VerbatimBorderColor: + + - two lengths ``\sphinxverbatimsep`` and ``\sphinxverbatimborder``, + - booleans ``\ifsphinxverbatimwithframe`` and ``\ifsphinxverbatimwrapslines``. + +* latex, captions for literal blocks inside tables are handled, and long code + lines wrapped to fit table cell (ref: #2704) +* #2597: Show warning messages as darkred +* latex, allow image dimensions using px unit (default is 96px=1in) +* Show warnings if invalid dimension units found +* #2650: Add ``--pdb`` option to setup.py command +* latex, make the use of ``\small`` for code listings customizable (ref #2721) +* #2663: Add ``--warning-is-error`` option to setup.py command +* Show warnings if deprecated latex options are used +* Add sphinx.config.ENUM to check the config values is in candidates +* math: Add hyperlink marker to each equations in HTML output +* Add new theme ``nonav`` that doesn't include any navigation links. + This is for any help generator like qthelp. +* #2680: `sphinx.ext.todo` now emits warnings if `todo_emit_warnings` enabled. + Also, it emits an additional event named `todo-defined` to handle the TODO + entries in 3rd party extensions. +* Python domain signature parser now uses the xref mixin for 'exceptions', + allowing exception classes to be autolinked. +* #2513: Add `latex_engine` to switch the LaTeX engine by conf.py +* #2682: C++, basic support for attributes (C++11 style and GNU style). + The new configuration variables 'cpp_id_attributes' and 'cpp_paren_attributes' + can be used to introduce custom attributes. +* #1958: C++, add configuration variable 'cpp_index_common_prefix' for removing + prefixes from the index text of C++ objects. * C++, added concept directive. Thanks to mickk-on-cpp. * C++, added support for template introduction syntax. Thanks to mickk-on-cpp. Bugs fixed ---------- +* #2707: (latex) the column width is badly computed for tabular +* #2799: Sphinx installs roles and directives automatically on importing sphinx + module. Now Sphinx installs them on running application. + Documentation ------------- -Release 1.4.2 (in development) +Release 1.4.6 (in development) ============================== +Bugs fixed +---------- + +* applehelp: Sphinx crashes if ``hiutil`` or ``codesign`` commands not found +* Fix ``make clean`` abort issue when build dir contains regular files like ``DS_Store``. +* Reduce epubcheck warnings/errors: + + * Fix DOCTYPE to html5 + * Change extension from .html to .xhtml. + * Disable search page on epub results + +* #2778: Fix autodoc crashes if obj.__dict__ is a property method and raises exception +* Fix duplicated toc in epub3 output. +* #2775: Fix failing linkcheck with servers not supporting identidy encoding +* #2833: Fix formatting instance annotations in ext.autodoc. +* #1911: ``-D`` option of `sphinx-build` does not override the ``extensions`` variable + +Release 1.4.5 (released Jul 13, 2016) +===================================== + +Incompatible changes +-------------------- + +* latex, inclusion of non-inline images from image directive resulted in + non-coherent whitespaces depending on original image width; new behaviour + by necessity differs from earlier one in some cases. (ref: #2672) +* latex, use of ``\includegraphics`` to refer to Sphinx custom variant is + deprecated; in future it will revert to original LaTeX macro, custom one + already has alternative name ``\sphinxincludegraphics``. + +Features added +-------------- + +* new config option ``latex_keep_old_macro_names``, defaults to True. If False, + lets macros (for text styling) be defined only with ``\sphinx``-prefixed names. +* latex writer allows user customization of "shadowed" boxes (topics), via + three length variables. +* woff-format web font files now supported by the epub builder. + +Bugs fixed +---------- + +* jsdump fix for python 3: fixes the HTML search on python > 3 +* #2676: (latex) Error with verbatim text in captions since Sphinx 1.4.4 +* #2629: memoir class crashes LaTeX. Fixed ``by latex_keep_old_macro_names=False`` (ref 2675) +* #2684: `sphinx.ext.intersphinx` crashes with six-1.4.1 +* #2679: ``float`` package needed for ``'figure_align': 'H'`` latex option +* #2671: image directive may lead to inconsistent spacing in pdf +* #2705: ``toctree`` generates empty bullet_list if ``:titlesonly:`` specified +* #2479: `sphinx.ext.viewcode` uses python2 highlighter by default +* #2700: HtmlHelp builder has hard coded index.html +* latex, since 1.4.4 inline literal text is followed by spurious space +* #2722: C++, fix id generation for var/member declarations to include namespaces. +* latex, images (from image directive) in lists or quoted blocks did not obey + indentation (fixed together with #2671) +* #2733: since Sphinx-1.4.4 ``make latexpdf`` generates lots of hyperref warnings +* #2731: `sphinx.ext.autodoc` does not access propertymethods which raises any + exceptions +* #2666: C++, properly look up nested names involving constructors. +* #2579: Could not refer a label including both spaces and colons via + `sphinx.ext.intersphinx` +* #2718: Sphinx crashes if the document file is not readable +* #2699: hyperlinks in help HTMLs are broken if `html_file_suffix` is set +* #2723: extra spaces in latex pdf output from multirow cell +* #2735: latexpdf ``Underfull \hbox (badness 10000)`` warnings from title page +* #2667: latex crashes if resized images appeared in section title +* #2763: (html) Provide default value for required ``alt`` attribute for image + tags of SVG source, required to validate and now consistent w/ other formats. + + +Release 1.4.4 (released Jun 12, 2016) +===================================== + +Bugs fixed +---------- + +* #2630: Latex sphinx.sty Notice Enviroment formatting problem +* #2632: Warning directives fail in quote environment latex build +* #2633: Sphinx crashes with old styled indices +* Fix a ``\begin{\minipage}`` typo in sphinx.sty from 1.4.2 (ref: 68becb1) +* #2622: Latex produces empty pages after title and table of contents +* #2640: 1.4.2 LaTeX crashes if code-block inside warning directive +* Let LaTeX use straight quotes also in inline code (ref #2627) +* #2351: latex crashes if enumerated lists are placed on footnotes +* #2646: latex crashes if math contains twice empty lines +* #2480: `sphinx.ext.autodoc`: memory addresses were shown +* latex: allow code-blocks appearing inside lists and quotes at maximal nesting + depth (ref #777, #2624, #2651) +* #2635: Latex code directives produce inconsistent frames based on viewing + resolution +* #2639: Sphinx now bundles iftex.sty +* Failed to build PDF with framed.sty 0.95 +* Sphinx now bundles needspace.sty + + +Release 1.4.3 (released Jun 5, 2016) +==================================== + +Bugs fixed +---------- + +* #2530: got "Counter too large" error on building PDF if large numbered + footnotes existed in admonitions +* ``width`` option of figure directive does not work if ``align`` option specified at same time (ref: #2595) +* #2590: The ``inputenc`` package breaks compiling under lualatex and xelatex +* #2540: date on latex front page use different font +* Suppress "document isn't included in any toctree" warning if the document is included (ref: #2603) +* #2614: Some tables in PDF output will end up shifted if user sets non zero + \parindent in preamble +* #2602: URL redirection breaks the hyperlinks generated by `sphinx.ext.intersphinx` +* #2613: Show warnings if merged extensions are loaded +* #2619: make sure amstext LaTeX package always loaded (ref: d657225, 488ee52, + 9d82cad and #2615) +* #2593: latex crashes if any figures in the table + + +Release 1.4.2 (released May 29, 2016) +===================================== + Features added -------------- @@ -64,7 +262,8 @@ Bugs fixed * #2397: Setup shorthandoff for turkish documents * #2447: VerbatimBorderColor wrongly used also for captions of PDF * #2456: C++, fix crash related to document merging (e.g., singlehtml and Latex builders). -* #2446: latex(pdf) sets local tables of contents (or more generally topic nodes) in unbreakable boxes, causes overflow at bottom +* #2446: latex(pdf) sets local tables of contents (or more generally topic + nodes) in unbreakable boxes, causes overflow at bottom * #2476: Omit MathJax markers if :nowrap: is given * #2465: latex builder fails in case no caption option is provided to toctree directive * Sphinx crashes if self referenced toctree found @@ -100,6 +299,7 @@ Bugs fixed * #2581: The search doesn't work if language="es" (spanish) * #2382: Adjust spacing after abbreviations on figure numbers in LaTeX writer * #2383: The generated footnote by `latex_show_urls` overflows lines +* #2497, #2552: The label of search button does not fit for the button itself Release 1.4.1 (released Apr 12, 2016) @@ -272,7 +472,8 @@ Bugs fixed is highlighted as Python 3 (which is mostly a superset of Python 2) if possible. To get the old behavior back, add ``highlight_language = "python"`` to conf.py. * #2329: Refresh environment forcely if source directory has changed. -* #2331: Fix code-blocks are filled by block in dvi; remove ``xcdraw`` option from xcolor package +* #2331: Fix code-blocks are filled by block in dvi; remove ``xcdraw`` option from + xcolor package * Fix the confval type checker emits warnings if unicode is given to confvals which expects string value * #2360: Fix numref in LaTeX output is broken * #2361: Fix additional paragraphs inside the "compound" directive are indented diff --git a/EXAMPLES b/EXAMPLES index e6d7cedbd..e5d27f747 100644 --- a/EXAMPLES +++ b/EXAMPLES @@ -61,6 +61,7 @@ Documentation using the classic theme * Quex: http://quex.sourceforge.net/doc/html/main.html * Ring programming language: http://ring-lang.sourceforge.net/doc/index.html * Scapy: http://www.secdev.org/projects/scapy/doc/ +* Seaborn: https://stanford.edu/~mwaskom/software/seaborn/ * Segway: http://noble.gs.washington.edu/proj/segway/doc/1.1.0/segway.html * SimPy: http://simpy.readthedocs.org/en/latest/ * SymPy: http://docs.sympy.org/ diff --git a/MANIFEST.in b/MANIFEST.in index bb0be4958..5e95299de 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -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 * diff --git a/Makefile b/Makefile index 02854840e..2828f1a25 100644 --- a/Makefile +++ b/Makefile @@ -6,10 +6,11 @@ PYTHON ?= python DONT_CHECK = -i build -i dist -i sphinx/style/jquery.js \ -i sphinx/pycode/pgen2 -i sphinx/util/smartypants.py \ -i .ropeproject -i doc/_build -i tests/path.py \ - -i tests/coverage.py -i env -i utils/convert.py \ + -i tests/coverage.py -i utils/convert.py \ -i tests/typing_test_data.py \ -i tests/test_autodoc_py35.py \ -i tests/build \ + -i tests/roots/test-warnings/undecodable.rst \ -i sphinx/search/da.py \ -i sphinx/search/de.py \ -i sphinx/search/en.py \ @@ -33,12 +34,15 @@ all: clean-pyc clean-backupfiles style-check test style-check: @$(PYTHON) utils/check_sources.py $(DONT_CHECK) . -clean: clean-pyc clean-patchfiles clean-backupfiles clean-generated +clean: clean-pyc clean-pycache clean-patchfiles clean-backupfiles clean-generated clean-testfiles clean-pyc: find . -name '*.pyc' -exec rm -f {} + find . -name '*.pyo' -exec rm -f {} + +clean-pycache: + find . -name __pycache__ -exec rm -rf {} + + clean-patchfiles: find . -name '*.orig' -exec rm -f {} + find . -name '*.rej' -exec rm -f {} + @@ -50,6 +54,10 @@ clean-backupfiles: clean-generated: rm -f utils/*3.py* +clean-testfiles: + rm -rf tests/build + rm -rf .tox/ + pylint: @pylint --rcfile utils/pylintrc sphinx diff --git a/README.rst b/README.rst index 391d0bd1a..384e2cc6a 100644 --- a/README.rst +++ b/README.rst @@ -33,6 +33,12 @@ Install from cloned source as editable:: pip install -e . +Release signatures +================== + +Releases are signed with `498D6B9E `_ + + Reading the docs ================ diff --git a/doc/_static/bookcover.png b/doc/_static/bookcover.png index 5b521b67b..0a8167fcc 100644 Binary files a/doc/_static/bookcover.png and b/doc/_static/bookcover.png differ diff --git a/doc/_static/pocoo.png b/doc/_static/pocoo.png index 67663b976..1648bb8d7 100644 Binary files a/doc/_static/pocoo.png and b/doc/_static/pocoo.png differ diff --git a/doc/_static/sphinx.png b/doc/_static/sphinx.png index 4bd9c7536..0a103cd3e 100644 Binary files a/doc/_static/sphinx.png and b/doc/_static/sphinx.png differ diff --git a/doc/_themes/sphinx13/static/bodybg.png b/doc/_themes/sphinx13/static/bodybg.png index ebe92f669..6f667b99e 100644 Binary files a/doc/_themes/sphinx13/static/bodybg.png and b/doc/_themes/sphinx13/static/bodybg.png differ diff --git a/doc/_themes/sphinx13/static/footerbg.png b/doc/_themes/sphinx13/static/footerbg.png index df783e2c7..d1bcb009b 100644 Binary files a/doc/_themes/sphinx13/static/footerbg.png and b/doc/_themes/sphinx13/static/footerbg.png differ diff --git a/doc/_themes/sphinx13/static/headerbg.png b/doc/_themes/sphinx13/static/headerbg.png index 22830f99e..522504964 100644 Binary files a/doc/_themes/sphinx13/static/headerbg.png and b/doc/_themes/sphinx13/static/headerbg.png differ diff --git a/doc/_themes/sphinx13/static/listitem.png b/doc/_themes/sphinx13/static/listitem.png index e45715f91..f7f814d00 100644 Binary files a/doc/_themes/sphinx13/static/listitem.png and b/doc/_themes/sphinx13/static/listitem.png differ diff --git a/doc/_themes/sphinx13/static/relbg.png b/doc/_themes/sphinx13/static/relbg.png index 2006af7d2..68a9b77eb 100644 Binary files a/doc/_themes/sphinx13/static/relbg.png and b/doc/_themes/sphinx13/static/relbg.png differ diff --git a/doc/_themes/sphinx13/static/sphinxheader.png b/doc/_themes/sphinx13/static/sphinxheader.png index 12988c3d1..845da4ab9 100644 Binary files a/doc/_themes/sphinx13/static/sphinxheader.png and b/doc/_themes/sphinx13/static/sphinxheader.png differ diff --git a/doc/conf.py b/doc/conf.py index 753ffab4c..f3bf569f8 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -47,7 +47,7 @@ epub_fix_images = False epub_max_image_width = 0 epub_show_urls = 'inline' epub_use_index = False -epub_guide = (('toc', 'contents.html', u'Table of Contents'),) +epub_guide = (('toc', 'contents.xhtml', u'Table of Contents'),) latex_documents = [('contents', 'sphinx.tex', 'Sphinx Documentation', 'Georg Brandl', 'manual', 1)] diff --git a/doc/config.rst b/doc/config.rst index f0a290a23..66d4b9da6 100644 --- a/doc/config.rst +++ b/doc/config.rst @@ -56,7 +56,7 @@ General configuration .. confval:: extensions - A list of strings that are module names of Sphinx extensions. These can be + A list of strings that are module names of :ref:`extensions`. These can be extensions coming with Sphinx (named ``sphinx.ext.*``) or custom ones. Note that you can extend :data:`sys.path` within the conf file if your @@ -870,6 +870,13 @@ that use Sphinx's HTMLWriter class. .. versionadded:: 0.6 +.. confval:: html_sourcelink_suffix + + Suffix to be appended to source links (see :confval:`html_show_sourcelink`), + unless they have this suffix already. Default is ``'.txt'``. + + .. versionadded:: 1.5 + .. confval:: html_use_opensearch If nonempty, an `OpenSearch `_ description file will be @@ -1460,7 +1467,17 @@ the `Dublin Core metadata `_. Options for LaTeX output ------------------------ -These options influence LaTeX output. +These options influence LaTeX output. See further :doc:`latex`. + +.. confval:: latex_engine + + The LaTeX engine to build the docs. The setting can have the following + values: + + * pdflatex -- PDFLaTeX (default) + * xelatex -- XeLaTeX + * lualatex -- LuaLaTeX + * platex -- pLaTeX (default if `language` is 'ja') .. confval:: latex_documents @@ -1568,6 +1585,21 @@ These options influence LaTeX output. value selected the ``'inline'`` display. For backwards compatibility, ``True`` is still accepted. +.. confval:: latex_keep_old_macro_names + + If ``True`` (default) the ``\strong``, ``\code``, ``\bfcode``, ``\email``, + ``\tablecontinued``, ``\titleref``, ``\menuselection``, ``\accelerator``, + ``\crossref``, ``\termref``, and ``\optional`` text styling macros are + pre-defined by Sphinx and may be user-customized by some + ``\renewcommand``'s inserted either via ``'preamble'`` key or :dudir:`raw + ` directive. If ``False``, only ``\sphinxstrong``, + etc... macros are defined (and may be redefined by user). Setting to + ``False`` may help solve macro name conflicts caused by user-added latex + packages. + + .. versionadded:: 1.4.5 + + .. confval:: latex_elements .. versionadded:: 0.5 @@ -1586,6 +1618,15 @@ These options influence LaTeX output. ``'pointsize'`` Point size option of the document class (``'10pt'``, ``'11pt'`` or ``'12pt'``), default ``'10pt'``. + ``'pxunit'`` + the value of the ``px`` when used in image attributes ``width`` and + ``height``. The default value is ``'49336sp'`` which achieves + ``96px=1in`` (``1in = 72.27*65536 = 4736286.72sp``, and all dimensions + in TeX are internally integer multiples of ``sp``). To obtain for + example ``100px=1in``, one can use ``'0.01in'`` but it is more precise + to use ``'47363sp'``. To obtain ``72px=1in``, use ``'1bp'``. + + .. versionadded:: 1.5 ``'babel'`` "babel" package inclusion, default ``'\\usepackage{babel}'``. ``'fontpkg'`` @@ -1608,7 +1649,7 @@ These options influence LaTeX output. .. versionadded:: 1.4 ``'preamble'`` - Additional preamble content, default empty. + Additional preamble content, default empty. See :doc:`latex`. ``'figure_align'`` Latex figure float alignment, default 'htbp' (here, top, bottom, page). Whenever an image doesn't fit into the current page, it will be @@ -1627,7 +1668,7 @@ These options influence LaTeX output. ``'\\usepackage[utf8]{inputenc}'`` when using pdflatex. Otherwise unset. - .. versionchanged:: 1.5 + .. versionchanged:: 1.4.3 Previously ``'\\usepackage[utf8]{inputenc}'`` was used for all compilers. ``'cmappkg'`` @@ -1678,6 +1719,11 @@ These options influence LaTeX output. .. versionadded:: 1.0 + .. versionchanged:: 1.5 + + In Japanese docs(`language` is ``ja``), ``'jreport'`` is used for + ``'howto'`` and ``'jsbooks'`` is used for ``'manual'`` by default. + .. confval:: latex_additional_files A list of file names, relative to the configuration directory, to copy to the @@ -1953,3 +1999,33 @@ Options for the XML builder constructs ``*``, ``?``, ``[...]`` and ``[!...]`` with the feature that these all don't match slashes. A double star ``**`` can be used to match any sequence of characters *including* slashes. + + +.. _cpp-config: + +Options for the C++ domain +-------------------------- + +.. confval:: cpp_index_common_prefix + + A list of prefixes that will be ignored when sorting C++ objects in the global index. + For example ``['awesome_lib::']``. + + .. versionadded:: 1.5 + +.. confval:: cpp_id_attributes + + A list of strings that the parser additionally should accept as attributes. + This can for example be used when attributes have been ``#define`` d for portability. + + .. versionadded:: 1.5 + +.. confval:: cpp_paren_attributes + + A list of strings that the parser additionally should accept as attributes with one argument. + That is, if ``my_align_as`` is in the list, then ``my_align_as(X)`` is parsed as an attribute + for all strings ``X`` that have balanced brances (``()``, ``[]``, and ``{}``). + This can for example be used when attributes have been ``#define`` d for portability. + + .. versionadded:: 1.5 + diff --git a/doc/contents.rst b/doc/contents.rst index a51910b81..79a10493d 100644 --- a/doc/contents.rst +++ b/doc/contents.rst @@ -1,3 +1,4 @@ + .. _contents: Sphinx documentation contents @@ -17,6 +18,7 @@ Sphinx documentation contents intl theming templating + latex extensions extdev/index websupport diff --git a/doc/domains.rst b/doc/domains.rst index 7128067d3..7c23056d8 100644 --- a/doc/domains.rst +++ b/doc/domains.rst @@ -359,6 +359,18 @@ single word, like this:: :param int priority: The priority of the message, can be a number 1-5 +.. versionadded:: 1.5 + +Container types such as lists and dictionaries can be linked automatically +using the following syntax:: + + :type priorities: list(int) + :type priorities: list[int] + :type mapping: dict(str, int) + :type mapping: dict[str, int] + :type point: tuple(float, float) + :type point: tuple[float, float] + .. _python-roles: Cross-referencing Python objects @@ -545,10 +557,10 @@ a visibility statement (``public``, ``private`` or ``protected``). Full and partial template specialisations can be declared:: - .. cpp::class:: template<> \ + .. cpp:class:: template<> \ std::array - .. cpp::class:: template \ + .. cpp:class:: template \ std::array @@ -680,9 +692,9 @@ a visibility statement (``public``, ``private`` or ``protected``). Describe an enumerator, optionally with its value defined, e.g.,:: - .. cpp::enumerator:: MyEnum::myEnumerator + .. cpp:enumerator:: MyEnum::myEnumerator - .. cpp::enumerator:: MyEnum::myOtherEnumerator = 42 + .. cpp:enumerator:: MyEnum::myOtherEnumerator = 42 .. rst:directive:: .. cpp:concept:: template-parameter-list name @@ -972,6 +984,12 @@ References to partial specialisations must always include the template parameter Currently the lookup only succeed if the template parameter identifiers are equal strings. +Configuration Variables +~~~~~~~~~~~~~~~~~~~~~~~ + +See :ref:`cpp-config`. + + The Standard Domain ------------------- diff --git a/doc/ext/doctest.rst b/doc/ext/doctest.rst index 3d4f66a9a..818b86007 100644 --- a/doc/ext/doctest.rst +++ b/doc/ext/doctest.rst @@ -182,7 +182,7 @@ The doctest extension uses the following configuration values: .. confval:: doctest_default_flags By default, these options are enabled: - + - ``ELLIPSIS``, allowing you to put ellipses in the expected output that match anything in the actual output; - ``IGNORE_EXCEPTION_DETAIL``, causing everything following the leftmost diff --git a/doc/ext/example_google.py b/doc/ext/example_google.py index 81a312cfd..34a720e36 100644 --- a/doc/ext/example_google.py +++ b/doc/ext/example_google.py @@ -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. diff --git a/doc/ext/example_google.rst b/doc/ext/example_google.rst index 06508082c..a06f161b9 100644 --- a/doc/ext/example_google.rst +++ b/doc/ext/example_google.rst @@ -9,7 +9,9 @@ Example Google Style Python Docstrings :ref:`example_numpy` -Download: :download:`example_google.py ` +.. only:: builder_html + + Download: :download:`example_google.py ` .. literalinclude:: example_google.py :language: python diff --git a/doc/ext/example_numpy.py b/doc/ext/example_numpy.py index bb91cac82..7a2db94cc 100644 --- a/doc/ext/example_numpy.py +++ b/doc/ext/example_numpy.py @@ -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. diff --git a/doc/ext/example_numpy.rst b/doc/ext/example_numpy.rst index a3b41613e..38d3439c8 100644 --- a/doc/ext/example_numpy.rst +++ b/doc/ext/example_numpy.rst @@ -9,7 +9,9 @@ Example NumPy Style Python Docstrings :ref:`example_google` -Download: :download:`example_numpy.py ` +.. only:: builder_html + + Download: :download:`example_numpy.py ` .. literalinclude:: example_numpy.py :language: python diff --git a/doc/ext/inheritance.rst b/doc/ext/inheritance.rst index dd8d5aa99..bd287aa49 100644 --- a/doc/ext/inheritance.rst +++ b/doc/ext/inheritance.rst @@ -40,7 +40,7 @@ It adds this directive: included. .. versionchanged:: 1.5 - Added ``caption`` option + Added ``caption`` option New config values are: diff --git a/doc/ext/napoleon.rst b/doc/ext/napoleon.rst index 2f2fb4376..ea3e4042f 100644 --- a/doc/ext/napoleon.rst +++ b/doc/ext/napoleon.rst @@ -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 diff --git a/doc/ext/todo.rst b/doc/ext/todo.rst index a809bc665..09abfa9b8 100644 --- a/doc/ext/todo.rst +++ b/doc/ext/todo.rst @@ -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. diff --git a/doc/ext/viewcode.rst b/doc/ext/viewcode.rst index 5bf8eb033..5823090f6 100644 --- a/doc/ext/viewcode.rst +++ b/doc/ext/viewcode.rst @@ -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 `_'s score + becomes worse even if the reader supports. diff --git a/doc/install.rst b/doc/install.rst index 0ecd73609..a2aeaf9cb 100644 --- a/doc/install.rst +++ b/doc/install.rst @@ -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 diff --git a/doc/installpython.jpg b/doc/installpython.jpg index b0e458e40..fff4630ae 100644 Binary files a/doc/installpython.jpg and b/doc/installpython.jpg differ diff --git a/doc/latex.rst b/doc/latex.rst new file mode 100644 index 000000000..826a715c6 --- /dev/null +++ b/doc/latex.rst @@ -0,0 +1,151 @@ +.. highlightlang:: python + +.. _latex: + +LaTeX customization +=================== + +.. module:: latex + :synopsis: LaTeX specifics. + +The *latex* target does not (yet) benefit from pre-prepared themes like the +*html* target does (see :doc:`theming`). + +There are two principal means of setting up customization: + +#. usage of the :ref:`latex-options` as described in :doc:`config`, particularly the + various keys of :confval:`latex_elements`, to modify the loaded packages, + for example:: + + 'fontpkg': '\\usepackage{times}', # can load other font + 'fncychap': '\\usepackage[Bjarne]{fncychap}', # can use other option + + .. tip:: + + It is not mandatory to load *fncychap*. Naturally, without it and in + absence of further customizations, the chapter headings will revert to + LaTeX's default for the *report* class. + +#. usage of LaTeX ``\renewcommand``, ``\renewenvironment``, ``\setlength``, + ``\definecolor`` to modify the defaults from package file :file:`sphinx.sty` + and class files :file:`sphinxhowto.cls` and :file:`sphinxmanual.cls`. If such + definitions are few, they can be located inside the ``'preamble'`` key of + :confval:`latex_elements`. In case of many it may prove more convenient to + assemble them into a specialized file :file:`customizedmacros.tex` and use:: + + 'preamble': '\\makeatletter\\input{customizedmacros.tex}\\makeatother', + + More advanced LaTeX users will set up a style file + :file:`customizedmacros.sty`, which can then be loaded via:: + + 'preamble': '\\usepackage{customizedmacros}', + + The :ref:`build configuration file ` 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`` with + ```` being one of ``strong``, ``bfcode``, ``email``, ``tablecontinued``, + ``titleref``, ``menuselection``, ``accelerator``, ``crossref``, ``termref``, + ``optional``. By default and for backwards compatibility the ``\sphinx`` + expands to ``\`` 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`` with ```` 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 ```` one of + :dudir:`warning`, :dudir:`caution`, :dudir:`attention`, + :dudir:`danger`, :dudir:`error`, the colours + *sphinxbordercolor* and *sphinxbgcolor* can be + re-defined using ``\definecolor`` command. The + ``\sphinxborder`` 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 ```` 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``. 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. diff --git a/doc/markup/inline.rst b/doc/markup/inline.rst index 0e825b66a..ae47f820d 100644 --- a/doc/markup/inline.rst +++ b/doc/markup/inline.rst @@ -200,6 +200,12 @@ Referencing downloadable files The ``example.py`` file will be copied to the output directory, and a suitable link generated to it. + Not to show unavailable download links, you should wrap whole paragraphs that + have this role:: + + .. only:: builder_html + + See :download:`this example script <../example.py>`. Cross-referencing figures by figure number ------------------------------------------ diff --git a/doc/more.png b/doc/more.png index a27a0fcba..97553a8b7 100644 Binary files a/doc/more.png and b/doc/more.png differ diff --git a/doc/pythonorg.png b/doc/pythonorg.png index 32f0787d1..cf9ccbbdb 100644 Binary files a/doc/pythonorg.png and b/doc/pythonorg.png differ diff --git a/doc/rest.rst b/doc/rest.rst index 293b2ea02..7b2b92ddc 100644 --- a/doc/rest.rst +++ b/doc/rest.rst @@ -363,8 +363,9 @@ directory on building (e.g. the ``_static`` directory for HTML output.) Interpretation of image size options (``width`` and ``height``) is as follows: if the size has no unit or the unit is pixels, the given size will only be -respected for output channels that support pixels (i.e. not in LaTeX output). -Other units (like ``pt`` for points) will be used for HTML and LaTeX output. +respected for output channels that support pixels. Other units (like ``pt`` +for points) will be used for HTML and LaTeX output (the latter replaces ``pt`` +by ``bp`` as this is the TeX unit such that ``72bp=1in``). Sphinx extends the standard docutils behavior by allowing an asterisk for the extension:: @@ -386,6 +387,9 @@ Note that image file names should not contain spaces. .. versionchanged:: 0.6 Image paths can now be absolute. +.. versionchanged:: 1.5 + latex target supports pixels (default is ``96px=1in``). + Footnotes --------- diff --git a/doc/themes/agogo.png b/doc/themes/agogo.png index 453a1f7dc..5a09cb96c 100644 Binary files a/doc/themes/agogo.png and b/doc/themes/agogo.png differ diff --git a/doc/themes/alabaster.png b/doc/themes/alabaster.png index 6e02c35ca..4a49c1ad0 100644 Binary files a/doc/themes/alabaster.png and b/doc/themes/alabaster.png differ diff --git a/doc/themes/bizstyle.png b/doc/themes/bizstyle.png index 4deae9a79..e19fb6b34 100644 Binary files a/doc/themes/bizstyle.png and b/doc/themes/bizstyle.png differ diff --git a/doc/themes/classic.png b/doc/themes/classic.png index 6989ebe9b..3b3c9cbd8 100644 Binary files a/doc/themes/classic.png and b/doc/themes/classic.png differ diff --git a/doc/themes/fullsize/agogo.png b/doc/themes/fullsize/agogo.png index bfdba3a17..106a16cea 100644 Binary files a/doc/themes/fullsize/agogo.png and b/doc/themes/fullsize/agogo.png differ diff --git a/doc/themes/fullsize/alabaster.png b/doc/themes/fullsize/alabaster.png index 3e026c999..5eca20912 100644 Binary files a/doc/themes/fullsize/alabaster.png and b/doc/themes/fullsize/alabaster.png differ diff --git a/doc/themes/fullsize/bizstyle.png b/doc/themes/fullsize/bizstyle.png index d917e2ff2..586064765 100644 Binary files a/doc/themes/fullsize/bizstyle.png and b/doc/themes/fullsize/bizstyle.png differ diff --git a/doc/themes/fullsize/classic.png b/doc/themes/fullsize/classic.png index 9c00f6899..269dab22f 100644 Binary files a/doc/themes/fullsize/classic.png and b/doc/themes/fullsize/classic.png differ diff --git a/doc/themes/fullsize/haiku.png b/doc/themes/fullsize/haiku.png index 8d807f4e1..707d2bfec 100644 Binary files a/doc/themes/fullsize/haiku.png and b/doc/themes/fullsize/haiku.png differ diff --git a/doc/themes/fullsize/nature.png b/doc/themes/fullsize/nature.png index 02d8743b3..00730c0a5 100644 Binary files a/doc/themes/fullsize/nature.png and b/doc/themes/fullsize/nature.png differ diff --git a/doc/themes/fullsize/pyramid.png b/doc/themes/fullsize/pyramid.png index 961cb896c..3b9d04d13 100644 Binary files a/doc/themes/fullsize/pyramid.png and b/doc/themes/fullsize/pyramid.png differ diff --git a/doc/themes/fullsize/scrolls.png b/doc/themes/fullsize/scrolls.png index 4e5c45f21..8a1c1faf5 100644 Binary files a/doc/themes/fullsize/scrolls.png and b/doc/themes/fullsize/scrolls.png differ diff --git a/doc/themes/fullsize/sphinx_rtd_theme.png b/doc/themes/fullsize/sphinx_rtd_theme.png index 4a3d74c88..95cff4ccd 100644 Binary files a/doc/themes/fullsize/sphinx_rtd_theme.png and b/doc/themes/fullsize/sphinx_rtd_theme.png differ diff --git a/doc/themes/fullsize/sphinxdoc.png b/doc/themes/fullsize/sphinxdoc.png index b74633452..eb498e3e8 100644 Binary files a/doc/themes/fullsize/sphinxdoc.png and b/doc/themes/fullsize/sphinxdoc.png differ diff --git a/doc/themes/fullsize/traditional.png b/doc/themes/fullsize/traditional.png index da69efe12..07ad00875 100644 Binary files a/doc/themes/fullsize/traditional.png and b/doc/themes/fullsize/traditional.png differ diff --git a/doc/themes/haiku.png b/doc/themes/haiku.png index 78a2570c4..4530debb9 100644 Binary files a/doc/themes/haiku.png and b/doc/themes/haiku.png differ diff --git a/doc/themes/nature.png b/doc/themes/nature.png index cbe773d5c..ad39b32b7 100644 Binary files a/doc/themes/nature.png and b/doc/themes/nature.png differ diff --git a/doc/themes/pyramid.png b/doc/themes/pyramid.png index eb13cd5f2..72749dd6b 100644 Binary files a/doc/themes/pyramid.png and b/doc/themes/pyramid.png differ diff --git a/doc/themes/scrolls.png b/doc/themes/scrolls.png index 30ccc8d49..1a117379f 100644 Binary files a/doc/themes/scrolls.png and b/doc/themes/scrolls.png differ diff --git a/doc/themes/sphinx_rtd_theme.png b/doc/themes/sphinx_rtd_theme.png index e13f52b04..7c3b7ae05 100644 Binary files a/doc/themes/sphinx_rtd_theme.png and b/doc/themes/sphinx_rtd_theme.png differ diff --git a/doc/themes/sphinxdoc.png b/doc/themes/sphinxdoc.png index 31512d8d8..587363e61 100644 Binary files a/doc/themes/sphinxdoc.png and b/doc/themes/sphinxdoc.png differ diff --git a/doc/themes/traditional.png b/doc/themes/traditional.png index 5ff44f869..9820fd0ea 100644 Binary files a/doc/themes/traditional.png and b/doc/themes/traditional.png differ diff --git a/doc/theming.rst b/doc/theming.rst index df0755f1f..ee45df52d 100644 --- a/doc/theming.rst +++ b/doc/theming.rst @@ -81,6 +81,8 @@ that has to return the directory with themes in it:: Builtin themes -------------- +.. cssclass:: longtable + +--------------------+--------------------+ | **Theme overview** | | +--------------------+--------------------+ diff --git a/doc/translation.png b/doc/translation.png index 347e287f6..11f3d02cd 100644 Binary files a/doc/translation.png and b/doc/translation.png differ diff --git a/doc/tutorial.rst b/doc/tutorial.rst index 385746f72..bced21ade 100644 --- a/doc/tutorial.rst +++ b/doc/tutorial.rst @@ -300,12 +300,17 @@ features of intersphinx. More topics to be covered ------------------------- -- Other extensions (math, viewcode, doctest) +- :doc:`Other extensions `: + + * :doc:`ext/math`, + * :doc:`ext/viewcode`, + * :doc:`ext/doctest`, + * ... - Static files -- Selecting a theme -- Templating +- :doc:`Selecting a theme ` +- :ref:`Templating ` - Using extensions -- Writing extensions +- :ref:`Writing extensions ` .. rubric:: Footnotes diff --git a/setup.cfg b/setup.cfg index 2d2f3b535..a65719461 100644 --- a/setup.cfg +++ b/setup.cfg @@ -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 diff --git a/setup.py b/setup.py index 3d792b2dc..c1aa346ba 100644 --- a/setup.py +++ b/setup.py @@ -64,6 +64,7 @@ extras_require = { 'nose', 'mock', # it would be better for 'test:python_version in "2.6,2.7"' 'simplejson', # better: 'test:platform_python_implementation=="PyPy"' + 'html5lib', ], } @@ -137,11 +138,8 @@ else: domain + '.js')) for js_file, (locale, po_file) in zip(js_files, po_files): - infile = open(po_file, 'r') - try: + with open(po_file, 'r') as infile: catalog = read_po(infile, locale) - finally: - infile.close() if catalog.fuzzy and not self.use_fuzzy: continue @@ -158,8 +156,7 @@ else: msgid = msgid[0] jscatalog[msgid] = message.string - outfile = open(js_file, 'wb') - try: + with open(js_file, 'wb') as outfile: outfile.write('Documentation.addTranslations(') dump(dict( messages=jscatalog, @@ -167,8 +164,6 @@ else: locale=str(catalog.locale) ), outfile, sort_keys=True) outfile.write(');') - finally: - outfile.close() cmdclass['compile_catalog'] = compile_catalog_plusjs diff --git a/sphinx/application.py b/sphinx/application.py index e82719d77..d8cae8435 100644 --- a/sphinx/application.py +++ b/sphinx/application.py @@ -32,17 +32,16 @@ from sphinx.roles import XRefRole from sphinx.config import Config from sphinx.errors import SphinxError, SphinxWarning, ExtensionError, \ VersionRequirementError, ConfigError -from sphinx.domains import ObjType, BUILTIN_DOMAINS +from sphinx.domains import ObjType from sphinx.domains.std import GenericObject, Target, StandardDomain -from sphinx.builders import BUILTIN_BUILDERS from sphinx.environment import BuildEnvironment from sphinx.io import SphinxStandaloneReader -from sphinx.util import pycompat # noqa: imported for side-effects +from sphinx.util import pycompat # noqa: F401 from sphinx.util import import_object from sphinx.util.tags import Tags from sphinx.util.osutil import ENOENT from sphinx.util.logging import is_suppressed_warning -from sphinx.util.console import bold, lightgray, darkgray, darkgreen, \ +from sphinx.util.console import bold, lightgray, darkgray, darkred, darkgreen, \ term_width_line from sphinx.util.i18n import find_catalog_source_files @@ -65,10 +64,44 @@ events = { 'html-page-context': 'pagename, context, doctree or None', 'build-finished': 'exception', } +builtin_extensions = ( + 'sphinx.builders.applehelp', + 'sphinx.builders.changes', + 'sphinx.builders.epub', + 'sphinx.builders.epub3', + 'sphinx.builders.devhelp', + 'sphinx.builders.dummy', + 'sphinx.builders.gettext', + 'sphinx.builders.html', + 'sphinx.builders.htmlhelp', + 'sphinx.builders.latex', + 'sphinx.builders.linkcheck', + 'sphinx.builders.manpage', + 'sphinx.builders.qthelp', + 'sphinx.builders.texinfo', + 'sphinx.builders.text', + 'sphinx.builders.websupport', + 'sphinx.builders.xml', + 'sphinx.domains.c', + 'sphinx.domains.cpp', + 'sphinx.domains.javascript', + 'sphinx.domains.python', + 'sphinx.domains.rst', + 'sphinx.domains.std', + 'sphinx.directives', + 'sphinx.directives.code', + 'sphinx.directives.other', + 'sphinx.directives.patches', + 'sphinx.roles', +) CONFIG_FILENAME = 'conf.py' ENV_PICKLE_FILENAME = 'environment.pickle' +# list of deprecated extensions. Keys are extension name. +# Values are Sphinx version that merge the extension. +EXTENSION_BLACKLIST = {"sphinxjp.themecore": "1.2"} + class Sphinx(object): @@ -83,9 +116,9 @@ class Sphinx(object): self._additional_source_parsers = {} self._listeners = {} self._setting_up_extension = ['?'] - self.domains = BUILTIN_DOMAINS.copy() + self.domains = {} self.buildername = buildername - self.builderclasses = BUILTIN_BUILDERS.copy() + self.builderclasses = {} self.builder = None self.env = None self.enumerable_nodes = {} @@ -148,6 +181,10 @@ class Sphinx(object): if self.confdir is None: self.confdir = self.srcdir + # load all built-in extension modules + for extension in builtin_extensions: + self.setup_extension(extension) + # extension loading support for alabaster theme # self.config.html_theme is not set from conf.py at here # for now, sphinx always load a 'alabaster' extension. @@ -188,6 +225,10 @@ class Sphinx(object): 'version %s and therefore cannot be built with the ' 'loaded version (%s).' % (extname, needs_ver, has_ver)) + # check primary_domain if requested + if self.config.primary_domain and self.config.primary_domain not in self.domains: + self.warn('primary_domain %r not found, ignored.' % self.config.primary_domain) + # set up translation infrastructure self._init_i18n() # check all configuration values for permissible types @@ -235,8 +276,8 @@ class Sphinx(object): def _init_env(self, freshenv): if freshenv: - self.env = BuildEnvironment(self.srcdir, self.doctreedir, - self.config) + self.env = BuildEnvironment(self.srcdir, self.doctreedir, self.config) + self.env.set_warnfunc(self.warn) self.env.find_files(self.config) for domain in self.domains.keys(): self.env.domains[domain] = self.domains[domain](self.env) @@ -245,6 +286,7 @@ class Sphinx(object): self.info(bold('loading pickled environment... '), nonl=True) self.env = BuildEnvironment.frompickle( self.srcdir, self.config, path.join(self.doctreedir, ENV_PICKLE_FILENAME)) + self.env.set_warnfunc(self.warn) self.env.domains = {} for domain in self.domains.keys(): # this can raise if the data version doesn't fit @@ -257,8 +299,6 @@ class Sphinx(object): self.info('failed: %s' % err) return self._init_env(freshenv=True) - self.env.set_warnfunc(self.warn) - def _init_builder(self, buildername): if buildername is None: print('No builder selected, using default: html', file=self._status) @@ -267,11 +307,6 @@ class Sphinx(object): raise SphinxError('Builder name %s not registered' % buildername) builderclass = self.builderclasses[buildername] - if isinstance(builderclass, tuple): - # builtin builder - mod, cls = builderclass - builderclass = getattr( - __import__('sphinx.builders.' + mod, None, None, [cls]), cls) self.builder = builderclass(self) self.emit('builder-inited') @@ -326,7 +361,8 @@ class Sphinx(object): wfile.flush() self.messagelog.append(message) - def warn(self, message, location=None, prefix='WARNING: ', type=None, subtype=None): + def warn(self, message, location=None, prefix='WARNING: ', + type=None, subtype=None, colorfunc=darkred): """Emit a warning. If *location* is given, it should either be a tuple of (docname, lineno) @@ -356,7 +392,7 @@ class Sphinx(object): if self.warningiserror: raise SphinxWarning(warntext) self._warncount += 1 - self._log(warntext, self._warning, True) + self._log(colorfunc(warntext), self._warning, True) def info(self, message='', nonl=False): """Emit an informational message. @@ -460,6 +496,11 @@ class Sphinx(object): self.debug('[app] setting up extension: %r', extension) if extension in self._extensions: return + if extension in EXTENSION_BLACKLIST: + self.warn('the extension %r was already merged with Sphinx since version %s; ' + 'this extension is ignored.' % ( + extension, EXTENSION_BLACKLIST[extension])) + return self._setting_up_extension.append(extension) try: mod = __import__(extension, None, None, ['setup']) @@ -557,13 +598,9 @@ class Sphinx(object): raise ExtensionError('Builder class %s has no "name" attribute' % builder) if builder.name in self.builderclasses: - if isinstance(self.builderclasses[builder.name], tuple): - raise ExtensionError('Builder %r is a builtin builder' % - builder.name) - else: - raise ExtensionError( - 'Builder %r already exists (in module %s)' % ( - builder.name, self.builderclasses[builder.name].__module__)) + raise ExtensionError( + 'Builder %r already exists (in module %s)' % ( + builder.name, self.builderclasses[builder.name].__module__)) self.builderclasses[builder.name] = builder def add_config_value(self, name, default, rebuild, types=()): @@ -764,8 +801,7 @@ class Sphinx(object): def add_latex_package(self, packagename, options=None): self.debug('[app] adding latex package: %r', packagename) - from sphinx.builders.latex import LaTeXBuilder - LaTeXBuilder.usepackages.append((packagename, options)) + self.builder.usepackages.append((packagename, options)) def add_lexer(self, alias, lexer): self.debug('[app] adding lexer: %r', (alias, lexer)) diff --git a/sphinx/builders/__init__.py b/sphinx/builders/__init__.py index 8863050ba..fe0c9c665 100644 --- a/sphinx/builders/__init__.py +++ b/sphinx/builders/__init__.py @@ -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'), -} diff --git a/sphinx/builders/applehelp.py b/sphinx/builders/applehelp.py index d3ad861dc..7db086953 100644 --- a/sphinx/builders/applehelp.py +++ b/sphinx/builders/applehelp.py @@ -13,14 +13,16 @@ from __future__ import print_function import codecs import pipes -from os import path +from os import path, environ +import shlex from sphinx.builders.html import StandaloneHTMLBuilder -from sphinx.util import copy_static_entry -from sphinx.util.osutil import copyfile, ensuredir +from sphinx.config import string_classes +from sphinx.util.osutil import copyfile, ensuredir, make_filename from sphinx.util.console import bold +from sphinx.util.fileutil import copy_asset from sphinx.util.pycompat import htmlescape -from sphinx.util.matching import compile_matchers +from sphinx.util.matching import Matcher from sphinx.errors import SphinxError import plistlib @@ -84,6 +86,7 @@ class AppleHelpBuilder(StandaloneHTMLBuilder): super(AppleHelpBuilder, self).init() # the output files for HTML help must be .html only self.out_suffix = '.html' + self.link_suffix = '.html' if self.config.applehelp_bundle_id is None: raise SphinxError('You must set applehelp_bundle_id before ' @@ -104,17 +107,15 @@ class AppleHelpBuilder(StandaloneHTMLBuilder): self.finish_tasks.add_task(self.build_helpbook) def copy_localized_files(self): - source_dir = path.join(self.confdir, - self.config.applehelp_locale + '.lproj') + source_dir = path.join(self.confdir, self.config.applehelp_locale + '.lproj') target_dir = self.outdir if path.isdir(source_dir): self.info(bold('copying localized files... '), nonl=True) - ctx = self.globalcontext.copy() - matchers = compile_matchers(self.config.exclude_patterns) - copy_static_entry(source_dir, target_dir, self, ctx, - exclude_matchers=matchers) + excluded = Matcher(self.config.exclude_patterns + ['**/.*']) + copy_asset(source_dir, target_dir, excluded, + context=self.globalcontext, renderer=self.templates) self.info('done') @@ -213,16 +214,19 @@ class AppleHelpBuilder(StandaloneHTMLBuilder): self.warn('you will need to index this help book with:\n %s' % (' '.join([pipes.quote(arg) for arg in args]))) else: - p = subprocess.Popen(args, - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT) + try: + p = subprocess.Popen(args, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) - output = p.communicate()[0] + output = p.communicate()[0] - if p.returncode != 0: - raise AppleHelpIndexerFailed(output) - else: - self.info('done') + if p.returncode != 0: + raise AppleHelpIndexerFailed(output) + else: + self.info('done') + except OSError: + raise AppleHelpIndexerFailed('Command not found: %s' % args[0]) # If we've been asked to, sign the bundle if self.config.applehelp_codesign_identity: @@ -244,13 +248,48 @@ class AppleHelpBuilder(StandaloneHTMLBuilder): self.warn('you will need to sign this help book with:\n %s' % (' '.join([pipes.quote(arg) for arg in args]))) else: - p = subprocess.Popen(args, - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT) + try: + p = subprocess.Popen(args, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) - output = p.communicate()[0] + output = p.communicate()[0] - if p.returncode != 0: - raise AppleHelpCodeSigningFailed(output) - else: - self.info('done') + if p.returncode != 0: + raise AppleHelpCodeSigningFailed(output) + else: + self.info('done') + except OSError: + raise AppleHelpCodeSigningFailed('Command not found: %s' % args[0]) + + +def setup(app): + app.setup_extension('sphinx.builders.html') + app.add_builder(AppleHelpBuilder) + + app.add_config_value('applehelp_bundle_name', + lambda self: make_filename(self.project), 'applehelp') + app.add_config_value('applehelp_bundle_id', None, 'applehelp', string_classes) + app.add_config_value('applehelp_dev_region', 'en-us', 'applehelp') + app.add_config_value('applehelp_bundle_version', '1', 'applehelp') + app.add_config_value('applehelp_icon', None, 'applehelp', string_classes) + app.add_config_value('applehelp_kb_product', + lambda self: '%s-%s' % (make_filename(self.project), self.release), + 'applehelp') + app.add_config_value('applehelp_kb_url', None, 'applehelp', string_classes) + app.add_config_value('applehelp_remote_url', None, 'applehelp', string_classes) + app.add_config_value('applehelp_index_anchors', False, 'applehelp', string_classes) + app.add_config_value('applehelp_min_term_length', None, 'applehelp', string_classes) + app.add_config_value('applehelp_stopwords', + lambda self: self.language or 'en', 'applehelp') + app.add_config_value('applehelp_locale', lambda self: self.language or 'en', 'applehelp') + app.add_config_value('applehelp_title', lambda self: self.project + ' Help', 'applehelp') + app.add_config_value('applehelp_codesign_identity', + lambda self: environ.get('CODE_SIGN_IDENTITY', None), + 'applehelp'), + app.add_config_value('applehelp_codesign_flags', + lambda self: shlex.split(environ.get('OTHER_CODE_SIGN_FLAGS', '')), + 'applehelp'), + app.add_config_value('applehelp_indexer_path', '/usr/bin/hiutil', 'applehelp') + app.add_config_value('applehelp_codesign_path', '/usr/bin/codesign', 'applehelp') + app.add_config_value('applehelp_disable_external_tools', False, None) diff --git a/sphinx/builders/changes.py b/sphinx/builders/changes.py index ed9edc403..1bccb67d9 100644 --- a/sphinx/builders/changes.py +++ b/sphinx/builders/changes.py @@ -15,12 +15,12 @@ from os import path from six import iteritems from sphinx import package_dir -from sphinx.util import copy_static_entry from sphinx.locale import _ from sphinx.theming import Theme from sphinx.builders import Builder from sphinx.util.osutil import ensuredir, os_path from sphinx.util.console import bold +from sphinx.util.fileutil import copy_asset_file from sphinx.util.pycompat import htmlescape @@ -138,12 +138,10 @@ class ChangesBuilder(Builder): f.write(self.templates.render('changes/rstsource.html', ctx)) themectx = dict(('theme_' + key, val) for (key, val) in iteritems(self.theme.get_options({}))) - copy_static_entry(path.join(package_dir, 'themes', 'default', - 'static', 'default.css_t'), - self.outdir, self, themectx) - copy_static_entry(path.join(package_dir, 'themes', 'basic', - 'static', 'basic.css'), - self.outdir, self) + copy_asset_file(path.join(package_dir, 'themes', 'default', 'static', 'default.css_t'), + self.outdir, context=themectx, renderer=self.templates) + copy_asset_file(path.join(package_dir, 'themes', 'basic', 'static', 'basic.css'), + self.outdir) def hl(self, text, version): text = htmlescape(text) @@ -154,3 +152,7 @@ class ChangesBuilder(Builder): def finish(self): pass + + +def setup(app): + app.add_builder(ChangesBuilder) diff --git a/sphinx/builders/devhelp.py b/sphinx/builders/devhelp.py index eb3e997d8..0f88e9f38 100644 --- a/sphinx/builders/devhelp.py +++ b/sphinx/builders/devhelp.py @@ -18,6 +18,7 @@ from os import path from docutils import nodes from sphinx import addnodes +from sphinx.util.osutil import make_filename from sphinx.builders.html import StandaloneHTMLBuilder try: @@ -59,6 +60,7 @@ class DevhelpBuilder(StandaloneHTMLBuilder): def init(self): StandaloneHTMLBuilder.init(self) self.out_suffix = '.html' + self.link_suffix = '.html' def handle_finish(self): self.build_devhelp(self.outdir, self.config.devhelp_basename) @@ -129,3 +131,10 @@ class DevhelpBuilder(StandaloneHTMLBuilder): # Dump the XML file with comp_open(path.join(outdir, outname + '.devhelp'), 'w') as f: tree.write(f, 'utf-8') + + +def setup(app): + app.setup_extension('sphinx.builders.html') + app.add_builder(DevhelpBuilder) + + app.add_config_value('devhelp_basename', lambda self: make_filename(self.project), None) diff --git a/sphinx/builders/dummy.py b/sphinx/builders/dummy.py index 75b834c2b..b119d9687 100644 --- a/sphinx/builders/dummy.py +++ b/sphinx/builders/dummy.py @@ -34,3 +34,7 @@ class DummyBuilder(Builder): def finish(self): pass + + +def setup(app): + app.add_builder(DummyBuilder) diff --git a/sphinx/builders/epub.py b/sphinx/builders/epub.py index 349574ae0..ffe33e1ed 100644 --- a/sphinx/builders/epub.py +++ b/sphinx/builders/epub.py @@ -29,7 +29,7 @@ from docutils import nodes from sphinx import addnodes from sphinx.builders.html import StandaloneHTMLBuilder from sphinx.util.i18n import format_date -from sphinx.util.osutil import ensuredir, copyfile, EEXIST +from sphinx.util.osutil import ensuredir, copyfile, make_filename, EEXIST from sphinx.util.smartypants import sphinx_smarty_pants as ssp from sphinx.util.console import brown @@ -113,7 +113,7 @@ COVER_TEMPLATE = u'''\ ''' -COVERPAGE_NAME = u'epub-cover.html' +COVERPAGE_NAME = u'epub-cover.xhtml' FILE_TEMPLATE = u'''\ +''' + LINK_TARGET_TEMPLATE = u' [%(uri)s]' FOOTNOTE_LABEL_TEMPLATE = u'#%d' @@ -143,7 +147,7 @@ GUIDE_TITLES = { } MEDIA_TYPES = { - '.html': 'application/xhtml+xml', + '.xhtml': 'application/xhtml+xml', '.css': 'text/css', '.png': 'image/png', '.gif': 'image/gif', @@ -152,6 +156,7 @@ MEDIA_TYPES = { '.jpeg': 'image/jpeg', '.otf': 'application/x-font-otf', '.ttf': 'application/x-font-ttf', + '.woff': 'application/font-woff', } VECTOR_GRAPHICS_EXTENSIONS = ('.svg',) @@ -183,6 +188,11 @@ class EpubBuilder(StandaloneHTMLBuilder): add_permalinks = False # don't add sidebar etc. embedded = True + # disable download role + download_support = False + + # don't generate search index or include search page + search = False mimetype_template = MIMETYPE_TEMPLATE container_template = CONTAINER_TEMPLATE @@ -197,6 +207,7 @@ class EpubBuilder(StandaloneHTMLBuilder): spine_template = SPINE_TEMPLATE guide_template = GUIDE_TEMPLATE toctree_template = TOCTREE_TEMPLATE + doctype = DOCTYPE link_target_template = LINK_TARGET_TEMPLATE css_link_target_class = CSS_LINK_TARGET_CLASS guide_titles = GUIDE_TITLES @@ -206,7 +217,8 @@ class EpubBuilder(StandaloneHTMLBuilder): def init(self): StandaloneHTMLBuilder.init(self) # the output files for epub must be .html only - self.out_suffix = '.html' + self.out_suffix = '.xhtml' + self.link_suffix = '.xhtml' self.playorder = 0 self.tocid = 0 @@ -276,7 +288,7 @@ class EpubBuilder(StandaloneHTMLBuilder): """ refnodes.insert(0, { 'level': 1, - 'refuri': self.esc(self.config.master_doc + '.html'), + 'refuri': self.esc(self.config.master_doc + self.out_suffix), 'text': ssp(self.esc( self.env.titles[self.config.master_doc].astext())) }) @@ -471,6 +483,9 @@ class EpubBuilder(StandaloneHTMLBuilder): else: super(EpubBuilder, self).copy_image_files() + def copy_download_files(self): + pass + def handle_page(self, pagename, addctx, templatename='page.html', outfilename=None, event_arg=None): """Create a rendered page. @@ -480,6 +495,7 @@ class EpubBuilder(StandaloneHTMLBuilder): """ if pagename.startswith('genindex'): self.fix_genindex(addctx['genindexentries']) + addctx['doctype'] = self.doctype StandaloneHTMLBuilder.handle_page(self, pagename, addctx, templatename, outfilename, event_arg) @@ -760,3 +776,33 @@ class EpubBuilder(StandaloneHTMLBuilder): fp = path.join(outdir, file) epub.write(fp, file, zipfile.ZIP_DEFLATED) epub.close() + + +def setup(app): + app.setup_extension('sphinx.builders.html') + app.add_builder(EpubBuilder) + + # config values + app.add_config_value('epub_basename', lambda self: make_filename(self.project), None) + app.add_config_value('epub_theme', 'epub', 'html') + app.add_config_value('epub_theme_options', {}, 'html') + app.add_config_value('epub_title', lambda self: self.html_title, 'html') + app.add_config_value('epub_author', 'unknown', 'html') + app.add_config_value('epub_language', lambda self: self.language or 'en', 'html') + app.add_config_value('epub_publisher', 'unknown', 'html') + app.add_config_value('epub_copyright', lambda self: self.copyright, 'html') + app.add_config_value('epub_identifier', 'unknown', 'html') + app.add_config_value('epub_scheme', 'unknown', 'html') + app.add_config_value('epub_uid', 'unknown', 'env') + app.add_config_value('epub_cover', (), 'env') + app.add_config_value('epub_guide', (), 'env') + app.add_config_value('epub_pre_files', [], 'env') + app.add_config_value('epub_post_files', [], 'env') + app.add_config_value('epub_exclude_files', [], 'env') + app.add_config_value('epub_tocdepth', 3, 'env') + app.add_config_value('epub_tocdup', True, 'env') + app.add_config_value('epub_tocscope', 'default', 'env') + app.add_config_value('epub_fix_images', False, 'env') + app.add_config_value('epub_max_image_width', 0, 'env') + app.add_config_value('epub_show_urls', 'inline', 'html') + app.add_config_value('epub_use_index', lambda self: self.html_use_index, 'html') diff --git a/sphinx/builders/epub3.py b/sphinx/builders/epub3.py index b243486f6..fc15a1c46 100644 --- a/sphinx/builders/epub3.py +++ b/sphinx/builders/epub3.py @@ -13,6 +13,7 @@ import codecs from os import path +from sphinx.config import string_classes from sphinx.builders.epub import EpubBuilder @@ -73,7 +74,6 @@ PACKAGE_DOC_TEMPLATE = u'''\ %(files)s - %(spine)s @@ -82,6 +82,9 @@ PACKAGE_DOC_TEMPLATE = u'''\ ''' +DOCTYPE = u''' +''' + # The epub3 publisher @@ -99,6 +102,7 @@ class Epub3Builder(EpubBuilder): navlist_template = NAVLIST_TEMPLATE navlist_indent = NAVLIST_INDENT content_template = PACKAGE_DOC_TEMPLATE + doctype = DOCTYPE # Finish by building the epub file def handle_finish(self): @@ -209,3 +213,12 @@ class Epub3Builder(EpubBuilder): # Add nav.xhtml to epub file self.files.append(outname) + + +def setup(app): + app.setup_extension('sphinx.builders.epub') + app.add_builder(Epub3Builder) + + app.add_config_value('epub3_description', '', 'epub3', string_classes) + app.add_config_value('epub3_contributor', 'unknown', 'epub3', string_classes) + app.add_config_value('epub3_page_progression_direction', 'ltr', 'epub3', string_classes) diff --git a/sphinx/builders/gettext.py b/sphinx/builders/gettext.py index c8f4dab4f..aa9400575 100644 --- a/sphinx/builders/gettext.py +++ b/sphinx/builders/gettext.py @@ -135,7 +135,7 @@ tzdelta = datetime.fromtimestamp(timestamp) - \ source_date_epoch = getenv('SOURCE_DATE_EPOCH') if source_date_epoch is not None: timestamp = float(source_date_epoch) - tzdelta = 0 + tzdelta = timedelta(0) class LocalTimeZone(tzinfo): @@ -233,3 +233,13 @@ class MessageCatalogBuilder(I18nBuilder): replace('"', r'\"'). \ replace('\n', '\\n"\n"') pofile.write('msgid "%s"\nmsgstr ""\n\n' % message) + + +def setup(app): + app.add_builder(MessageCatalogBuilder) + + app.add_config_value('gettext_compact', True, 'gettext') + app.add_config_value('gettext_location', True, 'gettext') + app.add_config_value('gettext_uuid', False, 'gettext') + app.add_config_value('gettext_auto_build', True, 'env') + app.add_config_value('gettext_additional_targets', [], 'env') diff --git a/sphinx/builders/html.py b/sphinx/builders/html.py index 63ccdd66c..2cb12609b 100644 --- a/sphinx/builders/html.py +++ b/sphinx/builders/html.py @@ -27,13 +27,15 @@ from docutils.frontend import OptionParser from docutils.readers.doctree import Reader as DoctreeReader from sphinx import package_dir, __display_version__ -from sphinx.util import jsonimpl, copy_static_entry, copy_extra_entry +from sphinx.util import jsonimpl from sphinx.util.i18n import format_date from sphinx.util.osutil import SEP, os_path, relative_uri, ensuredir, \ movefile, copyfile from sphinx.util.nodes import inline_all_toctrees -from sphinx.util.matching import patmatch, compile_matchers -from sphinx.locale import _ +from sphinx.util.fileutil import copy_asset +from sphinx.util.matching import patmatch, Matcher, DOTFILES +from sphinx.config import string_classes +from sphinx.locale import _, l_ from sphinx.search import js_index from sphinx.theming import Theme from sphinx.builders import Builder @@ -80,6 +82,7 @@ class StandaloneHTMLBuilder(Builder): add_permalinks = True embedded = False # for things like HTML help or Qt help: suppresses sidebar search = True # for things like HTML help and Apple help: suppress search + download_support = True # enable download role # This is a class attribute because it is mutated by Sphinx.add_javascript. script_files = ['_static/jquery.js', '_static/underscore.js', @@ -339,6 +342,7 @@ class StandaloneHTMLBuilder(Builder): show_sphinx = self.config.html_show_sphinx, has_source = self.config.html_copy_source, show_source = self.config.html_show_sourcelink, + sourcelink_suffix = self.config.html_sourcelink_suffix, file_suffix = self.out_suffix, script_files = self.script_files, language = self.config.language, @@ -402,15 +406,21 @@ class StandaloneHTMLBuilder(Builder): # title rendered as HTML title = self.env.longtitles.get(docname) title = title and self.render_partial(title)['title'] or '' + + # Suffix for the document + source_suffix = path.splitext(self.env.doc2path(docname))[1] + # the name for the copied source - sourcename = self.config.html_copy_source and docname + '.txt' or '' + if self.config.html_copy_source: + sourcename = docname + source_suffix + if source_suffix != self.config.html_sourcelink_suffix: + sourcename += self.config.html_sourcelink_suffix + else: + sourcename = '' # metadata for the document meta = self.env.metadata.get(docname) - # Suffix for the document - source_suffix = '.' + self.env.doc2path(docname).split('.')[-1] - # local TOC and global TOC tree self_toc = self.env.get_toc_for(docname, self) toc = self.render_partial(self_toc)['fragment'] @@ -581,9 +591,8 @@ class StandaloneHTMLBuilder(Builder): self.info(bold('copying static files... '), nonl=True) ensuredir(path.join(self.outdir, '_static')) # first, create pygments style file - f = open(path.join(self.outdir, '_static', 'pygments.css'), 'w') - f.write(self.highlighter.get_stylesheet()) - f.close() + with open(path.join(self.outdir, '_static', 'pygments.css'), 'w') as f: + f.write(self.highlighter.get_stylesheet()) # then, copy translations JavaScript file if self.config.language is not None: jsfile = self._get_translations_js() @@ -605,21 +614,19 @@ class StandaloneHTMLBuilder(Builder): # then, copy over theme-supplied static files if self.theme: - themeentries = [path.join(themepath, 'static') - for themepath in self.theme.get_dirchain()[::-1]] - for entry in themeentries: - copy_static_entry(entry, path.join(self.outdir, '_static'), - self, ctx) + for theme_path in self.theme.get_dirchain()[::-1]: + entry = path.join(theme_path, 'static') + copy_asset(entry, path.join(self.outdir, '_static'), excluded=DOTFILES, + context=ctx, renderer=self.templates) # then, copy over all user-supplied static files - staticentries = [path.join(self.confdir, spath) - for spath in self.config.html_static_path] - matchers = compile_matchers(self.config.exclude_patterns) - for entry in staticentries: + excluded = Matcher(self.config.exclude_patterns + ["**/.*"]) + for static_path in self.config.html_static_path: + entry = path.join(self.confdir, static_path) if not path.exists(entry): self.warn('html_static_path entry %r does not exist' % entry) continue - copy_static_entry(entry, path.join(self.outdir, '_static'), self, - ctx, exclude_matchers=matchers) + copy_asset(entry, path.join(self.outdir, '_static'), excluded, + context=ctx, renderer=self.templates) # copy logo and favicon files if not already in static path if self.config.html_logo: logobase = path.basename(self.config.html_logo) @@ -642,14 +649,15 @@ class StandaloneHTMLBuilder(Builder): def copy_extra_files(self): # copy html_extra_path files self.info(bold('copying extra files... '), nonl=True) - extraentries = [path.join(self.confdir, epath) - for epath in self.config.html_extra_path] - matchers = compile_matchers(self.config.exclude_patterns) - for entry in extraentries: + excluded = Matcher(self.config.exclude_patterns) + + for extra_path in self.config.html_extra_path: + entry = path.join(self.confdir, extra_path) if not path.exists(entry): self.warn('html_extra_path entry %r does not exist' % entry) continue - copy_extra_entry(entry, self.outdir, matchers) + + copy_asset(entry, self.outdir, excluded) self.info('done') def write_buildinfo(self): @@ -712,7 +720,12 @@ class StandaloneHTMLBuilder(Builder): def index_page(self, pagename, doctree, title): # only index pages with title if self.indexer is not None and title: - self.indexer.feed(pagename, title, doctree) + filename = self.env.doc2path(pagename, base=None) + try: + self.indexer.feed(pagename, filename, title, doctree) + except TypeError: + # fallback for old search-adapters + self.indexer.feed(pagename, title, doctree) def _get_local_toctree(self, docname, collapse=True, **kwds): if 'includehidden' not in kwds: @@ -1056,6 +1069,7 @@ class SerializingHTMLBuilder(StandaloneHTMLBuilder): self.theme = None # no theme necessary self.templates = None # no template bridge necessary self.init_translator_class() + self.init_templates() self.init_highlighter() def get_target_uri(self, docname, typ=None): @@ -1148,3 +1162,52 @@ class JSONHTMLBuilder(SerializingHTMLBuilder): def init(self): SerializingHTMLBuilder.init(self) + + +def setup(app): + # builders + app.add_builder(StandaloneHTMLBuilder) + app.add_builder(DirectoryHTMLBuilder) + app.add_builder(SingleFileHTMLBuilder) + app.add_builder(PickleHTMLBuilder) + app.add_builder(JSONHTMLBuilder) + + # config values + app.add_config_value('html_theme', 'alabaster', 'html') + app.add_config_value('html_theme_path', [], 'html') + app.add_config_value('html_theme_options', {}, 'html') + app.add_config_value('html_title', + lambda self: l_('%s %s documentation') % (self.project, self.release), + 'html', string_classes) + app.add_config_value('html_short_title', lambda self: self.html_title, 'html') + app.add_config_value('html_style', None, 'html', string_classes) + app.add_config_value('html_logo', None, 'html', string_classes) + app.add_config_value('html_favicon', None, 'html', string_classes) + app.add_config_value('html_static_path', [], 'html') + app.add_config_value('html_extra_path', [], 'html') + app.add_config_value('html_last_updated_fmt', None, 'html', string_classes) + app.add_config_value('html_use_smartypants', True, 'html') + app.add_config_value('html_translator_class', None, 'html', string_classes) + app.add_config_value('html_sidebars', {}, 'html') + app.add_config_value('html_additional_pages', {}, 'html') + app.add_config_value('html_use_modindex', True, 'html') # deprecated + app.add_config_value('html_domain_indices', True, 'html', [list]) + app.add_config_value('html_add_permalinks', u'\u00B6', 'html') + app.add_config_value('html_use_index', True, 'html') + app.add_config_value('html_split_index', False, 'html') + app.add_config_value('html_copy_source', True, 'html') + app.add_config_value('html_show_sourcelink', True, 'html') + app.add_config_value('html_sourcelink_suffix', '.txt', 'html') + app.add_config_value('html_use_opensearch', '', 'html') + app.add_config_value('html_file_suffix', None, 'html', string_classes) + app.add_config_value('html_link_suffix', None, 'html', string_classes) + app.add_config_value('html_show_copyright', True, 'html') + app.add_config_value('html_show_sphinx', True, 'html') + app.add_config_value('html_context', {}, 'html') + app.add_config_value('html_output_encoding', 'utf-8', 'html') + app.add_config_value('html_compact_lists', True, 'html') + app.add_config_value('html_secnumber_suffix', '. ', 'html') + app.add_config_value('html_search_language', None, 'html', string_classes) + app.add_config_value('html_search_options', {}, 'html') + app.add_config_value('html_search_scorer', '', None) + app.add_config_value('html_scaled_image_link', True, 'html') diff --git a/sphinx/builders/htmlhelp.py b/sphinx/builders/htmlhelp.py index b1a5d7dda..cdb51b2c6 100644 --- a/sphinx/builders/htmlhelp.py +++ b/sphinx/builders/htmlhelp.py @@ -18,6 +18,7 @@ from os import path from docutils import nodes from sphinx import addnodes +from sphinx.util.osutil import make_filename from sphinx.builders.html import StandaloneHTMLBuilder from sphinx.util.pycompat import htmlescape @@ -63,7 +64,7 @@ Binary Index=No Compiled file=%(outname)s.chm Contents file=%(outname)s.hhc Default Window=%(outname)s -Default topic=index.html +Default topic=%(master_doc)s Display compile progress=No Full text search stop list file=%(outname)s.stp Full-text search=Yes @@ -73,7 +74,7 @@ Title=%(title)s [WINDOWS] %(outname)s="%(title)s","%(outname)s.hhc","%(outname)s.hhk",\ -"index.html","index.html",,,,,0x63520,220,0x10384e,[0,0,1024,768],,,,,,,0 +"%(master_doc)s","%(master_doc)s",,,,,0x63520,220,0x10384e,[0,0,1024,768],,,,,,,0 [FILES] ''' @@ -183,6 +184,7 @@ class HTMLHelpBuilder(StandaloneHTMLBuilder): StandaloneHTMLBuilder.init(self) # the output files for HTML help must be .html only self.out_suffix = '.html' + self.link_suffix = '.html' # determine the correct locale setting locale = chm_locales.get(self.config.language) if locale is not None: @@ -204,11 +206,14 @@ class HTMLHelpBuilder(StandaloneHTMLBuilder): self.info('writing project file...') with self.open_file(outdir, outname+'.hhp') as f: - f.write(project_template % {'outname': outname, - 'title': self.config.html_title, - 'version': self.config.version, - 'project': self.config.project, - 'lcid': self.lcid}) + f.write(project_template % { + 'outname': outname, + 'title': self.config.html_title, + 'version': self.config.version, + 'project': self.config.project, + 'lcid': self.lcid, + 'master_doc': self.config.master_doc + self.out_suffix + }) if not outdir.endswith(os.sep): outdir += os.sep olen = len(outdir) @@ -225,7 +230,7 @@ class HTMLHelpBuilder(StandaloneHTMLBuilder): f.write(contents_header) # special books f.write('
  • ' + 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('
  • ' + object_sitemap % (indexcls.localname, '%s.html' % indexname)) @@ -292,3 +297,10 @@ class HTMLHelpBuilder(StandaloneHTMLBuilder): for title, (refs, subitems, key_) in group: write_index(title, refs, subitems) f.write('\n') + + +def setup(app): + app.setup_extension('sphinx.builders.html') + app.add_builder(HTMLHelpBuilder) + + app.add_config_value('htmlhelp_basename', lambda self: make_filename(self.project), None) diff --git a/sphinx/builders/latex.py b/sphinx/builders/latex.py index ac26e33c9..51d361d5e 100644 --- a/sphinx/builders/latex.py +++ b/sphinx/builders/latex.py @@ -11,7 +11,6 @@ import os from os import path -import warnings from six import iteritems from docutils import nodes @@ -19,14 +18,16 @@ from docutils.io import FileOutput from docutils.utils import new_document from docutils.frontend import OptionParser -from sphinx import package_dir, addnodes +from sphinx import package_dir, addnodes, highlighting from sphinx.util import texescape +from sphinx.config import string_classes, ENUM from sphinx.errors import SphinxError from sphinx.locale import _ from sphinx.builders import Builder from sphinx.environment import NoUri from sphinx.util.nodes import inline_all_toctrees -from sphinx.util.osutil import SEP, copyfile +from sphinx.util.fileutil import copy_asset_file +from sphinx.util.osutil import SEP, make_filename from sphinx.util.console import bold, darkgreen from sphinx.writers.latex import LaTeXWriter @@ -38,27 +39,12 @@ class LaTeXBuilder(Builder): name = 'latex' format = 'latex' supported_image_types = ['application/pdf', 'image/png', 'image/jpeg'] - usepackages = [] def init(self): self.docnames = [] self.document_data = [] + self.usepackages = [] texescape.init() - self.check_options() - - def check_options(self): - if self.config.latex_toplevel_sectioning not in (None, 'part', 'chapter', 'section'): - self.warn('invalid latex_toplevel_sectioning, ignored: %s' % - self.config.latex_top_sectionlevel) - self.config.latex_top_sectionlevel = None - - if self.config.latex_use_parts: - warnings.warn('latex_use_parts will be removed at Sphinx-1.5. ' - 'Use latex_toplevel_sectioning instead.', - DeprecationWarning) - - if self.config.latex_toplevel_sectioning: - self.warn('latex_use_parts conflicts with latex_toplevel_sectioning, ignored.') def get_outdated_docs(self): return 'all documents' # for now @@ -92,6 +78,16 @@ class LaTeXBuilder(Builder): docname = docname[:-5] self.titles.append((docname, entry[2])) + def write_stylesheet(self): + highlighter = highlighting.PygmentsBridge( + 'latex', self.config.pygments_style, self.config.trim_doctest_flags) + stylesheet = path.join(self.outdir, 'sphinxhighlight.sty') + with open(stylesheet, 'w') as f: + f.write('\\NeedsTeXFormat{LaTeX2e}[1995/12/01]\n') + f.write('\\ProvidesPackage{sphinxhighlight}' + '[2016/05/29 stylesheet for highlighting with pygments]\n\n') + f.write(highlighter.get_stylesheet()) + def write(self, *ignored): docwriter = LaTeXWriter(self) docsettings = OptionParser( @@ -100,6 +96,7 @@ class LaTeXBuilder(Builder): read_config_files=True).get_default_values() self.init_document_data() + self.write_stylesheet() for entry in self.document_data: docname, targetname, title, author, docclass = entry[:5] @@ -192,33 +189,109 @@ class LaTeXBuilder(Builder): self.info(bold('copying images...'), nonl=1) for src, dest in iteritems(self.images): self.info(' '+src, nonl=1) - copyfile(path.join(self.srcdir, src), - path.join(self.outdir, dest)) + copy_asset_file(path.join(self.srcdir, src), + path.join(self.outdir, dest)) self.info() # copy TeX support files from texinputs + context = {'latex_engine': self.config.latex_engine} self.info(bold('copying TeX support files...')) staticdirname = path.join(package_dir, 'texinputs') for filename in os.listdir(staticdirname): if not filename.startswith('.'): - copyfile(path.join(staticdirname, filename), - path.join(self.outdir, filename)) + copy_asset_file(path.join(staticdirname, filename), + self.outdir, context=context) # copy additional files if self.config.latex_additional_files: self.info(bold('copying additional files...'), nonl=1) for filename in self.config.latex_additional_files: self.info(' '+filename, nonl=1) - copyfile(path.join(self.confdir, filename), - path.join(self.outdir, path.basename(filename))) + copy_asset_file(path.join(self.confdir, filename), self.outdir) self.info() # the logo is handled differently if self.config.latex_logo: - logobase = path.basename(self.config.latex_logo) - logotarget = path.join(self.outdir, logobase) if not path.isfile(path.join(self.confdir, self.config.latex_logo)): raise SphinxError('logo file %r does not exist' % self.config.latex_logo) - elif not path.isfile(logotarget): - copyfile(path.join(self.confdir, self.config.latex_logo), logotarget) + else: + copy_asset_file(path.join(self.confdir, self.config.latex_logo), self.outdir) self.info('done') + + +def validate_config_values(app): + if app.config.latex_toplevel_sectioning not in (None, 'part', 'chapter', 'section'): + app.warn('invalid latex_toplevel_sectioning, ignored: %s' % + app.config.latex_toplevel_sectioning) + app.config.latex_toplevel_sectioning = None + + if app.config.latex_use_parts: + if app.config.latex_toplevel_sectioning: + app.warn('latex_use_parts conflicts with latex_toplevel_sectioning, ignored.') + else: + app.warn('latex_use_parts is deprecated. Use latex_toplevel_sectioning instead.') + app.config.latex_toplevel_sectioning = 'parts' + + if app.config.latex_use_modindex is not True: # changed by user + app.warn('latex_use_modeindex is deprecated. Use latex_domain_indices instead.') + + if app.config.latex_preamble: + if app.config.latex_elements.get('preamble'): + app.warn("latex_preamble conflicts with latex_elements['preamble'], ignored.") + else: + app.warn("latex_preamble is deprecated. Use latex_elements['preamble'] instead.") + app.config.latex_elements['preamble'] = app.config.latex_preamble + + if app.config.latex_paper_size != 'letter': + if app.config.latex_elements.get('papersize'): + app.warn("latex_paper_size conflicts with latex_elements['papersize'], ignored.") + else: + app.warn("latex_paper_size is deprecated. " + "Use latex_elements['papersize'] instead.") + if app.config.latex_paper_size: + app.config.latex_elements['papersize'] = app.config.latex_paper_size + 'paper' + + if app.config.latex_font_size != '10pt': + if app.config.latex_elements.get('pointsize'): + app.warn("latex_font_size conflicts with latex_elements['pointsize'], ignored.") + else: + app.warn("latex_font_size is deprecated. Use latex_elements['pointsize'] instead.") + app.config.latex_elements['pointsize'] = app.config.latex_font_size + + +def setup(app): + app.add_builder(LaTeXBuilder) + app.connect('builder-inited', validate_config_values) + + app.add_config_value('latex_engine', + lambda self: 'pdflatex' if self.language != 'ja' else 'platex', + None, + ENUM('pdflatex', 'xelatex', 'lualatex', 'platex')) + app.add_config_value('latex_documents', + lambda self: [(self.master_doc, make_filename(self.project) + '.tex', + self.project, '', 'manual')], + None) + app.add_config_value('latex_logo', None, None, string_classes) + app.add_config_value('latex_appendices', [], None) + app.add_config_value('latex_keep_old_macro_names', True, None) + # now deprecated - use latex_toplevel_sectioning + app.add_config_value('latex_use_parts', False, None) + app.add_config_value('latex_toplevel_sectioning', None, None, [str]) + app.add_config_value('latex_use_modindex', True, None) # deprecated + app.add_config_value('latex_domain_indices', True, None, [list]) + app.add_config_value('latex_show_urls', 'no', None) + app.add_config_value('latex_show_pagerefs', False, None) + # paper_size and font_size are still separate values + # so that you can give them easily on the command line + app.add_config_value('latex_paper_size', 'letter', None) + app.add_config_value('latex_font_size', '10pt', None) + app.add_config_value('latex_elements', {}, None) + app.add_config_value('latex_additional_files', [], None) + + japanese_default = {'manual': 'jsbook', + 'howto': 'jreport'} + app.add_config_value('latex_docclass', + lambda self: japanese_default if self.language == 'ja' else {}, + None) + # now deprecated - use latex_elements + app.add_config_value('latex_preamble', '', None) diff --git a/sphinx/builders/linkcheck.py b/sphinx/builders/linkcheck.py index 7c30597a8..dfaeb5bba 100644 --- a/sphinx/builders/linkcheck.py +++ b/sphinx/builders/linkcheck.py @@ -54,6 +54,13 @@ except pkg_resources.DistributionNotFound: 'install "requests[security]" as a dependency or upgrade to ' 'a python version with SNI support (Python 3 and Python 2.7.9+).' ) +except pkg_resources.UnknownExtra: + warnings.warn( + 'Some links may return broken results due to being unable to ' + 'check the Server Name Indication (SNI) in the returned SSL cert ' + 'against the hostname in the url requested. Recommended to ' + 'install requests-2.4.1+.' + ) requests_user_agent = [('User-agent', 'Mozilla/5.0 (X11; Linux x86_64; rv:25.0) ' 'Gecko/20100101 Firefox/25.0')] @@ -300,3 +307,13 @@ class CheckExternalLinksBuilder(Builder): def finish(self): for worker in self.workers: self.wqueue.put((None, None, None), False) + + +def setup(app): + app.add_builder(CheckExternalLinksBuilder) + + app.add_config_value('linkcheck_ignore', [], None) + app.add_config_value('linkcheck_retries', 1, None) + app.add_config_value('linkcheck_timeout', None, None, [int]) + app.add_config_value('linkcheck_workers', 5, None) + app.add_config_value('linkcheck_anchors', True, None) diff --git a/sphinx/builders/manpage.py b/sphinx/builders/manpage.py index a2e75f9f7..248ed40b2 100644 --- a/sphinx/builders/manpage.py +++ b/sphinx/builders/manpage.py @@ -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) diff --git a/sphinx/builders/qthelp.py b/sphinx/builders/qthelp.py index 4139c92c6..c53b56657 100644 --- a/sphinx/builders/qthelp.py +++ b/sphinx/builders/qthelp.py @@ -21,6 +21,7 @@ from docutils import nodes from sphinx import addnodes from sphinx.builders.html import StandaloneHTMLBuilder from sphinx.util import force_decode +from sphinx.util.osutil import make_filename from sphinx.util.pycompat import htmlescape @@ -104,15 +105,25 @@ class QtHelpBuilder(StandaloneHTMLBuilder): # don't add links add_permalinks = False + # don't add sidebar etc. embedded = True + # disable download role + download_support = False + + # don't generate the search index or include the search page + search = False def init(self): StandaloneHTMLBuilder.init(self) # the output files for HTML help must be .html only self.out_suffix = '.html' + self.link_suffix = '.html' # self.config.html_style = 'traditional.css' + def get_theme_config(self): + return self.config.qthelp_theme, self.config.qthelp_theme_options + def handle_finish(self): self.build_qhp(self.outdir, self.config.qthelp_basename) @@ -290,3 +301,12 @@ class QtHelpBuilder(StandaloneHTMLBuilder): keywords.extend(self.build_keywords(subitem[0], subitem[1], [])) return keywords + + +def setup(app): + app.setup_extension('sphinx.builders.html') + app.add_builder(QtHelpBuilder) + + app.add_config_value('qthelp_basename', lambda self: make_filename(self.project), None) + app.add_config_value('qthelp_theme', 'nonav', 'html') + app.add_config_value('qthelp_theme_options', {}, 'html') diff --git a/sphinx/builders/texinfo.py b/sphinx/builders/texinfo.py index 8c4bd2419..f070840b6 100644 --- a/sphinx/builders/texinfo.py +++ b/sphinx/builders/texinfo.py @@ -22,7 +22,7 @@ from sphinx.locale import _ from sphinx.builders import Builder from sphinx.environment import NoUri from sphinx.util.nodes import inline_all_toctrees -from sphinx.util.osutil import SEP, copyfile +from sphinx.util.osutil import SEP, copyfile, make_filename from sphinx.util.console import bold, darkgreen from sphinx.writers.texinfo import TexinfoWriter @@ -225,3 +225,20 @@ class TexinfoBuilder(Builder): except (IOError, OSError) as err: self.warn("error writing file %s: %s" % (fn, err)) self.info(' done') + + +def setup(app): + app.add_builder(TexinfoBuilder) + + app.add_config_value('texinfo_documents', + lambda self: [(self.master_doc, make_filename(self.project).lower(), + self.project, '', make_filename(self.project), + 'The %s reference manual.' % + make_filename(self.project), + 'Python')], + None) + app.add_config_value('texinfo_appendices', [], None) + app.add_config_value('texinfo_elements', {}, None) + app.add_config_value('texinfo_domain_indices', True, None, [list]) + app.add_config_value('texinfo_show_urls', 'footnote', None) + app.add_config_value('texinfo_no_detailmenu', False, None) diff --git a/sphinx/builders/text.py b/sphinx/builders/text.py index 202ec20db..2daf8b043 100644 --- a/sphinx/builders/text.py +++ b/sphinx/builders/text.py @@ -67,3 +67,10 @@ class TextBuilder(Builder): def finish(self): pass + + +def setup(app): + app.add_builder(TextBuilder) + + app.add_config_value('text_sectionchars', '*=-~"+`', 'env') + app.add_config_value('text_newlines', 'unix', 'env') diff --git a/sphinx/builders/websupport.py b/sphinx/builders/websupport.py index 843b0899e..d8ff5ad8d 100644 --- a/sphinx/builders/websupport.py +++ b/sphinx/builders/websupport.py @@ -165,3 +165,7 @@ class WebSupportBuilder(PickleHTMLBuilder): def dump_search_index(self): self.indexer.finish_indexing() + + +def setup(app): + app.add_builder(WebSupportBuilder) diff --git a/sphinx/builders/xml.py b/sphinx/builders/xml.py index 589e8a63a..e0e33312c 100644 --- a/sphinx/builders/xml.py +++ b/sphinx/builders/xml.py @@ -95,3 +95,10 @@ class PseudoXMLBuilder(XMLBuilder): out_suffix = '.pseudoxml' _writer_class = PseudoXMLWriter + + +def setup(app): + app.add_builder(XMLBuilder) + app.add_builder(PseudoXMLBuilder) + + app.add_config_value('xml_pretty', True, 'env') diff --git a/sphinx/config.py b/sphinx/config.py index ef57334fe..9de59a9ff 100644 --- a/sphinx/config.py +++ b/sphinx/config.py @@ -10,14 +10,13 @@ """ import re -from os import path, environ, getenv -import shlex +from os import path, getenv from six import PY2, PY3, iteritems, string_types, binary_type, text_type, integer_types from sphinx.errors import ConfigError from sphinx.locale import l_ -from sphinx.util.osutil import make_filename, cd +from sphinx.util.osutil import cd from sphinx.util.pycompat import execfile_, NoneType from sphinx.util.i18n import format_date @@ -29,10 +28,25 @@ if PY3: CONFIG_SYNTAX_ERROR += "\nDid you change the syntax from 2.x to 3.x?" CONFIG_EXIT_ERROR = "The configuration file (or one of the modules it imports) " \ "called sys.exit()" +CONFIG_ENUM_WARNING = "The config value `{name}` has to be a one of {candidates}, " \ + "but `{current}` is given." CONFIG_TYPE_WARNING = "The config value `{name}' has type `{current.__name__}', " \ "defaults to `{default.__name__}.'" +class ENUM: + """represents the config value should be a one of candidates. + + Example: + app.add_config_value('latex_show_urls', 'no', ENUM('no', 'footnote', 'inline')) + """ + def __init__(self, *candidates): + self.candidates = candidates + + def match(self, value): + return value in self.candidates + + string_classes = [text_type] if PY2: string_classes.append(binary_type) # => [str, unicode] @@ -94,192 +108,12 @@ class Config(object): 'table': l_('Table %s'), 'code-block': l_('Listing %s')}, 'env'), - - # HTML options - html_theme = ('alabaster', 'html'), - html_theme_path = ([], 'html'), - html_theme_options = ({}, 'html'), - html_title = (lambda self: l_('%s %s documentation') % - (self.project, self.release), - 'html', string_classes), - html_short_title = (lambda self: self.html_title, 'html'), - html_style = (None, 'html', string_classes), - html_logo = (None, 'html', string_classes), - html_favicon = (None, 'html', string_classes), - html_static_path = ([], 'html'), - html_extra_path = ([], 'html'), - # the real default is locale-dependent - html_last_updated_fmt = (None, 'html', string_classes), - html_use_smartypants = (True, 'html'), - html_translator_class = (None, 'html', string_classes), - html_sidebars = ({}, 'html'), - html_additional_pages = ({}, 'html'), - html_use_modindex = (True, 'html'), # deprecated - html_domain_indices = (True, 'html', [list]), - html_add_permalinks = (u'\u00B6', 'html'), - html_use_index = (True, 'html'), - html_split_index = (False, 'html'), - html_copy_source = (True, 'html'), - html_show_sourcelink = (True, 'html'), - html_use_opensearch = ('', 'html'), - html_file_suffix = (None, 'html', string_classes), - html_link_suffix = (None, 'html', string_classes), - html_show_copyright = (True, 'html'), - html_show_sphinx = (True, 'html'), - html_context = ({}, 'html'), - html_output_encoding = ('utf-8', 'html'), - html_compact_lists = (True, 'html'), - html_secnumber_suffix = ('. ', 'html'), - html_search_language = (None, 'html', string_classes), - html_search_options = ({}, 'html'), - html_search_scorer = ('', None), - html_scaled_image_link = (True, 'html'), - - # HTML help only options - htmlhelp_basename = (lambda self: make_filename(self.project), None), - - # Qt help only options - qthelp_basename = (lambda self: make_filename(self.project), None), - - # Devhelp only options - devhelp_basename = (lambda self: make_filename(self.project), None), - - # Apple help options - applehelp_bundle_name = (lambda self: make_filename(self.project), - 'applehelp'), - applehelp_bundle_id = (None, 'applehelp', string_classes), - applehelp_dev_region = ('en-us', 'applehelp'), - applehelp_bundle_version = ('1', 'applehelp'), - applehelp_icon = (None, 'applehelp', string_classes), - applehelp_kb_product = (lambda self: '%s-%s' % - (make_filename(self.project), self.release), - 'applehelp'), - applehelp_kb_url = (None, 'applehelp', string_classes), - applehelp_remote_url = (None, 'applehelp', string_classes), - applehelp_index_anchors = (False, 'applehelp', string_classes), - applehelp_min_term_length = (None, 'applehelp', string_classes), - applehelp_stopwords = (lambda self: self.language or 'en', 'applehelp'), - applehelp_locale = (lambda self: self.language or 'en', 'applehelp'), - applehelp_title = (lambda self: self.project + ' Help', 'applehelp'), - applehelp_codesign_identity = (lambda self: - environ.get('CODE_SIGN_IDENTITY', None), - 'applehelp'), - applehelp_codesign_flags = (lambda self: - shlex.split( - environ.get('OTHER_CODE_SIGN_FLAGS', - '')), - 'applehelp'), - applehelp_indexer_path = ('/usr/bin/hiutil', 'applehelp'), - applehelp_codesign_path = ('/usr/bin/codesign', 'applehelp'), - applehelp_disable_external_tools = (False, None), - - # Epub options - epub_basename = (lambda self: make_filename(self.project), None), - epub_theme = ('epub', 'html'), - epub_theme_options = ({}, 'html'), - epub_title = (lambda self: self.html_title, 'html'), - epub3_description = ('', 'epub3', string_classes), - epub_author = ('unknown', 'html'), - epub3_contributor = ('unknown', 'epub3', string_classes), - epub_language = (lambda self: self.language or 'en', 'html'), - epub_publisher = ('unknown', 'html'), - epub_copyright = (lambda self: self.copyright, 'html'), - epub_identifier = ('unknown', 'html'), - epub_scheme = ('unknown', 'html'), - epub_uid = ('unknown', 'env'), - epub_cover = ((), 'env'), - epub_guide = ((), 'env'), - epub_pre_files = ([], 'env'), - epub_post_files = ([], 'env'), - epub_exclude_files = ([], 'env'), - epub_tocdepth = (3, 'env'), - epub_tocdup = (True, 'env'), - epub_tocscope = ('default', 'env'), - epub_fix_images = (False, 'env'), - epub_max_image_width = (0, 'env'), - epub_show_urls = ('inline', 'html'), - epub_use_index = (lambda self: self.html_use_index, 'html'), - epub3_page_progression_direction = ('ltr', 'epub3', string_classes), - - # LaTeX options - latex_documents = (lambda self: [(self.master_doc, - make_filename(self.project) + '.tex', - self.project, - '', 'manual')], - None), - latex_logo = (None, None, string_classes), - latex_appendices = ([], None), - # now deprecated - use latex_toplevel_sectioning - latex_use_parts = (False, None), - latex_toplevel_sectioning = (None, None, [str]), - latex_use_modindex = (True, None), # deprecated - latex_domain_indices = (True, None, [list]), - latex_show_urls = ('no', None), - latex_show_pagerefs = (False, None), - # paper_size and font_size are still separate values - # so that you can give them easily on the command line - latex_paper_size = ('letter', None), - latex_font_size = ('10pt', None), - latex_elements = ({}, None), - latex_additional_files = ([], None), - latex_docclass = ({}, None), - # now deprecated - use latex_elements - latex_preamble = ('', None), - - # text options - text_sectionchars = ('*=-~"+`', 'env'), - text_newlines = ('unix', 'env'), - - # manpage options - man_pages = (lambda self: [(self.master_doc, - make_filename(self.project).lower(), - '%s %s' % (self.project, self.release), - [], 1)], - None), - man_show_urls = (False, None), - - # Texinfo options - texinfo_documents = (lambda self: [(self.master_doc, - make_filename(self.project).lower(), - self.project, '', - make_filename(self.project), - 'The %s reference manual.' % - make_filename(self.project), - 'Python')], - None), - texinfo_appendices = ([], None), - texinfo_elements = ({}, None), - texinfo_domain_indices = (True, None, [list]), - texinfo_show_urls = ('footnote', None), - texinfo_no_detailmenu = (False, None), - - # linkcheck options - linkcheck_ignore = ([], None), - linkcheck_retries = (1, None), - linkcheck_timeout = (None, None, [int]), - linkcheck_workers = (5, None), - linkcheck_anchors = (True, None), - - # gettext options - gettext_compact = (True, 'gettext'), - gettext_location = (True, 'gettext'), - gettext_uuid = (False, 'gettext'), - gettext_auto_build = (True, 'env'), - gettext_additional_targets = ([], 'env'), - - # XML options - xml_pretty = (True, 'env'), ) def __init__(self, dirname, filename, overrides, tags): self.overrides = overrides self.values = Config.config_values.copy() config = {} - if 'extensions' in overrides: # XXX do we need this? - if isinstance(overrides['extensions'], string_types): - config['extensions'] = overrides.pop('extensions').split(',') - else: - config['extensions'] = overrides.pop('extensions') if dirname is not None: config_file = path.join(dirname, filename) config['__file__'] = config_file @@ -298,6 +132,12 @@ class Config(object): # these two must be preinitialized because extensions can add their # own config values self.setup = config.get('setup', None) + + if 'extensions' in overrides: + if isinstance(overrides['extensions'], string_types): + config['extensions'] = overrides.pop('extensions').split(',') + else: + config['extensions'] = overrides.pop('extensions') self.extensions = config.get('extensions', []) # correct values of copyright year that are not coherent with @@ -326,19 +166,24 @@ class Config(object): if default is None and not permitted: continue # neither inferrable nor expliclitly permitted types current = self[name] - if type(current) is type(default): - continue - if type(current) in permitted: - continue + if isinstance(permitted, ENUM): + if not permitted.match(current): + warn(CONFIG_ENUM_WARNING.format( + name=name, current=current, candidates=permitted.candidates)) + else: + if type(current) is type(default): + continue + if type(current) in permitted: + continue - common_bases = (set(type(current).__bases__ + (type(current),)) & - set(type(default).__bases__)) - common_bases.discard(object) - if common_bases: - continue # at least we share a non-trivial base class + common_bases = (set(type(current).__bases__ + (type(current),)) & + set(type(default).__bases__)) + common_bases.discard(object) + if common_bases: + continue # at least we share a non-trivial base class - warn(CONFIG_TYPE_WARNING.format( - name=name, current=type(current), default=type(default))) + warn(CONFIG_TYPE_WARNING.format( + name=name, current=type(current), default=type(default))) def check_unicode(self, warn): # check all string values for non-ASCII characters in bytestrings, diff --git a/sphinx/directives/__init__.py b/sphinx/directives/__init__.py index d99a9bc1b..b0c69a8e1 100644 --- a/sphinx/directives/__init__.py +++ b/sphinx/directives/__init__.py @@ -17,11 +17,6 @@ from docutils.parsers.rst import Directive, directives, roles from sphinx import addnodes from sphinx.util.docfields import DocFieldTransformer -# import and register directives -from sphinx.directives.code import * # noqa -from sphinx.directives.other import * # noqa -from sphinx.directives.patches import * # noqa - # RE to strip backslash escapes nl_escape_re = re.compile(r'\\\n') @@ -216,8 +211,9 @@ class DefaultDomain(Directive): return [] -directives.register_directive('default-role', DefaultRole) -directives.register_directive('default-domain', DefaultDomain) -directives.register_directive('describe', ObjectDescription) -# new, more consistent, name -directives.register_directive('object', ObjectDescription) +def setup(app): + directives.register_directive('default-role', DefaultRole) + directives.register_directive('default-domain', DefaultDomain) + directives.register_directive('describe', ObjectDescription) + # new, more consistent, name + directives.register_directive('object', ObjectDescription) diff --git a/sphinx/directives/code.py b/sphinx/directives/code.py index de804f988..f88b30987 100644 --- a/sphinx/directives/code.py +++ b/sphinx/directives/code.py @@ -342,8 +342,9 @@ class LiteralInclude(Directive): return [retnode] -directives.register_directive('highlight', Highlight) -directives.register_directive('highlightlang', Highlight) # old -directives.register_directive('code-block', CodeBlock) -directives.register_directive('sourcecode', CodeBlock) -directives.register_directive('literalinclude', LiteralInclude) +def setup(app): + directives.register_directive('highlight', Highlight) + directives.register_directive('highlightlang', Highlight) # old + directives.register_directive('code-block', CodeBlock) + directives.register_directive('sourcecode', CodeBlock) + directives.register_directive('literalinclude', LiteralInclude) diff --git a/sphinx/directives/other.py b/sphinx/directives/other.py index 51294570c..a24a40a49 100644 --- a/sphinx/directives/other.py +++ b/sphinx/directives/other.py @@ -405,27 +405,29 @@ class Include(BaseInclude): return BaseInclude.run(self) rel_filename, filename = env.relfn2path(self.arguments[0]) self.arguments[0] = filename + env.note_included(filename) return BaseInclude.run(self) -directives.register_directive('toctree', TocTree) -directives.register_directive('sectionauthor', Author) -directives.register_directive('moduleauthor', Author) -directives.register_directive('codeauthor', Author) -directives.register_directive('index', Index) -directives.register_directive('deprecated', VersionChange) -directives.register_directive('versionadded', VersionChange) -directives.register_directive('versionchanged', VersionChange) -directives.register_directive('seealso', SeeAlso) -directives.register_directive('tabularcolumns', TabularColumns) -directives.register_directive('centered', Centered) -directives.register_directive('acks', Acks) -directives.register_directive('hlist', HList) -directives.register_directive('only', Only) -directives.register_directive('include', Include) +def setup(app): + directives.register_directive('toctree', TocTree) + directives.register_directive('sectionauthor', Author) + directives.register_directive('moduleauthor', Author) + directives.register_directive('codeauthor', Author) + directives.register_directive('index', Index) + directives.register_directive('deprecated', VersionChange) + directives.register_directive('versionadded', VersionChange) + directives.register_directive('versionchanged', VersionChange) + directives.register_directive('seealso', SeeAlso) + directives.register_directive('tabularcolumns', TabularColumns) + directives.register_directive('centered', Centered) + directives.register_directive('acks', Acks) + directives.register_directive('hlist', HList) + directives.register_directive('only', Only) + directives.register_directive('include', Include) -# register the standard rst class directive under a different name -# only for backwards compatibility now -directives.register_directive('cssclass', Class) -# new standard name when default-domain with "class" is in effect -directives.register_directive('rst-class', Class) + # register the standard rst class directive under a different name + # only for backwards compatibility now + directives.register_directive('cssclass', Class) + # new standard name when default-domain with "class" is in effect + directives.register_directive('rst-class', Class) diff --git a/sphinx/directives/patches.py b/sphinx/directives/patches.py index 4f6f3729f..a4a046917 100644 --- a/sphinx/directives/patches.py +++ b/sphinx/directives/patches.py @@ -35,4 +35,5 @@ class Figure(images.Figure): return [figure_node] -directives.register_directive('figure', Figure) +def setup(app): + directives.register_directive('figure', Figure) diff --git a/sphinx/domains/__init__.py b/sphinx/domains/__init__.py index e4d397efe..c67abc207 100644 --- a/sphinx/domains/__init__.py +++ b/sphinx/domains/__init__.py @@ -273,20 +273,3 @@ class Domain(object): if primary: return type.lname return _('%s %s') % (self.label, type.lname) - - -from sphinx.domains.c import CDomain # noqa -from sphinx.domains.cpp import CPPDomain # noqa -from sphinx.domains.std import StandardDomain # noqa -from sphinx.domains.python import PythonDomain # noqa -from sphinx.domains.javascript import JavaScriptDomain # noqa -from sphinx.domains.rst import ReSTDomain # noqa - -BUILTIN_DOMAINS = { - 'std': StandardDomain, - 'py': PythonDomain, - 'c': CDomain, - 'cpp': CPPDomain, - 'js': JavaScriptDomain, - 'rst': ReSTDomain, -} diff --git a/sphinx/domains/c.py b/sphinx/domains/c.py index c7fd0681e..43e869dbc 100644 --- a/sphinx/domains/c.py +++ b/sphinx/domains/c.py @@ -279,6 +279,9 @@ class CDomain(Domain): typ, target, node, contnode): # strip pointer asterisk target = target.rstrip(' *') + # becase TypedField can generate xrefs + if target in CObject.stopwords: + return contnode if target not in self.data['objects']: return None obj = self.data['objects'][target] @@ -299,3 +302,7 @@ class CDomain(Domain): def get_objects(self): for refname, (docname, type) in list(self.data['objects'].items()): yield (refname, refname, type, docname, 'c.' + refname, 1) + + +def setup(app): + app.add_domain(CDomain) diff --git a/sphinx/domains/cpp.py b/sphinx/domains/cpp.py index d53b9431d..2b6958768 100644 --- a/sphinx/domains/cpp.py +++ b/sphinx/domains/cpp.py @@ -553,6 +553,80 @@ def _verify_description_mode(mode): raise Exception("Description mode '%s' is invalid." % mode) +class ASTCPPAttribute(ASTBase): + def __init__(self, arg): + self.arg = arg + + def __unicode__(self): + return "[[" + self.arg + "]]" + + def describe_signature(self, signode): + txt = text_type(self) + signode.append(nodes.Text(txt, txt)) + + +class ASTGnuAttribute(ASTBase): + def __init__(self, name, args): + self.name = name + self.args = args + + def __unicode__(self): + res = [self.name] + if self.args: + res.append('(') + res.append(text_type(self.args)) + res.append(')') + return ''.join(res) + + +class ASTGnuAttributeList(ASTBase): + def __init__(self, attrs): + self.attrs = attrs + + def __unicode__(self): + res = ['__attribute__(('] + first = True + for attr in self.attrs: + if not first: + res.append(', ') + first = False + res.append(text_type(attr)) + res.append('))') + return ''.join(res) + + def describe_signature(self, signode): + txt = text_type(self) + signode.append(nodes.Text(txt, txt)) + + +class ASTIdAttribute(ASTBase): + """For simple attributes defined by the user.""" + + def __init__(self, id): + self.id = id + + def __unicode__(self): + return self.id + + def describe_signature(self, signode): + signode.append(nodes.Text(self.id, self.id)) + + +class ASTParenAttribute(ASTBase): + """For paren attributes defined by the user.""" + + def __init__(self, id, arg): + self.id = id + self.arg = arg + + def __unicode__(self): + return self.id + '(' + self.arg + ')' + + def describe_signature(self, signode): + txt = text_type(self) + signode.append(nodes.Text(txt, txt)) + + class ASTIdentifier(ASTBase): def __init__(self, identifier): assert identifier is not None @@ -1341,7 +1415,7 @@ class ASTParametersQualifiers(ASTBase): class ASTDeclSpecsSimple(ASTBase): def __init__(self, storage, threadLocal, inline, virtual, explicit, - constexpr, volatile, const, friend): + constexpr, volatile, const, friend, attrs): self.storage = storage self.threadLocal = threadLocal self.inline = inline @@ -1351,6 +1425,7 @@ class ASTDeclSpecsSimple(ASTBase): self.volatile = volatile self.const = const self.friend = friend + self.attrs = attrs def mergeWith(self, other): if not other: @@ -1363,10 +1438,12 @@ class ASTDeclSpecsSimple(ASTBase): self.constexpr or other.constexpr, self.volatile or other.volatile, self.const or other.const, - self.friend or other.friend) + self.friend or other.friend, + self.attrs + other.attrs) def __unicode__(self): res = [] + res.extend(text_type(attr) for attr in self.attrs) if self.storage: res.append(self.storage) if self.threadLocal: @@ -1392,6 +1469,10 @@ class ASTDeclSpecsSimple(ASTBase): if len(modifiers) > 0: modifiers.append(nodes.Text(' ')) modifiers.append(addnodes.desc_annotation(text, text)) + for attr in self.attrs: + if len(modifiers) > 0: + modifiers.append(nodes.Text(' ')) + modifiers.append(attr.describe_signature(modifiers)) if self.storage: _add(modifiers, self.storage) if self.threadLocal: @@ -2062,7 +2143,7 @@ class ASTTypeWithInit(ASTBase): def get_id_v2(self, objectType=None, symbol=None): if objectType == 'member': - return symbol.declaration.name.get_id_v2() + return symbol.get_full_nested_name().get_id_v2() else: return self.type.get_id_v2() @@ -2780,6 +2861,10 @@ class Symbol(object): if symbol is None: # TODO: maybe search without template args return None + # We have now matched part of a nested name, and need to match more + # so even if we should matchSelf before, we definitely shouldn't + # even more. (see also issue #2666) + matchSelf = False parentSymbol = symbol assert False # should have returned in the loop @@ -2825,7 +2910,7 @@ class DefinitionParser(object): _prefix_keys = ('class', 'struct', 'enum', 'union', 'typename') - def __init__(self, definition, warnEnv): + def __init__(self, definition, warnEnv, config): self.definition = definition.strip() self.pos = 0 self.end = len(self.definition) @@ -2833,6 +2918,7 @@ class DefinitionParser(object): self._previous_state = (0, None) self.warnEnv = warnEnv + self.config = config def _make_multi_error(self, errors, header): if len(errors) == 1: @@ -2901,6 +2987,12 @@ class DefinitionParser(object): return True return False + def skip_string_and_ws(self, string): + if self.skip_string(string): + self.skip_ws() + return True + return False + @property def eof(self): return self.pos >= self.end @@ -2927,6 +3019,85 @@ class DefinitionParser(object): if not self.eof: self.fail('Expected end of definition.') + def _parse_balanced_token_seq(self, end): + # TODO: add handling of string literals and similar + brackets = {'(': ')', '[': ']', '{': '}'} + startPos = self.pos + symbols = [] + while not self.eof: + if len(symbols) == 0 and self.current_char in end: + break + if self.current_char in brackets.keys(): + symbols.append(brackets[self.current_char]) + elif len(symbols) > 0 and self.current_char == symbols[-1]: + symbols.pop() + elif self.current_char in ")]}": + self.fail("Unexpected '%s' in balanced-token-seq." % self.current_char) + self.pos += 1 + if self.eof: + self.fail("Could not find end of balanced-token-seq starting at %d." + % startPos) + return self.definition[startPos:self.pos] + + def _parse_attribute(self): + self.skip_ws() + # try C++11 style + startPos = self.pos + if self.skip_string_and_ws('['): + if not self.skip_string('['): + self.pos = startPos + else: + # TODO: actually implement the correct grammar + arg = self._parse_balanced_token_seq(end=[']']) + if not self.skip_string_and_ws(']'): + self.fail("Expected ']' in end of attribute.") + if not self.skip_string_and_ws(']'): + self.fail("Expected ']' in end of attribute after [[...]") + return ASTCPPAttribute(arg) + + # try GNU style + if self.skip_word_and_ws('__attribute__'): + if not self.skip_string_and_ws('('): + self.fail("Expected '(' after '__attribute__'.") + if not self.skip_string_and_ws('('): + self.fail("Expected '(' after '__attribute__('.") + attrs = [] + while 1: + if self.match(_identifier_re): + name = self.matched_text + self.skip_ws() + if self.skip_string_and_ws('('): + self.fail('Parameterized GNU style attribute not yet supported.') + attrs.append(ASTGnuAttribute(name, None)) + # TODO: parse arguments for the attribute + if self.skip_string_and_ws(','): + continue + elif self.skip_string_and_ws(')'): + break + else: + self.fail("Expected identifier, ')', or ',' in __attribute__.") + if not self.skip_string_and_ws(')'): + self.fail("Expected ')' after '__attribute__((...)'") + return ASTGnuAttributeList(attrs) + + # try the simple id attributes defined by the user + for id in self.config.cpp_id_attributes: + if self.skip_word_and_ws(id): + return ASTIdAttribute(id) + + # try the paren attributes defined by the user + for id in self.config.cpp_paren_attributes: + if not self.skip_string_and_ws(id): + continue + if not self.skip_string('('): + self.fail("Expected '(' after user-defined paren-attribute.") + arg = self._parse_balanced_token_seq(end=[')']) + if not self.skip_string(')'): + self.fail("Expected ')' to end user-defined paren-attribute.") + return ASTParenAttribute(id, arg) + + return None + def _parse_expression(self, end): # Stupidly "parse" an expression. # 'end' should be a list of characters which ends the expression. @@ -3127,10 +3298,9 @@ class DefinitionParser(object): self.fail('Expected ")" after "..." in ' 'parameters_and_qualifiers.') break - if paramMode == 'function': - arg = self._parse_type_with_init(outer=None, named='single') - else: - arg = self._parse_type(named=False) + # note: it seems that function arguments can always sbe named, + # even in function pointers and similar. + arg = self._parse_type_with_init(outer=None, named='single') # TODO: parse default parameters # TODO: didn't we just do that? args.append(ASTFunctinoParameter(arg)) @@ -3209,6 +3379,7 @@ class DefinitionParser(object): volatile = None const = None friend = None + attrs = [] while 1: # accept any permutation of a subset of some decl-specs self.skip_ws() if not storage: @@ -3262,9 +3433,14 @@ class DefinitionParser(object): const = self.skip_word('const') if const: continue + attr = self._parse_attribute() + if attr: + attrs.append(attr) + continue break return ASTDeclSpecsSimple(storage, threadLocal, inline, virtual, - explicit, constexpr, volatile, const, friend) + explicit, constexpr, volatile, const, + friend, attrs) def _parse_decl_specs(self, outer, typed=True): if outer: @@ -3921,7 +4097,7 @@ class CPPObject(ObjectDescription): id_v1 = None id_v2 = ast.get_id_v2() # store them in reverse order, so the newest is first - ids = [id_v2, id_v1] + ids = [id_v2, id_v1] newestId = ids[0] assert newestId # shouldn't be None @@ -3930,7 +4106,12 @@ class CPPObject(ObjectDescription): 'report as bug (id=%s).' % (text_type(ast), newestId)) name = text_type(ast.symbol.get_full_nested_name()).lstrip(':') - indexText = self.get_index_text(name) + strippedName = name + for prefix in self.env.config.cpp_index_common_prefix: + if name.startswith(prefix): + strippedName = strippedName[len(prefix):] + break + indexText = self.get_index_text(strippedName) self.indexnode['entries'].append(('single', indexText, newestId, '', None)) if newestId not in self.state.document.ids: @@ -3942,8 +4123,14 @@ class CPPObject(ObjectDescription): else: # print("[CPP] non-unique name:", name) pass - for id in ids: - if id: # is None when the element didn't exist in that version + # always add the newest id + assert newestId + signode['ids'].append(newestId) + # only add compatibility ids when there are no conflicts + for id in ids[1:]: + if not id: # is None when the element didn't exist in that version + continue + if id not in self.state.document.ids: signode['ids'].append(id) signode['first'] = (not self.names) # hmm, what is this abound? self.state.document.note_explicit_target(signode) @@ -3969,7 +4156,7 @@ class CPPObject(ObjectDescription): self.env.ref_context['cpp:parent_symbol'] = root parentSymbol = self.env.ref_context['cpp:parent_symbol'] - parser = DefinitionParser(sig, self) + parser = DefinitionParser(sig, self, self.env.config) try: ast = self.parse_definition(parser) parser.assert_end() @@ -3996,6 +4183,15 @@ class CPPObject(ObjectDescription): self.describe_signature(signode, ast) return ast + def before_content(self): + lastSymbol = self.env.ref_context['cpp:last_symbol'] + assert lastSymbol + self.oldParentSymbol = self.env.ref_context['cpp:parent_symbol'] + self.env.ref_context['cpp:parent_symbol'] = lastSymbol + + def after_content(self): + self.env.ref_context['cpp:parent_symbol'] = self.oldParentSymbol + class CPPTypeObject(CPPObject): def get_index_text(self, name): @@ -4106,7 +4302,7 @@ class CPPNamespaceObject(Directive): symbol = rootSymbol stack = [] else: - parser = DefinitionParser(self.arguments[0], self) + parser = DefinitionParser(self.arguments[0], self, env.config) try: ast = parser.parse_namespace_object() parser.assert_end() @@ -4135,7 +4331,7 @@ class CPPNamespacePushObject(Directive): env = self.state.document.settings.env if self.arguments[0].strip() in ('NULL', '0', 'nullptr'): return - parser = DefinitionParser(self.arguments[0], self) + parser = DefinitionParser(self.arguments[0], self, env.config) try: ast = parser.parse_namespace_object() parser.assert_end() @@ -4285,7 +4481,7 @@ class CPPDomain(Domain): if emitWarnings: env.warn_node(msg, node) warner = Warner() - parser = DefinitionParser(target, warner) + parser = DefinitionParser(target, warner, env.config) try: ast = parser.parse_xref_object() parser.skip_ws() @@ -4315,6 +4511,31 @@ class CPPDomain(Domain): matchSelf=True) if s is None or s.declaration is None: return None, None + + if typ.startswith('cpp:'): + typ = typ[4:] + if typ == 'func': + typ = 'function' + declTyp = s.declaration.objectType + + def checkType(): + if typ == 'any': + return True + if declTyp == 'templateParam': + return True + if typ == 'var' or typ == 'member': + return declTyp in ['var', 'member'] + if typ in ['enum', 'enumerator', 'function', 'class']: + return declTyp == typ + if typ == 'type': + return declTyp in ['enum', 'class', 'function', 'type'] + print("Type is %s" % typ) + assert False + if not checkType(): + warner.warn("cpp:%s targets a %s (%s)." + % (typ, s.declaration.objectType, + s.get_full_nested_name())) + declaration = s.declaration fullNestedName = s.get_full_nested_name() name = text_type(fullNestedName).lstrip(':') @@ -4354,3 +4575,10 @@ class CPPDomain(Domain): docname = symbol.docname newestId = symbol.declaration.get_newest_id() yield (name, name, objectType, docname, newestId, 1) + + +def setup(app): + app.add_domain(CPPDomain) + app.add_config_value("cpp_index_common_prefix", [], 'env') + app.add_config_value("cpp_id_attributes", [], 'env') + app.add_config_value("cpp_paren_attributes", [], 'env') diff --git a/sphinx/domains/javascript.py b/sphinx/domains/javascript.py index b5f64022a..ade6e4224 100644 --- a/sphinx/domains/javascript.py +++ b/sphinx/domains/javascript.py @@ -234,3 +234,7 @@ class JavaScriptDomain(Domain): for refname, (docname, type) in list(self.data['objects'].items()): yield refname, refname, type, docname, \ refname.replace('$', '_S_'), 1 + + +def setup(app): + app.add_domain(JavaScriptDomain) diff --git a/sphinx/domains/python.py b/sphinx/domains/python.py index 1639d8288..3d7e10467 100644 --- a/sphinx/domains/python.py +++ b/sphinx/domains/python.py @@ -101,11 +101,36 @@ class PyXrefMixin(object): break return result + def make_xrefs(self, rolename, domain, target, innernode=nodes.emphasis, + contnode=None): + delims = '(\s*[\[\]\(\),]\s*)' + delims_re = re.compile(delims) + sub_targets = re.split(delims, target) + + split_contnode = bool(contnode and contnode.astext() == target) + + results = [] + for sub_target in sub_targets: + if split_contnode: + contnode = nodes.Text(sub_target) + + if delims_re.match(sub_target): + results.append(contnode or innernode(sub_target, sub_target)) + else: + results.append(self.make_xref(rolename, domain, sub_target, + innernode, contnode)) + + return results + class PyField(PyXrefMixin, Field): pass +class PyGroupedField(PyXrefMixin, GroupedField): + pass + + class PyTypedField(PyXrefMixin, TypedField): pass @@ -130,9 +155,9 @@ class PyObject(ObjectDescription): names=('var', 'ivar', 'cvar'), typerolename='obj', typenames=('vartype',), can_collapse=True), - GroupedField('exceptions', label=l_('Raises'), rolename='exc', - names=('raises', 'raise', 'exception', 'except'), - can_collapse=True), + PyGroupedField('exceptions', label=l_('Raises'), rolename='exc', + names=('raises', 'raise', 'exception', 'except'), + can_collapse=True), Field('returnvalue', label=l_('Returns'), has_arg=False, names=('returns', 'return')), PyField('returntype', label=l_('Return type'), has_arg=False, @@ -771,3 +796,7 @@ class PythonDomain(Domain): for refname, (docname, type) in iteritems(self.data['objects']): if type != 'module': # modules are already handled yield (refname, refname, type, docname, refname, 1) + + +def setup(app): + app.add_domain(PythonDomain) diff --git a/sphinx/domains/rst.py b/sphinx/domains/rst.py index b11c9450b..526ae18a7 100644 --- a/sphinx/domains/rst.py +++ b/sphinx/domains/rst.py @@ -156,3 +156,7 @@ class ReSTDomain(Domain): def get_objects(self): for (typ, name), docname in iteritems(self.data['objects']): yield name, name, typ, docname, typ + '-' + name, 1 + + +def setup(app): + app.add_domain(ReSTDomain) diff --git a/sphinx/domains/std.py b/sphinx/domains/std.py index 997d95ba3..001d9f6d9 100644 --- a/sphinx/domains/std.py +++ b/sphinx/domains/std.py @@ -14,7 +14,6 @@ import unicodedata from six import iteritems from docutils import nodes -from docutils.nodes import fully_normalize_name from docutils.parsers.rst import directives from docutils.statemachine import ViewList @@ -585,106 +584,119 @@ class StandardDomain(Domain): newnode.append(innernode) return newnode - def resolve_xref(self, env, fromdocname, builder, - typ, target, node, contnode): + def resolve_xref(self, env, fromdocname, builder, typ, target, node, contnode): if typ == 'ref': - if node['refexplicit']: - # reference to anonymous label; the reference uses - # the supplied link caption - docname, labelid = self.data['anonlabels'].get(target, ('', '')) - sectname = node.astext() - else: - # reference to named label; the final node will - # contain the section name after the label - docname, labelid, sectname = self.data['labels'].get(target, - ('', '', '')) - if not docname: - return None - - return self.build_reference_node(fromdocname, builder, - docname, labelid, sectname, 'ref') + resolver = self._resolve_ref_xref elif typ == 'numref': + resolver = self._resolve_numref_xref + elif typ == 'keyword': + resolver = self._resolve_keyword_xref + elif typ == 'option': + resolver = self._resolve_option_xref + else: + resolver = self._resolve_obj_xref + + return resolver(env, fromdocname, builder, typ, target, node, contnode) + + def _resolve_ref_xref(self, env, fromdocname, builder, typ, target, node, contnode): + if node['refexplicit']: + # reference to anonymous label; the reference uses + # the supplied link caption docname, labelid = self.data['anonlabels'].get(target, ('', '')) - if not docname: - return None + sectname = node.astext() + else: + # reference to named label; the final node will + # contain the section name after the label + docname, labelid, sectname = self.data['labels'].get(target, + ('', '', '')) + if not docname: + return None - if env.config.numfig is False: - env.warn(fromdocname, 'numfig is disabled. :numref: is ignored.', - lineno=node.line) - return contnode + return self.build_reference_node(fromdocname, builder, + docname, labelid, sectname, 'ref') - target_node = env.get_doctree(docname).ids.get(labelid) - figtype = self.get_figtype(target_node) - if figtype is None: - return None + def _resolve_numref_xref(self, env, fromdocname, builder, typ, target, node, contnode): + docname, labelid = self.data['anonlabels'].get(target, ('', '')) + if not docname: + return None - try: - figure_id = target_node['ids'][0] - fignumber = env.toc_fignumbers[docname][figtype][figure_id] - except (KeyError, IndexError): - # target_node is found, but fignumber is not assigned. - # Maybe it is defined in orphaned document. - env.warn(fromdocname, "no number is assigned for %s: %s" % (figtype, labelid), - lineno=node.line) - return contnode + if env.config.numfig is False: + env.warn_node('numfig is disabled. :numref: is ignored.', node) + return contnode - title = contnode.astext() - if target == fully_normalize_name(title): + target_node = env.get_doctree(docname).ids.get(labelid) + figtype = self.get_figtype(target_node) + if figtype is None: + return None + + try: + figure_id = target_node['ids'][0] + fignumber = env.toc_fignumbers[docname][figtype][figure_id] + except (KeyError, IndexError): + # target_node is found, but fignumber is not assigned. + # Maybe it is defined in orphaned document. + env.warn_node("no number is assigned for %s: %s" % (figtype, labelid), node) + return contnode + + try: + if node['refexplicit']: + title = contnode.astext() + else: title = env.config.numfig_format.get(figtype, '') - try: - newtitle = title % '.'.join(map(str, fignumber)) - except TypeError: - env.warn(fromdocname, 'invalid numfig_format: %s' % title, - lineno=node.line) - return None + newtitle = title % '.'.join(map(str, fignumber)) + except TypeError: + env.warn_node('invalid numfig_format: %s' % title, node) + return None - return self.build_reference_node(fromdocname, builder, - docname, labelid, newtitle, 'numref', - nodeclass=addnodes.number_reference, - title=title) - elif typ == 'keyword': - # keywords are oddballs: they are referenced by named labels - docname, labelid, _ = self.data['labels'].get(target, ('', '', '')) - if not docname: - return None - return make_refnode(builder, fromdocname, docname, - labelid, contnode) - elif typ == 'option': - progname = node.get('std:program') - target = target.strip() - docname, labelid = self.data['progoptions'].get((progname, target), ('', '')) - if not docname: - commands = [] - while ws_re.search(target): - subcommand, target = ws_re.split(target, 1) - commands.append(subcommand) - progname = "-".join(commands) + return self.build_reference_node(fromdocname, builder, + docname, labelid, newtitle, 'numref', + nodeclass=addnodes.number_reference, + title=title) - docname, labelid = self.data['progoptions'].get((progname, target), - ('', '')) - if docname: - break - else: - return None + def _resolve_keyword_xref(self, env, fromdocname, builder, typ, target, node, contnode): + # keywords are oddballs: they are referenced by named labels + docname, labelid, _ = self.data['labels'].get(target, ('', '', '')) + if not docname: + return None + return make_refnode(builder, fromdocname, docname, + labelid, contnode) - return make_refnode(builder, fromdocname, docname, - labelid, contnode) - else: - objtypes = self.objtypes_for_role(typ) or [] - for objtype in objtypes: - if (objtype, target) in self.data['objects']: - docname, labelid = self.data['objects'][objtype, target] + def _resolve_option_xref(self, env, fromdocname, builder, typ, target, node, contnode): + progname = node.get('std:program') + target = target.strip() + docname, labelid = self.data['progoptions'].get((progname, target), ('', '')) + if not docname: + commands = [] + while ws_re.search(target): + subcommand, target = ws_re.split(target, 1) + commands.append(subcommand) + progname = "-".join(commands) + + docname, labelid = self.data['progoptions'].get((progname, target), + ('', '')) + if docname: break else: - docname, labelid = '', '' - if not docname: return None - return make_refnode(builder, fromdocname, docname, - labelid, contnode) - def resolve_any_xref(self, env, fromdocname, builder, target, - node, contnode): + return make_refnode(builder, fromdocname, docname, + labelid, contnode) + + def _resolve_obj_xref(self, env, fromdocname, builder, typ, target, node, contnode): + objtypes = self.objtypes_for_role(typ) or [] + for objtype in objtypes: + if (objtype, target) in self.data['objects']: + docname, labelid = self.data['objects'][objtype, target] + break + else: + docname, labelid = '', '' + if not docname: + return None + return make_refnode(builder, fromdocname, docname, + labelid, contnode) + + def resolve_any_xref(self, env, fromdocname, builder, target, node, contnode): results = [] ltarget = target.lower() # :ref: lowercases its target automatically for role in ('ref', 'option'): # do not try "keyword" @@ -755,3 +767,7 @@ class StandardDomain(Domain): else: figtype, _ = self.enumerable_nodes.get(node.__class__, (None, None)) return figtype + + +def setup(app): + app.add_domain(StandardDomain) diff --git a/sphinx/environment.py b/sphinx/environment.py index 92064f911..e31ebea47 100644 --- a/sphinx/environment.py +++ b/sphinx/environment.py @@ -17,6 +17,7 @@ import types import bisect import codecs import string +import fnmatch import unicodedata from os import path from glob import glob @@ -75,7 +76,7 @@ default_settings = { # or changed to properly invalidate pickle files. # # NOTE: increase base version by 2 to have distinct numbers for Py2 and 3 -ENV_VERSION = 48 + (sys.version_info[0] - 2) +ENV_VERSION = 49 + (sys.version_info[0] - 2) dummy_reporter = Reporter('', 4, 4) @@ -169,6 +170,7 @@ class BuildEnvironment: # contains all read docnames self.dependencies = {} # docname -> set of dependent file # names, relative to documentation root + self.included = set() # docnames included from other documents self.reread_always = set() # docnames to re-read unconditionally on # next build @@ -328,6 +330,20 @@ class BuildEnvironment: domain.merge_domaindata(docnames, other.domaindata[domainname]) app.emit('env-merge-info', self, docnames, other) + def path2doc(self, filename): + """Return the docname for the filename if the file is document. + + *filename* should be absolute or relative to the source directory. + """ + if filename.startswith(self.srcdir): + filename = filename[len(self.srcdir) + 1:] + for suffix in self.config.source_suffix: + if fnmatch.fnmatch(filename, '*' + suffix): + return filename[:-len(suffix)] + else: + # the file does not have docname + return None + def doc2path(self, docname, base=True, suffix=None): """Return the filename for the document name. @@ -387,8 +403,13 @@ class BuildEnvironment: config.html_extra_path + ['**/_sources', '.#*', '**/.#*', '*.lproj/**'] ) - self.found_docs = set(get_matching_docs( - self.srcdir, config.source_suffix, exclude_matchers=matchers)) + self.found_docs = set() + for docname in get_matching_docs(self.srcdir, config.source_suffix, + exclude_matchers=matchers): + if os.access(self.doc2path(docname), os.R_OK): + self.found_docs.add(docname) + else: + self.warn(docname, "document not readable. Ignored.") # add catalog mo file dependency for docname in self.found_docs: @@ -820,6 +841,15 @@ class BuildEnvironment: """ self.dependencies.setdefault(self.docname, set()).add(filename) + def note_included(self, filename): + """Add *filename* as a included from other document. + + This means the document is not orphaned. + + *filename* should be absolute or relative to the source directory. + """ + self.included.add(self.path2doc(filename)) + def note_reread(self): """Add the current document to the list of documents that will automatically be re-read at the next build. @@ -1413,7 +1443,10 @@ class BuildEnvironment: # nodes with length 1 don't have any children anyway if len(toplevel) > 1: subtrees = toplevel.traverse(addnodes.toctree) - toplevel[1][:] = subtrees + if subtrees: + toplevel[1][:] = subtrees + else: + toplevel.pop(1) # resolve all sub-toctrees for subtocnode in toc.traverse(addnodes.toctree): if not (subtocnode.get('hidden', False) and @@ -1459,6 +1492,9 @@ class BuildEnvironment: _toctree_add_classes(newnode, 1) self._toctree_prune(newnode, 1, prune and maxdepth or 0, collapse) + if len(newnode[-1]) == 0: # No titles found + return None + # set the target paths in the toctrees (they are not known at TOC # generation time) for refnode in newnode.traverse(nodes.reference): @@ -1488,9 +1524,9 @@ class BuildEnvironment: typ, target, node, contnode) # really hardwired reference types elif typ == 'any': - newnode = self._resolve_any_reference(builder, node, contnode) + newnode = self._resolve_any_reference(builder, refdoc, node, contnode) elif typ == 'doc': - newnode = self._resolve_doc_reference(builder, node, contnode) + newnode = self._resolve_doc_reference(builder, refdoc, node, contnode) elif typ == 'citation': newnode = self._resolve_citation(builder, refdoc, node, contnode) # no new node found? try the missing-reference event @@ -1538,10 +1574,10 @@ class BuildEnvironment: msg = '%r reference target not found: %%(target)s' % typ self.warn_node(msg % {'target': target}, node, type='ref', subtype=typ) - def _resolve_doc_reference(self, builder, node, contnode): + def _resolve_doc_reference(self, builder, refdoc, node, contnode): # directly reference to document by source name; # can be absolute or relative - docname = docname_join(node['refdoc'], node['reftarget']) + docname = docname_join(refdoc, node['reftarget']) if docname in self.all_docs: if node['refexplicit']: # reference with explicit title @@ -1551,7 +1587,7 @@ class BuildEnvironment: innernode = nodes.inline(caption, caption) innernode['classes'].append('doc') newnode = nodes.reference('', '', internal=True) - newnode['refuri'] = builder.get_relative_uri(node['refdoc'], docname) + newnode['refuri'] = builder.get_relative_uri(refdoc, docname) newnode.append(innernode) return newnode @@ -1574,13 +1610,12 @@ class BuildEnvironment: # transforms.CitationReference.apply. del node['ids'][:] - def _resolve_any_reference(self, builder, node, contnode): + def _resolve_any_reference(self, builder, refdoc, node, contnode): """Resolve reference generated by the "any" role.""" - refdoc = node['refdoc'] target = node['reftarget'] results = [] # first, try resolving as :doc: - doc_ref = self._resolve_doc_reference(builder, node, contnode) + doc_ref = self._resolve_doc_reference(builder, refdoc, node, contnode) if doc_ref: results.append(('doc', doc_ref)) # next, do the standard domain (makes this a priority) @@ -1931,6 +1966,9 @@ class BuildEnvironment: if docname == self.config.master_doc: # the master file is not included anywhere ;) continue + if docname in self.included: + # the document is included from other documents + continue if 'orphan' in self.metadata[docname]: continue self.warn(docname, 'document isn\'t included in any toctree') diff --git a/sphinx/errors.py b/sphinx/errors.py index 8d695c190..5fb77a135 100644 --- a/sphinx/errors.py +++ b/sphinx/errors.py @@ -67,7 +67,10 @@ class PycodeError(Exception): return res -class SphinxParallelError(Exception): +class SphinxParallelError(SphinxError): + + category = 'Sphinx parallel build error' + def __init__(self, orig_exc, traceback): self.orig_exc = orig_exc self.traceback = traceback diff --git a/sphinx/ext/autodoc.py b/sphinx/ext/autodoc.py index 6ae0966fb..08bc99cdf 100644 --- a/sphinx/ext/autodoc.py +++ b/sphinx/ext/autodoc.py @@ -261,12 +261,13 @@ def format_annotation(annotation): Displaying complex types from ``typing`` relies on its private API. """ + if not isinstance(annotation, type): + return repr(annotation) + qualified_name = (annotation.__module__ + '.' + annotation.__qualname__ if annotation else repr(annotation)) - if not isinstance(annotation, type): - return repr(annotation) - elif annotation.__module__ == 'builtins': + if annotation.__module__ == 'builtins': return annotation.__qualname__ elif typing: if isinstance(annotation, typing.TypeVar): diff --git a/sphinx/ext/imgmath.py b/sphinx/ext/imgmath.py index f8e402be3..e5b8b26c5 100644 --- a/sphinx/ext/imgmath.py +++ b/sphinx/ext/imgmath.py @@ -22,6 +22,7 @@ from six import text_type from docutils import nodes import sphinx +from sphinx.locale import _ from sphinx.errors import SphinxError, ExtensionError from sphinx.util.png import read_png_depth, write_png_depth from sphinx.util.osutil import ensuredir, ENOENT, cd @@ -253,7 +254,9 @@ def html_visit_displaymath(self, node): self.body.append(self.starttag(node, 'div', CLASS='math')) self.body.append('

    ') if node['number']: - self.body.append('(%s)' % node['number']) + self.body.append('(%s)' % node['number']) + self.add_permalink_ref(node, _('Permalink to this equation')) + self.body.append('') if fname is None: # something failed -- use text-only as a bad substitute self.body.append('%s

    \n' % diff --git a/sphinx/ext/intersphinx.py b/sphinx/ext/intersphinx.py index 8e6573e8a..c43b8ae6a 100644 --- a/sphinx/ext/intersphinx.py +++ b/sphinx/ext/intersphinx.py @@ -34,7 +34,8 @@ from os import path import re from six import iteritems, string_types -from six.moves.urllib import parse, request +from six.moves.urllib import request +from six.moves.urllib.parse import urlsplit, urlunsplit from docutils import nodes from docutils.utils import relative_path @@ -105,7 +106,7 @@ def read_inventory_v2(f, uri, join, bufsize=16*1024): for line in split_lines(read_chunks()): # be careful to handle names with embedded spaces correctly - m = re.match(r'(?x)(.+?)\s+(\S*:\S*)\s+(\S+)\s+(\S+)\s+(.*)', + m = re.match(r'(?x)(.+?)\s+(\S*:\S*)\s+(-?\d+)\s+(\S+)\s+(.*)', line.rstrip()) if not m: continue @@ -145,7 +146,7 @@ def _strip_basic_auth(url): :rtype: ``tuple`` """ - url_parts = parse.urlsplit(url) + url_parts = urlsplit(url) username = url_parts.username password = url_parts.password frags = list(url_parts) @@ -154,7 +155,7 @@ def _strip_basic_auth(url): frags[1] = "%s:%s" % (url_parts.hostname, url_parts.port) else: frags[1] = url_parts.hostname - url = parse.urlunsplit(frags) + url = urlunsplit(frags) return (url, username, password) @@ -208,12 +209,12 @@ def _get_safe_url(url): url, username, _ = _strip_basic_auth(url) if username is not None: # case: url contained basic auth creds; obscure password - url_parts = parse.urlsplit(url) + url_parts = urlsplit(url) safe_netloc = '{0}@{1}'.format(username, url_parts.hostname) # replace original netloc w/ obscured version frags = list(url_parts) frags[1] = safe_netloc - safe_url = parse.urlunsplit(frags) + safe_url = urlunsplit(frags) return safe_url @@ -237,6 +238,13 @@ def fetch_inventory(app, uri, inv): '%s: %s' % (inv, err.__class__, err)) return try: + if hasattr(f, 'geturl'): + newuri = f.geturl() + if newuri.endswith("/" + INVENTORY_FILENAME): + newuri = newuri[:-len(INVENTORY_FILENAME) - 1] + if uri != newuri and uri != newuri + "/": + app.info('intersphinx inventory has moved: %s -> %s' % (uri, newuri)) + uri = newuri line = f.readline().rstrip().decode('utf-8') try: if line == '# Sphinx inventory version 1': diff --git a/sphinx/ext/jsmath.py b/sphinx/ext/jsmath.py index f36e12fed..9981ffd3a 100644 --- a/sphinx/ext/jsmath.py +++ b/sphinx/ext/jsmath.py @@ -13,6 +13,7 @@ from docutils import nodes import sphinx +from sphinx.locale import _ from sphinx.application import ExtensionError from sphinx.ext.mathbase import setup_math as mathbase_setup @@ -34,8 +35,9 @@ def html_visit_displaymath(self, node): if i == 0: # necessary to e.g. set the id property correctly if node['number']: - self.body.append('(%s)' % - node['number']) + self.body.append('(%s)' % node['number']) + self.add_permalink_ref(node, _('Permalink to this equation')) + self.body.append('') self.body.append(self.starttag(node, 'div', CLASS='math')) else: # but only once! diff --git a/sphinx/ext/mathbase.py b/sphinx/ext/mathbase.py index 13a560c0a..ddcec492c 100644 --- a/sphinx/ext/mathbase.py +++ b/sphinx/ext/mathbase.py @@ -58,7 +58,7 @@ def wrap_displaymath(math, label, numbering): begin = r'\begin{align*}%s\!\begin{aligned}' % labeldef end = r'\end{aligned}\end{align*}' for part in parts: - equations.append('%s\\\\\n' % part) + equations.append('%s\\\\\n' % part.strip()) return '%s\n%s%s' % (begin, ''.join(equations), end) diff --git a/sphinx/ext/mathjax.py b/sphinx/ext/mathjax.py index bdaab55e0..2f414f4e7 100644 --- a/sphinx/ext/mathjax.py +++ b/sphinx/ext/mathjax.py @@ -14,6 +14,7 @@ from docutils import nodes import sphinx +from sphinx.locale import _ from sphinx.errors import ExtensionError from sphinx.ext.mathbase import setup_math as mathbase_setup @@ -35,7 +36,9 @@ def html_visit_displaymath(self, node): # necessary to e.g. set the id property correctly if node['number']: - self.body.append('(%s)' % node['number']) + self.body.append('(%s)' % node['number']) + self.add_permalink_ref(node, _('Permalink to this equation')) + self.body.append('') self.body.append(self.builder.config.mathjax_display[0]) parts = [prt for prt in node['latex'].split('\n\n') if prt.strip()] if len(parts) > 1: # Add alignment if there are more than 1 equation diff --git a/sphinx/ext/napoleon/__init__.py b/sphinx/ext/napoleon/__init__.py index 9dedc15d7..651355c57 100644 --- a/sphinx/ext/napoleon/__init__.py +++ b/sphinx/ext/napoleon/__init__.py @@ -51,16 +51,17 @@ class Config(object): Attributes ---------- - napoleon_google_docstring : bool, defaults to True + napoleon_google_docstring : :obj:`bool` (Defaults to True) True to parse `Google style`_ docstrings. False to disable support for Google style docstrings. - napoleon_numpy_docstring : bool, defaults to True + napoleon_numpy_docstring : :obj:`bool` (Defaults to True) True to parse `NumPy style`_ docstrings. False to disable support for NumPy style docstrings. - napoleon_include_init_with_doc : bool, defaults to False - True to include init methods (i.e. ``__init___``) with - docstrings in the documentation. False to fall back to Sphinx's - default behavior. + napoleon_include_init_with_doc : :obj:`bool` (Defaults to False) + 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. **If True**:: @@ -72,7 +73,7 @@ class Config(object): def __init__(self): # This will NOT be included in the docs - napoleon_include_private_with_doc : bool, defaults to False + napoleon_include_private_with_doc : :obj:`bool` (Defaults to False) True to include private members (like ``_membername``) with docstrings in the documentation. False to fall back to Sphinx's default behavior. @@ -88,7 +89,7 @@ class Config(object): # This will NOT be included in the docs pass - napoleon_include_special_with_doc : bool, defaults to False + napoleon_include_special_with_doc : :obj:`bool` (Defaults to False) True to include special members (like ``__membername__``) with docstrings in the documentation. False to fall back to Sphinx's default behavior. @@ -105,7 +106,7 @@ class Config(object): # This will NOT be included in the docs return unicode(self.__class__.__name__) - napoleon_use_admonition_for_examples : bool, defaults to False + napoleon_use_admonition_for_examples : :obj:`bool` (Defaults to False) True to use the ``.. admonition::`` directive for the **Example** and **Examples** sections. False to use the ``.. rubric::`` directive instead. One may look better than the other depending on what HTML @@ -129,7 +130,7 @@ class Config(object): This is just a quick example - napoleon_use_admonition_for_notes : bool, defaults to False + napoleon_use_admonition_for_notes : :obj:`bool` (Defaults to False) True to use the ``.. admonition::`` directive for **Notes** sections. False to use the ``.. rubric::`` directive instead. @@ -142,7 +143,7 @@ class Config(object): -------- :attr:`napoleon_use_admonition_for_examples` - napoleon_use_admonition_for_references : bool, defaults to False + napoleon_use_admonition_for_references : :obj:`bool` (Defaults to False) True to use the ``.. admonition::`` directive for **References** sections. False to use the ``.. rubric::`` directive instead. @@ -150,7 +151,7 @@ class Config(object): -------- :attr:`napoleon_use_admonition_for_examples` - napoleon_use_ivar : bool, defaults to False + napoleon_use_ivar : :obj:`bool` (Defaults to False) True to use the ``:ivar:`` role for instance variables. False to use the ``.. attribute::`` directive instead. @@ -174,7 +175,7 @@ class Config(object): Description of `attr1` - napoleon_use_param : bool, defaults to True + napoleon_use_param : :obj:`bool` (Defaults to True) True to use a ``:param:`` role for each function parameter. False to use a single ``:parameters:`` role for all the parameters. @@ -201,21 +202,22 @@ class Config(object): * **arg2** (*int, optional*) -- Description of `arg2`, defaults to 0 - napoleon_use_keyword : bool, defaults to True + napoleon_use_keyword : :obj:`bool` (Defaults to True) True to use a ``:keyword:`` role for each function keyword argument. False to use a single ``:keyword arguments:`` role for all the keywords. - 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) + 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) See Also -------- :attr:`napoleon_use_param` - napoleon_use_rtype : bool, defaults to True + napoleon_use_rtype : :obj:`bool` (Defaults to True) True to use the ``:rtype:`` role for the return type. False to output the return type inline with the description. @@ -295,20 +297,23 @@ def setup(app): def _patch_python_domain(): - import sphinx.domains.python - from sphinx.domains.python import PyTypedField - import sphinx.locale - l_ = sphinx.locale.lazy_gettext - for doc_field in sphinx.domains.python.PyObject.doc_field_types: - if doc_field.name == 'parameter': - doc_field.names = ('param', 'parameter', 'arg', 'argument') - break - sphinx.domains.python.PyObject.doc_field_types.append( - PyTypedField('keyword', label=l_('Keyword Arguments'), - names=('keyword', 'kwarg', 'kwparam'), - typerolename='obj', typenames=('paramtype', 'kwtype'), - can_collapse=True), - ) + try: + from sphinx.domains.python import PyTypedField + except ImportError: + pass + else: + import sphinx.domains.python + import sphinx.locale + l_ = sphinx.locale.lazy_gettext + for doc_field in sphinx.domains.python.PyObject.doc_field_types: + if doc_field.name == 'parameter': + doc_field.names = ('param', 'parameter', 'arg', 'argument') + break + sphinx.domains.python.PyObject.doc_field_types.append( + PyTypedField('keyword', label=l_('Keyword Arguments'), + names=('keyword', 'kwarg', 'kwparam'), + typerolename='obj', typenames=('paramtype', 'kwtype'), + can_collapse=True)) def _process_docstring(app, what, name, obj, options, lines): diff --git a/sphinx/ext/napoleon/docstring.py b/sphinx/ext/napoleon/docstring.py index c12b75e6d..e526a11ae 100644 --- a/sphinx/ext/napoleon/docstring.py +++ b/sphinx/ext/napoleon/docstring.py @@ -24,8 +24,9 @@ from sphinx.util.pycompat import UnicodeMixin _directive_regex = re.compile(r'\.\. \S+::') _google_section_regex = re.compile(r'^(\s|\w)+:\s*$') -_google_typed_arg_regex = re.compile(r'\s*(.+?)\s*\(\s*(.+?)\s*\)') +_google_typed_arg_regex = re.compile(r'\s*(.+?)\s*\(\s*(.*[^\s]+)\s*\)') _numpy_section_regex = re.compile(r'^[=\-`:\'"~^_*+#<>]{2,}\s*$') +_single_colon_regex = re.compile(r'(?>> from sphinx.ext.napoleon import Config @@ -174,7 +173,7 @@ class GoogleDocstring(UnicodeMixin): Returns ------- - List[str] + list(str) The lines of the docstring in a list. """ @@ -256,12 +255,7 @@ class GoogleDocstring(UnicodeMixin): else: _desc = lines[1:] - match = _google_typed_arg_regex.match(before) - if match: - _name = match.group(1) - _type = match.group(2) - else: - _type = before + _type = before _desc = self.__class__(_desc, self._config).lines() return [(_name, _type, _desc,)] @@ -307,6 +301,19 @@ class GoogleDocstring(UnicodeMixin): else: return name + def _fix_field_desc(self, desc): + if self._is_list(desc): + desc = [''] + desc + elif desc[0].endswith('::'): + desc_block = desc[1:] + indent = self._get_indent(desc[0]) + block_indent = self._get_initial_indent(desc_block) + if block_indent > indent: + desc = [''] + desc + else: + desc = ['', desc[0]] + self._indent(desc_block, 4) + return desc + def _format_admonition(self, admonition, lines): lines = self._strip_empty(lines) if len(lines) == 1: @@ -333,6 +340,22 @@ class GoogleDocstring(UnicodeMixin): else: return [prefix] + def _format_docutils_params(self, fields, field_role='param', + type_role='type'): + lines = [] + for _name, _type, _desc in fields: + _desc = self._strip_empty(_desc) + if any(_desc): + _desc = self._fix_field_desc(_desc) + field = ':%s %s: ' % (field_role, _name) + lines.extend(self._format_block(field, _desc)) + else: + lines.append(':%s %s:' % (field_role, _name)) + + if _type: + lines.append(':%s %s: %s' % (type_role, _name, _type)) + return lines + [''] + def _format_field(self, _name, _type, _desc): _desc = self._strip_empty(_desc) has_desc = any(_desc) @@ -354,9 +377,11 @@ class GoogleDocstring(UnicodeMixin): field = '' if has_desc: - if self._is_list(_desc): - return [field, ''] + _desc - return [field + _desc[0]] + _desc[1:] + _desc = self._fix_field_desc(_desc) + if _desc[0]: + return [field + _desc[0]] + _desc[1:] + else: + return [field] + _desc else: return [field] @@ -393,6 +418,12 @@ class GoogleDocstring(UnicodeMixin): return i return len(line) + def _get_initial_indent(self, lines): + for line in lines: + if line: + return self._get_indent(line) + return 0 + def _get_min_indent(self, lines): min_indent = None for line in lines: @@ -529,11 +560,10 @@ class GoogleDocstring(UnicodeMixin): def _parse_keyword_arguments_section(self, section): fields = self._consume_fields() if self._config.napoleon_use_keyword: - return self._generate_docutils_params( + return self._format_docutils_params( fields, field_role="keyword", - type_role="kwtype" - ) + type_role="kwtype") else: return self._format_fields('Keyword Arguments', fields) @@ -560,26 +590,10 @@ class GoogleDocstring(UnicodeMixin): def _parse_parameters_section(self, section): fields = self._consume_fields() if self._config.napoleon_use_param: - return self._generate_docutils_params(fields) + return self._format_docutils_params(fields) else: return self._format_fields('Parameters', fields) - def _generate_docutils_params(self, fields, field_role='param', type_role='type'): - lines = [] - for _name, _type, _desc in fields: - _desc = self._strip_empty(_desc) - if any(_desc): - if self._is_list(_desc): - _desc = [''] + _desc - field = ':%s %s: ' % (field_role, _name) - lines.extend(self._format_block(field, _desc)) - else: - lines.append(':%s %s:' % (field_role, _name)) - - if _type: - lines.append(':%s %s: %s' % (type_role, _name, _type)) - return lines + [''] - def _parse_raises_section(self, section): fields = self._consume_fields(parse_type=False, prefer_type=True) field_type = ':raises:' @@ -678,11 +692,12 @@ class GoogleDocstring(UnicodeMixin): if found_colon: after_colon.append(source) else: - if (i % 2) == 0 and ":" in source: + m = _single_colon_regex.search(source) + if (i % 2) == 0 and m: found_colon = True - before, colon, after = source.partition(":") - before_colon.append(before) - after_colon.append(after) + colon = source[m.start(): m.end()] + before_colon.append(source[:m.start()]) + after_colon.append(source[m.end():]) else: before_colon.append(source) @@ -715,36 +730,34 @@ class NumpyDocstring(GoogleDocstring): Parameters ---------- - docstring : str or List[str] + docstring : :obj:`str` or :obj:`list` of :obj:`str` The docstring to parse, given either as a string or split into individual lines. - config : Optional[sphinx.ext.napoleon.Config or sphinx.config.Config] + config: :obj:`sphinx.ext.napoleon.Config` or :obj:`sphinx.config.Config` The configuration settings to use. If not given, defaults to the config object on `app`; or if `app` is not given defaults to the - a new `sphinx.ext.napoleon.Config` object. + a new :class:`sphinx.ext.napoleon.Config` object. - See Also - -------- - :class:`sphinx.ext.napoleon.Config` Other Parameters ---------------- - app : Optional[sphinx.application.Sphinx] + app : :class:`sphinx.application.Sphinx`, optional Application object representing the Sphinx process. - what : Optional[str] + what : :obj:`str`, optional A string specifying the type of the object to which the docstring belongs. Valid values: "module", "class", "exception", "function", "method", "attribute". - name : Optional[str] + name : :obj:`str`, optional The fully qualified name of the object. obj : module, class, exception, function, method, or attribute The object to which the docstring belongs. - options : Optional[sphinx.ext.autodoc.Options] + options : :class:`sphinx.ext.autodoc.Options`, optional The options given to the directive: an object with attributes inherited_members, undoc_members, show_inheritance and noindex that are True if the flag option of same name was given to the auto directive. + Example ------- >>> from sphinx.ext.napoleon import Config @@ -801,7 +814,7 @@ class NumpyDocstring(GoogleDocstring): Returns ------- - List[str] + list(str) The lines of the docstring in a list. """ diff --git a/sphinx/ext/todo.py b/sphinx/ext/todo.py index a853ec93c..f3b526ce6 100644 --- a/sphinx/ext/todo.py +++ b/sphinx/ext/todo.py @@ -70,6 +70,8 @@ def process_todos(app, doctree): if not hasattr(env, 'todo_all_todos'): env.todo_all_todos = [] for node in doctree.traverse(todo_node): + app.emit('todo-defined', node) + try: targetnode = node.parent[node.parent.index(node) - 1] if not isinstance(targetnode, nodes.target): @@ -86,6 +88,9 @@ def process_todos(app, doctree): 'target': targetnode, }) + if env.config.todo_emit_warnings: + env.warn_node("TODO entry found: %s" % node[1].astext(), node) + class TodoList(Directive): """ @@ -187,8 +192,10 @@ def depart_todo_node(self, node): def setup(app): + app.add_event('todo-defined') app.add_config_value('todo_include_todos', False, 'html') app.add_config_value('todo_link_only', False, 'html') + app.add_config_value('todo_emit_warnings', False, 'html') app.add_node(todolist) app.add_node(todo_node, diff --git a/sphinx/ext/viewcode.py b/sphinx/ext/viewcode.py index 89e7a9965..276a137d5 100644 --- a/sphinx/ext/viewcode.py +++ b/sphinx/ext/viewcode.py @@ -46,6 +46,10 @@ def doctree_read(app, doctree): env = app.builder.env if not hasattr(env, '_viewcode_modules'): env._viewcode_modules = {} + if app.builder.name == "singlehtml": + return + if app.builder.name.startswith("epub") and not env.config.viewcode_enable_epub: + return def has_tag(modname, fullname, docname, refname): entry = env._viewcode_modules.get(modname, None) @@ -139,8 +143,8 @@ def collect_pages(app): # construct a page name for the highlighted source pagename = '_modules/' + modname.replace('.', '/') # highlight the source using the builder's highlighter - if env.config.highlight_language == 'python3': - lexer = 'python3' + if env.config.highlight_language in ('python3', 'default'): + lexer = env.config.highlight_language else: lexer = 'python' highlighted = highlighter.highlight_block(code, lexer, linenos=False) @@ -215,6 +219,7 @@ def collect_pages(app): def setup(app): app.add_config_value('viewcode_import', True, False) + app.add_config_value('viewcode_enable_epub', False, False) app.connect('doctree-read', doctree_read) app.connect('env-merge-info', env_merge_info) app.connect('html-collect-pages', collect_pages) diff --git a/sphinx/io.py b/sphinx/io.py index 8d9970e80..36ac7bf98 100644 --- a/sphinx/io.py +++ b/sphinx/io.py @@ -15,7 +15,7 @@ from six import string_types, text_type from sphinx.transforms import ApplySourceWorkaround, ExtraTranslatableNodes, Locale, \ CitationReferences, DefaultSubstitutions, MoveModuleTargets, HandleCodeBlocks, \ - AutoNumbering, SortIds, RemoveTranslatableInline + AutoNumbering, AutoIndexUpgrader, SortIds, RemoveTranslatableInline from sphinx.util import import_object, split_docinfo @@ -59,7 +59,7 @@ class SphinxStandaloneReader(SphinxBaseReader): """ transforms = [ApplySourceWorkaround, ExtraTranslatableNodes, Locale, CitationReferences, DefaultSubstitutions, MoveModuleTargets, HandleCodeBlocks, - AutoNumbering, SortIds, RemoveTranslatableInline] + AutoNumbering, AutoIndexUpgrader, SortIds, RemoveTranslatableInline] class SphinxI18nReader(SphinxBaseReader): @@ -112,10 +112,9 @@ class SphinxFileInput(FileInput): return data.decode(self.encoding, 'sphinx') # py2: decoding def read(self): - def get_parser_type(docname): - path = self.env.doc2path(docname) + def get_parser_type(source_path): for suffix in self.env.config.source_parsers: - if path.endswith(suffix): + if source_path.endswith(suffix): parser_class = self.env.config.source_parsers[suffix] if isinstance(parser_class, string_types): parser_class = import_object(parser_class, 'source parser') @@ -129,7 +128,7 @@ class SphinxFileInput(FileInput): self.app.emit('source-read', self.env.docname, arg) data = arg[0] docinfo, data = split_docinfo(data) - if 'restructuredtext' in get_parser_type(self.env.docname): + if 'restructuredtext' in get_parser_type(self.source_path): if self.env.config.rst_epilog: data = data + '\n' + self.env.config.rst_epilog + '\n' if self.env.config.rst_prolog: diff --git a/sphinx/make_mode.py b/sphinx/make_mode.py index 9a17895bd..3bc8fa2a0 100644 --- a/sphinx/make_mode.py +++ b/sphinx/make_mode.py @@ -18,13 +18,12 @@ from __future__ import print_function import os import sys -import shutil from os import path from subprocess import call import sphinx from sphinx.util.console import bold, blue -from sphinx.util.osutil import cd +from sphinx.util.osutil import cd, rmtree proj_name = os.getenv('SPHINXPROJ', '') @@ -42,8 +41,6 @@ BUILDERS = [ ("", "latex", "to make LaTeX files, you can set PAPER=a4 or PAPER=letter"), ("posix", "latexpdf", "to make LaTeX files and run them through pdflatex"), ("posix", "latexpdfja", "to make LaTeX files and run them through platex/dvipdfmx"), - ("posix", "lualatexpdf", "to make LaTeX files and run them through lualatex"), - ("posix", "xelatexpdf", "to make LaTeX files and run them through xelatex"), ("", "text", "to make text files"), ("", "man", "to make manual pages"), ("", "texinfo", "to make Texinfo files"), @@ -77,7 +74,7 @@ class Make(object): return 1 print("Removing everything under %r..." % self.builddir) for item in os.listdir(self.builddir): - shutil.rmtree(self.builddir_join(item)) + rmtree(self.builddir_join(item)) def build_help(self): print(bold("Sphinx v%s" % sphinx.__display_version__)) @@ -173,18 +170,6 @@ class Make(object): with cd(self.builddir_join('latex')): os.system('make all-pdf-ja') - def build_lualatexpdf(self): - if self.run_generic_build('latex') > 0: - return 1 - with cd(self.builddir_join('latex')): - os.system('make PDFLATEX=lualatex all-pdf') - - def build_xelatexpdf(self): - if self.run_generic_build('latex') > 0: - return 1 - with cd(self.builddir_join('latex')): - os.system('make PDFLATEX=xelatex all-pdf') - def build_text(self): if self.run_generic_build('text') > 0: return 1 diff --git a/sphinx/quickstart.py b/sphinx/quickstart.py index 1fd2bd626..326da03db 100644 --- a/sphinx/quickstart.py +++ b/sphinx/quickstart.py @@ -34,10 +34,11 @@ from six.moves import input from six.moves.urllib.parse import quote as urlquote from docutils.utils import column_width -from sphinx import __display_version__ +from sphinx import __display_version__, package_dir from sphinx.util.osutil import make_filename from sphinx.util.console import purple, bold, red, turquoise, \ nocolor, color_terminal +from sphinx.util.template import SphinxRenderer from sphinx.util import texescape TERM_ENCODING = getattr(sys.stdin, 'encoding', None) @@ -65,1057 +66,6 @@ EXTENSIONS = ('autodoc', 'doctest', 'intersphinx', 'todo', 'coverage', PROMPT_PREFIX = '> ' -if PY3: - # prevents that the file is checked for being written in Python 2.x syntax - QUICKSTART_CONF = u'#!/usr/bin/env python3\n' -else: - QUICKSTART_CONF = u'' - -QUICKSTART_CONF += u'''\ -# -*- coding: utf-8 -*- -# -# %(project)s documentation build configuration file, created by -# sphinx-quickstart on %(now)s. -# -# This file is execfile()d with the current directory set to its -# containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# -# import os -# import sys -# sys.path.insert(0, os.path.abspath('.')) - -# -- General configuration ------------------------------------------------ - -# If your documentation needs a minimal Sphinx version, state it here. -# -# needs_sphinx = '1.0' - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [%(extensions)s] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['%(dot)stemplates'] - -# The suffix(es) of source filenames. -# You can specify multiple suffix as a list of string: -# -# source_suffix = ['.rst', '.md'] -source_suffix = '%(suffix)s' - -# The encoding of source files. -# -# source_encoding = 'utf-8-sig' - -# The master toctree document. -master_doc = '%(master_str)s' - -# General information about the project. -project = u'%(project_str)s' -copyright = u'%(copyright_str)s' -author = u'%(author_str)s' - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -version = u'%(version_str)s' -# The full version, including alpha/beta/rc tags. -release = u'%(release_str)s' - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -# -# This is also used if you do content translation via gettext catalogs. -# Usually you set "language" from the command line for these cases. -language = %(language)r - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -# -# today = '' -# -# Else, today_fmt is used as the format for a strftime call. -# -# today_fmt = '%%B %%d, %%Y' - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This patterns also effect to html_static_path and html_extra_path -exclude_patterns = [%(exclude_patterns)s] - -# The reST default role (used for this markup: `text`) to use for all -# documents. -# -# default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -# -# add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -# -# add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -# -# show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# A list of ignored prefixes for module index sorting. -# modindex_common_prefix = [] - -# If true, keep warnings as "system message" paragraphs in the built documents. -# keep_warnings = False - -# If true, `todo` and `todoList` produce output, else they produce nothing. -todo_include_todos = %(ext_todo)s - - -# -- Options for HTML output ---------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -# -html_theme = 'alabaster' - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -# -# html_theme_options = {} - -# Add any paths that contain custom themes here, relative to this directory. -# html_theme_path = [] - -# The name for this set of Sphinx documents. -# " v documentation" by default. -# -# html_title = u'%(project_str)s v%(release_str)s' - -# A shorter title for the navigation bar. Default is the same as html_title. -# -# html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -# -# html_logo = None - -# The name of an image file (relative to this directory) to use as a favicon of -# the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -# -# html_favicon = None - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['%(dot)sstatic'] - -# Add any extra paths that contain custom files (such as robots.txt or -# .htaccess) here, relative to this directory. These files are copied -# directly to the root of the documentation. -# -# html_extra_path = [] - -# If not None, a 'Last updated on:' timestamp is inserted at every page -# bottom, using the given strftime format. -# The empty string is equivalent to '%%b %%d, %%Y'. -# -# html_last_updated_fmt = None - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -# -# html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -# -# html_sidebars = {} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -# -# html_additional_pages = {} - -# If false, no module index is generated. -# -# html_domain_indices = True - -# If false, no index is generated. -# -# html_use_index = True - -# If true, the index is split into individual pages for each letter. -# -# html_split_index = False - -# If true, links to the reST sources are added to the pages. -# -# html_show_sourcelink = True - -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -# -# html_show_sphinx = True - -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -# -# html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -# -# html_use_opensearch = '' - -# This is the file name suffix for HTML files (e.g. ".xhtml"). -# html_file_suffix = None - -# Language to be used for generating the HTML full-text search index. -# Sphinx supports the following languages: -# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' -# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr', 'zh' -# -# html_search_language = 'en' - -# A dictionary with options for the search language support, empty by default. -# 'ja' uses this config value. -# 'zh' user can custom change `jieba` dictionary path. -# -# html_search_options = {'type': 'default'} - -# The name of a javascript file (relative to the configuration directory) that -# implements a search results scorer. If empty, the default will be used. -# -# html_search_scorer = 'scorer.js' - -# Output file base name for HTML help builder. -htmlhelp_basename = '%(project_fn)sdoc' - -# -- Options for LaTeX output --------------------------------------------- - -latex_elements = { - # The paper size ('letterpaper' or 'a4paper'). - # - # 'papersize': 'letterpaper', - - # The font size ('10pt', '11pt' or '12pt'). - # - # 'pointsize': '10pt', - - # Additional stuff for the LaTeX preamble. - # - # 'preamble': '', - - # Latex figure (float) alignment - # - # 'figure_align': 'htbp', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, -# author, documentclass [howto, manual, or own class]). -latex_documents = [ - (master_doc, '%(project_fn)s.tex', u'%(project_doc_texescaped_str)s', - u'%(author_texescaped_str)s', 'manual'), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -# -# latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -# -# latex_use_parts = False - -# If true, show page references after internal links. -# -# latex_show_pagerefs = False - -# If true, show URL addresses after external links. -# -# latex_show_urls = False - -# Documents to append as an appendix to all manuals. -# -# latex_appendices = [] - -# If false, no module index is generated. -# -# latex_domain_indices = True - - -# -- Options for manual page output --------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - (master_doc, '%(project_manpage)s', u'%(project_doc_str)s', - [author], 1) -] - -# If true, show URL addresses after external links. -# -# man_show_urls = False - - -# -- Options for Texinfo output ------------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - (master_doc, '%(project_fn)s', u'%(project_doc_str)s', - author, '%(project_fn)s', 'One line description of project.', - 'Miscellaneous'), -] - -# Documents to append as an appendix to all manuals. -# -# texinfo_appendices = [] - -# If false, no module index is generated. -# -# texinfo_domain_indices = True - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -# -# texinfo_show_urls = 'footnote' - -# If true, do not generate a @detailmenu in the "Top" node's menu. -# -# texinfo_no_detailmenu = False -''' - -EPUB_CONFIG = u''' - -# -- Options for Epub output ---------------------------------------------- - -# Bibliographic Dublin Core info. -epub_title = project -epub_author = author -epub_publisher = author -epub_copyright = copyright - -# The basename for the epub file. It defaults to the project name. -# epub_basename = project - -# The HTML theme for the epub output. Since the default themes are not -# optimized for small screen space, using the same theme for HTML and epub -# output is usually not wise. This defaults to 'epub', a theme designed to save -# visual space. -# -# epub_theme = 'epub' - -# The language of the text. It defaults to the language option -# or 'en' if the language is not set. -# -# epub_language = '' - -# The scheme of the identifier. Typical schemes are ISBN or URL. -# epub_scheme = '' - -# The unique identifier of the text. This can be a ISBN number -# or the project homepage. -# -# epub_identifier = '' - -# A unique identification for the text. -# -# epub_uid = '' - -# A tuple containing the cover image and cover page html template filenames. -# -# epub_cover = () - -# A sequence of (type, uri, title) tuples for the guide element of content.opf. -# -# epub_guide = () - -# HTML files that should be inserted before the pages created by sphinx. -# The format is a list of tuples containing the path and title. -# -# epub_pre_files = [] - -# HTML files that should be inserted after the pages created by sphinx. -# The format is a list of tuples containing the path and title. -# -# epub_post_files = [] - -# A list of files that should not be packed into the epub file. -epub_exclude_files = ['search.html'] - -# The depth of the table of contents in toc.ncx. -# -# epub_tocdepth = 3 - -# Allow duplicate toc entries. -# -# epub_tocdup = True - -# Choose between 'default' and 'includehidden'. -# -# epub_tocscope = 'default' - -# Fix unsupported image types using the Pillow. -# -# epub_fix_images = False - -# Scale large images. -# -# epub_max_image_width = 0 - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -# -# epub_show_urls = 'inline' - -# If false, no index is generated. -# -# epub_use_index = True -''' - -INTERSPHINX_CONFIG = u''' - -# Example configuration for intersphinx: refer to the Python standard library. -intersphinx_mapping = {'https://docs.python.org/': None} -''' - -MASTER_FILE = u'''\ -.. %(project)s documentation master file, created by - sphinx-quickstart on %(now)s. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -Welcome to %(project)s's documentation! -===========%(project_underline)s================= - -Contents: - -.. toctree:: - :maxdepth: %(mastertocmaxdepth)s - -%(mastertoctree)s - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - -''' - -MAKEFILE = u'''\ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -PAPER = -BUILDDIR = %(rbuilddir)s - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) \ -$(SPHINXOPTS) %(rsrcdir)s -# the i18n builder cannot share the environment and doctrees with the others -I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) %(rsrcdir)s - -.PHONY: help -help: -\t@echo "Please use \\`make ' where is one of" -\t@echo " html to make standalone HTML files" -\t@echo " dirhtml to make HTML files named index.html in directories" -\t@echo " singlehtml to make a single large HTML file" -\t@echo " pickle to make pickle files" -\t@echo " json to make JSON files" -\t@echo " htmlhelp to make HTML files and a HTML help project" -\t@echo " qthelp to make HTML files and a qthelp project" -\t@echo " applehelp to make an Apple Help Book" -\t@echo " devhelp to make HTML files and a Devhelp project" -\t@echo " epub to make an epub" -\t@echo " epub3 to make an epub3" -\t@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" -\t@echo " latexpdf to make LaTeX files and run them through pdflatex" -\t@echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" -\t@echo " lualatexpdf to make LaTeX files and run them through pdflatex" -\t@echo " xelatexpdf to make LaTeX files and run them through pdflatex" -\t@echo " text to make text files" -\t@echo " man to make manual pages" -\t@echo " texinfo to make Texinfo files" -\t@echo " info to make Texinfo files and run them through makeinfo" -\t@echo " gettext to make PO message catalogs" -\t@echo " changes to make an overview of all changed/added/deprecated items" -\t@echo " xml to make Docutils-native XML files" -\t@echo " pseudoxml to make pseudoxml-XML files for display purposes" -\t@echo " linkcheck to check all external links for integrity" -\t@echo " doctest to run all doctests embedded in the documentation \ -(if enabled)" -\t@echo " coverage to run coverage check of the documentation (if enabled)" -\t@echo " dummy to check syntax errors of document sources" - -.PHONY: clean -clean: -\trm -rf $(BUILDDIR)/* - -.PHONY: html -html: -\t$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html -\t@echo -\t@echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -.PHONY: dirhtml -dirhtml: -\t$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml -\t@echo -\t@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -.PHONY: singlehtml -singlehtml: -\t$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml -\t@echo -\t@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." - -.PHONY: pickle -pickle: -\t$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle -\t@echo -\t@echo "Build finished; now you can process the pickle files." - -.PHONY: json -json: -\t$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json -\t@echo -\t@echo "Build finished; now you can process the JSON files." - -.PHONY: htmlhelp -htmlhelp: -\t$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp -\t@echo -\t@echo "Build finished; now you can run HTML Help Workshop with the" \\ -\t ".hhp project file in $(BUILDDIR)/htmlhelp." - -.PHONY: qthelp -qthelp: -\t$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp -\t@echo -\t@echo "Build finished; now you can run "qcollectiongenerator" with the" \\ -\t ".qhcp project file in $(BUILDDIR)/qthelp, like this:" -\t@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/%(project_fn)s.qhcp" -\t@echo "To view the help file:" -\t@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/%(project_fn)s.qhc" - -.PHONY: applehelp -applehelp: -\t$(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp -\t@echo -\t@echo "Build finished. The help book is in $(BUILDDIR)/applehelp." -\t@echo "N.B. You won't be able to view it unless you put it in" \\ -\t "~/Library/Documentation/Help or install it in your application" \\ -\t "bundle." - -.PHONY: devhelp -devhelp: -\t$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp -\t@echo -\t@echo "Build finished." -\t@echo "To view the help file:" -\t@echo "# mkdir -p $$HOME/.local/share/devhelp/%(project_fn)s" -\t@echo "# ln -s $(BUILDDIR)/devhelp\ - $$HOME/.local/share/devhelp/%(project_fn)s" -\t@echo "# devhelp" - -.PHONY: epub -epub: -\t$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub -\t@echo -\t@echo "Build finished. The epub file is in $(BUILDDIR)/epub." - -.PHONY: epub3 -epub3: -\t$(SPHINXBUILD) -b epub3 $(ALLSPHINXOPTS) $(BUILDDIR)/epub3 -\t@echo -\t@echo "Build finished. The epub3 file is in $(BUILDDIR)/epub3." - -.PHONY: latex -latex: -\t$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex -\t@echo -\t@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." -\t@echo "Run \\`make' in that directory to run these through (pdf)latex" \\ -\t "(use \\`make latexpdf' here to do that automatically)." - -.PHONY: latexpdf -latexpdf: -\t$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex -\t@echo "Running LaTeX files through pdflatex..." -\t$(MAKE) -C $(BUILDDIR)/latex all-pdf -\t@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -.PHONY: latexpdfja -latexpdfja: -\t$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex -\t@echo "Running LaTeX files through platex and dvipdfmx..." -\t$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja -\t@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -.PHONY: lualatexpdf -lualatexpdf: -\t$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex -\t@echo "Running LaTeX files through lualatex..." -\t$(MAKE) PDFLATEX=lualatex -C $(BUILDDIR)/latex all-pdf -\t@echo "lualatex finished; the PDF files are in $(BUILDDIR)/latex." - -.PHONY: xelatexpdf -xelatexpdf: -\t$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex -\t@echo "Running LaTeX files through xelatex..." -\t$(MAKE) PDFLATEX=xelatex -C $(BUILDDIR)/latex all-pdf -\t@echo "xelatex finished; the PDF files are in $(BUILDDIR)/latex." - -.PHONY: text -text: -\t$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text -\t@echo -\t@echo "Build finished. The text files are in $(BUILDDIR)/text." - -.PHONY: man -man: -\t$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man -\t@echo -\t@echo "Build finished. The manual pages are in $(BUILDDIR)/man." - -.PHONY: texinfo -texinfo: -\t$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo -\t@echo -\t@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." -\t@echo "Run \\`make' in that directory to run these through makeinfo" \\ -\t "(use \\`make info' here to do that automatically)." - -.PHONY: info -info: -\t$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo -\t@echo "Running Texinfo files through makeinfo..." -\tmake -C $(BUILDDIR)/texinfo info -\t@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." - -.PHONY: gettext -gettext: -\t$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale -\t@echo -\t@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." - -.PHONY: changes -changes: -\t$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes -\t@echo -\t@echo "The overview file is in $(BUILDDIR)/changes." - -.PHONY: linkcheck -linkcheck: -\t$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck -\t@echo -\t@echo "Link check complete; look for any errors in the above output " \\ -\t "or in $(BUILDDIR)/linkcheck/output.txt." - -.PHONY: doctest -doctest: -\t$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest -\t@echo "Testing of doctests in the sources finished, look at the " \\ -\t "results in $(BUILDDIR)/doctest/output.txt." - -.PHONY: coverage -coverage: -\t$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage -\t@echo "Testing of coverage in the sources finished, look at the " \\ -\t "results in $(BUILDDIR)/coverage/python.txt." - -.PHONY: xml -xml: -\t$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml -\t@echo -\t@echo "Build finished. The XML files are in $(BUILDDIR)/xml." - -.PHONY: pseudoxml -pseudoxml: -\t$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml -\t@echo -\t@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." - -.PHONY: dummy -dummy: -\t$(SPHINXBUILD) -b dummy $(ALLSPHINXOPTS) $(BUILDDIR)/dummy -\t@echo -\t@echo "Build finished. Dummy builder generates no files." -''' - -BATCHFILE = u'''\ -@ECHO OFF - -REM Command file for Sphinx documentation - -if "%%SPHINXBUILD%%" == "" ( -\tset SPHINXBUILD=sphinx-build -) -set BUILDDIR=%(rbuilddir)s -set ALLSPHINXOPTS=-d %%BUILDDIR%%/doctrees %%SPHINXOPTS%% %(rsrcdir)s -set I18NSPHINXOPTS=%%SPHINXOPTS%% %(rsrcdir)s -if NOT "%%PAPER%%" == "" ( -\tset ALLSPHINXOPTS=-D latex_paper_size=%%PAPER%% %%ALLSPHINXOPTS%% -\tset I18NSPHINXOPTS=-D latex_paper_size=%%PAPER%% %%I18NSPHINXOPTS%% -) - -if "%%1" == "" goto help - -if "%%1" == "help" ( -\t:help -\techo.Please use `make ^` where ^ is one of -\techo. html to make standalone HTML files -\techo. dirhtml to make HTML files named index.html in directories -\techo. singlehtml to make a single large HTML file -\techo. pickle to make pickle files -\techo. json to make JSON files -\techo. htmlhelp to make HTML files and a HTML help project -\techo. qthelp to make HTML files and a qthelp project -\techo. devhelp to make HTML files and a Devhelp project -\techo. epub to make an epub -\techo. epub3 to make an epub3 -\techo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter -\techo. text to make text files -\techo. man to make manual pages -\techo. texinfo to make Texinfo files -\techo. gettext to make PO message catalogs -\techo. changes to make an overview over all changed/added/deprecated items -\techo. xml to make Docutils-native XML files -\techo. pseudoxml to make pseudoxml-XML files for display purposes -\techo. linkcheck to check all external links for integrity -\techo. doctest to run all doctests embedded in the documentation if enabled -\techo. coverage to run coverage check of the documentation if enabled -\techo. dummy to check syntax errors of document sources -\tgoto end -) - -if "%%1" == "clean" ( -\tfor /d %%%%i in (%%BUILDDIR%%\*) do rmdir /q /s %%%%i -\tdel /q /s %%BUILDDIR%%\* -\tgoto end -) - - -REM Check if sphinx-build is available and fallback to Python version if any -%%SPHINXBUILD%% 1>NUL 2>NUL -if errorlevel 9009 goto sphinx_python -goto sphinx_ok - -:sphinx_python - -set SPHINXBUILD=python -m sphinx.__init__ -%%SPHINXBUILD%% 2> nul -if errorlevel 9009 ( -\techo. -\techo.The 'sphinx-build' command was not found. Make sure you have Sphinx -\techo.installed, then set the SPHINXBUILD environment variable to point -\techo.to the full path of the 'sphinx-build' executable. Alternatively you -\techo.may add the Sphinx directory to PATH. -\techo. -\techo.If you don't have Sphinx installed, grab it from -\techo.http://sphinx-doc.org/ -\texit /b 1 -) - -:sphinx_ok - - -if "%%1" == "html" ( -\t%%SPHINXBUILD%% -b html %%ALLSPHINXOPTS%% %%BUILDDIR%%/html -\tif errorlevel 1 exit /b 1 -\techo. -\techo.Build finished. The HTML pages are in %%BUILDDIR%%/html. -\tgoto end -) - -if "%%1" == "dirhtml" ( -\t%%SPHINXBUILD%% -b dirhtml %%ALLSPHINXOPTS%% %%BUILDDIR%%/dirhtml -\tif errorlevel 1 exit /b 1 -\techo. -\techo.Build finished. The HTML pages are in %%BUILDDIR%%/dirhtml. -\tgoto end -) - -if "%%1" == "singlehtml" ( -\t%%SPHINXBUILD%% -b singlehtml %%ALLSPHINXOPTS%% %%BUILDDIR%%/singlehtml -\tif errorlevel 1 exit /b 1 -\techo. -\techo.Build finished. The HTML pages are in %%BUILDDIR%%/singlehtml. -\tgoto end -) - -if "%%1" == "pickle" ( -\t%%SPHINXBUILD%% -b pickle %%ALLSPHINXOPTS%% %%BUILDDIR%%/pickle -\tif errorlevel 1 exit /b 1 -\techo. -\techo.Build finished; now you can process the pickle files. -\tgoto end -) - -if "%%1" == "json" ( -\t%%SPHINXBUILD%% -b json %%ALLSPHINXOPTS%% %%BUILDDIR%%/json -\tif errorlevel 1 exit /b 1 -\techo. -\techo.Build finished; now you can process the JSON files. -\tgoto end -) - -if "%%1" == "htmlhelp" ( -\t%%SPHINXBUILD%% -b htmlhelp %%ALLSPHINXOPTS%% %%BUILDDIR%%/htmlhelp -\tif errorlevel 1 exit /b 1 -\techo. -\techo.Build finished; now you can run HTML Help Workshop with the ^ -.hhp project file in %%BUILDDIR%%/htmlhelp. -\tgoto end -) - -if "%%1" == "qthelp" ( -\t%%SPHINXBUILD%% -b qthelp %%ALLSPHINXOPTS%% %%BUILDDIR%%/qthelp -\tif errorlevel 1 exit /b 1 -\techo. -\techo.Build finished; now you can run "qcollectiongenerator" with the ^ -.qhcp project file in %%BUILDDIR%%/qthelp, like this: -\techo.^> qcollectiongenerator %%BUILDDIR%%\\qthelp\\%(project_fn)s.qhcp -\techo.To view the help file: -\techo.^> assistant -collectionFile %%BUILDDIR%%\\qthelp\\%(project_fn)s.ghc -\tgoto end -) - -if "%%1" == "devhelp" ( -\t%%SPHINXBUILD%% -b devhelp %%ALLSPHINXOPTS%% %%BUILDDIR%%/devhelp -\tif errorlevel 1 exit /b 1 -\techo. -\techo.Build finished. -\tgoto end -) - -if "%%1" == "epub" ( -\t%%SPHINXBUILD%% -b epub %%ALLSPHINXOPTS%% %%BUILDDIR%%/epub -\tif errorlevel 1 exit /b 1 -\techo. -\techo.Build finished. The epub file is in %%BUILDDIR%%/epub. -\tgoto end -) - -if "%%1" == "epub3" ( -\t%%SPHINXBUILD%% -b epub3 %%ALLSPHINXOPTS%% %%BUILDDIR%%/epub3 -\tif errorlevel 1 exit /b 1 -\techo. -\techo.Build finished. The epub3 file is in %%BUILDDIR%%/epub3. -\tgoto end -) - -if "%%1" == "latex" ( -\t%%SPHINXBUILD%% -b latex %%ALLSPHINXOPTS%% %%BUILDDIR%%/latex -\tif errorlevel 1 exit /b 1 -\techo. -\techo.Build finished; the LaTeX files are in %%BUILDDIR%%/latex. -\tgoto end -) - -if "%%1" == "latexpdf" ( -\t%%SPHINXBUILD%% -b latex %%ALLSPHINXOPTS%% %%BUILDDIR%%/latex -\tcd %%BUILDDIR%%/latex -\tmake all-pdf -\tcd %%~dp0 -\techo. -\techo.Build finished; the PDF files are in %%BUILDDIR%%/latex. -\tgoto end -) - -if "%%1" == "latexpdfja" ( -\t%%SPHINXBUILD%% -b latex %%ALLSPHINXOPTS%% %%BUILDDIR%%/latex -\tcd %%BUILDDIR%%/latex -\tmake all-pdf-ja -\tcd %%~dp0 -\techo. -\techo.Build finished; the PDF files are in %%BUILDDIR%%/latex. -\tgoto end -) - -if "%%1" == "text" ( -\t%%SPHINXBUILD%% -b text %%ALLSPHINXOPTS%% %%BUILDDIR%%/text -\tif errorlevel 1 exit /b 1 -\techo. -\techo.Build finished. The text files are in %%BUILDDIR%%/text. -\tgoto end -) - -if "%%1" == "man" ( -\t%%SPHINXBUILD%% -b man %%ALLSPHINXOPTS%% %%BUILDDIR%%/man -\tif errorlevel 1 exit /b 1 -\techo. -\techo.Build finished. The manual pages are in %%BUILDDIR%%/man. -\tgoto end -) - -if "%%1" == "texinfo" ( -\t%%SPHINXBUILD%% -b texinfo %%ALLSPHINXOPTS%% %%BUILDDIR%%/texinfo -\tif errorlevel 1 exit /b 1 -\techo. -\techo.Build finished. The Texinfo files are in %%BUILDDIR%%/texinfo. -\tgoto end -) - -if "%%1" == "gettext" ( -\t%%SPHINXBUILD%% -b gettext %%I18NSPHINXOPTS%% %%BUILDDIR%%/locale -\tif errorlevel 1 exit /b 1 -\techo. -\techo.Build finished. The message catalogs are in %%BUILDDIR%%/locale. -\tgoto end -) - -if "%%1" == "changes" ( -\t%%SPHINXBUILD%% -b changes %%ALLSPHINXOPTS%% %%BUILDDIR%%/changes -\tif errorlevel 1 exit /b 1 -\techo. -\techo.The overview file is in %%BUILDDIR%%/changes. -\tgoto end -) - -if "%%1" == "linkcheck" ( -\t%%SPHINXBUILD%% -b linkcheck %%ALLSPHINXOPTS%% %%BUILDDIR%%/linkcheck -\tif errorlevel 1 exit /b 1 -\techo. -\techo.Link check complete; look for any errors in the above output ^ -or in %%BUILDDIR%%/linkcheck/output.txt. -\tgoto end -) - -if "%%1" == "doctest" ( -\t%%SPHINXBUILD%% -b doctest %%ALLSPHINXOPTS%% %%BUILDDIR%%/doctest -\tif errorlevel 1 exit /b 1 -\techo. -\techo.Testing of doctests in the sources finished, look at the ^ -results in %%BUILDDIR%%/doctest/output.txt. -\tgoto end -) - -if "%%1" == "coverage" ( -\t%%SPHINXBUILD%% -b coverage %%ALLSPHINXOPTS%% %%BUILDDIR%%/coverage -\tif errorlevel 1 exit /b 1 -\techo. -\techo.Testing of coverage in the sources finished, look at the ^ -results in %%BUILDDIR%%/coverage/python.txt. -\tgoto end -) - -if "%%1" == "xml" ( -\t%%SPHINXBUILD%% -b xml %%ALLSPHINXOPTS%% %%BUILDDIR%%/xml -\tif errorlevel 1 exit /b 1 -\techo. -\techo.Build finished. The XML files are in %%BUILDDIR%%/xml. -\tgoto end -) - -if "%%1" == "pseudoxml" ( -\t%%SPHINXBUILD%% -b pseudoxml %%ALLSPHINXOPTS%% %%BUILDDIR%%/pseudoxml -\tif errorlevel 1 exit /b 1 -\techo. -\techo.Build finished. The pseudo-XML files are in %%BUILDDIR%%/pseudoxml. -\tgoto end -) - -if "%%1" == "dummy" ( -\t%%SPHINXBUILD%% -b dummy %%ALLSPHINXOPTS%% %%BUILDDIR%%/dummy -\tif errorlevel 1 exit /b 1 -\techo. -\techo.Build finished. Dummy builder generates no files. -\tgoto end -) - -:end -''' - -# This will become the Makefile template for Sphinx 1.5. -MAKEFILE_NEW = u'''\ -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -SPHINXPROJ = %(project_fn)s -SOURCEDIR = %(rsrcdir)s -BUILDDIR = %(rbuilddir)s - -# Has to be explicit, otherwise we don't get "make" without targets right. -help: -\t@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -# You can add custom targets here. - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%%: -\t@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) -''' - -# This will become the make.bat template for Sphinx 1.5. -BATCHFILE_NEW = u'''\ -@ECHO OFF - -REM Command file for Sphinx documentation - -if "%%SPHINXBUILD%%" == "" ( -\tset SPHINXBUILD=sphinx-build -) -set SOURCEDIR=%(rsrcdir)s -set BUILDDIR=%(rbuilddir)s -set SPHINXPROJ=%(project_fn)s - -if "%%1" == "" goto help - -%%SPHINXBUILD%% >NUL 2>NUL -if errorlevel 9009 ( -\techo. -\techo.The 'sphinx-build' command was not found. Make sure you have Sphinx -\techo.installed, then set the SPHINXBUILD environment variable to point -\techo.to the full path of the 'sphinx-build' executable. Alternatively you -\techo.may add the Sphinx directory to PATH. -\techo. -\techo.If you don't have Sphinx installed, grab it from -\techo.http://sphinx-doc.org/ -\texit /b 1 -) - -%%SPHINXBUILD%% -M %%1 %%SOURCEDIR%% %%BUILDDIR%% %%SPHINXOPTS%% -goto end - -:help -%%SPHINXBUILD%% -M help %%SOURCEDIR%% %%BUILDDIR%% %%SPHINXOPTS%% - -:end -''' - def mkdir_p(dir): if path.isdir(dir): @@ -1134,6 +84,10 @@ def is_path(x): return x +def allow_empty(x): + return x + + def nonempty(x): if not x: raise ValidationError("Please enter some text.") @@ -1220,15 +174,12 @@ def do_prompt(d, key, text, default=None, validator=nonempty): d[key] = x -if PY3: +def convert_python_source(source, rex=re.compile(r"[uU]('.*?')")): # remove Unicode literal prefixes - def _convert_python_source(source, rex=re.compile(r"[uU]('.*?')")): + if PY3: return rex.sub('\\1', source) - - for f in ['QUICKSTART_CONF', 'EPUB_CONFIG', 'INTERSPHINX_CONFIG']: - globals()[f] = _convert_python_source(globals()[f]) - - del _convert_python_source + else: + return source def ask_user(d): @@ -1306,9 +257,9 @@ software. Each version can have multiple releases. For example, for Python the version is something like 2.5 or 3.0, while the release is something like 2.5.1 or 3.0a1. If you don't need this dual structure, just set both to the same value.''') - do_prompt(d, 'version', 'Project version') + do_prompt(d, 'version', 'Project version', '', allow_empty) if 'release' not in d: - do_prompt(d, 'release', 'Project release', d['version']) + do_prompt(d, 'release', 'Project release', d['version'], allow_empty) if 'language' not in d: print(''' @@ -1408,6 +359,7 @@ directly.''') def generate(d, overwrite=True, silent=False): """Generate project based on values in *d*.""" + template = SphinxRenderer() texescape.init() indent = ' ' * 4 @@ -1417,6 +369,7 @@ def generate(d, overwrite=True, silent=False): if 'mastertocmaxdepth' not in d: d['mastertocmaxdepth'] = 2 + d['PY3'] = PY3 d['project_fn'] = make_filename(d['project']) d['project_url'] = urlquote(d['project'].encode('idna')) d['project_manpage'] = d['project_fn'].lower() @@ -1472,34 +425,33 @@ def generate(d, overwrite=True, silent=False): else: print('File %s already exists, skipping.' % fpath) - conf_text = QUICKSTART_CONF % d - if d['epub']: - conf_text += EPUB_CONFIG % d - if d.get('ext_intersphinx'): - conf_text += INTERSPHINX_CONFIG + with open(os.path.join(package_dir, 'templates', 'quickstart', 'conf.py_t')) as f: + conf_text = convert_python_source(f.read()) - write_file(path.join(srcdir, 'conf.py'), conf_text) + write_file(path.join(srcdir, 'conf.py'), template.render_string(conf_text, d)) masterfile = path.join(srcdir, d['master'] + d['suffix']) - write_file(masterfile, MASTER_FILE % d) + write_file(masterfile, template.render('quickstart/master_doc.rst_t', d)) if d.get('make_mode') is True: - makefile_template = MAKEFILE_NEW - batchfile_template = BATCHFILE_NEW + makefile_template = 'quickstart/Makefile.new_t' + batchfile_template = 'quickstart/make.bat.new_t' else: - makefile_template = MAKEFILE - batchfile_template = BATCHFILE + makefile_template = 'quickstart/Makefile_t' + batchfile_template = 'quickstart/make.bat_t' if d['makefile'] is True: d['rsrcdir'] = d['sep'] and 'source' or '.' d['rbuilddir'] = d['sep'] and 'build' or d['dot'] + 'build' # use binary mode, to avoid writing \r\n on Windows - write_file(path.join(d['path'], 'Makefile'), makefile_template % d, u'\n') + write_file(path.join(d['path'], 'Makefile'), + template.render(makefile_template, d), u'\n') if d['batchfile'] is True: d['rsrcdir'] = d['sep'] and 'source' or '.' d['rbuilddir'] = d['sep'] and 'build' or d['dot'] + 'build' - write_file(path.join(d['path'], 'make.bat'), batchfile_template % d, u'\r\n') + write_file(path.join(d['path'], 'make.bat'), + template.render(batchfile_template, d), u'\r\n') if silent: return @@ -1650,13 +602,14 @@ def main(argv=sys.argv): try: if 'quiet' in d: - if not set(['project', 'author', 'version']).issubset(d): - print('''"quiet" is specified, but any of "project", \ -"author" or "version" is not specified.''') + if not set(['project', 'author']).issubset(d): + print('''"quiet" is specified, but any of "project" or \ +"author" is not specified.''') return - if set(['quiet', 'project', 'author', 'version']).issubset(d): + if set(['quiet', 'project', 'author']).issubset(d): # quiet mode with all required params satisfied, use default + d.setdefault('version', '') d.setdefault('release', d['version']) d2 = DEFAULT_VALUE.copy() d2.update(dict(("ext_"+ext, False) for ext in EXTENSIONS)) diff --git a/sphinx/roles.py b/sphinx/roles.py index a6583a6ea..6e8de3b4a 100644 --- a/sphinx/roles.py +++ b/sphinx/roles.py @@ -13,7 +13,6 @@ import re from six import iteritems from docutils import nodes, utils -from docutils.parsers.rst import roles from sphinx import addnodes from sphinx.locale import _ @@ -36,11 +35,6 @@ generic_docroles = { 'regexp': nodes.literal, } -for rolename, nodeclass in iteritems(generic_docroles): - generic = roles.GenericRole(rolename, nodeclass) - role = roles.CustomRole(rolename, generic, {'classes': [rolename]}) - roles.register_local_role(rolename, role) - # -- generic cross-reference role ---------------------------------------------- @@ -344,5 +338,14 @@ specific_docroles = { 'index': index_role, } -for rolename, func in iteritems(specific_docroles): - roles.register_local_role(rolename, func) + +def setup(app): + from docutils.parsers.rst import roles + + for rolename, nodeclass in iteritems(generic_docroles): + generic = roles.GenericRole(rolename, nodeclass) + role = roles.CustomRole(rolename, generic, {'classes': [rolename]}) + roles.register_local_role(rolename, role) + + for rolename, func in iteritems(specific_docroles): + roles.register_local_role(rolename, func) diff --git a/sphinx/search/__init__.py b/sphinx/search/__init__.py index 8bbce360e..6e21b2f5f 100644 --- a/sphinx/search/__init__.py +++ b/sphinx/search/__init__.py @@ -226,11 +226,13 @@ class IndexBuilder(object): def __init__(self, env, lang, options, scoring): self.env = env - # filename -> title + # docname -> title self._titles = {} - # stemmed word -> set(filenames) + # docname -> filename + self._filenames = {} + # stemmed word -> set(docname) self._mapping = {} - # stemmed words in titles -> set(filenames) + # stemmed words in titles -> set(docname) self._title_mapping = {} # word -> stemmed word self._stem_cache = {} @@ -338,15 +340,16 @@ class IndexBuilder(object): def freeze(self): """Create a usable data structure for serializing.""" - filenames, titles = zip(*sorted(self._titles.items())) - fn2index = dict((f, i) for (i, f) in enumerate(filenames)) + docnames, titles = zip(*sorted(self._titles.items())) + filenames = [self._filenames.get(docname) for docname in docnames] + fn2index = dict((f, i) for (i, f) in enumerate(docnames)) terms, title_terms = self.get_terms(fn2index) objects = self.get_objects(fn2index) # populates _objtypes objtypes = dict((v, k[0] + ':' + k[1]) for (k, v) in iteritems(self._objtypes)) objnames = self._objnames - return dict(filenames=filenames, titles=titles, terms=terms, + return dict(docnames=docnames, filenames=filenames, titles=titles, terms=terms, objects=objects, objtypes=objtypes, objnames=objnames, titleterms=title_terms, envversion=self.env.version) @@ -365,9 +368,11 @@ class IndexBuilder(object): for wordnames in itervalues(self._title_mapping): wordnames.intersection_update(filenames) - def feed(self, filename, title, doctree): + def feed(self, docname, filename, title, doctree): """Feed a doctree to the index.""" - self._titles[filename] = title + self._titles[docname] = title + self._filenames[docname] = filename + visitor = WordCollector(doctree, self.lang) doctree.walk(visitor) @@ -381,14 +386,19 @@ class IndexBuilder(object): _filter = self.lang.word_filter for word in visitor.found_title_words: - word = stem(word) - if _filter(word): - self._title_mapping.setdefault(word, set()).add(filename) + stemmed_word = stem(word) + if _filter(stemmed_word): + self._title_mapping.setdefault(stemmed_word, set()).add(docname) + elif _filter(word): # stemmer must not remove words from search index + self._title_mapping.setdefault(word, set()).add(docname) for word in visitor.found_words: - word = stem(word) - if word not in self._title_mapping and _filter(word): - self._mapping.setdefault(word, set()).add(filename) + stemmed_word = stem(word) + # again, stemmer must not remove words from search index + if not _filter(stemmed_word) and _filter(word): + stemmed_word = word + if stemmed_word not in self._title_mapping and _filter(stemmed_word): + self._mapping.setdefault(stemmed_word, set()).add(docname) def context_for_searchtool(self): return dict( diff --git a/tests/roots/test-html_extra_path/extra/.htaccess b/sphinx/search/test similarity index 100% rename from tests/roots/test-html_extra_path/extra/.htaccess rename to sphinx/search/test diff --git a/sphinx/setup_command.py b/sphinx/setup_command.py index 128c1415c..7df8bd6e8 100644 --- a/sphinx/setup_command.py +++ b/sphinx/setup_command.py @@ -15,6 +15,8 @@ from __future__ import print_function import sys import os +import traceback + from distutils.cmd import Command from distutils.errors import DistutilsOptionError, DistutilsExecError @@ -71,6 +73,7 @@ class BuildDoc(Command): ('build-dir=', None, 'Build directory'), ('config-dir=', 'c', 'Location of the configuration directory'), ('builder=', 'b', 'The builder to use. Defaults to "html"'), + ('warning-is-error', 'W', 'Turn warning into errors'), ('project=', None, 'The documented project\'s name'), ('version=', None, 'The short X.Y version'), ('release=', None, 'The full version, including alpha/beta/rc tags'), @@ -78,13 +81,17 @@ class BuildDoc(Command): 'replacement for |today|'), ('link-index', 'i', 'Link index.html to the master doc'), ('copyright', None, 'The copyright string'), + ('pdb', None, 'Start pdb on exception'), ] - boolean_options = ['fresh-env', 'all-files', 'link-index'] + boolean_options = ['fresh-env', 'all-files', 'warning-is-error', + 'link-index'] def initialize_options(self): self.fresh_env = self.all_files = False + self.pdb = False self.source_dir = self.build_dir = None self.builder = 'html' + self.warning_is_error = False self.project = '' self.version = '' self.release = '' @@ -158,7 +165,8 @@ class BuildDoc(Command): app = Sphinx(self.source_dir, self.config_dir, self.builder_target_dir, self.doctree_dir, self.builder, confoverrides, status_stream, - freshenv=self.fresh_env) + freshenv=self.fresh_env, + warningiserror=self.warning_is_error) try: app.build(force_all=self.all_files) @@ -166,13 +174,20 @@ class BuildDoc(Command): raise DistutilsExecError( 'caused by %s builder.' % app.builder.name) except Exception as err: - from docutils.utils import SystemMessage - if isinstance(err, SystemMessage): - print(darkred('reST markup error:'), file=sys.stderr) - print(err.args[0].encode('ascii', 'backslashreplace'), + if self.pdb: + import pdb + print(darkred('Exception occurred while building, starting debugger:'), file=sys.stderr) + traceback.print_exc() + pdb.post_mortem(sys.exc_info()[2]) else: - raise + from docutils.utils import SystemMessage + if isinstance(err, SystemMessage): + print(darkred('reST markup error:'), file=sys.stderr) + print(err.args[0].encode('ascii', 'backslashreplace'), + file=sys.stderr) + else: + raise if self.link_index: src = app.config.master_doc + app.builder.out_suffix diff --git a/sphinx/templates/latex/content.tex_t b/sphinx/templates/latex/content.tex_t new file mode 100644 index 000000000..cac910945 --- /dev/null +++ b/sphinx/templates/latex/content.tex_t @@ -0,0 +1,41 @@ +%% Generated by Sphinx. +\def\sphinxdocclass{<%= docclass %>} +\newif\ifsphinxKeepOldNames <%= keepoldnames %> +\documentclass[<%= papersize %>,<%= pointsize %><%= classoptions %>]{<%= wrapperclass %>} +\ifdefined\pdfpxdimen + \let\sphinxpxdimen\pdfpxdimen\else\newdimen\sphinxpxdimen +\fi \sphinxpxdimen=<%= pxunit %>\relax +<%= passoptionstopackages %> +<%= inputenc %> +<%= utf8extra %> +<%= cmappkg %> +<%= fontenc %> +<%= amsmath %> +<%= babel %> +<%= fontpkg %> +<%= fncychap %> +<%= longtable %> +\usepackage{sphinx} +\usepackage{multirow} +\usepackage{eqparbox} +<%= usepackages %> +<%= contentsname %> +<%= numfig_format %> +<%= pageautorefname %> +<%= tocdepth %> +<%= secnumdepth %> +<%= preamble %> + +\title{<%= title %>} +\date{<%= date %>} +\release{<%= release %>} +\author{<%= author %>} +\newcommand{\sphinxlogo}{<%= logo %>} +\renewcommand{\releasename}{<%= releasename %>} +<%= makeindex %> +<%= body %> +<%= footer %> +<%= indices %> +\renewcommand{\indexname}{<%= indexname %>} +<%= printindex %> +\end{document} diff --git a/sphinx/templates/quickstart/Makefile.new_t b/sphinx/templates/quickstart/Makefile.new_t new file mode 100644 index 000000000..f160bc212 --- /dev/null +++ b/sphinx/templates/quickstart/Makefile.new_t @@ -0,0 +1,21 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +SPHINXPROJ = {{ project_fn }} +SOURCEDIR = {{ rsrcdir }} +BUILDDIR = {{ rbuilddir }} + +# Has to be explicit, otherwise we don't get "make" without targets right. +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +# You can add custom targets here. + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + diff --git a/sphinx/templates/quickstart/Makefile_t b/sphinx/templates/quickstart/Makefile_t new file mode 100644 index 000000000..f86d2545a --- /dev/null +++ b/sphinx/templates/quickstart/Makefile_t @@ -0,0 +1,242 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = {{ rbuilddir }} + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) {{ rsrcdir }} +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) {{ rsrcdir }} + +.PHONY: help +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " applehelp to make an Apple Help Book" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " epub3 to make an epub3" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" + @echo " lualatexpdf to make LaTeX files and run them through lualatex" + @echo " xelatexpdf to make LaTeX files and run them through xelatex" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " texinfo to make Texinfo files" + @echo " info to make Texinfo files and run them through makeinfo" + @echo " gettext to make PO message catalogs" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " xml to make Docutils-native XML files" + @echo " pseudoxml to make pseudoxml-XML files for display purposes" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + @echo " coverage to run coverage check of the documentation (if enabled)" + @echo " dummy to check syntax errors of document sources" + +.PHONY: clean +clean: + rm -rf $(BUILDDIR)/* + +.PHONY: html +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +.PHONY: dirhtml +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +.PHONY: singlehtml +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +.PHONY: pickle +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +.PHONY: json +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +.PHONY: htmlhelp +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +.PHONY: qthelp +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/{{ project_fn }}.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/{{ project_fn }}.qhc" + +.PHONY: applehelp +applehelp: + $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp + @echo + @echo "Build finished. The help book is in $(BUILDDIR)/applehelp." + @echo "N.B. You won't be able to view it unless you put it in" \ + "~/Library/Documentation/Help or install it in your application" \ + "bundle." + +.PHONY: devhelp +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/{{ project_fn }}" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/{{ project_fn }}" + @echo "# devhelp" + +.PHONY: epub +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +.PHONY: epub3 +epub3: + $(SPHINXBUILD) -b epub3 $(ALLSPHINXOPTS) $(BUILDDIR)/epub3 + @echo + @echo "Build finished. The epub3 file is in $(BUILDDIR)/epub3." + +.PHONY: latex +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +.PHONY: latexpdf +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +.PHONY: latexpdfja +latexpdfja: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through platex and dvipdfmx..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +.PHONY: lualatexpdf +lualatexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through lualatex..." + $(MAKE) PDFLATEX=lualatex -C $(BUILDDIR)/latex all-pdf + @echo "lualatex finished; the PDF files are in $(BUILDDIR)/latex." + +.PHONY: xelatexpdf +xelatexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through xelatex..." + $(MAKE) PDFLATEX=xelatex -C $(BUILDDIR)/latex all-pdf + @echo "xelatex finished; the PDF files are in $(BUILDDIR)/latex." + +.PHONY: text +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +.PHONY: man +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +.PHONY: texinfo +texinfo: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo + @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." + @echo "Run \`make' in that directory to run these through makeinfo" \ + "(use \`make info' here to do that automatically)." + +.PHONY: info +info: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo "Running Texinfo files through makeinfo..." + make -C $(BUILDDIR)/texinfo info + @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." + +.PHONY: gettext +gettext: + $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale + @echo + @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." + +.PHONY: changes +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +.PHONY: linkcheck +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +.PHONY: doctest +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." + +.PHONY: coverage +coverage: + $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage + @echo "Testing of coverage in the sources finished, look at the " \ + "results in $(BUILDDIR)/coverage/python.txt." + +.PHONY: xml +xml: + $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml + @echo + @echo "Build finished. The XML files are in $(BUILDDIR)/xml." + +.PHONY: pseudoxml +pseudoxml: + $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml + @echo + @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." + +.PHONY: dummy +dummy: + $(SPHINXBUILD) -b dummy $(ALLSPHINXOPTS) $(BUILDDIR)/dummy + @echo + @echo "Build finished. Dummy builder generates no files." + diff --git a/sphinx/templates/quickstart/conf.py_t b/sphinx/templates/quickstart/conf.py_t new file mode 100644 index 000000000..5022bbdb5 --- /dev/null +++ b/sphinx/templates/quickstart/conf.py_t @@ -0,0 +1,433 @@ +{% if PY3 -%} +#!/usr/bin/env python3 +{% endif -%} +# -*- coding: utf-8 -*- +# +# {{ project }} documentation build configuration file, created by +# sphinx-quickstart on {{ now }}. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +# import os +# import sys +# sys.path.insert(0, os.path.abspath('.')) + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [{{ extensions }}] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['{{ dot }}templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = '{{ suffix }}' + +# The encoding of source files. +# +# source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = '{{ master_str }}' + +# General information about the project. +project = u'{{ project_str }}' +copyright = u'{{ copyright_str }}' +author = u'{{ author_str }}' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = u'{{ version_str }}' +# The full version, including alpha/beta/rc tags. +release = u'{{ release_str }}' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = {{ language | repr }} + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +# +# today = '' +# +# Else, today_fmt is used as the format for a strftime call. +# +# today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This patterns also effect to html_static_path and html_extra_path +exclude_patterns = [{{ exclude_patterns }}] + +# The reST default role (used for this markup: `text`) to use for all +# documents. +# +# default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +# +# add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +# +# add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +# +# show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +# modindex_common_prefix = [] + +# If true, keep warnings as "system message" paragraphs in the built documents. +# keep_warnings = False + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = {{ ext_todo }} + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'alabaster' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +# html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +# html_theme_path = [] + +# The name for this set of Sphinx documents. +# " v documentation" by default. +# +# html_title = u'{{ project_str }} v{{ release_str }}' + +# A shorter title for the navigation bar. Default is the same as html_title. +# +# html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +# +# html_logo = None + +# The name of an image file (relative to this directory) to use as a favicon of +# the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +# +# html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['{{ dot }}static'] + +# Add any extra paths that contain custom files (such as robots.txt or +# .htaccess) here, relative to this directory. These files are copied +# directly to the root of the documentation. +# +# html_extra_path = [] + +# If not None, a 'Last updated on:' timestamp is inserted at every page +# bottom, using the given strftime format. +# The empty string is equivalent to '%b %d, %Y'. +# +# html_last_updated_fmt = None + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +# +# html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +# +# html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +# +# html_additional_pages = {} + +# If false, no module index is generated. +# +# html_domain_indices = True + +# If false, no index is generated. +# +# html_use_index = True + +# If true, the index is split into individual pages for each letter. +# +# html_split_index = False + +# If true, links to the reST sources are added to the pages. +# +# html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +# +# html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +# +# html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +# +# html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +# html_file_suffix = None + +# Language to be used for generating the HTML full-text search index. +# Sphinx supports the following languages: +# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' +# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr', 'zh' +# +# html_search_language = 'en' + +# A dictionary with options for the search language support, empty by default. +# 'ja' uses this config value. +# 'zh' user can custom change `jieba` dictionary path. +# +# html_search_options = {'type': 'default'} + +# The name of a javascript file (relative to the configuration directory) that +# implements a search results scorer. If empty, the default will be used. +# +# html_search_scorer = 'scorer.js' + +# Output file base name for HTML help builder. +htmlhelp_basename = '{{ project_fn }}doc' + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, '{{ project_fn }}.tex', u'{{ project_doc_texescaped_str }}', + u'{{ author_texescaped_str }}', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +# +# latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +# +# latex_use_parts = False + +# If true, show page references after internal links. +# +# latex_show_pagerefs = False + +# If true, show URL addresses after external links. +# +# latex_show_urls = False + +# Documents to append as an appendix to all manuals. +# +# latex_appendices = [] + +# It false, will not define \strong, \code, \titleref, \crossref ... but only +# \sphinxstrong, ..., \sphinxtitleref, ... To help avoid clash with user added +# packages. +# +# latex_keep_old_macro_names = True + +# If false, no module index is generated. +# +# latex_domain_indices = True + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, '{{ project_manpage }}', u'{{ project_doc_str }}', + [author], 1) +] + +# If true, show URL addresses after external links. +# +# man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, '{{ project_fn }}', u'{{ project_doc_str }}', + author, '{{ project_fn }}', 'One line description of project.', + 'Miscellaneous'), +] + +# Documents to append as an appendix to all manuals. +# +# texinfo_appendices = [] + +# If false, no module index is generated. +# +# texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +# +# texinfo_show_urls = 'footnote' + +# If true, do not generate a @detailmenu in the "Top" node's menu. +# +# texinfo_no_detailmenu = False + +{% if epub %} +# -- Options for Epub output ---------------------------------------------- + +# Bibliographic Dublin Core info. +epub_title = project +epub_author = author +epub_publisher = author +epub_copyright = copyright + +# The basename for the epub file. It defaults to the project name. +# epub_basename = project + +# The HTML theme for the epub output. Since the default themes are not +# optimized for small screen space, using the same theme for HTML and epub +# output is usually not wise. This defaults to 'epub', a theme designed to save +# visual space. +# +# epub_theme = 'epub' + +# The language of the text. It defaults to the language option +# or 'en' if the language is not set. +# +# epub_language = '' + +# The scheme of the identifier. Typical schemes are ISBN or URL. +# epub_scheme = '' + +# The unique identifier of the text. This can be a ISBN number +# or the project homepage. +# +# epub_identifier = '' + +# A unique identification for the text. +# +# epub_uid = '' + +# A tuple containing the cover image and cover page html template filenames. +# +# epub_cover = () + +# A sequence of (type, uri, title) tuples for the guide element of content.opf. +# +# epub_guide = () + +# HTML files that should be inserted before the pages created by sphinx. +# The format is a list of tuples containing the path and title. +# +# epub_pre_files = [] + +# HTML files that should be inserted after the pages created by sphinx. +# The format is a list of tuples containing the path and title. +# +# epub_post_files = [] + +# A list of files that should not be packed into the epub file. +epub_exclude_files = ['search.html'] + +# The depth of the table of contents in toc.ncx. +# +# epub_tocdepth = 3 + +# Allow duplicate toc entries. +# +# epub_tocdup = True + +# Choose between 'default' and 'includehidden'. +# +# epub_tocscope = 'default' + +# Fix unsupported image types using the Pillow. +# +# epub_fix_images = False + +# Scale large images. +# +# epub_max_image_width = 0 + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +# +# epub_show_urls = 'inline' + +# If false, no index is generated. +# +# epub_use_index = True +{% endif %} + +{% if ext_intersphinx %} +# Example configuration for intersphinx: refer to the Python standard library. +intersphinx_mapping = {'https://docs.python.org/': None} +{% endif %} + diff --git a/sphinx/templates/quickstart/make.bat.new_t b/sphinx/templates/quickstart/make.bat.new_t new file mode 100644 index 000000000..4ed82305c --- /dev/null +++ b/sphinx/templates/quickstart/make.bat.new_t @@ -0,0 +1,34 @@ +@ECHO OFF + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR={{ rsrcdir }} +set BUILDDIR={{ rbuilddir }} +set SPHINXPROJ={{ project_fn }} + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% + +:end + diff --git a/sphinx/templates/quickstart/make.bat_t b/sphinx/templates/quickstart/make.bat_t new file mode 100644 index 000000000..88a8fa9d9 --- /dev/null +++ b/sphinx/templates/quickstart/make.bat_t @@ -0,0 +1,282 @@ +@ECHO OFF + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set BUILDDIR={{ rbuilddir }} +set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% {{ rsrcdir }} +set I18NSPHINXOPTS=%SPHINXOPTS% {{ rsrcdir }} +if NOT "%PAPER%" == "" ( + set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% + set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% +) + +if "%1" == "" goto help + +if "%1" == "help" ( + :help + echo.Please use `make ^` where ^ is one of + echo. html to make standalone HTML files + echo. dirhtml to make HTML files named index.html in directories + echo. singlehtml to make a single large HTML file + echo. pickle to make pickle files + echo. json to make JSON files + echo. htmlhelp to make HTML files and a HTML help project + echo. qthelp to make HTML files and a qthelp project + echo. devhelp to make HTML files and a Devhelp project + echo. epub to make an epub + echo. epub3 to make an epub3 + echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter + echo. text to make text files + echo. man to make manual pages + echo. texinfo to make Texinfo files + echo. gettext to make PO message catalogs + echo. changes to make an overview over all changed/added/deprecated items + echo. xml to make Docutils-native XML files + echo. pseudoxml to make pseudoxml-XML files for display purposes + echo. linkcheck to check all external links for integrity + echo. doctest to run all doctests embedded in the documentation if enabled + echo. coverage to run coverage check of the documentation if enabled + echo. dummy to check syntax errors of document sources + goto end +) + +if "%1" == "clean" ( + for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i + del /q /s %BUILDDIR%\* + goto end +) + + +REM Check if sphinx-build is available and fallback to Python version if any +%SPHINXBUILD% 1>NUL 2>NUL +if errorlevel 9009 goto sphinx_python +goto sphinx_ok + +:sphinx_python + +set SPHINXBUILD=python -m sphinx.__init__ +%SPHINXBUILD% 2> nul +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +:sphinx_ok + + +if "%1" == "html" ( + %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/html. + goto end +) + +if "%1" == "dirhtml" ( + %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. + goto end +) + +if "%1" == "singlehtml" ( + %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. + goto end +) + +if "%1" == "pickle" ( + %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the pickle files. + goto end +) + +if "%1" == "json" ( + %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the JSON files. + goto end +) + +if "%1" == "htmlhelp" ( + %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run HTML Help Workshop with the ^ +.hhp project file in %BUILDDIR%/htmlhelp. + goto end +) + +if "%1" == "qthelp" ( + %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run "qcollectiongenerator" with the ^ +.qhcp project file in %BUILDDIR%/qthelp, like this: + echo.^> qcollectiongenerator %BUILDDIR%\qthelp\{{ project_fn }}.qhcp + echo.To view the help file: + echo.^> assistant -collectionFile %BUILDDIR%\qthelp\{{ project_fn }}.ghc + goto end +) + +if "%1" == "devhelp" ( + %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. + goto end +) + +if "%1" == "epub" ( + %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The epub file is in %BUILDDIR%/epub. + goto end +) + +if "%1" == "epub3" ( + %SPHINXBUILD% -b epub3 %ALLSPHINXOPTS% %BUILDDIR%/epub3 + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The epub3 file is in %BUILDDIR%/epub3. + goto end +) + +if "%1" == "latex" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "latexpdf" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + cd %BUILDDIR%/latex + make all-pdf + cd %~dp0 + echo. + echo.Build finished; the PDF files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "latexpdfja" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + cd %BUILDDIR%/latex + make all-pdf-ja + cd %~dp0 + echo. + echo.Build finished; the PDF files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "text" ( + %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The text files are in %BUILDDIR%/text. + goto end +) + +if "%1" == "man" ( + %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The manual pages are in %BUILDDIR%/man. + goto end +) + +if "%1" == "texinfo" ( + %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. + goto end +) + +if "%1" == "gettext" ( + %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The message catalogs are in %BUILDDIR%/locale. + goto end +) + +if "%1" == "changes" ( + %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes + if errorlevel 1 exit /b 1 + echo. + echo.The overview file is in %BUILDDIR%/changes. + goto end +) + +if "%1" == "linkcheck" ( + %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck + if errorlevel 1 exit /b 1 + echo. + echo.Link check complete; look for any errors in the above output ^ +or in %BUILDDIR%/linkcheck/output.txt. + goto end +) + +if "%1" == "doctest" ( + %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest + if errorlevel 1 exit /b 1 + echo. + echo.Testing of doctests in the sources finished, look at the ^ +results in %BUILDDIR%/doctest/output.txt. + goto end +) + +if "%1" == "coverage" ( + %SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage + if errorlevel 1 exit /b 1 + echo. + echo.Testing of coverage in the sources finished, look at the ^ +results in %BUILDDIR%/coverage/python.txt. + goto end +) + +if "%1" == "xml" ( + %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The XML files are in %BUILDDIR%/xml. + goto end +) + +if "%1" == "pseudoxml" ( + %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. + goto end +) + +if "%1" == "dummy" ( + %SPHINXBUILD% -b dummy %ALLSPHINXOPTS% %BUILDDIR%/dummy + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. Dummy builder generates no files. + goto end +) + +:end + diff --git a/sphinx/templates/quickstart/master_doc.rst_t b/sphinx/templates/quickstart/master_doc.rst_t new file mode 100644 index 000000000..f5ec13309 --- /dev/null +++ b/sphinx/templates/quickstart/master_doc.rst_t @@ -0,0 +1,22 @@ +.. {{ project }} documentation master file, created by + sphinx-quickstart on {{ now }}. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to {{ project }}'s documentation! +==========={{ project_underline }}================= + +Contents: + +.. toctree:: + :maxdepth: {{ mastertocmaxdepth }} + +{{ mastertoctree }} + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` + diff --git a/sphinx/texinputs/Makefile b/sphinx/texinputs/Makefile_t similarity index 91% rename from sphinx/texinputs/Makefile rename to sphinx/texinputs/Makefile_t index d748006cc..ffec3662c 100644 --- a/sphinx/texinputs/Makefile +++ b/sphinx/texinputs/Makefile_t @@ -3,6 +3,7 @@ ALLDOCS = $(basename $(wildcard *.tex)) ALLPDF = $(addsuffix .pdf,$(ALLDOCS)) ALLDVI = $(addsuffix .dvi,$(ALLDOCS)) +ALLPS = $(addsuffix .ps,$(ALLDOCS)) # Prefix for archive names ARCHIVEPRREFIX = @@ -12,14 +13,18 @@ LATEXOPTS = FMT = pdf LATEX = latex -PDFLATEX = pdflatex +PDFLATEX = {{ latex_engine }} MAKEINDEX = makeindex +{% if latex_engine == 'platex' %} +all: all-pdf-ja +all-pdf: all-pdf-ja +{% else %} all: $(ALLPDF) all-pdf: $(ALLPDF) +{% endif -%} all-dvi: $(ALLDVI) -all-ps: all-dvi - for f in *.dvi; do dvips $$f; done +all-ps: $(ALLPS) all-pdf-ja: for f in *.pdf *.png *.gif *.jpg *.jpeg; do extractbb $$f; done @@ -70,6 +75,9 @@ xz: tar $(PDFLATEX) $(LATEXOPTS) '$<' $(PDFLATEX) $(LATEXOPTS) '$<' +%.ps: %.dvi + dvips '$<' + clean: rm -f *.log *.ind *.aux *.toc *.syn *.idx *.out *.ilg *.pla *.ps *.tar *.tar.gz *.tar.bz2 *.tar.xz $(ALLPDF) $(ALLDVI) diff --git a/sphinx/texinputs/needspace.sty b/sphinx/texinputs/needspace.sty new file mode 100644 index 000000000..113d87216 --- /dev/null +++ b/sphinx/texinputs/needspace.sty @@ -0,0 +1,35 @@ + +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{needspace}[2010/09/12 v1.3d reserve vertical space] + +\newcommand{\needspace}[1]{% + \begingroup + \setlength{\dimen@}{#1}% + \vskip\z@\@plus\dimen@ + \penalty -100\vskip\z@\@plus -\dimen@ + \vskip\dimen@ + \penalty 9999% + \vskip -\dimen@ + \vskip\z@skip % hide the previous |\vskip| from |\addvspace| + \endgroup +} + +\newcommand{\Needspace}{\@ifstar{\@sneedsp@}{\@needsp@}} + +\newcommand{\@sneedsp@}[1]{\par \penalty-100\begingroup + \setlength{\dimen@}{#1}% + \dimen@ii\pagegoal \advance\dimen@ii-\pagetotal + \ifdim \dimen@>\dimen@ii + \break + \fi\endgroup} + +\newcommand{\@needsp@}[1]{\par \penalty-100\begingroup + \setlength{\dimen@}{#1}% + \dimen@ii\pagegoal \advance\dimen@ii-\pagetotal + \ifdim \dimen@>\dimen@ii + \ifdim \dimen@ii>\z@ + \vfil + \fi + \break + \fi\endgroup} + diff --git a/sphinx/texinputs/newfloat.sty b/sphinx/texinputs/newfloat.sty deleted file mode 100644 index 47ac5e568..000000000 --- a/sphinx/texinputs/newfloat.sty +++ /dev/null @@ -1,737 +0,0 @@ -%% -%% This is file `newfloat.sty', -%% generated with the docstrip utility. -%% -%% The original source files were: -%% -%% newfloat.dtx (with options: `package') -%% -%% Copyright (C) 1994-2016 Axel Sommerfeldt (axel.sommerfeldt@f-m.fm) -%% -%% http://sourceforge.net/projects/latex-caption/ -%% -%% -------------------------------------------------------------------------- -%% -%% This work may be distributed and/or modified under the -%% conditions of the LaTeX Project Public License, either version 1.3 -%% of this license or (at your option) any later version. -%% The latest version of this license is in -%% http://www.latex-project.org/lppl.txt -%% and version 1.3 or later is part of all distributions of LaTeX -%% version 2003/12/01 or later. -%% -%% This work has the LPPL maintenance status "maintained". -%% -%% This Current Maintainer of this work is Axel Sommerfeldt. -%% -%% This work consists of the files -%% CHANGELOG, README, SUMMARY, caption.ins, -%% caption.dtx, caption2.dtx, caption3.dtx, -%% bicaption.dtx, ltcaption.dtx, subcaption.dtx, -%% newfloat.dtx, and totalcount.dtx -%% the derived files -%% caption.sty, caption2.sty, caption3.sty, -%% bicaption.sty, ltcaption.sty, subcaption.sty, -%% newfloat.sty, and totalcount.sty -%% and the user manuals -%% caption-deu.tex, caption-eng.tex, and caption-rus.tex. -%% -\NeedsTeXFormat{LaTeX2e}[1994/12/01] -\def\caption@tempa$Id: #1 #2 #3-#4-#5 #6${% - \def\caption@tempa{#3/#4/#5 }\def\caption@tempb{#2 }} -\caption@tempa $Id: newfloat.dtx 109 2015-09-17 09:29:07Z sommerfeldt $ -\ProvidesPackage{newfloat}[\caption@tempa v1.1-\caption@tempb Defining new floating environments (AR)] -\newcommand*\newfloat@Info[1]{% - \PackageInfo{newfloat}{#1}} -\newcommand*\newfloat@InfoNoLine[1]{% - \newfloat@Info{#1\@gobble}} -\newcommand*\newfloat@Error[1]{% - \PackageError{newfloat}{#1}\newfloat@eh} -\newcommand*\newfloat@eh{% - If you do not understand this error, please take a closer look\MessageBreak - at the documentation of the `newfloat' package.\MessageBreak\@ehc} -\RequirePackage{keyval}[1997/11/10] -\newcommand*\newfloat@def[2]{% - \newfloat@ifundefined{#1}{% - \@namedef{#1}{#2}}} -\newcommand*\newfloat@let[2]{% - \newfloat@ifundefined{#1}{% - \expandafter\let\csname #1\endcsname#2}} -\newcommand*\newfloat@ifundefined[2]{% - \@ifundefined{#1}{#2}{% - \newfloat@Info{% - \expandafter\string\csname#1\endcsname\space is already defined}}} -\newcommand*\DeclareFloatingEnvironment{% - \@testopt\@DeclareFloatingEnvironment{}} -\@onlypreamble\DeclareFloatingEnvironment -\def\@DeclareFloatingEnvironment[#1]#2{% - \newfloat@Info{New float `#2' with options `#1'}% - \newfloat@ifundefined{c@#2}{\newcounter{#2}}% - \ifdefined\c@float@type % from float package - \expandafter\edef\csname ftype@#2\endcsname{\the\value{float@type}}% - \addtocounter{float@type}{\value{float@type}}% - \else\ifdefined\c@newflo@tctr % from memoir document class - \expandafter\edef\csname ftype@#2\endcsname{\the\c@newflo@tctr}% - \advance\c@newflo@tctr \c@newflo@tctr - \else - \ifdefined\newfloat@ftype \else - \newcount\newfloat@ftype - \newfloat@ftype=8\relax - \fi - \expandafter\xdef\csname ftype@#2\endcsname{\the\newfloat@ftype}% - \advance\newfloat@ftype\newfloat@ftype - \fi\fi - \newfloat@Info{float type `#2'=\@nameuse{ftype@#2}}% - \newfloat@def{fnum@#2}% - {\@nameuse{#2name}\nobreakspace\@nameuse{the#2}\@nameuse{autodot}}% - \newfloat@capitalize\newfloat@Type{#2}% - \newfloat@let{#2name}{\newfloat@Type}% - \newfloat@def{fleg#2}{\@nameuse{#2name}}% legend naming (memoir) - \newfloat@ifundefined{flegtoc#2}{\@namedef{flegtoc#2}##1{}}% - \ifcsname @tufte@float\endcsname - \newenvironment{#2}[1][htbp]% - {\begin{@tufte@float}[##1]{#2}{}}% - {\end{@tufte@float}}% - \newenvironment{#2*}[1][htbp]% - {\begin{@tufte@float}[##1]{#2}{star}}% - {\end{@tufte@float}}% - \else - \newenvironment{#2}{\@float{#2}}{\end@float}% - \newenvironment{#2*}{\@dblfloat{#2}}{\end@dblfloat}% - \fi - \newfloat@def{listof#2}{\newfloat@listof{#2}}% - \newfloat@def{listof#2s}{\@nameuse{listof#2}}% - \newfloat@def{listof#2es}{\@nameuse{listof#2s}}% - \newfloat@def{newfloat@listof#2@hook}{}% - \ifdefined\l@figure - \newfloat@let{l@#2}{\l@figure}% - \else - \newfloat@def{l@#2}{\@dottedtocline{1}{1.5em}{2.3em}}% - \fi - \edef\newfloat@tempa{List of \newfloat@Type s}% - \newfloat@let{list#2name}{\newfloat@tempa}% - \expandafter\let\csname fst@#2\endcsname\@undefined - \newfloat@ifundefined{fps@#2}{\newfloat@setplacement{#2}{tbp}}% - \newfloat@ifundefined{ext@#2}{\newfloat@setfileext{#2}{lo#2}}% - \newfloat@setoptions*{#2}{#1}% - \@expandtwoargs\newfloat@announce{#2}{\@nameuse{ext@#2}}% - \@ifnextchar[\newfloat@DFE@setname\relax} -\@onlypreamble\@DeclareFloatingEnvironment -\def\newfloat@DFE@setname[#1]{% - \KV@@newfloat@name{#1}% - \@ifnextchar[\newfloat@DFE@setlistname\relax} -\@onlypreamble\newfloat@DFE@setname -\def\newfloat@DFE@setlistname[#1]{% - \KV@@newfloat@listname{#1}} -\@onlypreamble\newfloat@DFE@setlistname -\newcommand*\newfloat@capitalize[2]{% - \edef\newfloat@tempa{\gdef\noexpand#1{\@car#2\@nil}}% - \uppercase\expandafter{\newfloat@tempa}% - \edef\newfloat@tempa{% - \noexpand\g@addto@macro\noexpand#1{\@cdr#2\@nil}}% - \newfloat@tempa} -\newcommand*\newfloat@listof[1]{% - \@expandtwoargs\newfloat@list@of{#1}{\@nameuse{ext@#1}}} -\newcommand*\newfloat@list@of[2]{% - \begingroup - \expandafter\let\expandafter\listfigurename\csname list#1name\endcsname - \def\ext@figure{#2}% - \let\newfloat@starttoc\@starttoc - \def\@starttoc##1{\newfloat@starttoc{#2}}% - \let\newfloat@listoftoc\listoftoc - \def\listoftoc##1{\newfloat@listoftoc{#2}}% - \@nameuse{newfloat@listof#1@hook}% - \listoffigures - \endgroup} -\newcommand*\newfloat@setoptions{% - \@ifstar - {\newfloat@@setoptions\@firstofone}% - {\newfloat@@setoptions\@gobble}} -\newcommand*\newfloat@@setoptions[3]{% - \let\newfloat@within@value\@undefined - \let\newfloat@chapterlistsgaps@value\@undefined - #1{\KV@@newfloat@within\newfloat@within@default}% set default value for new floats - \def\newfloat@type{#2}% - \setkeys{@newfloat}{#3}% - \ifx\newfloat@within@value\@undefined \else - \newfloat@setoption{within}\newfloat@within@value - \fi - \ifx\newfloat@chapterlistsgaps@value\@undefined \else - \newfloat@setoption{chapterlistsgaps}\newfloat@chapterlistsgaps@value - \fi} -\newcommand*\newfloat@within@default{% - \ifcsname c@chapter\endcsname chapter\else none\fi} -\@onlypreamble\newfloat@within@default -\newcommand*\newfloat@setoption[1]{% - \edef\caption@tempa{\noexpand\@nameuse{newfloat@set#1}{\newfloat@type}}% - \caption@tempa} -\newcommand*\newfloat@setfileext[2]{% - \@namedef{ext@#1}{#2}} -\define@key{@newfloat}{fileext}{% - \newfloat@setoption{fileext}{#1}} -\newcommand*\newfloat@setlistname[2]{% - \@namedef{list#1name}{#2}} -\define@key{@newfloat}{listname}{% - \newfloat@setoption{listname}{#1}} -\newcommand*\newfloat@setname[2]{% - \newfloat@@setname{#1}{#2}% - \begingroup - \ifcsname languagename\endcsname - \ifcsname captions\languagename\endcsname - \expandafter\g@addto@macro\csname captions\languagename\endcsname - {\newfloat@@setname{#1}{#2}}% - \fi - \fi - \endgroup} -%%\AtBeginDocument{\let\newfloat@setname\newfloat@@setname} -\newcommand*\newfloat@@setname[2]{% - \@namedef{#1name}{#2}} -\define@key{@newfloat}{name}{% - \newfloat@setoption{name}{#1}} -\newcommand*\newfloat@setplacement[2]{% - \@namedef{fps@#1}{#2}} -\define@key{@newfloat}{placement}{% - \newfloat@setoption{placement}{#1}} -\newcommand*\newfloat@setwithin[2]{% - \ifcsname c@chapter\endcsname - \@removefromreset{#1}{chapter}% - \fi - \@removefromreset{#1}{section}% - \edef\@tempa{#2}% - \ifx\@tempa\@empty - \def\@tempa{none}% - \fi - \def\@tempb{none}% - \ifx\@tempa\@tempb - \ifcsname c@chapter\endcsname - \@chapterlistsgap@off{#1}% - \fi - \newfloat@@setwithin{#1}{}{}% - \else - \def\@tempb{chapter}% - \ifx\@tempa\@tempb - \@addtoreset{#1}{chapter}% - \@chapterlistsgap@on{#1}% - \newfloat@@setwithin{#1}{\ifnum\c@chapter>\z@ \thechapter.\fi}{\theHchapter.}% - \else - \def\@tempb{section}% - \ifx\@tempa\@tempb - \@addtoreset{#1}{section}% - \ifcsname c@chapter\endcsname - \@addtoreset{#1}{chapter}% - \@chapterlistsgap@on{#1}% - \newfloat@@setwithin{#1}{\thesection.}{\theHsection.}% - \else - \newfloat@@setwithin{#1}{\ifnum\c@section>\z@ \thesection.\fi}{\theHsection.}% - \fi - \else - \newfloat@Error{Invalid value `#2' for option `within'}% - \fi - \fi - \fi} -\newcommand*\newfloat@@setwithin[3]{% - \global\@namedef{the#1}{#2\arabic{#1}}% - \global\@namedef{theH#1}{#3\arabic{#1}}} -\define@key{@newfloat}{within}{% - \def\newfloat@within@value{#1}} -\newcommand*\newfloat@setwithout[1]{% - \newfloat@setwithin{#1}{none}} -\define@key{@newfloat}{without}[]{% - \def\newfloat@within@value{none}} -\newcommand*\newfloat@setchapterlistsgaps[2]{% - \edef\@tempa{#2}% - \def\@tempb{off}% - \ifx\@tempa\@tempb - \@chapterlistsgap@off{#1}% - \else - \def\@tempb{on}% - \ifx\@tempa\@tempb - \@chapterlistsgap@on{#1}% - \else - \newfloat@Error{Invalid value `#2' for option `chapterlistsgaps'}% - \fi - \fi} -\define@key{@newfloat}{chapterlistsgaps}{% - \def\newfloat@chapterlistsgaps@value{#1}} -\providecommand*\@removefromreset[2]{{% - \expandafter\let\csname c@#1\endcsname\@removefromreset - \def\@elt##1{% - \expandafter\ifx\csname c@##1\endcsname\@removefromreset - \else - \noexpand\@elt{##1}% - \fi}% - \expandafter\xdef\csname cl@#2\endcsname{% - \csname cl@#2\endcsname}}} -\newcommand*\newfloat@announce[2]{% - \@cons\newfloat@list{{#1}}% - \@cons\newfloat@@list{{#1}}% - \newfloat@ifundefined{newfloat@ext@#2}{% - \@namedef{newfloat@ext@#2}{#1}% - \ifcsname c@lofdepth\endcsname - \newfloat@ifundefined{c@#2depth}{% - \newcounter{#2depth}% - \setcounter{#2depth}{1}}% - \fi - \ifcsname addtotoclist\endcsname - \addtotoclist[float]{#2}% - \newfloat@def{listof#2name}{\@nameuse{list#1name}}% - \fi - }% - \ifcsname contentsuse\endcsname - \contentsuse{#1}{#2}% - \fi - \newfloat@hook{#1}} -\@onlypreamble\newfloat@announce -\newcommand*\newfloat@@list{} -\newcommand*\SetupFloatingEnvironment[1]{% - \newfloat@addtolist{#1}% - \newfloat@setoptions{#1}} -\newcommand\ForEachFloatingEnvironment{% - \@ifstar - {\@ForEachFloatingEnvironment\@gobble}% - {\@ForEachFloatingEnvironment\@iden}} -\newcommand\@ForEachFloatingEnvironment[2]{% - \def\@elt##1{#2}% - \newfloat@list - \let\@elt\relax - #1{\newfloat@addtohook{#2}}} -\providecommand\newfloat@addtohook[1]{% - \toks@=\expandafter{\newfloat@hook{##1}#1}% - \edef\@tempa{\def\noexpand\newfloat@hook####1{\the\toks@}}% - \@tempa} -\providecommand*\newfloat@hook[1]{} -\newcommand\PrepareListOf[1]{% - \expandafter\g@addto@macro\csname newfloat@listof#1@hook\endcsname} -\@onlypreamble\PrepareListOf -\newcommand*\newfloat@list{} -\newcommand*\newfloat@addtolist[1]{% - \newfloat@ifinlist{#1}{}{% - \ifcsname ext@#1\endcsname - \@cons\newfloat@list{{#1}}% - \@namedef{newfloat@ext@\@nameuse{ext@#1}}{#1}% - \newfloat@let{@ifchapterlistsgap@#1}{\@iden}% - \else - \newfloat@Error{`#1' does not seem to be a floating environment}% - \fi}} -\newcommand*\newfloat@ifinlist[1]{% - \let\next\@secondoftwo - \begingroup - \expandafter\let\csname c@#1\endcsname\newfloat@ifinlist - \def\@elt##1{% - \expandafter\ifx\csname c@##1\endcsname\newfloat@ifinlist - \global\let\next\@firstoftwo - \fi}% - \newfloat@list - \endgroup - \next} -\ifcsname ext@figure\endcsname - \newfloat@addtolist{figure} -\fi -\ifcsname ext@table\endcsname - \newfloat@addtolist{table} -\fi -\ifcsname @chapter\endcsname - \providecommand*\@chapterlistsgap{10\p@}% - \providecommand*\@addchapterlistsgap[2]{% - \@nameuse{@ifchapterlistsgap@#1}{% if switched on - \@@addchapterlistsgap{#1}{#2}}} - \providecommand*\@@addchapterlistsgap[2]{% - \@ifundefined{@addchapterlistsgap@#2}{% only once per extension - \@namedef{@addchapterlistsgap@#2}{#1}% - \@@@addchapterlistsgap{#2}}{}} - \providecommand*\@@@addchapterlistsgap[1]{% - \ifdim \@chapterlistsgap>\z@ - \addtocontents{#1}{\protect\addvspace{\@chapterlistsgap}}% - \fi} - \providecommand*\@addchapterlistsgaps{% - \begingroup - \def\@elt##1{% - \@expandtwoargs\@addchapterlistsgap{##1}{\@nameuse{ext@##1}}}% - \newfloat@list - \endgroup} - \providecommand*\@chapterlistsgap@off[1]{% - \expandafter\let\csname @ifchapterlistsgap@#1\endcsname\@gobble - \ifcsname unsettoc\endcsname - \@expandtwoargs\unsettoc{\@nameuse{ext@#1}}{chapteratlist}% - \fi} - \providecommand*\@chapterlistsgap@on[1]{% - \expandafter\let\csname @ifchapterlistsgap@#1\endcsname\@iden - \ifcsname setuptoc\endcsname - \@expandtwoargs\setuptoc{\@nameuse{ext@#1}}{chapteratlist}% - \fi} -\fi -\define@key{newfloat}{chapterlistsgap}{% - \renewcommand*\@chapterlistsgap{#1}} -\define@key{newfloat}{within}{% - \def\newfloat@within@default{#1}% set new default value - \def\@elt##1{\newfloat@setwithin{##1}{#1}}% - \newfloat@list - \let\@elt\relax} -\define@key{newfloat}{without}[]{% - \KV@newfloat@within{none}} -\def\@elt#1{% - \define@key{newfloat}{#1name}{% - \newfloat@setname{#1}{##1}}% - \define@key{newfloat}{list#1name}{% - \newfloat@setname{list#1}{##1}}% - \define@key{newfloat}{#1within}{% - \newfloat@setwithin{#1}{##1}}% - \define@key{newfloat}{#1without}[]{% - \newfloat@setwithout{#1}}% -}% -\newfloat@list -\let\@elt\relax -\define@key{newfloat}{planb}[true]{% - \def\@tempa{#1}% - \def\@tempb{false}% - \ifx\@tempa\@tempb - \let\newfloat@ifplanb\@gobble - \else - \def\@tempb{true}% - \ifx\@tempa\@tempb - \let\newfloat@ifplanb\@iden - \else - \newfloat@Error{Invalid value `#1' for option `planb'}% - \fi - \fi} -\define@key{newfloat}{planb-fileext}{% - \newfloat@Info{Setting Plan B file extension to `#1'} - \xdef\newfloat@addtocontents@ext{#1}} - -\let\@tempc\relax -\@expandtwoargs\setkeys{newfloat}{planb,\@ptionlist{\@currname.\@currext}}% -\AtEndOfPackage{\let\@unprocessedoptions\relax} -\newcommand*\newfloatsetup{\setkeys{newfloat}} -\newcommand\newfloat@replace@chapter[2]{% - \begingroup - \let\if@twocolumn\iffalse - \let\if@mainmatter\iffalse - \let\if@thema\iffalse - \def\@tempa[##1]##2{#1}% - \ifx\@tempa\@chapter - \gdef\@chapter[##1]##2{#2}% - \global\let\newfloat@replace@chapter\@gobbletwo - \else\ifx\@tempa\Hy@org@chapter - \gdef\Hy@org@chapter[##1]##2{#2}% - \global\let\newfloat@replace@chapter\@gobbletwo - \fi\fi - \endgroup} -\ifcsname @chapter\endcsname \else - \let\newfloat@replace@chapter\@gobbletwo -\fi -\newfloat@replace@chapter{% - \ifnum \c@secnumdepth >\m@ne - \refstepcounter{chapter}% - \typeout{\@chapapp\space\thechapter.}% - \addcontentsline{toc}{chapter}% - {\protect\numberline{\thechapter}#1}% - \else - \addcontentsline{toc}{chapter}{#1}% - \fi - \chaptermark{#1}% - \addtocontents{lof}{\protect\addvspace{10\p@}}% - \addtocontents{lot}{\protect\addvspace{10\p@}}% - \if@twocolumn - \@topnewpage[\@makechapterhead{#2}]% - \else - \@makechapterhead{#2}% - \@afterheading - \fi -}{% - \ifnum \c@secnumdepth >\m@ne - \refstepcounter{chapter}% - \typeout{\@chapapp\space\thechapter.}% - \addcontentsline{toc}{chapter}% - {\protect\numberline{\thechapter}#1}% - \else - \addcontentsline{toc}{chapter}{#1}% - \fi - \chaptermark{#1}% - \@addchapterlistsgaps - \if@twocolumn - \@topnewpage[\@makechapterhead{#2}]% - \else - \@makechapterhead{#2}% - \@afterheading - \fi} -\newfloat@replace@chapter{% - \ifnum \c@secnumdepth >\m@ne - \if@mainmatter - \refstepcounter{chapter}% - \typeout{\@chapapp\space\thechapter.}% - \addcontentsline{toc}{chapter}% - {\protect\numberline{\thechapter}#1}% - \else - \addcontentsline{toc}{chapter}{#1}% - \fi - \else - \addcontentsline{toc}{chapter}{#1}% - \fi - \chaptermark{#1}% - \addtocontents{lof}{\protect\addvspace{10\p@}}% - \addtocontents{lot}{\protect\addvspace{10\p@}}% - \if@twocolumn - \@topnewpage[\@makechapterhead{#2}]% - \else - \@makechapterhead{#2}% - \@afterheading - \fi -}{% - \ifnum \c@secnumdepth >\m@ne - \if@mainmatter - \refstepcounter{chapter}% - \typeout{\@chapapp\space\thechapter.}% - \addcontentsline{toc}{chapter}% - {\protect\numberline{\thechapter}#1}% - \else - \addcontentsline{toc}{chapter}{#1}% - \fi - \else - \addcontentsline{toc}{chapter}{#1}% - \fi - \chaptermark{#1}% - \@addchapterlistsgaps - \if@twocolumn - \@topnewpage[\@makechapterhead{#2}]% - \else - \@makechapterhead{#2}% - \@afterheading - \fi} -\newfloat@replace@chapter{% - \refstepcounter{chapter}% - \ifnum\c@secnumdepth<\z@ \let\@secnumber\@empty - \else \let\@secnumber\thechapter \fi - \typeout{\chaptername\space\@secnumber}% - \def\@toclevel{0}% - \ifx\chaptername\appendixname \@tocwriteb\tocappendix{chapter}{#2}% - \else \@tocwriteb\tocchapter{chapter}{#2}\fi - \chaptermark{#1}% - \addtocontents{lof}{\protect\addvspace{10\p@}}% - \addtocontents{lot}{\protect\addvspace{10\p@}}% - \@makechapterhead{#2}\@afterheading -}{% - \refstepcounter{chapter}% - \ifnum\c@secnumdepth<\z@ \let\@secnumber\@empty - \else \let\@secnumber\thechapter \fi - \typeout{\chaptername\space\@secnumber}% - \def\@toclevel{0}% - \ifx\chaptername\appendixname \@tocwriteb\tocappendix{chapter}{#2}% - \else \@tocwriteb\tocchapter{chapter}{#2}\fi - \chaptermark{#1}% - \@addchapterlistsgaps - \@makechapterhead{#2}\@afterheading} -\@ifpackageloaded{tocbasic}{% - \let\newfloat@replace@chapter\@gobbletwo}{} -\ifcsname insertchapterspace\endcsname - \renewcommand*\insertchapterspace{\@addchapterlistsgaps} - \let\newfloat@replace@chapter\@gobbletwo -\fi -\newfloat@replace@chapter{% - \ifnum \c@secnumdepth >\m@ne - \refstepcounter{chapter}% - \typeout{\@chapapp\space\thechapter.}% - \addcontentsline{toc}{chapter}% - {\protect\numberline{\thechapter}\toc@font0 #1}% - \else - \addcontentsline{toc}{chapter}{\toc@font0 #1}% - \fi - \chaptermark{#1}% - \addtocontents{lof}{\protect\addvspace{10\p@}}% - \addtocontents{lot}{\protect\addvspace{10\p@}}% - \if@twocolumn - \@topnewpage[\@makechapterhead{#2}]% - \else - \@makechapterhead{#2}% - \@afterheading - \fi -}{% - \ifnum \c@secnumdepth >\m@ne - \refstepcounter{chapter}% - \typeout{\@chapapp\space\thechapter.}% - \addcontentsline{toc}{chapter}% - {\protect\numberline{\thechapter}\toc@font0 #1}% - \else - \addcontentsline{toc}{chapter}{\toc@font0 #1}% - \fi - \chaptermark{#1}% - \@addchapterlistsgaps - \if@twocolumn - \@topnewpage[\@makechapterhead{#2}]% - \else - \@makechapterhead{#2}% - \@afterheading - \fi} - % boek(3).cls [2004/06/07 v2.1a NTG LaTeX document class] -\newfloat@replace@chapter{% - \ifnum \c@secnumdepth >\m@ne - \if@mainmatter - \refstepcounter{chapter}% - \typeout{\@chapapp\space\thechapter.}% - \addcontentsline{toc}{chapter}% - {\protect\numberline{\thechapter}\toc@font0 #1}% - \else - \addcontentsline{toc}{chapter}{\toc@font0 #1}% - \fi - \else - \addcontentsline{toc}{chapter}{\toc@font0 #1}% - \fi - \chaptermark{#1}% - \addtocontents{lof}{\protect\addvspace{10\p@}}% - \addtocontents{lot}{\protect\addvspace{10\p@}}% - \if@twocolumn - \@topnewpage[\@makechapterhead{#2}]% - \else - \@makechapterhead{#2}% - \@afterheading - \fi -}{% - \ifnum \c@secnumdepth >\m@ne - \if@mainmatter - \refstepcounter{chapter}% - \typeout{\@chapapp\space\thechapter.}% - \addcontentsline{toc}{chapter}% - {\protect\numberline{\thechapter}\toc@font0 #1}% - \else - \addcontentsline{toc}{chapter}{\toc@font0 #1}% - \fi - \else - \addcontentsline{toc}{chapter}{\toc@font0 #1}% - \fi - \chaptermark{#1}% - \@addchapterlistsgaps - \if@twocolumn - \@topnewpage[\@makechapterhead{#2}]% - \else - \@makechapterhead{#2}% - \@afterheading - \fi} -\newfloat@replace@chapter{% - \ifnum \c@secnumdepth >\m@ne - \if@mainmatter - \refstepcounter{chapter}% - \typeout{\chaptername\space\thechapter.} - \if@thema - \ifx\@shortauthor\@empty - \addcontentsline{toc}{chapter}{% - \protect\numberline{\thechapter.}#1}% - \else - \addcontentsline{toc}{chapter}{% - \protect\numberline{\thechapter.}% - \@shortauthor\hfill\mbox{}\vskip\normallineskip #1}% - \fi - \else - \addcontentsline{toc}{chapter}{% - \protect\numberline{\thechapter.}#1}% - \fi - \else - \addcontentsline{toc}{chapter}{#1} - \fi - \else - \addcontentsline{toc}{chapter}{#1} - \fi - \chaptermark{#1} - \addtocontents{lof}{\protect\addvspace{10pt}} - \addtocontents{lot}{\protect\addvspace{10pt}} - \if@twocolumn - \@topnewpage[\@makechapterhead{#2}] - \else - \@makechapterhead{#2} - \@afterheading - \fi -}{% - \ifnum \c@secnumdepth >\m@ne - \if@mainmatter - \refstepcounter{chapter}% - \typeout{\chaptername\space\thechapter.}% - \if@thema - \ifx\@shortauthor\@empty - \addcontentsline{toc}{chapter}{% - \protect\numberline{\thechapter.}#1}% - \else - \addcontentsline{toc}{chapter}{% - \protect\numberline{\thechapter.}% - \@shortauthor\hfill\mbox{}\vskip\normallineskip #1}% - \fi - \else - \addcontentsline{toc}{chapter}{% - \protect\numberline{\thechapter.}#1}% - \fi - \else - \addcontentsline{toc}{chapter}{#1}% - \fi - \else - \addcontentsline{toc}{chapter}{#1}% - \fi - \chaptermark{#1}% - \@addchapterlistsgaps - \if@twocolumn - \@topnewpage[\@makechapterhead{#2}]% - \else - \@makechapterhead{#2}% - \@afterheading - \fi} -\ifx\newfloat@replace@chapter\@gobbletwo \else - \newfloat@InfoNoLine{% - Unsupported document class, or \noexpand\@chapter\MessageBreak - was already redefined by another package} - \newfloat@InfoNoLine{\string\@chapter\space=\space\meaning\@chapter} - \newfloat@InfoNoLine{\string\Hy@org@chapter\space=\space\meaning\Hy@org@chapter} - \newfloat@ifplanb{% - \newfloat@InfoNoLine{Trying Plan B..}% - \let\newfloat@addtocontents@ORI\addtocontents - \long\def\addtocontents#1#2{% - \newfloat@addtocontents{#1}{#2}#2\addvspace\newfloat@nil}% - \long\def\newfloat@addtocontents#1#2#3\addvspace#4\newfloat@nil{% - \def\newfloat@tempa{#4}% - \ifx\newfloat@tempa\@empty - \newfloat@addtocontents@ORI{#1}{#2}% - \else - \ifx\newfloat@addtocontents@ext\@undefined - \newfloat@Info{Setting Plan B file extension to `#1'...}% - \xdef\newfloat@addtocontents@ext{#1}% - \fi - \edef\newfloat@tempa{#1}% - \ifx\newfloat@tempa\newfloat@addtocontents@ext - \begingroup - \let\addtocontents\newfloat@addtocontents@ORI - \@addchapterlistsgaps - \endgroup - \fi - \fi}} -\fi -\newcommand\newfloat@ForEachNew[2][newfloat@@list]{% - \AtBeginDocument{% - \ifcsname#1\endcsname - \def\@elt##1{#2}% - \newfloat@@list - \let\@elt\relax - \fi}}% -\@onlypreamble\newfloat@ForEachNew -%% \begin{macrocode} -\newfloat@ForEachNew[float@exts]{% - \@nameuse{@ifchapterlistsgap@#1}{% if switched on - \let\float@do=\relax - \edef\@tempa{% - \noexpand\float@exts{\the\float@exts\float@do{\@nameuse{ext@#1}}}}% - \@tempa}} -\newfloat@ForEachNew[FP@floatBegin]{% - \newcounter{FP@#1C}% - \newenvironment{FP#1}{\FP@floatBegin{#1}}{\FP@floatEnd}} -\providecommand*\ext@lstlisting{lol}% -\newfloat@ForEachNew[@rotfloat]{% - \newenvironment{sideways#1}{\@rotfloat{#1}}{\end@rotfloat}% - \newenvironment{sideways#1*}{\@rotdblfloat{#1}}{\end@rotdblfloat}} -\newcommand*\newfloat@For@SC[2]{% - \def#1{b}% = \sidecaptionvpos{#2}{b} (v1.6) - \newenvironment{SC#2}% - {\SC@float[#1]{#2}}{\endSC@float}% - \newenvironment{SC#2*}% - {\SC@dblfloat[#1]{#2}}{\endSC@dblfloat}} -\@onlypreamble\newfloat@For@SC -\newfloat@ForEachNew[SC@float]{% - \expandafter\newfloat@For@SC\csname SC@#1@vpos\endcsname{#1}} -\newfloat@ForEachNew[wrapfloat]{% - \newenvironment{wrap#1}{\wrapfloat{#1}}{\endwrapfloat}} -\endinput -%% -%% End of file `newfloat.sty'. diff --git a/sphinx/texinputs/sphinx.sty b/sphinx/texinputs/sphinx.sty index 956924e99..e612cf5ef 100644 --- a/sphinx/texinputs/sphinx.sty +++ b/sphinx/texinputs/sphinx.sty @@ -6,18 +6,34 @@ % \NeedsTeXFormat{LaTeX2e}[1995/12/01] -\ProvidesPackage{sphinx}[2010/01/15 LaTeX package (Sphinx markup)] +\ProvidesPackage{sphinx}[2016/06/10 LaTeX package (Sphinx markup)] +% this is the \ltx@ifundefined of ltxcmds.sty, which is loaded by +% hyperref.sty, but we need it before, and initial ltxcmds.sty +% as in TL2009/Debian had wrong definition. +\newcommand{\spx@ifundefined}[1]{% + \ifcsname #1\endcsname + \expandafter\ifx\csname #1\endcsname\relax + \expandafter\expandafter\expandafter\@firstoftwo + \else + \expandafter\expandafter\expandafter\@secondoftwo + \fi + \else + \expandafter\@firstoftwo + \fi +} + +\RequirePackage{graphicx} \@ifclassloaded{memoir}{}{\RequirePackage{fancyhdr}} +% for \text macro and \iffirstchoice@ conditional even if amsmath not loaded +\RequirePackage{amstext} \RequirePackage{textcomp} \RequirePackage{titlesec} \RequirePackage{tabulary} \RequirePackage{makeidx} % For framing code-blocks and warning type notices, and shadowing topics \RequirePackage{framed} -\newif\ifSphinx@inframed % flag set if we are in a framed environment -\RequirePackage{ifthen} % The xcolor package draws better fcolorboxes around verbatim code \IfFileExists{xcolor.sty}{ \RequirePackage{xcolor} @@ -26,12 +42,16 @@ } % For highlighted code. \RequirePackage{fancyvrb} +\fvset{fontsize=\small} % For table captions. \RequirePackage{threeparttable} % Handle footnotes in tables. \RequirePackage{footnote} \makesavenoteenv{tabulary} -% For floating figures in the text. +% For the H specifier. Do not \restylefloat{figure}, it breaks Sphinx code +% for allowing figures in tables. +\RequirePackage{float} +% For floating figures in the text. Better to load after float. \RequirePackage{wrapfig} % Separate paragraphs by space by default. \RequirePackage{parskip} @@ -61,20 +81,20 @@ \newcount\pdfoutput\pdfoutput=0 \fi -\RequirePackage{graphicx} - % for PDF output, use colors and maximal compression -\newif\ifsphinxpdfoutput\sphinxpdfoutputfalse -\ifx\pdfoutput\undefined\else\ifcase\pdfoutput +\newif\ifsphinxpdfoutput % used in \maketitle +\ifx\pdfoutput\undefined\else + \ifnum\pdfoutput=\z@ \let\py@NormalColor\relax \let\py@TitleColor\relax -\else + \else \sphinxpdfoutputtrue \input{pdfcolor} \def\py@NormalColor{\color[rgb]{0.0,0.0,0.0}} \def\py@TitleColor{\color{TitleColor}} \pdfcompresslevel=9 -\fi\fi + \fi +\fi % XeLaTeX can do colors, too \ifx\XeTeXrevision\undefined\else @@ -109,9 +129,10 @@ % Use this to set the font family for headers and other decor: \newcommand{\py@HeaderFamily}{\sffamily\bfseries} +\newcommand{\sphinxSetHeaderFamily}[1]{\renewcommand{\py@HeaderFamily}{#1}} % Redefine the 'normal' header/footer style when using "fancyhdr" package: -\@ifundefined{fancyhf}{}{ +\spx@ifundefined{fancyhf}{}{ % Use \pagestyle{normal} as the primary pagestyle for text. \fancypagestyle{normal}{ \fancyhf{} @@ -122,9 +143,8 @@ \renewcommand{\headrulewidth}{0.4pt} \renewcommand{\footrulewidth}{0.4pt} % define chaptermark with \@chappos when \@chappos is available for Japanese - \ifx\@chappos\undefined\else - \def\chaptermark##1{\markboth{\@chapapp\space\thechapter\space\@chappos\space ##1}{}} - \fi + \spx@ifundefined{@chappos}{} + {\def\chaptermark##1{\markboth{\@chapapp\space\thechapter\space\@chappos\space ##1}{}}} } % Update the plain style so we get the page number & footer line, % but not a chapter or section title. This is to keep the first @@ -138,28 +158,45 @@ } % Some custom font markup commands. -% -\newcommand{\strong}[1]{{\textbf{#1}}} -\newcommand{\code}[1]{\texttt{#1}} -\newcommand{\bfcode}[1]{\code{\bfseries#1}} -\newcommand{\email}[1]{\textsf{#1}} -\newcommand{\tablecontinued}[1]{\textsf{#1}} -\newcommand{\titleref}[1]{\emph{#1}} -\newcommand{\menuselection}[1]{\emph{#1}} -\newcommand{\accelerator}[1]{\underline{#1}} -\newcommand{\crossref}[1]{\emph{#1}} -\newcommand{\termref}[1]{\emph{#1}} +% *** the macros without \sphinx prefix are still defined at bottom of file *** +\newcommand{\sphinxstrong}[1]{{\textbf{#1}}} +% let \sphinxcode and \sphinxbfcode use straight quotes. \@noligs patched by upquote, +% but needs protection in "moving arguments" such as for captions. +% Use \scantokens to handle e.g. \item[{\sphinxcode{'fontenc'}}] +\DeclareRobustCommand{\sphinxcode}[1]{{\@noligs\scantokens{\texttt{#1}\relax}}} +\newcommand{\sphinxbfcode}[1]{\sphinxcode{\bfseries#1}} +\newcommand{\sphinxemail}[1]{\textsf{#1}} +\newcommand{\sphinxtablecontinued}[1]{\textsf{#1}} +\newcommand{\sphinxtitleref}[1]{\emph{#1}} +\newcommand{\sphinxmenuselection}[1]{\emph{#1}} +\newcommand{\sphinxaccelerator}[1]{\underline{#1}} +\newcommand{\sphinxcrossref}[1]{\emph{#1}} +\newcommand{\sphinxtermref}[1]{\emph{#1}} +% miscellaneous related to footnotes \newcommand*{\sphinxAtStartFootnote}{\mbox{ }} +% Support large numbered footnotes in minipage (cf. admonitions) +\def\thempfootnote{\arabic{mpfootnote}} -% Redefine the Verbatim environment to allow border and background colors -% and to handle the top caption in a non separable by pagebreak way. -% The original environment is still used for verbatims within tables. -\let\OriginalVerbatim=\Verbatim -\let\endOriginalVerbatim=\endVerbatim +% Preparations for sphinxVerbatim environment, which is a wrapper of fancyvrb +% Verbatim with framing allowing pagebreaks, with border and background colors +% and possibly also a top caption, non separable by pagebreak. -\newcommand\Sphinx@colorbox [2]{% -% #1 will be \fcolorbox or, for first part of frame: \Sphinx@fcolorbox +% For maintaining compatibility with Sphinx < 1.5, we define and use these +% when (unmodified) Verbatim will be needed. But Sphinx >= 1.5 does not modify +% original Verbatim anyhow. +\let\OriginalVerbatim \Verbatim +\let\endOriginalVerbatim\endVerbatim + +\newif\ifspx@inframed % flag set if we are already in a framed environment +\newdimen\sphinxverbatimsep \sphinxverbatimsep \fboxsep % default 3pt +\newdimen\sphinxverbatimborder\sphinxverbatimborder\fboxrule % default 0.4pt +\newif\ifsphinxverbatimwithframe \sphinxverbatimwithframetrue +\newif\ifsphinxverbatimwrapslines \sphinxverbatimwrapslinestrue +% if forced use of minipage encapsulation is needed (e.g. table cells) +\newif\ifsphinxverbatimwithminipage \sphinxverbatimwithminipagefalse +\newcommand\spx@colorbox [2]{% +% #1 will be \fcolorbox or, for first part of frame: \spx@fcolorbox % let the framing obey the current indentation (adapted from framed.sty's code). \hskip\@totalleftmargin \hskip-\fboxsep\hskip-\fboxrule @@ -168,100 +205,102 @@ \hskip-\linewidth \hskip-\@totalleftmargin \hskip\columnwidth } % use of \color@b@x here is compatible with both xcolor.sty and color.sty -\def\Sphinx@fcolorbox #1#2% - {\color@b@x {\fboxsep\z@\color{#1}\Sphinx@VerbatimFBox}{\color{#2}}}% +\def\spx@fcolorbox #1#2% + {\color@b@x {\fboxsep\z@\color{#1}\spx@VerbatimFBox}{\color{#2}}}% -% The title is specified from outside as macro \SphinxVerbatimTitle. -% \SphinxVerbatimTitle is reset to empty after each use of Verbatim. -\newcommand*\SphinxVerbatimTitle {} +% The title (caption) is specified from outside as macro \sphinxVerbatimTitle. +% \sphinxVerbatimTitle is reset to empty after each use of Verbatim. +\newcommand*\sphinxVerbatimTitle {} +% This box to typeset the caption before framed.sty multiple passes for framing. +\newbox\spx@VerbatimTitleBox % Holder macro for labels of literal blocks. Set-up by LaTeX writer. -\newcommand*\SphinxLiteralBlockLabel {} -\newcommand*\SphinxSetupCaptionForVerbatim [2] +\newcommand*\sphinxLiteralBlockLabel {} +\newcommand*\sphinxSetupCaptionForVerbatim [1] {% - \needspace{\literalblockneedspace}% -% insert a \label via \SphinxLiteralBlockLabel + \needspace{\sphinxliteralblockneedspace}% +% insert a \label via \sphinxLiteralBlockLabel % reset to normal the color for the literal block caption % the caption inserts \abovecaptionskip whitespace above itself (usually 10pt) % there is also \belowcaptionskip but it is usually zero, hence the \smallskip - \def\SphinxVerbatimTitle - {\py@NormalColor\captionof{#1}{\SphinxLiteralBlockLabel #2}\smallskip }% + \def\sphinxVerbatimTitle + {\py@NormalColor + \captionof{literalblock}{\sphinxLiteralBlockLabel #1}\smallskip }% } % Inspired and adapted from framed.sty's \CustomFBox with extra handling -% of a non separable by pagebreak caption, and controlled counter stepping. -\newif\ifSphinx@myfirstframedpass - -\long\def\Sphinx@VerbatimFBox#1{% +% of a non separable by pagebreak caption. +\long\def\spx@VerbatimFBox#1{% \leavevmode \begingroup - % framed.sty does some measuring but this macro adds possibly a caption - % use amsmath conditional to inhibit the caption counter stepping after - % first pass - \ifSphinx@myfirstframedpass\else\firstchoice@false\fi \setbox\@tempboxa\hbox{\kern\fboxsep{#1}\kern\fboxsep}% \hbox {\lower\dimexpr\fboxrule+\fboxsep+\dp\@tempboxa \hbox{% - \vbox{\ifx\SphinxVerbatimTitle\empty\else + \vbox{\ifvoid\spx@VerbatimTitleBox\else % add the caption in a centered way above possibly indented frame % hide its width from framed.sty's measuring step % note that the caption brings \abovecaptionskip top vertical space \moveright\dimexpr\fboxrule+.5\wd\@tempboxa - \hb@xt@\z@{\hss\begin{minipage}{\wd\@tempboxa}% - \SphinxVerbatimTitle - \end{minipage}\hss}\fi - \hrule\@height\fboxrule\relax - \hbox{\vrule\@width\fboxrule\relax + \hb@xt@\z@{\hss\unhcopy\spx@VerbatimTitleBox\hss}\fi + % draw frame border _latest_ to avoid pdf viewer issue + \kern\fboxrule + \hbox{\kern\fboxrule \vbox{\vskip\fboxsep\copy\@tempboxa\vskip\fboxsep}% - \vrule\@width\fboxrule\relax}% - \hrule\@height\fboxrule\relax}% + \kern-\wd\@tempboxa\kern-\fboxrule + \vrule\@width\fboxrule + \kern\wd\@tempboxa + \vrule\@width\fboxrule}% + \kern-\dimexpr\fboxsep+\ht\@tempboxa+\dp\@tempboxa + +\fboxsep+\fboxrule\relax + \hrule\@height\fboxrule + \kern\dimexpr\fboxsep+\ht\@tempboxa+\dp\@tempboxa+\fboxsep\relax + \hrule\@height\fboxrule}% }}% \endgroup - \global\Sphinx@myfirstframedpassfalse } % For linebreaks inside Verbatim environment from package fancyvrb. -\newbox\Sphinxcontinuationbox -\newbox\Sphinxvisiblespacebox +\newbox\sphinxcontinuationbox +\newbox\sphinxvisiblespacebox % These are user customizable e.g. from latex_elements's preamble key. % Use of \textvisiblespace for compatibility with XeTeX/LuaTeX/fontspec. -\newcommand*\Sphinxvisiblespace {\textcolor{red}{\textvisiblespace}} -\newcommand*\Sphinxcontinuationsymbol {\textcolor{red}{\llap{\tiny$\m@th\hookrightarrow$}}} -\newcommand*\Sphinxcontinuationindent {3ex } -\newcommand*\Sphinxafterbreak {\kern\Sphinxcontinuationindent\copy\Sphinxcontinuationbox} +\newcommand*\sphinxvisiblespace {\textcolor{red}{\textvisiblespace}} +\newcommand*\sphinxcontinuationsymbol {\textcolor{red}{\llap{\tiny$\m@th\hookrightarrow$}}} +\newcommand*\sphinxcontinuationindent {3ex } +\newcommand*\sphinxafterbreak {\kern\sphinxcontinuationindent\copy\sphinxcontinuationbox} % Take advantage of the already applied Pygments mark-up to insert % potential linebreaks for TeX processing. % {, <, #, %, $, ' and ": go to next line. % _, }, ^, &, >, - and ~: stay at end of broken line. % Use of \textquotesingle for straight quote. -\newcommand*\Sphinxbreaksatspecials {% - \def\PYGZus{\discretionary{\char`\_}{\Sphinxafterbreak}{\char`\_}}% - \def\PYGZob{\discretionary{}{\Sphinxafterbreak\char`\{}{\char`\{}}% - \def\PYGZcb{\discretionary{\char`\}}{\Sphinxafterbreak}{\char`\}}}% - \def\PYGZca{\discretionary{\char`\^}{\Sphinxafterbreak}{\char`\^}}% - \def\PYGZam{\discretionary{\char`\&}{\Sphinxafterbreak}{\char`\&}}% - \def\PYGZlt{\discretionary{}{\Sphinxafterbreak\char`\<}{\char`\<}}% - \def\PYGZgt{\discretionary{\char`\>}{\Sphinxafterbreak}{\char`\>}}% - \def\PYGZsh{\discretionary{}{\Sphinxafterbreak\char`\#}{\char`\#}}% - \def\PYGZpc{\discretionary{}{\Sphinxafterbreak\char`\%}{\char`\%}}% - \def\PYGZdl{\discretionary{}{\Sphinxafterbreak\char`\$}{\char`\$}}% - \def\PYGZhy{\discretionary{\char`\-}{\Sphinxafterbreak}{\char`\-}}% - \def\PYGZsq{\discretionary{}{\Sphinxafterbreak\textquotesingle}{\textquotesingle}}% - \def\PYGZdq{\discretionary{}{\Sphinxafterbreak\char`\"}{\char`\"}}% - \def\PYGZti{\discretionary{\char`\~}{\Sphinxafterbreak}{\char`\~}}% +\newcommand*\sphinxbreaksatspecials {% + \def\PYGZus{\discretionary{\char`\_}{\sphinxafterbreak}{\char`\_}}% + \def\PYGZob{\discretionary{}{\sphinxafterbreak\char`\{}{\char`\{}}% + \def\PYGZcb{\discretionary{\char`\}}{\sphinxafterbreak}{\char`\}}}% + \def\PYGZca{\discretionary{\char`\^}{\sphinxafterbreak}{\char`\^}}% + \def\PYGZam{\discretionary{\char`\&}{\sphinxafterbreak}{\char`\&}}% + \def\PYGZlt{\discretionary{}{\sphinxafterbreak\char`\<}{\char`\<}}% + \def\PYGZgt{\discretionary{\char`\>}{\sphinxafterbreak}{\char`\>}}% + \def\PYGZsh{\discretionary{}{\sphinxafterbreak\char`\#}{\char`\#}}% + \def\PYGZpc{\discretionary{}{\sphinxafterbreak\char`\%}{\char`\%}}% + \def\PYGZdl{\discretionary{}{\sphinxafterbreak\char`\$}{\char`\$}}% + \def\PYGZhy{\discretionary{\char`\-}{\sphinxafterbreak}{\char`\-}}% + \def\PYGZsq{\discretionary{}{\sphinxafterbreak\textquotesingle}{\textquotesingle}}% + \def\PYGZdq{\discretionary{}{\sphinxafterbreak\char`\"}{\char`\"}}% + \def\PYGZti{\discretionary{\char`\~}{\sphinxafterbreak}{\char`\~}}% } % Some characters . , ; ? ! / are not pygmentized. % This macro makes them "active" and they will insert potential linebreaks -\newcommand*\Sphinxbreaksatpunct {% - \lccode`\~`\.\lowercase{\def~}{\discretionary{\char`\.}{\Sphinxafterbreak}{\char`\.}}% - \lccode`\~`\,\lowercase{\def~}{\discretionary{\char`\,}{\Sphinxafterbreak}{\char`\,}}% - \lccode`\~`\;\lowercase{\def~}{\discretionary{\char`\;}{\Sphinxafterbreak}{\char`\;}}% - \lccode`\~`\:\lowercase{\def~}{\discretionary{\char`\:}{\Sphinxafterbreak}{\char`\:}}% - \lccode`\~`\?\lowercase{\def~}{\discretionary{\char`\?}{\Sphinxafterbreak}{\char`\?}}% - \lccode`\~`\!\lowercase{\def~}{\discretionary{\char`\!}{\Sphinxafterbreak}{\char`\!}}% - \lccode`\~`\/\lowercase{\def~}{\discretionary{\char`\/}{\Sphinxafterbreak}{\char`\/}}% +\newcommand*\sphinxbreaksatpunct {% + \lccode`\~`\.\lowercase{\def~}{\discretionary{\char`\.}{\sphinxafterbreak}{\char`\.}}% + \lccode`\~`\,\lowercase{\def~}{\discretionary{\char`\,}{\sphinxafterbreak}{\char`\,}}% + \lccode`\~`\;\lowercase{\def~}{\discretionary{\char`\;}{\sphinxafterbreak}{\char`\;}}% + \lccode`\~`\:\lowercase{\def~}{\discretionary{\char`\:}{\sphinxafterbreak}{\char`\:}}% + \lccode`\~`\?\lowercase{\def~}{\discretionary{\char`\?}{\sphinxafterbreak}{\char`\?}}% + \lccode`\~`\!\lowercase{\def~}{\discretionary{\char`\!}{\sphinxafterbreak}{\char`\!}}% + \lccode`\~`\/\lowercase{\def~}{\discretionary{\char`\/}{\sphinxafterbreak}{\char`\/}}% \catcode`\.\active \catcode`\,\active \catcode`\;\active @@ -272,42 +311,55 @@ \lccode`\~`\~ } -\renewcommand{\Verbatim}[1][1]{% +% needed to create wrapper environments of fancyvrb's Verbatim +\newcommand*{\sphinxVerbatimEnvironment}{\gdef\FV@EnvironName{sphinxVerbatim}} +% Sphinx <1.5 optional argument was in fact mandatory. It is now really +% optional and handled by original Verbatim. +\newenvironment{sphinxVerbatim}{% % quit horizontal mode if we are still in a paragraph \par % list starts new par, but we don't want it to be set apart vertically \parskip\z@skip % first, let's check if there is a caption - \ifx\SphinxVerbatimTitle\empty + \ifx\sphinxVerbatimTitle\empty \addvspace\z@% counteract possible previous negative skip (French lists!) \smallskip % there was no caption. Check if nevertheless a label was set. - \ifx\SphinxLiteralBlockLabel\empty\else + \ifx\sphinxLiteralBlockLabel\empty\else % we require some space to be sure hyperlink target from \phantomsection % will not be separated from upcoming verbatim by a page break - \needspace{\literalblockwithoutcaptionneedspace}% - \phantomsection\SphinxLiteralBlockLabel + \needspace{\sphinxliteralblockwithoutcaptionneedspace}% + \phantomsection\sphinxLiteralBlockLabel \fi + \setbox\spx@VerbatimTitleBox\box\voidb@x + \else + % non-empty \sphinxVerbatimTitle has label inside it (in case there is one) + \setbox\spx@VerbatimTitleBox + \hbox{\begin{minipage}{\linewidth}% + \sphinxVerbatimTitle + \end{minipage}}% \fi - % non-empty \SphinxVerbatimTitle has label inside it (in case there is one) + \fboxsep\sphinxverbatimsep \fboxrule\sphinxverbatimborder + % setting borderwidth to zero is simplest for no-frame effect with same pagebreaks + \ifsphinxverbatimwithframe\else\fboxrule\z@\fi % Customize framed.sty \MakeFramed to glue caption to literal block - \global\Sphinx@myfirstframedpasstrue - % via \Sphinx@fcolorbox, will use \Sphinx@VerbatimFBox which inserts title - \def\FrameCommand {\Sphinx@colorbox\Sphinx@fcolorbox }% + % via \spx@fcolorbox, will use \spx@VerbatimFBox which inserts title + \def\FrameCommand {\spx@colorbox\spx@fcolorbox }% \let\FirstFrameCommand\FrameCommand % for mid pages and last page portion of (long) split frame: - \def\MidFrameCommand{\Sphinx@colorbox\fcolorbox }% + \def\MidFrameCommand{\spx@colorbox\fcolorbox }% \let\LastFrameCommand\MidFrameCommand + \ifsphinxverbatimwrapslines % fancyvrb's Verbatim puts each input line in (unbreakable) horizontal boxes. % This customization wraps each line from the input in a \vtop, thus % allowing it to wrap and display on two or more lines in the latex output. % - The codeline counter will be increased only once. % - The wrapped material will not break across pages, it is impossible % to achieve this without extensive rewrite of fancyvrb. - % - The (not used in Sphinx) obeytabs option to Verbatim is + % - The (not used in sphinx) obeytabs option to Verbatim is % broken by this change (showtabs and tabspace work). - \sbox\Sphinxcontinuationbox {\Sphinxcontinuationsymbol}% - \sbox\Sphinxvisiblespacebox {\FV@SetupFont\Sphinxvisiblespace}% + \sbox\sphinxcontinuationbox {\sphinxcontinuationsymbol}% + \sbox\sphinxvisiblespacebox {\FV@SetupFont\sphinxvisiblespace}% \def\FancyVerbFormatLine ##1{\hsize\linewidth \vtop{\raggedright\hyphenpenalty\z@\exhyphenpenalty\z@ \doublehyphendemerits\z@\finalhyphendemerits\z@ @@ -318,74 +370,100 @@ % Stretch/shrink are however usually zero for typewriter font. \def\FV@Space {% \nobreak\hskip\z@ plus\fontdimen3\font minus\fontdimen4\font - \discretionary{\copy\Sphinxvisiblespacebox}{\Sphinxafterbreak} + \discretionary{\copy\sphinxvisiblespacebox}{\sphinxafterbreak} {\kern\fontdimen2\font}% }% % Allow breaks at special characters using \PYG... macros. - \Sphinxbreaksatspecials + \sphinxbreaksatspecials + % Breaks at punctuation characters . , ; ? ! and / (needs catcode activation) + \def\FancyVerbCodes{\sphinxbreaksatpunct}% + \fi % end of conditional code for wrapping long code lines + % go around fancyvrb's check of \@currenvir + \let\VerbatimEnvironment\sphinxVerbatimEnvironment + % go around fancyvrb's check of current list depth + \def\@toodeep {\advance\@listdepth\@ne}% % The list environment is needed to control perfectly the vertical space. % Note: \OuterFrameSep used by framed.sty is later set to \topsep hence 0pt. % - if caption: vertical space above caption = (\abovecaptionskip + D) with % D = \baselineskip-\FrameHeightAdjust, and then \smallskip above frame. % - if no caption: (\smallskip + D) above frame. By default D=6pt. - \list{}{% - \setlength\parskip{0pt}% - \setlength\itemsep{0ex}% - \setlength\topsep{0ex}% - \setlength\parsep{0pt}% let's not forget this one! - \setlength\partopsep{0pt}% - \setlength\leftmargin{0pt}% - }% - \item - % use a minipage if we are already inside a framed environment - \relax\ifSphinx@inframed\noindent\begin{\minipage}{\linewidth}\fi + % Use trivlist rather than list to avoid possible "too deeply nested" error. + \itemsep \z@skip + \topsep \z@skip + \partopsep \z@skip% trivlist will set \parsep to \parskip = zero (see above) + % \leftmargin will be set to zero by trivlist + \rightmargin\z@ + \parindent \z@% becomes \itemindent. Default zero, but perhaps overwritten. + \trivlist\item\relax + \ifsphinxverbatimwithminipage\spx@inframedtrue\fi + % use a minipage if we are already inside a framed environment + \ifspx@inframed\noindent\begin{minipage}{\linewidth}\fi \MakeFramed {% adapted over from framed.sty's snugshade environment - \advance\hsize-\width\@totalleftmargin\z@\linewidth\hsize - \@setminipage }% - \small + \advance\hsize-\width\@totalleftmargin\z@\linewidth\hsize\@setminipage + }% % For grid placement from \strut's in \FancyVerbFormatLine \lineskip\z@skip - % Breaks at punctuation characters . , ; ? ! and / need catcode=\active - \OriginalVerbatim[#1,codes*=\Sphinxbreaksatpunct]% + % will fetch its optional arguments if any + \OriginalVerbatim } -\renewcommand{\endVerbatim}{% +{% \endOriginalVerbatim - \par\unskip\@minipagefalse\endMakeFramed - \ifSphinx@inframed\end{minipage}\fi - \endlist - % LaTeX environments always revert local changes on exit, here e.g. \parskip + \par\unskip\@minipagefalse\endMakeFramed % from framed.sty snugshade + \ifspx@inframed\end{minipage}\fi + \endtrivlist } +\newenvironment {sphinxVerbatimNoFrame} + {\sphinxverbatimwithframefalse + % needed for fancyvrb as literal code will end in \end{sphinxVerbatimNoFrame} + \def\sphinxVerbatimEnvironment{\gdef\FV@EnvironName{sphinxVerbatimNoFrame}}% + \begin{sphinxVerbatim}} + {\end{sphinxVerbatim}} +\newenvironment {sphinxVerbatimintable} + {% don't use a frame if in a table cell + \sphinxverbatimwithframefalse + \sphinxverbatimwithminipagetrue + % counteract longtable redefinition of caption + \let\caption\sphinxfigcaption + % reduce above caption space if in a table cell + \abovecaptionskip\smallskipamount + \def\sphinxVerbatimEnvironment{\gdef\FV@EnvironName{sphinxVerbatimintable}}% + \begin{sphinxVerbatim}} + {\end{sphinxVerbatim}} % define macro to frame contents and add shadow on right and bottom -\def\Sphinx@shadowsep {5\p@} % \p@ means "pt " -\def\Sphinx@shadowsize {4\p@} -\def\Sphinx@shadowrule {\fboxrule} -\long\def\Sphinx@ShadowFBox#1{% +% use public names for customizable lengths +\newlength\sphinxshadowsep \setlength\sphinxshadowsep {5pt} +\newlength\sphinxshadowsize \setlength\sphinxshadowsize {4pt} +\newlength\sphinxshadowrule +% this uses \fboxrule value at loading time of sphinx.sty (0.4pt normally) +\setlength\sphinxshadowrule {\fboxrule} + +\long\def\spx@ShadowFBox#1{% \leavevmode\begingroup % first we frame the box #1 \setbox\@tempboxa - \hbox{\vrule\@width\Sphinx@shadowrule - \vbox{\hrule\@height\Sphinx@shadowrule - \kern\Sphinx@shadowsep - \hbox{\kern\Sphinx@shadowsep #1\kern\Sphinx@shadowsep}% - \kern\Sphinx@shadowsep - \hrule\@height\Sphinx@shadowrule}% - \vrule\@width\Sphinx@shadowrule}% + \hbox{\vrule\@width\sphinxshadowrule + \vbox{\hrule\@height\sphinxshadowrule + \kern\sphinxshadowsep + \hbox{\kern\sphinxshadowsep #1\kern\sphinxshadowsep}% + \kern\sphinxshadowsep + \hrule\@height\sphinxshadowrule}% + \vrule\@width\sphinxshadowrule}% % Now we add the shadow, like \shadowbox from fancybox.sty would do - \dimen@\dimexpr.5\Sphinx@shadowrule+\Sphinx@shadowsize\relax + \dimen@\dimexpr.5\sphinxshadowrule+\sphinxshadowsize\relax \hbox{\vbox{\offinterlineskip - \hbox{\copy\@tempboxa\kern-.5\Sphinx@shadowrule + \hbox{\copy\@tempboxa\kern-.5\sphinxshadowrule % add shadow on right side - \lower\Sphinx@shadowsize + \lower\sphinxshadowsize \hbox{\vrule\@height\ht\@tempboxa \@width\dimen@}% }% \kern-\dimen@ % shift back vertically to bottom of frame % and add shadow at bottom - \moveright\Sphinx@shadowsize + \moveright\sphinxshadowsize \vbox{\hrule\@width\wd\@tempboxa \@height\dimen@}% }% % move left by the size of right shadow so shadow adds no width - \kern-\Sphinx@shadowsize + \kern-\sphinxshadowsize }% \endgroup } @@ -394,10 +472,10 @@ % works well inside Lists and Quote-like environments % produced by ``topic'' directive (or local contents) % could nest if LaTeX writer authorized it -\newenvironment{SphinxShadowBox} - {\def\FrameCommand {\Sphinx@ShadowFBox }% +\newenvironment{sphinxShadowBox} + {\def\FrameCommand {\spx@ShadowFBox }% % configure framed.sty not to add extra vertical spacing - \OuterFrameSep \z@skip + \spx@ifundefined{OuterFrameSep}{}{\OuterFrameSep\z@skip}% % the \trivlist will add the vertical spacing on top and bottom which is % typical of center environment as used in Sphinx <= 1.4.1 % the \noindent has the effet of an extra blank line on top, to @@ -406,8 +484,8 @@ \def\FrameHeightAdjust {\baselineskip}% \trivlist\item\noindent % use a minipage if we are already inside a framed environment - \ifSphinx@inframed\begin{minipage}{\linewidth}\fi - \MakeFramed {\Sphinx@inframedtrue + \ifspx@inframed\begin{minipage}{\linewidth}\fi + \MakeFramed {\spx@inframedtrue % framed.sty puts into "\width" the added width (=2shadowsep+2shadowrule) % adjust \hsize to what the contents must use \advance\hsize-\width @@ -433,7 +511,7 @@ \fi \@minipagefalse \endMakeFramed - \ifSphinx@inframed\end{minipage}\fi + \ifspx@inframed\end{minipage}\fi \endtrivlist } @@ -474,25 +552,25 @@ }{\end{list}} % \optional is used for ``[, arg]``, i.e. desc_optional nodes. -\newcommand{\optional}[1]{% +\newcommand{\sphinxoptional}[1]{% {\textnormal{\Large[}}{#1}\hspace{0.5mm}{\textnormal{\Large]}}} \newlength{\py@argswidth} \newcommand{\py@sigparams}[2]{% - \parbox[t]{\py@argswidth}{#1\code{)}#2}} + \parbox[t]{\py@argswidth}{#1\sphinxcode{)}#2}} \newcommand{\pysigline}[1]{\item[#1]\nopagebreak} \newcommand{\pysiglinewithargsret}[3]{% - \settowidth{\py@argswidth}{#1\code{(}}% + \settowidth{\py@argswidth}{#1\sphinxcode{(}}% \addtolength{\py@argswidth}{-2\py@argswidth}% \addtolength{\py@argswidth}{\linewidth}% - \item[#1\code{(}\py@sigparams{#2}{#3}]} + \item[#1\sphinxcode{(}\py@sigparams{#2}{#3}]} % Production lists % \newenvironment{productionlist}{ -% \def\optional##1{{\Large[}##1{\Large]}} - \def\production##1##2{\\\code{##1}&::=&\code{##2}} - \def\productioncont##1{\\& &\code{##1}} +% \def\sphinxoptional##1{{\Large[}##1{\Large]}} + \def\production##1##2{\\\sphinxcode{##1}&::=&\sphinxcode{##2}} + \def\productioncont##1{\\& &\sphinxcode{##1}} \parindent=2em \indent \setlength{\LTpre}{0pt} @@ -503,29 +581,79 @@ } % Notices / Admonitions -% +% Some are quite plain +\newenvironment{sphinxlightbox}{% + \par\allowbreak + \noindent{\color{spx@notice@bordercolor}% + \rule{\linewidth}{\spx@notice@border}}\par\nobreak + {\parskip\z@skip\noindent}% + } + {% + \par + % counteract previous possible negative skip (French lists!): + % (we can't cancel that any earlier \vskip introduced a potential pagebreak) + \ifdim\lastskip<\z@\vskip-\lastskip\fi + \nobreak\vbox{\noindent\kern\@totalleftmargin + {\color{spx@notice@bordercolor}% + \rule[\dimexpr.4\baselineskip-\spx@notice@border\relax] + {\linewidth}{\spx@notice@border}}\hss}\allowbreak + }% end of sphinxlightbox environment definition +% may be renewenvironment'd by user for complete customization +\newenvironment{sphinxnote}[1] + {\begin{sphinxlightbox}\sphinxstrong{#1} }{\end{sphinxlightbox}} +\newenvironment{sphinxhint}[1] + {\begin{sphinxlightbox}\sphinxstrong{#1} }{\end{sphinxlightbox}} +\newenvironment{sphinximportant}[1] + {\begin{sphinxlightbox}\sphinxstrong{#1} }{\end{sphinxlightbox}} +\newenvironment{sphinxtip}[1] + {\begin{sphinxlightbox}\sphinxstrong{#1} }{\end{sphinxlightbox}} +% or user may just customize the bordercolor and the border width +% re-use \definecolor if change needed, and \renewcommand for rule width +\definecolor{sphinxnotebordercolor}{rgb}{0,0,0} +\definecolor{sphinxhintbordercolor}{rgb}{0,0,0} +\definecolor{sphinximportantbordercolor}{rgb}{0,0,0} +\definecolor{sphinxtipbordercolor}{rgb}{0,0,0} +\newcommand{\sphinxnoteborder}{0.5pt} +\newcommand{\sphinxhintborder}{0.5pt} +\newcommand{\sphinximportantborder}{0.5pt} +\newcommand{\sphinxtipborder}{0.5pt} +% these are needed for common handling by notice environment of lightbox +% and heavybox but they are currently not used by lightbox environment +\definecolor{sphinxnotebgcolor}{rgb}{1,1,1} +\definecolor{sphinxhintbgcolor}{rgb}{1,1,1} +\definecolor{sphinximportantbgcolor}{rgb}{1,1,1} +\definecolor{sphinxtipbgcolor}{rgb}{1,1,1} + +% Others get more distinction +\newdimen\spx@notice@border % Code adapted from framed.sty's "snugshade" environment. % Nesting works (inner frames do not allow page breaks). -\newcommand{\py@heavybox}{\par - \setlength{\FrameRule}{\p@}% 1pt +\newenvironment{sphinxheavybox}{\par + \setlength{\FrameRule}{\spx@notice@border}% \setlength{\FrameSep}{\dimexpr.6\baselineskip-\FrameRule\relax} % configure framed.sty's parameters to obtain same vertical spacing % as for "light" boxes. We need for this to manually insert parskip glue and % revert a skip done by framed before the frame. - \setlength{\OuterFrameSep}{0pt} + \spx@ifundefined{OuterFrameSep}{}{\OuterFrameSep\z@skip}% \vspace{\FrameHeightAdjust} % copied/adapted from framed.sty's snugshade \def\FrameCommand##1{\hskip\@totalleftmargin - \fboxsep\FrameSep \fboxrule\FrameRule\fbox{##1}% + \fboxsep\FrameSep \fboxrule\FrameRule + \fcolorbox{spx@notice@bordercolor}{spx@notice@bgcolor}{##1}% \hskip-\linewidth \hskip-\@totalleftmargin \hskip\columnwidth}% % use a minipage if we are already inside a framed environment - \ifSphinx@inframed + \ifspx@inframed \noindent\begin{minipage}{\linewidth} \else - \vspace{\parskip} + % handle case where notice is first thing in a list item (or is quoted) + \if@inlabel + \noindent\par\vspace{-\baselineskip} + \else + \vspace{\parskip} + \fi \fi - \MakeFramed {\Sphinx@inframedtrue + \MakeFramed {\spx@inframedtrue \advance\hsize-\width \@totalleftmargin\z@ \linewidth\hsize % minipage initialization copied from LaTeX source code. \@pboxswfalse @@ -536,58 +664,66 @@ \@minipagerestore \@setminipage }% } -\newcommand{\py@endheavybox}{% + {% \par\unskip % handles footnotes \ifvoid\@mpfootins\else \vskip\skip\@mpfootins\normalcolor\footnoterule\unvbox\@mpfootins \fi - \@minipagefalse\endMakeFramed - \ifSphinx@inframed\end{minipage}\fi + \@minipagefalse + \endMakeFramed + \ifspx@inframed\end{minipage}\fi % arrange for similar spacing below frame as for "light" boxes. \vskip .4\baselineskip - } + }% end of sphinxheavybox environment definition +% may be renewenvironment'd by user for complete customization +\newenvironment{sphinxwarning}[1] + {\begin{sphinxheavybox}\sphinxstrong{#1} }{\end{sphinxheavybox}} +\newenvironment{sphinxcaution}[1] + {\begin{sphinxheavybox}\sphinxstrong{#1} }{\end{sphinxheavybox}} +\newenvironment{sphinxattention}[1] + {\begin{sphinxheavybox}\sphinxstrong{#1} }{\end{sphinxheavybox}} +\newenvironment{sphinxdanger}[1] + {\begin{sphinxheavybox}\sphinxstrong{#1} }{\end{sphinxheavybox}} +\newenvironment{sphinxerror}[1] + {\begin{sphinxheavybox}\sphinxstrong{#1} }{\end{sphinxheavybox}} +% or just re-do \definecolor for colours, \renewcommand for frame width +\definecolor{sphinxwarningbordercolor}{rgb}{0,0,0} +\definecolor{sphinxcautionbordercolor}{rgb}{0,0,0} +\definecolor{sphinxattentionbordercolor}{rgb}{0,0,0} +\definecolor{sphinxdangerbordercolor}{rgb}{0,0,0} +\definecolor{sphinxerrorbordercolor}{rgb}{0,0,0} +\definecolor{sphinxwarningbgcolor}{rgb}{1,1,1} +\definecolor{sphinxcautionbgcolor}{rgb}{1,1,1} +\definecolor{sphinxattentionbgcolor}{rgb}{1,1,1} +\definecolor{sphinxdangerbgcolor}{rgb}{1,1,1} +\definecolor{sphinxerrorbgcolor}{rgb}{1,1,1} +\newcommand{\sphinxwarningborder}{1pt} +\newcommand{\sphinxcautionborder}{1pt} +\newcommand{\sphinxattentionborder}{1pt} +\newcommand{\sphinxdangerborder}{1pt} +\newcommand{\sphinxerrorborder}{1pt} -\newcommand{\py@lightbox}{% - \par\allowbreak - \noindent\rule{\linewidth}{0.5pt}\par\nobreak - {\parskip\z@skip\noindent}% - } -\newcommand{\py@endlightbox}{% - \par - % counteract previous possible negative skip (French lists!): - % (we can't cancel that any earlier \vskip introduced a potential pagebreak) - \ifdim\lastskip<\z@\vskip-\lastskip\fi - \nobreak\vbox{\noindent\rule[.4\baselineskip]{\linewidth}{0.5pt}}\allowbreak - } +% the \colorlet of xcolor (if at all loaded) is overkill for our use case +\newcommand{\sphinxcolorlet}[2] + {\expandafter\let\csname\@backslashchar color@#1\expandafter\endcsname + \csname\@backslashchar color@#2\endcsname } -% Some are quite plain: -\newcommand{\py@noticestart@note}{\py@lightbox} -\newcommand{\py@noticeend@note}{\py@endlightbox} -\newcommand{\py@noticestart@hint}{\py@lightbox} -\newcommand{\py@noticeend@hint}{\py@endlightbox} -\newcommand{\py@noticestart@important}{\py@lightbox} -\newcommand{\py@noticeend@important}{\py@endlightbox} -\newcommand{\py@noticestart@tip}{\py@lightbox} -\newcommand{\py@noticeend@tip}{\py@endlightbox} - -% Others gets more visible distinction: -\newcommand{\py@noticestart@warning}{\py@heavybox} -\newcommand{\py@noticeend@warning}{\py@endheavybox} -\newcommand{\py@noticestart@caution}{\py@heavybox} -\newcommand{\py@noticeend@caution}{\py@endheavybox} -\newcommand{\py@noticestart@attention}{\py@heavybox} -\newcommand{\py@noticeend@attention}{\py@endheavybox} -\newcommand{\py@noticestart@danger}{\py@heavybox} -\newcommand{\py@noticeend@danger}{\py@endheavybox} -\newcommand{\py@noticestart@error}{\py@heavybox} -\newcommand{\py@noticeend@error}{\py@endheavybox} - -\newenvironment{notice}[2]{ - \def\py@noticetype{#1} - \csname py@noticestart@#1\endcsname - \strong{#2} -}{\csname py@noticeend@\py@noticetype\endcsname} +% the main dispatch for all types of notices +\newenvironment{sphinxadmonition}{\begin{notice}}{\end{notice}} +% use of ``notice'' is for backwards compatibility and will be removed in +% future release; sphinxadmonition environment will be defined directly. +\newenvironment{notice}[2]{% #1=type, #2=heading + % can't use #1 directly in definition of end part + \def\spx@noticetype {#1}% + % set parameters of heavybox/lightbox + \sphinxcolorlet{spx@notice@bordercolor}{sphinx#1bordercolor}% + \sphinxcolorlet{spx@notice@bgcolor}{sphinx#1bgcolor}% + \setlength\spx@notice@border {\dimexpr\csname sphinx#1border\endcsname\relax}% + % start specific environment, passing the heading as argument + \begin{sphinx#1}{#2}} + % in end part, need to go around a LaTeX's "feature" + {\edef\spx@temp{\noexpand\end{sphinx\spx@noticetype}}\spx@temp} % Allow the release number to be specified independently of the % \date{}. This allows the date to reflect the document's date and @@ -616,7 +752,7 @@ % This sets up the fancy chapter headings that make the documents look % at least a little better than the usual LaTeX output. % -\@ifundefined{ChTitleVar}{}{ +\spx@ifundefined{ChTitleVar}{}{ \ChNameVar{\raggedleft\normalsize\py@HeaderFamily} \ChNumVar{\raggedleft \bfseries\Large\py@HeaderFamily} \ChTitleVar{\raggedleft \textrm{\Huge\py@HeaderFamily}} @@ -656,7 +792,7 @@ % The following is stuff copied from docutils' latex writer. % -\newcommand{\optionlistlabel}[1]{\bf #1 \hfill} +\newcommand{\optionlistlabel}[1]{\normalfont\bfseries #1 \hfill}% \bf deprecated \newenvironment{optionlist}[1] {\begin{list}{} {\setlength{\labelwidth}{#1} @@ -678,26 +814,29 @@ \raggedright} {\end{list}} -% Redefine includgraphics for avoiding images larger than the screen size -% If the size is not specified. +% Re-define \includegraphics to resize images larger than the line width +% if the size is not specified. +% Warning: future version of Sphinx will not modify original \includegraphics, +% Below custom code will be direct definition of \sphinxincludegraphics, with +% \py@Oldincludegraphics replaced by direct use of original \includegraphics. \let\py@Oldincludegraphics\includegraphics - -\newbox\image@box% -\newdimen\image@width% -\renewcommand\includegraphics[2][\@empty]{% - \ifx#1\@empty% - \setbox\image@box=\hbox{\py@Oldincludegraphics{#2}}% - \image@width\wd\image@box% - \ifdim \image@width>\linewidth% - \setbox\image@box=\hbox{\py@Oldincludegraphics[width=\linewidth]{#2}}% - \box\image@box% - \else% - \py@Oldincludegraphics{#2}% - \fi% - \else% +\newbox\spx@image@box +\renewcommand*{\includegraphics}[2][\@empty]{% + \ifx\@empty #1% attention, #1 could be bb.., bad if first after \ifx + \setbox\spx@image@box=\hbox{\py@Oldincludegraphics{#2}}% + \ifdim \wd\spx@image@box>\linewidth + \py@Oldincludegraphics[width=\linewidth]{#2}% + \else + \leavevmode\box\spx@image@box + \fi + \else \py@Oldincludegraphics[#1]{#2}% - \fi% + \fi } +% Writer will put \sphinxincludegraphics in LaTeX source, and with this, +% documents which used their own modified \includegraphics will compile +% as before. But see warning above. +\newcommand*{\sphinxincludegraphics}{\includegraphics} % to make pdf with correct encoded bookmarks in Japanese % this should precede the hyperref package @@ -745,12 +884,12 @@ \fi% } -\providecommand*{\DUprovidelength}[2]{ - \ifthenelse{\isundefined{#1}}{\newlength{#1}\setlength{#1}{#2}}{} +\providecommand*{\DUprovidelength}[2]{% + \ifdefined#1\else\newlength{#1}\setlength{#1}{#2}\fi } \DUprovidelength{\DUlineblockindent}{2.5em} -\ifthenelse{\isundefined{\DUlineblock}}{ +\ifdefined\DUlineblock\else \newenvironment{DUlineblock}[1]{% \list{}{\setlength{\partopsep}{\parskip} \addtolength{\partopsep}{\baselineskip} @@ -761,8 +900,7 @@ \raggedright } {\endlist} -}{} - +\fi % From footmisc.sty: allows footnotes in titles \let\FN@sf@@footnote\footnote @@ -813,18 +951,79 @@ } \fi -% Define literal-block environment -\RequirePackage{newfloat} -\DeclareFloatingEnvironment{literal-block} -\ifx\thechapter\undefined - \SetupFloatingEnvironment{literal-block}{within=section,placement=h} -\else - \SetupFloatingEnvironment{literal-block}{within=chapter,placement=h} -\fi -\SetupFloatingEnvironment{literal-block}{name=List} +% for captions of literal blocks +\newcounter{literalblock} +\spx@ifundefined{c@chapter} + {\@addtoreset{literalblock}{section} + \def\theliteralblock {\ifnum\c@section>\z@ \thesection.\fi\arabic{literalblock}} + \def\theHliteralblock {\theHsection.\arabic{literalblock}}} + {\@addtoreset{literalblock}{chapter} + \def\theliteralblock {\ifnum\c@chapter>\z@ \thechapter.\fi\arabic{literalblock}} + \def\theHliteralblock {\theHchapter.\arabic{literalblock}}} +% at start of caption title +\newcommand*{\fnum@literalblock}{\literalblockname\nobreakspace\theliteralblock} +% this will be overwritten in document preamble by Babel translation +\newcommand*{\literalblockname}{Listing } +% file extension needed for \caption's good functioning, the file is created +% only if a \listof{literalblock}{foo} command is encountered, which is +% analogous to \listoffigures, but for the code listings (foo = chosen title.) +\newcommand*{\ext@literalblock}{lol} + % control caption around literal-block \RequirePackage{capt-of} \RequirePackage{needspace} % if the left page space is less than \literalblockneedspace, insert page-break -\newcommand{\literalblockneedspace}{5\baselineskip} -\newcommand{\literalblockwithoutcaptionneedspace}{1.5\baselineskip} +\newcommand{\sphinxliteralblockneedspace}{5\baselineskip} +\newcommand{\sphinxliteralblockwithoutcaptionneedspace}{1.5\baselineskip} + +% figure in table +\newenvironment{sphinxfigure-in-table}[1][\linewidth]{% + \def\@captype{figure}% + \begin{minipage}{#1}% +}{\end{minipage}} +% store original \caption macro for use with figures in longtable and tabulary +\AtBeginDocument{\let\spx@originalcaption\caption} +\newcommand*\sphinxfigcaption + {\ifx\equation$%$% this is trick to identify tabulary first pass + \firstchoice@false\else\firstchoice@true\fi + \spx@originalcaption } + +% by default, also define macros with the no-prefix names +\ifsphinxKeepOldNames + \typeout{** (sphinx) defining (legacy) text style macros without \string\sphinx\space prefix} + \typeout{** if clashes with packages, set latex_keep_old_macro_names=False in conf.py} + \@for\@tempa:=strong,bfcode,email,tablecontinued,titleref,% + menuselection,accelerator,crossref,termref,optional\do +{% first, check if command with no prefix already exists + \expandafter\newcommand\csname\@tempa\endcsname{}% + % if no error give it the meaning defined so far with \sphinx prefix + \expandafter\let\csname\@tempa\expandafter\endcsname + \csname sphinx\@tempa\endcsname + % redefine the \sphinx prefixed macro to expand to non-prefixed one + \expandafter\def\csname sphinx\@tempa\expandafter\endcsname + \expandafter{\csname\@tempa\endcsname}% +} + % robustified case needs special treatment + \newcommand\code{}\let\code\relax + \DeclareRobustCommand{\code}[1]{{\@noligs\scantokens{\texttt{#1}\relax}}} + \def\sphinxcode{\code}% +\fi + +% additional customizable styling +\newcommand*{\sphinxstyleindexentry}{\texttt} +\newcommand{\sphinxstyleindexextra}[1]{ \emph{(#1)}} +\newcommand*{\sphinxstyleindexpageref}{, \pageref} +\newcommand{\sphinxstyletopictitle}[1]{\textbf{#1}\par\medskip} +\let\sphinxstylesidebartitle\sphinxstyletopictitle +\newcommand*{\sphinxstyleothertitle}{\textbf} +\newcommand{\sphinxstylesidebarsubtitle}[1]{~\\\textbf{#1} \smallskip} +\newcommand*{\sphinxstylethead}{\textsf} +\newcommand*{\sphinxstyleemphasis}{\emph} +\newcommand{\sphinxstyleliteralemphasis}[1]{\emph{\texttt{#1}}} +\newcommand*{\sphinxstylestrong}{\textbf} +\newcommand{\sphinxstyleliteralstrong}[1]{\textbf{\texttt{#1}}} +\newcommand*{\sphinxstyleabbreviation}{\textsc} +\newcommand*{\sphinxstyleliteralintitle}{\texttt} + +% stylesheet for highlighting with pygments +\RequirePackage{sphinxhighlight} diff --git a/sphinx/texinputs/sphinxhowto.cls b/sphinx/texinputs/sphinxhowto.cls index 8607ef8c4..8d5c59232 100644 --- a/sphinx/texinputs/sphinxhowto.cls +++ b/sphinx/texinputs/sphinxhowto.cls @@ -35,30 +35,31 @@ % Change the title page to look a bit better, and fit in with the fncychap % ``Bjarne'' style a bit better. % -\renewcommand{\maketitle}{ - \rule{\textwidth}{1pt} +\renewcommand{\maketitle}{% + \noindent\rule{\textwidth}{1pt}\ifsphinxpdfoutput\newline\null\fi\par \ifsphinxpdfoutput \begingroup % These \defs are required to deal with multi-line authors; it % changes \\ to ', ' (comma-space), making it pass muster for % generating document info in the PDF file. - \def\\{, } - \def\and{and } + \def\\{, }% + \def\and{and }% \pdfinfo{ /Author (\@author) /Title (\@title) - } + }% \endgroup \fi \begin{flushright} - \sphinxlogo% - {\rm\Huge\py@HeaderFamily \@title} \par - {\em\large\py@HeaderFamily \py@release\releaseinfo} \par + \sphinxlogo + \py@HeaderFamily + {\Huge \@title }\par + {\itshape\large \py@release \releaseinfo}\par \vspace{25pt} - {\Large\py@HeaderFamily + {\Large \begin{tabular}[t]{c} \@author - \end{tabular}} \par + \end{tabular}}\par \vspace{25pt} \@date \par \py@authoraddress \par diff --git a/sphinx/texinputs/sphinxmanual.cls b/sphinx/texinputs/sphinxmanual.cls index b576b673e..f20449449 100644 --- a/sphinx/texinputs/sphinxmanual.cls +++ b/sphinx/texinputs/sphinxmanual.cls @@ -43,26 +43,27 @@ \begin{titlepage}% \let\footnotesize\small \let\footnoterule\relax - \rule{\textwidth}{1pt}% + \noindent\rule{\textwidth}{1pt}\ifsphinxpdfoutput\newline\null\fi\par \ifsphinxpdfoutput \begingroup % These \defs are required to deal with multi-line authors; it % changes \\ to ', ' (comma-space), making it pass muster for % generating document info in the PDF file. - \def\\{, } - \def\and{and } + \def\\{, }% + \def\and{and }% \pdfinfo{ /Author (\@author) /Title (\@title) - } + }% \endgroup \fi \begin{flushright}% - \sphinxlogo% - {\rm\Huge\py@HeaderFamily \@title \par}% - {\em\LARGE\py@HeaderFamily \py@release\releaseinfo \par} + \sphinxlogo + \py@HeaderFamily + {\Huge \@title \par} + {\itshape\LARGE \py@release\releaseinfo \par} \vfill - {\LARGE\py@HeaderFamily + {\LARGE \begin{tabular}[t]{c} \@author \end{tabular} @@ -76,52 +77,27 @@ \end{flushright}%\par \@thanks \end{titlepage}% - \cleardoublepage% \setcounter{footnote}{0}% \let\thanks\relax\let\maketitle\relax %\gdef\@thanks{}\gdef\@author{}\gdef\@title{} } - -% Catch the end of the {abstract} environment, but here make sure the abstract -% is followed by a blank page if the 'openright' option is used. -% -\let\py@OldEndAbstract=\endabstract -\renewcommand{\endabstract}{ - \if@openright - \ifodd\value{page} - \typeout{Adding blank page after the abstract.} - \vfil\pagebreak - \fi - \fi - \py@OldEndAbstract -} - -% This wraps the \tableofcontents macro with all the magic to get the spacing -% right and have the right number of pages if the 'openright' option has been -% used. This eliminates a fair amount of crud in the individual document files. -% \let\py@OldTableofcontents=\tableofcontents \renewcommand{\tableofcontents}{% + % before resetting page counter, let's do the right thing. + \if@openright\cleardoublepage\else\clearpage\fi \pagenumbering{roman}% - \setcounter{page}{1}% - \pagebreak% \pagestyle{plain}% - {% - \parskip = 0mm% - \py@OldTableofcontents% - \if@openright% - \ifodd\value{page}% - \typeout{Adding blank page after the table of contents.}% - \pagebreak\hspace{0pt}% - \fi% - \fi% - \cleardoublepage% - }% + \begingroup + \parskip \z@skip + \py@OldTableofcontents + \endgroup + % before resetting page counter, let's do the right thing. + \if@openright\cleardoublepage\else\clearpage\fi \pagenumbering{arabic}% - \@ifundefined{fancyhf}{}{\pagestyle{normal}}% + \ifdefined\fancyhf\pagestyle{normal}\fi } -\pagenumbering{alph} +\pagenumbering{alph}% avoid hyperref "duplicate destination" warnings % This is needed to get the width of the section # area wide enough in the % library reference. Doing it here keeps it the same for all the manuals. @@ -134,7 +110,7 @@ % For a report document class this environment is a chapter. \let\py@OldThebibliography=\thebibliography \renewcommand{\thebibliography}[1]{ - \cleardoublepage + \if@openright\cleardoublepage\else\clearpage\fi \phantomsection \py@OldThebibliography{1} \addcontentsline{toc}{chapter}{\bibname} @@ -146,7 +122,7 @@ \@ifclassloaded{memoir}{}{ \let\py@OldTheindex=\theindex \renewcommand{\theindex}{ - \cleardoublepage + \if@openright\cleardoublepage\else\clearpage\fi \phantomsection \py@OldTheindex \addcontentsline{toc}{chapter}{\indexname} diff --git a/sphinx/texinputs/tabulary.sty b/sphinx/texinputs/tabulary.sty index 11fdf7428..03e07ec2a 100644 --- a/sphinx/texinputs/tabulary.sty +++ b/sphinx/texinputs/tabulary.sty @@ -14,7 +14,7 @@ %% \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{tabulary} - [2008/12/01 v0.9 tabulary package (DPC)] + [2014/06/11 v0.10 tabulary package (DPC) + footnote patch (sphinx)] \RequirePackage{array} \catcode`\Z=14 \DeclareOption{debugshow}{\catcode`\Z=9\relax} @@ -354,6 +354,7 @@ Z \message{^^JTotal:\the\@tempdima^^J}% \expandafter\let\expandafter\color\expandafter\relax \expandafter\let\expandafter\CT@column@color\expandafter\relax \expandafter\let\expandafter\CT@row@color\expandafter\relax + \expandafter\let\expandafter\CT@cell@color\expandafter\relax \@mkpream{#1}} \let\TY@@mkpream\@mkpream \def\TY@classz{% @@ -396,6 +397,7 @@ Z \message{^^JTotal:\the\@tempdima^^J}% \CT@setup \CT@column@color \CT@row@color + \CT@cell@color \CT@do@color \endgroup \@tempdima\ht\z@ diff --git a/sphinx/themes/agogo/static/bgfooter.png b/sphinx/themes/agogo/static/bgfooter.png index 9ce5bdd90..b7c7cadd4 100644 Binary files a/sphinx/themes/agogo/static/bgfooter.png and b/sphinx/themes/agogo/static/bgfooter.png differ diff --git a/sphinx/themes/agogo/static/bgtop.png b/sphinx/themes/agogo/static/bgtop.png index a0d4709ba..05740880f 100644 Binary files a/sphinx/themes/agogo/static/bgtop.png and b/sphinx/themes/agogo/static/bgtop.png differ diff --git a/sphinx/themes/basic/layout.html b/sphinx/themes/basic/layout.html index 1afc4a0bf..f8ff477c7 100644 --- a/sphinx/themes/basic/layout.html +++ b/sphinx/themes/basic/layout.html @@ -91,7 +91,8 @@ VERSION: '{{ release|e }}', COLLAPSE_INDEX: false, FILE_SUFFIX: '{{ '' if no_search_suffix else file_suffix }}', - HAS_SOURCE: {{ has_source|lower }} + HAS_SOURCE: {{ has_source|lower }}, + SOURCELINK_SUFFIX: '{{ sourcelink_suffix }}' }; {%- for scriptfile in script_files %} diff --git a/sphinx/themes/basic/searchbox.html b/sphinx/themes/basic/searchbox.html index 5749b761f..ae25f7f12 100644 --- a/sphinx/themes/basic/searchbox.html +++ b/sphinx/themes/basic/searchbox.html @@ -11,8 +11,8 @@