mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge remote-tracking branch 'upstream/master' into 5842-apidoc-extensions
This commit is contained in:
59
CHANGES
59
CHANGES
@@ -17,6 +17,7 @@ Dependencies
|
||||
which in Ubuntu xenial are provided by package ``fonts-freefont-otf``, and
|
||||
e.g. in Fedora 29 via package ``texlive-gnu-freefont``.
|
||||
* requests 2.5.0 or above
|
||||
* The six package is no longer a dependency.
|
||||
|
||||
Incompatible changes
|
||||
--------------------
|
||||
@@ -45,6 +46,11 @@ Incompatible changes
|
||||
block. As a result, they are highlighted as python3 by default.
|
||||
* The order of argument for ``HTMLTranslator``, ``HTML5Translator`` and
|
||||
``ManualPageTranslator`` are changed
|
||||
* LaTeX: hard-coded redefinitions of ``\l@section`` and ``\l@subsection``
|
||||
formerly done during loading of ``'manual'`` docclass get executed later, at
|
||||
time of ``\sphinxtableofcontents``. This means that custom user definitions
|
||||
from LaTeX preamble now get overwritten. Use ``\sphinxtableofcontentshook``
|
||||
to insert custom user definitions. See :ref:`latex-macros`.
|
||||
|
||||
Deprecated
|
||||
----------
|
||||
@@ -127,6 +133,10 @@ Features added
|
||||
* LaTeX: support rendering (not in math, yet) of Greek and Cyrillic Unicode
|
||||
letters in non-Cyrillic document even with ``'pdflatex'`` as
|
||||
:confval:`latex_engine` (refs: #5645)
|
||||
* #5660: The ``versionadded``, ``versionchanged`` and ``deprecated`` directives
|
||||
are now generated with their own specific CSS classes
|
||||
(``added``, ``changed`` and ``deprecated``, respectively) in addition to the
|
||||
generic ``versionmodified`` class.
|
||||
* #5841: apidoc: Add --extensions option to sphinx-apidoc
|
||||
|
||||
Bugs fixed
|
||||
@@ -149,7 +159,7 @@ Bugs fixed
|
||||
Testing
|
||||
--------
|
||||
|
||||
Release 1.8.3 (in development)
|
||||
Release 1.8.4 (in development)
|
||||
==============================
|
||||
|
||||
Dependencies
|
||||
@@ -167,6 +177,22 @@ Features added
|
||||
Bugs fixed
|
||||
----------
|
||||
|
||||
Testing
|
||||
--------
|
||||
|
||||
Release 1.8.3 (released Dec 26, 2018)
|
||||
=====================================
|
||||
|
||||
Features added
|
||||
--------------
|
||||
|
||||
* LaTeX: it is possible to insert custom material to appear on back of title
|
||||
page, see discussion of ``'maketitle'`` key of :confval:`latex_elements`
|
||||
(``'manual'`` docclass only)
|
||||
|
||||
Bugs fixed
|
||||
----------
|
||||
|
||||
* #5725: mathjax: Use CDN URL for "latest" version by default
|
||||
* #5460: html search does not work with some 3rd party themes
|
||||
* #5520: LaTeX, caption package incompatibility since Sphinx 1.6
|
||||
@@ -179,9 +205,13 @@ Bugs fixed
|
||||
* #5636: C++, fix parsing of floating point literals.
|
||||
* #5496 (again): C++, fix assertion in partial builds with duplicates.
|
||||
* #5724: quickstart: sphinx-quickstart fails when $LC_ALL is empty
|
||||
|
||||
Testing
|
||||
--------
|
||||
* #1956: Default conf.py is not PEP8-compliant
|
||||
* #5849: LaTeX: document class ``\maketitle`` is overwritten with no
|
||||
possibility to use original meaning in place of Sphinx custom one
|
||||
* #5834: apidoc: wrong help for ``--tocfile``
|
||||
* #5800: todo: crashed if todo is defined in TextElement
|
||||
* #5846: htmlhelp: convert hex escaping to decimal escaping in .hhc/.hhk files
|
||||
* htmlhelp: broken .hhk file generated when title contains a double quote
|
||||
|
||||
Release 1.8.2 (released Nov 11, 2018)
|
||||
=====================================
|
||||
@@ -551,27 +581,6 @@ Documentation
|
||||
* #5083: Fix wrong make.bat option for internationalization.
|
||||
* #5115: napoleon: add admonitions added by #4613 to the docs.
|
||||
|
||||
Release 1.7.10 (in development)
|
||||
===============================
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
|
||||
Incompatible changes
|
||||
--------------------
|
||||
|
||||
Deprecated
|
||||
----------
|
||||
|
||||
Features added
|
||||
--------------
|
||||
|
||||
Bugs fixed
|
||||
----------
|
||||
|
||||
Testing
|
||||
--------
|
||||
|
||||
Release 1.7.9 (released Sep 05, 2018)
|
||||
=====================================
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ Sphinx documentation contents
|
||||
templating
|
||||
latex
|
||||
extdev/index
|
||||
development/tutorials/index
|
||||
|
||||
faq
|
||||
glossary
|
||||
|
||||
@@ -100,7 +100,7 @@ This is the current list of contributed extensions in that repository:
|
||||
- zopeext: provide an ``autointerface`` directive for using `Zope interfaces`_
|
||||
|
||||
|
||||
See the :ref:`extension tutorial <exttut>` on getting started with writing your
|
||||
See the :doc:`extension tutorials <../development/tutorials/index>` on getting started with writing your
|
||||
own extensions.
|
||||
|
||||
|
||||
|
||||
162
doc/development/tutorials/helloworld.rst
Normal file
162
doc/development/tutorials/helloworld.rst
Normal file
@@ -0,0 +1,162 @@
|
||||
Developing a "Hello world" directive
|
||||
====================================
|
||||
|
||||
The objective of this tutorial is to create a very basic extension that adds a new
|
||||
directive that outputs a paragraph containing `hello world`.
|
||||
|
||||
Only basic information is provided in this tutorial. For more information,
|
||||
refer to the :doc:`other tutorials <index>` that go into more
|
||||
details.
|
||||
|
||||
.. warning:: For this extension, you will need some basic understanding of docutils_
|
||||
and Python.
|
||||
|
||||
Creating a new extension file
|
||||
-----------------------------
|
||||
|
||||
Your extension file could be in any folder of your project. In our case,
|
||||
let's do the following:
|
||||
|
||||
#. Create an :file:`_ext` folder in :file:`source`.
|
||||
#. Create a new Python file in the :file:`_ext` folder called
|
||||
:file:`helloworld.py`.
|
||||
|
||||
Here is an example of the folder structure you might obtain:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
└── source
|
||||
├── _ext
|
||||
│ └── helloworld.py
|
||||
├── _static
|
||||
├── _themes
|
||||
├── conf.py
|
||||
├── somefolder
|
||||
├── somefile.rst
|
||||
└── someotherfile.rst
|
||||
|
||||
Writing the extension
|
||||
---------------------
|
||||
|
||||
Open :file:`helloworld.py` and paste the following code in it:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.parsers.rst import Directive
|
||||
|
||||
|
||||
class HelloWorld(Directive):
|
||||
def run(self):
|
||||
paragraph_node = nodes.paragraph(text='Hello World!')
|
||||
return [paragraph_node]
|
||||
|
||||
|
||||
def setup(app):
|
||||
app.add_directive("helloworld", HelloWorld)
|
||||
|
||||
|
||||
Some essential things are happening in this example, and you will see them
|
||||
in all directives:
|
||||
|
||||
.. rubric:: Directive declaration
|
||||
|
||||
Our new directive is declared in the ``HelloWorld`` class, it extends
|
||||
docutils_' ``Directive`` class. All extensions that create directives
|
||||
should extend this class.
|
||||
|
||||
.. rubric:: ``run`` method
|
||||
|
||||
This method is a requirement and it is part of every directive. It contains
|
||||
the main logic of the directive and it returns a list of docutils nodes to
|
||||
be processed by Sphinx.
|
||||
|
||||
.. seealso::
|
||||
|
||||
:doc:`todo`
|
||||
|
||||
.. rubric:: docutils nodes
|
||||
|
||||
The ``run`` method returns a list of nodes. Nodes are docutils' way of
|
||||
representing the content of a document. There are many types of nodes
|
||||
available: text, paragraph, reference, table, etc.
|
||||
|
||||
.. seealso::
|
||||
|
||||
`The docutils documentation on nodes <docutils nodes>`_
|
||||
|
||||
The ``nodes.paragraph`` class creates a new paragraph node. A paragraph
|
||||
node typically contains some text that we can set during instantiation using
|
||||
the ``text`` parameter.
|
||||
|
||||
.. rubric:: ``setup`` function
|
||||
|
||||
This function is a requirement. We use it to plug our new directive into
|
||||
Sphinx.
|
||||
The simplest thing you can do it call the ``app.add_directive`` method.
|
||||
|
||||
.. note::
|
||||
|
||||
The first argument is the name of the directive itself as used in an rST file.
|
||||
|
||||
In our case, we would use ``helloworld``:
|
||||
|
||||
.. code-block:: rst
|
||||
|
||||
Some intro text here...
|
||||
|
||||
.. helloworld::
|
||||
|
||||
Some more text here...
|
||||
|
||||
|
||||
Updating the conf.py file
|
||||
-------------------------
|
||||
|
||||
The extension file has to be declared in your :file:`conf.py` file to make
|
||||
Sphinx aware of it:
|
||||
|
||||
#. Open :file:`conf.py`. It is in the :file:`source` folder by default.
|
||||
#. Add ``sys.path.append(os.path.abspath("./_ext"))`` before
|
||||
the ``extensions`` variable declaration (if it exists).
|
||||
#. Update or create the ``extensions`` list and add the
|
||||
extension file name to the list:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
extensions.append('helloworld')
|
||||
|
||||
You can now use the extension.
|
||||
|
||||
.. admonition:: Example
|
||||
|
||||
.. code-block:: rst
|
||||
|
||||
Some intro text here...
|
||||
|
||||
.. helloworld::
|
||||
|
||||
Some more text here...
|
||||
|
||||
The sample above would generate:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
Some intro text here...
|
||||
|
||||
Hello World!
|
||||
|
||||
Some more text here...
|
||||
|
||||
This is the very basic principle of an extension that creates a new directive.
|
||||
|
||||
For a more advanced example, refer to :doc:`todo`.
|
||||
|
||||
Further reading
|
||||
---------------
|
||||
|
||||
You can create your own nodes if needed, refer to the
|
||||
:doc:`todo` for more information.
|
||||
|
||||
.. _docutils: http://docutils.sourceforge.net/
|
||||
.. _`docutils nodes`: http://docutils.sourceforge.net/docs/ref/doctree.html
|
||||
11
doc/development/tutorials/index.rst
Normal file
11
doc/development/tutorials/index.rst
Normal file
@@ -0,0 +1,11 @@
|
||||
Extension tutorials
|
||||
===================
|
||||
|
||||
Refer to the following tutorials to get started with extension development.
|
||||
|
||||
.. toctree::
|
||||
:caption: Directive tutorials
|
||||
:maxdepth: 1
|
||||
|
||||
helloworld
|
||||
todo
|
||||
@@ -1,7 +1,5 @@
|
||||
.. _exttut:
|
||||
|
||||
Tutorial: Writing a simple extension
|
||||
====================================
|
||||
Developing a "TODO" extension
|
||||
=============================
|
||||
|
||||
This section is intended as a walkthrough for the creation of custom extensions.
|
||||
It covers the basics of writing and activating an extension, as well as
|
||||
@@ -12,112 +10,12 @@ include todo entries in the documentation, and to collect these in a central
|
||||
place. (A similar "todo" extension is distributed with Sphinx.)
|
||||
|
||||
|
||||
Important objects
|
||||
-----------------
|
||||
|
||||
There are several key objects whose API you will use while writing an
|
||||
extension. These are:
|
||||
|
||||
**Application**
|
||||
The application object (usually called ``app``) is an instance of
|
||||
:class:`.Sphinx`. It controls most high-level functionality, such as the
|
||||
setup of extensions, event dispatching and producing output (logging).
|
||||
|
||||
If you have the environment object, the application is available as
|
||||
``env.app``.
|
||||
|
||||
**Environment**
|
||||
The build environment object (usually called ``env``) is an instance of
|
||||
:class:`.BuildEnvironment`. It is responsible for parsing the source
|
||||
documents, stores all metadata about the document collection and is
|
||||
serialized to disk after each build.
|
||||
|
||||
Its API provides methods to do with access to metadata, resolving references,
|
||||
etc. It can also be used by extensions to cache information that should
|
||||
persist for incremental rebuilds.
|
||||
|
||||
If you have the application or builder object, the environment is available
|
||||
as ``app.env`` or ``builder.env``.
|
||||
|
||||
**Builder**
|
||||
The builder object (usually called ``builder``) is an instance of a specific
|
||||
subclass of :class:`.Builder`. Each builder class knows how to convert the
|
||||
parsed documents into an output format, or otherwise process them (e.g. check
|
||||
external links).
|
||||
|
||||
If you have the application object, the builder is available as
|
||||
``app.builder``.
|
||||
|
||||
**Config**
|
||||
The config object (usually called ``config``) provides the values of
|
||||
configuration values set in :file:`conf.py` as attributes. It is an instance
|
||||
of :class:`.Config`.
|
||||
|
||||
The config is available as ``app.config`` or ``env.config``.
|
||||
|
||||
|
||||
Build Phases
|
||||
------------
|
||||
|
||||
One thing that is vital in order to understand extension mechanisms is the way
|
||||
in which a Sphinx project is built: this works in several phases.
|
||||
|
||||
**Phase 0: Initialization**
|
||||
|
||||
In this phase, almost nothing of interest to us happens. The source
|
||||
directory is searched for source files, and extensions are initialized.
|
||||
Should a stored build environment exist, it is loaded, otherwise a new one is
|
||||
created.
|
||||
|
||||
**Phase 1: Reading**
|
||||
|
||||
In Phase 1, all source files (and on subsequent builds, those that are new or
|
||||
changed) are read and parsed. This is the phase where directives and roles
|
||||
are encountered by docutils, and the corresponding code is executed. The
|
||||
output of this phase is a *doctree* for each source file; that is a tree of
|
||||
docutils nodes. For document elements that aren't fully known until all
|
||||
existing files are read, temporary nodes are created.
|
||||
|
||||
There are nodes provided by docutils, which are documented `in the docutils
|
||||
documentation <http://docutils.sourceforge.net/docs/ref/doctree.html>`__.
|
||||
Additional nodes are provided by Sphinx and :ref:`documented here <nodes>`.
|
||||
|
||||
During reading, the build environment is updated with all meta- and cross
|
||||
reference data of the read documents, such as labels, the names of headings,
|
||||
described Python objects and index entries. This will later be used to
|
||||
replace the temporary nodes.
|
||||
|
||||
The parsed doctrees are stored on the disk, because it is not possible to
|
||||
hold all of them in memory.
|
||||
|
||||
**Phase 2: Consistency checks**
|
||||
|
||||
Some checking is done to ensure no surprises in the built documents.
|
||||
|
||||
**Phase 3: Resolving**
|
||||
|
||||
Now that the metadata and cross-reference data of all existing documents is
|
||||
known, all temporary nodes are replaced by nodes that can be converted into
|
||||
output using components called tranform. For example, links are created for
|
||||
object references that exist, and simple literal nodes are created for those
|
||||
that don't.
|
||||
|
||||
**Phase 4: Writing**
|
||||
|
||||
This phase converts the resolved doctrees to the desired output format, such
|
||||
as HTML or LaTeX. This happens via a so-called docutils writer that visits
|
||||
the individual nodes of each doctree and produces some output in the process.
|
||||
|
||||
.. note::
|
||||
|
||||
Some builders deviate from this general build plan, for example, the builder
|
||||
that checks external links does not need anything more than the parsed
|
||||
doctrees and therefore does not have phases 2--4.
|
||||
|
||||
|
||||
Extension Design
|
||||
----------------
|
||||
|
||||
.. note:: To understand the design this extension, refer to
|
||||
:ref:`important-objects` and :ref:`build-phases`.
|
||||
|
||||
We want the extension to add the following to Sphinx:
|
||||
|
||||
* A "todo" directive, containing some content that is marked with "TODO", and
|
||||
@@ -174,12 +72,13 @@ the individual calls do is the following:
|
||||
|
||||
If the third argument was ``'html'``, HTML documents would be full rebuild if the
|
||||
config value changed its value. This is needed for config values that
|
||||
influence reading (build phase 1).
|
||||
influence reading (build :ref:`phase 1 <build-phases>`).
|
||||
|
||||
* :meth:`~Sphinx.add_node` adds a new *node class* to the build system. It also
|
||||
can specify visitor functions for each supported output format. These visitor
|
||||
functions are needed when the new nodes stay until phase 4 -- since the
|
||||
``todolist`` node is always replaced in phase 3, it doesn't need any.
|
||||
functions are needed when the new nodes stay until :ref:`phase 4 <build-phases>`
|
||||
-- since the ``todolist`` node is always replaced in :ref:`phase 3 <build-phases>`,
|
||||
it doesn't need any.
|
||||
|
||||
We need to create the two node classes ``todo`` and ``todolist`` later.
|
||||
|
||||
@@ -276,7 +175,7 @@ The ``todo`` directive function looks like this::
|
||||
return [targetnode, todo_node]
|
||||
|
||||
Several important things are covered here. First, as you can see, you can refer
|
||||
to the build environment instance using ``self.state.document.settings.env``.
|
||||
to the :ref:`build environment instance <important-objects>` using ``self.state.document.settings.env``.
|
||||
|
||||
Then, to act as a link target (from the todolist), the todo directive needs to
|
||||
return a target node in addition to the todo node. The target ID (in HTML, this
|
||||
@@ -340,7 +239,8 @@ Here we clear out all todos whose docname matches the given one from the
|
||||
added again during parsing.
|
||||
|
||||
The other handler belongs to the :event:`doctree-resolved` event. This event is
|
||||
emitted at the end of phase 3 and allows custom resolving to be done::
|
||||
emitted at the end of :ref:`phase 3 <build-phases>` and allows custom resolving
|
||||
to be done::
|
||||
|
||||
def process_todo_nodes(app, doctree, fromdocname):
|
||||
if not app.config.todo_include_todos:
|
||||
@@ -52,6 +52,115 @@ Note that it is still necessary to register the builder using
|
||||
|
||||
.. _entry points: https://setuptools.readthedocs.io/en/latest/setuptools.html#dynamic-discovery-of-services-and-plugins
|
||||
|
||||
.. _important-objects:
|
||||
|
||||
Important objects
|
||||
-----------------
|
||||
|
||||
There are several key objects whose API you will use while writing an
|
||||
extension. These are:
|
||||
|
||||
**Application**
|
||||
The application object (usually called ``app``) is an instance of
|
||||
:class:`.Sphinx`. It controls most high-level functionality, such as the
|
||||
setup of extensions, event dispatching and producing output (logging).
|
||||
|
||||
If you have the environment object, the application is available as
|
||||
``env.app``.
|
||||
|
||||
**Environment**
|
||||
The build environment object (usually called ``env``) is an instance of
|
||||
:class:`.BuildEnvironment`. It is responsible for parsing the source
|
||||
documents, stores all metadata about the document collection and is
|
||||
serialized to disk after each build.
|
||||
|
||||
Its API provides methods to do with access to metadata, resolving references,
|
||||
etc. It can also be used by extensions to cache information that should
|
||||
persist for incremental rebuilds.
|
||||
|
||||
If you have the application or builder object, the environment is available
|
||||
as ``app.env`` or ``builder.env``.
|
||||
|
||||
**Builder**
|
||||
The builder object (usually called ``builder``) is an instance of a specific
|
||||
subclass of :class:`.Builder`. Each builder class knows how to convert the
|
||||
parsed documents into an output format, or otherwise process them (e.g. check
|
||||
external links).
|
||||
|
||||
If you have the application object, the builder is available as
|
||||
``app.builder``.
|
||||
|
||||
**Config**
|
||||
The config object (usually called ``config``) provides the values of
|
||||
configuration values set in :file:`conf.py` as attributes. It is an instance
|
||||
of :class:`.Config`.
|
||||
|
||||
The config is available as ``app.config`` or ``env.config``.
|
||||
|
||||
To see an example of use of these objects, refer to :doc:`../development/tutorials/index`.
|
||||
|
||||
.. _build-phases:
|
||||
|
||||
Build Phases
|
||||
------------
|
||||
|
||||
One thing that is vital in order to understand extension mechanisms is the way
|
||||
in which a Sphinx project is built: this works in several phases.
|
||||
|
||||
**Phase 0: Initialization**
|
||||
|
||||
In this phase, almost nothing of interest to us happens. The source
|
||||
directory is searched for source files, and extensions are initialized.
|
||||
Should a stored build environment exist, it is loaded, otherwise a new one is
|
||||
created.
|
||||
|
||||
**Phase 1: Reading**
|
||||
|
||||
In Phase 1, all source files (and on subsequent builds, those that are new or
|
||||
changed) are read and parsed. This is the phase where directives and roles
|
||||
are encountered by docutils, and the corresponding code is executed. The
|
||||
output of this phase is a *doctree* for each source file; that is a tree of
|
||||
docutils nodes. For document elements that aren't fully known until all
|
||||
existing files are read, temporary nodes are created.
|
||||
|
||||
There are nodes provided by docutils, which are documented `in the docutils
|
||||
documentation <http://docutils.sourceforge.net/docs/ref/doctree.html>`__.
|
||||
Additional nodes are provided by Sphinx and :ref:`documented here <nodes>`.
|
||||
|
||||
During reading, the build environment is updated with all meta- and cross
|
||||
reference data of the read documents, such as labels, the names of headings,
|
||||
described Python objects and index entries. This will later be used to
|
||||
replace the temporary nodes.
|
||||
|
||||
The parsed doctrees are stored on the disk, because it is not possible to
|
||||
hold all of them in memory.
|
||||
|
||||
**Phase 2: Consistency checks**
|
||||
|
||||
Some checking is done to ensure no surprises in the built documents.
|
||||
|
||||
**Phase 3: Resolving**
|
||||
|
||||
Now that the metadata and cross-reference data of all existing documents is
|
||||
known, all temporary nodes are replaced by nodes that can be converted into
|
||||
output using components called tranform. For example, links are created for
|
||||
object references that exist, and simple literal nodes are created for those
|
||||
that don't.
|
||||
|
||||
**Phase 4: Writing**
|
||||
|
||||
This phase converts the resolved doctrees to the desired output format, such
|
||||
as HTML or LaTeX. This happens via a so-called docutils writer that visits
|
||||
the individual nodes of each doctree and produces some output in the process.
|
||||
|
||||
.. note::
|
||||
|
||||
Some builders deviate from this general build plan, for example, the builder
|
||||
that checks external links does not need anything more than the parsed
|
||||
doctrees and therefore does not have phases 2--4.
|
||||
|
||||
To see an example of application, refer to :doc:`../development/tutorials/todo`.
|
||||
|
||||
.. _ext-metadata:
|
||||
|
||||
Extension metadata
|
||||
@@ -82,8 +191,8 @@ APIs used for writing extensions
|
||||
--------------------------------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
tutorial
|
||||
appapi
|
||||
projectapi
|
||||
envapi
|
||||
|
||||
@@ -30,7 +30,7 @@ How do I...
|
||||
``sidebartoc`` block.
|
||||
|
||||
... write my own extension?
|
||||
See the :ref:`extension tutorial <exttut>`.
|
||||
See the :doc:`/development/tutorials/index`.
|
||||
|
||||
... convert from my existing docs using MoinMoin markup?
|
||||
The easiest way is to convert to xhtml, then convert `xhtml to reST`_.
|
||||
|
||||
@@ -365,6 +365,8 @@ Here are some macros from the package file :file:`sphinx.sty` and class files
|
||||
:file:`sphinxhowto.cls`, :file:`sphinxmanual.cls`, which have public names
|
||||
thus allowing redefinitions. Check the respective files for the defaults.
|
||||
|
||||
.. _latex-macros:
|
||||
|
||||
Macros
|
||||
~~~~~~
|
||||
|
||||
@@ -390,13 +392,32 @@ Macros
|
||||
.. versionadded:: 1.6.3
|
||||
``\sphinxstylecodecontinued`` and ``\sphinxstylecodecontinues``.
|
||||
- the table of contents is typeset via ``\sphinxtableofcontents`` which is a
|
||||
wrapper (whose definition can be found in :file:`sphinxhowto.cls` or in
|
||||
:file:`sphinxmanual.cls`) of standard ``\tableofcontents``.
|
||||
wrapper (defined differently in :file:`sphinxhowto.cls` and in
|
||||
:file:`sphinxmanual.cls`) of standard ``\tableofcontents``. The macro
|
||||
``\sphinxtableofcontentshook`` is executed during its expansion right before
|
||||
``\tableofcontents`` itself.
|
||||
|
||||
.. versionchanged:: 1.5
|
||||
formerly, the meaning of ``\tableofcontents`` was modified by Sphinx.
|
||||
- the ``\maketitle`` command is redefined by the class files
|
||||
:file:`sphinxmanual.cls` and :file:`sphinxhowto.cls`.
|
||||
.. versionchanged:: 2.0
|
||||
hard-coded redefinitions of ``\l@section`` and ``\l@subsection`` formerly
|
||||
done during loading of ``'manual'`` docclass are now executed later via
|
||||
``\sphinxtableofcontentshook``. This macro is also executed by the
|
||||
``'howto'`` docclass, but defaults to empty with it.
|
||||
- a custom ``\sphinxmaketitle`` is defined in the class files
|
||||
:file:`sphinxmanual.cls` and :file:`sphinxhowto.cls` and is used as
|
||||
default setting of ``'maketitle'`` :confval:`latex_elements` key.
|
||||
|
||||
.. versionchanged:: 1.8.3
|
||||
formerly, ``\maketitle`` from LaTeX document class was modified by
|
||||
Sphinx.
|
||||
- for ``'manual'`` docclass a macro ``\sphinxbackoftitlepage``, if it is
|
||||
defined, gets executed at end of ``\sphinxmaketitle``, before the final
|
||||
``\clearpage``. Use either the ``'maketitle'`` key or the ``'preamble'`` key
|
||||
of :confval:`latex_elements` to add a custom definition of
|
||||
``\sphinxbackoftitlepage``.
|
||||
|
||||
.. versionadded:: 1.8.3
|
||||
- the citation reference is typeset via ``\sphinxcite`` which is a wrapper
|
||||
of standard ``\cite``.
|
||||
|
||||
|
||||
@@ -2279,10 +2279,22 @@ information.
|
||||
Previously this was done from inside :file:`sphinx.sty`.
|
||||
|
||||
``'maketitle'``
|
||||
"maketitle" call, default ``'\\maketitle'`` (but it has been
|
||||
redefined by the Sphinx ``manual`` and ``howto`` classes.) Override
|
||||
if you want to generate a differently-styled title page.
|
||||
"maketitle" call, default ``'\\sphinxmaketitle'``. Override
|
||||
if you want to generate a differently styled title page.
|
||||
|
||||
.. hint::
|
||||
|
||||
If the key value is set to
|
||||
``r'\newcommand\sphinxbackoftitlepage{<Extra
|
||||
material>}\sphinxmaketitle'``, then ``<Extra material>`` will be
|
||||
typeset on back of title page (``'manual'`` docclass only).
|
||||
|
||||
.. versionchanged:: 1.8.3
|
||||
Original ``\maketitle`` from document class is not overwritten,
|
||||
hence is re-usable as part of some custom setting for this key.
|
||||
.. versionadded:: 1.8.3
|
||||
``\sphinxbackoftitlepage`` optional macro. It can also be defined
|
||||
inside ``'preamble'`` key rather than this one.
|
||||
``'releasename'``
|
||||
value that prefixes ``'release'`` element on title page, default
|
||||
``'Release'``. As for *title* and *author* used in the tuples of
|
||||
|
||||
@@ -41,10 +41,9 @@ Configuration
|
||||
|
||||
.. confval:: viewcode_follow_imported_members
|
||||
|
||||
If this is ``True``, viewcode extension will follow alias objects that
|
||||
imported from another module such as functions, classes and attributes. As
|
||||
side effects, this option else they produce nothing. The default is
|
||||
``True``.
|
||||
If this is ``True``, viewcode extension will emit
|
||||
:event:`viewcode-follow-imported` event to resolve the name of the module
|
||||
by other extensions. The default is ``True``.
|
||||
|
||||
.. versionadded:: 1.3
|
||||
|
||||
|
||||
@@ -113,8 +113,7 @@ Prompt* (:kbd:`⊞Win-r` and type :command:`cmd`). Once the command prompt is
|
||||
open, type :command:`python --version` and press Enter. If Python is
|
||||
available, you will see the version of Python printed to the screen. If you do
|
||||
not have Python installed, refer to the `Hitchhikers Guide to Python's`__
|
||||
Python on Windows installation guides. You can install either `Python 3`__ or
|
||||
`Python 2.7`__. Python 3 is recommended.
|
||||
Python on Windows installation guides. You must install `Python 3`__.
|
||||
|
||||
Once Python is installed, you can install Sphinx using :command:`pip`. Refer
|
||||
to the :ref:`pip installation instructions <install-pypi>` below for more
|
||||
@@ -122,7 +121,6 @@ information.
|
||||
|
||||
__ https://docs.python-guide.org/
|
||||
__ https://docs.python-guide.org/starting/install3/win/
|
||||
__ https://docs.python-guide.org/starting/install/win/
|
||||
|
||||
|
||||
.. _install-pypi:
|
||||
|
||||
@@ -22,26 +22,41 @@ Configuration
|
||||
|
||||
To configure your Sphinx project for Markdown support, proceed as follows:
|
||||
|
||||
#. Install *recommonmark*::
|
||||
#. Install the Markdown parser *recommonmark* from its source on GitHub::
|
||||
|
||||
pip install recommonmark
|
||||
pip install git+https://github.com/rtfd/recommonmark
|
||||
|
||||
#. Add the Markdown parser to the ``source_parsers`` configuration variable in
|
||||
your Sphinx configuration file::
|
||||
.. note::
|
||||
|
||||
source_parsers = {
|
||||
'.md': 'recommonmark.parser.CommonMarkParser',
|
||||
The configuration as explained here requires recommonmark version
|
||||
0.5.0.dev or higher, which is at the time of writing not available on
|
||||
PyPI. If you want to use a released recommonmark version, follow the
|
||||
instructions in the `Sphinx 1.8 documentation`__.
|
||||
|
||||
__ https://www.sphinx-doc.org/en/1.8/usage/markdown.html
|
||||
|
||||
#. Add *recommonmark* to the
|
||||
:confval:`list of configured extensions <extensions>`::
|
||||
|
||||
extensions = ['recommonmark']
|
||||
|
||||
.. versionchanged:: 1.8
|
||||
Version 1.8 deprecates and version 3.0 removes the ``source_parsers``
|
||||
configuration variable that was used by older *recommonmark* versions.
|
||||
|
||||
#. If you want to use Markdown files with extensions other than ``.md``, adjust
|
||||
the :confval:`source_suffix` variable. The following example configures
|
||||
Sphinx to parse all files with the extensions ``.md`` and ``.txt`` as
|
||||
Markdown::
|
||||
|
||||
source_suffix = {
|
||||
'.rst': 'restructuredtext',
|
||||
'.txt': 'markdown',
|
||||
'.md': 'markdown',
|
||||
}
|
||||
|
||||
You can replace ``.md`` with a filename extension of your choice.
|
||||
|
||||
#. Add the Markdown filename extension to the ``source_suffix`` configuration
|
||||
variable::
|
||||
|
||||
source_suffix = ['.rst', '.md']
|
||||
|
||||
#. You can further configure *recommonmark* to allow custom syntax that
|
||||
standard *CommonMark* doesn't support. Read more in the `recommonmark
|
||||
standard *CommonMark* doesn't support. Read more in the `recommonmark
|
||||
documentation`__.
|
||||
|
||||
__ https://recommonmark.readthedocs.io/en/latest/auto_structify.html
|
||||
|
||||
1
setup.py
1
setup.py
@@ -15,7 +15,6 @@ if sys.version_info < (3, 5):
|
||||
sys.exit(1)
|
||||
|
||||
install_requires = [
|
||||
'six>=1.5',
|
||||
'Jinja2>=2.3',
|
||||
'Pygments>=2.0',
|
||||
'docutils>=0.12',
|
||||
|
||||
@@ -25,7 +25,6 @@ from docutils.frontend import OptionParser
|
||||
from docutils.io import DocTreeInput, StringOutput
|
||||
from docutils.readers.doctree import Reader as DoctreeReader
|
||||
from docutils.utils import relative_path
|
||||
from six import text_type
|
||||
|
||||
from sphinx import package_dir, __display_version__
|
||||
from sphinx.application import ENV_PICKLE_FILENAME
|
||||
@@ -86,10 +85,10 @@ def get_stable_hash(obj):
|
||||
return get_stable_hash(list(obj.items()))
|
||||
elif isinstance(obj, (list, tuple)):
|
||||
obj = sorted(get_stable_hash(o) for o in obj)
|
||||
return md5(text_type(obj).encode()).hexdigest()
|
||||
return md5(str(obj).encode()).hexdigest()
|
||||
|
||||
|
||||
class Stylesheet(text_type):
|
||||
class Stylesheet(str):
|
||||
"""A metadata of stylesheet.
|
||||
|
||||
To keep compatibility with old themes, an instance of stylesheet behaves as
|
||||
@@ -101,7 +100,7 @@ class Stylesheet(text_type):
|
||||
|
||||
def __new__(cls, filename, *args, **attributes):
|
||||
# type: (str, str, str) -> None
|
||||
self = text_type.__new__(cls, filename) # type: ignore
|
||||
self = str.__new__(cls, filename) # type: ignore
|
||||
self.filename = filename
|
||||
self.attributes = attributes
|
||||
self.attributes.setdefault('rel', 'stylesheet')
|
||||
@@ -146,7 +145,7 @@ class JSContainer(list):
|
||||
return ret
|
||||
|
||||
|
||||
class JavaScript(text_type):
|
||||
class JavaScript(str):
|
||||
"""A metadata of javascript file.
|
||||
|
||||
To keep compatibility with old themes, an instance of javascript behaves as
|
||||
@@ -158,7 +157,7 @@ class JavaScript(text_type):
|
||||
|
||||
def __new__(cls, filename, **attributes):
|
||||
# type: (str, **str) -> None
|
||||
self = text_type.__new__(cls, filename) # type: ignore
|
||||
self = str.__new__(cls, filename) # type: ignore
|
||||
self.filename = filename
|
||||
self.attributes = attributes
|
||||
self.attributes.setdefault('type', 'text/javascript')
|
||||
@@ -1633,7 +1632,7 @@ def setup(app):
|
||||
app.add_config_value('html_sidebars', {}, 'html')
|
||||
app.add_config_value('html_additional_pages', {}, 'html')
|
||||
app.add_config_value('html_domain_indices', True, 'html', [list])
|
||||
app.add_config_value('html_add_permalinks', '\u00B6', 'html')
|
||||
app.add_config_value('html_add_permalinks', '¶', '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')
|
||||
|
||||
@@ -25,7 +25,7 @@ from sphinx.util.osutil import make_filename_from_project
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
from typing import Any, Dict, IO, List, Tuple # NOQA
|
||||
from typing import Any, Dict, IO, List, Match, Tuple # NOQA
|
||||
from sphinx.application import Sphinx # NOQA
|
||||
from sphinx.config import Config # NOQA
|
||||
|
||||
@@ -169,6 +169,20 @@ chm_locales = {
|
||||
}
|
||||
|
||||
|
||||
def chm_htmlescape(s, quote=True):
|
||||
# type: (str, bool) -> str
|
||||
"""
|
||||
chm_htmlescape() is a wrapper of html.escape().
|
||||
.hhc/.hhk files don't recognize hex escaping, we need convert
|
||||
hex escaping to decimal escaping. for example: ``'`` -> ``'``
|
||||
html.escape() may generates a hex escaping ``'`` for single
|
||||
quote ``'``, this wrapper fixes this.
|
||||
"""
|
||||
s = html.escape(s, quote)
|
||||
s = s.replace(''', ''') # re-escape as decimal
|
||||
return s
|
||||
|
||||
|
||||
class HTMLHelpBuilder(StandaloneHTMLBuilder):
|
||||
"""
|
||||
Builder that also outputs Windows HTML help project, contents and
|
||||
@@ -278,7 +292,7 @@ class HTMLHelpBuilder(StandaloneHTMLBuilder):
|
||||
write_toc(subnode, ullevel)
|
||||
elif isinstance(node, nodes.reference):
|
||||
link = node['refuri']
|
||||
title = html.escape(node.astext()).replace('"', '"')
|
||||
title = chm_htmlescape(node.astext(), True)
|
||||
f.write(object_sitemap % (title, link))
|
||||
elif isinstance(node, nodes.bullet_list):
|
||||
if ullevel != 0:
|
||||
@@ -305,10 +319,9 @@ class HTMLHelpBuilder(StandaloneHTMLBuilder):
|
||||
# type: (str, List[Tuple[str, str]], List[Tuple[str, List[Tuple[str, str]]]]) -> None # NOQA
|
||||
def write_param(name, value):
|
||||
# type: (str, str) -> None
|
||||
item = ' <param name="%s" value="%s">\n' % \
|
||||
(name, value)
|
||||
item = ' <param name="%s" value="%s">\n' % (name, value)
|
||||
f.write(item)
|
||||
title = html.escape(title)
|
||||
title = chm_htmlescape(title, True)
|
||||
f.write('<LI> <OBJECT type="text/sitemap">\n')
|
||||
write_param('Keyword', title)
|
||||
if len(refs) == 0:
|
||||
|
||||
@@ -12,7 +12,6 @@ import os
|
||||
from os import path
|
||||
|
||||
from docutils.frontend import OptionParser
|
||||
from six import text_type
|
||||
|
||||
from sphinx import package_dir, addnodes, highlighting
|
||||
from sphinx.builders import Builder
|
||||
@@ -24,7 +23,7 @@ from sphinx.builders.latex.transforms import (
|
||||
from sphinx.config import ENUM
|
||||
from sphinx.environment import NoUri
|
||||
from sphinx.environment.adapters.asset import ImageAdapter
|
||||
from sphinx.errors import SphinxError, ConfigError
|
||||
from sphinx.errors import SphinxError
|
||||
from sphinx.locale import _, __
|
||||
from sphinx.transforms import SphinxTransformer
|
||||
from sphinx.util import texescape, logging, status_iterator
|
||||
@@ -413,23 +412,6 @@ class LaTeXBuilder(Builder):
|
||||
|
||||
def validate_config_values(app, config):
|
||||
# type: (Sphinx, Config) -> None
|
||||
for document in config.latex_documents:
|
||||
try:
|
||||
text_type(document[2])
|
||||
except UnicodeDecodeError:
|
||||
raise ConfigError(
|
||||
__('Invalid latex_documents.title found (might contain non-ASCII chars. '
|
||||
'Please use u"..." notation instead): %r') % (document,)
|
||||
)
|
||||
|
||||
try:
|
||||
text_type(document[3])
|
||||
except UnicodeDecodeError:
|
||||
raise ConfigError(
|
||||
__('Invalid latex_documents.author found (might contain non-ASCII chars. '
|
||||
'Please use u"..." notation instead): %r') % (document,)
|
||||
)
|
||||
|
||||
for key in list(config.latex_elements):
|
||||
if key not in DEFAULT_SETTINGS:
|
||||
msg = __("Unknown configure key: latex_elements[%r]. ignored.")
|
||||
|
||||
@@ -16,7 +16,6 @@ import sys
|
||||
import traceback
|
||||
|
||||
from docutils.utils import SystemMessage
|
||||
from six import text_type
|
||||
|
||||
import sphinx.locale
|
||||
from sphinx import __display_version__, package_dir
|
||||
@@ -53,17 +52,17 @@ def handle_exception(app, args, exception, stderr=sys.stderr):
|
||||
print(terminal_safe(exception.args[0]), file=stderr)
|
||||
elif isinstance(exception, SphinxError):
|
||||
print(red('%s:' % exception.category), file=stderr)
|
||||
print(terminal_safe(text_type(exception)), file=stderr)
|
||||
print(terminal_safe(str(exception)), file=stderr)
|
||||
elif isinstance(exception, UnicodeError):
|
||||
print(red(__('Encoding error:')), file=stderr)
|
||||
print(terminal_safe(text_type(exception)), file=stderr)
|
||||
print(terminal_safe(str(exception)), file=stderr)
|
||||
tbpath = save_traceback(app)
|
||||
print(red(__('The full traceback has been saved in %s, if you want '
|
||||
'to report the issue to the developers.') % tbpath),
|
||||
file=stderr)
|
||||
elif isinstance(exception, RuntimeError) and 'recursion depth' in str(exception):
|
||||
print(red(__('Recursion error:')), file=stderr)
|
||||
print(terminal_safe(text_type(exception)), file=stderr)
|
||||
print(terminal_safe(str(exception)), file=stderr)
|
||||
print(file=stderr)
|
||||
print(__('This can happen with very large or deeply nested source '
|
||||
'files. You can carefully increase the default Python '
|
||||
|
||||
@@ -32,7 +32,6 @@ except ImportError:
|
||||
USE_LIBEDIT = False
|
||||
|
||||
from docutils.utils import column_width
|
||||
from six import text_type
|
||||
|
||||
import sphinx.locale
|
||||
from sphinx import __display_version__, package_dir
|
||||
@@ -158,7 +157,7 @@ def term_decode(text):
|
||||
warnings.warn('term_decode() is deprecated.',
|
||||
RemovedInSphinx40Warning, stacklevel=2)
|
||||
|
||||
if isinstance(text, text_type):
|
||||
if isinstance(text, str):
|
||||
return text
|
||||
|
||||
# Use the known encoding, if possible
|
||||
@@ -391,10 +390,9 @@ def generate(d, overwrite=True, silent=False, templatedir=None):
|
||||
d['project_underline'] = column_width(d['project']) * '='
|
||||
d.setdefault('extensions', [])
|
||||
d['copyright'] = time.strftime('%Y') + ', ' + d['author']
|
||||
d['author_texescaped'] = text_type(d['author']).\
|
||||
translate(texescape.tex_escape_map)
|
||||
d['author_texescaped'] = d['author'].translate(texescape.tex_escape_map)
|
||||
d['project_doc'] = d['project'] + ' Documentation'
|
||||
d['project_doc_texescaped'] = text_type(d['project'] + ' Documentation').\
|
||||
d['project_doc_texescaped'] = (d['project'] + ' Documentation').\
|
||||
translate(texescape.tex_escape_map)
|
||||
|
||||
# escape backslashes and single quotes in strings that are put into
|
||||
|
||||
@@ -16,8 +16,6 @@ from collections import OrderedDict
|
||||
from os import path, getenv
|
||||
from typing import Any, NamedTuple, Union
|
||||
|
||||
from six import text_type
|
||||
|
||||
from sphinx.deprecation import RemovedInSphinx30Warning, RemovedInSphinx40Warning
|
||||
from sphinx.errors import ConfigError, ExtensionError
|
||||
from sphinx.locale import _, __
|
||||
@@ -41,7 +39,7 @@ copyright_year_re = re.compile(r'^((\d{4}-)?)(\d{4})(?=[ ,])')
|
||||
|
||||
ConfigValue = NamedTuple('ConfigValue', [('name', str),
|
||||
('value', Any),
|
||||
('rebuild', Union[bool, text_type])])
|
||||
('rebuild', Union[bool, str])])
|
||||
|
||||
|
||||
def is_serializable(obj):
|
||||
@@ -78,7 +76,7 @@ class ENUM:
|
||||
|
||||
|
||||
# RemovedInSphinx40Warning
|
||||
string_classes = [text_type] # type: List
|
||||
string_classes = [str] # type: List
|
||||
|
||||
|
||||
class Config:
|
||||
|
||||
@@ -34,6 +34,12 @@ versionlabels = {
|
||||
'deprecated': _('Deprecated since version %s'),
|
||||
}
|
||||
|
||||
versionlabel_classes = {
|
||||
'versionadded': 'added',
|
||||
'versionchanged': 'changed',
|
||||
'deprecated': 'deprecated',
|
||||
}
|
||||
|
||||
locale.versionlabels = DeprecatedDict(
|
||||
versionlabels,
|
||||
'sphinx.locale.versionlabels is deprecated. '
|
||||
@@ -78,6 +84,7 @@ class VersionChange(SphinxDirective):
|
||||
messages = []
|
||||
if self.content:
|
||||
self.state.nested_parse(self.content, self.content_offset, node)
|
||||
classes = ['versionmodified', versionlabel_classes[self.name]]
|
||||
if len(node):
|
||||
if isinstance(node[0], nodes.paragraph) and node[0].rawsource:
|
||||
content = nodes.inline(node[0].rawsource, translatable=True)
|
||||
@@ -87,11 +94,11 @@ class VersionChange(SphinxDirective):
|
||||
node[0].replace_self(nodes.paragraph('', '', content, translatable=False))
|
||||
|
||||
para = cast(nodes.paragraph, node[0])
|
||||
para.insert(0, nodes.inline('', '%s: ' % text, classes=['versionmodified']))
|
||||
para.insert(0, nodes.inline('', '%s: ' % text, classes=classes))
|
||||
else:
|
||||
para = nodes.paragraph('', '',
|
||||
nodes.inline('', '%s.' % text,
|
||||
classes=['versionmodified']),
|
||||
classes=classes),
|
||||
translatable=False)
|
||||
node.append(para)
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@ from copy import deepcopy
|
||||
|
||||
from docutils import nodes, utils
|
||||
from docutils.parsers.rst import directives
|
||||
from six import text_type
|
||||
|
||||
from sphinx import addnodes
|
||||
from sphinx.deprecation import RemovedInSphinx40Warning
|
||||
@@ -635,7 +634,7 @@ class ASTBase:
|
||||
|
||||
def __str__(self):
|
||||
# type: () -> str
|
||||
return self._stringify(lambda ast: text_type(ast))
|
||||
return self._stringify(lambda ast: str(ast))
|
||||
|
||||
def get_display_string(self):
|
||||
# type: () -> str
|
||||
@@ -666,7 +665,7 @@ class ASTCPPAttribute(ASTBase):
|
||||
|
||||
def describe_signature(self, signode):
|
||||
# type: (addnodes.desc_signature) -> None
|
||||
txt = text_type(self)
|
||||
txt = str(self)
|
||||
signode.append(nodes.Text(txt, txt))
|
||||
|
||||
|
||||
@@ -705,7 +704,7 @@ class ASTGnuAttributeList(ASTBase):
|
||||
|
||||
def describe_signature(self, signode):
|
||||
# type: (addnodes.desc_signature) -> None
|
||||
txt = text_type(self)
|
||||
txt = str(self)
|
||||
signode.append(nodes.Text(txt, txt))
|
||||
|
||||
|
||||
@@ -739,7 +738,7 @@ class ASTParenAttribute(ASTBase):
|
||||
|
||||
def describe_signature(self, signode):
|
||||
# type: (addnodes.desc_signature) -> None
|
||||
txt = text_type(self)
|
||||
txt = str(self)
|
||||
signode.append(nodes.Text(txt, txt))
|
||||
|
||||
|
||||
@@ -779,7 +778,7 @@ class ASTBooleanLiteral(ASTBase):
|
||||
return 'L0E'
|
||||
|
||||
def describe_signature(self, signode, mode, env, symbol):
|
||||
signode.append(nodes.Text(text_type(self)))
|
||||
signode.append(nodes.Text(str(self)))
|
||||
|
||||
|
||||
class ASTNumberLiteral(ASTBase):
|
||||
@@ -796,7 +795,7 @@ class ASTNumberLiteral(ASTBase):
|
||||
return "L%sE" % self.data
|
||||
|
||||
def describe_signature(self, signode, mode, env, symbol):
|
||||
txt = text_type(self)
|
||||
txt = str(self)
|
||||
signode.append(nodes.Text(txt, txt))
|
||||
|
||||
|
||||
@@ -835,7 +834,7 @@ class ASTCharLiteral(ASTBase):
|
||||
return self.type + str(self.value)
|
||||
|
||||
def describe_signature(self, signode, mode, env, symbol):
|
||||
txt = text_type(self)
|
||||
txt = str(self)
|
||||
signode.append(nodes.Text(txt, txt))
|
||||
|
||||
|
||||
@@ -854,7 +853,7 @@ class ASTStringLiteral(ASTBase):
|
||||
return "LA%d_KcE" % (len(self.data) - 2)
|
||||
|
||||
def describe_signature(self, signode, mode, env, symbol):
|
||||
txt = text_type(self)
|
||||
txt = str(self)
|
||||
signode.append(nodes.Text(txt, txt))
|
||||
|
||||
|
||||
@@ -917,7 +916,7 @@ class ASTFoldExpr(ASTBase):
|
||||
# type: (int) -> str
|
||||
assert version >= 3
|
||||
if version == 3:
|
||||
return text_type(self)
|
||||
return str(self)
|
||||
# TODO: find the right mangling scheme
|
||||
assert False
|
||||
|
||||
@@ -1473,7 +1472,7 @@ class ASTFallbackExpr(ASTBase):
|
||||
|
||||
def get_id(self, version):
|
||||
# type: (int) -> str
|
||||
return text_type(self.expr)
|
||||
return str(self.expr)
|
||||
|
||||
def describe_signature(self, signode, mode, env, symbol):
|
||||
signode += nodes.Text(self.expr)
|
||||
@@ -1511,7 +1510,7 @@ class ASTIdentifier(ASTBase):
|
||||
if self.is_anon():
|
||||
return 'Ut%d_%s' % (len(self.identifier) - 1, self.identifier[1:])
|
||||
else:
|
||||
return text_type(len(self.identifier)) + self.identifier
|
||||
return str(len(self.identifier)) + self.identifier
|
||||
|
||||
# and this is where we finally make a difference between __str__ and the display string
|
||||
|
||||
@@ -1994,7 +1993,7 @@ class ASTOperator(ASTBase):
|
||||
def describe_signature(self, signode, mode, env, prefix, templateArgs, symbol):
|
||||
# type: (addnodes.desc_signature, str, Any, str, str, Symbol) -> None
|
||||
_verify_description_mode(mode)
|
||||
identifier = text_type(self)
|
||||
identifier = str(self)
|
||||
if mode == 'lastIsName':
|
||||
signode += addnodes.desc_name(identifier, identifier)
|
||||
else:
|
||||
@@ -2043,7 +2042,7 @@ class ASTOperatorType(ASTOperator):
|
||||
|
||||
def get_name_no_template(self):
|
||||
# type: () -> str
|
||||
return text_type(self)
|
||||
return str(self)
|
||||
|
||||
|
||||
class ASTOperatorLiteral(ASTOperator):
|
||||
@@ -2078,9 +2077,9 @@ class ASTTemplateArgConstant(ASTBase):
|
||||
def get_id(self, version):
|
||||
# type: (int) -> str
|
||||
if version == 1:
|
||||
return text_type(self).replace(' ', '-')
|
||||
return str(self).replace(' ', '-')
|
||||
if version == 2:
|
||||
return 'X' + text_type(self) + 'E'
|
||||
return 'X' + str(self) + 'E'
|
||||
return 'X' + self.value.get_id(version) + 'E'
|
||||
|
||||
def describe_signature(self, signode, mode, env, symbol):
|
||||
@@ -2155,7 +2154,7 @@ class ASTNestedNameElement(ASTBase):
|
||||
|
||||
def describe_signature(self, signode, mode, env, prefix, symbol):
|
||||
# type: (addnodes.desc_signature, str, BuildEnvironment, str, Symbol) -> None
|
||||
tArgs = text_type(self.templateArgs) if self.templateArgs is not None else ''
|
||||
tArgs = str(self.templateArgs) if self.templateArgs is not None else ''
|
||||
self.identOrOp.describe_signature(signode, mode, env, prefix, tArgs, symbol)
|
||||
if self.templateArgs is not None:
|
||||
self.templateArgs.describe_signature(signode, mode, env, symbol)
|
||||
@@ -2188,7 +2187,7 @@ class ASTNestedName(ASTBase):
|
||||
def get_id(self, version, modifiers=''):
|
||||
# type: (int, str) -> str
|
||||
if version == 1:
|
||||
tt = text_type(self)
|
||||
tt = str(self)
|
||||
if tt in _id_shorthands_v1:
|
||||
return _id_shorthands_v1[tt]
|
||||
else:
|
||||
@@ -2223,9 +2222,9 @@ class ASTNestedName(ASTBase):
|
||||
_verify_description_mode(mode)
|
||||
# just print the name part, with template args, not template params
|
||||
if mode == 'noneIsName':
|
||||
signode += nodes.Text(text_type(self))
|
||||
signode += nodes.Text(str(self))
|
||||
elif mode == 'param':
|
||||
name = text_type(self)
|
||||
name = str(self)
|
||||
signode += nodes.emphasis(name, name)
|
||||
elif mode == 'markType' or mode == 'lastIsName':
|
||||
# Each element should be a pending xref targeting the complete
|
||||
@@ -2258,10 +2257,10 @@ class ASTNestedName(ASTBase):
|
||||
if template:
|
||||
dest += nodes.Text("template ")
|
||||
first = False
|
||||
txt_nne = text_type(nne)
|
||||
txt_nne = str(nne)
|
||||
if txt_nne != '':
|
||||
if nne.templateArgs and iTemplateParams < len(templateParams):
|
||||
templateParamsPrefix += text_type(templateParams[iTemplateParams])
|
||||
templateParamsPrefix += str(templateParams[iTemplateParams])
|
||||
iTemplateParams += 1
|
||||
nne.describe_signature(dest, 'markType',
|
||||
env, templateParamsPrefix + prefix, symbol)
|
||||
@@ -2306,7 +2305,7 @@ class ASTTrailingTypeSpecFundamental(ASTBase):
|
||||
|
||||
def describe_signature(self, signode, mode, env, symbol):
|
||||
# type: (addnodes.desc_signature, str, BuildEnvironment, Symbol) -> None
|
||||
signode += nodes.Text(text_type(self.name))
|
||||
signode += nodes.Text(str(self.name))
|
||||
|
||||
|
||||
class ASTTrailingTypeSpecName(ASTBase):
|
||||
@@ -2354,7 +2353,7 @@ class ASTTrailingTypeSpecDecltypeAuto(ASTBase):
|
||||
|
||||
def describe_signature(self, signode, mode, env, symbol):
|
||||
# type: (addnodes.desc_signature, str, BuildEnvironment, Symbol) -> None
|
||||
signode.append(nodes.Text(text_type(self)))
|
||||
signode.append(nodes.Text(str(self)))
|
||||
|
||||
|
||||
class ASTTrailingTypeSpecDecltype(ASTBase):
|
||||
@@ -2467,7 +2466,7 @@ class ASTParametersQualifiers(ASTBase):
|
||||
if not first:
|
||||
res.append(', ')
|
||||
first = False
|
||||
res.append(text_type(a))
|
||||
res.append(str(a))
|
||||
res.append(')')
|
||||
if self.volatile:
|
||||
res.append(' volatile')
|
||||
@@ -2478,7 +2477,7 @@ class ASTParametersQualifiers(ASTBase):
|
||||
res.append(self.refQual)
|
||||
if self.exceptionSpec:
|
||||
res.append(' ')
|
||||
res.append(text_type(self.exceptionSpec))
|
||||
res.append(str(self.exceptionSpec))
|
||||
if self.final:
|
||||
res.append(' final')
|
||||
if self.override:
|
||||
@@ -2515,13 +2514,13 @@ class ASTParametersQualifiers(ASTBase):
|
||||
if self.refQual:
|
||||
_add_text(signode, self.refQual)
|
||||
if self.exceptionSpec:
|
||||
_add_anno(signode, text_type(self.exceptionSpec))
|
||||
_add_anno(signode, str(self.exceptionSpec))
|
||||
if self.final:
|
||||
_add_anno(signode, 'final')
|
||||
if self.override:
|
||||
_add_anno(signode, 'override')
|
||||
if self.initializer:
|
||||
_add_text(signode, '= ' + text_type(self.initializer))
|
||||
_add_text(signode, '= ' + str(self.initializer))
|
||||
|
||||
|
||||
class ASTDeclSpecsSimple(ASTBase):
|
||||
@@ -2653,7 +2652,7 @@ class ASTDeclSpecs(ASTBase):
|
||||
if len(res) > 0:
|
||||
res.append(" ")
|
||||
res.append(transform(self.trailingTypeSpec))
|
||||
r = text_type(self.rightSpecs)
|
||||
r = str(self.rightSpecs)
|
||||
if len(r) > 0:
|
||||
if len(res) > 0:
|
||||
res.append(" ")
|
||||
@@ -2704,7 +2703,7 @@ class ASTArray(ASTBase):
|
||||
return 'A'
|
||||
if version == 2:
|
||||
if self.size:
|
||||
return 'A' + text_type(self.size) + '_'
|
||||
return 'A' + str(self.size) + '_'
|
||||
else:
|
||||
return 'A_'
|
||||
if self.size:
|
||||
@@ -3321,7 +3320,7 @@ class ASTType(ASTBase):
|
||||
_verify_description_mode(mode)
|
||||
self.declSpecs.describe_signature(signode, 'markType', env, symbol)
|
||||
if (self.decl.require_space_after_declSpecs() and
|
||||
len(text_type(self.declSpecs)) > 0):
|
||||
len(str(self.declSpecs)) > 0):
|
||||
signode += nodes.Text(' ')
|
||||
# for parameters that don't really declare new names we get 'markType',
|
||||
# this should not be propagated, but be 'noneIsName'.
|
||||
@@ -3929,8 +3928,8 @@ class Symbol:
|
||||
param = templateParams.params[i]
|
||||
arg = templateArgs.args[i]
|
||||
# TODO: doing this by string manipulation is probably not the most efficient
|
||||
paramName = text_type(param.name)
|
||||
argTxt = text_type(arg)
|
||||
paramName = str(param.name)
|
||||
argTxt = str(arg)
|
||||
isArgPackExpansion = argTxt.endswith('...')
|
||||
if param.isPack != isArgPackExpansion:
|
||||
return True
|
||||
@@ -3958,13 +3957,13 @@ class Symbol:
|
||||
return False
|
||||
if templateParams:
|
||||
# TODO: do better comparison
|
||||
if text_type(s.templateParams) != text_type(templateParams):
|
||||
if str(s.templateParams) != str(templateParams):
|
||||
return False
|
||||
if (s.templateArgs is None) != (templateArgs is None):
|
||||
return False
|
||||
if s.templateArgs:
|
||||
# TODO: do better comparison
|
||||
if text_type(s.templateArgs) != text_type(templateArgs):
|
||||
if str(s.templateArgs) != str(templateArgs):
|
||||
return False
|
||||
return True
|
||||
if matchSelf and matches(self):
|
||||
@@ -4253,7 +4252,7 @@ class Symbol:
|
||||
if not ourChild.declaration:
|
||||
ourChild._fill_empty(otherChild.declaration, otherChild.docname)
|
||||
elif ourChild.docname != otherChild.docname:
|
||||
name = text_type(ourChild.declaration)
|
||||
name = str(ourChild.declaration)
|
||||
msg = __("Duplicate declaration, also defined in '%s'.\n"
|
||||
"Declaration is '%s'.")
|
||||
msg = msg % (ourChild.docname, name)
|
||||
@@ -4401,20 +4400,20 @@ class Symbol:
|
||||
res.append('::')
|
||||
else:
|
||||
if self.templateParams:
|
||||
res.append(text_type(self.templateParams))
|
||||
res.append(str(self.templateParams))
|
||||
res.append('\n')
|
||||
res.append('\t' * indent)
|
||||
if self.identOrOp:
|
||||
res.append(text_type(self.identOrOp))
|
||||
res.append(str(self.identOrOp))
|
||||
else:
|
||||
res.append(text_type(self.declaration))
|
||||
res.append(str(self.declaration))
|
||||
if self.templateArgs:
|
||||
res.append(text_type(self.templateArgs))
|
||||
res.append(str(self.templateArgs))
|
||||
if self.declaration:
|
||||
res.append(": ")
|
||||
if self.isRedeclaration:
|
||||
res.append('!!duplicate!! ')
|
||||
res.append(text_type(self.declaration))
|
||||
res.append(str(self.declaration))
|
||||
if self.docname:
|
||||
res.append('\t(')
|
||||
res.append(self.docname)
|
||||
@@ -6151,7 +6150,7 @@ class DefinitionParser:
|
||||
msg += " Declaration:\n\t"
|
||||
if templatePrefix:
|
||||
msg += "%s\n\t" % templatePrefix
|
||||
msg += text_type(nestedName)
|
||||
msg += str(nestedName)
|
||||
self.warn(msg)
|
||||
|
||||
newTemplates = []
|
||||
@@ -6445,7 +6444,7 @@ class CPPObject(ObjectDescription):
|
||||
parentDecl = parentSymbol.declaration
|
||||
if parentDecl is not None and parentDecl.objectType == 'function':
|
||||
self.warn("C++ declarations inside functions are not supported." +
|
||||
" Parent function is " + text_type(parentSymbol.get_full_nested_name()))
|
||||
" Parent function is " + str(parentSymbol.get_full_nested_name()))
|
||||
name = _make_phony_error_name()
|
||||
symbol = parentSymbol.add_name(name)
|
||||
env.temp_data['cpp:last_symbol'] = symbol
|
||||
@@ -6928,7 +6927,7 @@ class CPPDomain(Domain):
|
||||
templateShorthand=True,
|
||||
matchSelf=True, recurseInAnon=True)
|
||||
if s is None or s.declaration is None:
|
||||
txtName = text_type(name)
|
||||
txtName = str(name)
|
||||
if txtName.startswith('std::') or txtName == 'std':
|
||||
raise NoUri()
|
||||
return None, None
|
||||
@@ -7031,7 +7030,7 @@ class CPPDomain(Domain):
|
||||
continue
|
||||
assert symbol.docname
|
||||
fullNestedName = symbol.get_full_nested_name()
|
||||
name = text_type(fullNestedName).lstrip(':')
|
||||
name = str(fullNestedName).lstrip(':')
|
||||
dispname = fullNestedName.get_display_string().lstrip(':')
|
||||
objectType = symbol.declaration.objectType
|
||||
docname = symbol.docname
|
||||
@@ -7050,7 +7049,7 @@ class CPPDomain(Domain):
|
||||
rootSymbol = self.data['root_symbol']
|
||||
parentSymbol = rootSymbol.direct_lookup(parentKey)
|
||||
parentName = parentSymbol.get_full_nested_name()
|
||||
return '::'.join([text_type(parentName), target])
|
||||
return '::'.join([str(parentName), target])
|
||||
|
||||
|
||||
def setup(app):
|
||||
|
||||
@@ -12,8 +12,6 @@ import re
|
||||
import unicodedata
|
||||
from itertools import groupby
|
||||
|
||||
from six import text_type
|
||||
|
||||
from sphinx.locale import _, __
|
||||
from sphinx.util import split_into, logging
|
||||
|
||||
@@ -44,7 +42,7 @@ class IndexEntries:
|
||||
# Force the word to be unicode if it's a ASCII bytestring.
|
||||
# This will solve problems with unicode normalization later.
|
||||
# For instance the RFC role will add bytestrings at the moment
|
||||
word = text_type(word)
|
||||
word = str(word)
|
||||
entry = dic.get(word)
|
||||
if not entry:
|
||||
dic[word] = entry = [[], {}, key]
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
:license: BSD, see LICENSE for details.
|
||||
"""
|
||||
|
||||
from six import text_type
|
||||
|
||||
from sphinx import addnodes
|
||||
from sphinx.environment.collectors import EnvironmentCollector
|
||||
from sphinx.util import split_index_msg, logging
|
||||
@@ -45,7 +43,7 @@ class IndexEntriesCollector(EnvironmentCollector):
|
||||
for entry in node['entries']:
|
||||
split_index_msg(entry[0], entry[1])
|
||||
except ValueError as exc:
|
||||
logger.warning(text_type(exc), location=node)
|
||||
logger.warning(str(exc), location=node)
|
||||
node.parent.remove(node)
|
||||
else:
|
||||
for entry in node['entries']:
|
||||
|
||||
@@ -336,7 +336,7 @@ Note: By default this script will not overwrite already created files."""))
|
||||
dest='includeprivate',
|
||||
help=__('include "_private" modules'))
|
||||
parser.add_argument('--tocfile', action='store', dest='tocfile', default='modules',
|
||||
help=__("don't create a table of contents file"))
|
||||
help=__("filename of table of contents (default: modules)"))
|
||||
parser.add_argument('-T', '--no-toc', action='store_false', dest='tocfile',
|
||||
help=__("don't create a table of contents file"))
|
||||
parser.add_argument('-E', '--no-headings', action='store_true',
|
||||
|
||||
@@ -12,12 +12,10 @@
|
||||
|
||||
import inspect
|
||||
import re
|
||||
import sys
|
||||
import warnings
|
||||
from typing import Any
|
||||
|
||||
from docutils.statemachine import StringList
|
||||
from six import text_type
|
||||
|
||||
import sphinx
|
||||
from sphinx.deprecation import RemovedInSphinx30Warning, RemovedInSphinx40Warning
|
||||
@@ -461,13 +459,7 @@ class Documenter:
|
||||
def get_sourcename(self):
|
||||
# type: () -> str
|
||||
if self.analyzer:
|
||||
# prevent encoding errors when the file name is non-ASCII
|
||||
if not isinstance(self.analyzer.srcname, text_type):
|
||||
filename = text_type(self.analyzer.srcname,
|
||||
sys.getfilesystemencoding(), 'replace')
|
||||
else:
|
||||
filename = self.analyzer.srcname
|
||||
return '%s:docstring of %s' % (filename, self.fullname)
|
||||
return '%s:docstring of %s' % (self.analyzer.srcname, self.fullname)
|
||||
return 'docstring of %s' % self.fullname
|
||||
|
||||
def add_content(self, more_content, no_docstring=False):
|
||||
|
||||
@@ -65,7 +65,6 @@ from docutils import nodes
|
||||
from docutils.parsers.rst import directives
|
||||
from docutils.parsers.rst.states import RSTStateMachine, state_classes
|
||||
from docutils.statemachine import StringList
|
||||
from six import text_type
|
||||
|
||||
import sphinx
|
||||
from sphinx import addnodes
|
||||
@@ -160,8 +159,7 @@ def autosummary_table_visit_html(self, node):
|
||||
par = cast(nodes.paragraph, col1_entry[0])
|
||||
for j, subnode in enumerate(list(par)):
|
||||
if isinstance(subnode, nodes.Text):
|
||||
new_text = text_type(subnode.astext())
|
||||
new_text = new_text.replace(" ", "\u00a0")
|
||||
new_text = subnode.astext().replace(" ", "\u00a0")
|
||||
par[j] = nodes.Text(new_text)
|
||||
except IndexError:
|
||||
pass
|
||||
|
||||
@@ -17,7 +17,6 @@ from os import path
|
||||
from subprocess import Popen, PIPE
|
||||
|
||||
from docutils import nodes
|
||||
from six import text_type
|
||||
|
||||
import sphinx
|
||||
from sphinx.errors import SphinxError
|
||||
@@ -290,7 +289,7 @@ def html_visit_math(self, node):
|
||||
try:
|
||||
fname, depth = render_math(self, '$' + node.astext() + '$')
|
||||
except MathExtError as exc:
|
||||
msg = text_type(exc)
|
||||
msg = str(exc)
|
||||
sm = nodes.system_message(msg, type='WARNING', level=2,
|
||||
backrefs=[], source=node.astext())
|
||||
sm.walkabout(self)
|
||||
@@ -317,7 +316,7 @@ def html_visit_displaymath(self, node):
|
||||
try:
|
||||
fname, depth = render_math(self, latex)
|
||||
except MathExtError as exc:
|
||||
msg = text_type(exc)
|
||||
msg = str(exc)
|
||||
sm = nodes.system_message(msg, type='WARNING', level=2,
|
||||
backrefs=[], source=node.astext())
|
||||
sm.walkabout(self)
|
||||
|
||||
@@ -173,7 +173,10 @@ def process_todo_nodes(app, doctree, fromdocname):
|
||||
try:
|
||||
newnode['refuri'] = app.builder.get_relative_uri(
|
||||
fromdocname, todo_info['docname'])
|
||||
newnode['refuri'] += '#' + todo_info['target']['refid']
|
||||
if 'refid' in todo_info['target']:
|
||||
newnode['refuri'] += '#' + todo_info['target']['refid']
|
||||
else:
|
||||
newnode['refuri'] += '#' + todo_info['target']['ids'][0]
|
||||
except NoUri:
|
||||
# ignore if no URI can be determined, e.g. for LaTeX output
|
||||
pass
|
||||
|
||||
@@ -20,7 +20,6 @@ from pygments.lexers import PythonLexer, Python3Lexer, PythonConsoleLexer, \
|
||||
CLexer, TextLexer, RstLexer
|
||||
from pygments.styles import get_style_by_name
|
||||
from pygments.util import ClassNotFound
|
||||
from six import text_type
|
||||
|
||||
from sphinx.deprecation import RemovedInSphinx30Warning
|
||||
from sphinx.ext import doctest
|
||||
@@ -113,7 +112,7 @@ class PygmentsBridge:
|
||||
|
||||
def highlight_block(self, source, lang, opts=None, location=None, force=False, **kwargs):
|
||||
# type: (str, str, Any, Any, bool, Any) -> str
|
||||
if not isinstance(source, text_type):
|
||||
if not isinstance(source, str):
|
||||
source = source.decode()
|
||||
|
||||
# find out which lexer to use
|
||||
|
||||
@@ -14,8 +14,6 @@ import warnings
|
||||
from collections import UserString, defaultdict
|
||||
from gettext import NullTranslations
|
||||
|
||||
from six import text_type
|
||||
|
||||
from sphinx.deprecation import RemovedInSphinx30Warning
|
||||
|
||||
if False:
|
||||
@@ -41,7 +39,7 @@ class _TranslationProxy(UserString):
|
||||
# type: (Callable, str) -> object
|
||||
if not args:
|
||||
# not called with "function" and "arguments", but a plain string
|
||||
return text_type(func)
|
||||
return str(func)
|
||||
return object.__new__(cls)
|
||||
|
||||
def __getnewargs__(self):
|
||||
@@ -73,7 +71,7 @@ class _TranslationProxy(UserString):
|
||||
|
||||
def __dir__(self):
|
||||
# type: () -> List[str]
|
||||
return dir(text_type)
|
||||
return dir(str)
|
||||
|
||||
def __str__(self):
|
||||
# type: () -> str
|
||||
@@ -124,7 +122,7 @@ class _TranslationProxy(UserString):
|
||||
def __repr__(self):
|
||||
# type: () -> str
|
||||
try:
|
||||
return 'i' + repr(text_type(self.data))
|
||||
return 'i' + repr(str(self.data))
|
||||
except Exception:
|
||||
return '<%s broken>' % self.__class__.__name__
|
||||
|
||||
|
||||
@@ -16,8 +16,6 @@ import tokenize
|
||||
from token import NAME, NEWLINE, INDENT, DEDENT, NUMBER, OP, STRING
|
||||
from tokenize import COMMENT, NL
|
||||
|
||||
from six import text_type
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
from typing import Any, Dict, IO, List, Tuple # NOQA
|
||||
@@ -349,7 +347,7 @@ class VariableCommentPicker(ast.NodeVisitor):
|
||||
targets = get_assign_targets(self.previous)
|
||||
varnames = get_lvar_names(targets[0], self.get_self())
|
||||
for varname in varnames:
|
||||
if isinstance(node.value.s, text_type):
|
||||
if isinstance(node.value.s, str):
|
||||
docstring = node.value.s
|
||||
else:
|
||||
docstring = node.value.s.decode(self.encoding or 'utf-8')
|
||||
|
||||
@@ -13,8 +13,6 @@ import re
|
||||
import warnings
|
||||
from os import path
|
||||
|
||||
from six import text_type
|
||||
|
||||
from docutils import nodes
|
||||
|
||||
from sphinx import addnodes
|
||||
@@ -351,9 +349,9 @@ class IndexBuilder:
|
||||
otypes[domainname, type] = typeindex
|
||||
otype = domain.object_types.get(type)
|
||||
if otype:
|
||||
# use unicode() to fire translation proxies
|
||||
# use str() to fire translation proxies
|
||||
onames[typeindex] = (domainname, type,
|
||||
text_type(domain.get_type_name(otype)))
|
||||
str(domain.get_type_name(otype)))
|
||||
else:
|
||||
onames[typeindex] = (domainname, type, type)
|
||||
if anchor == fullname:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Configuration file for the Sphinx documentation builder.
|
||||
#
|
||||
# This file does only contain a selection of the most common options. For a
|
||||
# full list see the documentation:
|
||||
# This file only contains a selection of the most common options. For a full
|
||||
# list see the documentation:
|
||||
# http://www.sphinx-doc.org/en/master/config
|
||||
|
||||
# -- Path setup --------------------------------------------------------------
|
||||
@@ -167,3 +167,4 @@ intersphinx_mapping = {'https://docs.python.org/': None}
|
||||
# If true, `todo` and `todoList` produce output, else they produce nothing.
|
||||
todo_include_todos = True
|
||||
{%- endif %}
|
||||
|
||||
|
||||
@@ -9,8 +9,6 @@ import os
|
||||
import shutil
|
||||
import sys
|
||||
|
||||
from six import text_type
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
import builtins # NOQA
|
||||
@@ -20,7 +18,7 @@ if False:
|
||||
FILESYSTEMENCODING = sys.getfilesystemencoding() or sys.getdefaultencoding()
|
||||
|
||||
|
||||
class path(text_type):
|
||||
class path(str):
|
||||
"""
|
||||
Represents a path which behaves like a string.
|
||||
"""
|
||||
@@ -222,4 +220,4 @@ class path(text_type):
|
||||
|
||||
def __repr__(self):
|
||||
# type: () -> str
|
||||
return '%s(%s)' % (self.__class__.__name__, text_type.__repr__(self))
|
||||
return '%s(%s)' % (self.__class__.__name__, super().__repr__())
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
%
|
||||
|
||||
\NeedsTeXFormat{LaTeX2e}[1995/12/01]
|
||||
\ProvidesClass{sphinxhowto}[2018/09/18 v1.8.1 Document class (Sphinx HOWTO)]
|
||||
\ProvidesClass{sphinxhowto}[2018/12/23 v2.0 Document class (Sphinx howto)]
|
||||
|
||||
% 'oneside' option overriding the 'twoside' default
|
||||
\newif\if@oneside
|
||||
@@ -30,7 +30,7 @@
|
||||
% Change the title page to look a bit better, and fit in with the fncychap
|
||||
% ``Bjarne'' style a bit better.
|
||||
%
|
||||
\renewcommand{\maketitle}{%
|
||||
\newcommand{\sphinxmaketitle}{%
|
||||
\noindent\rule{\textwidth}{1pt}\par
|
||||
\begingroup % for PDF information dictionary
|
||||
\def\endgraf{ }\def\and{\& }%
|
||||
@@ -57,15 +57,16 @@
|
||||
%\gdef\@thanks{}\gdef\@author{}\gdef\@title{}
|
||||
}
|
||||
|
||||
\newcommand{\sphinxtableofcontents}{
|
||||
\newcommand{\sphinxtableofcontents}{%
|
||||
\begingroup
|
||||
\parskip = 0mm
|
||||
\parskip \z@skip
|
||||
\sphinxtableofcontentshook
|
||||
\tableofcontents
|
||||
\endgroup
|
||||
\rule{\textwidth}{1pt}
|
||||
\vspace{12pt}
|
||||
\noindent\rule{\textwidth}{1pt}\par
|
||||
\vspace{12pt}%
|
||||
}
|
||||
|
||||
\newcommand\sphinxtableofcontentshook{}
|
||||
\pagenumbering{arabic}
|
||||
|
||||
% Fix the bibliography environment to add an entry to the Table of
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
%
|
||||
|
||||
\NeedsTeXFormat{LaTeX2e}[1995/12/01]
|
||||
\ProvidesClass{sphinxmanual}[2018/09/18 v1.8.1 Document class (Sphinx manual)]
|
||||
\ProvidesClass{sphinxmanual}[2018/12/23 v2.0 Document class (Sphinx manual)]
|
||||
|
||||
% chapters starting at odd pages (overridden by 'openany' document option)
|
||||
\PassOptionsToClass{openright}{\sphinxdocclass}
|
||||
@@ -33,9 +33,9 @@
|
||||
% Change the title page to look a bit better, and fit in with the fncychap
|
||||
% ``Bjarne'' style a bit better.
|
||||
%
|
||||
\renewcommand{\maketitle}{%
|
||||
\let\spx@tempa\relax
|
||||
\ifHy@pageanchor\def\spx@tempa{\Hy@pageanchortrue}\fi
|
||||
\newcommand{\sphinxmaketitle}{%
|
||||
\let\sphinxrestorepageanchorsetting\relax
|
||||
\ifHy@pageanchor\def\sphinxrestorepageanchorsetting{\Hy@pageanchortrue}\fi
|
||||
\hypersetup{pageanchor=false}% avoid duplicate destination warnings
|
||||
\begin{titlepage}%
|
||||
\let\footnotesize\small
|
||||
@@ -69,14 +69,17 @@
|
||||
\setcounter{footnote}{0}%
|
||||
\let\thanks\relax\let\maketitle\relax
|
||||
%\gdef\@thanks{}\gdef\@author{}\gdef\@title{}
|
||||
\clearpage
|
||||
\ifdefined\sphinxbackoftitlepage\sphinxbackoftitlepage\fi
|
||||
\if@openright\cleardoublepage\else\clearpage\fi
|
||||
\spx@tempa
|
||||
\sphinxrestorepageanchorsetting
|
||||
}
|
||||
|
||||
\newcommand{\sphinxtableofcontents}{%
|
||||
\pagenumbering{roman}%
|
||||
\begingroup
|
||||
\parskip \z@skip
|
||||
\sphinxtableofcontentshook
|
||||
\tableofcontents
|
||||
\endgroup
|
||||
% before resetting page counter, let's do the right thing.
|
||||
@@ -87,8 +90,10 @@
|
||||
% 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.
|
||||
%
|
||||
\renewcommand*\l@section{\@dottedtocline{1}{1.5em}{2.6em}}
|
||||
\renewcommand*\l@subsection{\@dottedtocline{2}{4.1em}{3.5em}}
|
||||
\newcommand{\sphinxtableofcontentshook}{%
|
||||
\renewcommand*\l@section{\@dottedtocline{1}{1.5em}{2.6em}}%
|
||||
\renewcommand*\l@subsection{\@dottedtocline{2}{4.1em}{3.5em}}%
|
||||
}
|
||||
|
||||
% Fix the bibliography environment to add an entry to the Table of
|
||||
% Contents.
|
||||
|
||||
@@ -13,7 +13,6 @@ from typing import NamedTuple
|
||||
|
||||
from docutils import nodes
|
||||
from pygments.lexers import PythonConsoleLexer, guess_lexer
|
||||
from six import text_type
|
||||
|
||||
from sphinx import addnodes
|
||||
from sphinx.ext import doctest
|
||||
@@ -25,7 +24,7 @@ if False:
|
||||
from sphinx.application import Sphinx # NOQA
|
||||
|
||||
|
||||
HighlightSetting = NamedTuple('HighlightSetting', [('language', text_type),
|
||||
HighlightSetting = NamedTuple('HighlightSetting', [('language', str),
|
||||
('lineno_threshold', int)])
|
||||
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@ from hashlib import sha1
|
||||
from math import ceil
|
||||
|
||||
from docutils import nodes
|
||||
from six import text_type
|
||||
|
||||
from sphinx.locale import __
|
||||
from sphinx.transforms import SphinxTransform
|
||||
@@ -118,8 +117,7 @@ class ImageDownloader(BaseImageConverter):
|
||||
node['uri'] = path
|
||||
self.app.env.images.add_file(self.env.docname, path)
|
||||
except Exception as exc:
|
||||
logger.warning(__('Could not fetch remote image: %s [%s]') %
|
||||
(node['uri'], text_type(exc)))
|
||||
logger.warning(__('Could not fetch remote image: %s [%s]') % (node['uri'], exc))
|
||||
|
||||
|
||||
class DataURIExtractor(BaseImageConverter):
|
||||
|
||||
@@ -26,7 +26,6 @@ from time import mktime, strptime
|
||||
from urllib.parse import urlsplit, urlunsplit, quote_plus, parse_qsl, urlencode
|
||||
|
||||
from docutils.utils import relative_path
|
||||
from six import text_type
|
||||
|
||||
from sphinx.deprecation import RemovedInSphinx30Warning, RemovedInSphinx40Warning
|
||||
from sphinx.errors import PycodeError, SphinxParallelError, ExtensionError
|
||||
@@ -70,9 +69,7 @@ def path_stabilize(filepath):
|
||||
# type: (str) -> str
|
||||
"normalize path separater and unicode string"
|
||||
newpath = filepath.replace(os.path.sep, SEP)
|
||||
if isinstance(newpath, text_type):
|
||||
newpath = unicodedata.normalize('NFC', newpath)
|
||||
return newpath
|
||||
return unicodedata.normalize('NFC', newpath)
|
||||
|
||||
|
||||
def get_matching_files(dirname, exclude_matchers=()):
|
||||
@@ -637,9 +634,9 @@ def display_chunk(chunk):
|
||||
# type: (Any) -> str
|
||||
if isinstance(chunk, (list, tuple)):
|
||||
if len(chunk) == 1:
|
||||
return text_type(chunk[0])
|
||||
return str(chunk[0])
|
||||
return '%s .. %s' % (chunk[0], chunk[-1])
|
||||
return text_type(chunk)
|
||||
return str(chunk)
|
||||
|
||||
|
||||
def old_status_iterator(iterable, summary, color="darkgreen", stringify_func=display_chunk):
|
||||
@@ -696,15 +693,12 @@ def rfc1123_to_epoch(rfc1123):
|
||||
def xmlname_checker():
|
||||
# type: () -> Pattern
|
||||
# https://www.w3.org/TR/REC-xml/#NT-Name
|
||||
# Only Python 3.3 or newer support character code in regular expression
|
||||
name_start_chars = [
|
||||
':', ['A', 'Z'], '_', ['a', 'z'], ['\u00C0', '\u00D6'],
|
||||
['\u00D8', '\u00F6'], ['\u00F8', '\u02FF'], ['\u0370', '\u037D'],
|
||||
['\u037F', '\u1FFF'], ['\u200C', '\u200D'], ['\u2070', '\u218F'],
|
||||
['\u2C00', '\u2FEF'], ['\u3001', '\uD7FF'], ['\uF900', '\uFDCF'],
|
||||
['\uFDF0', '\uFFFD']]
|
||||
|
||||
name_start_chars.append(['\U00010000', '\U000EFFFF'])
|
||||
['\uFDF0', '\uFFFD'], ['\U00010000', '\U000EFFFF']]
|
||||
|
||||
name_chars = [
|
||||
"\\-", "\\.", ['0', '9'], '\u00B7', ['\u0300', '\u036F'],
|
||||
|
||||
@@ -17,7 +17,6 @@ from os import path
|
||||
from typing import NamedTuple
|
||||
|
||||
import imagesize
|
||||
from six import text_type
|
||||
|
||||
from sphinx.deprecation import RemovedInSphinx30Warning
|
||||
|
||||
@@ -42,8 +41,8 @@ mime_suffixes = OrderedDict([
|
||||
('.svgz', 'image/svg+xml'),
|
||||
])
|
||||
|
||||
DataURI = NamedTuple('DataURI', [('mimetype', text_type),
|
||||
('charset', text_type),
|
||||
DataURI = NamedTuple('DataURI', [('mimetype', str),
|
||||
('charset', str),
|
||||
('data', bytes)])
|
||||
|
||||
|
||||
|
||||
@@ -103,16 +103,12 @@ def getargspec(func):
|
||||
def isenumclass(x):
|
||||
# type: (Type) -> bool
|
||||
"""Check if the object is subclass of enum."""
|
||||
if enum is None:
|
||||
return False
|
||||
return inspect.isclass(x) and issubclass(x, enum.Enum)
|
||||
|
||||
|
||||
def isenumattribute(x):
|
||||
# type: (Any) -> bool
|
||||
"""Check if the object is attribute of enum."""
|
||||
if enum is None:
|
||||
return False
|
||||
return isinstance(x, enum.Enum)
|
||||
|
||||
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
import json
|
||||
from collections import UserString
|
||||
|
||||
from six import text_type
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
from typing import Any, IO # NOQA
|
||||
@@ -23,7 +21,7 @@ class SphinxJSONEncoder(json.JSONEncoder):
|
||||
def default(self, obj):
|
||||
# type: (Any) -> str
|
||||
if isinstance(obj, UserString):
|
||||
return text_type(obj)
|
||||
return str(obj)
|
||||
return super().default(obj)
|
||||
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ import re
|
||||
from typing import Any, cast
|
||||
|
||||
from docutils import nodes
|
||||
from six import text_type
|
||||
|
||||
from sphinx import addnodes
|
||||
from sphinx.locale import __
|
||||
@@ -115,7 +114,7 @@ def repr_domxml(node, length=80):
|
||||
try:
|
||||
text = node.asdom().toxml()
|
||||
except Exception:
|
||||
text = text_type(node)
|
||||
text = str(node)
|
||||
if length and len(text) > length:
|
||||
text = text[:length] + '...'
|
||||
return text
|
||||
@@ -398,7 +397,7 @@ def inline_all_toctrees(builder, docnameset, docname, tree, colorfunc, traversed
|
||||
tree = cast(nodes.document, tree.deepcopy())
|
||||
for toctreenode in tree.traverse(addnodes.toctree):
|
||||
newnodes = []
|
||||
includefiles = map(text_type, toctreenode['includefiles'])
|
||||
includefiles = map(str, toctreenode['includefiles'])
|
||||
for includefile in includefiles:
|
||||
if includefile not in traversed:
|
||||
try:
|
||||
|
||||
@@ -14,8 +14,6 @@ from html import escape as htmlescape # NOQA
|
||||
from io import TextIOWrapper # NOQA
|
||||
from textwrap import indent # NOQA
|
||||
|
||||
from six import text_type
|
||||
|
||||
from sphinx.deprecation import RemovedInSphinx40Warning
|
||||
from sphinx.locale import __
|
||||
from sphinx.util import logging
|
||||
@@ -64,7 +62,7 @@ def convert_with_2to3(filepath):
|
||||
lineno, offset = err.context[1]
|
||||
# try to match ParseError details with SyntaxError details
|
||||
raise SyntaxError(err.msg, (filepath, lineno, offset, err.value))
|
||||
return text_type(tree)
|
||||
return str(tree)
|
||||
|
||||
|
||||
class UnicodeMixin:
|
||||
|
||||
@@ -12,7 +12,6 @@ from typing import Any, Callable, Dict, List, Tuple, Union
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.parsers.rst.states import Inliner
|
||||
from six import text_type
|
||||
|
||||
|
||||
# An entry of Directive.option_spec
|
||||
@@ -22,11 +21,11 @@ DirectiveOption = Callable[[str], Any]
|
||||
TextlikeNode = Union[nodes.Text, nodes.TextElement]
|
||||
|
||||
# common role functions
|
||||
RoleFunction = Callable[[text_type, text_type, text_type, int, Inliner, Dict, List[text_type]],
|
||||
RoleFunction = Callable[[str, str, str, int, Inliner, Dict, List[str]],
|
||||
Tuple[List[nodes.Node], List[nodes.system_message]]]
|
||||
|
||||
# title getter functions for enumerable nodes (see sphinx.domains.std)
|
||||
TitleGetter = Callable[[nodes.Node], text_type]
|
||||
TitleGetter = Callable[[nodes.Node], str]
|
||||
|
||||
# inventory data on memory
|
||||
Inventory = Dict[str, Dict[str, Tuple[str, str, str, str]]]
|
||||
|
||||
@@ -92,7 +92,7 @@ class HTMLTranslator(SphinxTranslator, BaseTranslator):
|
||||
self.permalink_text = self.config.html_add_permalinks
|
||||
# support backwards-compatible setting to a bool
|
||||
if not isinstance(self.permalink_text, str):
|
||||
self.permalink_text = self.permalink_text and '\u00B6' or ''
|
||||
self.permalink_text = self.permalink_text and '¶' or ''
|
||||
self.permalink_text = self.encode(self.permalink_text)
|
||||
self.secnumber_suffix = self.config.html_secnumber_suffix
|
||||
self.param_separator = ''
|
||||
|
||||
@@ -62,7 +62,7 @@ class HTML5Translator(SphinxTranslator, BaseTranslator):
|
||||
self.permalink_text = self.config.html_add_permalinks
|
||||
# support backwards-compatible setting to a bool
|
||||
if not isinstance(self.permalink_text, str):
|
||||
self.permalink_text = self.permalink_text and '\u00B6' or ''
|
||||
self.permalink_text = self.permalink_text and '¶' or ''
|
||||
self.permalink_text = self.encode(self.permalink_text)
|
||||
self.secnumber_suffix = self.config.html_secnumber_suffix
|
||||
self.param_separator = ''
|
||||
|
||||
@@ -20,7 +20,6 @@ from typing import Iterable, cast
|
||||
|
||||
from docutils import nodes, writers
|
||||
from docutils.writers.latex2e import Babel
|
||||
from six import text_type
|
||||
|
||||
from sphinx import addnodes
|
||||
from sphinx import highlighting
|
||||
@@ -159,7 +158,7 @@ DEFAULT_SETTINGS = {
|
||||
'releasename': '',
|
||||
'makeindex': '\\makeindex',
|
||||
'shorthandoff': '',
|
||||
'maketitle': '\\maketitle',
|
||||
'maketitle': '\\sphinxmaketitle',
|
||||
'tableofcontents': '\\sphinxtableofcontents',
|
||||
'atendofbody': '',
|
||||
'printindex': '\\printindex',
|
||||
@@ -759,7 +758,7 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
|
||||
def idescape(self, id):
|
||||
# type: (str) -> str
|
||||
return '\\detokenize{%s}' % text_type(id).translate(tex_replace_map).\
|
||||
return '\\detokenize{%s}' % str(id).translate(tex_replace_map).\
|
||||
encode('ascii', 'backslashreplace').decode('ascii').\
|
||||
replace('\\', '_')
|
||||
|
||||
@@ -780,34 +779,34 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
figure = self.builder.config.numfig_format['figure'].split('%s', 1)
|
||||
if len(figure) == 1:
|
||||
ret.append('\\def\\fnum@figure{%s}\n' %
|
||||
text_type(figure[0]).strip().translate(tex_escape_map))
|
||||
str(figure[0]).strip().translate(tex_escape_map))
|
||||
else:
|
||||
definition = text_type(figure[0]).strip().translate(tex_escape_map)
|
||||
definition = str(figure[0]).strip().translate(tex_escape_map)
|
||||
ret.append(self.babel_renewcommand('\\figurename', definition))
|
||||
if figure[1]:
|
||||
ret.append('\\makeatletter\n')
|
||||
ret.append('\\def\\fnum@figure{\\figurename\\thefigure%s}\n' %
|
||||
text_type(figure[1]).strip().translate(tex_escape_map))
|
||||
str(figure[1]).strip().translate(tex_escape_map))
|
||||
ret.append('\\makeatother\n')
|
||||
|
||||
table = self.builder.config.numfig_format['table'].split('%s', 1)
|
||||
if len(table) == 1:
|
||||
ret.append('\\def\\fnum@table{%s}\n' %
|
||||
text_type(table[0]).strip().translate(tex_escape_map))
|
||||
str(table[0]).strip().translate(tex_escape_map))
|
||||
else:
|
||||
definition = text_type(table[0]).strip().translate(tex_escape_map)
|
||||
definition = str(table[0]).strip().translate(tex_escape_map)
|
||||
ret.append(self.babel_renewcommand('\\tablename', definition))
|
||||
if table[1]:
|
||||
ret.append('\\makeatletter\n')
|
||||
ret.append('\\def\\fnum@table{\\tablename\\thetable%s}\n' %
|
||||
text_type(table[1]).strip().translate(tex_escape_map))
|
||||
str(table[1]).strip().translate(tex_escape_map))
|
||||
ret.append('\\makeatother\n')
|
||||
|
||||
codeblock = self.builder.config.numfig_format['code-block'].split('%s', 1)
|
||||
if len(codeblock) == 1:
|
||||
pass # FIXME
|
||||
else:
|
||||
definition = text_type(codeblock[0]).strip().translate(tex_escape_map)
|
||||
definition = str(codeblock[0]).strip().translate(tex_escape_map)
|
||||
ret.append(self.babel_renewcommand('\\literalblockname', definition))
|
||||
if codeblock[1]:
|
||||
pass # FIXME
|
||||
@@ -824,7 +823,7 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
if i > 0:
|
||||
ret.append('\\indexspace\n')
|
||||
ret.append('\\bigletter{%s}\n' %
|
||||
text_type(letter).translate(tex_escape_map))
|
||||
str(letter).translate(tex_escape_map))
|
||||
for entry in entries:
|
||||
if not entry[3]:
|
||||
continue
|
||||
@@ -2003,7 +2002,7 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
id = node.get('refuri', '')[1:].replace('#', ':')
|
||||
|
||||
title = node.get('title', '%s')
|
||||
title = text_type(title).translate(tex_escape_map).replace('\\%s', '%s')
|
||||
title = str(title).translate(tex_escape_map).replace('\\%s', '%s')
|
||||
if '\\{name\\}' in title or '\\{number\\}' in title:
|
||||
# new style format (cf. "Fig.%{number}")
|
||||
title = title.replace('\\{name\\}', '{name}').replace('\\{number\\}', '{number}')
|
||||
@@ -2451,7 +2450,7 @@ class LaTeXTranslator(SphinxTranslator):
|
||||
|
||||
def encode(self, text):
|
||||
# type: (str) -> str
|
||||
text = text_type(text).translate(tex_escape_map)
|
||||
text = str(text).translate(tex_escape_map)
|
||||
if self.literal_whitespace:
|
||||
# Insert a blank before the newline, to avoid
|
||||
# ! LaTeX Error: There's no line here to end.
|
||||
|
||||
4
tests/roots/test-build-htmlhelp/conf.py
Normal file
4
tests/roots/test-build-htmlhelp/conf.py
Normal file
@@ -0,0 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
project = 'test'
|
||||
master_doc = 'index'
|
||||
19
tests/roots/test-build-htmlhelp/index.rst
Normal file
19
tests/roots/test-build-htmlhelp/index.rst
Normal file
@@ -0,0 +1,19 @@
|
||||
Index markup
|
||||
------------
|
||||
|
||||
.. index::
|
||||
single: entry
|
||||
pair: entry; pair
|
||||
double: entry; double
|
||||
triple: index; entry; triple
|
||||
keyword: with
|
||||
see: from; to
|
||||
seealso: fromalso; toalso
|
||||
|
||||
.. index::
|
||||
!Main, !Other
|
||||
!single: entry; pair
|
||||
|
||||
.. index:: triple-quoted string, Unicode Consortium, raw string
|
||||
single: """; string literal
|
||||
single: '''; string literal
|
||||
64
tests/roots/test-build-htmlhelp/make.bat
Normal file
64
tests/roots/test-build-htmlhelp/make.bat
Normal file
@@ -0,0 +1,64 @@
|
||||
@echo off
|
||||
setlocal
|
||||
|
||||
pushd %~dp0
|
||||
|
||||
set this=%~n0
|
||||
|
||||
if not defined PYTHON set PYTHON=py
|
||||
|
||||
if not defined SPHINXBUILD (
|
||||
%PYTHON% -c "import sphinx" > nul 2> nul
|
||||
if errorlevel 1 (
|
||||
echo Installing sphinx with %PYTHON%
|
||||
%PYTHON% -m pip install sphinx
|
||||
if errorlevel 1 exit /B
|
||||
)
|
||||
set SPHINXBUILD=%PYTHON% -c "import sphinx.cmd.build, sys; sys.exit(sphinx.cmd.build.main())"
|
||||
)
|
||||
|
||||
rem Search for HHC in likely places
|
||||
set HTMLHELP=
|
||||
where hhc /q && set HTMLHELP=hhc && goto :skiphhcsearch
|
||||
where /R ..\externals hhc > "%TEMP%\hhc.loc" 2> nul && set /P HTMLHELP= < "%TEMP%\hhc.loc" & del "%TEMP%\hhc.loc"
|
||||
if not exist "%HTMLHELP%" where /R "%ProgramFiles(x86)%" hhc > "%TEMP%\hhc.loc" 2> nul && set /P HTMLHELP= < "%TEMP%\hhc.loc" & del "%TEMP%\hhc.loc"
|
||||
if not exist "%HTMLHELP%" where /R "%ProgramFiles%" hhc > "%TEMP%\hhc.loc" 2> nul && set /P HTMLHELP= < "%TEMP%\hhc.loc" & del "%TEMP%\hhc.loc"
|
||||
if not exist "%HTMLHELP%" (
|
||||
echo.
|
||||
echo.The HTML Help Workshop was not found. Set the HTMLHELP variable
|
||||
echo.to the path to hhc.exe or download and install it from
|
||||
echo.http://msdn.microsoft.com/en-us/library/ms669985
|
||||
exit /B 1
|
||||
)
|
||||
echo hhc.exe path: %HTMLHELP%
|
||||
|
||||
if "%BUILDDIR%" EQU "" set BUILDDIR=build
|
||||
|
||||
%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.
|
||||
popd
|
||||
exit /B 1
|
||||
)
|
||||
|
||||
set SPHINXOPTS=-D html_theme_options.body_max_width=none %SPHINXOPTS%
|
||||
|
||||
cmd /S /C "%SPHINXBUILD% %SPHINXOPTS% -bhtmlhelp -dbuild\doctrees . "%BUILDDIR%\htmlhelp"
|
||||
|
||||
"%HTMLHELP%" "%BUILDDIR%\htmlhelp\test.hhp"
|
||||
rem hhc.exe seems to always exit with code 1, reset to 0 for less than 2
|
||||
if not errorlevel 2 cmd /C exit /b 0
|
||||
|
||||
echo.
|
||||
if errorlevel 1 (
|
||||
echo.Build failed (exit code %ERRORLEVEL%^), check for error messages
|
||||
echo.above. Any output will be found in %BUILDDIR%\%1
|
||||
) else (
|
||||
echo.Build succeeded. All output should be in %BUILDDIR%\%1
|
||||
)
|
||||
|
||||
popd
|
||||
@@ -2,3 +2,9 @@ foo
|
||||
===
|
||||
|
||||
.. todo:: todo in foo
|
||||
|
||||
.. py:function:: hello()
|
||||
|
||||
:param bug: #5800
|
||||
|
||||
.. todo:: todo in param field
|
||||
|
||||
@@ -8,8 +8,12 @@
|
||||
:license: BSD, see LICENSE for details.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
import pytest
|
||||
|
||||
from sphinx.builders.htmlhelp import chm_htmlescape
|
||||
|
||||
from sphinx.builders.htmlhelp import default_htmlhelp_basename
|
||||
from sphinx.config import Config
|
||||
|
||||
@@ -29,3 +33,31 @@ def test_default_htmlhelp_basename():
|
||||
config = Config({'project': 'Sphinx Documentation'})
|
||||
config.init_values()
|
||||
assert default_htmlhelp_basename(config) == 'sphinxdoc'
|
||||
|
||||
|
||||
@pytest.mark.sphinx('htmlhelp', testroot='build-htmlhelp')
|
||||
def test_chm(app):
|
||||
app.build()
|
||||
|
||||
# check .hhk file
|
||||
outname = app.builder.config.htmlhelp_basename
|
||||
hhk_path = str(app.outdir / outname + '.hhk')
|
||||
|
||||
with open(hhk_path, 'rb') as f:
|
||||
data = f.read()
|
||||
m = re.search(br'&#[xX][0-9a-fA-F]+;', data)
|
||||
assert m is None, 'Hex escaping exists in .hhk file: ' + str(m.group(0))
|
||||
|
||||
|
||||
def test_chm_htmlescape():
|
||||
assert chm_htmlescape('Hello world') == 'Hello world'
|
||||
assert chm_htmlescape(u'Unicode 文字') == u'Unicode 文字'
|
||||
assert chm_htmlescape('E') == '&#x45'
|
||||
|
||||
assert chm_htmlescape('<Hello> "world"') == '<Hello> "world"'
|
||||
assert chm_htmlescape('<Hello> "world"', True) == '<Hello> "world"'
|
||||
assert chm_htmlescape('<Hello> "world"', False) == '<Hello> "world"'
|
||||
|
||||
assert chm_htmlescape("Hello 'world'") == "Hello 'world'"
|
||||
assert chm_htmlescape("Hello 'world'", True) == "Hello 'world'"
|
||||
assert chm_htmlescape("Hello 'world'", False) == "Hello 'world'"
|
||||
|
||||
@@ -12,7 +12,6 @@ import re
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
from six import text_type
|
||||
|
||||
import sphinx.domains.cpp as cppDomain
|
||||
from sphinx import addnodes
|
||||
@@ -39,7 +38,7 @@ def check(name, input, idDict, output=None):
|
||||
if output is None:
|
||||
output = input
|
||||
ast = parse(name, input)
|
||||
res = text_type(ast)
|
||||
res = str(ast)
|
||||
if res != output:
|
||||
print("")
|
||||
print("Input: ", input)
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
import pytest
|
||||
from docutils import nodes
|
||||
from mock import Mock
|
||||
from six import text_type
|
||||
|
||||
from sphinx import addnodes
|
||||
from sphinx.domains.python import py_sig_re, _pseudo_parse_arglist, PythonDomain
|
||||
@@ -30,22 +29,22 @@ def parse(sig):
|
||||
|
||||
def test_function_signatures():
|
||||
rv = parse('func(a=1) -> int object')
|
||||
assert text_type(rv) == 'a=1'
|
||||
assert rv == 'a=1'
|
||||
|
||||
rv = parse('func(a=1, [b=None])')
|
||||
assert text_type(rv) == 'a=1, [b=None]'
|
||||
assert rv == 'a=1, [b=None]'
|
||||
|
||||
rv = parse('func(a=1[, b=None])')
|
||||
assert text_type(rv) == 'a=1, [b=None]'
|
||||
assert rv == 'a=1, [b=None]'
|
||||
|
||||
rv = parse("compile(source : string, filename, symbol='file')")
|
||||
assert text_type(rv) == "source : string, filename, symbol='file'"
|
||||
assert rv == "source : string, filename, symbol='file'"
|
||||
|
||||
rv = parse('func(a=[], [b=None])')
|
||||
assert text_type(rv) == 'a=[], [b=None]'
|
||||
assert rv == 'a=[], [b=None]'
|
||||
|
||||
rv = parse('func(a=[][, b=None])')
|
||||
assert text_type(rv) == 'a=[], [b=None]'
|
||||
assert rv == 'a=[], [b=None]'
|
||||
|
||||
|
||||
@pytest.mark.sphinx('dummy', testroot='domain-py')
|
||||
|
||||
@@ -40,13 +40,19 @@ def test_todo(app, status, warning):
|
||||
'<p class="last">todo in foo</p>')
|
||||
assert re.search(html, content, re.S)
|
||||
|
||||
html = ('<p class="first admonition-title">Todo</p>\n'
|
||||
'<p class="last">todo in param field</p>')
|
||||
assert re.search(html, content, re.S)
|
||||
|
||||
# check emitted warnings
|
||||
assert 'WARNING: TODO entry found: todo in foo' in warning.getvalue()
|
||||
assert 'WARNING: TODO entry found: todo in bar' in warning.getvalue()
|
||||
|
||||
# check handled event
|
||||
assert len(todos) == 2
|
||||
assert set(todo[1].astext() for todo in todos) == set(['todo in foo', 'todo in bar'])
|
||||
assert len(todos) == 3
|
||||
assert set(todo[1].astext() for todo in todos) == {'todo in foo',
|
||||
'todo in bar',
|
||||
'todo in param field'}
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='ext-todo', freshenv=True,
|
||||
@@ -81,8 +87,10 @@ def test_todo_not_included(app, status, warning):
|
||||
assert 'WARNING: TODO entry found: todo in bar' in warning.getvalue()
|
||||
|
||||
# check handled event
|
||||
assert len(todos) == 2
|
||||
assert set(todo[1].astext() for todo in todos) == set(['todo in foo', 'todo in bar'])
|
||||
assert len(todos) == 3
|
||||
assert set(todo[1].astext() for todo in todos) == {'todo in foo',
|
||||
'todo in bar',
|
||||
'todo in param field'}
|
||||
|
||||
|
||||
@pytest.mark.sphinx('latex', testroot='ext-todo', freshenv=True,
|
||||
@@ -105,7 +113,7 @@ def test_todo_valid_link(app, status, warning):
|
||||
link = r'\{\\hyperref\[\\detokenize\{(.*?foo.*?)}]\{\\sphinxcrossref{' \
|
||||
r'\\sphinxstyleemphasis{original entry}}}}'
|
||||
m = re.findall(link, content)
|
||||
assert len(m) == 2
|
||||
assert len(m) == 4
|
||||
target = m[0]
|
||||
|
||||
# Look for the targets of this link.
|
||||
|
||||
@@ -705,20 +705,20 @@ def test_html_versionchanges(app):
|
||||
return ''
|
||||
|
||||
expect1 = (
|
||||
"""<p><span class="versionmodified">Deprecated since version 1.0: </span>"""
|
||||
"""<p><span class="versionmodified deprecated">Deprecated since version 1.0: </span>"""
|
||||
"""THIS IS THE <em>FIRST</em> PARAGRAPH OF DEPRECATED.</p>\n"""
|
||||
"""<p>THIS IS THE <em>SECOND</em> PARAGRAPH OF DEPRECATED.</p>\n""")
|
||||
matched_content = get_content(result, "deprecated")
|
||||
assert expect1 == matched_content
|
||||
|
||||
expect2 = (
|
||||
"""<p><span class="versionmodified">New in version 1.0: </span>"""
|
||||
"""<p><span class="versionmodified added">New in version 1.0: </span>"""
|
||||
"""THIS IS THE <em>FIRST</em> PARAGRAPH OF VERSIONADDED.</p>\n""")
|
||||
matched_content = get_content(result, "versionadded")
|
||||
assert expect2 == matched_content
|
||||
|
||||
expect3 = (
|
||||
"""<p><span class="versionmodified">Changed in version 1.0: </span>"""
|
||||
"""<p><span class="versionmodified changed">Changed in version 1.0: </span>"""
|
||||
"""THIS IS THE <em>FIRST</em> PARAGRAPH OF VERSIONCHANGED.</p>\n""")
|
||||
matched_content = get_content(result, "versionchanged")
|
||||
assert expect3 == matched_content
|
||||
|
||||
@@ -12,7 +12,6 @@ import time
|
||||
from io import StringIO
|
||||
|
||||
import pytest
|
||||
from six import text_type
|
||||
|
||||
from sphinx import application
|
||||
from sphinx.cmd import quickstart as qs
|
||||
@@ -35,7 +34,6 @@ def mock_input(answers, needanswer=False):
|
||||
raise AssertionError('answer for %r missing and no default '
|
||||
'present' % prompt)
|
||||
called.add(prompt)
|
||||
prompt = text_type(prompt)
|
||||
for question in answers:
|
||||
if prompt.startswith(qs.PROMPT_PREFIX + question):
|
||||
return answers[question]
|
||||
|
||||
Reference in New Issue
Block a user