mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge branch '5.x'
# Conflicts: # sphinx/ext/autodoc/__init__.py # sphinx/writers/html5.py
This commit is contained in:
commit
94024e6efa
5
CHANGES
5
CHANGES
@ -56,6 +56,7 @@ Features added
|
|||||||
corner radii, a shadow (possibly inset), colours for border, background, shadow
|
corner radii, a shadow (possibly inset), colours for border, background, shadow
|
||||||
for each of the code-block, topic, attention, caution, danger, error and warning
|
for each of the code-block, topic, attention, caution, danger, error and warning
|
||||||
directives.
|
directives.
|
||||||
|
* #10655: LaTeX: Explain non-standard encoding in LatinRules.xdy
|
||||||
* #10599: HTML Theme: Wrap consecutive footnotes in an ``<aside>`` element when
|
* #10599: HTML Theme: Wrap consecutive footnotes in an ``<aside>`` element when
|
||||||
using Docutils 0.18 or later, to allow for easier styling. This matches the
|
using Docutils 0.18 or later, to allow for easier styling. This matches the
|
||||||
behaviour introduced in Docutils 0.19. Patch by Adam Turner.
|
behaviour introduced in Docutils 0.19. Patch by Adam Turner.
|
||||||
@ -69,6 +70,10 @@ Bugs fixed
|
|||||||
* #10031: py domain: Fix spurious whitespace in unparsing various operators (``+``,
|
* #10031: py domain: Fix spurious whitespace in unparsing various operators (``+``,
|
||||||
``-``, ``~``, and ``**``). Patch by Adam Turner.
|
``-``, ``~``, and ``**``). Patch by Adam Turner.
|
||||||
* #10460: logging: Always show node source locations as absolute paths.
|
* #10460: logging: Always show node source locations as absolute paths.
|
||||||
|
* HTML Search: HTML tags are displayed as a part of object name
|
||||||
|
* HTML Search: search snipets should not be folded
|
||||||
|
* HTML Search: Minor errors are emitted on fetching search snipets
|
||||||
|
* HTML Search: The markers for header links are shown in the search result
|
||||||
* #10520: HTML Theme: Fix use of sidebar classes in ``agogo.css_t``.
|
* #10520: HTML Theme: Fix use of sidebar classes in ``agogo.css_t``.
|
||||||
* #6679: HTML Theme: Fix inclusion of hidden toctrees in the agogo theme.
|
* #6679: HTML Theme: Fix inclusion of hidden toctrees in the agogo theme.
|
||||||
* #10566: HTML Theme: Fix enable_search_shortcuts does not work
|
* #10566: HTML Theme: Fix enable_search_shortcuts does not work
|
||||||
|
@ -65,6 +65,7 @@ Releases are signed with following keys:
|
|||||||
|
|
||||||
* `498D6B9E <https://pgp.mit.edu/pks/lookup?op=vindex&search=0x102C2C17498D6B9E>`_
|
* `498D6B9E <https://pgp.mit.edu/pks/lookup?op=vindex&search=0x102C2C17498D6B9E>`_
|
||||||
* `5EBA0E07 <https://pgp.mit.edu/pks/lookup?op=vindex&search=0x1425F8CE5EBA0E07>`_
|
* `5EBA0E07 <https://pgp.mit.edu/pks/lookup?op=vindex&search=0x1425F8CE5EBA0E07>`_
|
||||||
|
* `61F0FB52 <https://pgp.mit.edu/pks/lookup?op=vindex&search=0x52C8F72A61F0FB52>`_
|
||||||
|
|
||||||
.. _the documentation: https://www.sphinx-doc.org/
|
.. _the documentation: https://www.sphinx-doc.org/
|
||||||
.. _the contributors guide: https://www.sphinx-doc.org/en/master/internals/contributing.html
|
.. _the contributors guide: https://www.sphinx-doc.org/en/master/internals/contributing.html
|
||||||
|
16
doc/_themes/sphinx13/layout.html
vendored
16
doc/_themes/sphinx13/layout.html
vendored
@ -32,15 +32,15 @@
|
|||||||
{%- block content %}
|
{%- block content %}
|
||||||
<div class="document">
|
<div class="document">
|
||||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||||
{%- include "searchbox.html" %}
|
{%- include "searchbox.html" %}
|
||||||
<div>
|
<div class="sphinxsidebar-navigation__contents">
|
||||||
<h3>{{ _('Contents') }}</h3>
|
<h3>{{ _('On this page') }}</h3>
|
||||||
{%- if pagename != "index" %}
|
|
||||||
{{ toc }}
|
{{ toc }}
|
||||||
{%- else %}
|
</div>
|
||||||
{{ toctree(includehidden=True, maxdepth=3) }}
|
<div class="sphinxsidebar-navigation__pages">
|
||||||
{%- endif %}
|
<h3>{{ _('Site navigation') }}</h3>
|
||||||
</div>
|
{{ toctree(includehidden=True, maxdepth=3, titles_only=True) }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{%- block document %}
|
{%- block document %}
|
||||||
<div class="body" role="main">
|
<div class="body" role="main">
|
||||||
|
44
doc/_themes/sphinx13/static/sphinx13.css
vendored
44
doc/_themes/sphinx13/static/sphinx13.css
vendored
@ -27,7 +27,7 @@ div.document {
|
|||||||
div.body {
|
div.body {
|
||||||
border-left: 1px solid var(--colour-sphinx-blue);
|
border-left: 1px solid var(--colour-sphinx-blue);
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0.5em 1.25em;
|
padding: 0.5em 1.75em;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
max-width: 800px;
|
max-width: 800px;
|
||||||
}
|
}
|
||||||
@ -59,10 +59,15 @@ div.sphinxsidebarwrapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
div.sphinxsidebar {
|
div.sphinxsidebar {
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
align-self: flex-start;
|
||||||
|
height: 100vh;
|
||||||
|
width: 250px;
|
||||||
|
overflow-y: auto;
|
||||||
overflow-wrap: break-word;
|
overflow-wrap: break-word;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding-right: 15px;
|
padding-right: 15px;
|
||||||
width: 210px;
|
|
||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,8 +104,27 @@ div.sphinxsidebar ul {
|
|||||||
}
|
}
|
||||||
|
|
||||||
div.sphinxsidebar ul ul {
|
div.sphinxsidebar ul ul {
|
||||||
margin-left: 20px;
|
margin-left: 1rem;
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
|
font-size: .9em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* De-dent the first list because we hide the top-level item */
|
||||||
|
.sphinxsidebar .sphinxsidebar-navigation__contents > ul > li > ul {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.sphinxsidebar p.caption {
|
||||||
|
font-weight: 300;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.sphinxsidebar li.current > a {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sphinxsidebar-navigation__contents > ul > li > a {
|
||||||
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.footer {
|
div.footer {
|
||||||
@ -170,11 +194,10 @@ div.body h1 a tt, div.body h2 a tt, div.body h3 a tt, div.body h4 a tt, div.body
|
|||||||
|
|
||||||
a.headerlink {
|
a.headerlink {
|
||||||
color: var(--colour-sphinx-blue) !important;
|
color: var(--colour-sphinx-blue) !important;
|
||||||
font-size: 12px;
|
font-size: .8em;
|
||||||
margin-left: 6px;
|
margin-left: 6px;
|
||||||
padding: 0 4px 0 4px;
|
padding: 0 4px 0 4px;
|
||||||
text-decoration: none !important;
|
text-decoration: none !important;
|
||||||
float: right;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
a.headerlink:hover {
|
a.headerlink:hover {
|
||||||
@ -250,6 +273,12 @@ div.quotebar {
|
|||||||
margin-left: 1em;
|
margin-left: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
blockquote {
|
||||||
|
font-size: 1.5em;
|
||||||
|
padding-left: 1rem;
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
nav.contents,
|
nav.contents,
|
||||||
div.topic,
|
div.topic,
|
||||||
aside.topic {
|
aside.topic {
|
||||||
@ -271,11 +300,11 @@ div.admonition, div.warning {
|
|||||||
border: 1px solid #86989B;
|
border: 1px solid #86989B;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
background-color: #f7f7f7;
|
background-color: #f7f7f7;
|
||||||
padding: 0;
|
padding: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.admonition > p, div.warning > p {
|
div.admonition > p, div.warning > p {
|
||||||
margin: 0.5em 1em 0.5em 1em;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -285,7 +314,6 @@ div.admonition > pre, div.warning > pre {
|
|||||||
|
|
||||||
div.admonition > p.admonition-title,
|
div.admonition > p.admonition-title,
|
||||||
div.warning > p.admonition-title {
|
div.warning > p.admonition-title {
|
||||||
margin-top: 0.5em;
|
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
133
doc/index.rst
133
doc/index.rst
@ -2,16 +2,9 @@
|
|||||||
Welcome
|
Welcome
|
||||||
=======
|
=======
|
||||||
|
|
||||||
**Sphinx makes it easy to create intelligent and beautiful documentation.**
|
.. epigraph:: Sphinx makes it easy to create intelligent and beautiful documentation.
|
||||||
|
|
||||||
Install
|
Here are some of Sphinx's major features:
|
||||||
=======
|
|
||||||
|
|
||||||
Install Sphinx with ``pip install -U Sphinx``. See :doc:`usage/installation` for
|
|
||||||
further details.
|
|
||||||
|
|
||||||
Features
|
|
||||||
========
|
|
||||||
|
|
||||||
* **Output formats:** HTML (including Windows HTML Help), LaTeX (for printable
|
* **Output formats:** HTML (including Windows HTML Help), LaTeX (for printable
|
||||||
PDF versions), ePub, Texinfo, manual pages, plain text
|
PDF versions), ePub, Texinfo, manual pages, plain text
|
||||||
@ -24,78 +17,98 @@ Features
|
|||||||
indices
|
indices
|
||||||
* **Code handling:** automatic highlighting using the Pygments_ highlighter
|
* **Code handling:** automatic highlighting using the Pygments_ highlighter
|
||||||
* **Extensions:** automatic testing of code snippets, inclusion of docstrings
|
* **Extensions:** automatic testing of code snippets, inclusion of docstrings
|
||||||
from Python modules (API docs), and :ref:`more <builtin-extensions>`
|
from Python modules (API docs) via :ref:`built-in extensions
|
||||||
* **Contributed extensions:** dozens of extensions
|
<builtin-extensions>`, and much more functionality via :ref:`third-party
|
||||||
:ref:`contributed by users <third-party-extensions>`; most of them installable
|
extensions <third-party-extensions>`.
|
||||||
from PyPI
|
* **Themes:** modify the look and feel of outputs via :doc:`creating themes
|
||||||
|
<development/theming>`, and re-use many :ref:`third-party themes
|
||||||
.. _Pygments: https://pygments.org/
|
<third-party-themes>`.
|
||||||
|
* **Contributed extensions:** dozens of extensions :ref:`contributed by users
|
||||||
Sphinx uses reStructuredText_ as its markup language, and many of its strengths
|
<third-party-extensions>`; most of them installable from PyPI.
|
||||||
come from the power and straightforwardness of reStructuredText and its parsing
|
|
||||||
and translating suite, the Docutils_.
|
|
||||||
|
|
||||||
.. _reStructuredText: https://docutils.sourceforge.io/rst.html
|
.. _reStructuredText: https://docutils.sourceforge.io/rst.html
|
||||||
.. _Docutils: https://docutils.sourceforge.io/
|
.. _Docutils: https://docutils.sourceforge.io/
|
||||||
|
.. _Pygments: https://pygments.org/
|
||||||
|
|
||||||
Documentation
|
Sphinx uses the reStructuredText_ markup language by default, and can read
|
||||||
=============
|
:ref:`MyST markdown <markdown>` via third-party extensions. Both of these
|
||||||
|
are powerful and straightforward to use, and have functionality
|
||||||
|
for complex documentation and publishing workflows. They both build upon
|
||||||
|
Docutils_ to parse and write documents.
|
||||||
|
|
||||||
* :doc:`First steps with Sphinx <usage/quickstart>`: overview of basic tasks
|
See below for how to navigate Sphinx's documentation.
|
||||||
* :doc:`Tutorial <tutorial/index>`: beginners tutorial
|
|
||||||
* :ref:`Search page <search>`: search the documentation
|
|
||||||
* :doc:`Changes <changes>`: release history
|
|
||||||
* :ref:`General Index <genindex>`: all functions, classes, terms
|
|
||||||
* :ref:`Python Module Index <modindex>`: the index of Python modules
|
|
||||||
* :doc:`Glossary <glossary>`: definitions of various terms
|
|
||||||
* :doc:`Sphinx's Authors <internals/authors>`: the Sphinx developers
|
|
||||||
* `Contents <contents.html>`__: full table of contents
|
|
||||||
|
|
||||||
Support
|
.. seealso::
|
||||||
=======
|
|
||||||
|
|
||||||
For questions or to report problems with Sphinx, join the `sphinx-users`_
|
The `Sphinx documentation Table of Contents <contents.html>`_ has
|
||||||
mailing list on Google Groups, come to the ``#sphinx-doc`` channel on
|
a full list of this site's pages.
|
||||||
`libera.chat`_, or open an issue at the tracker_.
|
|
||||||
|
|
||||||
.. _sphinx-users: https://groups.google.com/group/sphinx-users
|
.. _get-started:
|
||||||
.. _libera.chat: https://web.libera.chat/?channel=#sphinx-doc
|
|
||||||
.. _tracker: https://github.com/sphinx-doc/sphinx/issues
|
|
||||||
|
|
||||||
Examples of other projects using Sphinx can be found in the :doc:`examples page
|
Get started
|
||||||
<examples>`. A useful tutorial_ has been written by the matplotlib developers.
|
===========
|
||||||
|
|
||||||
.. _tutorial: http://matplotlib.sourceforge.net/sampledoc/
|
These sections cover the basics of getting started with Sphinx, including
|
||||||
|
creating and building your own documentation from scratch.
|
||||||
There is a translation team in Transifex_ of this documentation, thanks to the
|
|
||||||
Sphinx document translators.
|
|
||||||
|
|
||||||
.. _Transifex: https://www.transifex.com/sphinx-doc/sphinx-doc/dashboard/
|
|
||||||
|
|
||||||
Contributor guide
|
|
||||||
=================
|
|
||||||
|
|
||||||
See the :doc:`Sphinx contributors' guide <internals/contributing>` if you would
|
|
||||||
like to contribute to the project.
|
|
||||||
|
|
||||||
.. master toctree:
|
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 5
|
:maxdepth: 2
|
||||||
:hidden:
|
:caption: Get started
|
||||||
|
|
||||||
|
usage/quickstart
|
||||||
|
usage/installation
|
||||||
|
tutorial/index
|
||||||
|
|
||||||
|
.. _user-guides:
|
||||||
|
|
||||||
|
User Guides
|
||||||
|
===========
|
||||||
|
|
||||||
|
These sections cover various topics in using and extending Sphinx for various
|
||||||
|
use-cases. They are a comprehensive guide to using Sphinx in many contexts and
|
||||||
|
assume more knowledge of Sphinx. If you are new to Sphinx, we recommend
|
||||||
|
starting with :ref:`get-started`.
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
:caption: User Guides
|
||||||
|
|
||||||
usage/index
|
usage/index
|
||||||
tutorial/index
|
|
||||||
development/index
|
development/index
|
||||||
man/index
|
|
||||||
|
|
||||||
templating
|
templating
|
||||||
latex
|
latex
|
||||||
extdev/index
|
extdev/index
|
||||||
|
|
||||||
internals/index
|
Community guide
|
||||||
|
===============
|
||||||
|
|
||||||
|
Sphinx is community supported and welcomes contributions from anybody.
|
||||||
|
The sections below should help you get started joining the Sphinx community
|
||||||
|
as well as contributing.
|
||||||
|
|
||||||
|
See the :doc:`Sphinx contributors' guide <internals/contributing>` if you would
|
||||||
|
like to contribute to the project.
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
:caption: Community
|
||||||
|
|
||||||
|
support
|
||||||
|
internals/index
|
||||||
faq
|
faq
|
||||||
|
|
||||||
|
Reference guide
|
||||||
|
===============
|
||||||
|
|
||||||
|
Reference documentation is more complete and programmatic in nature, it is a
|
||||||
|
collection of information that can be quickly referenced. If you would like
|
||||||
|
usecase-driven documentation, see :ref:`get-started` or :ref:`user-guides`.
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
:caption: Reference
|
||||||
|
|
||||||
|
man/index
|
||||||
glossary
|
glossary
|
||||||
changes
|
changes
|
||||||
examples
|
examples
|
||||||
|
@ -7,8 +7,8 @@ feature requests, writing new documentation or submitting patches for new or
|
|||||||
fixed behavior. This guide serves to illustrate how you can get started with
|
fixed behavior. This guide serves to illustrate how you can get started with
|
||||||
this.
|
this.
|
||||||
|
|
||||||
Getting help
|
Get help
|
||||||
------------
|
--------
|
||||||
|
|
||||||
The Sphinx community maintains a number of mailing lists and IRC channels.
|
The Sphinx community maintains a number of mailing lists and IRC channels.
|
||||||
|
|
||||||
@ -46,8 +46,8 @@ and post that instead.
|
|||||||
.. _`sphinx-dev`: mailto:sphinx-dev@googlegroups.com
|
.. _`sphinx-dev`: mailto:sphinx-dev@googlegroups.com
|
||||||
|
|
||||||
|
|
||||||
Writing code
|
Contribute code
|
||||||
------------
|
---------------
|
||||||
|
|
||||||
The Sphinx source code is managed using Git and is hosted on `GitHub`__. The
|
The Sphinx source code is managed using Git and is hosted on `GitHub`__. The
|
||||||
recommended way for new contributors to submit code to Sphinx is to fork this
|
recommended way for new contributors to submit code to Sphinx is to fork this
|
||||||
@ -57,6 +57,8 @@ before it is merged into the main repository.
|
|||||||
|
|
||||||
.. __: https://github.com/sphinx-doc/sphinx
|
.. __: https://github.com/sphinx-doc/sphinx
|
||||||
|
|
||||||
|
.. _contribute-get-started:
|
||||||
|
|
||||||
Getting started
|
Getting started
|
||||||
~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
@ -235,15 +237,38 @@ If you want to know more detailed usage, please refer to ``tests/conftest.py``
|
|||||||
and other ``test_*.py`` files under ``tests`` directory.
|
and other ``test_*.py`` files under ``tests`` directory.
|
||||||
|
|
||||||
|
|
||||||
Writing documentation
|
Contribute documentation
|
||||||
---------------------
|
------------------------
|
||||||
|
|
||||||
|
Contributing to documentation involves modifying the source files found in the
|
||||||
|
``doc/`` folder. To get started, you should first follow :ref:`contribute-get-started`,
|
||||||
|
and then take the steps below to work with the documentation.
|
||||||
|
|
||||||
|
The following sections describe how to get started with contributing
|
||||||
|
documentation, as well as key aspects of a few different tools that we use.
|
||||||
|
|
||||||
.. todo:: Add a more extensive documentation contribution guide.
|
.. todo:: Add a more extensive documentation contribution guide.
|
||||||
|
|
||||||
You can build documentation using ``tox``::
|
Build the documentation
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
We use `the tox tool <https://tox.wiki/en/latest/>`__ to quickly build the
|
||||||
|
documentation. Tox is kind-of like a Makefile, but includes the ability to
|
||||||
|
intsall an isolated environment used to run each task.
|
||||||
|
|
||||||
|
To build the documentation with ``tox``, run the following command::
|
||||||
|
|
||||||
tox -e docs
|
tox -e docs
|
||||||
|
|
||||||
|
This will parse the Sphinx documentation's source files and generate HTML for
|
||||||
|
you to preview in ``build/sphinx/html``.
|
||||||
|
|
||||||
|
You can also build a **live version of the documentation** that you can preview
|
||||||
|
in the browser. It will detect changes and reload the page any time you make
|
||||||
|
edits. To do so, run the following command::
|
||||||
|
|
||||||
|
tox -e docs-live
|
||||||
|
|
||||||
Translations
|
Translations
|
||||||
~~~~~~~~~~~~
|
~~~~~~~~~~~~
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
================
|
====================
|
||||||
Sphinx internals
|
Contribute to Sphinx
|
||||||
================
|
====================
|
||||||
|
|
||||||
This guide contains information about the Sphinx open source project itself.
|
This guide contains information about the Sphinx open source project itself.
|
||||||
This is where you can find information about how Sphinx is managed and learn
|
This is where you can find information about how Sphinx is managed and learn
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
Man Pages
|
Command-Line Tools
|
||||||
=========
|
==================
|
||||||
|
|
||||||
These are the applications provided as part of Sphinx.
|
These are the applications provided as part of Sphinx.
|
||||||
|
|
||||||
|
20
doc/support.rst
Normal file
20
doc/support.rst
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
Get support
|
||||||
|
===========
|
||||||
|
|
||||||
|
For questions or to report problems with Sphinx, join the `sphinx-users`_
|
||||||
|
mailing list on Google Groups, come to the ``#sphinx-doc`` channel on
|
||||||
|
`libera.chat`_, or open an issue at the tracker_.
|
||||||
|
|
||||||
|
.. _sphinx-users: https://groups.google.com/group/sphinx-users
|
||||||
|
.. _libera.chat: https://web.libera.chat/?channel=#sphinx-doc
|
||||||
|
.. _tracker: https://github.com/sphinx-doc/sphinx/issues
|
||||||
|
|
||||||
|
Examples of other projects using Sphinx can be found in the :doc:`examples page
|
||||||
|
<examples>`. A useful tutorial_ has been written by the matplotlib developers.
|
||||||
|
|
||||||
|
.. _tutorial: http://matplotlib.sourceforge.net/sampledoc/
|
||||||
|
|
||||||
|
There is a translation team in Transifex_ of this documentation, thanks to the
|
||||||
|
Sphinx document translators.
|
||||||
|
|
||||||
|
.. _Transifex: https://www.transifex.com/sphinx-doc/sphinx-doc/dashboard/
|
@ -1,8 +1,8 @@
|
|||||||
.. _tutorial:
|
.. _tutorial:
|
||||||
|
|
||||||
===============
|
========================
|
||||||
Sphinx tutorial
|
Build your first project
|
||||||
===============
|
========================
|
||||||
|
|
||||||
In this tutorial you will build a simple documentation project using Sphinx, and
|
In this tutorial you will build a simple documentation project using Sphinx, and
|
||||||
view it in your browser as HTML. The project will include narrative,
|
view it in your browser as HTML. The project will include narrative,
|
||||||
|
@ -10,8 +10,6 @@ looking for guidance on extending Sphinx, refer to :doc:`/development/index`.
|
|||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 2
|
:maxdepth: 2
|
||||||
|
|
||||||
quickstart
|
|
||||||
installation
|
|
||||||
restructuredtext/index
|
restructuredtext/index
|
||||||
markdown
|
markdown
|
||||||
configuration
|
configuration
|
||||||
|
@ -345,10 +345,12 @@ These themes are:
|
|||||||
available, however it will emit a notice that it is an alias for the new
|
available, however it will emit a notice that it is an alias for the new
|
||||||
'alabaster' theme.
|
'alabaster' theme.
|
||||||
|
|
||||||
|
.. _third-party-themes:
|
||||||
|
|
||||||
Third Party Themes
|
Third Party Themes
|
||||||
~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
There are many third-party themes available for Sphinx. Some of these are for
|
There are many third-party themes created for Sphinx. Some of these are for
|
||||||
general use, while others are specific to an individual project.
|
general use, while others are specific to an individual project.
|
||||||
|
|
||||||
sphinx-themes.org__ is a gallery that showcases various themes for Sphinx,
|
sphinx-themes.org__ is a gallery that showcases various themes for Sphinx,
|
||||||
|
@ -940,7 +940,7 @@ class Sphinx:
|
|||||||
"""
|
"""
|
||||||
self.registry.add_post_transform(transform)
|
self.registry.add_post_transform(transform)
|
||||||
|
|
||||||
def add_js_file(self, filename: str, priority: int = 500,
|
def add_js_file(self, filename: Optional[str], priority: int = 500,
|
||||||
loading_method: Optional[str] = None, **kwargs: Any) -> None:
|
loading_method: Optional[str] = None, **kwargs: Any) -> None:
|
||||||
"""Register a JavaScript file to include in the HTML output.
|
"""Register a JavaScript file to include in the HTML output.
|
||||||
|
|
||||||
|
@ -301,7 +301,9 @@ class Builder:
|
|||||||
summary=__('targets for %d source files that are out of date') %
|
summary=__('targets for %d source files that are out of date') %
|
||||||
len(to_build))
|
len(to_build))
|
||||||
|
|
||||||
def build(self, docnames: Iterable[str], summary: str = None, method: str = 'update') -> None: # NOQA
|
def build(
|
||||||
|
self, docnames: Iterable[str], summary: Optional[str] = None, method: str = 'update'
|
||||||
|
) -> None:
|
||||||
"""Main build method.
|
"""Main build method.
|
||||||
|
|
||||||
First updates the environment, and then calls :meth:`write`.
|
First updates the environment, and then calls :meth:`write`.
|
||||||
|
@ -4,7 +4,7 @@ import html
|
|||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
from os import path
|
from os import path
|
||||||
from typing import Any, Dict, List, NamedTuple, Set, Tuple
|
from typing import Any, Dict, List, NamedTuple, Optional, Set, Tuple
|
||||||
from zipfile import ZIP_DEFLATED, ZIP_STORED, ZipFile
|
from zipfile import ZIP_DEFLATED, ZIP_STORED, ZipFile
|
||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
@ -446,7 +446,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def handle_page(self, pagename: str, addctx: Dict, templatename: str = 'page.html',
|
def handle_page(self, pagename: str, addctx: Dict, templatename: str = 'page.html',
|
||||||
outfilename: str = None, event_arg: Any = None) -> None:
|
outfilename: Optional[str] = None, event_arg: Any = None) -> None:
|
||||||
"""Create a rendered page.
|
"""Create a rendered page.
|
||||||
|
|
||||||
This method is overwritten for genindex pages in order to fix href link
|
This method is overwritten for genindex pages in order to fix href link
|
||||||
|
@ -127,7 +127,7 @@ class ChangesBuilder(Builder):
|
|||||||
with open(targetfn, 'w', encoding='utf-8') as f:
|
with open(targetfn, 'w', encoding='utf-8') as f:
|
||||||
text = ''.join(hl(i + 1, line) for (i, line) in enumerate(lines))
|
text = ''.join(hl(i + 1, line) for (i, line) in enumerate(lines))
|
||||||
ctx = {
|
ctx = {
|
||||||
'filename': self.env.doc2path(docname, None),
|
'filename': self.env.doc2path(docname, False),
|
||||||
'text': text
|
'text': text
|
||||||
}
|
}
|
||||||
f.write(self.templates.render('changes/rstsource.html', ctx))
|
f.write(self.templates.render('changes/rstsource.html', ctx))
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
"""Directory HTML builders."""
|
"""Directory HTML builders."""
|
||||||
|
|
||||||
from os import path
|
from os import path
|
||||||
from typing import Any, Dict
|
from typing import Any, Dict, Optional
|
||||||
|
|
||||||
from sphinx.application import Sphinx
|
from sphinx.application import Sphinx
|
||||||
from sphinx.builders.html import StandaloneHTMLBuilder
|
from sphinx.builders.html import StandaloneHTMLBuilder
|
||||||
@ -19,7 +19,7 @@ class DirectoryHTMLBuilder(StandaloneHTMLBuilder):
|
|||||||
"""
|
"""
|
||||||
name = 'dirhtml'
|
name = 'dirhtml'
|
||||||
|
|
||||||
def get_target_uri(self, docname: str, typ: str = None) -> str:
|
def get_target_uri(self, docname: str, typ: Optional[str] = None) -> str:
|
||||||
if docname == 'index':
|
if docname == 'index':
|
||||||
return ''
|
return ''
|
||||||
if docname.endswith(SEP + 'index'):
|
if docname.endswith(SEP + 'index'):
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
"""Do syntax checks, but no writing."""
|
"""Do syntax checks, but no writing."""
|
||||||
|
|
||||||
from typing import Any, Dict, Set
|
from typing import Any, Dict, Optional, Set
|
||||||
|
|
||||||
from docutils.nodes import Node
|
from docutils.nodes import Node
|
||||||
|
|
||||||
@ -21,7 +21,7 @@ class DummyBuilder(Builder):
|
|||||||
def get_outdated_docs(self) -> Set[str]:
|
def get_outdated_docs(self) -> Set[str]:
|
||||||
return self.env.found_docs
|
return self.env.found_docs
|
||||||
|
|
||||||
def get_target_uri(self, docname: str, typ: str = None) -> str:
|
def get_target_uri(self, docname: str, typ: Optional[str] = None) -> str:
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
def prepare_writing(self, docnames: Set[str]) -> None:
|
def prepare_writing(self, docnames: Set[str]) -> None:
|
||||||
|
@ -77,7 +77,7 @@ class Epub3Builder(_epub_base.EpubBuilder):
|
|||||||
self.build_toc()
|
self.build_toc()
|
||||||
self.build_epub()
|
self.build_epub()
|
||||||
|
|
||||||
def content_metadata(self) -> Dict:
|
def content_metadata(self) -> Dict[str, Any]:
|
||||||
"""Create a dictionary with all metadata for the content.opf
|
"""Create a dictionary with all metadata for the content.opf
|
||||||
file properly escaped.
|
file properly escaped.
|
||||||
"""
|
"""
|
||||||
@ -144,11 +144,11 @@ class Epub3Builder(_epub_base.EpubBuilder):
|
|||||||
|
|
||||||
return navstack[0].children
|
return navstack[0].children
|
||||||
|
|
||||||
def navigation_doc_metadata(self, navlist: List[NavPoint]) -> Dict:
|
def navigation_doc_metadata(self, navlist: List[NavPoint]) -> Dict[str, Any]:
|
||||||
"""Create a dictionary with all metadata for the nav.xhtml file
|
"""Create a dictionary with all metadata for the nav.xhtml file
|
||||||
properly escaped.
|
properly escaped.
|
||||||
"""
|
"""
|
||||||
metadata: Dict = {}
|
metadata = {}
|
||||||
metadata['lang'] = html.escape(self.config.epub_language)
|
metadata['lang'] = html.escape(self.config.epub_language)
|
||||||
metadata['toc_locale'] = html.escape(self.guide_titles['toc'])
|
metadata['toc_locale'] = html.escape(self.guide_titles['toc'])
|
||||||
metadata['navlist'] = navlist
|
metadata['navlist'] = navlist
|
||||||
@ -217,7 +217,7 @@ def validate_config_values(app: Sphinx) -> None:
|
|||||||
|
|
||||||
def convert_epub_css_files(app: Sphinx, config: Config) -> None:
|
def convert_epub_css_files(app: Sphinx, config: Config) -> None:
|
||||||
"""This converts string styled epub_css_files to tuple styled one."""
|
"""This converts string styled epub_css_files to tuple styled one."""
|
||||||
epub_css_files: List[Tuple[str, Dict]] = []
|
epub_css_files: List[Tuple[str, Dict[str, Any]]] = []
|
||||||
for entry in config.epub_css_files:
|
for entry in config.epub_css_files:
|
||||||
if isinstance(entry, str):
|
if isinstance(entry, str):
|
||||||
epub_css_files.append((entry, {}))
|
epub_css_files.append((entry, {}))
|
||||||
@ -236,7 +236,7 @@ def setup(app: Sphinx) -> Dict[str, Any]:
|
|||||||
app.add_builder(Epub3Builder)
|
app.add_builder(Epub3Builder)
|
||||||
|
|
||||||
# config values
|
# config values
|
||||||
app.add_config_value('epub_basename', lambda self: make_filename(self.project), None)
|
app.add_config_value('epub_basename', lambda self: make_filename(self.project), False)
|
||||||
app.add_config_value('epub_version', 3.0, 'epub') # experimental
|
app.add_config_value('epub_version', 3.0, 'epub') # experimental
|
||||||
app.add_config_value('epub_theme', 'epub', 'epub')
|
app.add_config_value('epub_theme', 'epub', 'epub')
|
||||||
app.add_config_value('epub_theme_options', {}, 'epub')
|
app.add_config_value('epub_theme_options', {}, 'epub')
|
||||||
|
@ -5,7 +5,8 @@ from collections import OrderedDict, defaultdict
|
|||||||
from datetime import datetime, timedelta, tzinfo
|
from datetime import datetime, timedelta, tzinfo
|
||||||
from os import getenv, path, walk
|
from os import getenv, path, walk
|
||||||
from time import time
|
from time import time
|
||||||
from typing import Any, DefaultDict, Dict, Generator, Iterable, List, Set, Tuple, Union
|
from typing import (Any, DefaultDict, Dict, Generator, Iterable, List, Optional, Set, Tuple,
|
||||||
|
Union)
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
@ -78,7 +79,9 @@ class MsgOrigin:
|
|||||||
|
|
||||||
|
|
||||||
class GettextRenderer(SphinxRenderer):
|
class GettextRenderer(SphinxRenderer):
|
||||||
def __init__(self, template_path: str = None, outdir: str = None) -> None:
|
def __init__(
|
||||||
|
self, template_path: Optional[str] = None, outdir: Optional[str] = None
|
||||||
|
) -> None:
|
||||||
self.outdir = outdir
|
self.outdir = outdir
|
||||||
if template_path is None:
|
if template_path is None:
|
||||||
template_path = path.join(package_dir, 'templates', 'gettext')
|
template_path = path.join(package_dir, 'templates', 'gettext')
|
||||||
@ -93,7 +96,7 @@ class GettextRenderer(SphinxRenderer):
|
|||||||
self.env.filters['e'] = escape
|
self.env.filters['e'] = escape
|
||||||
self.env.filters['escape'] = escape
|
self.env.filters['escape'] = escape
|
||||||
|
|
||||||
def render(self, filename: str, context: Dict) -> str:
|
def render(self, filename: str, context: Dict[str, Any]) -> str:
|
||||||
def _relpath(s: str) -> str:
|
def _relpath(s: str) -> str:
|
||||||
return canon_path(relpath(s, self.outdir))
|
return canon_path(relpath(s, self.outdir))
|
||||||
|
|
||||||
@ -127,7 +130,7 @@ class I18nBuilder(Builder):
|
|||||||
self.tags = I18nTags()
|
self.tags = I18nTags()
|
||||||
self.catalogs: DefaultDict[str, Catalog] = defaultdict(Catalog)
|
self.catalogs: DefaultDict[str, Catalog] = defaultdict(Catalog)
|
||||||
|
|
||||||
def get_target_uri(self, docname: str, typ: str = None) -> str:
|
def get_target_uri(self, docname: str, typ: Optional[str] = None) -> str:
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
def get_outdated_docs(self) -> Set[str]:
|
def get_outdated_docs(self) -> Set[str]:
|
||||||
@ -179,10 +182,10 @@ class LocalTimeZone(tzinfo):
|
|||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
self.tzdelta = tzdelta
|
self.tzdelta = tzdelta
|
||||||
|
|
||||||
def utcoffset(self, dt: datetime) -> timedelta:
|
def utcoffset(self, dt: Optional[datetime]) -> timedelta:
|
||||||
return self.tzdelta
|
return self.tzdelta
|
||||||
|
|
||||||
def dst(self, dt: datetime) -> timedelta:
|
def dst(self, dt: Optional[datetime]) -> timedelta:
|
||||||
return timedelta(0)
|
return timedelta(0)
|
||||||
|
|
||||||
|
|
||||||
@ -249,7 +252,9 @@ class MessageCatalogBuilder(I18nBuilder):
|
|||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
raise ThemeError('%s: %r' % (template, exc)) from exc
|
raise ThemeError('%s: %r' % (template, exc)) from exc
|
||||||
|
|
||||||
def build(self, docnames: Iterable[str], summary: str = None, method: str = 'update') -> None: # NOQA
|
def build(
|
||||||
|
self, docnames: Iterable[str], summary: Optional[str] = None, method: str = 'update'
|
||||||
|
) -> None:
|
||||||
self._extract_from_template()
|
self._extract_from_template()
|
||||||
super().build(docnames, summary, method)
|
super().build(docnames, summary, method)
|
||||||
|
|
||||||
|
@ -818,7 +818,7 @@ class StandaloneHTMLBuilder(Builder):
|
|||||||
if jsfile:
|
if jsfile:
|
||||||
copyfile(jsfile, path.join(self.outdir, '_static', '_stemmer.js'))
|
copyfile(jsfile, path.join(self.outdir, '_static', '_stemmer.js'))
|
||||||
|
|
||||||
def copy_theme_static_files(self, context: Dict) -> None:
|
def copy_theme_static_files(self, context: Dict[str, Any]) -> None:
|
||||||
def onerror(filename: str, error: Exception) -> None:
|
def onerror(filename: str, error: Exception) -> None:
|
||||||
logger.warning(__('Failed to copy a file in html_static_file: %s: %r'),
|
logger.warning(__('Failed to copy a file in html_static_file: %s: %r'),
|
||||||
filename, error)
|
filename, error)
|
||||||
|
@ -4,6 +4,7 @@ import json
|
|||||||
import re
|
import re
|
||||||
import socket
|
import socket
|
||||||
import time
|
import time
|
||||||
|
from copy import deepcopy
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
from email.utils import parsedate_to_datetime
|
from email.utils import parsedate_to_datetime
|
||||||
from html.parser import HTMLParser
|
from html.parser import HTMLParser
|
||||||
@ -117,7 +118,7 @@ class CheckExternalLinksBuilder(DummyBuilder):
|
|||||||
socket.setdefaulttimeout(5.0)
|
socket.setdefaulttimeout(5.0)
|
||||||
|
|
||||||
def process_result(self, result: CheckResult) -> None:
|
def process_result(self, result: CheckResult) -> None:
|
||||||
filename = self.env.doc2path(result.docname, None)
|
filename = self.env.doc2path(result.docname, False)
|
||||||
|
|
||||||
linkstat = {"filename": filename, "lineno": result.lineno,
|
linkstat = {"filename": filename, "lineno": result.lineno,
|
||||||
"status": result.status, "code": result.code, "uri": result.uri,
|
"status": result.status, "code": result.code, "uri": result.uri,
|
||||||
@ -202,7 +203,7 @@ class HyperlinkAvailabilityChecker:
|
|||||||
self.rate_limits: Dict[str, RateLimit] = {}
|
self.rate_limits: Dict[str, RateLimit] = {}
|
||||||
self.rqueue: Queue = Queue()
|
self.rqueue: Queue = Queue()
|
||||||
self.workers: List[Thread] = []
|
self.workers: List[Thread] = []
|
||||||
self.wqueue: PriorityQueue = PriorityQueue()
|
self.wqueue: PriorityQueue[CheckRequest] = PriorityQueue()
|
||||||
|
|
||||||
self.to_ignore = [re.compile(x) for x in self.config.linkcheck_ignore]
|
self.to_ignore = [re.compile(x) for x in self.config.linkcheck_ignore]
|
||||||
|
|
||||||
@ -267,7 +268,7 @@ class HyperlinkAvailabilityCheckWorker(Thread):
|
|||||||
if self.config.linkcheck_timeout:
|
if self.config.linkcheck_timeout:
|
||||||
kwargs['timeout'] = self.config.linkcheck_timeout
|
kwargs['timeout'] = self.config.linkcheck_timeout
|
||||||
|
|
||||||
def get_request_headers() -> Dict:
|
def get_request_headers() -> Dict[str, str]:
|
||||||
url = urlparse(uri)
|
url = urlparse(uri)
|
||||||
candidates = ["%s://%s" % (url.scheme, url.netloc),
|
candidates = ["%s://%s" % (url.scheme, url.netloc),
|
||||||
"%s://%s/" % (url.scheme, url.netloc),
|
"%s://%s/" % (url.scheme, url.netloc),
|
||||||
@ -276,7 +277,7 @@ class HyperlinkAvailabilityCheckWorker(Thread):
|
|||||||
|
|
||||||
for u in candidates:
|
for u in candidates:
|
||||||
if u in self.config.linkcheck_request_headers:
|
if u in self.config.linkcheck_request_headers:
|
||||||
headers = dict(DEFAULT_REQUEST_HEADERS)
|
headers = deepcopy(DEFAULT_REQUEST_HEADERS)
|
||||||
headers.update(self.config.linkcheck_request_headers[u])
|
headers.update(self.config.linkcheck_request_headers[u])
|
||||||
return headers
|
return headers
|
||||||
|
|
||||||
@ -561,19 +562,19 @@ def setup(app: Sphinx) -> Dict[str, Any]:
|
|||||||
app.add_builder(CheckExternalLinksBuilder)
|
app.add_builder(CheckExternalLinksBuilder)
|
||||||
app.add_post_transform(HyperlinkCollector)
|
app.add_post_transform(HyperlinkCollector)
|
||||||
|
|
||||||
app.add_config_value('linkcheck_ignore', [], None)
|
app.add_config_value('linkcheck_ignore', [], False)
|
||||||
app.add_config_value('linkcheck_exclude_documents', [], None)
|
app.add_config_value('linkcheck_exclude_documents', [], False)
|
||||||
app.add_config_value('linkcheck_allowed_redirects', {}, None)
|
app.add_config_value('linkcheck_allowed_redirects', {}, False)
|
||||||
app.add_config_value('linkcheck_auth', [], None)
|
app.add_config_value('linkcheck_auth', [], False)
|
||||||
app.add_config_value('linkcheck_request_headers', {}, None)
|
app.add_config_value('linkcheck_request_headers', {}, False)
|
||||||
app.add_config_value('linkcheck_retries', 1, None)
|
app.add_config_value('linkcheck_retries', 1, False)
|
||||||
app.add_config_value('linkcheck_timeout', None, None, [int])
|
app.add_config_value('linkcheck_timeout', None, False, [int])
|
||||||
app.add_config_value('linkcheck_workers', 5, None)
|
app.add_config_value('linkcheck_workers', 5, False)
|
||||||
app.add_config_value('linkcheck_anchors', True, None)
|
app.add_config_value('linkcheck_anchors', True, False)
|
||||||
# Anchors starting with ! are ignored since they are
|
# Anchors starting with ! are ignored since they are
|
||||||
# commonly used for dynamic pages
|
# commonly used for dynamic pages
|
||||||
app.add_config_value('linkcheck_anchors_ignore', ["^!"], None)
|
app.add_config_value('linkcheck_anchors_ignore', ["^!"], False)
|
||||||
app.add_config_value('linkcheck_rate_limit_timeout', 300.0, None)
|
app.add_config_value('linkcheck_rate_limit_timeout', 300.0, False)
|
||||||
|
|
||||||
app.add_event('linkcheck-process-uri')
|
app.add_event('linkcheck-process-uri')
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import warnings
|
import warnings
|
||||||
from os import path
|
from os import path
|
||||||
from typing import Any, Dict, List, Set, Tuple, Union
|
from typing import Any, Dict, List, Optional, Set, Tuple, Union
|
||||||
|
|
||||||
from docutils.frontend import OptionParser
|
from docutils.frontend import OptionParser
|
||||||
from docutils.io import FileOutput
|
from docutils.io import FileOutput
|
||||||
@ -40,7 +40,7 @@ class ManualPageBuilder(Builder):
|
|||||||
def get_outdated_docs(self) -> Union[str, List[str]]:
|
def get_outdated_docs(self) -> Union[str, List[str]]:
|
||||||
return 'all manpages' # for now
|
return 'all manpages' # for now
|
||||||
|
|
||||||
def get_target_uri(self, docname: str, typ: str = None) -> str:
|
def get_target_uri(self, docname: str, typ: Optional[str] = None) -> str:
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
@progress_message(__('writing'))
|
@progress_message(__('writing'))
|
||||||
@ -111,9 +111,9 @@ def default_man_pages(config: Config) -> List[Tuple[str, str, str, List[str], in
|
|||||||
def setup(app: Sphinx) -> Dict[str, Any]:
|
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||||
app.add_builder(ManualPageBuilder)
|
app.add_builder(ManualPageBuilder)
|
||||||
|
|
||||||
app.add_config_value('man_pages', default_man_pages, None)
|
app.add_config_value('man_pages', default_man_pages, False)
|
||||||
app.add_config_value('man_show_urls', False, None)
|
app.add_config_value('man_show_urls', False, False)
|
||||||
app.add_config_value('man_make_section_directory', False, None)
|
app.add_config_value('man_make_section_directory', False, False)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'version': 'builtin',
|
'version': 'builtin',
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
"""Single HTML builders."""
|
"""Single HTML builders."""
|
||||||
|
|
||||||
from os import path
|
from os import path
|
||||||
from typing import Any, Dict, List, Tuple, Union
|
from typing import Any, Dict, List, Optional, Tuple, Union
|
||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
from docutils.nodes import Node
|
from docutils.nodes import Node
|
||||||
@ -27,10 +27,10 @@ class SingleFileHTMLBuilder(StandaloneHTMLBuilder):
|
|||||||
|
|
||||||
copysource = False
|
copysource = False
|
||||||
|
|
||||||
def get_outdated_docs(self) -> Union[str, List[str]]: # type: ignore
|
def get_outdated_docs(self) -> Union[str, List[str]]: # type: ignore[override]
|
||||||
return 'all documents'
|
return 'all documents'
|
||||||
|
|
||||||
def get_target_uri(self, docname: str, typ: str = None) -> str:
|
def get_target_uri(self, docname: str, typ: Optional[str] = None) -> str:
|
||||||
if docname in self.env.all_docs:
|
if docname in self.env.all_docs:
|
||||||
# all references are on the same page...
|
# all references are on the same page...
|
||||||
return self.config.root_doc + self.out_suffix + \
|
return self.config.root_doc + self.out_suffix + \
|
||||||
@ -39,7 +39,7 @@ class SingleFileHTMLBuilder(StandaloneHTMLBuilder):
|
|||||||
# chances are this is a html_additional_page
|
# chances are this is a html_additional_page
|
||||||
return docname + self.out_suffix
|
return docname + self.out_suffix
|
||||||
|
|
||||||
def get_relative_uri(self, from_: str, to: str, typ: str = None) -> str:
|
def get_relative_uri(self, from_: str, to: str, typ: Optional[str] = None) -> str:
|
||||||
# ignore source
|
# ignore source
|
||||||
return self.get_target_uri(to, typ)
|
return self.get_target_uri(to, typ)
|
||||||
|
|
||||||
@ -113,7 +113,7 @@ class SingleFileHTMLBuilder(StandaloneHTMLBuilder):
|
|||||||
|
|
||||||
return {self.config.root_doc: new_fignumbers}
|
return {self.config.root_doc: new_fignumbers}
|
||||||
|
|
||||||
def get_doc_context(self, docname: str, body: str, metatags: str) -> Dict:
|
def get_doc_context(self, docname: str, body: str, metatags: str) -> Dict[str, Any]:
|
||||||
# no relation links...
|
# no relation links...
|
||||||
toctree = TocTree(self.env).get_toctree_for(self.config.root_doc, self, False)
|
toctree = TocTree(self.env).get_toctree_for(self.config.root_doc, self, False)
|
||||||
# if there is no toctree, toc is None
|
# if there is no toctree, toc is None
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
import os
|
import os
|
||||||
import warnings
|
import warnings
|
||||||
from os import path
|
from os import path
|
||||||
from typing import Any, Dict, Iterable, List, Tuple, Union
|
from typing import Any, Dict, Iterable, List, Optional, Tuple, Union
|
||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
from docutils.frontend import OptionParser
|
from docutils.frontend import OptionParser
|
||||||
@ -52,13 +52,13 @@ class TexinfoBuilder(Builder):
|
|||||||
def get_outdated_docs(self) -> Union[str, List[str]]:
|
def get_outdated_docs(self) -> Union[str, List[str]]:
|
||||||
return 'all documents' # for now
|
return 'all documents' # for now
|
||||||
|
|
||||||
def get_target_uri(self, docname: str, typ: str = None) -> str:
|
def get_target_uri(self, docname: str, typ: Optional[str] = None) -> str:
|
||||||
if docname not in self.docnames:
|
if docname not in self.docnames:
|
||||||
raise NoUri(docname, typ)
|
raise NoUri(docname, typ)
|
||||||
else:
|
else:
|
||||||
return '%' + docname
|
return '%' + docname
|
||||||
|
|
||||||
def get_relative_uri(self, from_: str, to: str, typ: str = None) -> str:
|
def get_relative_uri(self, from_: str, to: str, typ: Optional[str] = None) -> str:
|
||||||
# ignore source path
|
# ignore source path
|
||||||
return self.get_target_uri(to, typ)
|
return self.get_target_uri(to, typ)
|
||||||
|
|
||||||
@ -202,13 +202,13 @@ def default_texinfo_documents(config: Config) -> List[Tuple[str, str, str, str,
|
|||||||
def setup(app: Sphinx) -> Dict[str, Any]:
|
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||||
app.add_builder(TexinfoBuilder)
|
app.add_builder(TexinfoBuilder)
|
||||||
|
|
||||||
app.add_config_value('texinfo_documents', default_texinfo_documents, None)
|
app.add_config_value('texinfo_documents', default_texinfo_documents, False)
|
||||||
app.add_config_value('texinfo_appendices', [], None)
|
app.add_config_value('texinfo_appendices', [], False)
|
||||||
app.add_config_value('texinfo_elements', {}, None)
|
app.add_config_value('texinfo_elements', {}, False)
|
||||||
app.add_config_value('texinfo_domain_indices', True, None, [list])
|
app.add_config_value('texinfo_domain_indices', True, False, [list])
|
||||||
app.add_config_value('texinfo_show_urls', 'footnote', None)
|
app.add_config_value('texinfo_show_urls', 'footnote', False)
|
||||||
app.add_config_value('texinfo_no_detailmenu', False, None)
|
app.add_config_value('texinfo_no_detailmenu', False, False)
|
||||||
app.add_config_value('texinfo_cross_references', True, None)
|
app.add_config_value('texinfo_cross_references', True, False)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'version': 'builtin',
|
'version': 'builtin',
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
"""Plain-text Sphinx builder."""
|
"""Plain-text Sphinx builder."""
|
||||||
|
|
||||||
from os import path
|
from os import path
|
||||||
from typing import Any, Dict, Iterator, Set, Tuple
|
from typing import Any, Dict, Iterator, Optional, Set, Tuple
|
||||||
|
|
||||||
from docutils.io import StringOutput
|
from docutils.io import StringOutput
|
||||||
from docutils.nodes import Node
|
from docutils.nodes import Node
|
||||||
@ -25,7 +25,7 @@ class TextBuilder(Builder):
|
|||||||
allow_parallel = True
|
allow_parallel = True
|
||||||
default_translator_class = TextTranslator
|
default_translator_class = TextTranslator
|
||||||
|
|
||||||
current_docname: str = None
|
current_docname: Optional[str] = None
|
||||||
|
|
||||||
def init(self) -> None:
|
def init(self) -> None:
|
||||||
# section numbers for headings in the currently visited document
|
# section numbers for headings in the currently visited document
|
||||||
@ -49,7 +49,7 @@ class TextBuilder(Builder):
|
|||||||
# source doesn't exist anymore
|
# source doesn't exist anymore
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def get_target_uri(self, docname: str, typ: str = None) -> str:
|
def get_target_uri(self, docname: str, typ: Optional[str] = None) -> str:
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
def prepare_writing(self, docnames: Set[str]) -> None:
|
def prepare_writing(self, docnames: Set[str]) -> None:
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
"""Docutils-native XML and pseudo-XML builders."""
|
"""Docutils-native XML and pseudo-XML builders."""
|
||||||
|
|
||||||
from os import path
|
from os import path
|
||||||
from typing import Any, Dict, Iterator, Set, Type, Union
|
from typing import Any, Dict, Iterator, Optional, Set, Type, Union
|
||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
from docutils.io import StringOutput
|
from docutils.io import StringOutput
|
||||||
@ -53,7 +53,7 @@ class XMLBuilder(Builder):
|
|||||||
# source doesn't exist anymore
|
# source doesn't exist anymore
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def get_target_uri(self, docname: str, typ: str = None) -> str:
|
def get_target_uri(self, docname: str, typ: Optional[str] = None) -> str:
|
||||||
return docname
|
return docname
|
||||||
|
|
||||||
def prepare_writing(self, docnames: Set[str]) -> None:
|
def prepare_writing(self, docnames: Set[str]) -> None:
|
||||||
|
@ -183,7 +183,7 @@ class QuickstartRenderer(SphinxRenderer):
|
|||||||
return super().render(template_name, context)
|
return super().render(template_name, context)
|
||||||
|
|
||||||
|
|
||||||
def ask_user(d: Dict) -> None:
|
def ask_user(d: Dict[str, Any]) -> None:
|
||||||
"""Ask the user for quickstart values missing from *d*.
|
"""Ask the user for quickstart values missing from *d*.
|
||||||
|
|
||||||
Values are:
|
Values are:
|
||||||
|
@ -158,7 +158,9 @@ class Config:
|
|||||||
self.extensions: List[str] = config.get('extensions', [])
|
self.extensions: List[str] = config.get('extensions', [])
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def read(cls, confdir: str, overrides: Dict = None, tags: Tags = None) -> "Config":
|
def read(
|
||||||
|
cls, confdir: str, overrides: Optional[Dict] = None, tags: Optional[Tags] = None
|
||||||
|
) -> "Config":
|
||||||
"""Create a Config object from configuration file."""
|
"""Create a Config object from configuration file."""
|
||||||
filename = path.join(confdir, CONFIG_FILENAME)
|
filename = path.join(confdir, CONFIG_FILENAME)
|
||||||
if not path.isfile(filename):
|
if not path.isfile(filename):
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import sys
|
import sys
|
||||||
import textwrap
|
import textwrap
|
||||||
from difflib import unified_diff
|
from difflib import unified_diff
|
||||||
from typing import TYPE_CHECKING, Any, Dict, List, Tuple
|
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple
|
||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
from docutils.nodes import Element, Node
|
from docutils.nodes import Element, Node
|
||||||
@ -48,7 +48,9 @@ class Highlight(SphinxDirective):
|
|||||||
linenothreshold=linenothreshold)]
|
linenothreshold=linenothreshold)]
|
||||||
|
|
||||||
|
|
||||||
def dedent_lines(lines: List[str], dedent: int, location: Tuple[str, int] = None) -> List[str]:
|
def dedent_lines(
|
||||||
|
lines: List[str], dedent: Optional[int], location: Optional[Tuple[str, int]] = None
|
||||||
|
) -> List[str]:
|
||||||
if dedent is None:
|
if dedent is None:
|
||||||
return textwrap.dedent(''.join(lines)).splitlines(True)
|
return textwrap.dedent(''.join(lines)).splitlines(True)
|
||||||
|
|
||||||
@ -186,7 +188,7 @@ class LiteralIncludeReader:
|
|||||||
('diff', 'end-at'),
|
('diff', 'end-at'),
|
||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self, filename: str, options: Dict, config: Config) -> None:
|
def __init__(self, filename: str, options: Dict[str, Any], config: Config) -> None:
|
||||||
self.filename = filename
|
self.filename = filename
|
||||||
self.options = options
|
self.options = options
|
||||||
self.encoding = options.get('encoding', config.source_encoding)
|
self.encoding = options.get('encoding', config.source_encoding)
|
||||||
@ -200,7 +202,9 @@ class LiteralIncludeReader:
|
|||||||
raise ValueError(__('Cannot use both "%s" and "%s" options') %
|
raise ValueError(__('Cannot use both "%s" and "%s" options') %
|
||||||
(option1, option2))
|
(option1, option2))
|
||||||
|
|
||||||
def read_file(self, filename: str, location: Tuple[str, int] = None) -> List[str]:
|
def read_file(
|
||||||
|
self, filename: str, location: Optional[Tuple[str, int]] = None
|
||||||
|
) -> List[str]:
|
||||||
try:
|
try:
|
||||||
with open(filename, encoding=self.encoding, errors='strict') as f:
|
with open(filename, encoding=self.encoding, errors='strict') as f:
|
||||||
text = f.read()
|
text = f.read()
|
||||||
@ -216,7 +220,7 @@ class LiteralIncludeReader:
|
|||||||
'be wrong, try giving an :encoding: option') %
|
'be wrong, try giving an :encoding: option') %
|
||||||
(self.encoding, filename)) from exc
|
(self.encoding, filename)) from exc
|
||||||
|
|
||||||
def read(self, location: Tuple[str, int] = None) -> Tuple[str, int]:
|
def read(self, location: Optional[Tuple[str, int]] = None) -> Tuple[str, int]:
|
||||||
if 'diff' in self.options:
|
if 'diff' in self.options:
|
||||||
lines = self.show_diff()
|
lines = self.show_diff()
|
||||||
else:
|
else:
|
||||||
@ -233,14 +237,16 @@ class LiteralIncludeReader:
|
|||||||
|
|
||||||
return ''.join(lines), len(lines)
|
return ''.join(lines), len(lines)
|
||||||
|
|
||||||
def show_diff(self, location: Tuple[str, int] = None) -> List[str]:
|
def show_diff(self, location: Optional[Tuple[str, int]] = None) -> List[str]:
|
||||||
new_lines = self.read_file(self.filename)
|
new_lines = self.read_file(self.filename)
|
||||||
old_filename = self.options.get('diff')
|
old_filename = self.options.get('diff')
|
||||||
old_lines = self.read_file(old_filename)
|
old_lines = self.read_file(old_filename)
|
||||||
diff = unified_diff(old_lines, new_lines, old_filename, self.filename)
|
diff = unified_diff(old_lines, new_lines, old_filename, self.filename)
|
||||||
return list(diff)
|
return list(diff)
|
||||||
|
|
||||||
def pyobject_filter(self, lines: List[str], location: Tuple[str, int] = None) -> List[str]:
|
def pyobject_filter(
|
||||||
|
self, lines: List[str], location: Optional[Tuple[str, int]] = None
|
||||||
|
) -> List[str]:
|
||||||
pyobject = self.options.get('pyobject')
|
pyobject = self.options.get('pyobject')
|
||||||
if pyobject:
|
if pyobject:
|
||||||
from sphinx.pycode import ModuleAnalyzer
|
from sphinx.pycode import ModuleAnalyzer
|
||||||
@ -258,7 +264,9 @@ class LiteralIncludeReader:
|
|||||||
|
|
||||||
return lines
|
return lines
|
||||||
|
|
||||||
def lines_filter(self, lines: List[str], location: Tuple[str, int] = None) -> List[str]:
|
def lines_filter(
|
||||||
|
self, lines: List[str], location: Optional[Tuple[str, int]] = None
|
||||||
|
) -> List[str]:
|
||||||
linespec = self.options.get('lines')
|
linespec = self.options.get('lines')
|
||||||
if linespec:
|
if linespec:
|
||||||
linelist = parselinenos(linespec, len(lines))
|
linelist = parselinenos(linespec, len(lines))
|
||||||
@ -282,7 +290,9 @@ class LiteralIncludeReader:
|
|||||||
|
|
||||||
return lines
|
return lines
|
||||||
|
|
||||||
def start_filter(self, lines: List[str], location: Tuple[str, int] = None) -> List[str]:
|
def start_filter(
|
||||||
|
self, lines: List[str], location: Optional[Tuple[str, int]] = None
|
||||||
|
) -> List[str]:
|
||||||
if 'start-at' in self.options:
|
if 'start-at' in self.options:
|
||||||
start = self.options.get('start-at')
|
start = self.options.get('start-at')
|
||||||
inclusive = False
|
inclusive = False
|
||||||
@ -313,7 +323,9 @@ class LiteralIncludeReader:
|
|||||||
|
|
||||||
return lines
|
return lines
|
||||||
|
|
||||||
def end_filter(self, lines: List[str], location: Tuple[str, int] = None) -> List[str]:
|
def end_filter(
|
||||||
|
self, lines: List[str], location: Optional[Tuple[str, int]] = None
|
||||||
|
) -> List[str]:
|
||||||
if 'end-at' in self.options:
|
if 'end-at' in self.options:
|
||||||
end = self.options.get('end-at')
|
end = self.options.get('end-at')
|
||||||
inclusive = True
|
inclusive = True
|
||||||
@ -340,21 +352,27 @@ class LiteralIncludeReader:
|
|||||||
|
|
||||||
return lines
|
return lines
|
||||||
|
|
||||||
def prepend_filter(self, lines: List[str], location: Tuple[str, int] = None) -> List[str]:
|
def prepend_filter(
|
||||||
|
self, lines: List[str], location: Optional[Tuple[str, int]] = None
|
||||||
|
) -> List[str]:
|
||||||
prepend = self.options.get('prepend')
|
prepend = self.options.get('prepend')
|
||||||
if prepend:
|
if prepend:
|
||||||
lines.insert(0, prepend + '\n')
|
lines.insert(0, prepend + '\n')
|
||||||
|
|
||||||
return lines
|
return lines
|
||||||
|
|
||||||
def append_filter(self, lines: List[str], location: Tuple[str, int] = None) -> List[str]:
|
def append_filter(
|
||||||
|
self, lines: List[str], location: Optional[Tuple[str, int]] = None
|
||||||
|
) -> List[str]:
|
||||||
append = self.options.get('append')
|
append = self.options.get('append')
|
||||||
if append:
|
if append:
|
||||||
lines.append(append + '\n')
|
lines.append(append + '\n')
|
||||||
|
|
||||||
return lines
|
return lines
|
||||||
|
|
||||||
def dedent_filter(self, lines: List[str], location: Tuple[str, int] = None) -> List[str]:
|
def dedent_filter(
|
||||||
|
self, lines: List[str], location: Optional[Tuple[str, int]] = None
|
||||||
|
) -> List[str]:
|
||||||
if 'dedent' in self.options:
|
if 'dedent' in self.options:
|
||||||
return dedent_lines(lines, self.options.get('dedent'), location=location)
|
return dedent_lines(lines, self.options.get('dedent'), location=location)
|
||||||
else:
|
else:
|
||||||
|
@ -119,7 +119,7 @@ class TocTree(SphinxDirective):
|
|||||||
if url_re.match(ref) or ref == 'self':
|
if url_re.match(ref) or ref == 'self':
|
||||||
toctree['entries'].append((title, ref))
|
toctree['entries'].append((title, ref))
|
||||||
elif docname not in self.env.found_docs:
|
elif docname not in self.env.found_docs:
|
||||||
if excluded(self.env.doc2path(docname, None)):
|
if excluded(self.env.doc2path(docname, False)):
|
||||||
message = __('toctree contains reference to excluded document %r')
|
message = __('toctree contains reference to excluded document %r')
|
||||||
subtype = 'excluded'
|
subtype = 'excluded'
|
||||||
else:
|
else:
|
||||||
|
@ -97,8 +97,8 @@ def parse_reftarget(reftarget: str, suppress_prefix: bool = False
|
|||||||
return reftype, reftarget, title, refspecific
|
return reftype, reftarget, title, refspecific
|
||||||
|
|
||||||
|
|
||||||
def type_to_xref(target: str, env: BuildEnvironment = None, suppress_prefix: bool = False
|
def type_to_xref(target: str, env: Optional[BuildEnvironment] = None,
|
||||||
) -> addnodes.pending_xref:
|
suppress_prefix: bool = False) -> addnodes.pending_xref:
|
||||||
"""Convert a type string to a cross reference node."""
|
"""Convert a type string to a cross reference node."""
|
||||||
if env:
|
if env:
|
||||||
kwargs = {'py:module': env.ref_context.get('py:module'),
|
kwargs = {'py:module': env.ref_context.get('py:module'),
|
||||||
@ -237,7 +237,9 @@ def _parse_annotation(annotation: str, env: BuildEnvironment) -> List[Node]:
|
|||||||
return [type_to_xref(annotation, env)]
|
return [type_to_xref(annotation, env)]
|
||||||
|
|
||||||
|
|
||||||
def _parse_arglist(arglist: str, env: BuildEnvironment = None) -> addnodes.desc_parameterlist:
|
def _parse_arglist(
|
||||||
|
arglist: str, env: Optional[BuildEnvironment] = None
|
||||||
|
) -> addnodes.desc_parameterlist:
|
||||||
"""Parse a list of arguments using AST parser"""
|
"""Parse a list of arguments using AST parser"""
|
||||||
params = addnodes.desc_parameterlist(arglist)
|
params = addnodes.desc_parameterlist(arglist)
|
||||||
sig = signature_from_str('(%s)' % arglist)
|
sig = signature_from_str('(%s)' % arglist)
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
import re
|
import re
|
||||||
import unicodedata
|
import unicodedata
|
||||||
from itertools import groupby
|
from itertools import groupby
|
||||||
from typing import Any, Dict, List, Pattern, Tuple, cast
|
from typing import Any, Dict, List, Optional, Pattern, Tuple, cast
|
||||||
|
|
||||||
from sphinx.builders import Builder
|
from sphinx.builders import Builder
|
||||||
from sphinx.domains.index import IndexDomain
|
from sphinx.domains.index import IndexDomain
|
||||||
@ -26,7 +26,7 @@ class IndexEntries:
|
|||||||
new: Dict[str, List] = {}
|
new: Dict[str, List] = {}
|
||||||
|
|
||||||
def add_entry(word: str, subword: str, main: str, link: bool = True,
|
def add_entry(word: str, subword: str, main: str, link: bool = True,
|
||||||
dic: Dict = new, key: str = None) -> None:
|
dic: Dict[str, List] = new, key: Optional[str] = None) -> None:
|
||||||
# Force the word to be unicode if it's a ASCII bytestring.
|
# Force the word to be unicode if it's a ASCII bytestring.
|
||||||
# This will solve problems with unicode normalization later.
|
# This will solve problems with unicode normalization later.
|
||||||
# For instance the RFC role will add bytestrings at the moment
|
# For instance the RFC role will add bytestrings at the moment
|
||||||
@ -118,7 +118,7 @@ class IndexEntries:
|
|||||||
# (in module foo)
|
# (in module foo)
|
||||||
# (in module bar)
|
# (in module bar)
|
||||||
oldkey = ''
|
oldkey = ''
|
||||||
oldsubitems: Dict[str, List] = None
|
oldsubitems: Optional[Dict[str, List]] = None
|
||||||
i = 0
|
i = 0
|
||||||
while i < len(newlist):
|
while i < len(newlist):
|
||||||
key, (targets, subitems, _key) = newlist[i]
|
key, (targets, subitems, _key) = newlist[i]
|
||||||
|
@ -164,7 +164,7 @@ class TocTree:
|
|||||||
ref, location=toctreenode)
|
ref, location=toctreenode)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
# this is raised if the included file does not exist
|
# this is raised if the included file does not exist
|
||||||
if excluded(self.env.doc2path(ref, None)):
|
if excluded(self.env.doc2path(ref, False)):
|
||||||
message = __('toctree contains reference to excluded document %r')
|
message = __('toctree contains reference to excluded document %r')
|
||||||
else:
|
else:
|
||||||
message = __('toctree contains reference to nonexisting document %r')
|
message = __('toctree contains reference to nonexisting document %r')
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
"""Contains SphinxError and a few subclasses."""
|
"""Contains SphinxError and a few subclasses."""
|
||||||
|
|
||||||
from typing import Any
|
from typing import Any, Optional
|
||||||
|
|
||||||
|
|
||||||
class SphinxError(Exception):
|
class SphinxError(Exception):
|
||||||
@ -39,7 +39,9 @@ class ApplicationError(SphinxError):
|
|||||||
class ExtensionError(SphinxError):
|
class ExtensionError(SphinxError):
|
||||||
"""Extension error."""
|
"""Extension error."""
|
||||||
|
|
||||||
def __init__(self, message: str, orig_exc: Exception = None, modname: str = None) -> None:
|
def __init__(
|
||||||
|
self, message: str, orig_exc: Optional[Exception] = None, modname: Optional[str] = None
|
||||||
|
) -> None:
|
||||||
super().__init__(message)
|
super().__init__(message)
|
||||||
self.message = message
|
self.message = message
|
||||||
self.orig_exc = orig_exc
|
self.orig_exc = orig_exc
|
||||||
|
@ -18,7 +18,7 @@ from copy import copy
|
|||||||
from fnmatch import fnmatch
|
from fnmatch import fnmatch
|
||||||
from importlib.machinery import EXTENSION_SUFFIXES
|
from importlib.machinery import EXTENSION_SUFFIXES
|
||||||
from os import path
|
from os import path
|
||||||
from typing import Any, Generator, List, Tuple
|
from typing import Any, Generator, List, Optional, Tuple
|
||||||
|
|
||||||
import sphinx.locale
|
import sphinx.locale
|
||||||
from sphinx import __display_version__, package_dir
|
from sphinx import __display_version__, package_dir
|
||||||
@ -58,7 +58,7 @@ def module_join(*modnames: str) -> str:
|
|||||||
return '.'.join(filter(None, modnames))
|
return '.'.join(filter(None, modnames))
|
||||||
|
|
||||||
|
|
||||||
def is_packagedir(dirname: str = None, files: List[str] = None) -> bool:
|
def is_packagedir(dirname: Optional[str] = None, files: Optional[List[str]] = None) -> bool:
|
||||||
"""Check given *files* contains __init__ file."""
|
"""Check given *files* contains __init__ file."""
|
||||||
if files is None and dirname is None:
|
if files is None and dirname is None:
|
||||||
return False
|
return False
|
||||||
@ -88,7 +88,7 @@ def write_file(name: str, text: str, opts: Any) -> None:
|
|||||||
|
|
||||||
|
|
||||||
def create_module_file(package: str, basename: str, opts: Any,
|
def create_module_file(package: str, basename: str, opts: Any,
|
||||||
user_template_dir: str = None) -> None:
|
user_template_dir: Optional[str] = None) -> None:
|
||||||
"""Build the text of the file and write the file."""
|
"""Build the text of the file and write the file."""
|
||||||
options = copy(OPTIONS)
|
options = copy(OPTIONS)
|
||||||
if opts.includeprivate and 'private-members' not in options:
|
if opts.includeprivate and 'private-members' not in options:
|
||||||
@ -107,7 +107,8 @@ def create_module_file(package: str, basename: str, opts: Any,
|
|||||||
|
|
||||||
def create_package_file(root: str, master_package: str, subroot: str, py_files: List[str],
|
def create_package_file(root: str, master_package: str, subroot: str, py_files: List[str],
|
||||||
opts: Any, subs: List[str], is_namespace: bool,
|
opts: Any, subs: List[str], is_namespace: bool,
|
||||||
excludes: List[str] = [], user_template_dir: str = None) -> None:
|
excludes: List[str] = [], user_template_dir: Optional[str] = None
|
||||||
|
) -> None:
|
||||||
"""Build the text of the file and write the file."""
|
"""Build the text of the file and write the file."""
|
||||||
# build a list of sub packages (directories containing an __init__ file)
|
# build a list of sub packages (directories containing an __init__ file)
|
||||||
subpackages = [module_join(master_package, subroot, pkgname)
|
subpackages = [module_join(master_package, subroot, pkgname)
|
||||||
@ -145,7 +146,7 @@ def create_package_file(root: str, master_package: str, subroot: str, py_files:
|
|||||||
|
|
||||||
|
|
||||||
def create_modules_toc_file(modules: List[str], opts: Any, name: str = 'modules',
|
def create_modules_toc_file(modules: List[str], opts: Any, name: str = 'modules',
|
||||||
user_template_dir: str = None) -> None:
|
user_template_dir: Optional[str] = None) -> None:
|
||||||
"""Create the module's index."""
|
"""Create the module's index."""
|
||||||
modules.sort()
|
modules.sort()
|
||||||
prev_module = ''
|
prev_module = ''
|
||||||
@ -231,7 +232,7 @@ def has_child_module(rootpath: str, excludes: List[str], opts: Any) -> bool:
|
|||||||
|
|
||||||
|
|
||||||
def recurse_tree(rootpath: str, excludes: List[str], opts: Any,
|
def recurse_tree(rootpath: str, excludes: List[str], opts: Any,
|
||||||
user_template_dir: str = None) -> List[str]:
|
user_template_dir: Optional[str] = None) -> List[str]:
|
||||||
"""
|
"""
|
||||||
Look for every file in the directory tree and create the corresponding
|
Look for every file in the directory tree and create the corresponding
|
||||||
ReST files.
|
ReST files.
|
||||||
|
@ -31,7 +31,6 @@ from sphinx.util.typing import stringify as stringify_typehint
|
|||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from sphinx.ext.autodoc.directive import DocumenterBridge
|
from sphinx.ext.autodoc.directive import DocumenterBridge
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@ -1655,7 +1654,7 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
|
|||||||
return False, [] # type: ignore
|
return False, [] # type: ignore
|
||||||
# specific members given
|
# specific members given
|
||||||
selected = []
|
selected = []
|
||||||
for name in self.options.members: # type: str
|
for name in self.options.members:
|
||||||
if name in members:
|
if name in members:
|
||||||
selected.append(members[name])
|
selected.append(members[name])
|
||||||
else:
|
else:
|
||||||
|
@ -73,6 +73,7 @@ from sphinx.ext.autodoc import INSTANCEATTR, Documenter
|
|||||||
from sphinx.ext.autodoc.directive import DocumenterBridge, Options
|
from sphinx.ext.autodoc.directive import DocumenterBridge, Options
|
||||||
from sphinx.ext.autodoc.importer import import_module
|
from sphinx.ext.autodoc.importer import import_module
|
||||||
from sphinx.ext.autodoc.mock import mock
|
from sphinx.ext.autodoc.mock import mock
|
||||||
|
from sphinx.extension import Extension
|
||||||
from sphinx.locale import __
|
from sphinx.locale import __
|
||||||
from sphinx.project import Project
|
from sphinx.project import Project
|
||||||
from sphinx.pycode import ModuleAnalyzer, PycodeError
|
from sphinx.pycode import ModuleAnalyzer, PycodeError
|
||||||
@ -136,10 +137,10 @@ def autosummary_table_visit_html(self: HTMLTranslator, node: autosummary_table)
|
|||||||
# -- autodoc integration -------------------------------------------------------
|
# -- autodoc integration -------------------------------------------------------
|
||||||
|
|
||||||
class FakeApplication:
|
class FakeApplication:
|
||||||
def __init__(self):
|
def __init__(self) -> None:
|
||||||
self.doctreedir = None
|
self.doctreedir = None
|
||||||
self.events = None
|
self.events = None
|
||||||
self.extensions = {}
|
self.extensions: Dict[str, Extension] = {}
|
||||||
self.srcdir = None
|
self.srcdir = None
|
||||||
self.config = Config()
|
self.config = Config()
|
||||||
self.project = Project(None, None)
|
self.project = Project(None, None)
|
||||||
@ -234,7 +235,7 @@ class Autosummary(SphinxDirective):
|
|||||||
docname = posixpath.join(tree_prefix, real_name)
|
docname = posixpath.join(tree_prefix, real_name)
|
||||||
docname = posixpath.normpath(posixpath.join(dirname, docname))
|
docname = posixpath.normpath(posixpath.join(dirname, docname))
|
||||||
if docname not in self.env.found_docs:
|
if docname not in self.env.found_docs:
|
||||||
if excluded(self.env.doc2path(docname, None)):
|
if excluded(self.env.doc2path(docname, False)):
|
||||||
msg = __('autosummary references excluded document %r. Ignored.')
|
msg = __('autosummary references excluded document %r. Ignored.')
|
||||||
else:
|
else:
|
||||||
msg = __('autosummary: stub file not found %r. '
|
msg = __('autosummary: stub file not found %r. '
|
||||||
|
@ -24,12 +24,12 @@ logger = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
# utility
|
# utility
|
||||||
def write_header(f: IO, text: str, char: str = '-') -> None:
|
def write_header(f: IO[str], text: str, char: str = '-') -> None:
|
||||||
f.write(text + '\n')
|
f.write(text + '\n')
|
||||||
f.write(char * len(text) + '\n')
|
f.write(char * len(text) + '\n')
|
||||||
|
|
||||||
|
|
||||||
def compile_regex_list(name: str, exps: str) -> List[Pattern]:
|
def compile_regex_list(name: str, exps: str) -> List[Pattern[str]]:
|
||||||
lst = []
|
lst = []
|
||||||
for exp in exps:
|
for exp in exps:
|
||||||
try:
|
try:
|
||||||
@ -53,14 +53,14 @@ class CoverageBuilder(Builder):
|
|||||||
pattern = path.join(self.srcdir, pattern)
|
pattern = path.join(self.srcdir, pattern)
|
||||||
self.c_sourcefiles.extend(glob.glob(pattern))
|
self.c_sourcefiles.extend(glob.glob(pattern))
|
||||||
|
|
||||||
self.c_regexes: List[Tuple[str, Pattern]] = []
|
self.c_regexes: List[Tuple[str, Pattern[str]]] = []
|
||||||
for (name, exp) in self.config.coverage_c_regexes.items():
|
for (name, exp) in self.config.coverage_c_regexes.items():
|
||||||
try:
|
try:
|
||||||
self.c_regexes.append((name, re.compile(exp)))
|
self.c_regexes.append((name, re.compile(exp)))
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.warning(__('invalid regex %r in coverage_c_regexes'), exp)
|
logger.warning(__('invalid regex %r in coverage_c_regexes'), exp)
|
||||||
|
|
||||||
self.c_ignorexps: Dict[str, List[Pattern]] = {}
|
self.c_ignorexps: Dict[str, List[Pattern[str]]] = {}
|
||||||
for (name, exps) in self.config.coverage_ignore_c_items.items():
|
for (name, exps) in self.config.coverage_ignore_c_items.items():
|
||||||
self.c_ignorexps[name] = compile_regex_list('coverage_ignore_c_items',
|
self.c_ignorexps[name] = compile_regex_list('coverage_ignore_c_items',
|
||||||
exps)
|
exps)
|
||||||
|
@ -9,8 +9,8 @@ import sys
|
|||||||
import time
|
import time
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
from os import path
|
from os import path
|
||||||
from typing import (TYPE_CHECKING, Any, Callable, Dict, Iterable, List, Sequence, Set, Tuple,
|
from typing import (TYPE_CHECKING, Any, Callable, Dict, Iterable, List, Optional, Sequence,
|
||||||
Type)
|
Set, Tuple, Type)
|
||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
from docutils.nodes import Element, Node, TextElement
|
from docutils.nodes import Element, Node, TextElement
|
||||||
@ -225,7 +225,7 @@ class TestGroup:
|
|||||||
|
|
||||||
class TestCode:
|
class TestCode:
|
||||||
def __init__(self, code: str, type: str, filename: str,
|
def __init__(self, code: str, type: str, filename: str,
|
||||||
lineno: int, options: Dict = None) -> None:
|
lineno: int, options: Optional[Dict] = None) -> None:
|
||||||
self.code = code
|
self.code = code
|
||||||
self.type = type
|
self.type = type
|
||||||
self.filename = filename
|
self.filename = filename
|
||||||
@ -317,7 +317,7 @@ class DocTestBuilder(Builder):
|
|||||||
logger.info(text, nonl=True)
|
logger.info(text, nonl=True)
|
||||||
self.outfile.write(text)
|
self.outfile.write(text)
|
||||||
|
|
||||||
def get_target_uri(self, docname: str, typ: str = None) -> str:
|
def get_target_uri(self, docname: str, typ: Optional[str] = None) -> str:
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
def get_outdated_docs(self) -> Set[str]:
|
def get_outdated_docs(self) -> Set[str]:
|
||||||
@ -362,11 +362,11 @@ Doctest summary
|
|||||||
filename = relpath(node.source, self.env.srcdir)\
|
filename = relpath(node.source, self.env.srcdir)\
|
||||||
.rsplit(':docstring of ', maxsplit=1)[0]
|
.rsplit(':docstring of ', maxsplit=1)[0]
|
||||||
except Exception:
|
except Exception:
|
||||||
filename = self.env.doc2path(docname, base=None)
|
filename = self.env.doc2path(docname, False)
|
||||||
return filename
|
return filename
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_line_number(node: Node) -> int:
|
def get_line_number(node: Node) -> Optional[int]:
|
||||||
"""Get the real line number or admit we don't know."""
|
"""Get the real line number or admit we don't know."""
|
||||||
# TODO: Work out how to store or calculate real (file-relative)
|
# TODO: Work out how to store or calculate real (file-relative)
|
||||||
# line numbers for doctest blocks in docstrings.
|
# line numbers for doctest blocks in docstrings.
|
||||||
|
@ -6,7 +6,7 @@ import re
|
|||||||
import subprocess
|
import subprocess
|
||||||
from os import path
|
from os import path
|
||||||
from subprocess import PIPE, CalledProcessError
|
from subprocess import PIPE, CalledProcessError
|
||||||
from typing import Any, Dict, List, Tuple
|
from typing import Any, Dict, List, Optional, Tuple
|
||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
from docutils.nodes import Node
|
from docutils.nodes import Node
|
||||||
@ -210,7 +210,7 @@ class GraphvizSimple(SphinxDirective):
|
|||||||
|
|
||||||
|
|
||||||
def render_dot(self: SphinxTranslator, code: str, options: Dict, format: str,
|
def render_dot(self: SphinxTranslator, code: str, options: Dict, format: str,
|
||||||
prefix: str = 'graphviz', filename: str = None) -> Tuple[str, str]:
|
prefix: str = 'graphviz', filename: Optional[str] = None) -> Tuple[str, str]:
|
||||||
"""Render graphviz code into a PNG or PDF output file."""
|
"""Render graphviz code into a PNG or PDF output file."""
|
||||||
graphviz_dot = options.get('graphviz_dot', self.builder.config.graphviz_dot)
|
graphviz_dot = options.get('graphviz_dot', self.builder.config.graphviz_dot)
|
||||||
hashkey = (code + str(options) + str(graphviz_dot) +
|
hashkey = (code + str(options) + str(graphviz_dot) +
|
||||||
|
@ -7,7 +7,7 @@ import subprocess
|
|||||||
import tempfile
|
import tempfile
|
||||||
from os import path
|
from os import path
|
||||||
from subprocess import PIPE, CalledProcessError
|
from subprocess import PIPE, CalledProcessError
|
||||||
from typing import Any, Dict, List, Tuple
|
from typing import Any, Dict, List, Optional, Tuple
|
||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
from docutils.nodes import Element
|
from docutils.nodes import Element
|
||||||
@ -34,7 +34,9 @@ templates_path = path.join(package_dir, 'templates', 'imgmath')
|
|||||||
class MathExtError(SphinxError):
|
class MathExtError(SphinxError):
|
||||||
category = 'Math extension error'
|
category = 'Math extension error'
|
||||||
|
|
||||||
def __init__(self, msg: str, stderr: str = None, stdout: str = None) -> None:
|
def __init__(
|
||||||
|
self, msg: str, stderr: Optional[str] = None, stdout: Optional[str] = None
|
||||||
|
) -> None:
|
||||||
if stderr:
|
if stderr:
|
||||||
msg += '\n[stderr]\n' + stderr
|
msg += '\n[stderr]\n' + stderr
|
||||||
if stdout:
|
if stdout:
|
||||||
@ -53,7 +55,7 @@ depthsvg_re = re.compile(r'.*, depth=(.*)pt')
|
|||||||
depthsvgcomment_re = re.compile(r'<!-- DEPTH=(-?\d+) -->')
|
depthsvgcomment_re = re.compile(r'<!-- DEPTH=(-?\d+) -->')
|
||||||
|
|
||||||
|
|
||||||
def read_svg_depth(filename: str) -> int:
|
def read_svg_depth(filename: str) -> Optional[int]:
|
||||||
"""Read the depth from comment at last line of SVG file
|
"""Read the depth from comment at last line of SVG file
|
||||||
"""
|
"""
|
||||||
with open(filename, encoding="utf-8") as f:
|
with open(filename, encoding="utf-8") as f:
|
||||||
|
@ -32,7 +32,7 @@ import builtins
|
|||||||
import inspect
|
import inspect
|
||||||
import re
|
import re
|
||||||
from importlib import import_module
|
from importlib import import_module
|
||||||
from typing import Any, Dict, Iterable, List, Tuple, cast
|
from typing import Any, Dict, Iterable, List, Optional, Tuple, cast
|
||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
from docutils.nodes import Node
|
from docutils.nodes import Node
|
||||||
@ -131,8 +131,9 @@ class InheritanceGraph:
|
|||||||
graphviz dot graph from them.
|
graphviz dot graph from them.
|
||||||
"""
|
"""
|
||||||
def __init__(self, class_names: List[str], currmodule: str, show_builtins: bool = False,
|
def __init__(self, class_names: List[str], currmodule: str, show_builtins: bool = False,
|
||||||
private_bases: bool = False, parts: int = 0, aliases: Dict[str, str] = None,
|
private_bases: bool = False, parts: int = 0,
|
||||||
top_classes: List[Any] = []) -> None:
|
aliases: Optional[Dict[str, str]] = None, top_classes: List[Any] = []
|
||||||
|
) -> None:
|
||||||
"""*class_names* is a list of child classes to show bases from.
|
"""*class_names* is a list of child classes to show bases from.
|
||||||
|
|
||||||
If *show_builtins* is True, then Python builtins will be shown
|
If *show_builtins* is True, then Python builtins will be shown
|
||||||
@ -212,7 +213,9 @@ class InheritanceGraph:
|
|||||||
|
|
||||||
return list(all_classes.values())
|
return list(all_classes.values())
|
||||||
|
|
||||||
def class_name(self, cls: Any, parts: int = 0, aliases: Dict[str, str] = None) -> str:
|
def class_name(
|
||||||
|
self, cls: Any, parts: int = 0, aliases: Optional[Dict[str, str]] = None
|
||||||
|
) -> str:
|
||||||
"""Given a class object, return a fully-qualified name.
|
"""Given a class object, return a fully-qualified name.
|
||||||
|
|
||||||
This works for things I've tested in matplotlib so far, but may not be
|
This works for things I've tested in matplotlib so far, but may not be
|
||||||
@ -256,13 +259,14 @@ class InheritanceGraph:
|
|||||||
'style': '"setlinewidth(0.5)"',
|
'style': '"setlinewidth(0.5)"',
|
||||||
}
|
}
|
||||||
|
|
||||||
def _format_node_attrs(self, attrs: Dict) -> str:
|
def _format_node_attrs(self, attrs: Dict[str, Any]) -> str:
|
||||||
return ','.join(['%s=%s' % x for x in sorted(attrs.items())])
|
return ','.join(['%s=%s' % x for x in sorted(attrs.items())])
|
||||||
|
|
||||||
def _format_graph_attrs(self, attrs: Dict) -> str:
|
def _format_graph_attrs(self, attrs: Dict[str, Any]) -> str:
|
||||||
return ''.join(['%s=%s;\n' % x for x in sorted(attrs.items())])
|
return ''.join(['%s=%s;\n' % x for x in sorted(attrs.items())])
|
||||||
|
|
||||||
def generate_dot(self, name: str, urls: Dict = {}, env: BuildEnvironment = None,
|
def generate_dot(self, name: str, urls: Dict[str, str] = {},
|
||||||
|
env: Optional[BuildEnvironment] = None,
|
||||||
graph_attrs: Dict = {}, node_attrs: Dict = {}, edge_attrs: Dict = {}
|
graph_attrs: Dict = {}, node_attrs: Dict = {}, edge_attrs: Dict = {}
|
||||||
) -> str:
|
) -> str:
|
||||||
"""Generate a graphviz dot graph from the classes that were passed in
|
"""Generate a graphviz dot graph from the classes that were passed in
|
||||||
|
@ -98,7 +98,7 @@ def _strip_basic_auth(url: str) -> str:
|
|||||||
return urlunsplit(frags)
|
return urlunsplit(frags)
|
||||||
|
|
||||||
|
|
||||||
def _read_from_url(url: str, config: Config = None) -> IO:
|
def _read_from_url(url: str, config: Optional[Config] = None) -> IO:
|
||||||
"""Reads data from *url* with an HTTP *GET*.
|
"""Reads data from *url* with an HTTP *GET*.
|
||||||
|
|
||||||
This function supports fetching from resources which use basic HTTP auth as
|
This function supports fetching from resources which use basic HTTP auth as
|
||||||
@ -652,7 +652,7 @@ def inspect_main(argv: List[str]) -> None:
|
|||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
class MockConfig:
|
class MockConfig:
|
||||||
intersphinx_timeout: int = None
|
intersphinx_timeout: Optional[int] = None
|
||||||
tls_verify = False
|
tls_verify = False
|
||||||
user_agent = None
|
user_agent = None
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ def html_visit_displaymath(self: HTMLTranslator, node: nodes.math_block) -> None
|
|||||||
raise nodes.SkipNode
|
raise nodes.SkipNode
|
||||||
|
|
||||||
|
|
||||||
def install_mathjax(app: Sphinx, pagename: str, templatename: str, context: Dict,
|
def install_mathjax(app: Sphinx, pagename: str, templatename: str, context: Dict[str, Any],
|
||||||
event_arg: Any) -> None:
|
event_arg: Any) -> None:
|
||||||
if app.builder.format != 'html' or app.builder.math_renderer_name != 'mathjax': # type: ignore # NOQA
|
if app.builder.format != 'html' or app.builder.math_renderer_name != 'mathjax': # type: ignore # NOQA
|
||||||
return
|
return
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from importlib import import_module
|
from importlib import import_module
|
||||||
from typing import Any, Dict
|
from typing import Any, Dict, Optional
|
||||||
|
|
||||||
from packaging import version
|
from packaging import version
|
||||||
from pygments import __version__ as pygmentsversion
|
from pygments import __version__ as pygmentsversion
|
||||||
@ -99,7 +99,7 @@ class PygmentsBridge:
|
|||||||
latex_formatter = LatexFormatter
|
latex_formatter = LatexFormatter
|
||||||
|
|
||||||
def __init__(self, dest: str = 'html', stylename: str = 'sphinx',
|
def __init__(self, dest: str = 'html', stylename: str = 'sphinx',
|
||||||
latex_engine: str = None) -> None:
|
latex_engine: Optional[str] = None) -> None:
|
||||||
self.dest = dest
|
self.dest = dest
|
||||||
self.latex_engine = latex_engine
|
self.latex_engine = latex_engine
|
||||||
|
|
||||||
@ -126,7 +126,7 @@ class PygmentsBridge:
|
|||||||
kwargs.update(self.formatter_args)
|
kwargs.update(self.formatter_args)
|
||||||
return self.formatter(**kwargs)
|
return self.formatter(**kwargs)
|
||||||
|
|
||||||
def get_lexer(self, source: str, lang: str, opts: Dict = None,
|
def get_lexer(self, source: str, lang: str, opts: Optional[Dict] = None,
|
||||||
force: bool = False, location: Any = None) -> Lexer:
|
force: bool = False, location: Any = None) -> Lexer:
|
||||||
if not opts:
|
if not opts:
|
||||||
opts = {}
|
opts = {}
|
||||||
@ -165,7 +165,7 @@ class PygmentsBridge:
|
|||||||
|
|
||||||
return lexer
|
return lexer
|
||||||
|
|
||||||
def highlight_block(self, source: str, lang: str, opts: Dict = None,
|
def highlight_block(self, source: str, lang: str, opts: Optional[Dict] = None,
|
||||||
force: bool = False, location: Any = None, **kwargs: Any) -> str:
|
force: bool = False, location: Any = None, **kwargs: Any) -> str:
|
||||||
if not isinstance(source, str):
|
if not isinstance(source, str):
|
||||||
source = source.decode()
|
source = source.decode()
|
||||||
|
@ -167,7 +167,7 @@ def init_console(locale_dir: str, catalog: str) -> Tuple[NullTranslations, bool]
|
|||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
# encoding is ignored
|
# encoding is ignored
|
||||||
language, _ = locale.getlocale(locale.LC_MESSAGES) # type: Tuple[Optional[str], Any]
|
language, _ = locale.getlocale(locale.LC_MESSAGES)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
# LC_MESSAGES is not always defined. Fallback to the default language
|
# LC_MESSAGES is not always defined. Fallback to the default language
|
||||||
# in case it is not.
|
# in case it is not.
|
||||||
@ -191,7 +191,7 @@ def _lazy_translate(catalog: str, namespace: str, message: str) -> str:
|
|||||||
return translator.gettext(message)
|
return translator.gettext(message)
|
||||||
|
|
||||||
|
|
||||||
def get_translation(catalog: str, namespace: str = 'general') -> Callable:
|
def get_translation(catalog: str, namespace: str = 'general') -> Callable[[str], str]:
|
||||||
"""Get a translation function based on the *catalog* and *namespace*.
|
"""Get a translation function based on the *catalog* and *namespace*.
|
||||||
|
|
||||||
The extension can use this API to translate the messages on the
|
The extension can use this API to translate the messages on the
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
"""Handlers for additional ReST roles."""
|
"""Handlers for additional ReST roles."""
|
||||||
|
|
||||||
import re
|
import re
|
||||||
from typing import TYPE_CHECKING, Any, Dict, List, Tuple, Type
|
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, Type
|
||||||
|
|
||||||
import docutils.parsers.rst.directives
|
import docutils.parsers.rst.directives
|
||||||
import docutils.parsers.rst.roles
|
import docutils.parsers.rst.roles
|
||||||
@ -64,7 +64,8 @@ class XRefRole(ReferenceRole):
|
|||||||
innernodeclass: Type[TextElement] = nodes.literal
|
innernodeclass: Type[TextElement] = nodes.literal
|
||||||
|
|
||||||
def __init__(self, fix_parens: bool = False, lowercase: bool = False,
|
def __init__(self, fix_parens: bool = False, lowercase: bool = False,
|
||||||
nodeclass: Type[Element] = None, innernodeclass: Type[TextElement] = None,
|
nodeclass: Optional[Type[Element]] = None,
|
||||||
|
innernodeclass: Optional[Type[TextElement]] = None,
|
||||||
warn_dangling: bool = False) -> None:
|
warn_dangling: bool = False) -> None:
|
||||||
self.fix_parens = fix_parens
|
self.fix_parens = fix_parens
|
||||||
self.lowercase = lowercase
|
self.lowercase = lowercase
|
||||||
|
@ -7,7 +7,7 @@ import os
|
|||||||
import sys
|
import sys
|
||||||
import warnings
|
import warnings
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
from typing import Any, Dict
|
from typing import Any, Dict, Optional
|
||||||
|
|
||||||
from sphinx.application import Sphinx
|
from sphinx.application import Sphinx
|
||||||
from sphinx.cmd.build import handle_exception
|
from sphinx.cmd.build import handle_exception
|
||||||
@ -90,15 +90,15 @@ class BuildDoc(Command):
|
|||||||
def initialize_options(self) -> None:
|
def initialize_options(self) -> None:
|
||||||
self.fresh_env = self.all_files = False
|
self.fresh_env = self.all_files = False
|
||||||
self.pdb = False
|
self.pdb = False
|
||||||
self.source_dir: str = None
|
self.source_dir: Optional[str] = None
|
||||||
self.build_dir: str = None
|
self.build_dir: Optional[str] = None
|
||||||
self.builder = 'html'
|
self.builder = 'html'
|
||||||
self.warning_is_error = False
|
self.warning_is_error = False
|
||||||
self.project = ''
|
self.project = ''
|
||||||
self.version = ''
|
self.version = ''
|
||||||
self.release = ''
|
self.release = ''
|
||||||
self.today = ''
|
self.today = ''
|
||||||
self.config_dir: str = None
|
self.config_dir: Optional[str] = None
|
||||||
self.link_index = False
|
self.link_index = False
|
||||||
self.copyright = ''
|
self.copyright = ''
|
||||||
# Link verbosity to distutils' (which uses 1 by default).
|
# Link verbosity to distutils' (which uses 1 by default).
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
;; style file for xindy
|
;; Common Lisp style file for xindy
|
||||||
;; filename: LatinRules.xdy
|
;; filename: LatinRules.xdy
|
||||||
;;
|
;;
|
||||||
|
;; Please note that this data file deliberately uses strings
|
||||||
|
;; with single non-ascii bytes. This is intentional and
|
||||||
|
;; follows the usage observed in similar xindy support files.
|
||||||
|
;;
|
||||||
;; It is based upon xindy's files lang/general/utf8.xdy and
|
;; It is based upon xindy's files lang/general/utf8.xdy and
|
||||||
;; lang/general/utf8-lang.xdy which implement
|
;; lang/general/utf8-lang.xdy which implement
|
||||||
;; "a general sorting order for Western European languages"
|
;; "a general sorting order for Western European languages".
|
||||||
;;
|
;;
|
||||||
;; The aim for Sphinx is to be able to index in a Cyrillic document
|
;; The aim for Sphinx is to be able to index in a Cyrillic document
|
||||||
;; also terms using the Latin alphabets, inclusive of letters
|
;; also terms using the Latin alphabets, inclusive of letters
|
||||||
@ -14,7 +18,7 @@
|
|||||||
;;
|
;;
|
||||||
;; So here we use only 0o266 or higher bytes.
|
;; So here we use only 0o266 or higher bytes.
|
||||||
;; (Ŋ, ŋ, IJ, and ij are absent from
|
;; (Ŋ, ŋ, IJ, and ij are absent from
|
||||||
;; lang/general/utf8.xdy and not included here)
|
;; lang/general/utf8.xdy and not included here.)
|
||||||
;; Contributed by the Sphinx team, 2018.
|
;; Contributed by the Sphinx team, 2018.
|
||||||
|
|
||||||
(define-letter-group "A" :prefixes ("¶"))
|
(define-letter-group "A" :prefixes ("¶"))
|
||||||
|
@ -88,7 +88,7 @@ const _displayItem = (item, highlightTerms, searchTerms) => {
|
|||||||
linkEl.href = linkUrl + "?" + params.toString() + anchor;
|
linkEl.href = linkUrl + "?" + params.toString() + anchor;
|
||||||
linkEl.innerHTML = title;
|
linkEl.innerHTML = title;
|
||||||
if (descr)
|
if (descr)
|
||||||
listItem.appendChild(document.createElement("span")).innerText =
|
listItem.appendChild(document.createElement("span")).innerHTML =
|
||||||
" (" + descr + ")";
|
" (" + descr + ")";
|
||||||
else if (showSearchSummary)
|
else if (showSearchSummary)
|
||||||
fetch(requestUrl)
|
fetch(requestUrl)
|
||||||
@ -155,10 +155,8 @@ const Search = {
|
|||||||
_pulse_status: -1,
|
_pulse_status: -1,
|
||||||
|
|
||||||
htmlToText: (htmlString) => {
|
htmlToText: (htmlString) => {
|
||||||
const htmlElement = document
|
const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html');
|
||||||
.createRange()
|
htmlElement.querySelectorAll(".headerlink").forEach((el) => { el.remove() });
|
||||||
.createContextualFragment(htmlString);
|
|
||||||
htmlElement.querySelectorAll(".headerlink").forEach((el) => el.parentNode.removeChild(el));
|
|
||||||
const docContent = htmlElement.querySelector('[role="main"]');
|
const docContent = htmlElement.querySelector('[role="main"]');
|
||||||
if (docContent !== undefined) return docContent.textContent;
|
if (docContent !== undefined) return docContent.textContent;
|
||||||
console.warn(
|
console.warn(
|
||||||
@ -519,7 +517,7 @@ const Search = {
|
|||||||
|
|
||||||
let summary = document.createElement("p");
|
let summary = document.createElement("p");
|
||||||
summary.classList.add("context");
|
summary.classList.add("context");
|
||||||
summary.innerText = top + text.substr(startWithContext, 240).trim() + tail;
|
summary.textContent = top + text.substr(startWithContext, 240).trim() + tail;
|
||||||
|
|
||||||
highlightWords.forEach((highlightWord) =>
|
highlightWords.forEach((highlightWord) =>
|
||||||
_highlightText(summary, highlightWord, "highlighted")
|
_highlightText(summary, highlightWord, "highlighted")
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
"""Utility functions for math."""
|
"""Utility functions for math."""
|
||||||
|
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
from docutils import nodes
|
from docutils import nodes
|
||||||
|
|
||||||
from sphinx.builders.html import HTMLTranslator
|
from sphinx.builders.html import HTMLTranslator
|
||||||
@ -20,7 +22,7 @@ def get_node_equation_number(writer: HTMLTranslator, node: nodes.math_block) ->
|
|||||||
return node['number']
|
return node['number']
|
||||||
|
|
||||||
|
|
||||||
def wrap_displaymath(text: str, label: str, numbering: bool) -> str:
|
def wrap_displaymath(text: str, label: Optional[str], numbering: bool) -> str:
|
||||||
def is_equation(part: str) -> str:
|
def is_equation(part: str) -> str:
|
||||||
return part.strip()
|
return part.strip()
|
||||||
|
|
||||||
|
@ -513,7 +513,7 @@ _non_id_translate_digraphs = {
|
|||||||
|
|
||||||
|
|
||||||
def make_id(env: "BuildEnvironment", document: nodes.document,
|
def make_id(env: "BuildEnvironment", document: nodes.document,
|
||||||
prefix: str = '', term: str = None) -> str:
|
prefix: str = '', term: Optional[str] = None) -> str:
|
||||||
"""Generate an appropriate node_id for given *prefix* and *term*."""
|
"""Generate an appropriate node_id for given *prefix* and *term*."""
|
||||||
node_id = None
|
node_id = None
|
||||||
if prefix:
|
if prefix:
|
||||||
@ -550,7 +550,8 @@ def find_pending_xref_condition(node: addnodes.pending_xref, condition: str
|
|||||||
|
|
||||||
|
|
||||||
def make_refnode(builder: "Builder", fromdocname: str, todocname: str, targetid: str,
|
def make_refnode(builder: "Builder", fromdocname: str, todocname: str, targetid: str,
|
||||||
child: Union[Node, List[Node]], title: str = None) -> nodes.reference:
|
child: Union[Node, List[Node]], title: Optional[str] = None
|
||||||
|
) -> nodes.reference:
|
||||||
"""Shortcut to create a reference node."""
|
"""Shortcut to create a reference node."""
|
||||||
node = nodes.reference('', '', internal=True)
|
node = nodes.reference('', '', internal=True)
|
||||||
if fromdocname == todocname and targetid:
|
if fromdocname == todocname and targetid:
|
||||||
|
@ -112,7 +112,7 @@ def make_filename_from_project(project: str) -> str:
|
|||||||
return make_filename(project_suffix_re.sub('', project)).lower()
|
return make_filename(project_suffix_re.sub('', project)).lower()
|
||||||
|
|
||||||
|
|
||||||
def relpath(path: str, start: str = os.curdir) -> str:
|
def relpath(path: str, start: Optional[str] = os.curdir) -> str:
|
||||||
"""Return a relative filepath to *path* either from the current directory or
|
"""Return a relative filepath to *path* either from the current directory or
|
||||||
from an optional *start* directory.
|
from an optional *start* directory.
|
||||||
|
|
||||||
|
@ -81,7 +81,9 @@ class ParallelTasks:
|
|||||||
logging.convert_serializable(collector.logs)
|
logging.convert_serializable(collector.logs)
|
||||||
pipe.send((failed, collector.logs, ret))
|
pipe.send((failed, collector.logs, ret))
|
||||||
|
|
||||||
def add_task(self, task_func: Callable, arg: Any = None, result_func: Callable = None) -> None: # NOQA
|
def add_task(
|
||||||
|
self, task_func: Callable, arg: Any = None, result_func: Optional[Callable] = None
|
||||||
|
) -> None:
|
||||||
tid = self._taskid
|
tid = self._taskid
|
||||||
self._taskid += 1
|
self._taskid += 1
|
||||||
self._result_funcs[tid] = result_func or (lambda arg, result: None)
|
self._result_funcs[tid] = result_func or (lambda arg, result: None)
|
||||||
|
@ -8,7 +8,7 @@ from sphinx.deprecation import RemovedInSphinx70Warning
|
|||||||
|
|
||||||
|
|
||||||
class PorterStemmer:
|
class PorterStemmer:
|
||||||
def __init__(self):
|
def __init__(self) -> None:
|
||||||
warnings.warn(f"{self.__class__.__name__} is deprecated, use "
|
warnings.warn(f"{self.__class__.__name__} is deprecated, use "
|
||||||
"snowballstemmer.stemmer('porter') instead.",
|
"snowballstemmer.stemmer('porter') instead.",
|
||||||
RemovedInSphinx70Warning, stacklevel=2)
|
RemovedInSphinx70Warning, stacklevel=2)
|
||||||
@ -22,7 +22,7 @@ class PorterStemmer:
|
|||||||
|
|
||||||
|
|
||||||
class BaseStemmer:
|
class BaseStemmer:
|
||||||
def __init__(self):
|
def __init__(self) -> None:
|
||||||
warnings.warn(f"{self.__class__.__name__} is deprecated, use "
|
warnings.warn(f"{self.__class__.__name__} is deprecated, use "
|
||||||
"snowballstemmer.stemmer('porter') instead.",
|
"snowballstemmer.stemmer('porter') instead.",
|
||||||
RemovedInSphinx70Warning, stacklevel=3)
|
RemovedInSphinx70Warning, stacklevel=3)
|
||||||
@ -32,7 +32,7 @@ class BaseStemmer:
|
|||||||
|
|
||||||
|
|
||||||
class PyStemmer(BaseStemmer):
|
class PyStemmer(BaseStemmer):
|
||||||
def __init__(self): # NoQA
|
def __init__(self) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.stemmer = snowballstemmer.stemmer('porter')
|
self.stemmer = snowballstemmer.stemmer('porter')
|
||||||
|
|
||||||
@ -44,7 +44,7 @@ class PyStemmer(BaseStemmer):
|
|||||||
|
|
||||||
|
|
||||||
class StandardStemmer(BaseStemmer):
|
class StandardStemmer(BaseStemmer):
|
||||||
def __init__(self): # NoQA
|
def __init__(self) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.stemmer = snowballstemmer.stemmer('porter')
|
self.stemmer = snowballstemmer.stemmer('porter')
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
from typing import Iterator, List
|
from typing import Iterator, List, Optional
|
||||||
|
|
||||||
from jinja2 import nodes
|
from jinja2 import nodes
|
||||||
from jinja2.environment import Environment
|
from jinja2.environment import Environment
|
||||||
@ -35,7 +35,7 @@ class BooleanParser(Parser):
|
|||||||
|
|
||||||
|
|
||||||
class Tags:
|
class Tags:
|
||||||
def __init__(self, tags: List[str] = None) -> None:
|
def __init__(self, tags: Optional[List[str]] = None) -> None:
|
||||||
self.tags = dict.fromkeys(tags or [], True)
|
self.tags = dict.fromkeys(tags or [], True)
|
||||||
|
|
||||||
def has(self, tag: str) -> bool:
|
def has(self, tag: str) -> bool:
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
import os
|
import os
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from os import path
|
from os import path
|
||||||
from typing import Callable, Dict, List, Tuple, Union
|
from typing import Any, Callable, Dict, List, Optional, Tuple, Union
|
||||||
|
|
||||||
from jinja2 import TemplateNotFound
|
from jinja2 import TemplateNotFound
|
||||||
from jinja2.environment import Environment
|
from jinja2.environment import Environment
|
||||||
@ -17,15 +17,15 @@ from sphinx.util import rst, texescape
|
|||||||
|
|
||||||
|
|
||||||
class BaseRenderer:
|
class BaseRenderer:
|
||||||
def __init__(self, loader: BaseLoader = None) -> None:
|
def __init__(self, loader: Optional[BaseLoader] = None) -> None:
|
||||||
self.env = SandboxedEnvironment(loader=loader, extensions=['jinja2.ext.i18n'])
|
self.env = SandboxedEnvironment(loader=loader, extensions=['jinja2.ext.i18n'])
|
||||||
self.env.filters['repr'] = repr
|
self.env.filters['repr'] = repr
|
||||||
self.env.install_gettext_translations(get_translator())
|
self.env.install_gettext_translations(get_translator())
|
||||||
|
|
||||||
def render(self, template_name: str, context: Dict) -> str:
|
def render(self, template_name: str, context: Dict[str, Any]) -> str:
|
||||||
return self.env.get_template(template_name).render(context)
|
return self.env.get_template(template_name).render(context)
|
||||||
|
|
||||||
def render_string(self, source: str, context: Dict) -> str:
|
def render_string(self, source: str, context: Dict[str, Any]) -> str:
|
||||||
return self.env.from_string(source).render(context)
|
return self.env.from_string(source).render(context)
|
||||||
|
|
||||||
|
|
||||||
@ -41,25 +41,27 @@ class FileRenderer(BaseRenderer):
|
|||||||
super().__init__(loader)
|
super().__init__(loader)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def render_from_file(cls, filename: str, context: Dict) -> str:
|
def render_from_file(cls, filename: str, context: Dict[str, Any]) -> str:
|
||||||
dirname = os.path.dirname(filename)
|
dirname = os.path.dirname(filename)
|
||||||
basename = os.path.basename(filename)
|
basename = os.path.basename(filename)
|
||||||
return cls(dirname).render(basename, context)
|
return cls(dirname).render(basename, context)
|
||||||
|
|
||||||
|
|
||||||
class SphinxRenderer(FileRenderer):
|
class SphinxRenderer(FileRenderer):
|
||||||
def __init__(self, template_path: Union[str, List[str]] = None) -> None:
|
def __init__(self, template_path: Union[None, str, List[str]] = None) -> None:
|
||||||
if template_path is None:
|
if template_path is None:
|
||||||
template_path = os.path.join(package_dir, 'templates')
|
template_path = os.path.join(package_dir, 'templates')
|
||||||
super().__init__(template_path)
|
super().__init__(template_path)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def render_from_file(cls, filename: str, context: Dict) -> str:
|
def render_from_file(cls, filename: str, context: Dict[str, Any]) -> str:
|
||||||
return FileRenderer.render_from_file(filename, context)
|
return FileRenderer.render_from_file(filename, context)
|
||||||
|
|
||||||
|
|
||||||
class LaTeXRenderer(SphinxRenderer):
|
class LaTeXRenderer(SphinxRenderer):
|
||||||
def __init__(self, template_path: str = None, latex_engine: str = None) -> None:
|
def __init__(
|
||||||
|
self, template_path: Optional[str] = None, latex_engine: Optional[str] = None
|
||||||
|
) -> None:
|
||||||
if template_path is None:
|
if template_path is None:
|
||||||
template_path = os.path.join(package_dir, 'templates', 'latex')
|
template_path = os.path.join(package_dir, 'templates', 'latex')
|
||||||
super().__init__(template_path)
|
super().__init__(template_path)
|
||||||
@ -81,7 +83,9 @@ class LaTeXRenderer(SphinxRenderer):
|
|||||||
|
|
||||||
|
|
||||||
class ReSTRenderer(SphinxRenderer):
|
class ReSTRenderer(SphinxRenderer):
|
||||||
def __init__(self, template_path: Union[str, List[str]] = None, language: str = None) -> None: # NOQA
|
def __init__(
|
||||||
|
self, template_path: Union[None, str, List[str]] = None, language: Optional[str] = None
|
||||||
|
) -> None:
|
||||||
super().__init__(template_path)
|
super().__init__(template_path)
|
||||||
|
|
||||||
# add language to environment
|
# add language to environment
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
"""TeX escaping helper."""
|
"""TeX escaping helper."""
|
||||||
|
|
||||||
import re
|
import re
|
||||||
from typing import Dict
|
from typing import Dict, Optional
|
||||||
|
|
||||||
tex_replacements = [
|
tex_replacements = [
|
||||||
# map TeX special chars
|
# map TeX special chars
|
||||||
@ -100,7 +100,7 @@ _tex_hlescape_map: Dict[int, str] = {}
|
|||||||
_tex_hlescape_map_without_unicode: Dict[int, str] = {}
|
_tex_hlescape_map_without_unicode: Dict[int, str] = {}
|
||||||
|
|
||||||
|
|
||||||
def escape(s: str, latex_engine: str = None) -> str:
|
def escape(s: str, latex_engine: Optional[str] = None) -> str:
|
||||||
"""Escape text for LaTeX output."""
|
"""Escape text for LaTeX output."""
|
||||||
if latex_engine in ('lualatex', 'xelatex'):
|
if latex_engine in ('lualatex', 'xelatex'):
|
||||||
# unicode based LaTeX engine
|
# unicode based LaTeX engine
|
||||||
@ -109,7 +109,7 @@ def escape(s: str, latex_engine: str = None) -> str:
|
|||||||
return s.translate(_tex_escape_map)
|
return s.translate(_tex_escape_map)
|
||||||
|
|
||||||
|
|
||||||
def hlescape(s: str, latex_engine: str = None) -> str:
|
def hlescape(s: str, latex_engine: Optional[str] = None) -> str:
|
||||||
"""Escape text for LaTeX highlighter."""
|
"""Escape text for LaTeX highlighter."""
|
||||||
if latex_engine in ('lualatex', 'xelatex'):
|
if latex_engine in ('lualatex', 'xelatex'):
|
||||||
# unicode based LaTeX engine
|
# unicode based LaTeX engine
|
||||||
|
@ -70,7 +70,9 @@ InventoryItem = Tuple[str, str, str, str]
|
|||||||
Inventory = Dict[str, Dict[str, InventoryItem]]
|
Inventory = Dict[str, Dict[str, InventoryItem]]
|
||||||
|
|
||||||
|
|
||||||
def get_type_hints(obj: Any, globalns: Dict = None, localns: Dict = None) -> Dict[str, Any]:
|
def get_type_hints(
|
||||||
|
obj: Any, globalns: Optional[Dict[str, Any]] = None, localns: Optional[Dict] = None
|
||||||
|
) -> Dict[str, Any]:
|
||||||
"""Return a dictionary containing type hints for a function, method, module or class object.
|
"""Return a dictionary containing type hints for a function, method, module or class object.
|
||||||
|
|
||||||
This is a simple wrapper of `typing.get_type_hints()` that does not raise an error on
|
This is a simple wrapper of `typing.get_type_hints()` that does not raise an error on
|
||||||
|
@ -8,7 +8,7 @@ import re
|
|||||||
import warnings
|
import warnings
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from os import path
|
from os import path
|
||||||
from typing import TYPE_CHECKING, Any, Dict, Iterable, List, Set, Tuple, cast
|
from typing import TYPE_CHECKING, Any, Dict, Iterable, List, Optional, Set, Tuple, cast
|
||||||
|
|
||||||
from docutils import nodes, writers
|
from docutils import nodes, writers
|
||||||
from docutils.nodes import Element, Node, Text
|
from docutils.nodes import Element, Node, Text
|
||||||
@ -172,7 +172,9 @@ class Table:
|
|||||||
assert self.cells[(self.row + row, self.col + col)] == 0
|
assert self.cells[(self.row + row, self.col + col)] == 0
|
||||||
self.cells[(self.row + row, self.col + col)] = self.cell_id
|
self.cells[(self.row + row, self.col + col)] = self.cell_id
|
||||||
|
|
||||||
def cell(self, row: int = None, col: int = None) -> "TableCell":
|
def cell(
|
||||||
|
self, row: Optional[int] = None, col: Optional[int] = None
|
||||||
|
) -> Optional["TableCell"]:
|
||||||
"""Returns a cell object (i.e. rectangular area) containing given position.
|
"""Returns a cell object (i.e. rectangular area) containing given position.
|
||||||
|
|
||||||
If no option arguments: ``row`` or ``col`` are given, the current position;
|
If no option arguments: ``row`` or ``col`` are given, the current position;
|
||||||
@ -496,7 +498,7 @@ class LaTeXTranslator(SphinxTranslator):
|
|||||||
return renderer.render(template_name, variables)
|
return renderer.render(template_name, variables)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def table(self) -> Table:
|
def table(self) -> Optional[Table]:
|
||||||
"""Get current table."""
|
"""Get current table."""
|
||||||
if self.tables:
|
if self.tables:
|
||||||
return self.tables[-1]
|
return self.tables[-1]
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
import re
|
import re
|
||||||
import textwrap
|
import textwrap
|
||||||
from os import path
|
from os import path
|
||||||
from typing import (TYPE_CHECKING, Any, Dict, Iterable, Iterator, List, Pattern, Set, Tuple,
|
from typing import (TYPE_CHECKING, Any, Dict, Iterable, Iterator, List, Optional, Pattern, Set,
|
||||||
Union, cast)
|
Tuple, Union, cast)
|
||||||
|
|
||||||
from docutils import nodes, writers
|
from docutils import nodes, writers
|
||||||
from docutils.nodes import Element, Node, Text
|
from docutils.nodes import Element, Node, Text
|
||||||
@ -91,7 +91,7 @@ def find_subsections(section: Element) -> List[nodes.section]:
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def smart_capwords(s: str, sep: str = None) -> str:
|
def smart_capwords(s: str, sep: Optional[str] = None) -> str:
|
||||||
"""Like string.capwords() but does not capitalize words that already
|
"""Like string.capwords() but does not capitalize words that already
|
||||||
contain a capital letter."""
|
contain a capital letter."""
|
||||||
words = s.split(sep)
|
words = s.split(sep)
|
||||||
@ -173,7 +173,7 @@ class TexinfoTranslator(SphinxTranslator):
|
|||||||
self.body: List[str] = []
|
self.body: List[str] = []
|
||||||
self.context: List[str] = []
|
self.context: List[str] = []
|
||||||
self.descs: List[addnodes.desc] = []
|
self.descs: List[addnodes.desc] = []
|
||||||
self.previous_section: nodes.section = None
|
self.previous_section: Optional[nodes.section] = None
|
||||||
self.section_level = 0
|
self.section_level = 0
|
||||||
self.seen_title = False
|
self.seen_title = False
|
||||||
self.next_section_ids: Set[str] = set()
|
self.next_section_ids: Set[str] = set()
|
||||||
@ -184,7 +184,7 @@ class TexinfoTranslator(SphinxTranslator):
|
|||||||
self.in_footnote = 0
|
self.in_footnote = 0
|
||||||
self.in_samp = 0
|
self.in_samp = 0
|
||||||
self.handled_abbrs: Set[str] = set()
|
self.handled_abbrs: Set[str] = set()
|
||||||
self.colwidths: List[int] = None
|
self.colwidths: Optional[List[int]] = None
|
||||||
|
|
||||||
def finish(self) -> None:
|
def finish(self) -> None:
|
||||||
if self.previous_section is None:
|
if self.previous_section is None:
|
||||||
|
11
tox.ini
11
tox.ini
@ -86,6 +86,17 @@ extras =
|
|||||||
commands =
|
commands =
|
||||||
sphinx-lint --enable line-too-long --max-line-length 85 CHANGES CONTRIBUTING.rst README.rst doc/
|
sphinx-lint --enable line-too-long --max-line-length 85 CHANGES CONTRIBUTING.rst README.rst doc/
|
||||||
|
|
||||||
|
[testenv:docs-live]
|
||||||
|
basepython = python3
|
||||||
|
description =
|
||||||
|
Build documentation.
|
||||||
|
extras =
|
||||||
|
docs
|
||||||
|
deps =
|
||||||
|
sphinx-autobuild
|
||||||
|
commands =
|
||||||
|
sphinx-autobuild ./doc ./build/sphinx/
|
||||||
|
|
||||||
[testenv:twine]
|
[testenv:twine]
|
||||||
basepython = python3
|
basepython = python3
|
||||||
description =
|
description =
|
||||||
|
Loading…
Reference in New Issue
Block a user