LaTeX: support for booktabs-style and zebra-striped tables (#10759)

This is a combination of 2 + 28 + 7 + and some more commits...

* Cherry-pick: Add support for booktabs-style tables to LaTeX builder

* Cherry-pick: Add support for zebra-striped tables to LaTeX builder

Co-authored-by: Stefan Wiehler <stefan.wiehler@missinglinkelectronics.com>

Above work originally initiated by @sephalon (thanks!)

Development refactored and continued by @jfbu

* latex_table_style configuration, support booktabs, colorrows, borderless

Some details:

- Simplify a bit a conditional in the longtable template

  This also puts the target for a longtable with a label but no caption
  above the toprule for better hyperlinking (testing shows hyperlink
  target can not end up alone at bottom of previous page).

- Extend allowed syntax for colour assignments via 'sphinxsetup'

- latex_table_style new configuration value and coloured rows

  For the user interface I tried to look for inspiration in
  https://docutils.sourceforge.io/docs/user/config.html#table-style
  which mentions booktabs and borderless.  They also mention
  captionbelow which we can implement later, now that architecture
  is here.  They don't mention coloured rows.

- Test on our own document... looks fine!

- Work-around an incompatibility of \cline with row colours

- Reverse priority of classes to allow overruling booktabs by standard
  after parsing source but before letting LaTeX writer act

- Closes #8220

  Commit
  bb859c6696
  already improved a bit, this finishes it (as :rst:dir:`rst-class` was
  actually not linking to anywhere).

- Let booktabs style defaults to *not* using \cmidrule.  They actually
  don't make much sense there, as all \hline's are removed.

- Add \sphinxnorowcolor which allows construct such as this one in
  a tabularcolumns directive:

    >{\columncolor{blue}\sphinxnorowcolor}

  else LaTeX always overrides column colour by row colour

- Add TableMergeColorHeader, TableMergeColorOdd, TableMergeColorEven
  so single-row merged cells can be styled especially

- Extend row colours to all header rows not only the first one
  (all header rows will share same colour settings)

- Auto-adjust to a no '|'-colspec for optimal handling of merged cell

- Add \sphinxcolorblend

- Workaround LaTeX's \cline features and other grid tables matters

- Add \sphinxbuildwarning for important warnings

- Fix some white gaps in merged cells of tables with vlines and
  colorrows

- Work around LaTeX's \cline serious deficiencies for complex grid
  tables

  This commit corrects \cline badly impacting vertical spacing and
  making tables look even more cramped as they usually are in LaTeX
  (although one sees it clearly only with \arrarrulewidth a bit more
  than the LaTeX default of 0.4pt).

  Most importantly this commit solves the problem that \cline's got
  masked by colour panels from the row below.

- Update CHANGES for PR #10759

- Improve documentation of new latex_table_style regarding colours
This commit is contained in:
Jean-François B
2022-10-12 17:15:40 +02:00
committed by GitHub
parent c51a88da8b
commit e7c0881992
45 changed files with 1822 additions and 424 deletions

View File

@@ -2233,6 +2233,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.2.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.2.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

View File

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

View File

@@ -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`.
.. 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.
.. 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 ::
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.
|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:
+-----+------------------------------------------+
|``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 |
+-----+------------------------------------------+
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.
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::
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`).
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.
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.
.. 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}``.
.. versionchanged:: 1.6
Merged cells from complex grid tables (either multi-row, multi-column, or
both) now allow blockquotes, lists, literal blocks, ... as do regular
cells.
Sphinx's merged cells interact well with ``p{width}``, ``\X{a}{b}``,
``\Y{f}`` and tabulary's columns.
.. note::
:rst:dir:`tabularcolumns` conflicts with ``:widths:`` option of table
directives. If both are specified, ``:widths:`` option will be ignored.
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.
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::
- 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}``).
- Literal blocks do not work with ``tabulary`` at all. Sphinx will
fall back to ``tabular`` or ``longtable`` environments and generate a
suitable column specification.
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.
.. versionchanged:: 1.6
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``.
.. 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
----

View File

@@ -88,7 +88,7 @@ writing your own themes, refer to :doc:`/development/theming`.
Builtin themes
~~~~~~~~~~~~~~
.. cssclass:: longtable
.. cssclass:: longtable, standard
+--------------------+--------------------+
| **Theme overview** | |