Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/sphinx-doc/sphinx.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Turner <9087854+aa-turner@users.noreply.github.com>2022-10-16 13:24:18 +0300
committerAdam Turner <9087854+aa-turner@users.noreply.github.com>2022-10-16 13:24:18 +0300
commite70a0fac6d17596d71c0107f7509369995a59673 (patch)
treebdb85ee4c7ad0439d6b1137e1f08a801c6104cce
parent82cb4cdb2bf5c154261df9cd59bdcb368228f11d (diff)
parentc1f2a52d5d97f874d84e4d5421c99a566242af6b (diff)
Merge branch '5.x'
# Conflicts: # .github/workflows/main.yml # CHANGES # sphinx/__init__.py # sphinx/domains/c.py
-rw-r--r--.github/ISSUE_TEMPLATE/bug-report.yml80
-rw-r--r--.github/workflows/latex.yml11
-rw-r--r--.github/workflows/main.yml2
-rw-r--r--CHANGES32
-rw-r--r--doc/conf.py3
-rw-r--r--doc/extdev/deprecated.rst4
-rw-r--r--doc/latex.rst70
-rw-r--r--doc/usage/configuration.rst95
-rw-r--r--doc/usage/extensions/autosectionlabel.rst9
-rw-r--r--doc/usage/restructuredtext/basics.rst17
-rw-r--r--doc/usage/restructuredtext/directives.rst147
-rw-r--r--doc/usage/restructuredtext/domains.rst3
-rw-r--r--doc/usage/theming.rst2
-rw-r--r--sphinx/__init__.py2
-rw-r--r--sphinx/builders/_epub_base.py3
-rw-r--r--sphinx/builders/latex/__init__.py4
-rw-r--r--sphinx/cmd/build.py43
-rw-r--r--sphinx/directives/__init__.py3
-rw-r--r--sphinx/domains/std.py15
-rw-r--r--sphinx/ext/autodoc/preserve_defaults.py3
-rw-r--r--sphinx/ext/autodoc/typehints.py3
-rw-r--r--sphinx/ext/autosectionlabel.py6
-rw-r--r--sphinx/ext/duration.py3
-rw-r--r--sphinx/ext/extlinks.py6
-rw-r--r--sphinx/ext/imgconverter.py3
-rw-r--r--sphinx/ext/imgmath.py119
-rw-r--r--sphinx/ext/napoleon/__init__.py6
-rw-r--r--sphinx/templates/latex/latex.tex_t9
-rw-r--r--sphinx/templates/latex/longtable.tex_t64
-rw-r--r--sphinx/templates/latex/tabular.tex_t35
-rw-r--r--sphinx/templates/latex/tabulary.tex_t35
-rw-r--r--sphinx/texinputs/sphinx.sty152
-rw-r--r--sphinx/texinputs/sphinxlatexstyleheadings.sty3
-rw-r--r--sphinx/texinputs/sphinxlatextables.sty835
-rw-r--r--sphinx/texinputs/sphinxpackagefootnote.sty3
-rw-r--r--sphinx/writers/html.py2
-rw-r--r--sphinx/writers/html5.py2
-rw-r--r--sphinx/writers/latex.py107
-rw-r--r--tests/roots/test-ext-extlinks-hardcoded-urls-multiple-replacements/index.rst2
-rw-r--r--tests/roots/test-image-escape/conf.py0
-rw-r--r--tests/roots/test-image-escape/img_#1.pngbin0 -> 66247 bytes
-rw-r--r--tests/roots/test-image-escape/index.rst5
-rw-r--r--tests/roots/test-latex-table/complex.rst23
-rw-r--r--tests/roots/test-latex-table/expects/complex_spanning_cell.tex14
-rw-r--r--tests/roots/test-latex-table/expects/gridtable.tex19
-rw-r--r--tests/roots/test-latex-table/expects/gridtable_with_tabularcolumn.tex73
-rw-r--r--tests/roots/test-latex-table/expects/longtable.tex37
-rw-r--r--tests/roots/test-latex-table/expects/longtable_having_align.tex36
-rw-r--r--tests/roots/test-latex-table/expects/longtable_having_caption.tex36
-rw-r--r--tests/roots/test-latex-table/expects/longtable_having_problematic_cell.tex36
-rw-r--r--tests/roots/test-latex-table/expects/longtable_having_stub_columns_and_problematic_cell.tex34
-rw-r--r--tests/roots/test-latex-table/expects/longtable_having_verbatim.tex36
-rw-r--r--tests/roots/test-latex-table/expects/longtable_having_widths.tex37
-rw-r--r--tests/roots/test-latex-table/expects/longtable_having_widths_and_problematic_cell.tex36
-rw-r--r--tests/roots/test-latex-table/expects/longtable_with_tabularcolumn.tex37
-rw-r--r--tests/roots/test-latex-table/expects/simple_table.tex14
-rw-r--r--tests/roots/test-latex-table/expects/table_having_caption.tex14
-rw-r--r--tests/roots/test-latex-table/expects/table_having_problematic_cell.tex14
-rw-r--r--tests/roots/test-latex-table/expects/table_having_stub_columns_and_problematic_cell.tex12
-rw-r--r--tests/roots/test-latex-table/expects/table_having_threeparagraphs_cell_in_first_col.tex10
-rw-r--r--tests/roots/test-latex-table/expects/table_having_verbatim.tex14
-rw-r--r--tests/roots/test-latex-table/expects/table_having_widths.tex18
-rw-r--r--tests/roots/test-latex-table/expects/table_having_widths_and_problematic_cell.tex14
-rw-r--r--tests/roots/test-latex-table/expects/tabular_having_widths.tex14
-rw-r--r--tests/roots/test-latex-table/expects/tabularcolumn.tex17
-rw-r--r--tests/roots/test-latex-table/expects/tabulary_having_widths.tex14
-rw-r--r--tests/roots/test-latex-table/longtable.rst2
-rw-r--r--tests/roots/test-latex-table/tabular.rst3
-rw-r--r--tests/roots/test-object-description-sections/conf.py0
-rw-r--r--tests/roots/test-object-description-sections/index.rst6
-rw-r--r--tests/roots/test-root/objects.txt3
-rw-r--r--tests/test_build_html.py12
-rw-r--r--tests/test_build_latex.py46
-rw-r--r--tests/test_directive_object_description.py45
-rw-r--r--tests/test_ext_extlinks.py1
-rw-r--r--tox.ini1
76 files changed, 2093 insertions, 583 deletions
diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml
index c78f1a2a7..9eeac53ab 100644
--- a/.github/ISSUE_TEMPLATE/bug-report.yml
+++ b/.github/ISSUE_TEMPLATE/bug-report.yml
@@ -7,16 +7,34 @@ body:
attributes:
label: Describe the bug
description: >-
- A clear and concise description of what the bug is.
+ A clear and concise description of what the bug is, including the
+ expected behaviour and what has gone wrong.
+
+ Please include screenshots, if applicable.
validations:
required: true
- type: textarea
attributes:
label: How to Reproduce
- description: Please provide steps to reproduce this bug.
+ description: >-
+ Please provide steps to reproduce this bug, with the smallest possible
+ set of source files. For normal bugs this should ideally be one
+ ``index.rst`` file, and for ``sphinx.ext.autodoc`` bugs, this should
+ ideally be a single ``index.rst`` file, and a single example Python
+ module.
value: |
+ Minimal method (you can also paste the contents of ``index.rst`` and
+ ``conf.py`` into this report):
+ ```bash
+ $ echo "Content demonstrating the bug..." > index.rst
+ $ echo "" > conf.py
+ $ sphinx-build -M html . _build
+ $ # open _build/html/index and see bla bla
```
+
+ ``git clone`` method (this is advised against, to help the Sphinx team):
+ ```bash
$ git clone https://github.com/.../some_project
$ cd some_project
$ pip install -r requirements.txt
@@ -27,28 +45,6 @@ body:
validations:
required: true
- - type: textarea
- attributes:
- label: Expected behavior
- description: >-
- A clear and concise description of what you expected to happen.
-
- - type: input
- attributes:
- label: Your project
- description: >-
- Link to your sphinx project, or attach zipped small project sample.
- validations:
- required: true
-
- - type: textarea
- attributes:
- label: Screenshots
- description: >-
- If applicable, add screenshots to help explain your problem.
- validations:
- required: false
-
- type: markdown
attributes:
value: |
@@ -56,38 +52,30 @@ body:
- type: input
attributes:
- label: OS
+ label: Environment Information
description: >-
- [e.g. Unix/Linux/Mac/Win/other with version]
- validations:
- required: true
- - type: input
- attributes:
- label: Python version
- validations:
- required: true
- - type: input
- attributes:
- label: Sphinx version
+ Install development Sphinx
+ ``pip install https://github.com/AA-Turner/sphinx/archive/refs/heads/5.x.zip``
+ then run ``sphinx-build --bug-report`` or ``python -m sphinx --bug-report``.
+ and paste the output here.
validations:
required: true
- type: input
attributes:
label: Sphinx extensions
description: >-
- [e.g. sphinx.ext.autodoc, recommonmark]
- validations:
- required: false
- - type: input
- attributes:
- label: Extra tools
- description: >-
- [e.g. Browser, tex or something else]
+ Attempt to reproduce your error with the smallest set of extensions possible.
+ This makes it easier to determine where the problem you are encountering is.
+
+ e.g. ["sphinx.ext.autodoc", "recommonmark"]
validations:
required: false
- type: textarea
attributes:
label: Additional context
description: >-
- Add any other context about the problem here.
- [e.g. URL or Ticket]
+ Add any other context about the problem here, for example:
+
+ * Any other tools used (Browser, TeX, etc) with versions
+ * Reference to another issue or pull request
+ * URL to some external resource
diff --git a/.github/workflows/latex.yml b/.github/workflows/latex.yml
index 12e39f54f..9a7913460 100644
--- a/.github/workflows/latex.yml
+++ b/.github/workflows/latex.yml
@@ -6,15 +6,16 @@ permissions:
contents: read
jobs:
- build:
- runs-on: ubuntu-18.04
- name: Python 3.8
+ test:
+ runs-on: ubuntu-latest
+ name: Test on LaTeX image
container:
- image: sphinxdoc/docker-ci
+ image: ghcr.io/sphinx-doc/sphinx-ci
env:
DO_EPUBCHECK: 1
- PATH: /python3.8/bin/:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
steps:
+ - name: Alias python3 to python
+ run: ln -s /usr/bin/python3 /usr/bin/python
- uses: actions/checkout@v3
- name: Check Python version
run: python --version
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 78483810c..c2f5420e7 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -7,7 +7,7 @@ permissions:
jobs:
ubuntu:
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
name: Python ${{ matrix.python }} (${{ matrix.docutils }})
strategy:
fail-fast: false
diff --git a/CHANGES b/CHANGES
index 0fa4318df..e1b9ccebf 100644
--- a/CHANGES
+++ b/CHANGES
@@ -49,29 +49,19 @@ Bugs fixed
Testing
--------
-Release 5.3.0 (in development)
-==============================
-
-Dependencies
-------------
-
-Incompatible changes
---------------------
-
-Deprecated
-----------
-
-Features added
---------------
+Release 5.3.0 (released Oct 16, 2022)
+=====================================
-* #10840: One can cross-reference including an option value: ``:option:`--module=foobar```.
+* #10759: LaTeX: add :confval:`latex_table_style` and support the
+ ``'booktabs'``, ``'borderless'``, and ``'colorrows'`` styles.
+ (thanks to Stefan Wiehler for initial pull requests #6666, #6671)
+* #10840: One can cross-reference including an option value like ``:option:`--module=foobar```,
+ ``:option:`--module[=foobar]``` or ``:option:`--module foobar```.
Patch by Martin Liska.
-
-Bugs fixed
-----------
-
-Testing
---------
+* #10881: autosectionlabel: Record the generated section label to the debug log.
+* #10268: Correctly URI-escape image filenames.
+* #10887: domains: Allow sections in all the content of all object description
+ directives (e.g. :rst:dir:`py:function`). Patch by Adam Turner
Release 5.2.3 (released Sep 30, 2022)
=====================================
diff --git a/doc/conf.py b/doc/conf.py
index f903fd570..5826fefa6 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -78,7 +78,7 @@ latex_elements = {
{\begin{sphinxtheindex}\end{sphinxtheindex}}
''',
'sphinxsetup': """%
-VerbatimColor={RGB}{242,242,242},%
+VerbatimColor=black!5,% tests 5.3.0 extended syntax
VerbatimBorderColor={RGB}{32,32,32},%
pre_border-radius=3pt,%
pre_box-decoration-break=slice,%
@@ -86,6 +86,7 @@ pre_box-decoration-break=slice,%
}
latex_show_urls = 'footnote'
latex_use_xindy = True
+latex_table_style = ['booktabs', 'colorrows']
autodoc_member_order = 'groupwise'
autosummary_generate = False
diff --git a/doc/extdev/deprecated.rst b/doc/extdev/deprecated.rst
index 8c850ceb6..1692f2d4e 100644
--- a/doc/extdev/deprecated.rst
+++ b/doc/extdev/deprecated.rst
@@ -10,7 +10,7 @@ major versions (for more details, please see :ref:`deprecation-policy`).
The following is a list of deprecated interfaces.
-.. tabularcolumns:: |>{\raggedright}\Y{.4}|>{\centering}\Y{.1}|>{\centering}\Y{.12}|>{\raggedright\arraybackslash}\Y{.38}|
+.. tabularcolumns:: >{\raggedright}\Y{.4}>{\centering}\Y{.1}>{\sphinxcolorblend{!95!red}\centering\noindent\bfseries\color{red}}\Y{.12}>{\raggedright\arraybackslash}\Y{.38}
.. list-table:: deprecated APIs
:header-rows: 1
@@ -19,7 +19,7 @@ The following is a list of deprecated interfaces.
* - Target
- Deprecated
- - (will be) Removed
+ - Removed
- Alternatives
* - HTML 4 support
diff --git a/doc/latex.rst b/doc/latex.rst
index ae8c256cb..e8fcb95f8 100644
--- a/doc/latex.rst
+++ b/doc/latex.rst
@@ -823,16 +823,31 @@ Do not use quotes to enclose values, whether numerical or strings.
definition of the continuation symbol was changed at 1.5 to accommodate
various font sizes (e.g. code-blocks can be in footnotes).
+.. note::
+
+ Values for colour keys must either:
+
+ - obey the syntax of the ``\definecolor`` LaTeX command, e.g. something
+ such as ``VerbatimColor={rgb}{0.2,0.3,0.5}`` or ``{RGB}{37,23,255}`` or
+ ``{gray}{0.75}`` or (only with package ``xcolor``) ``{HTML}{808080}`` or
+ ...
+
+ - or obey the syntax of the ``\colorlet`` command from package ``xcolor``
+ (which then must exist in the LaTeX installation),
+ e.g. ``VerbatimColor=red!10`` or ``red!50!green`` or ``-red!75`` or
+ ``MyPreviouslyDefinedColour`` or... Refer to xcolor_ documentation for
+ this syntax.
+
+ .. _xcolor: https://ctan.org/pkg/xcolor
+
+ .. versionchanged:: 5.3.0
+ Formerly only the ``\definecolor`` syntax was accepted.
+
``TitleColor``
The colour for titles (as configured via use of package "titlesec".)
Default: ``{rgb}{0.126,0.263,0.361}``
- .. warning::
-
- Colours set via ``'sphinxsetup'`` must obey the syntax of the
- argument of the ``color/xcolor`` packages ``\definecolor`` command.
-
``InnerLinkColor``
A colour passed to ``hyperref`` as value of ``linkcolor`` and
``citecolor``.
@@ -862,10 +877,47 @@ Do not use quotes to enclose values, whether numerical or strings.
.. versionadded:: 1.6.6
- .. note::
+.. _tablecolors:
+
+``TableRowColorHeader``
+ Sets the background colour for (all) the header rows of tables.
+
+ It will have an effect only if either the :confval:`latex_table_style`
+ contains ``'colorrows'`` or if the table is assigned the ``colorrows``
+ class. It is ignored for tables with ``nocolorrows`` class.
- Starting with this colour, and for all others following, the
- names declared to "color" or "xcolor" are prefixed with "sphinx".
+ As for the other ``'sphinxsetup'`` keys, it can also be set or modified
+ from a ``\sphinxsetup{...}`` LaTeX command inserted via the :dudir:`raw`
+ directive, or also from a LaTeX environment associated to a `container
+ class <latexcontainer_>`_ and using such ``\sphinxsetup{...}``.
+
+ Default: ``{gray}{0.86}``
+
+ There is also ``TableMergeColorHeader``. If used, sets a specific colour
+ for merged single-row cells in the header.
+
+ .. versionadded:: 5.3.0
+
+``TableRowColorOdd``
+ Sets the background colour for odd rows in tables (the row count starts at
+ ``1`` at the first non-header row). Has an effect only if the
+ :confval:`latex_table_style` contains ``'colorrows'`` or for specific
+ tables assigned the ``colorrows`` class.
+
+ Default: ``{gray}{0.92}``
+
+ There is also ``TableMergeColorOdd``.
+
+ .. versionadded:: 5.3.0
+
+``TableRowColorEven``
+ Sets the background colour for even rows in tables.
+
+ Default ``{gray}{0.98}``
+
+ There is also ``TableMergeColorEven``.
+
+ .. versionadded:: 5.3.0
``verbatimsep``
The separation between code lines and the frame.
@@ -1425,6 +1477,8 @@ Miscellany
Formerly, use of *fncychap* with other styles than ``Bjarne`` was
dysfunctional.
+.. _latexcontainer:
+
- Docutils :dudir:`container` directives are supported in LaTeX output: to
let a container class with name ``foo`` influence the final PDF via LaTeX,
it is only needed to define in the preamble an environment
diff --git a/doc/usage/configuration.rst b/doc/usage/configuration.rst
index c18c2d317..ff428a655 100644
--- a/doc/usage/configuration.rst
+++ b/doc/usage/configuration.rst
@@ -2201,6 +2201,101 @@ These options influence LaTeX output.
.. versionadded:: 1.6
+.. confval:: latex_table_style
+
+ A list of styling classes (strings). Currently supported:
+
+ - ``'booktabs'``: no vertical lines, and only 2 or 3 horizontal lines (the
+ latter if there is a header), using the booktabs_ package.
+
+ - ``'borderless'``: no lines whatsoever.
+
+ - ``'colorrows'``: the table rows are rendered with alternating background
+ colours. The interface to customize them is via :ref:`dedicated keys
+ <tablecolors>` of :ref:`latexsphinxsetup`.
+
+ .. important::
+
+ With the ``'colorrows'`` style, the ``\rowcolors`` LaTeX command
+ becomes a no-op (this command has limitations and has never correctly
+ supported all types of tables Sphinx produces in LaTeX). Please
+ update your project to use instead
+ the :ref:`latex table color configuration <tablecolors>` keys.
+
+ Default: ``[]``
+
+ .. versionadded:: 5.3.0
+
+ If using ``'booktabs'`` or ``'borderless'`` it seems recommended to also
+ opt for ``'colorrows'``...
+
+ Each table can override the global style via ``:class:`` option, or
+ ``.. rst-class::`` for no-directive tables (cf. :ref:`table-directives`).
+ Currently recognized classes are ``booktabs``, ``borderless``,
+ ``standard``, ``colorrows``, ``nocolorrows``. The latter two can be
+ combined with any of the first three. The ``standard`` class produces
+ tables with both horizontal and vertical lines (as has been the default so
+ far with Sphinx).
+
+ A single-row multi-column merged cell will obey the row colour, if it is
+ set. See also ``TableMergeColor{Header,Odd,Even}`` in the
+ :ref:`latexsphinxsetup` section.
+
+ .. note::
+
+ - It is hard-coded in LaTeX that a single cell will obey the row colour
+ even if there is a column colour set via ``\columncolor`` from a
+ column specification (see :rst:dir:`tabularcolumns`). Sphinx provides
+ ``\sphinxnorowcolor`` which can be used like this:
+
+ .. code-block:: latex
+
+ >{\columncolor{blue}\sphinxnorowcolor}
+
+ in a table column specification.
+
+ - Sphinx also provides ``\sphinxcolorblend`` which however requires the
+ xcolor_ package. Here is an example:
+
+ .. code-block:: latex
+
+ >{\sphinxcolorblend{!95!red}}
+
+ It means that in this column, the row colours will be slightly tinted
+ by red; refer to xcolor_ documentation for more on the syntax of its
+ ``\blendcolors`` command (a ``\blendcolors`` in place of
+ ``\sphinxcolorblend`` would modify colours of the cell *contents*, not
+ of the cell *background colour panel*...). You can find an example of
+ usage in the :ref:`dev-deprecated-apis` section of this document in
+ PDF format.
+
+ .. hint::
+
+ If you want to use a special colour for the *contents* of the
+ cells of a given column use ``>{\noindent\color{<color>}}``,
+ possibly in addition to the above.
+
+ - Multi-row merged cells, whether single column or multi-column
+ currently ignore any set column, row, or cell colour.
+
+ - It is possible for a simple cell to set a custom colour via the
+ :dudir:`raw` directive and the ``\cellcolor`` LaTeX command used
+ anywhere in the cell contents. This currently is without effect
+ in a merged cell, whatever its kind.
+
+ .. hint::
+
+ In a document not using ``'booktabs'`` globally, it is possible to style
+ an individual table via the ``booktabs`` class, but it will be necessary
+ to add ``r'\usepackage{booktabs}'`` to the LaTeX preamble.
+
+ On the other hand one can use ``colorrows`` class for individual tables
+ with no extra package (as Sphinx since 5.3.0 always loads colortbl_).
+
+ .. _booktabs: https://ctan.org/pkg/booktabs
+ .. _colortbl: https://ctan.org/pkg/colortbl
+ .. _xcolor: https://ctan.org/pkg/xcolor
+
.. confval:: latex_use_xindy
If ``True``, the PDF build from the LaTeX files created by Sphinx
diff --git a/doc/usage/extensions/autosectionlabel.rst b/doc/usage/extensions/autosectionlabel.rst
index caaa5db26..b5b9b51a9 100644
--- a/doc/usage/extensions/autosectionlabel.rst
+++ b/doc/usage/extensions/autosectionlabel.rst
@@ -45,3 +45,12 @@ Configuration
example, when set 1 to ``autosectionlabel_maxdepth``, labels are generated
only for top level sections, and deeper sections are not labeled. It
defaults to ``None`` (disabled).
+
+
+Debugging
+---------
+
+The ``WARNING: undefined label`` indicates that your reference in
+:rst:role:`ref` is mis-spelled. Invoking :program:`sphinx-build` with ``-vv``
+(see :option:`-v`) will print all section names and the labels that have been
+generated for them. This output can help finding the right reference label.
diff --git a/doc/usage/restructuredtext/basics.rst b/doc/usage/restructuredtext/basics.rst
index c846dc145..824b59ee2 100644
--- a/doc/usage/restructuredtext/basics.rst
+++ b/doc/usage/restructuredtext/basics.rst
@@ -370,7 +370,15 @@ Docutils supports the following directives:
- :dudir:`include` (include reStructuredText from another file) -- in Sphinx,
when given an absolute include file path, this directive takes it as
relative to the source directory
- - :dudir:`class` (assign a class attribute to the next element) [1]_
+
+ .. _rstclass:
+
+ - :dudir:`class` (assign a class attribute to the next element)
+
+ .. note::
+
+ When the default domain contains a ``class`` directive, this directive
+ will be shadowed. Therefore, Sphinx re-exports it as ``rst-class``.
* HTML specifics:
@@ -621,10 +629,3 @@ There are some problems one commonly runs into while authoring reST documents:
* **No nested inline markup:** Something like ``*see :func:`foo`*`` is not
possible.
-
-
-.. rubric:: Footnotes
-
-.. [1] When the default domain contains a :rst:dir:`class` directive, this
- directive will be shadowed. Therefore, Sphinx re-exports it as
- :rst:dir:`rst-class`.
diff --git a/doc/usage/restructuredtext/directives.rst b/doc/usage/restructuredtext/directives.rst
index 4029b04e6..44e4b5ffe 100644
--- a/doc/usage/restructuredtext/directives.rst
+++ b/doc/usage/restructuredtext/directives.rst
@@ -371,8 +371,9 @@ units as well as normal text.
.. centered:: LICENSE AGREEMENT
.. deprecated:: 1.1
- This presentation-only directive is a legacy from older versions. Use a
- :rst:dir:`rst-class` directive instead and add an appropriate style.
+ This presentation-only directive is a legacy from older versions.
+ Use a :ref:`rst-class <rstclass>` directive instead and add an
+ appropriate style.
.. rst:directive:: hlist
@@ -1045,114 +1046,78 @@ Use :ref:`reStructuredText tables <rst-tables>`, i.e. either
The :dudir:`table` directive serves as optional wrapper of the *grid* and
*simple* syntaxes.
-They work fine in HTML output, however there are some gotchas when using tables
-in LaTeX: the column width is hard to determine correctly automatically. For
-this reason, the following directive exists:
+They work fine in HTML output, but rendering tables to LaTeX is complex.
+Check the :confval:`latex_table_style`.
-.. rst:directive:: .. tabularcolumns:: column spec
-
- This directive gives a "column spec" for the next table occurring in the
- source file. The spec is the second argument to the LaTeX ``tabulary``
- package's environment (which Sphinx uses to translate tables). It can have
- values like ::
-
- |l|l|l|
-
- which means three left-adjusted, nonbreaking columns. For columns with
- longer text that should automatically be broken, use either the standard
- ``p{width}`` construct, or tabulary's automatic specifiers:
+.. versionchanged:: 1.6
+ Merged cells (multi-row, multi-column, both) from grid tables containing
+ complex contents such as multiple paragraphs, blockquotes, lists, literal
+ blocks, will render correctly to LaTeX output.
- +-----+------------------------------------------+
- |``L``| flush left column with automatic width |
- +-----+------------------------------------------+
- |``R``| flush right column with automatic width |
- +-----+------------------------------------------+
- |``C``| centered column with automatic width |
- +-----+------------------------------------------+
- |``J``| justified column with automatic width |
- +-----+------------------------------------------+
+.. rst:directive:: .. tabularcolumns:: column spec
- The automatic widths of the ``LRCJ`` columns are attributed by ``tabulary``
- in proportion to the observed shares in a first pass where the table cells
- are rendered at their natural "horizontal" widths.
+ This directive influences only the LaTeX output for the next table in
+ source. The mandatory argument is a column specification (known as an
+ "alignment preamble" in LaTeX idiom). Please refer to a LaTeX
+ documentation, such as the `wiki page`_, for basics of such a column
+ specification.
- By default, Sphinx uses a table layout with ``J`` for every column.
+ .. _wiki page: https://en.wikibooks.org/wiki/LaTeX/Tables
.. versionadded:: 0.3
- .. versionchanged:: 1.6
- Merged cells may now contain multiple paragraphs and are much better
- handled, thanks to custom Sphinx LaTeX macros. This novel situation
- motivated the switch to ``J`` specifier and not ``L`` by default.
-
- .. hint::
+ .. note::
- Sphinx actually uses ``T`` specifier having done ``\newcolumntype{T}{J}``.
- To revert to previous default, insert ``\newcolumntype{T}{L}`` in the
- LaTeX preamble (see :confval:`latex_elements`).
+ :rst:dir:`tabularcolumns` conflicts with ``:widths:`` option of table
+ directives. If both are specified, ``:widths:`` option will be ignored.
- A frequent issue with tabulary is that columns with little contents are
- "squeezed". The minimal column width is a tabulary parameter called
- ``\tymin``. You may set it globally in the LaTeX preamble via
- ``\setlength{\tymin}{40pt}`` for example.
+ Sphinx will render tables with more than 30 rows with ``longtable``.
+ Besides the ``l``, ``r``, ``c`` and ``p{width}`` column specifiers, one can
+ also use ``\X{a}{b}`` (new in version 1.5) which configures the column
+ width to be a fraction ``a/b`` of the total line width and ``\Y{f}`` (new
+ in version 1.6) where ``f`` is a decimal: for example ``\Y{0.2}`` means that
+ the column will occupy ``0.2`` times the line width.
- Else, use the :rst:dir:`tabularcolumns` directive with an explicit
- ``p{40pt}`` (for example) for that column. You may use also ``l``
- specifier but this makes the task of setting column widths more difficult
- if some merged cell intersects that column.
+ When this directive is used for a table with at most 30 rows, Sphinx will
+ render it with ``tabulary``. One can then use specific column types ``L``
+ (left), ``R`` (right), ``C`` (centered) and ``J`` (justified). They have
+ the effect of a ``p{width}`` (i.e. each cell is a LaTeX ``\parbox``) with
+ the specified internal text alignment and an automatically computed
+ ``width``.
.. warning::
- Tables with more than 30 rows are rendered using ``longtable``, not
- ``tabulary``, in order to allow pagebreaks. The ``L``, ``R``, ...
- specifiers do not work for these tables.
-
- Tables that contain list-like elements such as object descriptions,
- blockquotes or any kind of lists cannot be set out of the box with
- ``tabulary``. They are therefore set with the standard LaTeX ``tabular``
- (or ``longtable``) environment if you don't give a ``tabularcolumns``
- directive. If you do, the table will be set with ``tabulary`` but you
- must use the ``p{width}`` construct (or Sphinx's ``\X`` and ``\Y``
- specifiers described below) for the columns containing these elements.
-
- Literal blocks do not work with ``tabulary`` at all, so tables containing
- a literal block are always set with ``tabular``. The verbatim environment
- used for literal blocks only works in ``p{width}`` (and ``\X`` or ``\Y``)
- columns, hence Sphinx generates such column specs for tables containing
- literal blocks.
-
- Since Sphinx 1.5, the ``\X{a}{b}`` specifier is used (there *is* a backslash
- in the specifier letter). It is like ``p{width}`` with the width set to a
- fraction ``a/b`` of the current line width. You can use it in the
- :rst:dir:`tabularcolumns` (it is not a problem if some LaTeX macro is also
- called ``\X``.)
-
- It is *not* needed for ``b`` to be the total number of columns, nor for the
- sum of the fractions of the ``\X`` specifiers to add up to one. For example
- ``|\X{2}{5}|\X{1}{5}|\X{1}{5}|`` is legitimate and the table will occupy
- 80% of the line width, the first of its three columns having the same width
- as the sum of the next two.
-
- This is used by the ``:widths:`` option of the :dudir:`table` directive.
-
- Since Sphinx 1.6, there is also the ``\Y{f}`` specifier which admits a
- decimal argument, such has ``\Y{0.15}``: this would have the same effect as
- ``\X{3}{20}``.
+ - Cells that contain list-like elements such as object descriptions,
+ blockquotes or any kind of lists are not compatible with the ``LRCJ``
+ column types. The column type must then be some ``p{width}`` with an
+ explicit ``width`` (or ``\X{a}{b}`` or ``\Y{f}``).
- .. versionchanged:: 1.6
+ - Literal blocks do not work with ``tabulary`` at all. Sphinx will
+ fall back to ``tabular`` or ``longtable`` environments and generate a
+ suitable column specification.
- Merged cells from complex grid tables (either multi-row, multi-column, or
- both) now allow blockquotes, lists, literal blocks, ... as do regular
- cells.
+In absence of the :rst:dir:`tabularcolumns` directive, and for a table with at
+most 30 rows and no problematic cells as described in the above warning,
+Sphinx uses ``tabulary`` and the ``J`` column-type for every column.
- Sphinx's merged cells interact well with ``p{width}``, ``\X{a}{b}``,
- ``\Y{f}`` and tabulary's columns.
+.. versionchanged:: 1.6
- .. note::
+ Formerly, the ``L`` column-type was used (text is flushed-left). To revert
+ to this, include ``\newcolumntype{T}{L}`` in the LaTeX preamble, as in fact
+ Sphinx uses ``T`` and sets it by default to be an alias of ``J``.
- :rst:dir:`tabularcolumns` conflicts with ``:widths:`` option of table
- directives. If both are specified, ``:widths:`` option will be ignored.
+.. hint::
+
+ A frequent issue with ``tabulary`` is that columns with little contents
+ appear to be "squeezed". One can add to the LaTeX preamble for example
+ ``\setlength{\tymin}{40pt}`` to ensure a minimal column width of ``40pt``,
+ the ``tabulary`` default of ``10pt`` being too small.
+
+.. hint::
+ To force usage of the LaTeX ``longtable`` environment pass ``longtable`` as
+ a ``:class:`` option to :dudir:`table`, :dudir:`csv-table`, or
+ :dudir:`list-table`. Use :ref:`rst-class <rstclass>` for other tables.
Math
----
diff --git a/doc/usage/restructuredtext/domains.rst b/doc/usage/restructuredtext/domains.rst
index cd7091763..96e2bcc69 100644
--- a/doc/usage/restructuredtext/domains.rst
+++ b/doc/usage/restructuredtext/domains.rst
@@ -1792,7 +1792,8 @@ There is a set of directives allowing documenting command-line programs:
.. versionchanged:: 5.3
- One can cross-reference including an option value: ``:option:`--module=foobar```.
+ One can cross-reference including an option value: ``:option:`--module=foobar```,
+ ,``:option:`--module[=foobar]``` or ``:option:`--module foobar```.
Use :confval:`option_emphasise_placeholders` for parsing of
"variable part" of a literal text (similarly to the :rst:role:`samp` role).
diff --git a/doc/usage/theming.rst b/doc/usage/theming.rst
index 0e4b4a64d..c33c7d477 100644
--- a/doc/usage/theming.rst
+++ b/doc/usage/theming.rst
@@ -88,7 +88,7 @@ writing your own themes, refer to :doc:`/development/theming`.
Builtin themes
~~~~~~~~~~~~~~
-.. cssclass:: longtable
+.. cssclass:: longtable, standard
+--------------------+--------------------+
| **Theme overview** | |
diff --git a/sphinx/__init__.py b/sphinx/__init__.py
index 77f38cc48..31d415031 100644
--- a/sphinx/__init__.py
+++ b/sphinx/__init__.py
@@ -30,7 +30,7 @@ __display_version__ = __version__ # used for command line version
#:
#: .. versionadded:: 1.2
#: Before version 1.2, check the string ``sphinx.__version__``.
-version_info = (6, 0, 0, 'final', 0)
+version_info = (6, 0, 0, 'beta', 0)
package_dir = path.abspath(path.dirname(__file__))
diff --git a/sphinx/builders/_epub_base.py b/sphinx/builders/_epub_base.py
index 2f3917411..422fd448f 100644
--- a/sphinx/builders/_epub_base.py
+++ b/sphinx/builders/_epub_base.py
@@ -5,6 +5,7 @@ import os
import re
from os import path
from typing import Any, Dict, List, NamedTuple, Optional, Set, Tuple
+from urllib.parse import quote
from zipfile import ZIP_DEFLATED, ZIP_STORED, ZipFile
from docutils import nodes
@@ -524,7 +525,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
type='epub', subtype='unknown_project_files')
continue
filename = filename.replace(os.sep, '/')
- item = ManifestItem(html.escape(filename),
+ item = ManifestItem(html.escape(quote(filename)),
html.escape(self.make_id(filename)),
html.escape(self.media_types[ext]))
metadata['manifest_items'].append(item)
diff --git a/sphinx/builders/latex/__init__.py b/sphinx/builders/latex/__init__.py
index d07093fd2..2979589db 100644
--- a/sphinx/builders/latex/__init__.py
+++ b/sphinx/builders/latex/__init__.py
@@ -170,6 +170,9 @@ class LaTeXBuilder(Builder):
self.context.update(self.config.latex_elements)
self.context['release'] = self.config.release
self.context['use_xindy'] = self.config.latex_use_xindy
+ self.context['booktabs'] = 'booktabs' in self.config.latex_table_style
+ self.context['borderless'] = 'borderless' in self.config.latex_table_style
+ self.context['colorrows'] = 'colorrows' in self.config.latex_table_style
if self.config.today:
self.context['date'] = self.config.today
@@ -524,6 +527,7 @@ def setup(app: Sphinx) -> Dict[str, Any]:
app.add_config_value('latex_show_pagerefs', False, False)
app.add_config_value('latex_elements', {}, False)
app.add_config_value('latex_additional_files', [], False)
+ app.add_config_value('latex_table_style', [], False, [list])
app.add_config_value('latex_theme', 'manual', False, [str])
app.add_config_value('latex_theme_options', {}, False)
app.add_config_value('latex_theme_path', [], False, [list])
diff --git a/sphinx/cmd/build.py b/sphinx/cmd/build.py
index cab282bd1..b2e87770d 100644
--- a/sphinx/cmd/build.py
+++ b/sphinx/cmd/build.py
@@ -195,9 +195,7 @@ def make_main(argv: List[str] = sys.argv[1:]) -> int:
return make_mode.run_make_mode(argv[1:])
-def build_main(argv: List[str] = sys.argv[1:]) -> int:
- """Sphinx build "main" command-line entry."""
-
+def _parse_arguments(argv: List[str] = sys.argv[1:]) -> argparse.Namespace:
parser = get_parser()
args = parser.parse_args(argv)
@@ -236,6 +234,10 @@ def build_main(argv: List[str] = sys.argv[1:]) -> int:
warning = Tee(warning, warnfp) # type: ignore
error = warning
+ args.status = status
+ args.warning = warning
+ args.error = error
+
confoverrides = {}
for val in args.define:
try:
@@ -258,26 +260,55 @@ def build_main(argv: List[str] = sys.argv[1:]) -> int:
if args.nitpicky:
confoverrides['nitpicky'] = True
+ args.confoverrides = confoverrides
+
+ return args
+
+
+def build_main(argv: List[str] = sys.argv[1:]) -> int:
+ """Sphinx build "main" command-line entry."""
+ args = _parse_arguments(argv)
+
app = None
try:
confdir = args.confdir or args.sourcedir
with patch_docutils(confdir), docutils_namespace():
app = Sphinx(args.sourcedir, args.confdir, args.outputdir,
- args.doctreedir, args.builder, confoverrides, status,
- warning, args.freshenv, args.warningiserror,
+ args.doctreedir, args.builder, args.confoverrides, args.status,
+ args.warning, args.freshenv, args.warningiserror,
args.tags, args.verbosity, args.jobs, args.keep_going,
args.pdb)
app.build(args.force_all, args.filenames)
return app.statuscode
except (Exception, KeyboardInterrupt) as exc:
- handle_exception(app, args, exc, error)
+ handle_exception(app, args, exc, args.error)
return 2
+def _bug_report_info() -> int:
+ from platform import platform, python_implementation
+
+ import docutils
+ import jinja2
+
+ print('Please paste all output below into the bug report template\n\n')
+ print('```text')
+ print(f'Platform: {sys.platform}; ({platform()})')
+ print(f'Python version: {sys.version})')
+ print(f'Python implementation: {python_implementation()}')
+ print(f'Sphinx version: {sphinx.__display_version__}')
+ print(f'Docutils version: {docutils.__version__}')
+ print(f'Jinja2 version: {jinja2.__version__}')
+ print('```')
+ return 0
+
+
def main(argv: List[str] = sys.argv[1:]) -> int:
sphinx.locale.setlocale(locale.LC_ALL, '')
sphinx.locale.init_console(os.path.join(package_dir, 'locale'), 'sphinx')
+ if argv[:1] == ['--bug-report']:
+ return _bug_report_info()
if argv[:1] == ['-M']:
return make_main(argv)
else:
diff --git a/sphinx/directives/__init__.py b/sphinx/directives/__init__.py
index e59cb1295..8fcbd1fff 100644
--- a/sphinx/directives/__init__.py
+++ b/sphinx/directives/__init__.py
@@ -12,6 +12,7 @@ from sphinx.addnodes import desc_signature
from sphinx.util import docutils
from sphinx.util.docfields import DocFieldTransformer, Field, TypedField
from sphinx.util.docutils import SphinxDirective
+from sphinx.util.nodes import nested_parse_with_titles
from sphinx.util.typing import OptionSpec
if TYPE_CHECKING:
@@ -259,7 +260,7 @@ class ObjectDescription(SphinxDirective, Generic[T]):
# needed for association of version{added,changed} directives
self.env.temp_data['object'] = self.names[0]
self.before_content()
- self.state.nested_parse(self.content, self.content_offset, contentnode)
+ nested_parse_with_titles(self.state, self.content, contentnode)
self.transform_content(contentnode)
self.env.app.emit('object-description-transform',
self.domain, self.objtype, contentnode)
diff --git a/sphinx/domains/std.py b/sphinx/domains/std.py
index f6d1c4dc4..586ac4d20 100644
--- a/sphinx/domains/std.py
+++ b/sphinx/domains/std.py
@@ -943,10 +943,17 @@ class StandardDomain(Domain):
progname = node.get('std:program')
target = target.strip()
docname, labelid = self.progoptions.get((progname, target), ('', ''))
- # for :option:`-foo=bar` search for -foo option directive
- if not docname and '=' in target:
- target2 = target[:target.find('=')]
- docname, labelid = self.progoptions.get((progname, target2), ('', ''))
+ if not docname:
+ # Support also reference that contain an option value:
+ # * :option:`-foo=bar`
+ # * :option:`-foo[=bar]`
+ # * :option:`-foo bar`
+ for needle in {'=', '[=', ' '}:
+ if needle in target:
+ stem, _, _ = target.partition(needle)
+ docname, labelid = self.progoptions.get((progname, stem), ('', ''))
+ if docname:
+ break
if not docname:
commands = []
while ws_re.search(target):
diff --git a/sphinx/ext/autodoc/preserve_defaults.py b/sphinx/ext/autodoc/preserve_defaults.py
index 0c21c3081..2cd58ade5 100644
--- a/sphinx/ext/autodoc/preserve_defaults.py
+++ b/sphinx/ext/autodoc/preserve_defaults.py
@@ -8,6 +8,7 @@ import ast
import inspect
from typing import Any, Dict, List, Optional
+import sphinx
from sphinx.application import Sphinx
from sphinx.locale import __
from sphinx.pycode.ast import parse as ast_parse
@@ -117,6 +118,6 @@ def setup(app: Sphinx) -> Dict[str, Any]:
app.connect('autodoc-before-process-signature', update_defvalue)
return {
- 'version': '1.0',
+ 'version': sphinx.__display_version__,
'parallel_read_safe': True
}
diff --git a/sphinx/ext/autodoc/typehints.py b/sphinx/ext/autodoc/typehints.py
index 98c51e9e9..2acacfe94 100644
--- a/sphinx/ext/autodoc/typehints.py
+++ b/sphinx/ext/autodoc/typehints.py
@@ -7,6 +7,7 @@ from typing import Any, Dict, Iterable, Set, cast
from docutils import nodes
from docutils.nodes import Element
+import sphinx
from sphinx import addnodes
from sphinx.application import Sphinx
from sphinx.util import inspect, typing
@@ -206,7 +207,7 @@ def setup(app: Sphinx) -> Dict[str, Any]:
app.connect('object-description-transform', merge_typehints)
return {
- 'version': 'builtin',
+ 'version': sphinx.__display_version__,
'parallel_read_safe': True,
'parallel_write_safe': True,
}
diff --git a/sphinx/ext/autosectionlabel.py b/sphinx/ext/autosectionlabel.py
index ff2f695ec..7dc9ddaec 100644
--- a/sphinx/ext/autosectionlabel.py
+++ b/sphinx/ext/autosectionlabel.py
@@ -5,6 +5,7 @@ from typing import Any, Dict, cast
from docutils import nodes
from docutils.nodes import Node
+import sphinx
from sphinx.application import Sphinx
from sphinx.domains.std import StandardDomain
from sphinx.locale import __
@@ -39,6 +40,9 @@ def register_sections_as_label(app: Sphinx, document: Node) -> None:
name = nodes.fully_normalize_name(ref_name)
sectname = clean_astext(title)
+ logger.debug(__('section "%s" gets labeled as "%s"'),
+ ref_name, name,
+ location=node, type='autosectionlabel', subtype=docname)
if name in domain.labels:
logger.warning(__('duplicate label %s, other instance in %s'),
name, app.env.doc2path(domain.labels[name][0]),
@@ -54,7 +58,7 @@ def setup(app: Sphinx) -> Dict[str, Any]:
app.connect('doctree-read', register_sections_as_label)
return {
- 'version': 'builtin',
+ 'version': sphinx.__display_version__,
'parallel_read_safe': True,
'parallel_write_safe': True,
}
diff --git a/sphinx/ext/duration.py b/sphinx/ext/duration.py
index 94fd9077a..13b92fc1a 100644
--- a/sphinx/ext/duration.py
+++ b/sphinx/ext/duration.py
@@ -7,6 +7,7 @@ from typing import Any, Dict, List, cast
from docutils import nodes
+import sphinx
from sphinx.application import Sphinx
from sphinx.domains import Domain
from sphinx.locale import __
@@ -81,7 +82,7 @@ def setup(app: Sphinx) -> Dict[str, Any]:
app.connect('build-finished', on_build_finished)
return {
- 'version': 'builtin',
+ 'version': sphinx.__display_version__,
'parallel_read_safe': True,
'parallel_write_safe': True,
}
diff --git a/sphinx/ext/extlinks.py b/sphinx/ext/extlinks.py
index 55e7d94c2..e039a18d5 100644
--- a/sphinx/ext/extlinks.py
+++ b/sphinx/ext/extlinks.py
@@ -66,7 +66,11 @@ class ExternalLinksChecker(SphinxPostTransform):
uri_pattern = re.compile(re.escape(base_uri).replace('%s', '(?P<value>.+)'))
match = uri_pattern.match(uri)
- if match and match.groupdict().get('value'):
+ if (
+ match and
+ match.groupdict().get('value') and
+ '/' not in match.groupdict()['value']
+ ):
# build a replacement suggestion
msg = __('hardcoded link %r could be replaced by an extlink '
'(try using %r instead)')
diff --git a/sphinx/ext/imgconverter.py b/sphinx/ext/imgconverter.py
index 2a2260c17..599984c18 100644
--- a/sphinx/ext/imgconverter.py
+++ b/sphinx/ext/imgconverter.py
@@ -5,6 +5,7 @@ import sys
from subprocess import PIPE, CalledProcessError
from typing import Any, Dict
+import sphinx
from sphinx.application import Sphinx
from sphinx.errors import ExtensionError
from sphinx.locale import __
@@ -83,7 +84,7 @@ def setup(app: Sphinx) -> Dict[str, Any]:
app.add_config_value('image_converter_args', [], 'env')
return {
- 'version': 'builtin',
+ 'version': sphinx.__display_version__,
'parallel_read_safe': True,
'parallel_write_safe': True,
}
diff --git a/sphinx/ext/imgmath.py b/sphinx/ext/imgmath.py
index ddef58187..f00567e19 100644
--- a/sphinx/ext/imgmath.py
+++ b/sphinx/ext/imgmath.py
@@ -1,7 +1,6 @@
"""Render math in HTML via dvipng or dvisvgm."""
import base64
-import posixpath
import re
import shutil
import subprocess
@@ -157,13 +156,10 @@ def convert_dvi_to_image(command: List[str], name: str) -> Tuple[str, str]:
raise MathExtError('%s exited with error' % name, exc.stderr, exc.stdout) from exc
-def convert_dvi_to_png(dvipath: str, builder: Builder) -> Tuple[str, Optional[int]]:
+def convert_dvi_to_png(dvipath: str, builder: Builder, out_path: str) -> Optional[int]:
"""Convert DVI file to PNG image."""
- tempdir = ensure_tempdir(builder)
- filename = path.join(tempdir, 'math.png')
-
name = 'dvipng'
- command = [builder.config.imgmath_dvipng, '-o', filename, '-T', 'tight', '-z9']
+ command = [builder.config.imgmath_dvipng, '-o', out_path, '-T', 'tight', '-z9']
command.extend(builder.config.imgmath_dvipng_args)
if builder.config.imgmath_use_preview:
command.append('--depth')
@@ -177,19 +173,16 @@ def convert_dvi_to_png(dvipath: str, builder: Builder) -> Tuple[str, Optional[in
matched = depth_re.match(line)
if matched:
depth = int(matched.group(1))
- write_png_depth(filename, depth)
+ write_png_depth(out_path, depth)
break
- return filename, depth
+ return depth
-def convert_dvi_to_svg(dvipath: str, builder: Builder) -> Tuple[str, Optional[int]]:
+def convert_dvi_to_svg(dvipath: str, builder: Builder, out_path: str) -> Optional[int]:
"""Convert DVI file to SVG image."""
- tempdir = ensure_tempdir(builder)
- filename = path.join(tempdir, 'math.svg')
-
name = 'dvisvgm'
- command = [builder.config.imgmath_dvisvgm, '-o', filename]
+ command = [builder.config.imgmath_dvisvgm, '-o', out_path]
command.extend(builder.config.imgmath_dvisvgm_args)
command.append(dvipath)
@@ -201,16 +194,16 @@ def convert_dvi_to_svg(dvipath: str, builder: Builder) -> Tuple[str, Optional[in
matched = depthsvg_re.match(line)
if matched:
depth = round(float(matched.group(1)) * 100 / 72.27) # assume 100ppi
- write_svg_depth(filename, depth)
+ write_svg_depth(out_path, depth)
break
- return filename, depth
+ return depth
def render_math(
self: HTMLTranslator,
math: str,
-) -> Tuple[Optional[str], Optional[int], Optional[str], Optional[str]]:
+) -> Tuple[Optional[str], Optional[int]]:
"""Render the LaTeX math expression *math* using latex and dvipng or
dvisvgm.
@@ -234,43 +227,43 @@ def render_math(
self.builder.config,
self.builder.confdir)
- filename = "%s.%s" % (sha1(latex.encode()).hexdigest(), image_format)
- relfn = posixpath.join(self.builder.imgpath, 'math', filename)
- outfn = path.join(self.builder.outdir, self.builder.imagedir, 'math', filename)
- if path.isfile(outfn):
+ filename = f"{sha1(latex.encode()).hexdigest()}.{image_format}"
+ generated_path = path.join(self.builder.outdir, self.builder.imagedir, 'math', filename)
+ ensuredir(path.dirname(generated_path))
+ if path.isfile(generated_path):
if image_format == 'png':
- depth = read_png_depth(outfn)
+ depth = read_png_depth(generated_path)
elif image_format == 'svg':
- depth = read_svg_depth(outfn)
- return relfn, depth, None, outfn
+ depth = read_svg_depth(generated_path)
+ return generated_path, depth
# if latex or dvipng (dvisvgm) has failed once, don't bother to try again
if hasattr(self.builder, '_imgmath_warned_latex') or \
hasattr(self.builder, '_imgmath_warned_image_translator'):
- return None, None, None, None
+ return None, None
# .tex -> .dvi
try:
dvipath = compile_math(latex, self.builder)
except InvokeError:
self.builder._imgmath_warned_latex = True # type: ignore
- return None, None, None, None
+ return None, None
# .dvi -> .png/.svg
try:
if image_format == 'png':
- imgpath, depth = convert_dvi_to_png(dvipath, self.builder)
+ depth = convert_dvi_to_png(dvipath, self.builder, generated_path)
elif image_format == 'svg':
- imgpath, depth = convert_dvi_to_svg(dvipath, self.builder)
+ depth = convert_dvi_to_svg(dvipath, self.builder, generated_path)
except InvokeError:
self.builder._imgmath_warned_image_translator = True # type: ignore
- return None, None, None, None
+ return None, None
- return relfn, depth, imgpath, outfn
+ return generated_path, depth
-def render_maths_to_base64(image_format: str, outfn: Optional[str]) -> str:
- with open(outfn, "rb") as f:
+def render_maths_to_base64(image_format: str, generated_path: Optional[str]) -> str:
+ with open(generated_path, "rb") as f:
encoded = base64.b64encode(f.read()).decode(encoding='utf-8')
if image_format == 'png':
return f'data:image/png;base64,{encoded}'
@@ -279,15 +272,23 @@ def render_maths_to_base64(image_format: str, outfn: Optional[str]) -> str:
raise MathExtError('imgmath_image_format must be either "png" or "svg"')
-def cleanup_tempdir(app: Sphinx, exc: Exception) -> None:
+def clean_up_files(app: Sphinx, exc: Exception) -> None:
if exc:
return
- if not hasattr(app.builder, '_imgmath_tempdir'):
- return
- try:
- shutil.rmtree(app.builder._mathpng_tempdir) # type: ignore
- except Exception:
- pass
+
+ if hasattr(app.builder, '_imgmath_tempdir'):
+ try:
+ shutil.rmtree(app.builder._imgmath_tempdir) # type: ignore
+ except Exception:
+ pass
+
+ if app.builder.config.imgmath_embed:
+ # in embed mode, the images are still generated in the math output dir
+ # to be shared across workers, but are not useful to the final document
+ try:
+ shutil.rmtree(path.join(app.builder.outdir, app.builder.imagedir, 'math'))
+ except Exception:
+ pass
def get_tooltip(self: HTMLTranslator, node: Element) -> str:
@@ -298,7 +299,7 @@ def get_tooltip(self: HTMLTranslator, node: Element) -> str:
def html_visit_math(self: HTMLTranslator, node: nodes.math) -> None:
try:
- fname, depth, imgpath, outfn = render_math(self, '$' + node.astext() + '$')
+ rendered_path, depth = render_math(self, '$' + node.astext() + '$')
except MathExtError as exc:
msg = str(exc)
sm = nodes.system_message(msg, type='WARNING', level=2,
@@ -306,20 +307,18 @@ def html_visit_math(self: HTMLTranslator, node: nodes.math) -> None:
sm.walkabout(self)
logger.warning(__('display latex %r: %s'), node.astext(), msg)
raise nodes.SkipNode from exc
- if self.builder.config.imgmath_embed:
- image_format = self.builder.config.imgmath_image_format.lower()
- img_src = render_maths_to_base64(image_format, imgpath)
- else:
- # Move generated image on tempdir to build dir
- if imgpath is not None:
- ensuredir(path.dirname(outfn))
- shutil.move(imgpath, outfn)
- img_src = fname
- if img_src is None:
+
+ if rendered_path is None:
# something failed -- use text-only as a bad substitute
self.body.append('<span class="math">%s</span>' %
self.encode(node.astext()).strip())
else:
+ if self.builder.config.imgmath_embed:
+ image_format = self.builder.config.imgmath_image_format.lower()
+ img_src = render_maths_to_base64(image_format, rendered_path)
+ else:
+ relative_path = path.relpath(rendered_path, self.builder.outdir)
+ img_src = relative_path.replace(path.sep, '/')
c = f'<img class="math" src="{img_src}"' + get_tooltip(self, node)
if depth is not None:
c += f' style="vertical-align: {-depth:d}px"'
@@ -333,7 +332,7 @@ def html_visit_displaymath(self: HTMLTranslator, node: nodes.math_block) -> None
else:
latex = wrap_displaymath(node.astext(), None, False)
try:
- fname, depth, imgpath, outfn = render_math(self, latex)
+ rendered_path, depth = render_math(self, latex)
except MathExtError as exc:
msg = str(exc)
sm = nodes.system_message(msg, type='WARNING', level=2,
@@ -348,20 +347,18 @@ def html_visit_displaymath(self: HTMLTranslator, node: nodes.math_block) -> None
self.body.append('<span class="eqno">(%s)' % number)
self.add_permalink_ref(node, _('Permalink to this equation'))
self.body.append('</span>')
- if self.builder.config.imgmath_embed:
- image_format = self.builder.config.imgmath_image_format.lower()
- img_src = render_maths_to_base64(image_format, imgpath)
- else:
- # Move generated image on tempdir to build dir
- if imgpath is not None:
- ensuredir(path.dirname(outfn))
- shutil.move(imgpath, outfn)
- img_src = fname
- if img_src is None:
+
+ if rendered_path is None:
# something failed -- use text-only as a bad substitute
self.body.append('<span class="math">%s</span></p>\n</div>' %
self.encode(node.astext()).strip())
else:
+ if self.builder.config.imgmath_embed:
+ image_format = self.builder.config.imgmath_image_format.lower()
+ img_src = render_maths_to_base64(image_format, rendered_path)
+ else:
+ relative_path = path.relpath(rendered_path, self.builder.outdir)
+ img_src = relative_path.replace(path.sep, '/')
self.body.append(f'<img src="{img_src}"' + get_tooltip(self, node) +
'/></p>\n</div>')
raise nodes.SkipNode
@@ -386,5 +383,5 @@ def setup(app: Sphinx) -> Dict[str, Any]:
app.add_config_value('imgmath_add_tooltips', True, 'html')
app.add_config_value('imgmath_font_size', 12, 'html')
app.add_config_value('imgmath_embed', False, 'html', [bool])
- app.connect('build-finished', cleanup_tempdir)
+ app.connect('build-finished', clean_up_files)
return {'version': sphinx.__display_version__, 'parallel_read_safe': True}
diff --git a/sphinx/ext/napoleon/__init__.py b/sphinx/ext/napoleon/__init__.py
index bcb12416e..06ca82779 100644
--- a/sphinx/ext/napoleon/__init__.py
+++ b/sphinx/ext/napoleon/__init__.py
@@ -2,7 +2,7 @@
from typing import Any, Dict, List
-from sphinx import __display_version__ as __version__
+import sphinx
from sphinx.application import Sphinx
from sphinx.ext.napoleon.docstring import GoogleDocstring, NumpyDocstring
from sphinx.util import inspect
@@ -310,7 +310,7 @@ def setup(app: Sphinx) -> Dict[str, Any]:
"""
if not isinstance(app, Sphinx):
# probably called by tests
- return {'version': __version__, 'parallel_read_safe': True}
+ return {'version': sphinx.__display_version__, 'parallel_read_safe': True}
_patch_python_domain()
@@ -320,7 +320,7 @@ def setup(app: Sphinx) -> Dict[str, Any]:
for name, (default, rebuild) in Config._config_values.items():
app.add_config_value(name, default, rebuild)
- return {'version': __version__, 'parallel_read_safe': True}
+ return {'version': sphinx.__display_version__, 'parallel_read_safe': True}
def _patch_python_domain() -> None:
diff --git a/sphinx/templates/latex/latex.tex_t b/sphinx/templates/latex/latex.tex_t
index 66408a4c4..deb030504 100644
--- a/sphinx/templates/latex/latex.tex_t
+++ b/sphinx/templates/latex/latex.tex_t
@@ -25,6 +25,15 @@
%% memoir class requires extra handling
\makeatletter\@ifclassloaded{memoir}
{\ifdefined\memhyperindexfalse\memhyperindexfalse\fi}{}\makeatother
+<% endif %>
+<% if booktabs -%>
+\PassOptionsToPackage{booktabs}{sphinx}
+<% endif -%>
+<% if borderless -%>
+\PassOptionsToPackage{borderless}{sphinx}
+<% endif -%>
+<% if colorrows -%>
+\PassOptionsToPackage{colorrows}{sphinx}
<% endif -%>
<%= passoptionstopackages %>
\PassOptionsToPackage{warn}{textcomp}
diff --git a/sphinx/templates/latex/longtable.tex_t b/sphinx/templates/latex/longtable.tex_t
index 8d4cd748c..f5cb522ce 100644
--- a/sphinx/templates/latex/longtable.tex_t
+++ b/sphinx/templates/latex/longtable.tex_t
@@ -1,4 +1,28 @@
-\begin{savenotes}\sphinxatlongtablestart\begin{longtable}
+\begin{savenotes}
+\sphinxatlongtablestart
+\sphinxthistablewithglobalstyle
+<% if 'booktabs' in table.styles -%>
+\sphinxthistablewithbooktabsstyle
+<% endif -%>
+<% if 'borderless' in table.styles -%>
+\sphinxthistablewithborderlessstyle
+<% endif -%>
+<% if 'standard' in table.styles -%>
+\sphinxthistablewithstandardstyle
+<% endif -%>
+<% if 'vlines' in table.styles -%>
+\sphinxthistablewithvlinesstyle
+<% endif -%>
+<% if 'novlines' in table.styles -%>
+\sphinxthistablewithnovlinesstyle
+<% endif -%>
+<% if 'colorrows' in table.styles -%>
+\sphinxthistablewithcolorrowsstyle
+<% endif -%>
+<% if 'nocolorrows' in table.styles -%>
+\sphinxthistablewithnocolorrowsstyle
+<% endif -%>
+\begin{longtable}
<%- if table.align in ('center', 'default') -%>
[c]
<%- elif table.align == 'left' -%>
@@ -10,25 +34,37 @@
<%- if table.caption -%>
\sphinxthelongtablecaptionisattop
\caption{<%= ''.join(table.caption) %>\strut}<%= labels %>\\*[\sphinxlongtablecapskipadjust]
-\hline
<% elif labels -%>
-\hline\noalign{\phantomsection<%= labels %>}%
-<% else -%>
-\hline
+\noalign{\phantomsection<%= labels %>}%
+<% endif -%>
+\sphinxtoprule
+<%= ''.join(table.header) -%>
+<%- if table.header -%>
+\sphinxmidrule
<% endif -%>
-<%= ''.join(table.header) %>
\endfirsthead
-\multicolumn{<%= table.colcount %>}{c}%
-{\makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} <%= _('continued from previous page') %>}}}\\
-\hline
-<%= ''.join(table.header) %>
+\multicolumn{<%= table.colcount %>}{c}{\sphinxnorowcolor
+ \makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} <%= _('continued from previous page') %>}}%
+}\\
+\sphinxtoprule
+<%= ''.join(table.header) -%>
+<%- if table.header -%>
+\sphinxmidrule
+<% endif -%>
\endhead
-\hline
-\multicolumn{<%= table.colcount %>}{r}{\makebox[0pt][r]{\sphinxtablecontinued{<%= _('continues on next page') %>}}}\\
+\sphinxbottomrule
+\multicolumn{<%= table.colcount %>}{r}{\sphinxnorowcolor
+ \makebox[0pt][r]{\sphinxtablecontinued{<%= _('continues on next page') %>}}%
+}\\
\endfoot
\endlastfoot
-<%= ''.join(table.body) %>
-\end{longtable}\sphinxatlongtableend\end{savenotes}
+\sphinxtableatstartofbodyhook
+<%= ''.join(table.body) -%>
+\sphinxbottomrule
+\end{longtable}
+\sphinxtableafterendhook
+\sphinxatlongtableend
+\end{savenotes}
diff --git a/sphinx/templates/latex/tabular.tex_t b/sphinx/templates/latex/tabular.tex_t
index a0db7faff..0a9310a5e 100644
--- a/sphinx/templates/latex/tabular.tex_t
+++ b/sphinx/templates/latex/tabular.tex_t
@@ -1,4 +1,26 @@
\begin{savenotes}\sphinxattablestart
+\sphinxthistablewithglobalstyle
+<% if 'booktabs' in table.styles -%>
+\sphinxthistablewithbooktabsstyle
+<% endif -%>
+<% if 'borderless' in table.styles -%>
+\sphinxthistablewithborderlessstyle
+<% endif -%>
+<% if 'standard' in table.styles -%>
+\sphinxthistablewithstandardstyle
+<% endif -%>
+<% if 'vlines' in table.styles -%>
+\sphinxthistablewithvlinesstyle
+<% endif -%>
+<% if 'novlines' in table.styles -%>
+\sphinxthistablewithnovlinesstyle
+<% endif -%>
+<% if 'colorrows' in table.styles -%>
+\sphinxthistablewithcolorrowsstyle
+<% endif -%>
+<% if 'nocolorrows' in table.styles -%>
+\sphinxthistablewithnocolorrowsstyle
+<% endif -%>
<% if table.align -%>
<%- if table.align in ('center', 'default') -%>
\centering
@@ -19,9 +41,14 @@
\phantomsection<%= labels %>\nobreak
<% endif -%>
\begin{tabular}[t]<%= table.get_colspec() -%>
-\hline
-<%= ''.join(table.header) %>
-<%=- ''.join(table.body) %>
+\sphinxtoprule
+<%= ''.join(table.header) -%>
+<%- if table.header -%>
+\sphinxmidrule
+<% endif -%>
+\sphinxtableatstartofbodyhook
+<%=- ''.join(table.body) -%>
+\sphinxbottomrule
\end{tabular}
-\par
+\sphinxtableafterendhook\par
\sphinxattableend\end{savenotes}
diff --git a/sphinx/templates/latex/tabulary.tex_t b/sphinx/templates/latex/tabulary.tex_t
index 3236b798a..6ebcec6d2 100644
--- a/sphinx/templates/latex/tabulary.tex_t
+++ b/sphinx/templates/latex/tabulary.tex_t
@@ -1,4 +1,26 @@
\begin{savenotes}\sphinxattablestart
+\sphinxthistablewithglobalstyle
+<% if 'booktabs' in table.styles -%>
+\sphinxthistablewithbooktabsstyle
+<% endif -%>
+<% if 'borderless' in table.styles -%>
+\sphinxthistablewithborderlessstyle
+<% endif -%>
+<% if 'standard' in table.styles -%>
+\sphinxthistablewithstandardstyle
+<% endif -%>
+<% if 'vlines' in table.styles -%>
+\sphinxthistablewithvlinesstyle
+<% endif -%>
+<% if 'novlines' in table.styles -%>
+\sphinxthistablewithnovlinesstyle
+<% endif -%>
+<% if 'colorrows' in table.styles -%>
+\sphinxthistablewithcolorrowsstyle
+<% endif -%>
+<% if 'nocolorrows' in table.styles -%>
+\sphinxthistablewithnocolorrowsstyle
+<% endif -%>
<% if table.align -%>
<%- if table.align in ('center', 'default') -%>
\centering
@@ -19,9 +41,14 @@
\phantomsection<%= labels %>\nobreak
<% endif -%>
\begin{tabulary}{\linewidth}[t]<%= table.get_colspec() -%>
-\hline
-<%= ''.join(table.header) %>
-<%=- ''.join(table.body) %>
+\sphinxtoprule
+<%= ''.join(table.header) -%>
+<%- if table.header -%>
+\sphinxmidrule
+<% endif -%>
+\sphinxtableatstartofbodyhook
+<%=- ''.join(table.body) -%>
+\sphinxbottomrule
\end{tabulary}
-\par
+\sphinxtableafterendhook\par
\sphinxattableend\end{savenotes}
diff --git a/sphinx/texinputs/sphinx.sty b/sphinx/texinputs/sphinx.sty
index 8e01c8ac2..0ac55cc49 100644
--- a/sphinx/texinputs/sphinx.sty
+++ b/sphinx/texinputs/sphinx.sty
@@ -6,7 +6,7 @@
%
\NeedsTeXFormat{LaTeX2e}[1995/12/01]
-\ProvidesPackage{sphinx}[2022/06/30 v5.1.0 LaTeX package (Sphinx markup)]
+\ProvidesPackage{sphinx}[2022/08/15 v5.3.0 LaTeX package (Sphinx markup)]
% provides \ltx@ifundefined
% (many packages load ltxcmds: graphicx does for pdftex and lualatex but
@@ -17,6 +17,7 @@
%% for deprecation warnings
\newcommand\sphinxdeprecationwarning[4]{% #1 the deprecated macro or name,
% #2 = when deprecated, #3 = when removed, #4 = additional info
+ {% limit scope of \spx@tempa, \AtEndDocument works even if nested.
\edef\spx@tempa{\detokenize{#1}}%
\ltx@ifundefined{sphinx_depr_\spx@tempa}{%
\global\expandafter\let\csname sphinx_depr_\spx@tempa\endcsname\spx@tempa
@@ -28,7 +29,43 @@
\@spaces- and removed at Sphinx #3.^^J
#4^^J****}}%
}{% warning already emitted (at end of latex log), don't repeat
- }}
+ }%
+ }% end of scope limiting group for \spx@tempa
+}
+%% important build warnings use an undefined reference to induce latexmk
+%% into complaining (once per warning) at very end of console output
+\newcommand\sphinxbuildwarning[1]{%
+ \ifcsname sphinx_emitted_#1\endcsname
+ \else
+ \global\expandafter\let\csname sphinx_emitted_#1\endcsname\@empty
+ \AtEndDocument{\hbox{% should the printing of text be made conditional on
+ % some boolean?
+ \bfseries\color{red}%
+ \@nameuse{sphinx_buildwarning_#1}%
+ % place an undefined reference deliberately
+ \let\nfss@text\@gobble % no ??
+ \ref{!!\@nameuse{sphinx_buildwarning_#1}}%
+ }}%
+ \fi
+}
+\@namedef{sphinx_buildwarning_coloursyntax}{%
+ The colours whose definition used xcolor syntax were set to white
+ as xcolor was not found; check the latex log warnings for details}
+\@namedef{sphinx_buildwarning_colorblend}{%
+ Command \string\sphinxcolorblend\space seen but ignored in tables
+ as xcolor was not found; check the latex log warnings for details}
+\@namedef{sphinx_buildwarning_nopict2e}{%
+ Some radii options for box corners used; they were ignored as pict2e
+ was not found}
+\@namedef{sphinx_buildwarning_badtitlesec}{%
+ Your system has titlesec version 2.10.1 which causes disappearance
+ of section numbers; check the latex log warning for details}
+\@namedef{sphinx_buildwarning_booktabs}{%
+ Some tables with booktabs class (check latex log) but booktabs
+ package not loaded; add its loading to the latex preamble}%
+\@namedef{sphinx_buildwarning_badfootnotes}{%
+ Footnote rendering may have had problems, due to extra package or
+ document class; check latex log for instructions}%
%% OPTION HANDLING
@@ -47,16 +84,62 @@
}{
\RequirePackage{color}
}
-% the \colorlet of xcolor (if at all loaded) is overkill for our use case
+
+% the \colorlet of xcolor (if at all loaded) is overkill for our internal use
\newcommand{\sphinxcolorlet}[2]
{\expandafter\let\csname\@backslashchar color@#1\expandafter\endcsname
\csname\@backslashchar color@#2\endcsname }
+% (5.3.0) allow colour options to use both the \definecolor and the \colorlet
+% syntaxes, for example VerbatimColor={gray}{0.9} or VerbatimColor=red!10
+% In the latter case we need the real \colorlet from xcolor package.
+\def\spx@defineorletcolor#1{%
+ \def\spx@definedcolor{{#1}}%
+ \futurelet\spx@token\spx@defineorlet}
+\def\spx@defineorlet{%
+ \ifx\spx@token\bgroup
+ \expandafter\spx@definecolor\else\expandafter\spx@colorlet\fi}
+\def\spx@colorlet#1\relax{\expandafter\colorlet\spx@definedcolor{#1}}
+\def\spx@definecolor{\expandafter\definecolor\spx@definedcolor}
+%
+\@ifpackageloaded{xcolor}%
+ {}%
+ {% xcolor not loaded because it was not found in the LaTeX installation
+\def\spx@colorlet#1\relax{%
+ \sphinxbuildwarning{coloursyntax}%
+ \PackageWarning{sphinx}{%
+Sorry, the #1 syntax requires package xcolor,\MessageBreak
+which was not found on your TeX/LaTeX installation.\MessageBreak
+\@spaces\expandafter\@firstofone\spx@definedcolor\MessageBreak
+will be set to white}%
+ \expandafter\definecolor\spx@definedcolor{rgb}{1,1,1}%
+ }% end of redefinition of \spx@colorlet
+ }% end of xcolor not found branch
+
% Handle options via "kvoptions" (later loaded by hyperref anyhow)
\RequirePackage{kvoptions}
\SetupKeyvalOptions{prefix=spx@opt@} % use \spx@opt@ prefix
+% Optional usage of booktabs package for tables
+\DeclareBoolOption[false]{booktabs}
+\DeclareBoolOption[false]{borderless}
+\DeclareBoolOption[true]{booktabscolorgaps}
+\DeclareVoidOption{booktabsnogaps}{%
+ \ifx\@nodocument\relax
+ % in body
+ \expandafter\@firstofone
+ \else
+ % in preamble, wait for at begin document
+ \expandafter\AtBeginDocument
+ \fi
+ {\ifdefined\abovetopsep % silently do nothing if booktabs not loaded
+ \abovetopsep\z@\belowrulesep\z@\aboverulesep\z@\belowbottomsep\z@
+ \fi
+ }%
+}
+% Coloured table rows
+\DeclareBoolOption[false]{colorrows}
% Sphinx legacy text layout: 1in margins on all four sides
\ifx\@jsc@uplatextrue\@undefined
\DeclareStringOption[1in]{hmargin}
@@ -143,20 +226,42 @@
% same problems as for dimensions: we want the key handler to use \definecolor.
% first, some colours with no prefix, for backwards compatibility
\newcommand*{\sphinxDeclareColorOption}[2]{%
+ % set the initial default; only \definecolor syntax for defaults!
\definecolor{#1}#2%
- \define@key{sphinx}{#1}{\definecolor{#1}##1}%
+ % set the key handler to accept both \definecolor and \colorlet syntax
+ \define@key{sphinx}{#1}{\spx@defineorletcolor{#1}##1\relax}%
}%
\sphinxDeclareColorOption{TitleColor}{{rgb}{0.126,0.263,0.361}}
\sphinxDeclareColorOption{InnerLinkColor}{{rgb}{0.208,0.374,0.486}}
\sphinxDeclareColorOption{OuterLinkColor}{{rgb}{0.216,0.439,0.388}}
\sphinxDeclareColorOption{VerbatimColor}{{rgb}{1,1,1}}
\sphinxDeclareColorOption{VerbatimBorderColor}{{rgb}{0,0,0}}
-% now the colours defined with "sphinx" prefix in their names
+% all other colours will be named with a "sphinx" prefix
\newcommand*{\sphinxDeclareSphinxColorOption}[2]{%
- % set the initial default
+ % set the initial default; only \definecolor syntax for defaults!
\definecolor{sphinx#1}#2%
- % set the key handler. The "value" ##1 must be acceptable by \definecolor.
- \define@key{sphinx}{#1}{\definecolor{sphinx#1}##1}%
+ % set the key handler to accept both \definecolor and \colorlet syntax
+ \define@key{sphinx}{#1}{\spx@defineorletcolor{sphinx#1}##1\relax}%
+}%
+% table row colors
+\sphinxDeclareSphinxColorOption{TableRowColorHeader}{{gray}{0.86}}
+\sphinxDeclareSphinxColorOption{TableRowColorOdd}{{gray}{0.92}}
+\sphinxDeclareSphinxColorOption{TableRowColorEven}{{gray}{0.98}}
+% if not set, the "Merge" colour will keep in sync with the "Row" colour
+\def\sphinxTableMergeColorHeader{sphinxTableRowColorHeader}
+\define@key{sphinx}{TableMergeColorHeader}{%
+ \spx@defineorletcolor{sphinxTableMergeColorHeader}#1\relax
+ \def\sphinxTableMergeColorHeader{sphinxTableMergeColorHeader}%
+}%
+\def\sphinxTableMergeColorOdd{sphinxTableRowColorOdd}
+\define@key{sphinx}{TableMergeColorOdd}{%
+ \spx@defineorletcolor{sphinxTableMergeColorOdd}#1\relax
+ \def\sphinxTableMergeColorOdd{sphinxTableMergeColorOdd}%
+}%
+\def\sphinxTableMergeColorEven{sphinxTableRowColorEven}
+\define@key{sphinx}{TableMergeColorEven}{%
+ \spx@defineorletcolor{sphinxTableMergeColorEven}#1\relax
+ \def\sphinxTableMergeColorEven{sphinxTableMergeColorEven}%
}%
% Default color chosen to be as in minted.sty LaTeX package!
\sphinxDeclareSphinxColorOption{VerbatimHighlightColor}{{rgb}{0.878,1,1}}
@@ -292,21 +397,21 @@
\newif\ifspx@pre@withbordercolor
\define@key{sphinx}{pre_border-TeXcolor}{%
\spx@pre@withbordercolortrue
- \definecolor{VerbatimBorderColor}#1% legacy colour name with no sphinx prefix
+ \spx@defineorletcolor{VerbatimBorderColor}#1\relax
}
\expandafter\let\expandafter\KV@sphinx@VerbatimBorderColor
\csname KV@sphinx@pre_border-TeXcolor\endcsname
\newif\ifspx@pre@withbackgroundcolor
\define@key{sphinx}{pre_background-TeXcolor}{%
\spx@pre@withbackgroundcolortrue
- \definecolor{VerbatimColor}#1% legacy colour name with no sphinx prefix
+ \spx@defineorletcolor{VerbatimColor}#1\relax
}
\expandafter\let\expandafter\KV@sphinx@VerbatimColor
\csname KV@sphinx@pre_background-TeXcolor\endcsname
\newif\ifspx@pre@withshadowcolor
\define@key{sphinx}{pre_box-shadow-TeXcolor}{%
\spx@pre@withshadowcolortrue
- \definecolor{sphinxVerbatimShadowColor}#1%
+ \spx@defineorletcolor{sphinxVerbatimShadowColor}#1\relax
}
\definecolor{sphinxVerbatimShadowColor}{rgb}{0,0,0}
% topics
@@ -412,17 +517,17 @@
\newif\ifspx@topic@withbordercolor
\define@key{sphinx}{div.topic_border-TeXcolor}{%
\spx@topic@withbordercolortrue
- \definecolor{sphinxTopicBorderColor}#1%
+ \spx@defineorletcolor{sphinxTopicBorderColor}#1\relax
}
\newif\ifspx@topic@withbackgroundcolor
\define@key{sphinx}{div.topic_background-TeXcolor}{%
\spx@topic@withbackgroundcolortrue
- \definecolor{sphinxTopicBackgroundColor}#1%
+ \spx@defineorletcolor{sphinxTopicBackgroundColor}#1\relax
}
\newif\ifspx@topic@withshadowcolor
\define@key{sphinx}{div.topic_box-shadow-TeXcolor}{%
\spx@topic@withshadowcolortrue
- \definecolor{sphinxTopicShadowColor}#1%
+ \spx@defineorletcolor{sphinxTopicShadowColor}#1\relax
}
% warning, caution, attention, danger, error
\def\spx@tempa#1{%
@@ -572,9 +677,12 @@
\definecolor{sphinx#4BorderColor}{rgb}{0,0,0}%
\definecolor{sphinx#4BgColor}{rgb}{1,1,1}%
\definecolor{sphinx#4ShadowColor}{rgb}{0,0,0}%
- \define@key{sphinx}{div.#4_border-TeXcolor}{#1\definecolor{sphinx#4BorderColor}##1}%
- \define@key{sphinx}{div.#4_background-TeXcolor}{#2\definecolor{sphinx#4BgColor}##1}%
- \define@key{sphinx}{div.#4_box-shadow-TeXcolor}{#3\definecolor{sphinx#4ShadowColor}##1}%
+ \define@key{sphinx}{div.#4_border-TeXcolor}%
+ {#1\spx@defineorletcolor{sphinx#4BorderColor}##1\relax}%
+ \define@key{sphinx}{div.#4_background-TeXcolor}%
+ {#2\spx@defineorletcolor{sphinx#4BgColor}##1\relax}%
+ \define@key{sphinx}{div.#4_box-shadow-TeXcolor}%
+ {#3\spx@defineorletcolor{sphinx#4ShadowColor}##1\relax}%
\expandafter\let\csname KV@sphinx@#4BorderColor\expandafter\endcsname
\csname KV@sphinx@div.#4_border-TeXcolor\endcsname
\expandafter\let\csname KV@sphinx@#4BgColor\expandafter\endcsname
@@ -594,6 +702,9 @@
\DisableKeyvalOption{sphinx}{numfigreset}
\DisableKeyvalOption{sphinx}{nonumfigreset}
\DisableKeyvalOption{sphinx}{mathnumfig}
+\DisableKeyvalOption{sphinx}{booktabs}
+\DisableKeyvalOption{sphinx}{borderless}
+\DisableKeyvalOption{sphinx}{rowcolors}
% FIXME: this is unrelated to an option, move this elsewhere
% To allow hyphenation of first word in narrow contexts; no option,
% customization to be done via 'preamble' key
@@ -693,11 +804,8 @@
{\PackageWarningNoLine{sphinx}{%
The package pict2e is required for rounded boxes.\MessageBreak
It does not seem to be available on your system.\MessageBreak
- Options for setting radii will thus be ignored}%
- \AtEndDocument{\PackageWarningNoLine{sphinx}{%
- I issued a warning which may have gotten lost in the\MessageBreak
- gigantic console output: pict2e.sty was not found,\MessageBreak
- and radii setting options have been ignored}}%
+ Options for setting radii have thus been ignored}%
+ \sphinxbuildwarning{nopict2e}%
\def\spx@boxes@fcolorbox@rounded{\spx@boxes@fcolorbox}%
}%
}%
diff --git a/sphinx/texinputs/sphinxlatexstyleheadings.sty b/sphinx/texinputs/sphinxlatexstyleheadings.sty
index fa9be82b4..a54980bc0 100644
--- a/sphinx/texinputs/sphinxlatexstyleheadings.sty
+++ b/sphinx/texinputs/sphinxlatexstyleheadings.sty
@@ -1,7 +1,7 @@
%% TITLES
%
% change this info string if making any custom modification
-\ProvidesFile{sphinxlatexstyleheadings.sty}[2021/01/27 headings]
+\ProvidesFile{sphinxlatexstyleheadings.sty}[2022/08/15 headings]
\RequirePackage[nobottomtitles*]{titlesec}
\@ifpackagelater{titlesec}{2016/03/15}%
@@ -25,6 +25,7 @@
******** and Sphinx could not patch it, perhaps because your local ...|^^J%
******** copy is already fixed without a changed release date. .......|^^J%
******** If not, you must update titlesec! ...........................|}}%
+ \sphinxbuildwarning{badtitlesec}%
\fi
}%
}{}
diff --git a/sphinx/texinputs/sphinxlatextables.sty b/sphinx/texinputs/sphinxlatextables.sty
index c3c1d6ad1..fee7b16bc 100644
--- a/sphinx/texinputs/sphinxlatextables.sty
+++ b/sphinx/texinputs/sphinxlatextables.sty
@@ -1,7 +1,7 @@
%% TABLES (WITH SUPPORT FOR MERGED CELLS OF GENERAL CONTENTS)
%
% change this info string if making any custom modification
-\ProvidesFile{sphinxlatextables.sty}[2021/01/27 tables]%
+\ProvidesFile{sphinxlatextables.sty}[2022/08/15 tables]%
% Provides support for this output mark-up from Sphinx latex writer
% and table templates:
@@ -25,12 +25,31 @@
% - \sphinxtablestrut
% - \sphinxthecaptionisattop
% - \sphinxthelongtablecaptionisattop
+% - \sphinxhline
+% - \sphinxcline
+% - \sphinxvlinecrossing
+% - \sphinxfixclines
+% - \sphinxtoprule
+% - \sphinxmidrule
+% - \sphinxbottomrule
+% - \sphinxtableatstartofbodyhook
+% - \sphinxtableafterendhook
+% - \sphinxthistablewithglobalstyle
+% - \sphinxthistablewithbooktabsstyle
+% - \sphinxthistablewithborderlessstyle
+% - \sphinxthistablewithstandardstyle
+% - \sphinxthistablewithcolorrowsstyle
+% - \sphinxthistablewithnocolorrowsstyle
+% - \sphinxthistablewithvlinesstyle
+% - \sphinxthistablewithnovlinesstyle
%
% Executes \RequirePackage for:
%
% - tabulary
% - longtable
% - varwidth
+% - colortbl
+% - booktabs if 'booktabs' in latex_table_style
%
% Extends tabulary and longtable via patches and custom macros to support
% merged cells possibly containing code-blocks in complex tables
@@ -43,9 +62,13 @@
% X or S (Sphinx) may have meanings if some table package is loaded hence
% \X was chosen to avoid possibility of conflict
\newcolumntype{\X}[2]{p{\dimexpr
- (\linewidth-\arrayrulewidth)*#1/#2-\tw@\tabcolsep-\arrayrulewidth\relax}}
+ (\linewidth-\spx@arrayrulewidth)*#1/#2-\tw@\tabcolsep-\spx@arrayrulewidth\relax}}
\newcolumntype{\Y}[1]{p{\dimexpr
- #1\dimexpr\linewidth-\arrayrulewidth\relax-\tw@\tabcolsep-\arrayrulewidth\relax}}
+ #1\dimexpr\linewidth-\spx@arrayrulewidth\relax-\tw@\tabcolsep-\spx@arrayrulewidth\relax}}
+% \spx@arrayrulewidth is used internally and its meaning will be set according
+% to the table type; no extra user code should modify it. In particular any
+% \setlength{\spx@arrayrulewidth}{...} may break all of LaTeX... (really...)
+\def\spx@arrayrulewidth{\arrayrulewidth}% 5.3.0, to be adjusted by each table
% using here T (for Tabulary) feels less of a problem than the X could be
\newcolumntype{T}{J}%
% For tables allowing pagebreaks
@@ -167,6 +190,11 @@
\unexpanded\expandafter{\@vwid@setup}}%
}%
+% NOTA BENE: since the multicolumn and multirow code was written Sphinx
+% decided to prefix non public internal macros by \spx@ and in fact all
+% such macros here should now be prefixed by \spx@table@, but doing the
+% update is delayed to later. (written at 5.3.0)
+
%%%%%%%%%%%%%%%%%%%%%
% --- MULTICOLUMN ---
% standard LaTeX's \multicolumn
@@ -208,6 +236,16 @@
% \arrayrulewidth space for each column separation in its estimate of available
% width).
%
+% Update at 5.3.0: code uses \spx@arrayrulewidth which is kept in sync with the
+% table column specification (aka preamble):
+% - no | in preamble: \spx@arrayrulewidth -> \z@
+% - at least a | in the preamble: \spx@arrayrulewidth -> \arrayrulewidth
+% This is used for computation of merged cells widths. Mixed preambles using
+% at least a | but not using it for all columns (as can be obtained via the
+% tabularcolumns directive) may cause some merged cells contents to be slightly
+% shifted to the left as they assume merged columns are | separated where in
+% fact they perhaps are not.
+%
% TN. 1b: as Sphinx multicolumn uses neither \omit nor \span, it can not
% (easily) get rid of extra macros from >{...} or <{...} between columns. At
% least, it has been made compatible with colortbl's \columncolor.
@@ -229,7 +267,19 @@
% Sphinx generates no nested tables, and if some LaTeX macro uses internally a
% tabular this will not have a \sphinxstartmulticolumn within it!
%
-\def\sphinxstartmulticolumn{%
+% 5.3.0 adds a check for multirow as single-row multi-column will allow a row
+% colour but multi-row multi-column should not.
+% Attention that this assumes \sphinxstartmulticolumn is always followed
+% in latex mark-up either by \sphinxmultirow or \begin (from \begin{varwidth}).
+\def\sphinxstartmulticolumn#1#2{%
+ \ifx\sphinxmultirow#2%
+ \gdef\spx@table@hackCT@inmergedcell{\spx@table@hackCT@nocolor}%
+ \else
+ \global\let\spx@table@hackCT@inmergedcell\spx@@table@hackCT@inmergedcell
+ \fi
+ \sphinx@startmulticolumn{#1}#2%
+}%
+\def\sphinx@startmulticolumn{%
\ifx\equation$% $ tabulary's first pass
\expandafter\sphinx@TYI@start@multicolumn
\else % either not tabulary or tabulary's second pass
@@ -285,32 +335,21 @@
\else
% if in an l, r, c type column, try and hope for the best
\xdef\sphinx@tempb{\the\dimexpr(\ifx\TY@final\@undefined\linewidth\else
- \sphinx@TY@tablewidth\fi-\arrayrulewidth)/\sphinx@tempa
- -\tw@\tabcolsep-\arrayrulewidth\relax}%
+ \sphinx@TY@tablewidth\fi-\spx@arrayrulewidth)/\sphinx@tempa
+ -\tw@\tabcolsep-\spx@arrayrulewidth\relax}%
\fi
\noindent\kern\sphinx@tempb\relax
\xdef\sphinx@multiwidth
- {\the\dimexpr\sphinx@multiwidth+\sphinx@tempb+\tw@\tabcolsep+\arrayrulewidth}%
- % hack the \vline and the colortbl macros
- \sphinx@hack@vline\sphinx@hack@CT&\relax
+ {\the\dimexpr\sphinx@multiwidth+\sphinx@tempb+\tw@\tabcolsep+\spx@arrayrulewidth}%
+ \spx@table@hackCT@fixcolorpanel
+ % silence a | column separator in our merged cell
+ \spx@table@hackCT@inhibitvline
+ % prevent column colours to interfere with our multi-column but allow row
+ % colour (we can't obey a \cellcolor as it has not be seen yet at this stage)
+ \spx@table@hackCT@inmergedcell&\relax
% repeat
\expandafter\sphinx@multispan\expandafter{\the\numexpr#1-\@ne}%
}%
-% packages like colortbl add group levels, we need to "climb back up" to be
-% able to hack the \vline and also the colortbl inserted tokens. This creates
-% empty space whether or not the columns were | separated:
-\def\sphinx@hack@vline{\ifnum\currentgrouptype=6\relax
- \kern\arrayrulewidth\arrayrulewidth\z@\else\aftergroup\sphinx@hack@vline\fi}%
-\def\sphinx@hack@CT{\ifnum\currentgrouptype=6\relax
- \let\CT@setup\sphinx@CT@setup\else\aftergroup\sphinx@hack@CT\fi}%
-% It turns out \CT@row@color is not expanded contrarily to \CT@column@color
-% during LaTeX+colortbl preamble preparation, hence it would be possible for
-% \sphinx@CT@setup to discard only the column color and choose to obey or not
-% row color and cell color. It would even be possible to propagate cell color
-% to row color for the duration of the Sphinx multicolumn... the (provisional?)
-% choice has been made to cancel the colortbl colours for the multicolumn
-% duration.
-\def\sphinx@CT@setup #1\endgroup{\endgroup}% hack to remove colour commands
\def\sphinx@multispan@end#1{%
% first, trace back our steps horizontally
\noindent\kern-\dimexpr\sphinx@multiwidth\relax
@@ -320,11 +359,12 @@
\else
\xdef\sphinx@multiwidth{\the\dimexpr\sphinx@multiwidth+
(\ifx\TY@final\@undefined\linewidth\else
- \sphinx@TY@tablewidth\fi-\arrayrulewidth)/\sphinx@tempa
- -\tw@\tabcolsep-\arrayrulewidth\relax}%
+ \sphinx@TY@tablewidth\fi-\spx@arrayrulewidth)/\sphinx@tempa
+ -\tw@\tabcolsep-\spx@arrayrulewidth\relax}%
\fi
- % we need to remove colour set-up also for last cell of the multi-column
- \aftergroup\sphinx@hack@CT
+ % last cell of the multi-column
+ \aftergroup\spx@table@hackCT@fixcolorpanel
+ \aftergroup\spx@table@hackCT@inmergedcell
}%
\newcommand*\sphinxcolwidth[2]{%
% this dimension will always be used for varwidth, and serves as maximum
@@ -345,8 +385,8 @@
\linewidth
\else
% l, c, r columns. Do our best.
- \dimexpr(\linewidth-\arrayrulewidth)/#2-
- \tw@\tabcolsep-\arrayrulewidth\relax
+ \dimexpr(\linewidth-\spx@arrayrulewidth)/#2-
+ \tw@\tabcolsep-\spx@arrayrulewidth\relax
\fi
\else % in tabulary
\ifx\equation$%$% first pass
@@ -357,8 +397,8 @@
\linewidth % in a L, R, C, J column or a p, \X, \Y ...
\else
% we have hacked \TY@final to put in \sphinx@TY@tablewidth the table width
- \dimexpr(\sphinx@TY@tablewidth-\arrayrulewidth)/#2-
- \tw@\tabcolsep-\arrayrulewidth\relax
+ \dimexpr(\sphinx@TY@tablewidth-\spx@arrayrulewidth)/#2-
+ \tw@\tabcolsep-\spx@arrayrulewidth\relax
\fi
\fi
\fi
@@ -368,7 +408,125 @@
% \sphinxcolwidth will use this only inside LaTeX's standard \multicolumn
\def\sphinx@multiwidth #1#2{\dimexpr % #1 to gobble the \@gobble (!)
(\ifx\TY@final\@undefined\linewidth\else\sphinx@TY@tablewidth\fi
- -\arrayrulewidth)*#2-\tw@\tabcolsep-\arrayrulewidth\relax}%
+ -\spx@arrayrulewidth)*#2-\tw@\tabcolsep-\spx@arrayrulewidth\relax}%
+
+% \spx@table@hackCT@inhibitvline
+% packages like colortbl add group levels, we need to "climb back up" to be
+% able to hack the \vline and also the colortbl inserted tokens. The hack
+% sets the \arrayrulewidth to \z@ to inhibit a | separator at right end
+% of the cell, if present (our code does not use \omit so can not avoid the
+% \vline insertion, but setting its width to zero makes it do nothing).
+% Some subtlety with colour panels must be taken care of.
+\def\spx@table@hackCT@inhibitvline{\ifnum\currentgrouptype=6\relax
+ \kern\spx@arrayrulewidth % will be compensated by extra colour panel left overhang
+ \arrayrulewidth\z@% trick to inhibit the {\vrule width \arrayrulewidth}
+ \else\aftergroup\spx@table@hackCT@inhibitvline\fi}%
+
+% hacking around colour matters
+% Sphinx 1.6 comment:
+% It turns out \CT@row@color is not expanded contrarily to \CT@column@color
+% during LaTeX+colortbl preamble preparation, hence it would be possible for
+% \CT@setup to discard only the column color and choose to obey or not
+% row color and cell color. It would even be possible to propagate cell color
+% to row color for the duration of the Sphinx multicolumn... the (provisional?)
+% choice has been made to cancel the colortbl colours for the multicolumn
+% duration.
+% Sphinx 5.3.0 comment:
+% - colortbl has no mechanism to disable colour background in a given cell:
+% \cellcolor triggers one more \color, but has no possibility to revert
+% a previously emitted \color, only to override it via an additional \color
+% - prior to 5.3.0, Sphinx did not officially support colour in tables,
+% but it did have a mechanism to protect merged cells from being partly
+% covered by colour panels at various places. At 5.3.0 this mechanism
+% is relaxed a bit to allow row colour for a single-row merged cell.
+%
+% fixcolorpanel
+\def\spx@table@hackCT@fixcolorpanel{\ifnum\currentgrouptype=6\relax
+ \edef\spx@table@leftcolorpanelextra
+ % \edef as \arrayrulewidth will be set to \z@ next,
+ % hence also \spx@arrayrulewidth...
+ {\sphinxcolorpanelextraoverhang+\the\spx@arrayrulewidth}%
+ \else\aftergroup\spx@table@hackCT@fixcolorpanel\fi}%
+%
+% inmergedcell
+% \spx@table@hackCT@inmergedcell will be locally set to either this
+% \spx@@table@hackCT@inmergedcell or to \spx@table@hackCT@nocolor
+% "\let\spx@original@CT@setup\CT@setup" is done after loading colortbl
+\def\spx@@table@hackCT@inmergedcell{\ifnum\currentgrouptype=6\relax
+ \let\CT@setup\spx@CT@setup@inmergedcell
+ \else\aftergroup\spx@@table@hackCT@inmergedcell\fi
+}%
+\newif\ifspx@table@inmergedcell
+\def\spx@CT@setup@inmergedcell #1\endgroup{%
+ % - obey only row color and disable effect of \sphinxblendcolor
+ % - turn on the inmergedcell boolean to signal to \CT@row@color
+ \spx@original@CT@setup
+ \spx@table@inmergedcelltrue % needed by \CT@row@color
+ % deactivate effect of \sphinxcolorblend if it happened at all
+ \ifdefined\blendcolors\blendcolors{}\fi
+ \CT@row@color
+ \CT@do@color
+ \global\let\CT@cell@color\relax
+ \endgroup
+}%
+%
+% nocolor
+\def\spx@table@hackCT@nocolor{\ifnum\currentgrouptype=6\relax
+% sadly \CT@column@color is possibly already expanded so we can't
+% simply do \let\CT@column@color\relax etc...
+% admittedly we could perhaps hack \CT@color but well
+ \let\CT@setup\spx@CT@setup@nocolor
+ \else\aftergroup\spx@table@hackCT@nocolor\fi
+}
+\def\spx@CT@setup@nocolor#1\endgroup{%
+ \global\let\CT@cell@color\relax
+ % the above fix was added at 5.3.0
+ % formerly a \cellcolor added by a raw latex directive in the merged cell
+ % would have caused colour to apply to the *next* cell after the merged
+ % one; we don't support \cellcolor from merged cells contents anyhow.
+ \endgroup}
+%
+% norowcolor
+\def\spx@table@hackCT@norowcolor{%
+% a bit easier although merged cells complicate the matter as they do need
+% to keep the rowcolor; and we can't know yet if we are in a merged cell
+ \ifnum\currentgrouptype=6\relax
+ \ifx\CT@row@color\relax
+ \else
+ \let\spx@saved@CT@row@color\CT@row@color
+ \def\CT@row@color{%
+ \ifspx@table@inmergedcell\expandafter\spx@saved@CT@row@color\fi
+ }%
+ \fi
+ \else\aftergroup\spx@table@hackCT@norowcolor\fi
+}
+%
+% \sphinxcolorblend
+\def\spx@table@hackCT@colorblend{%
+ \ifnum\currentgrouptype=6\relax
+ \expandafter\blendcolors\spx@colorblendparam
+ % merged cells will do a \blendcolors{} to cancel the effet
+ % we can not know here yet if in merged cell as the boolean
+ % \ifspx@table@inmergedcell is not yet updated
+ \else
+ \aftergroup\spx@table@hackCT@colorblend
+ \fi
+}
+\def\sphinxcolorblend#1{\gdef\spx@colorblendparam{{#1}}\spx@table@hackCT@colorblend}
+% Either xcolor.sty exists on user system and has been loaded by sphinx.sty,
+% or it does not exist, so we can use \@ifpackageloaded without delaying.
+\@ifpackageloaded{xcolor}%
+ {}%
+ {\def\sphinxcolorblend#1{%
+\PackageWarning{sphinx}{This table uses \string\sphinxcolorblend\space
+ but xcolor is not in\MessageBreak
+ the TeX/LaTeX installation, the command will be\MessageBreak
+ ignored in this and the next tables}%
+ \global\let\sphinxcolorblend\@gobble
+ \sphinxbuildwarning{colorblend}%
+ }%
+ }
+
%%%%%%%%%%%%%%%%%%
% --- MULTIROW ---
@@ -390,9 +548,22 @@
% that the table rows have the needed height. The needed mark-up is done
% by LaTeX writer, which has its own id for the merged cells.
%
-% The colour issue is solved by clearing colour panels in all cells,
+% The colour issue is "solved" by clearing colour panels in all cells,
% whether or not the multirow is single-column or multi-column.
%
+% MEMO at 5.3.0: to allow a multirow cell in a single column to react to
+% \columncolor correctly, it seems only way is that the contents
+% are inserted by bottom cell (this is mentioned in multirow.sty doc, too).
+% Sphinx could at Python level "move" the contents to that cell. But the
+% mechanism used here via \sphinxtablestrut to enlarge rows to make room for
+% the contents if needed becomes more challenging yet, because \sphinxtablestrut
+% mark-up will be parsed by TeX *before* it sees the contents of the merged
+% cell.. So it seems the best way would be to actually store the contents into
+% some owned-by-Sphinx box storage which needs to be globally allocated to
+% that usage ; then we need multiple such boxes, say at least 5 to cover
+% 99% or use case. Or perhaps some trick with storing in a \vbox and recovering
+% via some \vsplit but this becomes complicated... perhaps in future.
+%
% In passing we obtain baseline alignements across rows (only if
% \arraystretch is 1, as LaTeX's does not obey \arraystretch in "p"
% multi-line contents, only first and last line...)
@@ -410,6 +581,15 @@
\setbox\z@\hbox\bgroup\aftergroup\sphinx@@multirow\strut
}%
\def\sphinx@@multirow {%
+% MEMO: we could check status of \CT@cell@color here, but unfortunately we
+% can't know the exact height which will be covered by the cells in total
+% (it may be more than our \box\z@ dimensions). We could use an \fcolorbox
+% wrapper on \box\z@ but this will not extend precisely to the bottom rule.
+%
+% Only solution if we want to obey a raw \cellcolor, or a \columncolor, seems
+% to delay unboxing the gathered contents as part of the bottom row with
+% a suitable vertical adjustment...
+%
% The contents, which is a varwidth environment, has been captured in
% \box0 (a \hbox).
% We have with \sphinx@cellid an assigned unique id. The goal is to give
@@ -475,7 +655,592 @@
\@width\z@
\endgroup
% we need this to avoid colour panels hiding bottom parts of multirow text
- \sphinx@hack@CT
+ \spx@table@hackCT@nocolor
}%
+%%%%%%%%%%%%%%%%%%
+% --- STYLING ---
+%
+
+%
+% Support for colour in table
+%
+% Core LaTeX package (very old, part of texlive-latex-base on Debian distr.)
+% providing \columncolor, \rowcolor, \cellcolor and \arrayrulecolor.
+\RequirePackage{colortbl}
+\let\spx@original@CT@setup\CT@setup
+
+% LaTeX's \cline has **strong** deficiencies
+% ******************************************
+% We work around them via an added \sphinxfixclines{number of columns} in the
+% table mark-up, and also extra mark-up \sphinxvlinecrossing{col no} for
+% crossings not contiguous to any cline. To fix the gap at left extremity of a
+% \cline, we redefine the core LaTeX \c@line because this avoids adjoining a
+% small square with potential PDF viewer anti-aliasing issues. We waited
+% after loading colortbl because it also redefines \c@line for it to obey the
+% colour set by \arrayrulecolor.
+% MEMO: booktabs package does *not* redefine \@cline so we are safe here.
+\def\@cline#1-#2\@nil{%
+ \omit
+ \@multicnt#1%
+ \advance\@multispan\m@ne
+ \ifnum\@multicnt=\@ne\@firstofone{&\omit}\fi
+ \@multicnt#2%
+ \advance\@multicnt-#1%
+ \advance\@multispan\@ne
+ {\CT@arc@
+% start of Sphinx modification
+ \ifnum#1>\@ne\kern-\spx@arrayrulewidth\fi% fix gap at join with vertical lines
+% end of Sphinx modification
+% Comments:
+%
+% If we had the information whether the previous column ended with a | or
+% not, we could decide what to do here. Alternatively the mark-up could
+% use either original \cline or the one modified as here depending on case.
+% One wonders why LaTeX does not provide itself the alternative as a
+% complement to \cline, to use on case by case basis.
+% Here we handle both at same time via using the \spx@arrayrulewidth which
+% will be \z@ if no | at all so will induce here nothing.
+%
+% As a result Sphinx basically supports well only tables having either all
+% columns |-separated, or no | at all, as it uses \spx@arrayrrulewidth in
+% all columns (here and in multicolumn code).
+%
+% We also considered a method not modifying \c@line but it requires too
+% much extra mark-up from Python LaTeX writer and/or extra LaTeX coding.
+% back to LaTeX+colortbl code
+ \leaders\hrule\@height\arrayrulewidth\hfill}%
+ \cr
+% the last one will need to be compensated, this is job of \sphinxclines
+ \noalign{\vskip-\arrayrulewidth}%
+}
+\def\spx@table@fixvlinejoin{%
+ {\CT@arc@ % this is the color command set up by \arrayrulecolor
+ \vrule\@height\arrayrulewidth
+% side remark: LaTeX has only a single \arrayrulewidth for all kinds
+% for cell borders in table, horizontal or vertical...
+ \@depth\z@
+ \@width\spx@arrayrulewidth
+ }%
+}
+% Sphinx LaTeX writer issues one such for each vertical line separating two
+% contiguous multirow cells; i.e. those crossings which can are not already
+% taken care of by our modified at left extremity \cline.
+% One could imagine a more \...crossingS (plural) receiving a comma delimited
+% list, which would simplify the mark-up but this would complexify both the
+% Python and the LaTeX coding.
+\def\sphinxtablevlinecrossing#1{%
+ \sphinxtabledecrementrownum
+ \omit
+ \@multispan{#1}%
+ \hfill
+ \spx@table@fixvlinejoin
+ \cr
+ \noalign{\vskip-\arrayrulewidth}%
+}
+% This "fixclines" is also needed if no \sphinxcline emitted and is useful
+% even in extreme case with no \sphinxvlinecrossing either, to give correct
+% height to multirow extending across all table width assuming other rows are
+% separated generally by an \hline, so as to keep coherent line spacing.
+%
+% It is designed to work ok even if no | separators are in the table (because
+% \spx@table@fixvlinejoin uses \spx@arrayrulewidth which is \z@ in that case).
+\def\sphinxtablefixclines#1{% #1 is the number of columns of the table
+ \sphinxtabledecrementrownum
+ \omit
+ \spx@table@fixvlinejoin% unneeded if first \cline started at column 1 but does
+ % not hurt; fills small gap at left-bordered table
+ \@multispan{#1}%
+ \hfill
+ \spx@table@fixvlinejoin% fill small gap at right-bordered table
+ \cr
+ % this final one does NO \vskip-\arrayrulewidth... that's the whole point
+}
+%%%% end of \cline workarounds
+
+%
+% - passing option "table" to xcolor also loads colortbl but we needed to
+% load color or xcolor prior to the handling of the options
+%
+% - the \rowcolors command from [table]{xcolor} has various problems:
+%
+% * it is rigid and does not out-of-the-box allow a more complex scheme
+% such as colorA+colorB+colorC+colorB+colorC+colorB+colorC... suitable to
+% distinguish a header row.
+%
+% * its code does not export the used colour, an information which we may
+% need for example to colourize the rule via \arrayrulecolor in the
+% appropriate manner, for example to colourize the booktabs induced vertical
+% whitespace to avoid gaps (if one wants to).
+%
+% * incompatibility with tabulary: the output depends on parity of total
+% number of rows!
+%
+% * problems with longtable: the caption will receive a background colour
+% panel, if we do not deactivate the \rowcolors action during definition of
+% the headers and footers; this requires extra mark-up. Besides if we
+% deactivate using \hiderowcolors during header and footer formation, the
+% parity of the body rows is shifted, \rownum is even, not odd, at first body
+% row. And setting \rownum at start of first body row is too late for
+% influencing the colour.
+%
+% * it has a global impact and must be reset at each table. We can not
+% issue it only once and it provides no public interface (without @) to
+% cancel its effect conveniently (\hiderowcolors can only be used from
+% *inside* a table.)
+%
+% * its core mechanism which increments the row count is triggered
+% if a \cline is encountered... so this offsets the alternating colours...
+% ... or not if there are two \cline's in the row...
+% (as we will use same mechanism we have to correct this increment).
+%
+% So we need our own code.
+
+% Provide \rownum and rownum LaTeX counter (code copied from colortbl v1.0f)
+\ltx@ifundefined{rownum}{%
+ \ltx@ifundefined{c@rownum}%
+ {\newcount\rownum\let\c@rownum\rownum}%
+ {\let\rownum\c@rownum}%
+ }%
+{\let\c@rownum\rownum}
+\providecommand\therownum{\arabic{rownum}}
+
+% extra overhang for color panels to avoid visual artifacts in pdf viewers
+% (particularly if borderless)
+\def\sphinxcolorpanelextraoverhang{0.1pt}
+\def\spx@table@leftcolorpanelextra {\sphinxcolorpanelextraoverhang}
+\def\spx@table@rightcolorpanelextra{\sphinxcolorpanelextraoverhang}
+% the macro to which \CT@row@color will be set for coloured rows, serves both
+% in header and body, the colours must have been defined at time of use
+\def\spx@table@CT@row@color{\ifspx@table@inmergedcell
+ \CT@color{sphinxTableMergeColor}%
+ \else
+ \CT@color{sphinxTableRowColor}%
+ \fi
+ \@tempdimb\dimexpr\col@sep+\spx@table@leftcolorpanelextra\relax
+ \@tempdimc\dimexpr\col@sep+\spx@table@rightcolorpanelextra\relax
+ }%
+% used by itself this will influence a single row if \CT@everycr is the
+% colortbl one, to influences all rows the \CT@everycr must be modified (see
+% below)
+\def\sphinxrowcolorON {\global\let\CT@row@color\spx@table@CT@row@color}%
+% this one turns off row colours until the next \sphinxrowcolorON
+\def\sphinxrowcolorOFF{\global\let\CT@row@color\relax}%
+% this one inhibits the row colour in one cell only (can be used as
+% >{\sphinxnorowcolor} for turning off row colours in a given column)
+\def\sphinxnorowcolor{\spx@table@hackCT@norowcolor}%
+
+% \sphinxtoprule (or rather \sphinxtabletoprulehook) will be modified by
+% the colorrows class to execute this one:
+\def\spx@table@@toprule@rowcolorON{%
+ \noalign{%
+ % Because of tabulary 2-pass system, the colour set-up at end of table
+ % would contaminate the header colours at start of table, so must reset
+ % them here. We want all header rows to obey same colours, so we don't
+ % use original \CT@everycr which sets \CT@row@color to \relax.
+ \global\CT@everycr{\the\everycr}%
+ \global\sphinxcolorlet{sphinxTableRowColor}{sphinxTableRowColorHeader}%
+ \global\sphinxcolorlet{sphinxTableMergeColor}{\sphinxTableMergeColorHeader}%
+ \sphinxrowcolorON
+ }%
+}%
+
+% \sphinxtableatstartofbodyhook will be modified by colorrows class to
+% execute this one; it starts the alternating colours and triggers increment
+% or \rownum count at each new row (the xcolor base method for \rowcolors)
+\def\spx@table@@startbodycolorrows{%
+ \noalign{%
+ \global\CT@everycr{% Nota Bene: in a longtable with \hline the \everycr is
+ % done two extra times! but 2 is even, so this is ok
+ \noalign{\global\advance\rownum\@ne % the xcolor \rowcolors base trick
+% MEMO: colortbl \CT@row@color is expanded *after* the cell contents have been
+% gathered and measured, so it can't be used to expose e.g. the colour to the
+% cell contents macro code. Of course if it is known how the colour is chosen
+% the procedure could be done from inside the cell. Simpler to expose the colour
+% in a public name sphinxTableRowColor at start of the row in this \noalign.
+ \sphinxSwitchCaseRowColor\rownum
+ }%
+ \the\everycr
+ }%
+ \global\rownum\@ne % is done from inside table so ok with tabulary two passes
+ \sphinxSwitchCaseRowColor\rownum % set up color for the first body row
+ \sphinxrowcolorON % has been done from \sphinxtoprule location but let's do
+ % it again in case \sphinxtabletoprulehook has been used
+ % to inhibit colours in the header rows
+ }% end of noalign contents
+}
+% set the colours according to row parity; a priori #1 is \rownum, but
+% the macro has been designed to be usable in user level added code
+\def\sphinxSwitchCaseRowColor#1{%
+ \ifodd#1\relax
+ \global\sphinxcolorlet{sphinxTableRowColor}{sphinxTableRowColorOdd}%
+ \global\sphinxcolorlet{sphinxTableMergeColor}{\sphinxTableMergeColorOdd}%
+ \else
+ \global\sphinxcolorlet{sphinxTableRowColor}{sphinxTableRowColorEven}%
+ \global\sphinxcolorlet{sphinxTableMergeColor}{\sphinxTableMergeColorEven}%
+ \fi
+}
+
+% each \cline or \cmidrule (booktabs) consumes one \cr, offsetting the \rownum
+% parity; so this macro serves to compensate and must be added to each such
+% \cline or \cmidrule (see below)
+\def\spx@table@@decrementrownum{\noalign{\global\advance\rownum\m@ne}}
+\let\sphinxtabledecrementrownum\@empty
+
+% \sphinxtableafterendhook will be modified by colorrows class to execute
+% this after the table
+\def\spx@table@resetcolortbl{%
+ \sphinxrowcolorOFF
+ \spx@table@reset@CTeverycr
+% this last bit is done in order for the \sphinxbottomrule from the "foot"
+% longtable template to be able to use same code as the \sphinxbottomrule
+% at end of table body; see \sphinxbooktabsspecialbottomrule code
+ \global\rownum\z@
+}
+\def\spx@table@reset@CTeverycr{%
+% we should probably be more cautious and not hard-code here the colortbl
+% set-up; so the macro is defined without @ to fac
+ \global\CT@everycr{\noalign{\global\let\CT@row@color\relax}\the\everycr}%
+}
+
+% At last the style macros \sphinxthistablewithstandardstyle etc...
+
+% They are executed before the table environments in a scope limiting
+% wrapper "savenotes" environment.
+%
+% 0) colour support is enacted via adding code to three hooks:
+% - \sphinxtabletoprulehook (implicit from \sphinxtoprule expansion)
+% - \sphinxtableatstartofbodyhook (explicit from table templates)
+% - \sphinxtableafterendhook (explicit from table templates)
+% additionally special adjustment must be made in \sphinxcline
+%
+\def\sphinxtoprule{\spx@toprule\sphinxtabletoprulehook}
+% \spx@toprule is what is defined by the standard, booktabs and borderless
+% styles.
+% The colorrows class will prepend \spx@table@toprule@rowcolorON into
+% \sphinxtabletoprulehook which a priori is \@empty but can contain user added
+% extra code, and is executed after \spx@toprule.
+\let\sphinxtabletoprulehook \@empty
+\let\sphinxtableatstartofbodyhook\@empty
+\let\sphinxtableafterendhook \@empty
+%
+% 1) we manage these three hooks in a way allowing a custom user extra wrapper
+% environment from a container class to use them as entry point for some
+% custom code. The container code is done first, prior to table templates.
+% So, the style macros will *prepend* the needed color-code to the existing
+% custom user code, so the custom user code can override them. The custom
+% user code should not redefine any of the 3 \sphinxtable...hook macros via a
+% \global\def, but their contents can use \gdef. In fact they probably need
+% to for the first two hooks which are executed from inside the table and
+% a priori need their code to be in a \noalign which limits scope.
+%
+% 2) the table templates and LaTeX writer code make it so that only
+% one of either
+% \sphinxthistablewithcolorrowsstyle,
+% or \sphinxthistablewithnocolorrowsstyle
+% will be inserted explicitly depending on local :class: for table.
+% The global 'colorrows' style in latex_table_style translates at bottom
+% of this file into code for inserting \sphinxthistablewithcolorrowsstyle
+% at end of \sphinxthistablewithglobalstyle. So it is impossible
+% to have first \sphinxthistablewithnocolorrowsstyle, then
+% \sphinxthistablewithcolorrowsstyle. Nevertheless we have written
+% the code so that in this case colorrows would indeed activate (except
+% if it was already executed before as it self-annihilates).
+
+% standard style
+\def\sphinxthistablewithstandardstyle{%
+ % Those two are produced by the latex writer
+ \def\sphinxhline {\hline}%
+ % \sphinxtabledecrementrownum is a no-op which is redefined by colorrows
+ % to correct the \rownum increment induced by \cline in colorrows regime
+ \def\sphinxcline {\sphinxtabledecrementrownum\cline}%
+ % LaTeX's \cline needs fixing
+ \let\sphinxvlinecrossing\sphinxtablevlinecrossing
+ \let\sphinxfixclines \sphinxtablefixclines
+ % Those three are inserted by the table templates
+ \def\spx@toprule {\hline}%
+ \def\sphinxmidrule {\hline}%
+ \def\sphinxbottomrule {\hline}%
+ % Do not tamper with this internal
+ \def\spx@arrayrulewidth{\arrayrulewidth}%
+}
+
+% booktabs style
+% The \@xcmidrule patch below will do beyond its main stuff
+% \sphinxadjustcmidrulebelowsep
+% Indeed the poor booktabs spacing with \cmidrule (if \sphinxbooktabscmidrule
+% defined below is overwritten to use it) is quite awful. Do
+% \let\sphinxadjustcmidrulebelowsep\empty
+% if you prefer booktabs defaults.
+\def\sphinxadjustcmidrulebelowsep{\belowrulesep=\aboverulesep}
+\AtBeginDocument{% patch booktabs to avoid extra vertical space from
+ % consecutive \sphinxcline, if defined to use \cmidrule
+ \ifdefined\@xcmidrule
+ \let\spx@original@@xcmidrule\@xcmidrule
+ \def\@xcmidrule{\sphinxadjustcmidrulebelowsep
+ % if we don't do that, two \sphinxcline in the same row
+ % will cause the second short rule to be shifted down
+ \ifx\@tempa\sphinxcline\let\@tempa\cmidrule\fi
+ \spx@original@@xcmidrule}%
+ \fi
+}
+% wrappers to allow customization, e.g. via a container class
+% the top, mid, bottom definitions are in fact overwritten (later, below)
+% byt more complex ones needed to handle booktabs+colorrows context
+\def\sphinxbooktabstoprule {\toprule}
+\def\sphinxbooktabsmidrule {\midrule}
+\def\sphinxbooktabsbottomrule{\bottomrule}
+%
+\let\sphinxbooktabscmidrule \@gobble % i.e. draw no short rules at all!
+% You can redefine this to use \cmidrule with various options, such
+% as \cmidrule(lr), but:
+% Attention, if you want this to use \cmidrule (or \cline) you must,
+% if the table uses row colours,
+% also include the \sphinxtabledecrementrownum token like e.g. this
+% \def\sphinxbooktabscmidrule{\sphinxtabledecrementrownum\cmidrule(lr)}
+% and it must be first due to internals of the \cmidrule usage of \futurelet.
+
+\def\sphinxthistablewithbooktabsstyle{%
+ \let\sphinxhline\@empty % there is no wrapper macro here so if you want to change that
+ % you will have to redefine \sphinxthistablewithbooktabsstyle
+ \def\sphinxcline {\sphinxbooktabscmidrule}% defaults to give \@gobble
+ \let\sphinxvlinecrossing\@gobble % no | in a booktabs-style table !
+ \let\sphinxfixclines \@gobble % should not be used with booktabs + \cmidrule
+ \def\spx@toprule {\sphinxbooktabstoprule}%
+ \def\sphinxmidrule {\sphinxbooktabsmidrule}%
+ \def\sphinxbottomrule{\sphinxbooktabsbottomrule}%
+ \def\spx@arrayrulewidth{\z@}%
+}
+\AtBeginDocument{\@ifpackageloaded{booktabs}%
+ {}%
+ {\def\sphinxthistablewithbooktabsstyle{%
+ \PackageWarning{sphinx}{%
+Add \string\usepackage{booktabs} to the preamble to allow\MessageBreak
+local use of booktabs table style}%
+ \sphinxbuildwarning{booktabs}%
+ \sphinxthistablewithstandardstyle
+ }}%
+}%
+
+% borderless style
+\def\sphinxthistablewithborderlessstyle{%
+ \let\sphinxhline \@empty
+ \let\sphinxcline \@gobble
+ \let\sphinxvlinecrossing\@gobble
+ \let\sphinxfixclines \@gobble
+ \let\spx@toprule \@empty
+ \let\sphinxmidrule \@empty
+ \let\sphinxbottomrule \@empty
+ \def\spx@arrayrulewidth{\z@}%
+}%
+
+% colorrows style
+%
+\let\sphinxifthistablewithcolorrowsTF\@secondoftwo
+\def\sphinxthistablewithcolorrowsstyle{%
+ \let\sphinxifthistablewithcolorrowsTF\@firstoftwo
+% this is defined to auto-silence itself (in the surrounding scope-limiting
+% environment) after one execution ("colorrows" can never follow "nocolorrows")
+ \let\sphinxthistablewithcolorrowsstyle\@empty
+%
+ \let\spx@table@toprule@rowcolorON \spx@table@@toprule@rowcolorON
+ \let\spx@table@startbodycolorrows \spx@table@@startbodycolorrows
+ \let\sphinxtabledecrementrownum \spx@table@@decrementrownum
+% Is it the best choice to "prepend" to existing code there?
+ \spx@prepend\spx@table@toprule@rowcolorON\to\sphinxtabletoprulehook
+ \spx@prepend\spx@table@startbodycolorrows\to\sphinxtableatstartofbodyhook
+%
+% this one is not set to \@empty by nocolorrows, because it looks harmless
+% to execute it always, as it simply resets to standard colortbl state after
+% the table; so we don't need an @@ version for this one
+ \spx@prepend\spx@table@resetcolortbl\to\sphinxtableafterendhook
+}
+\def\spx@prepend#1\to#2{% attention about using this only with #2 "storage macro"
+ \toks@{#1}%
+ \toks@\expandafter\expandafter\expandafter{\expandafter\the\expandafter\toks@#2}%
+ \edef#2{\the\toks@}%
+}%
+
+\def\sphinxthistablewithnocolorrowsstyle{%
+ \let\sphinxifthistablewithcolorrowsTF\@secondoftwo
+% rather than trying to remove the code added by 'colorrows' style, we
+% simply make it no-op, without even checking if really it was activated.
+ \let\spx@table@toprule@rowcolorON\@empty
+ \let\spx@table@startbodycolorrows\@empty
+ \let\sphinxtabledecrementrownum \@empty
+% we don't worry about \sphinxtableafterendhook as the \spx@table@resetcolortbl
+% done at end can not do harm; and we could also have not bothered with the
+% \sphinxtabledecrementrownum as its \rownum decrement, if active, is harmless
+% in non-colorrows context
+}
+
+% (not so easy) implementation of the booktabscolorgaps option. This option
+% defaults to true and is not officially documented, as already colorrows is
+% only opt-in, so it is there only as a "turn-off" switch, but if nobody
+% complains in next few months, it will probably be removed altogether at
+% 6.0.0. The reason it exists is because of longtable aspeces described
+% below.
+%
+% As it is used via \sphinxsetup booktabscolorgaps status is not known here
+% and may change locally. So it must be implemented via delayed or
+% conditional code.
+%
+% We do not know the order of execution of \sphinxthistablewithbooktabsstyle
+% versus \sphinxthistablewithcolorrows: if booktabs is global option it
+% will be executed first; but if colorrows is global option and not booktabs
+% then colorrows will be executed first via \sphinxthistablewithglobalstyle
+%
+% Modifying things from locations such as \sphinxtabletoprulehook which are
+% executed within the table is not convenient as it must use \global
+% but then we would have to undo this after the table.
+%
+% So what we do is to prepare booktabs specific macros to incorporate
+% a conditional to check the colorrows status. We must each time check
+% both if colorrows is activated and if colorgaps is. We do this via
+% macros without @ so they can be used easily in customization code.
+% When and if booktabscolorgaps option is removed, we can then replace
+% \sphinxifbooktabswithcolorgapsTF by \sphinxifthistablewithcolorrowsTF
+\def\sphinxifbooktabswithcolorgapsTF{%
+ \if1\ifspx@opt@booktabscolorgaps
+ \sphinxifthistablewithcolorrowsTF{1}{0}%
+ \else0\fi
+ \expandafter\@firstoftwo
+ \else\expandafter\@secondoftwo
+ \fi
+}
+% as this is done without "@" it can be relatively easily be overwritten
+% by user in customization code
+\def\sphinxbooktabstoprule{%
+ \sphinxifbooktabswithcolorgapsTF
+ {\sphinxbooktabsspecialtoprule}%
+ {\toprule}%
+}%
+\def\sphinxbooktabscolorgapsoverhang{0.1pt}% avoid pixel/rounding effects
+% auxiliary fork
+\long\def\spx@table@crazyfork
+ #1\endfirsthead\endhead\sphinxtableatstartofbodyhook#2#3\@nil{#2}
+% we fetch the next token to check if there is a header or not
+% this is a bit fragile as it relies on the table templates
+% and it assumes this token #1 is never braced...
+% let's make this \long in case #1 is \par (should not be)
+\long\def\sphinxbooktabsspecialtoprule\sphinxtabletoprulehook#1{%
+ \specialrule{\heavyrulewidth}{\abovetopsep}{\z@}%
+ % this macro contains colour init code (and defines sphinxTableRowColor)
+ \sphinxtabletoprulehook
+ % unfortunately colortbl provides no way to save/restore the
+ % \arrayrulecolor status, we have to code it ourselves
+ \noalign{\global\let\spx@@saved@CT@arc@\CT@arc@
+% \@declaredcolor is not \long. Although #1 can probably never be \par with
+% our templates, let's be cautious and not use the creazyfork inside the \color
+ \spx@table@crazyfork
+% this crazy code checks if #1 is one of \endfirsthead, \endhead or
+% \sphinxtableatstartofbodyhook, as criterion for table with no header
+ #1\endhead\sphinxtableatstartofbodyhook\@secondoftwo
+ \endfirsthead#1\sphinxtableatstartofbodyhook\@secondoftwo
+ \endfirsthead\endhead#1\@secondoftwo
+ \endfirsthead\endhead\sphinxtableatstartofbodyhook\@firstoftwo
+ \@nil
+ {\gdef\CT@arc@{\color{sphinxTableRowColor}}}%
+ {\gdef\CT@arc@{\color{sphinxTableRowColorOdd}}}%
+ }% end of \noalign
+ % \specialrule uses \noalign itself
+ \specialrule{\dimexpr\belowrulesep+\sphinxbooktabscolorgapsoverhang\relax}%
+ {\z@}{-\sphinxbooktabscolorgapsoverhang}%
+ \noalign{\global\let\CT@arc@\spx@@saved@CT@arc@}%
+ #1% let's not forget to re-insert this #1 in token stream
+ % fortunately longtable's \endfirsthead/\endhead are not delimiters but
+ % are really tokens awaiting expansion...
+}%
+\def\sphinxbooktabsmidrule{%
+ \sphinxifbooktabswithcolorgapsTF
+ {\sphinxbooktabsspecialmidrule}%
+ {\midrule}%
+}%
+\def\sphinxbooktabsspecialmidrule{%
+ \noalign{\global\let\spx@@saved@CT@arc@\CT@arc@
+ \gdef\CT@arc@{\color{sphinxTableRowColor}}% this is RowColorHeader
+ }%
+ \specialrule{\dimexpr\aboverulesep+\sphinxbooktabscolorgapsoverhang\relax\relax}%
+ {-\sphinxbooktabscolorgapsoverhang}{\z@}%
+ \noalign{\global\let\CT@arc@\spx@@saved@CT@arc@}%
+ \specialrule{\lightrulewidth}{\z@}{\z@}%
+ \noalign{\gdef\CT@arc@{\color{sphinxTableRowColorOdd}}}%
+ \specialrule{\dimexpr\belowrulesep+\sphinxbooktabscolorgapsoverhang\relax\relax}%
+ {\z@}{-\sphinxbooktabscolorgapsoverhang}%
+ \noalign{\global\let\CT@arc@\spx@@saved@CT@arc@}%
+}%
+\def\sphinxbooktabsbottomrule{%
+ \sphinxifbooktabswithcolorgapsTF
+ {\sphinxbooktabsspecialbottomrule}%
+ {\bottomrule}%
+}%
+% The colour here is already updated because of the \\ before so we must
+% execute again the colour selection code, but this is not too complicated.
+% What is annoying though is that \sphinxbottomrule in the longtable context
+% appears both in the "foot" part and after the last body row. For the first
+% occurrence the \rownum could be arbitrary if it had not been reset by each
+% table using it via the \sphinxtableafterendhook (see above). This avoids
+% having to modify the longtable template. But as \rownum is thus 0 in the
+% "foot", the \sphinxSwitchCaseRowColor has to know how to handle negative
+% inputs (in fact the -1 value), the Sphinx definition has no issue with that
+% but any redefinition must be aware of this constraint.
+\def\sphinxbooktabsspecialbottomrule{%
+ \noalign{\global\let\spx@@saved@CT@arc@\CT@arc@
+ \sphinxSwitchCaseRowColor{\numexpr\rownum-\@ne\relax}%
+ \gdef\CT@arc@{\color{sphinxTableRowColor}}%
+ }%
+ \specialrule{\dimexpr\aboverulesep+\sphinxbooktabscolorgapsoverhang\relax}%
+ {-\sphinxbooktabscolorgapsoverhang}{\z@}%
+ \noalign{\global\let\CT@arc@\spx@@saved@CT@arc@}%
+ \specialrule{\heavyrulewidth}{\z@}{\belowbottomsep}%
+}%
+%
+% MEMO: with longtable \sphinxtoprule, \sphinxmidrule and \sphinxbottomrule
+% are evaluated at time of constructing the headers and footers as boxes
+% (already typeset material and expanded macros; \sphinxbottomrule is also
+% evaluated at very end of table body, i.e. "normally"). So the used colour
+% to fill the booktabs gaps is decided during the headers and footers
+% construction by longtable. Actually they are expanded twice: in firsthead
+% then in head, respectively in foot and lastfoot. But in current design the
+% header row colours are fixed, not alternating, so there is at least no
+% coherence issue there.
+
+% The \spx@arrayrulewidth is used for some complex matters of merged
+% cells size computations.
+% tabularcolumns argument will override any global or local style and
+% trigger the appropriate adjustment of \spx@arrayrulewidth.
+% Notice that this will be bad if the table uses booktabs style
+% but anyhow table with booktabs should not use any | separator.
+\def\sphinxthistablewithvlinesstyle{%
+ \def\spx@arrayrulewidth{\arrayrulewidth}%
+ \let\sphinxvlinecrossing\sphinxtablevlinecrossing
+ \let\sphinxfixclines \sphinxtablefixclines
+}%
+\def\sphinxthistablewithnovlinesstyle{%
+ \def\spx@arrayrulewidth{\z@}%
+ \let\sphinxvlinecrossing\@gobble
+ % let's not bother to modify \sphinxfixclines, it works fine and is
+ % useful in standard style + no vline (only hlines and clines);
+ % besides, only one of vline or novline style macro is executed
+}%
+
+% default is the standard style
+\def\sphinxthistablewithglobalstyle{\sphinxthistablewithstandardstyle}
+
+\ifspx@opt@booktabs
+ \RequirePackage{booktabs}
+ \def\sphinxthistablewithglobalstyle{\sphinxthistablewithbooktabsstyle}
+\fi
+\ifspx@opt@borderless
+ \def\sphinxthistablewithglobalstyle{\sphinxthistablewithborderlessstyle}
+\fi
+% colorrows appends to the current globalstyle (standard, booktabs, or borderless)
+\ifspx@opt@colorrows % let the globalstyle trigger the colorrows style on top of it
+ \expandafter\def\expandafter\sphinxthistablewithglobalstyle\expandafter
+ {\sphinxthistablewithglobalstyle
+ \sphinxthistablewithcolorrowsstyle
+ }
+\fi
+
+
\endinput
diff --git a/sphinx/texinputs/sphinxpackagefootnote.sty b/sphinx/texinputs/sphinxpackagefootnote.sty
index 6a7884f83..55901234d 100644
--- a/sphinx/texinputs/sphinxpackagefootnote.sty
+++ b/sphinx/texinputs/sphinxpackagefootnote.sty
@@ -1,6 +1,6 @@
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{sphinxpackagefootnote}%
- [2022/02/12 v4.5.0 Sphinx custom footnotehyper package (Sphinx team)]
+ [2022/08/15 v5.3.0 Sphinx custom footnotehyper package (Sphinx team)]
%%
%% Package: sphinxpackagefootnote
%% Version: based on footnotehyper.sty 2021/02/04 v1.1d
@@ -338,6 +338,7 @@
}%
% slight reformulation for Sphinx
\def\FNH@bad@makefntext@alert{%
+ \sphinxbuildwarning{badfootnotes}%
\PackageWarningNoLine{sphinxpackagefootnote}%
{Footnotes will be sub-optimal, sorry. This is due to the document class or^^J
some package modifying macro \string\@makefntext.^^J
diff --git a/sphinx/writers/html.py b/sphinx/writers/html.py
index 329d64394..cb0794c04 100644
--- a/sphinx/writers/html.py
+++ b/sphinx/writers/html.py
@@ -615,7 +615,7 @@ class HTMLTranslator(SphinxTranslator, BaseTranslator):
# rewrite the URI if the environment knows about it
if olduri in self.builder.images:
node['uri'] = posixpath.join(self.builder.imgpath,
- self.builder.images[olduri])
+ urllib.parse.quote(self.builder.images[olduri]))
if 'scale' in node:
# Try to figure out image height and width. Docutils does that too,
diff --git a/sphinx/writers/html5.py b/sphinx/writers/html5.py
index 1556f84e4..a169c6069 100644
--- a/sphinx/writers/html5.py
+++ b/sphinx/writers/html5.py
@@ -562,7 +562,7 @@ class HTML5Translator(SphinxTranslator, BaseTranslator):
# rewrite the URI if the environment knows about it
if olduri in self.builder.images:
node['uri'] = posixpath.join(self.builder.imgpath,
- self.builder.images[olduri])
+ urllib.parse.quote(self.builder.images[olduri]))
if 'scale' in node:
# Try to figure out image height and width. Docutils does that too,
diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py
index fbff3d906..846d365d1 100644
--- a/sphinx/writers/latex.py
+++ b/sphinx/writers/latex.py
@@ -97,8 +97,24 @@ class Table:
self.body: List[str] = []
self.align = node.get('align', 'default')
self.classes: List[str] = node.get('classes', [])
+ self.styles: List[str] = []
+ if 'standard' in self.classes:
+ self.styles.append('standard')
+ elif 'borderless' in self.classes:
+ self.styles.append('borderless')
+ elif 'booktabs' in self.classes:
+ self.styles.append('booktabs')
+ if 'nocolorrows' in self.classes:
+ self.styles.append('nocolorrows')
+ elif 'colorrows' in self.classes:
+ self.styles.append('colorrows')
self.colcount = 0
self.colspec: str = None
+ self.colsep: str = None
+ if 'booktabs' in self.styles or 'borderless' in self.styles:
+ self.colsep = ''
+ elif 'standard' in self.styles:
+ self.colsep = '|'
self.colwidths: List[int] = []
self.has_problematic = False
self.has_oldproblematic = False
@@ -143,23 +159,30 @@ class Table:
This is what LaTeX calls the 'preamble argument' of the used table environment.
- .. note:: the ``\\X`` and ``T`` column type specifiers are defined in ``sphinx.sty``.
+ .. note::
+
+ The ``\\X`` and ``T`` column type specifiers are defined in
+ ``sphinxlatextables.sty``.
"""
if self.colspec:
return self.colspec
- elif self.colwidths and 'colwidths-given' in self.classes:
+
+ _colsep = self.colsep
+ if self.colwidths and 'colwidths-given' in self.classes:
total = sum(self.colwidths)
colspecs = [r'\X{%d}{%d}' % (width, total) for width in self.colwidths]
- return '{|%s|}' % '|'.join(colspecs) + CR
+ return '{%s%s%s}' % (_colsep, _colsep.join(colspecs), _colsep) + CR
elif self.has_problematic:
- return r'{|*{%d}{\X{1}{%d}|}}' % (self.colcount, self.colcount) + CR
+ return r'{%s*{%d}{\X{1}{%d}%s}}' % (_colsep, self.colcount,
+ self.colcount, _colsep) + CR
elif self.get_table_type() == 'tabulary':
# sphinx.sty sets T to be J by default.
- return '{|' + ('T|' * self.colcount) + '}' + CR
+ return '{' + _colsep + (('T' + _colsep) * self.colcount) + '}' + CR
elif self.has_oldproblematic:
- return r'{|*{%d}{\X{1}{%d}|}}' % (self.colcount, self.colcount) + CR
+ return r'{%s*{%d}{\X{1}{%d}%s}}' % (_colsep, self.colcount,
+ self.colcount, _colsep) + CR
else:
- return '{|' + ('l|' * self.colcount) + '}' + CR
+ return '{' + _colsep + (('l' + _colsep) * self.colcount) + '}' + CR
def add_cell(self, height: int, width: int) -> None:
"""Adds a new cell to a table.
@@ -857,8 +880,19 @@ class LaTeXTranslator(SphinxTranslator):
(self.curfilestack[-1], node.line or ''))
self.tables.append(Table(node))
+ if self.table.colsep is None:
+ self.table.colsep = '' if (
+ 'booktabs' in self.builder.config.latex_table_style or
+ 'borderless' in self.builder.config.latex_table_style
+ ) else '|'
if self.next_table_colspec:
self.table.colspec = '{%s}' % self.next_table_colspec + CR
+ if '|' in self.table.colspec:
+ self.table.styles.append('vlines')
+ self.table.colsep = '|'
+ else:
+ self.table.styles.append('novlines')
+ self.table.colsep = ''
if 'colwidths-given' in node.get('classes', []):
logger.info(__('both tabularcolumns and :widths: option are given. '
':widths: is ignored.'), location=node)
@@ -896,6 +930,8 @@ class LaTeXTranslator(SphinxTranslator):
self.pushbody(self.table.header)
def depart_thead(self, node: Element) -> None:
+ if self.body and self.body[-1] == r'\sphinxhline':
+ self.body.pop()
self.popbody()
def visit_tbody(self, node: Element) -> None:
@@ -903,11 +939,13 @@ class LaTeXTranslator(SphinxTranslator):
self.pushbody(self.table.body)
def depart_tbody(self, node: Element) -> None:
+ if self.body and self.body[-1] == r'\sphinxhline':
+ self.body.pop()
self.popbody()
def visit_row(self, node: Element) -> None:
self.table.col = 0
-
+ _colsep = self.table.colsep
# fill columns if the row starts with the bottom of multirow cell
while True:
cell = self.table.cell(self.table.row, self.table.col)
@@ -921,24 +959,35 @@ class LaTeXTranslator(SphinxTranslator):
# insert suitable strut for equalizing row heights in given multirow
self.body.append(r'\sphinxtablestrut{%d}' % cell.cell_id)
else: # use \multicolumn for wide multirow cell
- self.body.append(r'\multicolumn{%d}{|l|}{\sphinxtablestrut{%d}}' %
- (cell.width, cell.cell_id))
+ self.body.append(r'\multicolumn{%d}{%sl%s}{\sphinxtablestrut{%d}}' %
+ (cell.width, _colsep, _colsep, cell.cell_id))
def depart_row(self, node: Element) -> None:
self.body.append(r'\\' + CR)
cells = [self.table.cell(self.table.row, i) for i in range(self.table.colcount)]
underlined = [cell.row + cell.height == self.table.row + 1 for cell in cells]
if all(underlined):
- self.body.append(r'\hline')
+ self.body.append(r'\sphinxhline')
else:
i = 0
underlined.extend([False]) # sentinel
- while i < len(underlined):
- if underlined[i] is True:
- j = underlined[i:].index(False)
- self.body.append(r'\cline{%d-%d}' % (i + 1, i + j))
- i += j
+ if underlined[0] is False:
+ i = 1
+ while i < self.table.colcount and underlined[i] is False:
+ if cells[i - 1].cell_id != cells[i].cell_id:
+ self.body.append(r'\sphinxvlinecrossing{%d}' % i)
+ i += 1
+ while i < self.table.colcount:
+ # each time here underlined[i] is True
+ j = underlined[i:].index(False)
+ self.body.append(r'\sphinxcline{%d-%d}' % (i + 1, i + j))
+ i += j
i += 1
+ while i < self.table.colcount and underlined[i] is False:
+ if cells[i - 1].cell_id != cells[i].cell_id:
+ self.body.append(r'\sphinxvlinecrossing{%d}' % i)
+ i += 1
+ self.body.append(r'\sphinxfixclines{%d}' % self.table.colcount)
self.table.row += 1
def visit_entry(self, node: Element) -> None:
@@ -947,12 +996,14 @@ class LaTeXTranslator(SphinxTranslator):
self.table.add_cell(node.get('morerows', 0) + 1, node.get('morecols', 0) + 1)
cell = self.table.cell()
context = ''
+ _colsep = self.table.colsep
if cell.width > 1:
if self.config.latex_use_latex_multicolumn:
if self.table.col == 0:
- self.body.append(r'\multicolumn{%d}{|l|}{%%' % cell.width + CR)
+ self.body.append(r'\multicolumn{%d}{%sl%s}{%%' %
+ (cell.width, _colsep, _colsep) + CR)
else:
- self.body.append(r'\multicolumn{%d}{l|}{%%' % cell.width + CR)
+ self.body.append(r'\multicolumn{%d}{l%s}{%%' % (cell.width, _colsep) + CR)
context = '}%' + CR
else:
self.body.append(r'\sphinxstartmulticolumn{%d}%%' % cell.width + CR)
@@ -992,6 +1043,7 @@ class LaTeXTranslator(SphinxTranslator):
cell = self.table.cell()
self.table.col += cell.width
+ _colsep = self.table.colsep
# fill columns if next ones are a bottom of wide-multirow cell
while True:
@@ -999,16 +1051,16 @@ class LaTeXTranslator(SphinxTranslator):
if nextcell is None: # not a bottom of multirow cell
break
else: # a bottom part of multirow cell
- self.table.col += nextcell.width
self.body.append('&')
if nextcell.width == 1:
# insert suitable strut for equalizing row heights in multirow
# they also serve to clear colour panels which would hide the text
self.body.append(r'\sphinxtablestrut{%d}' % nextcell.cell_id)
else:
- # use \multicolumn for wide multirow cell
- self.body.append(r'\multicolumn{%d}{l|}{\sphinxtablestrut{%d}}' %
- (nextcell.width, nextcell.cell_id))
+ # use \multicolumn for not first row of wide multirow cell
+ self.body.append(r'\multicolumn{%d}{l%s}{\sphinxtablestrut{%d}}' %
+ (nextcell.width, _colsep, nextcell.cell_id))
+ self.table.col += nextcell.width
def visit_acks(self, node: Element) -> None:
# this is a list in the source, but should be rendered as a
@@ -1267,14 +1319,17 @@ class LaTeXTranslator(SphinxTranslator):
if include_graphics_options:
options = '[%s]' % ','.join(include_graphics_options)
base, ext = path.splitext(uri)
+
if self.in_title and base:
# Lowercase tokens forcely because some fncychap themes capitalize
# the options of \sphinxincludegraphics unexpectedly (ex. WIDTH=...).
- self.body.append(r'\lowercase{\sphinxincludegraphics%s}{{%s}%s}' %
- (options, base, ext))
+ cmd = r'\lowercase{\sphinxincludegraphics%s}{{%s}%s}' % (options, base, ext)
else:
- self.body.append(r'\sphinxincludegraphics%s{{%s}%s}' %
- (options, base, ext))
+ cmd = r'\sphinxincludegraphics%s{{%s}%s}' % (options, base, ext)
+ # escape filepath for includegraphics, https://tex.stackexchange.com/a/202714/41112
+ if '#' in base:
+ cmd = r'{\catcode`\#=12' + cmd + '}'
+ self.body.append(cmd)
self.body.extend(post)
def depart_image(self, node: Element) -> None:
diff --git a/tests/roots/test-ext-extlinks-hardcoded-urls-multiple-replacements/index.rst b/tests/roots/test-ext-extlinks-hardcoded-urls-multiple-replacements/index.rst
index c8b008ea2..162b3611a 100644
--- a/tests/roots/test-ext-extlinks-hardcoded-urls-multiple-replacements/index.rst
+++ b/tests/roots/test-ext-extlinks-hardcoded-urls-multiple-replacements/index.rst
@@ -17,6 +17,8 @@ https://github.com/octocat
`replaceable link`_
+`non replaceable link <https://github.com/sphinx-doc/sphinx/pulls>`_
+
.. hyperlinks
.. _replaceable link: https://github.com/octocat
diff --git a/tests/roots/test-image-escape/conf.py b/tests/roots/test-image-escape/conf.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/roots/test-image-escape/conf.py
diff --git a/tests/roots/test-image-escape/img_#1.png b/tests/roots/test-image-escape/img_#1.png
new file mode 100644
index 000000000..a97e86d66
--- /dev/null
+++ b/tests/roots/test-image-escape/img_#1.png
Binary files differ
diff --git a/tests/roots/test-image-escape/index.rst b/tests/roots/test-image-escape/index.rst
new file mode 100644
index 000000000..723bf4334
--- /dev/null
+++ b/tests/roots/test-image-escape/index.rst
@@ -0,0 +1,5 @@
+Sphinx image handling
+=====================
+
+.. an image with a character that is valid in a local file path but not a URL
+.. image:: img_#1.png
diff --git a/tests/roots/test-latex-table/complex.rst b/tests/roots/test-latex-table/complex.rst
index fa84f8266..d648ff194 100644
--- a/tests/roots/test-latex-table/complex.rst
+++ b/tests/roots/test-latex-table/complex.rst
@@ -4,6 +4,27 @@ complex tables
grid table
----------
+.. rst-class:: nocolorrows
+
++---------+---------+---------+
+| header1 | header2 | header3 |
++=========+=========+=========+
+| cell1-1 | cell1-2 | cell1-3 |
++---------+ +---------+
+| cell2-1 | | cell2-3 |
++ +---------+---------+
+| | cell3-2-par1 |
++---------+ |
+| cell4-1 | cell3-2-par2 |
++---------+---------+---------+
+| cell5-1 |
++---------+---------+---------+
+
+grid table with tabularcolumns having no vline
+----------------------------------------------
+
+.. tabularcolumns:: TTT
+
+---------+---------+---------+
| header1 | header2 | header3 |
+=========+=========+=========+
@@ -26,6 +47,8 @@ table having ...
* consecutive multirow at top of row (1-1 and 1-2)
* consecutive multirow at end of row (1-4 and 1-5)
+.. rst-class:: standard
+
+-----------+-----------+-----------+-----------+-----------+
| | | cell1-3 | | |
| | +-----------+ | cell1-5 |
diff --git a/tests/roots/test-latex-table/expects/complex_spanning_cell.tex b/tests/roots/test-latex-table/expects/complex_spanning_cell.tex
index 966f39a95..d2d618942 100644
--- a/tests/roots/test-latex-table/expects/complex_spanning_cell.tex
+++ b/tests/roots/test-latex-table/expects/complex_spanning_cell.tex
@@ -14,10 +14,12 @@ consecutive multirow at end of row (1\sphinxhyphen{}4 and 1\sphinxhyphen{}5)
\begin{savenotes}\sphinxattablestart
+\sphinxthistablewithglobalstyle
+\sphinxthistablewithstandardstyle
\centering
\begin{tabulary}{\linewidth}[t]{|T|T|T|T|T|}
-\hline
-\sphinxmultirow{3}{1}{%
+\sphinxtoprule
+\sphinxtableatstartofbodyhook\sphinxmultirow{3}{1}{%
\begin{varwidth}[t]{\sphinxcolwidth{1}{5}}
\sphinxAtStartPar
cell1\sphinxhyphen{}1
@@ -49,7 +51,7 @@ cell1\sphinxhyphen{}5
\vskip-\baselineskip\vbox{\hbox{\strut}}\end{varwidth}%
}%
\\
-\cline{3-3}\sphinxtablestrut{1}&\sphinxtablestrut{2}&\sphinxmultirow{2}{6}{%
+\sphinxvlinecrossing{1}\sphinxcline{3-3}\sphinxvlinecrossing{4}\sphinxfixclines{5}\sphinxtablestrut{1}&\sphinxtablestrut{2}&\sphinxmultirow{2}{6}{%
\begin{varwidth}[t]{\sphinxcolwidth{1}{5}}
\sphinxAtStartPar
cell2\sphinxhyphen{}3
@@ -57,11 +59,11 @@ cell2\sphinxhyphen{}3
\vskip-\baselineskip\vbox{\hbox{\strut}}\end{varwidth}%
}%
&\sphinxtablestrut{4}&\sphinxtablestrut{5}\\
-\cline{5-5}\sphinxtablestrut{1}&\sphinxtablestrut{2}&\sphinxtablestrut{6}&\sphinxtablestrut{4}&
+\sphinxvlinecrossing{1}\sphinxvlinecrossing{2}\sphinxvlinecrossing{3}\sphinxcline{5-5}\sphinxfixclines{5}\sphinxtablestrut{1}&\sphinxtablestrut{2}&\sphinxtablestrut{6}&\sphinxtablestrut{4}&
\sphinxAtStartPar
cell3\sphinxhyphen{}5
\\
-\hline
+\sphinxbottomrule
\end{tabulary}
-\par
+\sphinxtableafterendhook\par
\sphinxattableend\end{savenotes}
diff --git a/tests/roots/test-latex-table/expects/gridtable.tex b/tests/roots/test-latex-table/expects/gridtable.tex
index a71c9e202..407abe7f2 100644
--- a/tests/roots/test-latex-table/expects/gridtable.tex
+++ b/tests/roots/test-latex-table/expects/gridtable.tex
@@ -1,9 +1,11 @@
\label{\detokenize{complex:grid-table}}
\begin{savenotes}\sphinxattablestart
+\sphinxthistablewithglobalstyle
+\sphinxthistablewithnocolorrowsstyle
\centering
\begin{tabulary}{\linewidth}[t]{|T|T|T|}
-\hline
+\sphinxtoprule
\sphinxstyletheadfamily
\sphinxAtStartPar
header1
@@ -14,7 +16,8 @@ header2
\sphinxAtStartPar
header3
\\
-\hline
+\sphinxmidrule
+\sphinxtableatstartofbodyhook
\sphinxAtStartPar
cell1\sphinxhyphen{}1
&\sphinxmultirow{2}{5}{%
@@ -28,7 +31,7 @@ cell1\sphinxhyphen{}2
\sphinxAtStartPar
cell1\sphinxhyphen{}3
\\
-\cline{1-1}\cline{3-3}\sphinxmultirow{2}{7}{%
+\sphinxcline{1-1}\sphinxcline{3-3}\sphinxfixclines{3}\sphinxmultirow{2}{7}{%
\begin{varwidth}[t]{\sphinxcolwidth{1}{3}}
\sphinxAtStartPar
cell2\sphinxhyphen{}1
@@ -39,7 +42,7 @@ cell2\sphinxhyphen{}1
\sphinxAtStartPar
cell2\sphinxhyphen{}3
\\
-\cline{2-3}\sphinxtablestrut{7}&\sphinxstartmulticolumn{2}%
+\sphinxcline{2-3}\sphinxfixclines{3}\sphinxtablestrut{7}&\sphinxstartmulticolumn{2}%
\sphinxmultirow{2}{9}{%
\begin{varwidth}[t]{\sphinxcolwidth{2}{3}}
\sphinxAtStartPar
@@ -52,11 +55,11 @@ cell3\sphinxhyphen{}2\sphinxhyphen{}par2
}%
\sphinxstopmulticolumn
\\
-\cline{1-1}
+\sphinxcline{1-1}\sphinxfixclines{3}
\sphinxAtStartPar
cell4\sphinxhyphen{}1
&\multicolumn{2}{l|}{\sphinxtablestrut{9}}\\
-\hline\sphinxstartmulticolumn{3}%
+\sphinxhline\sphinxstartmulticolumn{3}%
\begin{varwidth}[t]{\sphinxcolwidth{3}{3}}
\sphinxAtStartPar
cell5\sphinxhyphen{}1
@@ -64,7 +67,7 @@ cell5\sphinxhyphen{}1
\vskip-\baselineskip\vbox{\hbox{\strut}}\end{varwidth}%
\sphinxstopmulticolumn
\\
-\hline
+\sphinxbottomrule
\end{tabulary}
-\par
+\sphinxtableafterendhook\par
\sphinxattableend\end{savenotes}
diff --git a/tests/roots/test-latex-table/expects/gridtable_with_tabularcolumn.tex b/tests/roots/test-latex-table/expects/gridtable_with_tabularcolumn.tex
new file mode 100644
index 000000000..c77b99041
--- /dev/null
+++ b/tests/roots/test-latex-table/expects/gridtable_with_tabularcolumn.tex
@@ -0,0 +1,73 @@
+\label{\detokenize{complex:grid-table-with-tabularcolumns-having-no-vline}}
+
+\begin{savenotes}\sphinxattablestart
+\sphinxthistablewithglobalstyle
+\sphinxthistablewithnovlinesstyle
+\centering
+\begin{tabulary}{\linewidth}[t]{TTT}
+\sphinxtoprule
+\sphinxstyletheadfamily
+\sphinxAtStartPar
+header1
+&\sphinxstyletheadfamily
+\sphinxAtStartPar
+header2
+&\sphinxstyletheadfamily
+\sphinxAtStartPar
+header3
+\\
+\sphinxmidrule
+\sphinxtableatstartofbodyhook
+\sphinxAtStartPar
+cell1\sphinxhyphen{}1
+&\sphinxmultirow{2}{5}{%
+\begin{varwidth}[t]{\sphinxcolwidth{1}{3}}
+\sphinxAtStartPar
+cell1\sphinxhyphen{}2
+\par
+\vskip-\baselineskip\vbox{\hbox{\strut}}\end{varwidth}%
+}%
+&
+\sphinxAtStartPar
+cell1\sphinxhyphen{}3
+\\
+\sphinxcline{1-1}\sphinxcline{3-3}\sphinxfixclines{3}\sphinxmultirow{2}{7}{%
+\begin{varwidth}[t]{\sphinxcolwidth{1}{3}}
+\sphinxAtStartPar
+cell2\sphinxhyphen{}1
+\par
+\vskip-\baselineskip\vbox{\hbox{\strut}}\end{varwidth}%
+}%
+&\sphinxtablestrut{5}&
+\sphinxAtStartPar
+cell2\sphinxhyphen{}3
+\\
+\sphinxcline{2-3}\sphinxfixclines{3}\sphinxtablestrut{7}&\sphinxstartmulticolumn{2}%
+\sphinxmultirow{2}{9}{%
+\begin{varwidth}[t]{\sphinxcolwidth{2}{3}}
+\sphinxAtStartPar
+cell3\sphinxhyphen{}2\sphinxhyphen{}par1
+
+\sphinxAtStartPar
+cell3\sphinxhyphen{}2\sphinxhyphen{}par2
+\par
+\vskip-\baselineskip\vbox{\hbox{\strut}}\end{varwidth}%
+}%
+\sphinxstopmulticolumn
+\\
+\sphinxcline{1-1}\sphinxfixclines{3}
+\sphinxAtStartPar
+cell4\sphinxhyphen{}1
+&\multicolumn{2}{l}{\sphinxtablestrut{9}}\\
+\sphinxhline\sphinxstartmulticolumn{3}%
+\begin{varwidth}[t]{\sphinxcolwidth{3}{3}}
+\sphinxAtStartPar
+cell5\sphinxhyphen{}1
+\par
+\vskip-\baselineskip\vbox{\hbox{\strut}}\end{varwidth}%
+\sphinxstopmulticolumn
+\\
+\sphinxbottomrule
+\end{tabulary}
+\sphinxtableafterendhook\par
+\sphinxattableend\end{savenotes}
diff --git a/tests/roots/test-latex-table/expects/longtable.tex b/tests/roots/test-latex-table/expects/longtable.tex
index e2138ad58..754d10249 100644
--- a/tests/roots/test-latex-table/expects/longtable.tex
+++ b/tests/roots/test-latex-table/expects/longtable.tex
@@ -1,7 +1,11 @@
\label{\detokenize{longtable:longtable}}
-\begin{savenotes}\sphinxatlongtablestart\begin{longtable}[c]{|l|l|}
-\hline
+\begin{savenotes}
+\sphinxatlongtablestart
+\sphinxthistablewithglobalstyle
+\sphinxthistablewithborderlessstyle
+\begin{longtable}[c]{ll}
+\sphinxtoprule
\sphinxstyletheadfamily
\sphinxAtStartPar
header1
@@ -9,12 +13,13 @@ header1
\sphinxAtStartPar
header2
\\
-\hline
+\sphinxmidrule
\endfirsthead
-\multicolumn{2}{c}%
-{\makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}}\\
-\hline
+\multicolumn{2}{c}{\sphinxnorowcolor
+ \makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}%
+}\\
+\sphinxtoprule
\sphinxstyletheadfamily
\sphinxAtStartPar
header1
@@ -22,14 +27,17 @@ header1
\sphinxAtStartPar
header2
\\
-\hline
+\sphinxmidrule
\endhead
-\hline
-\multicolumn{2}{r}{\makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}}\\
+\sphinxbottomrule
+\multicolumn{2}{r}{\sphinxnorowcolor
+ \makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}%
+}\\
\endfoot
\endlastfoot
+\sphinxtableatstartofbodyhook
\sphinxAtStartPar
cell1\sphinxhyphen{}1
@@ -37,19 +45,22 @@ cell1\sphinxhyphen{}1
\sphinxAtStartPar
cell1\sphinxhyphen{}2
\\
-\hline
+\sphinxhline
\sphinxAtStartPar
cell2\sphinxhyphen{}1
&
\sphinxAtStartPar
cell2\sphinxhyphen{}2
\\
-\hline
+\sphinxhline
\sphinxAtStartPar
cell3\sphinxhyphen{}1
&
\sphinxAtStartPar
cell3\sphinxhyphen{}2
\\
-\hline
-\end{longtable}\sphinxatlongtableend\end{savenotes}
+\sphinxbottomrule
+\end{longtable}
+\sphinxtableafterendhook
+\sphinxatlongtableend
+\end{savenotes}
diff --git a/tests/roots/test-latex-table/expects/longtable_having_align.tex b/tests/roots/test-latex-table/expects/longtable_having_align.tex
index 764ef55f3..dcf8f83a1 100644
--- a/tests/roots/test-latex-table/expects/longtable_having_align.tex
+++ b/tests/roots/test-latex-table/expects/longtable_having_align.tex
@@ -1,7 +1,10 @@
\label{\detokenize{longtable:longtable-having-align-option}}
-\begin{savenotes}\sphinxatlongtablestart\begin{longtable}[r]{|l|l|}
-\hline
+\begin{savenotes}
+\sphinxatlongtablestart
+\sphinxthistablewithglobalstyle
+\begin{longtable}[r]{|l|l|}
+\sphinxtoprule
\sphinxstyletheadfamily
\sphinxAtStartPar
header1
@@ -9,12 +12,13 @@ header1
\sphinxAtStartPar
header2
\\
-\hline
+\sphinxmidrule
\endfirsthead
-\multicolumn{2}{c}%
-{\makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}}\\
-\hline
+\multicolumn{2}{c}{\sphinxnorowcolor
+ \makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}%
+}\\
+\sphinxtoprule
\sphinxstyletheadfamily
\sphinxAtStartPar
header1
@@ -22,14 +26,17 @@ header1
\sphinxAtStartPar
header2
\\
-\hline
+\sphinxmidrule
\endhead
-\hline
-\multicolumn{2}{r}{\makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}}\\
+\sphinxbottomrule
+\multicolumn{2}{r}{\sphinxnorowcolor
+ \makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}%
+}\\
\endfoot
\endlastfoot
+\sphinxtableatstartofbodyhook
\sphinxAtStartPar
cell1\sphinxhyphen{}1
@@ -37,19 +44,22 @@ cell1\sphinxhyphen{}1
\sphinxAtStartPar
cell1\sphinxhyphen{}2
\\
-\hline
+\sphinxhline
\sphinxAtStartPar
cell2\sphinxhyphen{}1
&
\sphinxAtStartPar
cell2\sphinxhyphen{}2
\\
-\hline
+\sphinxhline
\sphinxAtStartPar
cell3\sphinxhyphen{}1
&
\sphinxAtStartPar
cell3\sphinxhyphen{}2
\\
-\hline
-\end{longtable}\sphinxatlongtableend\end{savenotes}
+\sphinxbottomrule
+\end{longtable}
+\sphinxtableafterendhook
+\sphinxatlongtableend
+\end{savenotes}
diff --git a/tests/roots/test-latex-table/expects/longtable_having_caption.tex b/tests/roots/test-latex-table/expects/longtable_having_caption.tex
index 0ca5506be..dd2a87fa6 100644
--- a/tests/roots/test-latex-table/expects/longtable_having_caption.tex
+++ b/tests/roots/test-latex-table/expects/longtable_having_caption.tex
@@ -1,9 +1,12 @@
\label{\detokenize{longtable:longtable-having-caption}}
-\begin{savenotes}\sphinxatlongtablestart\begin{longtable}[c]{|l|l|}
+\begin{savenotes}
+\sphinxatlongtablestart
+\sphinxthistablewithglobalstyle
+\begin{longtable}[c]{|l|l|}
\sphinxthelongtablecaptionisattop
\caption{caption for longtable\strut}\label{\detokenize{longtable:id1}}\\*[\sphinxlongtablecapskipadjust]
-\hline
+\sphinxtoprule
\sphinxstyletheadfamily
\sphinxAtStartPar
header1
@@ -11,12 +14,13 @@ header1
\sphinxAtStartPar
header2
\\
-\hline
+\sphinxmidrule
\endfirsthead
-\multicolumn{2}{c}%
-{\makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}}\\
-\hline
+\multicolumn{2}{c}{\sphinxnorowcolor
+ \makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}%
+}\\
+\sphinxtoprule
\sphinxstyletheadfamily
\sphinxAtStartPar
header1
@@ -24,14 +28,17 @@ header1
\sphinxAtStartPar
header2
\\
-\hline
+\sphinxmidrule
\endhead
-\hline
-\multicolumn{2}{r}{\makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}}\\
+\sphinxbottomrule
+\multicolumn{2}{r}{\sphinxnorowcolor
+ \makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}%
+}\\
\endfoot
\endlastfoot
+\sphinxtableatstartofbodyhook
\sphinxAtStartPar
cell1\sphinxhyphen{}1
@@ -39,19 +46,22 @@ cell1\sphinxhyphen{}1
\sphinxAtStartPar
cell1\sphinxhyphen{}2
\\
-\hline
+\sphinxhline
\sphinxAtStartPar
cell2\sphinxhyphen{}1
&
\sphinxAtStartPar
cell2\sphinxhyphen{}2
\\
-\hline
+\sphinxhline
\sphinxAtStartPar
cell3\sphinxhyphen{}1
&
\sphinxAtStartPar
cell3\sphinxhyphen{}2
\\
-\hline
-\end{longtable}\sphinxatlongtableend\end{savenotes}
+\sphinxbottomrule
+\end{longtable}
+\sphinxtableafterendhook
+\sphinxatlongtableend
+\end{savenotes}
diff --git a/tests/roots/test-latex-table/expects/longtable_having_problematic_cell.tex b/tests/roots/test-latex-table/expects/longtable_having_problematic_cell.tex
index 9551a0a3b..8258612f5 100644
--- a/tests/roots/test-latex-table/expects/longtable_having_problematic_cell.tex
+++ b/tests/roots/test-latex-table/expects/longtable_having_problematic_cell.tex
@@ -1,7 +1,10 @@
\label{\detokenize{longtable:longtable-having-problematic-cell}}
-\begin{savenotes}\sphinxatlongtablestart\begin{longtable}[c]{|*{2}{\X{1}{2}|}}
-\hline
+\begin{savenotes}
+\sphinxatlongtablestart
+\sphinxthistablewithglobalstyle
+\begin{longtable}[c]{|*{2}{\X{1}{2}|}}
+\sphinxtoprule
\sphinxstyletheadfamily
\sphinxAtStartPar
header1
@@ -9,12 +12,13 @@ header1
\sphinxAtStartPar
header2
\\
-\hline
+\sphinxmidrule
\endfirsthead
-\multicolumn{2}{c}%
-{\makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}}\\
-\hline
+\multicolumn{2}{c}{\sphinxnorowcolor
+ \makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}%
+}\\
+\sphinxtoprule
\sphinxstyletheadfamily
\sphinxAtStartPar
header1
@@ -22,14 +26,17 @@ header1
\sphinxAtStartPar
header2
\\
-\hline
+\sphinxmidrule
\endhead
-\hline
-\multicolumn{2}{r}{\makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}}\\
+\sphinxbottomrule
+\multicolumn{2}{r}{\sphinxnorowcolor
+ \makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}%
+}\\
\endfoot
\endlastfoot
+\sphinxtableatstartofbodyhook
\begin{itemize}
\item {}
\sphinxAtStartPar
@@ -44,19 +51,22 @@ item2
\sphinxAtStartPar
cell1\sphinxhyphen{}2
\\
-\hline
+\sphinxhline
\sphinxAtStartPar
cell2\sphinxhyphen{}1
&
\sphinxAtStartPar
cell2\sphinxhyphen{}2
\\
-\hline
+\sphinxhline
\sphinxAtStartPar
cell3\sphinxhyphen{}1
&
\sphinxAtStartPar
cell3\sphinxhyphen{}2
\\
-\hline
-\end{longtable}\sphinxatlongtableend\end{savenotes}
+\sphinxbottomrule
+\end{longtable}
+\sphinxtableafterendhook
+\sphinxatlongtableend
+\end{savenotes}
diff --git a/tests/roots/test-latex-table/expects/longtable_having_stub_columns_and_problematic_cell.tex b/tests/roots/test-latex-table/expects/longtable_having_stub_columns_and_problematic_cell.tex
index e54f8acec..44114ce78 100644
--- a/tests/roots/test-latex-table/expects/longtable_having_stub_columns_and_problematic_cell.tex
+++ b/tests/roots/test-latex-table/expects/longtable_having_stub_columns_and_problematic_cell.tex
@@ -1,7 +1,10 @@
\label{\detokenize{longtable:longtable-having-both-stub-columns-and-problematic-cell}}
-\begin{savenotes}\sphinxatlongtablestart\begin{longtable}[c]{|*{3}{\X{1}{3}|}}
-\hline
+\begin{savenotes}
+\sphinxatlongtablestart
+\sphinxthistablewithglobalstyle
+\begin{longtable}[c]{|*{3}{\X{1}{3}|}}
+\sphinxtoprule
\sphinxstyletheadfamily
\sphinxAtStartPar
header1
@@ -12,12 +15,13 @@ header2
\sphinxAtStartPar
header3
\\
-\hline
+\sphinxmidrule
\endfirsthead
-\multicolumn{3}{c}%
-{\makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}}\\
-\hline
+\multicolumn{3}{c}{\sphinxnorowcolor
+ \makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}%
+}\\
+\sphinxtoprule
\sphinxstyletheadfamily
\sphinxAtStartPar
header1
@@ -28,14 +32,17 @@ header2
\sphinxAtStartPar
header3
\\
-\hline
+\sphinxmidrule
\endhead
-\hline
-\multicolumn{3}{r}{\makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}}\\
+\sphinxbottomrule
+\multicolumn{3}{r}{\sphinxnorowcolor
+ \makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}%
+}\\
\endfoot
\endlastfoot
+\sphinxtableatstartofbodyhook
\sphinxstyletheadfamily \begin{itemize}
\item {}
\sphinxAtStartPar
@@ -53,7 +60,7 @@ instub1\sphinxhyphen{}2
\sphinxAtStartPar
notinstub1\sphinxhyphen{}3
\\
-\hline\sphinxstyletheadfamily
+\sphinxhline\sphinxstyletheadfamily
\sphinxAtStartPar
cell2\sphinxhyphen{}1
&\sphinxstyletheadfamily
@@ -63,5 +70,8 @@ cell2\sphinxhyphen{}2
\sphinxAtStartPar
cell2\sphinxhyphen{}3
\\
-\hline
-\end{longtable}\sphinxatlongtableend\end{savenotes}
+\sphinxbottomrule
+\end{longtable}
+\sphinxtableafterendhook
+\sphinxatlongtableend
+\end{savenotes}
diff --git a/tests/roots/test-latex-table/expects/longtable_having_verbatim.tex b/tests/roots/test-latex-table/expects/longtable_having_verbatim.tex
index a0e7ecfcd..fc78914a9 100644
--- a/tests/roots/test-latex-table/expects/longtable_having_verbatim.tex
+++ b/tests/roots/test-latex-table/expects/longtable_having_verbatim.tex
@@ -1,7 +1,10 @@
\label{\detokenize{longtable:longtable-having-verbatim}}
-\begin{savenotes}\sphinxatlongtablestart\begin{longtable}[c]{|*{2}{\X{1}{2}|}}
-\hline
+\begin{savenotes}
+\sphinxatlongtablestart
+\sphinxthistablewithglobalstyle
+\begin{longtable}[c]{|*{2}{\X{1}{2}|}}
+\sphinxtoprule
\sphinxstyletheadfamily
\sphinxAtStartPar
header1
@@ -9,12 +12,13 @@ header1
\sphinxAtStartPar
header2
\\
-\hline
+\sphinxmidrule
\endfirsthead
-\multicolumn{2}{c}%
-{\makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}}\\
-\hline
+\multicolumn{2}{c}{\sphinxnorowcolor
+ \makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}%
+}\\
+\sphinxtoprule
\sphinxstyletheadfamily
\sphinxAtStartPar
header1
@@ -22,14 +26,17 @@ header1
\sphinxAtStartPar
header2
\\
-\hline
+\sphinxmidrule
\endhead
-\hline
-\multicolumn{2}{r}{\makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}}\\
+\sphinxbottomrule
+\multicolumn{2}{r}{\sphinxnorowcolor
+ \makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}%
+}\\
\endfoot
\endlastfoot
+\sphinxtableatstartofbodyhook
\begin{sphinxVerbatimintable}[commandchars=\\\{\}]
\PYG{n}{hello} \PYG{n}{world}
@@ -38,19 +45,22 @@ header2
\sphinxAtStartPar
cell1\sphinxhyphen{}2
\\
-\hline
+\sphinxhline
\sphinxAtStartPar
cell2\sphinxhyphen{}1
&
\sphinxAtStartPar
cell2\sphinxhyphen{}2
\\
-\hline
+\sphinxhline
\sphinxAtStartPar
cell3\sphinxhyphen{}1
&
\sphinxAtStartPar
cell3\sphinxhyphen{}2
\\
-\hline
-\end{longtable}\sphinxatlongtableend\end{savenotes}
+\sphinxbottomrule
+\end{longtable}
+\sphinxtableafterendhook
+\sphinxatlongtableend
+\end{savenotes}
diff --git a/tests/roots/test-latex-table/expects/longtable_having_widths.tex b/tests/roots/test-latex-table/expects/longtable_having_widths.tex
index cdd0e7a2b..5bf1507a7 100644
--- a/tests/roots/test-latex-table/expects/longtable_having_widths.tex
+++ b/tests/roots/test-latex-table/expects/longtable_having_widths.tex
@@ -1,7 +1,11 @@
\label{\detokenize{longtable:longtable-having-widths-option}}
-\begin{savenotes}\sphinxatlongtablestart\begin{longtable}[c]{|\X{30}{100}|\X{70}{100}|}
-\hline\noalign{\phantomsection\label{\detokenize{longtable:namedlongtable}}\label{\detokenize{longtable:mylongtable}}}%
+\begin{savenotes}
+\sphinxatlongtablestart
+\sphinxthistablewithglobalstyle
+\begin{longtable}[c]{|\X{30}{100}|\X{70}{100}|}
+\noalign{\phantomsection\label{\detokenize{longtable:namedlongtable}}\label{\detokenize{longtable:mylongtable}}}%
+\sphinxtoprule
\sphinxstyletheadfamily
\sphinxAtStartPar
header1
@@ -9,12 +13,13 @@ header1
\sphinxAtStartPar
header2
\\
-\hline
+\sphinxmidrule
\endfirsthead
-\multicolumn{2}{c}%
-{\makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}}\\
-\hline
+\multicolumn{2}{c}{\sphinxnorowcolor
+ \makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}%
+}\\
+\sphinxtoprule
\sphinxstyletheadfamily
\sphinxAtStartPar
header1
@@ -22,14 +27,17 @@ header1
\sphinxAtStartPar
header2
\\
-\hline
+\sphinxmidrule
\endhead
-\hline
-\multicolumn{2}{r}{\makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}}\\
+\sphinxbottomrule
+\multicolumn{2}{r}{\sphinxnorowcolor
+ \makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}%
+}\\
\endfoot
\endlastfoot
+\sphinxtableatstartofbodyhook
\sphinxAtStartPar
cell1\sphinxhyphen{}1
@@ -37,22 +45,25 @@ cell1\sphinxhyphen{}1
\sphinxAtStartPar
cell1\sphinxhyphen{}2
\\
-\hline
+\sphinxhline
\sphinxAtStartPar
cell2\sphinxhyphen{}1
&
\sphinxAtStartPar
cell2\sphinxhyphen{}2
\\
-\hline
+\sphinxhline
\sphinxAtStartPar
cell3\sphinxhyphen{}1
&
\sphinxAtStartPar
cell3\sphinxhyphen{}2
\\
-\hline
-\end{longtable}\sphinxatlongtableend\end{savenotes}
+\sphinxbottomrule
+\end{longtable}
+\sphinxtableafterendhook
+\sphinxatlongtableend
+\end{savenotes}
\sphinxAtStartPar
See {\hyperref[\detokenize{longtable:mylongtable}]{\sphinxcrossref{mylongtable}}}, same as {\hyperref[\detokenize{longtable:namedlongtable}]{\sphinxcrossref{\DUrole{std,std-ref}{this one}}}}.
diff --git a/tests/roots/test-latex-table/expects/longtable_having_widths_and_problematic_cell.tex b/tests/roots/test-latex-table/expects/longtable_having_widths_and_problematic_cell.tex
index ea868ffe4..bf9192009 100644
--- a/tests/roots/test-latex-table/expects/longtable_having_widths_and_problematic_cell.tex
+++ b/tests/roots/test-latex-table/expects/longtable_having_widths_and_problematic_cell.tex
@@ -1,7 +1,10 @@
\label{\detokenize{longtable:longtable-having-both-widths-and-problematic-cell}}
-\begin{savenotes}\sphinxatlongtablestart\begin{longtable}[c]{|\X{30}{100}|\X{70}{100}|}
-\hline
+\begin{savenotes}
+\sphinxatlongtablestart
+\sphinxthistablewithglobalstyle
+\begin{longtable}[c]{|\X{30}{100}|\X{70}{100}|}
+\sphinxtoprule
\sphinxstyletheadfamily
\sphinxAtStartPar
header1
@@ -9,12 +12,13 @@ header1
\sphinxAtStartPar
header2
\\
-\hline
+\sphinxmidrule
\endfirsthead
-\multicolumn{2}{c}%
-{\makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}}\\
-\hline
+\multicolumn{2}{c}{\sphinxnorowcolor
+ \makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}%
+}\\
+\sphinxtoprule
\sphinxstyletheadfamily
\sphinxAtStartPar
header1
@@ -22,14 +26,17 @@ header1
\sphinxAtStartPar
header2
\\
-\hline
+\sphinxmidrule
\endhead
-\hline
-\multicolumn{2}{r}{\makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}}\\
+\sphinxbottomrule
+\multicolumn{2}{r}{\sphinxnorowcolor
+ \makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}%
+}\\
\endfoot
\endlastfoot
+\sphinxtableatstartofbodyhook
\begin{itemize}
\item {}
\sphinxAtStartPar
@@ -44,19 +51,22 @@ item2
\sphinxAtStartPar
cell1\sphinxhyphen{}2
\\
-\hline
+\sphinxhline
\sphinxAtStartPar
cell2\sphinxhyphen{}1
&
\sphinxAtStartPar
cell2\sphinxhyphen{}2
\\
-\hline
+\sphinxhline
\sphinxAtStartPar
cell3\sphinxhyphen{}1
&
\sphinxAtStartPar
cell3\sphinxhyphen{}2
\\
-\hline
-\end{longtable}\sphinxatlongtableend\end{savenotes}
+\sphinxbottomrule
+\end{longtable}
+\sphinxtableafterendhook
+\sphinxatlongtableend
+\end{savenotes}
diff --git a/tests/roots/test-latex-table/expects/longtable_with_tabularcolumn.tex b/tests/roots/test-latex-table/expects/longtable_with_tabularcolumn.tex
index 426086de5..6383d9d56 100644
--- a/tests/roots/test-latex-table/expects/longtable_with_tabularcolumn.tex
+++ b/tests/roots/test-latex-table/expects/longtable_with_tabularcolumn.tex
@@ -1,7 +1,11 @@
\label{\detokenize{longtable:longtable-with-tabularcolumn}}
-\begin{savenotes}\sphinxatlongtablestart\begin{longtable}[c]{|c|c|}
-\hline
+\begin{savenotes}
+\sphinxatlongtablestart
+\sphinxthistablewithglobalstyle
+\sphinxthistablewithvlinesstyle
+\begin{longtable}[c]{|c|c|}
+\sphinxtoprule
\sphinxstyletheadfamily
\sphinxAtStartPar
header1
@@ -9,12 +13,13 @@ header1
\sphinxAtStartPar
header2
\\
-\hline
+\sphinxmidrule
\endfirsthead
-\multicolumn{2}{c}%
-{\makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}}\\
-\hline
+\multicolumn{2}{c}{\sphinxnorowcolor
+ \makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}%
+}\\
+\sphinxtoprule
\sphinxstyletheadfamily
\sphinxAtStartPar
header1
@@ -22,14 +27,17 @@ header1
\sphinxAtStartPar
header2
\\
-\hline
+\sphinxmidrule
\endhead
-\hline
-\multicolumn{2}{r}{\makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}}\\
+\sphinxbottomrule
+\multicolumn{2}{r}{\sphinxnorowcolor
+ \makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}%
+}\\
\endfoot
\endlastfoot
+\sphinxtableatstartofbodyhook
\sphinxAtStartPar
cell1\sphinxhyphen{}1
@@ -37,19 +45,22 @@ cell1\sphinxhyphen{}1
\sphinxAtStartPar
cell1\sphinxhyphen{}2
\\
-\hline
+\sphinxhline
\sphinxAtStartPar
cell2\sphinxhyphen{}1
&
\sphinxAtStartPar
cell2\sphinxhyphen{}2
\\
-\hline
+\sphinxhline
\sphinxAtStartPar
cell3\sphinxhyphen{}1
&
\sphinxAtStartPar
cell3\sphinxhyphen{}2
\\
-\hline
-\end{longtable}\sphinxatlongtableend\end{savenotes}
+\sphinxbottomrule
+\end{longtable}
+\sphinxtableafterendhook
+\sphinxatlongtableend
+\end{savenotes}
diff --git a/tests/roots/test-latex-table/expects/simple_table.tex b/tests/roots/test-latex-table/expects/simple_table.tex
index a06bfb1cf..7bd85c737 100644
--- a/tests/roots/test-latex-table/expects/simple_table.tex
+++ b/tests/roots/test-latex-table/expects/simple_table.tex
@@ -1,9 +1,10 @@
\label{\detokenize{tabular:simple-table}}
\begin{savenotes}\sphinxattablestart
+\sphinxthistablewithglobalstyle
\centering
\begin{tabulary}{\linewidth}[t]{|T|T|}
-\hline
+\sphinxtoprule
\sphinxstyletheadfamily
\sphinxAtStartPar
header1
@@ -11,28 +12,29 @@ header1
\sphinxAtStartPar
header2
\\
-\hline
+\sphinxmidrule
+\sphinxtableatstartofbodyhook
\sphinxAtStartPar
cell1\sphinxhyphen{}1
&
\sphinxAtStartPar
cell1\sphinxhyphen{}2
\\
-\hline
+\sphinxhline
\sphinxAtStartPar
cell2\sphinxhyphen{}1
&
\sphinxAtStartPar
cell2\sphinxhyphen{}2
\\
-\hline
+\sphinxhline
\sphinxAtStartPar
cell3\sphinxhyphen{}1
&
\sphinxAtStartPar
cell3\sphinxhyphen{}2
\\
-\hline
+\sphinxbottomrule
\end{tabulary}
-\par
+\sphinxtableafterendhook\par
\sphinxattableend\end{savenotes}
diff --git a/tests/roots/test-latex-table/expects/table_having_caption.tex b/tests/roots/test-latex-table/expects/table_having_caption.tex
index 33a5f1d8f..f2ce55360 100644
--- a/tests/roots/test-latex-table/expects/table_having_caption.tex
+++ b/tests/roots/test-latex-table/expects/table_having_caption.tex
@@ -1,13 +1,14 @@
\label{\detokenize{tabular:table-having-caption}}
\begin{savenotes}\sphinxattablestart
+\sphinxthistablewithglobalstyle
\centering
\sphinxcapstartof{table}
\sphinxthecaptionisattop
\sphinxcaption{caption for table}\label{\detokenize{tabular:id1}}
\sphinxaftertopcaption
\begin{tabulary}{\linewidth}[t]{|T|T|}
-\hline
+\sphinxtoprule
\sphinxstyletheadfamily
\sphinxAtStartPar
header1
@@ -15,28 +16,29 @@ header1
\sphinxAtStartPar
header2
\\
-\hline
+\sphinxmidrule
+\sphinxtableatstartofbodyhook
\sphinxAtStartPar
cell1\sphinxhyphen{}1
&
\sphinxAtStartPar
cell1\sphinxhyphen{}2
\\
-\hline
+\sphinxhline
\sphinxAtStartPar
cell2\sphinxhyphen{}1
&
\sphinxAtStartPar
cell2\sphinxhyphen{}2
\\
-\hline
+\sphinxhline
\sphinxAtStartPar
cell3\sphinxhyphen{}1
&
\sphinxAtStartPar
cell3\sphinxhyphen{}2
\\
-\hline
+\sphinxbottomrule
\end{tabulary}
-\par
+\sphinxtableafterendhook\par
\sphinxattableend\end{savenotes}
diff --git a/tests/roots/test-latex-table/expects/table_having_problematic_cell.tex b/tests/roots/test-latex-table/expects/table_having_problematic_cell.tex
index c5c57e2f7..7d7ad4b71 100644
--- a/tests/roots/test-latex-table/expects/table_having_problematic_cell.tex
+++ b/tests/roots/test-latex-table/expects/table_having_problematic_cell.tex
@@ -1,9 +1,10 @@
\label{\detokenize{tabular:table-having-problematic-cell}}
\begin{savenotes}\sphinxattablestart
+\sphinxthistablewithglobalstyle
\centering
\begin{tabular}[t]{|*{2}{\X{1}{2}|}}
-\hline
+\sphinxtoprule
\sphinxstyletheadfamily
\sphinxAtStartPar
header1
@@ -11,7 +12,8 @@ header1
\sphinxAtStartPar
header2
\\
-\hline\begin{itemize}
+\sphinxmidrule
+\sphinxtableatstartofbodyhook\begin{itemize}
\item {}
\sphinxAtStartPar
item1
@@ -25,21 +27,21 @@ item2
\sphinxAtStartPar
cell1\sphinxhyphen{}2
\\
-\hline
+\sphinxhline
\sphinxAtStartPar
cell2\sphinxhyphen{}1
&
\sphinxAtStartPar
cell2\sphinxhyphen{}2
\\
-\hline
+\sphinxhline
\sphinxAtStartPar
cell3\sphinxhyphen{}1
&
\sphinxAtStartPar
cell3\sphinxhyphen{}2
\\
-\hline
+\sphinxbottomrule
\end{tabular}
-\par
+\sphinxtableafterendhook\par
\sphinxattableend\end{savenotes}
diff --git a/tests/roots/test-latex-table/expects/table_having_stub_columns_and_problematic_cell.tex b/tests/roots/test-latex-table/expects/table_having_stub_columns_and_problematic_cell.tex
index 13c48a213..fbd797a1b 100644
--- a/tests/roots/test-latex-table/expects/table_having_stub_columns_and_problematic_cell.tex
+++ b/tests/roots/test-latex-table/expects/table_having_stub_columns_and_problematic_cell.tex
@@ -1,9 +1,10 @@
\label{\detokenize{tabular:table-having-both-stub-columns-and-problematic-cell}}
\begin{savenotes}\sphinxattablestart
+\sphinxthistablewithglobalstyle
\centering
\begin{tabular}[t]{|*{3}{\X{1}{3}|}}
-\hline
+\sphinxtoprule
\sphinxstyletheadfamily
\sphinxAtStartPar
header1
@@ -14,7 +15,8 @@ header2
\sphinxAtStartPar
header3
\\
-\hline\sphinxstyletheadfamily \begin{itemize}
+\sphinxmidrule
+\sphinxtableatstartofbodyhook\sphinxstyletheadfamily \begin{itemize}
\item {}
\sphinxAtStartPar
instub1\sphinxhyphen{}1a
@@ -31,7 +33,7 @@ instub1\sphinxhyphen{}2
\sphinxAtStartPar
notinstub1\sphinxhyphen{}3
\\
-\hline\sphinxstyletheadfamily
+\sphinxhline\sphinxstyletheadfamily
\sphinxAtStartPar
cell2\sphinxhyphen{}1
&\sphinxstyletheadfamily
@@ -41,7 +43,7 @@ cell2\sphinxhyphen{}2
\sphinxAtStartPar
cell2\sphinxhyphen{}3
\\
-\hline
+\sphinxbottomrule
\end{tabular}
-\par
+\sphinxtableafterendhook\par
\sphinxattableend\end{savenotes}
diff --git a/tests/roots/test-latex-table/expects/table_having_threeparagraphs_cell_in_first_col.tex b/tests/roots/test-latex-table/expects/table_having_threeparagraphs_cell_in_first_col.tex
index c1a440558..9acd9a86d 100644
--- a/tests/roots/test-latex-table/expects/table_having_threeparagraphs_cell_in_first_col.tex
+++ b/tests/roots/test-latex-table/expects/table_having_threeparagraphs_cell_in_first_col.tex
@@ -1,14 +1,16 @@
\label{\detokenize{tabular:table-with-cell-in-first-column-having-three-paragraphs}}
\begin{savenotes}\sphinxattablestart
+\sphinxthistablewithglobalstyle
\centering
\begin{tabulary}{\linewidth}[t]{|T|}
-\hline
+\sphinxtoprule
\sphinxstyletheadfamily
\sphinxAtStartPar
header1
\\
-\hline
+\sphinxmidrule
+\sphinxtableatstartofbodyhook
\sphinxAtStartPar
cell1\sphinxhyphen{}1\sphinxhyphen{}par1
@@ -18,7 +20,7 @@ cell1\sphinxhyphen{}1\sphinxhyphen{}par2
\sphinxAtStartPar
cell1\sphinxhyphen{}1\sphinxhyphen{}par3
\\
-\hline
+\sphinxbottomrule
\end{tabulary}
-\par
+\sphinxtableafterendhook\par
\sphinxattableend\end{savenotes}
diff --git a/tests/roots/test-latex-table/expects/table_having_verbatim.tex b/tests/roots/test-latex-table/expects/table_having_verbatim.tex
index 23faac55e..a002de586 100644
--- a/tests/roots/test-latex-table/expects/table_having_verbatim.tex
+++ b/tests/roots/test-latex-table/expects/table_having_verbatim.tex
@@ -1,9 +1,10 @@
\label{\detokenize{tabular:table-having-verbatim}}
\begin{savenotes}\sphinxattablestart
+\sphinxthistablewithglobalstyle
\centering
\begin{tabular}[t]{|*{2}{\X{1}{2}|}}
-\hline
+\sphinxtoprule
\sphinxstyletheadfamily
\sphinxAtStartPar
header1
@@ -11,7 +12,8 @@ header1
\sphinxAtStartPar
header2
\\
-\hline
+\sphinxmidrule
+\sphinxtableatstartofbodyhook
\begin{sphinxVerbatimintable}[commandchars=\\\{\}]
\PYG{n}{hello} \PYG{n}{world}
\end{sphinxVerbatimintable}
@@ -19,21 +21,21 @@ header2
\sphinxAtStartPar
cell1\sphinxhyphen{}2
\\
-\hline
+\sphinxhline
\sphinxAtStartPar
cell2\sphinxhyphen{}1
&
\sphinxAtStartPar
cell2\sphinxhyphen{}2
\\
-\hline
+\sphinxhline
\sphinxAtStartPar
cell3\sphinxhyphen{}1
&
\sphinxAtStartPar
cell3\sphinxhyphen{}2
\\
-\hline
+\sphinxbottomrule
\end{tabular}
-\par
+\sphinxtableafterendhook\par
\sphinxattableend\end{savenotes}
diff --git a/tests/roots/test-latex-table/expects/table_having_widths.tex b/tests/roots/test-latex-table/expects/table_having_widths.tex
index d01a40576..fe5f4c44d 100644
--- a/tests/roots/test-latex-table/expects/table_having_widths.tex
+++ b/tests/roots/test-latex-table/expects/table_having_widths.tex
@@ -1,10 +1,13 @@
\label{\detokenize{tabular:table-having-widths-option}}
\begin{savenotes}\sphinxattablestart
+\sphinxthistablewithglobalstyle
+\sphinxthistablewithbooktabsstyle
+\sphinxthistablewithcolorrowsstyle
\centering
\phantomsection\label{\detokenize{tabular:namedtabular}}\label{\detokenize{tabular:mytabular}}\nobreak
-\begin{tabular}[t]{|\X{30}{100}|\X{70}{100}|}
-\hline
+\begin{tabular}[t]{\X{30}{100}\X{70}{100}}
+\sphinxtoprule
\sphinxstyletheadfamily
\sphinxAtStartPar
header1
@@ -12,30 +15,31 @@ header1
\sphinxAtStartPar
header2
\\
-\hline
+\sphinxmidrule
+\sphinxtableatstartofbodyhook
\sphinxAtStartPar
cell1\sphinxhyphen{}1
&
\sphinxAtStartPar
cell1\sphinxhyphen{}2
\\
-\hline
+\sphinxhline
\sphinxAtStartPar
cell2\sphinxhyphen{}1
&
\sphinxAtStartPar
cell2\sphinxhyphen{}2
\\
-\hline
+\sphinxhline
\sphinxAtStartPar
cell3\sphinxhyphen{}1
&
\sphinxAtStartPar
cell3\sphinxhyphen{}2
\\
-\hline
+\sphinxbottomrule
\end{tabular}
-\par
+\sphinxtableafterendhook\par
\sphinxattableend\end{savenotes}
\sphinxAtStartPar
diff --git a/tests/roots/test-latex-table/expects/table_having_widths_and_problematic_cell.tex b/tests/roots/test-latex-table/expects/table_having_widths_and_problematic_cell.tex
index ca6b697e5..1baf92c1a 100644
--- a/tests/roots/test-latex-table/expects/table_having_widths_and_problematic_cell.tex
+++ b/tests/roots/test-latex-table/expects/table_having_widths_and_problematic_cell.tex
@@ -1,9 +1,10 @@
\label{\detokenize{tabular:table-having-both-widths-and-problematic-cell}}
\begin{savenotes}\sphinxattablestart
+\sphinxthistablewithglobalstyle
\centering
\begin{tabular}[t]{|\X{30}{100}|\X{70}{100}|}
-\hline
+\sphinxtoprule
\sphinxstyletheadfamily
\sphinxAtStartPar
header1
@@ -11,7 +12,8 @@ header1
\sphinxAtStartPar
header2
\\
-\hline\begin{itemize}
+\sphinxmidrule
+\sphinxtableatstartofbodyhook\begin{itemize}
\item {}
\sphinxAtStartPar
item1
@@ -25,21 +27,21 @@ item2
\sphinxAtStartPar
cell1\sphinxhyphen{}2
\\
-\hline
+\sphinxhline
\sphinxAtStartPar
cell2\sphinxhyphen{}1
&
\sphinxAtStartPar
cell2\sphinxhyphen{}2
\\
-\hline
+\sphinxhline
\sphinxAtStartPar
cell3\sphinxhyphen{}1
&
\sphinxAtStartPar
cell3\sphinxhyphen{}2
\\
-\hline
+\sphinxbottomrule
\end{tabular}
-\par
+\sphinxtableafterendhook\par
\sphinxattableend\end{savenotes}
diff --git a/tests/roots/test-latex-table/expects/tabular_having_widths.tex b/tests/roots/test-latex-table/expects/tabular_having_widths.tex
index 596ba4868..15321d693 100644
--- a/tests/roots/test-latex-table/expects/tabular_having_widths.tex
+++ b/tests/roots/test-latex-table/expects/tabular_having_widths.tex
@@ -1,9 +1,10 @@
\label{\detokenize{tabular:table-having-align-option-tabular}}
\begin{savenotes}\sphinxattablestart
+\sphinxthistablewithglobalstyle
\raggedright
\begin{tabular}[t]{|\X{30}{100}|\X{70}{100}|}
-\hline
+\sphinxtoprule
\sphinxstyletheadfamily
\sphinxAtStartPar
header1
@@ -11,28 +12,29 @@ header1
\sphinxAtStartPar
header2
\\
-\hline
+\sphinxmidrule
+\sphinxtableatstartofbodyhook
\sphinxAtStartPar
cell1\sphinxhyphen{}1
&
\sphinxAtStartPar
cell1\sphinxhyphen{}2
\\
-\hline
+\sphinxhline
\sphinxAtStartPar
cell2\sphinxhyphen{}1
&
\sphinxAtStartPar
cell2\sphinxhyphen{}2
\\
-\hline
+\sphinxhline
\sphinxAtStartPar
cell3\sphinxhyphen{}1
&
\sphinxAtStartPar
cell3\sphinxhyphen{}2
\\
-\hline
+\sphinxbottomrule
\end{tabular}
-\par
+\sphinxtableafterendhook\par
\sphinxattableend\end{savenotes}
diff --git a/tests/roots/test-latex-table/expects/tabularcolumn.tex b/tests/roots/test-latex-table/expects/tabularcolumn.tex
index c020e0cb4..fcb01be3f 100644
--- a/tests/roots/test-latex-table/expects/tabularcolumn.tex
+++ b/tests/roots/test-latex-table/expects/tabularcolumn.tex
@@ -1,9 +1,11 @@
\label{\detokenize{tabular:table-with-tabularcolumn}}
\begin{savenotes}\sphinxattablestart
+\sphinxthistablewithglobalstyle
+\sphinxthistablewithnovlinesstyle
\centering
-\begin{tabulary}{\linewidth}[t]{|c|c|}
-\hline
+\begin{tabulary}{\linewidth}[t]{cc}
+\sphinxtoprule
\sphinxstyletheadfamily
\sphinxAtStartPar
header1
@@ -11,28 +13,29 @@ header1
\sphinxAtStartPar
header2
\\
-\hline
+\sphinxmidrule
+\sphinxtableatstartofbodyhook
\sphinxAtStartPar
cell1\sphinxhyphen{}1
&
\sphinxAtStartPar
cell1\sphinxhyphen{}2
\\
-\hline
+\sphinxhline
\sphinxAtStartPar
cell2\sphinxhyphen{}1
&
\sphinxAtStartPar
cell2\sphinxhyphen{}2
\\
-\hline
+\sphinxhline
\sphinxAtStartPar
cell3\sphinxhyphen{}1
&
\sphinxAtStartPar
cell3\sphinxhyphen{}2
\\
-\hline
+\sphinxbottomrule
\end{tabulary}
-\par
+\sphinxtableafterendhook\par
\sphinxattableend\end{savenotes}
diff --git a/tests/roots/test-latex-table/expects/tabulary_having_widths.tex b/tests/roots/test-latex-table/expects/tabulary_having_widths.tex
index 0b42fb0cf..246341630 100644
--- a/tests/roots/test-latex-table/expects/tabulary_having_widths.tex
+++ b/tests/roots/test-latex-table/expects/tabulary_having_widths.tex
@@ -1,9 +1,10 @@
\label{\detokenize{tabular:table-having-align-option-tabulary}}
\begin{savenotes}\sphinxattablestart
+\sphinxthistablewithglobalstyle
\raggedleft
\begin{tabulary}{\linewidth}[t]{|T|T|}
-\hline
+\sphinxtoprule
\sphinxstyletheadfamily
\sphinxAtStartPar
header1
@@ -11,28 +12,29 @@ header1
\sphinxAtStartPar
header2
\\
-\hline
+\sphinxmidrule
+\sphinxtableatstartofbodyhook
\sphinxAtStartPar
cell1\sphinxhyphen{}1
&
\sphinxAtStartPar
cell1\sphinxhyphen{}2
\\
-\hline
+\sphinxhline
\sphinxAtStartPar
cell2\sphinxhyphen{}1
&
\sphinxAtStartPar
cell2\sphinxhyphen{}2
\\
-\hline
+\sphinxhline
\sphinxAtStartPar
cell3\sphinxhyphen{}1
&
\sphinxAtStartPar
cell3\sphinxhyphen{}2
\\
-\hline
+\sphinxbottomrule
\end{tabulary}
-\par
+\sphinxtableafterendhook\par
\sphinxattableend\end{savenotes}
diff --git a/tests/roots/test-latex-table/longtable.rst b/tests/roots/test-latex-table/longtable.rst
index bace9d4d2..da6fa5c5c 100644
--- a/tests/roots/test-latex-table/longtable.rst
+++ b/tests/roots/test-latex-table/longtable.rst
@@ -5,7 +5,7 @@ longtable
---------
.. table::
- :class: longtable
+ :class: longtable, borderless
======= =======
header1 header2
diff --git a/tests/roots/test-latex-table/tabular.rst b/tests/roots/test-latex-table/tabular.rst
index 7f0909540..15db823a0 100644
--- a/tests/roots/test-latex-table/tabular.rst
+++ b/tests/roots/test-latex-table/tabular.rst
@@ -20,6 +20,7 @@ table having :widths: option
.. table::
:widths: 30,70
:name: namedtabular
+ :class: booktabs, colorrows
======= =======
header1 header2
@@ -63,7 +64,7 @@ table having :align: option (tabular)
table with tabularcolumn
------------------------
-.. tabularcolumns:: |c|c|
+.. tabularcolumns:: cc
======= =======
header1 header2
diff --git a/tests/roots/test-object-description-sections/conf.py b/tests/roots/test-object-description-sections/conf.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/roots/test-object-description-sections/conf.py
diff --git a/tests/roots/test-object-description-sections/index.rst b/tests/roots/test-object-description-sections/index.rst
new file mode 100644
index 000000000..1892f94d6
--- /dev/null
+++ b/tests/roots/test-object-description-sections/index.rst
@@ -0,0 +1,6 @@
+.. py:function:: func()
+
+ Overview
+ --------
+
+ Lorem ipsum dolar sit amet
diff --git a/tests/roots/test-root/objects.txt b/tests/roots/test-root/objects.txt
index fa9e475e5..170c026e7 100644
--- a/tests/roots/test-root/objects.txt
+++ b/tests/roots/test-root/objects.txt
@@ -214,7 +214,8 @@ Test repeated option directive.
My secret API.
-Reference the first option :option:`-mapi=secret`.
+Reference the first option :option:`-mapi=secret`, :option:`-mapi[=xxx]`
+or :option:`-mapi with_space`.
User markup
diff --git a/tests/test_build_html.py b/tests/test_build_html.py
index 9a31a4b8a..1a717f152 100644
--- a/tests/test_build_html.py
+++ b/tests/test_build_html.py
@@ -1355,6 +1355,15 @@ def test_html_remote_images(app, status, warning):
assert not (app.outdir / 'python-logo.png').exists()
+@pytest.mark.sphinx('html', testroot='image-escape')
+def test_html_encoded_image(app, status, warning):
+ app.builder.build_all()
+
+ result = (app.outdir / 'index.html').read_text()
+ assert ('<img alt="_images/img_%231.png" src="_images/img_%231.png" />' in result)
+ assert (app.outdir / '_images/img_#1.png').exists()
+
+
@pytest.mark.sphinx('html', testroot='remote-logo')
def test_html_remote_logo(app, status, warning):
app.builder.build_all()
@@ -1716,6 +1725,9 @@ def test_option_reference_with_value(app, status, warning):
assert ('<span class="pre">-mapi</span></span><span class="sig-prename descclassname">'
'</span><a class="headerlink" href="#cmdoption-git-commit-mapi"') in content
assert 'first option <a class="reference internal" href="#cmdoption-git-commit-mapi">' in content
+ assert ('<a class="reference internal" href="#cmdoption-git-commit-mapi">'
+ '<code class="xref std std-option docutils literal notranslate"><span class="pre">-mapi[=xxx]</span></code></a>') in content
+ assert '<span class="pre">-mapi</span> <span class="pre">with_space</span>' in content
@pytest.mark.sphinx('html', testroot='theming')
diff --git a/tests/test_build_latex.py b/tests/test_build_latex.py
index 8f7a2e85a..004fc021b 100644
--- a/tests/test_build_latex.py
+++ b/tests/test_build_latex.py
@@ -22,7 +22,8 @@ LATEX_ENGINES = ['pdflatex', 'lualatex', 'xelatex']
DOCCLASSES = ['howto', 'manual']
STYLEFILES = ['article.cls', 'fancyhdr.sty', 'titlesec.sty', 'amsmath.sty',
'framed.sty', 'color.sty', 'fancyvrb.sty',
- 'fncychap.sty', 'geometry.sty', 'kvoptions.sty', 'hyperref.sty']
+ 'fncychap.sty', 'geometry.sty', 'kvoptions.sty', 'hyperref.sty',
+ 'booktabs.sty']
LATEX_WARNINGS = ENV_WARNINGS + """\
%(root)s/index.rst:\\d+: WARNING: unknown option: '&option'
@@ -58,8 +59,8 @@ def compile_latex_document(app, filename='python.tex'):
except OSError as exc: # most likely the latex executable was not found
raise pytest.skip.Exception from exc
except CalledProcessError as exc:
- print(exc.stdout)
- print(exc.stderr)
+ print(exc.stdout.decode('utf8'))
+ print(exc.stderr.decode('utf8'))
raise AssertionError('%s exited with return code %s' % (app.config.latex_engine,
exc.returncode))
@@ -90,6 +91,10 @@ def skip_if_stylefiles_notfound(testfunc):
def test_build_latex_doc(app, status, warning, engine, docclass):
app.config.latex_engine = engine
app.config.latex_documents = [app.config.latex_documents[0][:4] + (docclass,)]
+ if engine == 'xelatex':
+ app.config.latex_table_style = ['booktabs']
+ elif engine == 'lualatex':
+ app.config.latex_table_style = ['colorrows']
app.builder.init()
LaTeXTranslator.ignore_missing_images = True
@@ -723,7 +728,8 @@ def test_footnote(app, status, warning):
assert '\\sphinxcite{footnote:bar}' in result
assert ('\\bibitem[bar]{footnote:bar}\n\\sphinxAtStartPar\ncite\n') in result
assert '\\sphinxcaption{Table caption \\sphinxfootnotemark[4]' in result
- assert ('\\hline%\n\\begin{footnotetext}[4]\\sphinxAtStartFootnote\n'
+ assert ('\\sphinxmidrule\n\\sphinxtableatstartofbodyhook%\n'
+ '\\begin{footnotetext}[4]\\sphinxAtStartFootnote\n'
'footnote in table caption\n%\n\\end{footnotetext}\\ignorespaces %\n'
'\\begin{footnotetext}[5]\\sphinxAtStartFootnote\n'
'footnote in table header\n%\n\\end{footnotetext}\\ignorespaces '
@@ -731,9 +737,9 @@ def test_footnote(app, status, warning):
'VIDIOC\\_CROPCAP\n&\n\\sphinxAtStartPar\n') in result
assert ('Information about VIDIOC\\_CROPCAP %\n'
'\\begin{footnote}[6]\\sphinxAtStartFootnote\n'
- 'footnote in table not in header\n%\n\\end{footnote}\n\\\\\n\\hline\n'
- '\\end{tabulary}\n'
- '\\par\n\\sphinxattableend\\end{savenotes}\n') in result
+ 'footnote in table not in header\n%\n\\end{footnote}\n\\\\\n'
+ '\\sphinxbottomrule\n\\end{tabulary}\n'
+ '\\sphinxtableafterendhook\\par\n\\sphinxattableend\\end{savenotes}\n') in result
@pytest.mark.sphinx('latex', testroot='footnotes')
@@ -761,7 +767,8 @@ def test_reference_in_caption_and_codeblock_in_footnote(app, status, warning):
'caption of normal table}\\label{\\detokenize{index:id36}}') in result
assert ('\\caption{footnote \\sphinxfootnotemark[10] '
'in caption \\sphinxfootnotemark[11] of longtable\\strut}') in result
- assert ('\\endlastfoot\n%\n\\begin{footnotetext}[10]\\sphinxAtStartFootnote\n'
+ assert ('\\endlastfoot\n\\sphinxtableatstartofbodyhook\n%\n'
+ '\\begin{footnotetext}[10]\\sphinxAtStartFootnote\n'
'Foot note in longtable\n%\n\\end{footnotetext}\\ignorespaces %\n'
'\\begin{footnotetext}[11]\\sphinxAtStartFootnote\n'
'Second footnote in caption of longtable\n') in result
@@ -1309,6 +1316,13 @@ def test_latex_table_complex_tables(app, status, warning):
expected = get_expected('gridtable')
assert actual == expected
+ # grid table with tabularcolumns
+ # MEMO: filename should end with tabularcolumns but tabularcolumn has been
+ # used in existing other cases
+ actual = tables['grid table with tabularcolumns having no vline']
+ expected = get_expected('gridtable_with_tabularcolumn')
+ assert actual == expected
+
# complex spanning cell
actual = tables['complex spanning cell']
expected = get_expected('complex_spanning_cell')
@@ -1316,6 +1330,22 @@ def test_latex_table_complex_tables(app, status, warning):
@pytest.mark.sphinx('latex', testroot='latex-table',
+ confoverrides={'latex_table_style': ['booktabs', 'colorrows']})
+def test_latex_table_with_booktabs_and_colorrows(app, status, warning):
+ app.builder.build_all()
+ result = (app.outdir / 'python.tex').read_text(encoding='utf8')
+ assert r'\PassOptionsToPackage{booktabs}{sphinx}' in result
+ assert r'\PassOptionsToPackage{colorrows}{sphinx}' in result
+ # tabularcolumns
+ assert r'\begin{longtable}[c]{|c|c|}' in result
+ # class: standard
+ assert r'\begin{tabulary}{\linewidth}[t]{|T|T|T|T|T|}' in result
+ assert r'\begin{longtable}[c]{ll}' in result
+ assert r'\begin{tabular}[t]{*{2}{\X{1}{2}}}' in result
+ assert r'\begin{tabular}[t]{\X{30}{100}\X{70}{100}}' in result
+
+
+@pytest.mark.sphinx('latex', testroot='latex-table',
confoverrides={'templates_path': ['_mytemplates/latex']})
def test_latex_table_custom_template_caseA(app, status, warning):
app.builder.build_all()
diff --git a/tests/test_directive_object_description.py b/tests/test_directive_object_description.py
new file mode 100644
index 000000000..e161d5401
--- /dev/null
+++ b/tests/test_directive_object_description.py
@@ -0,0 +1,45 @@
+"""Test object description directives."""
+
+import pytest
+from docutils import nodes
+
+from sphinx import addnodes
+from sphinx.io import create_publisher
+from sphinx.util.docutils import sphinx_domains
+
+
+def _doctree_for_test(builder, docname: str) -> nodes.document:
+ builder.env.prepare_settings(docname)
+ publisher = create_publisher(builder.app, 'restructuredtext')
+ with sphinx_domains(builder.env):
+ publisher.set_source(source_path=builder.env.doc2path(docname))
+ publisher.publish()
+ return publisher.document
+
+
+@pytest.mark.sphinx('text', testroot='object-description-sections')
+def test_object_description_sections(app):
+ doctree = _doctree_for_test(app.builder, 'index')
+ # <document>
+ # <index>
+ # <desc>
+ # <desc_signature>
+ # <desc_name>
+ # func
+ # <desc_parameterlist>
+ # <desc_content>
+ # <section>
+ # <title>
+ # Overview
+ # <paragraph>
+ # Lorem ipsum dolar sit amet
+
+ assert isinstance(doctree[0], addnodes.index)
+ assert isinstance(doctree[1], addnodes.desc)
+ assert isinstance(doctree[1][0], addnodes.desc_signature)
+ assert isinstance(doctree[1][1], addnodes.desc_content)
+ assert isinstance(doctree[1][1][0], nodes.section)
+ assert isinstance(doctree[1][1][0][0], nodes.title)
+ assert doctree[1][1][0][0][0] == 'Overview'
+ assert isinstance(doctree[1][1][0][1], nodes.paragraph)
+ assert doctree[1][1][0][1][0] == 'Lorem ipsum dolar sit amet'
diff --git a/tests/test_ext_extlinks.py b/tests/test_ext_extlinks.py
index 0e257364e..7634db688 100644
--- a/tests/test_ext_extlinks.py
+++ b/tests/test_ext_extlinks.py
@@ -28,6 +28,7 @@ def test_all_replacements_suggested_if_multiple_replacements_possible(app, warni
app.build()
warning_output = warning.getvalue()
# there should be six warnings for replaceable URLs, three pairs per link
+ assert warning_output.count("WARNING: hardcoded link") == 6
message = (
"index.rst:%d: WARNING: hardcoded link 'https://github.com/octocat' "
"could be replaced by an extlink (try using '%s' instead)"
diff --git a/tox.ini b/tox.ini
index 1a45e6192..7ec043830 100644
--- a/tox.ini
+++ b/tox.ini
@@ -13,6 +13,7 @@ passenv =
PERL
PERL5LIB
PYTEST_ADDOPTS
+ DO_EPUBCHECK
EPUBCHECK_PATH
TERM
description =