From 53f88400bc52e6c2322387c5d086f2fb54be51ea Mon Sep 17 00:00:00 2001 From: Stefan Wiehler Date: Wed, 21 Aug 2019 10:45:22 +0200 Subject: [PATCH 01/16] Add support for booktabs-style tables to LaTeX builder Render tables without vertical rules and horizontal rules of varying thickness (with additional space above and below) using the booktabs package. This is a rebase of original commit which was on master branch prior to 2.1 release. In this rebase the \RequirePackage{booktabs} has been removed from sphinx.sty, as it has to be conditional on latex_booktabs (or whatever its name will be) configuration option, and will be repositioned in a subsequent commit. --- doc/usage/configuration.rst | 8 +++++ sphinx/builders/latex/__init__.py | 1 + sphinx/templates/latex/longtable.tex_t | 26 +++++++++++++++ sphinx/templates/latex/tabular.tex_t | 10 ++++++ sphinx/templates/latex/tabulary.tex_t | 10 ++++++ sphinx/writers/latex.py | 45 +++++++++++++++++++------- 6 files changed, 89 insertions(+), 11 deletions(-) diff --git a/doc/usage/configuration.rst b/doc/usage/configuration.rst index 9e6230cd2db..78a69289e38 100644 --- a/doc/usage/configuration.rst +++ b/doc/usage/configuration.rst @@ -2241,6 +2241,14 @@ These options influence LaTeX output. .. versionadded:: 1.8 +.. confval:: latex_booktabs + + If ``True``, render tables without vertical rules and horizontal rules of + varying thickness (with additional space above and below) using the + ``booktabs`` package. + + .. versionadded:: 2.1 + .. confval:: latex_elements .. versionadded:: 0.5 diff --git a/sphinx/builders/latex/__init__.py b/sphinx/builders/latex/__init__.py index 32f9d32ef88..f3e4bf8d85f 100644 --- a/sphinx/builders/latex/__init__.py +++ b/sphinx/builders/latex/__init__.py @@ -517,6 +517,7 @@ def setup(app: Sphinx) -> Dict[str, Any]: app.add_config_value('latex_appendices', [], None) app.add_config_value('latex_use_latex_multicolumn', False, None) app.add_config_value('latex_use_xindy', default_latex_use_xindy, None, [bool]) + app.add_config_value('latex_booktabs', False, None) app.add_config_value('latex_toplevel_sectioning', None, None, ENUM(None, 'part', 'chapter', 'section')) app.add_config_value('latex_domain_indices', True, None, [list]) diff --git a/sphinx/templates/latex/longtable.tex_t b/sphinx/templates/latex/longtable.tex_t index 8d4cd748c1e..862a9eae5d7 100644 --- a/sphinx/templates/latex/longtable.tex_t +++ b/sphinx/templates/latex/longtable.tex_t @@ -10,25 +10,51 @@ <%- if table.caption -%> \sphinxthelongtablecaptionisattop \caption{<%= ''.join(table.caption) %>\strut}<%= labels %>\\*[\sphinxlongtablecapskipadjust] +<%- if table.booktabs -%> +\toprule +<% else -%> \hline +<% endif -%> <% elif labels -%> +<%- if table.booktabs -%> +\toprule\noalign{\phantomsection<%= labels %>}% +<% else -%> \hline\noalign{\phantomsection<%= labels %>}% +<% endif -%> +<% else -%> +<%- if table.booktabs -%> +\toprule <% else -%> \hline <% endif -%> +<% endif -%> <%= ''.join(table.header) %> \endfirsthead \multicolumn{<%= table.colcount %>}{c}% {\makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} <%= _('continued from previous page') %>}}}\\ +<%- if table.booktabs -%> +\toprule +<% else -%> \hline +<% endif -%> <%= ''.join(table.header) %> +<%- if table.header and table.booktabs -%> +\midrule +<% endif -%> \endhead +<%- if table.booktabs -%> +\bottomrule +<% else -%> \hline +<% endif -%> \multicolumn{<%= table.colcount %>}{r}{\makebox[0pt][r]{\sphinxtablecontinued{<%= _('continues on next page') %>}}}\\ \endfoot \endlastfoot <%= ''.join(table.body) %> +<%- if table.booktabs -%> +\bottomrule +<% endif -%> \end{longtable}\sphinxatlongtableend\end{savenotes} diff --git a/sphinx/templates/latex/tabular.tex_t b/sphinx/templates/latex/tabular.tex_t index a0db7faff1f..e1cb39311b2 100644 --- a/sphinx/templates/latex/tabular.tex_t +++ b/sphinx/templates/latex/tabular.tex_t @@ -19,9 +19,19 @@ \phantomsection<%= labels %>\nobreak <% endif -%> \begin{tabular}[t]<%= table.get_colspec() -%> +<%- if table.booktabs -%> +\toprule +<%- else -%> \hline +<%- endif -%> <%= ''.join(table.header) %> +<%- if table.header and table.booktabs -%> +\midrule +<%- endif -%> <%=- ''.join(table.body) %> +<%- if table.booktabs -%> +\bottomrule +<%- endif -%> \end{tabular} \par \sphinxattableend\end{savenotes} diff --git a/sphinx/templates/latex/tabulary.tex_t b/sphinx/templates/latex/tabulary.tex_t index 3236b798a52..15a8f058a8f 100644 --- a/sphinx/templates/latex/tabulary.tex_t +++ b/sphinx/templates/latex/tabulary.tex_t @@ -19,9 +19,19 @@ \phantomsection<%= labels %>\nobreak <% endif -%> \begin{tabulary}{\linewidth}[t]<%= table.get_colspec() -%> +<%- if table.booktabs -%> +\toprule +<%- else -%> \hline +<%- endif -%> <%= ''.join(table.header) %> +<%- if table.header and table.booktabs -%> +\midrule +<%- endif -%> <%=- ''.join(table.body) %> +<%- if table.booktabs -%> +\bottomrule +<%- endif -%> \end{tabulary} \par \sphinxattableend\end{savenotes} diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py index 5debd681f4c..694054d73c5 100644 --- a/sphinx/writers/latex.py +++ b/sphinx/writers/latex.py @@ -150,16 +150,21 @@ def get_colspec(self) -> str: elif 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}' % (self.colsep, self.colsep.join(colspecs), + self.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}}' % (self.colsep, self.colcount, + self.colcount, self.colsep) + CR elif self.get_table_type() == 'tabulary': # sphinx.sty sets T to be J by default. - return '{|' + ('T|' * self.colcount) + '}' + CR + return '{' + self.colsep + (('T' + self.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}}' % (self.colsep, self.colcount, + self.colcount, self.colsep) + CR else: - return '{|' + ('l|' * self.colcount) + '}' + CR + return '{' + self.colsep + (('l' + self.colsep) * self.colcount) + \ + '}' + CR def add_cell(self, height: int, width: int) -> None: """Adds a new cell to a table. @@ -863,6 +868,12 @@ def visit_table(self, node: Element) -> None: logger.info(__('both tabularcolumns and :widths: option are given. ' ':widths: is ignored.'), location=node) self.next_table_colspec = None + if self.builder.config.latex_booktabs: + self.table.booktabs = True + self.table.colsep = '' + else: + self.table.booktabs = False + self.table.colsep = '|' def depart_table(self, node: Element) -> None: labels = self.hypertarget_to(node) @@ -921,11 +932,16 @@ def visit_row(self, node: Element) -> None: # 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}' + r'{\sphinxtablestrut{%d}}' % + (cell.width, self.table.colsep, + self.table.colsep, cell.cell_id)) def depart_row(self, node: Element) -> None: self.body.append(r'\\' + CR) + if self.table.booktabs: + self.table.row += 1 + return 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): @@ -950,9 +966,14 @@ def visit_entry(self, node: Element) -> None: 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, + self.table.colsep, + self.table.colsep)) + CR else: - self.body.append(r'\multicolumn{%d}{l|}{%%' % cell.width + CR) + self.body.append(r'\multicolumn{%d}{l%s}{%%' % + (cell.width, + self.table.colsep)) + CR context = '}%' + CR else: self.body.append(r'\sphinxstartmulticolumn{%d}%%' % cell.width + CR) @@ -1007,8 +1028,10 @@ def depart_entry(self, node: Element) -> None: 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)) + self.body.append(r'\multicolumn{%d}{l%s}' + r'{\sphinxtablestrut{%d}}' % + (nextcell.width, self.table.colsep, + nextcell.cell_id)) def visit_acks(self, node: Element) -> None: # this is a list in the source, but should be rendered as a From a32331c0b9d36782527a511bc8f8b4838097af96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20B?= <2589111+jfbu@users.noreply.github.com> Date: Sat, 6 Aug 2022 18:35:25 +0200 Subject: [PATCH 02/16] Re-implement option latex_use_booktabs, adapt existing tests --- doc/usage/configuration.rst | 8 ++- sphinx/builders/latex/__init__.py | 3 +- sphinx/templates/latex/latex.tex_t | 3 + sphinx/templates/latex/longtable.tex_t | 45 ++++-------- sphinx/templates/latex/tabular.tex_t | 18 ++--- sphinx/templates/latex/tabulary.tex_t | 18 ++--- sphinx/texinputs/sphinx.sty | 33 +++++++++ sphinx/texinputs/sphinxlatextables.sty | 35 +++++---- sphinx/writers/latex.py | 72 +++++++++---------- .../expects/complex_spanning_cell.tex | 8 +-- .../test-latex-table/expects/gridtable.tex | 14 ++-- .../test-latex-table/expects/longtable.tex | 16 ++--- .../expects/longtable_having_align.tex | 16 ++--- .../expects/longtable_having_caption.tex | 16 ++--- .../longtable_having_problematic_cell.tex | 16 ++--- ...ving_stub_columns_and_problematic_cell.tex | 14 ++-- .../expects/longtable_having_verbatim.tex | 16 ++--- .../expects/longtable_having_widths.tex | 16 ++--- ...ble_having_widths_and_problematic_cell.tex | 16 ++--- .../expects/longtable_with_tabularcolumn.tex | 16 ++--- .../test-latex-table/expects/simple_table.tex | 10 +-- .../expects/table_having_caption.tex | 10 +-- .../expects/table_having_problematic_cell.tex | 10 +-- ...ving_stub_columns_and_problematic_cell.tex | 8 +-- ...ving_threeparagraphs_cell_in_first_col.tex | 6 +- .../expects/table_having_verbatim.tex | 10 +-- .../expects/table_having_widths.tex | 10 +-- ...ble_having_widths_and_problematic_cell.tex | 10 +-- .../expects/tabular_having_widths.tex | 10 +-- .../expects/tabularcolumn.tex | 10 +-- .../expects/tabulary_having_widths.tex | 10 +-- tests/test_build_latex.py | 6 +- 32 files changed, 261 insertions(+), 248 deletions(-) diff --git a/doc/usage/configuration.rst b/doc/usage/configuration.rst index 78a69289e38..6550c35890d 100644 --- a/doc/usage/configuration.rst +++ b/doc/usage/configuration.rst @@ -2241,13 +2241,15 @@ These options influence LaTeX output. .. versionadded:: 1.8 -.. confval:: latex_booktabs +.. confval:: latex_use_booktabs_package If ``True``, render tables without vertical rules and horizontal rules of varying thickness (with additional space above and below) using the - ``booktabs`` package. + booktabs_ package. - .. versionadded:: 2.1 + .. _booktabs: https://ctan.org/pkg/booktabs + + .. versionadded:: 5.2.0 .. confval:: latex_elements diff --git a/sphinx/builders/latex/__init__.py b/sphinx/builders/latex/__init__.py index f3e4bf8d85f..f02e69483e6 100644 --- a/sphinx/builders/latex/__init__.py +++ b/sphinx/builders/latex/__init__.py @@ -170,6 +170,7 @@ def init_context(self) -> None: self.context.update(self.config.latex_elements) self.context['release'] = self.config.release self.context['use_xindy'] = self.config.latex_use_xindy + self.context['use_booktabs'] = self.config.latex_use_booktabs if self.config.today: self.context['date'] = self.config.today @@ -517,7 +518,7 @@ def setup(app: Sphinx) -> Dict[str, Any]: app.add_config_value('latex_appendices', [], None) app.add_config_value('latex_use_latex_multicolumn', False, None) app.add_config_value('latex_use_xindy', default_latex_use_xindy, None, [bool]) - app.add_config_value('latex_booktabs', False, None) + app.add_config_value('latex_use_booktabs', False, None) app.add_config_value('latex_toplevel_sectioning', None, None, ENUM(None, 'part', 'chapter', 'section')) app.add_config_value('latex_domain_indices', True, None, [list]) diff --git a/sphinx/templates/latex/latex.tex_t b/sphinx/templates/latex/latex.tex_t index 66408a4c4a5..1cebac93418 100644 --- a/sphinx/templates/latex/latex.tex_t +++ b/sphinx/templates/latex/latex.tex_t @@ -25,6 +25,9 @@ %% memoir class requires extra handling \makeatletter\@ifclassloaded{memoir} {\ifdefined\memhyperindexfalse\memhyperindexfalse\fi}{}\makeatother +<% endif %> +<% if use_booktabs -%> +\PassOptionsToPackage{booktabs}{sphinx} <% endif -%> <%= passoptionstopackages %> \PassOptionsToPackage{warn}{textcomp} diff --git a/sphinx/templates/latex/longtable.tex_t b/sphinx/templates/latex/longtable.tex_t index 862a9eae5d7..a96c2003775 100644 --- a/sphinx/templates/latex/longtable.tex_t +++ b/sphinx/templates/latex/longtable.tex_t @@ -10,51 +10,32 @@ <%- if table.caption -%> \sphinxthelongtablecaptionisattop \caption{<%= ''.join(table.caption) %>\strut}<%= labels %>\\*[\sphinxlongtablecapskipadjust] -<%- if table.booktabs -%> -\toprule -<% else -%> -\hline -<% endif -%> +\sphinxtoprule <% elif labels -%> -<%- if table.booktabs -%> -\toprule\noalign{\phantomsection<%= labels %>}% -<% else -%> -\hline\noalign{\phantomsection<%= labels %>}% -<% endif -%> -<% else -%> -<%- if table.booktabs -%> -\toprule +\sphinxtoprule\noalign{\phantomsection<%= labels %>}% <% else -%> -\hline +\sphinxtoprule <% endif -%> +<%= ''.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') %>}}}\\ -<%- if table.booktabs -%> -\toprule -<% else -%> -\hline -<% endif -%> -<%= ''.join(table.header) %> -<%- if table.header and table.booktabs -%> -\midrule +\sphinxtoprule +<%= ''.join(table.header) -%> +<%- if table.header -%> +\sphinxmidrule <% endif -%> \endhead -<%- if table.booktabs -%> -\bottomrule -<% else -%> -\hline -<% endif -%> +\sphinxbottomrule \multicolumn{<%= table.colcount %>}{r}{\makebox[0pt][r]{\sphinxtablecontinued{<%= _('continues on next page') %>}}}\\ \endfoot \endlastfoot -<%= ''.join(table.body) %> -<%- if table.booktabs -%> -\bottomrule -<% endif -%> +<%= ''.join(table.body) -%> +\sphinxbottomrule \end{longtable}\sphinxatlongtableend\end{savenotes} diff --git a/sphinx/templates/latex/tabular.tex_t b/sphinx/templates/latex/tabular.tex_t index e1cb39311b2..d1a0b97f488 100644 --- a/sphinx/templates/latex/tabular.tex_t +++ b/sphinx/templates/latex/tabular.tex_t @@ -19,19 +19,13 @@ \phantomsection<%= labels %>\nobreak <% endif -%> \begin{tabular}[t]<%= table.get_colspec() -%> -<%- if table.booktabs -%> -\toprule -<%- else -%> -\hline -<%- endif -%> -<%= ''.join(table.header) %> -<%- if table.header and table.booktabs -%> -\midrule -<%- endif -%> -<%=- ''.join(table.body) %> -<%- if table.booktabs -%> -\bottomrule +\sphinxtoprule +<%= ''.join(table.header) -%> +<%- if table.header -%> +\sphinxmidrule <%- endif -%> +<%=- ''.join(table.body) -%> +\sphinxbottomrule \end{tabular} \par \sphinxattableend\end{savenotes} diff --git a/sphinx/templates/latex/tabulary.tex_t b/sphinx/templates/latex/tabulary.tex_t index 15a8f058a8f..f71214f5491 100644 --- a/sphinx/templates/latex/tabulary.tex_t +++ b/sphinx/templates/latex/tabulary.tex_t @@ -19,19 +19,13 @@ \phantomsection<%= labels %>\nobreak <% endif -%> \begin{tabulary}{\linewidth}[t]<%= table.get_colspec() -%> -<%- if table.booktabs -%> -\toprule -<%- else -%> -\hline -<%- endif -%> -<%= ''.join(table.header) %> -<%- if table.header and table.booktabs -%> -\midrule -<%- endif -%> -<%=- ''.join(table.body) %> -<%- if table.booktabs -%> -\bottomrule +\sphinxtoprule +<%= ''.join(table.header) -%> +<%- if table.header -%> +\sphinxmidrule <%- endif -%> +<%=- ''.join(table.body) -%> +\sphinxbottomrule \end{tabulary} \par \sphinxattableend\end{savenotes} diff --git a/sphinx/texinputs/sphinx.sty b/sphinx/texinputs/sphinx.sty index 8e01c8ac24c..dabe1d37b75 100644 --- a/sphinx/texinputs/sphinx.sty +++ b/sphinx/texinputs/sphinx.sty @@ -57,6 +57,8 @@ \RequirePackage{kvoptions} \SetupKeyvalOptions{prefix=spx@opt@} % use \spx@opt@ prefix +% Optional usage of booktabs package for tables +\DeclareBoolOption[false]{booktabs} % Sphinx legacy text layout: 1in margins on all four sides \ifx\@jsc@uplatextrue\@undefined \DeclareStringOption[1in]{hmargin} @@ -594,6 +596,7 @@ \DisableKeyvalOption{sphinx}{numfigreset} \DisableKeyvalOption{sphinx}{nonumfigreset} \DisableKeyvalOption{sphinx}{mathnumfig} +\DisableKeyvalOption{sphinx}{booktabs} % 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 @@ -724,6 +727,36 @@ %% TABLES % \input{sphinxlatextables.sty} +% Those two are produced by the latex writer +\def\sphinxhline{\hline} +\def\sphinxcline{\cline} +% Those three are inserted by the table templates +\def\sphinxtoprule{\hline} +\def\sphinxmidrule{\hline} +\def\sphinxbottomrule{\hline} +% \def\sphinxarrayrulewidth{\arrayrulewidth}% already done +\ifspx@opt@booktabs + \RequirePackage{booktabs} + \def\sphinxarrayrulewidth{\z@}% (attention! Do NOT assign to \sphinxarrayrulewidth + % this would modify \z@ and break all of LaTeX...) + \let\sphinxhline\@empty + \def\sphinxcline{\cmidrule(lr)}% + \def\sphinxtoprule{\toprule}% + \def\sphinxmidrule{\midrule}% + \def\sphinxbottomrule{\bottomrule}% +\fi +\AtBeginDocument +{\@ifpackageloaded{booktabs}% + {\ifspx@opt@booktabs\else + \AtEndDocument{% +\PackageWarningNoLine{sphinx}{% + Package booktabs is detected but configuration option\MessageBreak + latex_use_booktabs is False. Tables will not use booktabs styling}% +}% + \fi}% + {}% +}% + %% NUMBERING OF FIGURES, TABLES, AND LITERAL BLOCKS diff --git a/sphinx/texinputs/sphinxlatextables.sty b/sphinx/texinputs/sphinxlatextables.sty index c3c1d6ad1ff..bc4cdc44583 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/07 tables]% % Provides support for this output mark-up from Sphinx latex writer % and table templates: @@ -42,10 +42,11 @@ % sphinxpackagemulticell.sty % X or S (Sphinx) may have meanings if some table package is loaded hence % \X was chosen to avoid possibility of conflict +\def\sphinxarrayrulewidth{\arrayrulewidth}% will be set to \z@ if booktabs option \newcolumntype{\X}[2]{p{\dimexpr - (\linewidth-\arrayrulewidth)*#1/#2-\tw@\tabcolsep-\arrayrulewidth\relax}} + (\linewidth-\sphinxarrayrulewidth)*#1/#2-\tw@\tabcolsep-\sphinxarrayrulewidth\relax}} \newcolumntype{\Y}[1]{p{\dimexpr - #1\dimexpr\linewidth-\arrayrulewidth\relax-\tw@\tabcolsep-\arrayrulewidth\relax}} + #1\dimexpr\linewidth-\sphinxarrayrulewidth\relax-\tw@\tabcolsep-\sphinxarrayrulewidth\relax}} % using here T (for Tabulary) feels less of a problem than the X could be \newcolumntype{T}{J}% % For tables allowing pagebreaks @@ -208,6 +209,10 @@ % \arrayrulewidth space for each column separation in its estimate of available % width). % +% EDIT: Sphinx 5.2.0 uses \sphinxarrayrulewidth which is \z@ if booktabs +% option has been used. Do not mix booktabs option with usage of | in +% tabularcolumns directive. +% % 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. @@ -285,12 +290,12 @@ \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-\sphinxarrayrulewidth)/\sphinx@tempa + -\tw@\tabcolsep-\sphinxarrayrulewidth\relax}% \fi \noindent\kern\sphinx@tempb\relax \xdef\sphinx@multiwidth - {\the\dimexpr\sphinx@multiwidth+\sphinx@tempb+\tw@\tabcolsep+\arrayrulewidth}% + {\the\dimexpr\sphinx@multiwidth+\sphinx@tempb+\tw@\tabcolsep+\sphinxarrayrulewidth}% % hack the \vline and the colortbl macros \sphinx@hack@vline\sphinx@hack@CT&\relax % repeat @@ -299,8 +304,10 @@ % 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: +% (5.2.0 sets \sphinxarrayrulewidth to expand to \z@ if booktabs option has been +% made use of, the \arrayrulewidth\z@ serves then nothing but shoud not hurt). \def\sphinx@hack@vline{\ifnum\currentgrouptype=6\relax - \kern\arrayrulewidth\arrayrulewidth\z@\else\aftergroup\sphinx@hack@vline\fi}% + \kern\sphinxarrayrulewidth\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 @@ -320,8 +327,8 @@ \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-\sphinxarrayrulewidth)/\sphinx@tempa + -\tw@\tabcolsep-\sphinxarrayrulewidth\relax}% \fi % we need to remove colour set-up also for last cell of the multi-column \aftergroup\sphinx@hack@CT @@ -345,8 +352,8 @@ \linewidth \else % l, c, r columns. Do our best. - \dimexpr(\linewidth-\arrayrulewidth)/#2- - \tw@\tabcolsep-\arrayrulewidth\relax + \dimexpr(\linewidth-\sphinxarrayrulewidth)/#2- + \tw@\tabcolsep-\sphinxarrayrulewidth\relax \fi \else % in tabulary \ifx\equation$%$% first pass @@ -357,8 +364,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-\sphinxarrayrulewidth)/#2- + \tw@\tabcolsep-\sphinxarrayrulewidth\relax \fi \fi \fi @@ -368,7 +375,7 @@ % \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}% + -\sphinxarrayrulewidth)*#2-\tw@\tabcolsep-\sphinxarrayrulewidth\relax}% %%%%%%%%%%%%%%%%%% % --- MULTIROW --- diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py index 694054d73c5..638f65b7624 100644 --- a/sphinx/writers/latex.py +++ b/sphinx/writers/latex.py @@ -99,6 +99,7 @@ def __init__(self, node: Element) -> None: self.classes: List[str] = node.get('classes', []) self.colcount = 0 self.colspec: str = None + self.booktabs = False self.colwidths: List[int] = [] self.has_problematic = False self.has_oldproblematic = False @@ -143,28 +144,30 @@ def get_colspec(self) -> str: 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 = '' if self.booktabs else '|' + 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%s%s}' % (self.colsep, self.colsep.join(colspecs), - self.colsep) + CR + return '{%s%s%s}' % (_colsep, _colsep.join(colspecs), _colsep) + CR elif self.has_problematic: - return r'{%s*{%d}{\X{1}{%d}%s}}' % (self.colsep, self.colcount, - self.colcount, self.colsep) + 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 '{' + self.colsep + (('T' + self.colsep) * self.colcount) + \ - '}' + CR + return '{' + _colsep + (('T' + _colsep) * self.colcount) + '}' + CR elif self.has_oldproblematic: - return r'{%s*{%d}{\X{1}{%d}%s}}' % (self.colsep, self.colcount, - self.colcount, self.colsep) + CR + return r'{%s*{%d}{\X{1}{%d}%s}}' % (_colsep, self.colcount, + self.colcount, _colsep) + CR else: - return '{' + self.colsep + (('l' + self.colsep) * 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. @@ -862,18 +865,17 @@ def visit_table(self, node: Element) -> None: (self.curfilestack[-1], node.line or '')) self.tables.append(Table(node)) + self.table.booktabs = self.builder.config.latex_use_booktabs if self.next_table_colspec: self.table.colspec = '{%s}' % self.next_table_colspec + CR if 'colwidths-given' in node.get('classes', []): logger.info(__('both tabularcolumns and :widths: option are given. ' ':widths: is ignored.'), location=node) + if '|' in self.table.colspec and self.table.booktabs: + logger.info(__('tabularcolumns argument contains | which conflicts with' + 'latex_use_booktabs = True. This may cause layout problems' + 'in PDF output.'), location=node) self.next_table_colspec = None - if self.builder.config.latex_booktabs: - self.table.booktabs = True - self.table.colsep = '' - else: - self.table.booktabs = False - self.table.colsep = '|' def depart_table(self, node: Element) -> None: labels = self.hypertarget_to(node) @@ -907,6 +909,8 @@ def visit_thead(self, node: Element) -> None: 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: @@ -914,10 +918,13 @@ def visit_tbody(self, node: Element) -> None: 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 = '' if self.table.booktabs else '|' # fill columns if the row starts with the bottom of multirow cell while True: @@ -932,27 +939,22 @@ def visit_row(self, node: Element) -> None: # 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}{%sl%s}' - r'{\sphinxtablestrut{%d}}' % - (cell.width, self.table.colsep, - self.table.colsep, 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) - if self.table.booktabs: - self.table.row += 1 - return 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)) + self.body.append(r'\sphinxcline{%d-%d}' % (i + 1, i + j)) i += j i += 1 self.table.row += 1 @@ -963,17 +965,14 @@ def visit_entry(self, node: Element) -> None: self.table.add_cell(node.get('morerows', 0) + 1, node.get('morecols', 0) + 1) cell = self.table.cell() context = '' + _colsep = '' if self.table.booktabs else '|' if cell.width > 1: if self.config.latex_use_latex_multicolumn: if self.table.col == 0: self.body.append(r'\multicolumn{%d}{%sl%s}{%%' % - (cell.width, - self.table.colsep, - self.table.colsep)) + CR + (cell.width, _colsep, _colsep) + CR) else: - self.body.append(r'\multicolumn{%d}{l%s}{%%' % - (cell.width, - self.table.colsep)) + 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) @@ -1013,6 +1012,7 @@ def depart_entry(self, node: Element) -> None: cell = self.table.cell() self.table.col += cell.width + _colsep = '' if self.table.booktabs else '|' # fill columns if next ones are a bottom of wide-multirow cell while True: @@ -1028,10 +1028,8 @@ def depart_entry(self, node: Element) -> None: self.body.append(r'\sphinxtablestrut{%d}' % nextcell.cell_id) else: # use \multicolumn for wide multirow cell - self.body.append(r'\multicolumn{%d}{l%s}' - r'{\sphinxtablestrut{%d}}' % - (nextcell.width, self.table.colsep, - nextcell.cell_id)) + self.body.append(r'\multicolumn{%d}{l%s}{\sphinxtablestrut{%d}}' % + (nextcell.width, _colsep, nextcell.cell_id)) def visit_acks(self, node: Element) -> None: # this is a list in the source, but should be rendered as a 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 966f39a955e..81fc939067b 100644 --- a/tests/roots/test-latex-table/expects/complex_spanning_cell.tex +++ b/tests/roots/test-latex-table/expects/complex_spanning_cell.tex @@ -16,7 +16,7 @@ \begin{savenotes}\sphinxattablestart \centering \begin{tabulary}{\linewidth}[t]{|T|T|T|T|T|} -\hline +\sphinxtoprule \sphinxmultirow{3}{1}{% \begin{varwidth}[t]{\sphinxcolwidth{1}{5}} \sphinxAtStartPar @@ -49,7 +49,7 @@ \vskip-\baselineskip\vbox{\hbox{\strut}}\end{varwidth}% }% \\ -\cline{3-3}\sphinxtablestrut{1}&\sphinxtablestrut{2}&\sphinxmultirow{2}{6}{% +\sphinxcline{3-3}\sphinxtablestrut{1}&\sphinxtablestrut{2}&\sphinxmultirow{2}{6}{% \begin{varwidth}[t]{\sphinxcolwidth{1}{5}} \sphinxAtStartPar cell2\sphinxhyphen{}3 @@ -57,11 +57,11 @@ \vskip-\baselineskip\vbox{\hbox{\strut}}\end{varwidth}% }% &\sphinxtablestrut{4}&\sphinxtablestrut{5}\\ -\cline{5-5}\sphinxtablestrut{1}&\sphinxtablestrut{2}&\sphinxtablestrut{6}&\sphinxtablestrut{4}& +\sphinxcline{5-5}\sphinxtablestrut{1}&\sphinxtablestrut{2}&\sphinxtablestrut{6}&\sphinxtablestrut{4}& \sphinxAtStartPar cell3\sphinxhyphen{}5 \\ -\hline +\sphinxbottomrule \end{tabulary} \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 a71c9e202a0..f5780a5ea3c 100644 --- a/tests/roots/test-latex-table/expects/gridtable.tex +++ b/tests/roots/test-latex-table/expects/gridtable.tex @@ -3,7 +3,7 @@ \begin{savenotes}\sphinxattablestart \centering \begin{tabulary}{\linewidth}[t]{|T|T|T|} -\hline +\sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar header1 @@ -14,7 +14,7 @@ \sphinxAtStartPar header3 \\ -\hline +\sphinxmidrule \sphinxAtStartPar cell1\sphinxhyphen{}1 &\sphinxmultirow{2}{5}{% @@ -28,7 +28,7 @@ \sphinxAtStartPar cell1\sphinxhyphen{}3 \\ -\cline{1-1}\cline{3-3}\sphinxmultirow{2}{7}{% +\sphinxcline{1-1}\sphinxcline{3-3}\sphinxmultirow{2}{7}{% \begin{varwidth}[t]{\sphinxcolwidth{1}{3}} \sphinxAtStartPar cell2\sphinxhyphen{}1 @@ -39,7 +39,7 @@ \sphinxAtStartPar cell2\sphinxhyphen{}3 \\ -\cline{2-3}\sphinxtablestrut{7}&\sphinxstartmulticolumn{2}% +\sphinxcline{2-3}\sphinxtablestrut{7}&\sphinxstartmulticolumn{2}% \sphinxmultirow{2}{9}{% \begin{varwidth}[t]{\sphinxcolwidth{2}{3}} \sphinxAtStartPar @@ -52,11 +52,11 @@ }% \sphinxstopmulticolumn \\ -\cline{1-1} +\sphinxcline{1-1} \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 +64,7 @@ \vskip-\baselineskip\vbox{\hbox{\strut}}\end{varwidth}% \sphinxstopmulticolumn \\ -\hline +\sphinxbottomrule \end{tabulary} \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 e2138ad58fe..2654962f523 100644 --- a/tests/roots/test-latex-table/expects/longtable.tex +++ b/tests/roots/test-latex-table/expects/longtable.tex @@ -1,7 +1,7 @@ \label{\detokenize{longtable:longtable}} \begin{savenotes}\sphinxatlongtablestart\begin{longtable}[c]{|l|l|} -\hline +\sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar header1 @@ -9,12 +9,12 @@ \sphinxAtStartPar header2 \\ -\hline +\sphinxmidrule \endfirsthead \multicolumn{2}{c}% {\makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}}\\ -\hline +\sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar header1 @@ -22,10 +22,10 @@ \sphinxAtStartPar header2 \\ -\hline +\sphinxmidrule \endhead -\hline +\sphinxbottomrule \multicolumn{2}{r}{\makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}}\\ \endfoot @@ -37,19 +37,19 @@ \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{longtable}\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 764ef55f301..08819526218 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,7 @@ \label{\detokenize{longtable:longtable-having-align-option}} \begin{savenotes}\sphinxatlongtablestart\begin{longtable}[r]{|l|l|} -\hline +\sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar header1 @@ -9,12 +9,12 @@ \sphinxAtStartPar header2 \\ -\hline +\sphinxmidrule \endfirsthead \multicolumn{2}{c}% {\makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}}\\ -\hline +\sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar header1 @@ -22,10 +22,10 @@ \sphinxAtStartPar header2 \\ -\hline +\sphinxmidrule \endhead -\hline +\sphinxbottomrule \multicolumn{2}{r}{\makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}}\\ \endfoot @@ -37,19 +37,19 @@ \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{longtable}\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 0ca5506be9a..04f4e29d669 100644 --- a/tests/roots/test-latex-table/expects/longtable_having_caption.tex +++ b/tests/roots/test-latex-table/expects/longtable_having_caption.tex @@ -3,7 +3,7 @@ \begin{savenotes}\sphinxatlongtablestart\begin{longtable}[c]{|l|l|} \sphinxthelongtablecaptionisattop \caption{caption for longtable\strut}\label{\detokenize{longtable:id1}}\\*[\sphinxlongtablecapskipadjust] -\hline +\sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar header1 @@ -11,12 +11,12 @@ \sphinxAtStartPar header2 \\ -\hline +\sphinxmidrule \endfirsthead \multicolumn{2}{c}% {\makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}}\\ -\hline +\sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar header1 @@ -24,10 +24,10 @@ \sphinxAtStartPar header2 \\ -\hline +\sphinxmidrule \endhead -\hline +\sphinxbottomrule \multicolumn{2}{r}{\makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}}\\ \endfoot @@ -39,19 +39,19 @@ \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{longtable}\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 9551a0a3b25..810fd59d18c 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,7 @@ \label{\detokenize{longtable:longtable-having-problematic-cell}} \begin{savenotes}\sphinxatlongtablestart\begin{longtable}[c]{|*{2}{\X{1}{2}|}} -\hline +\sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar header1 @@ -9,12 +9,12 @@ \sphinxAtStartPar header2 \\ -\hline +\sphinxmidrule \endfirsthead \multicolumn{2}{c}% {\makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}}\\ -\hline +\sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar header1 @@ -22,10 +22,10 @@ \sphinxAtStartPar header2 \\ -\hline +\sphinxmidrule \endhead -\hline +\sphinxbottomrule \multicolumn{2}{r}{\makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}}\\ \endfoot @@ -44,19 +44,19 @@ \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{longtable}\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 e54f8acec03..37309a892d1 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,7 @@ \label{\detokenize{longtable:longtable-having-both-stub-columns-and-problematic-cell}} \begin{savenotes}\sphinxatlongtablestart\begin{longtable}[c]{|*{3}{\X{1}{3}|}} -\hline +\sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar header1 @@ -12,12 +12,12 @@ \sphinxAtStartPar header3 \\ -\hline +\sphinxmidrule \endfirsthead \multicolumn{3}{c}% {\makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}}\\ -\hline +\sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar header1 @@ -28,10 +28,10 @@ \sphinxAtStartPar header3 \\ -\hline +\sphinxmidrule \endhead -\hline +\sphinxbottomrule \multicolumn{3}{r}{\makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}}\\ \endfoot @@ -53,7 +53,7 @@ \sphinxAtStartPar notinstub1\sphinxhyphen{}3 \\ -\hline\sphinxstyletheadfamily +\sphinxhline\sphinxstyletheadfamily \sphinxAtStartPar cell2\sphinxhyphen{}1 &\sphinxstyletheadfamily @@ -63,5 +63,5 @@ \sphinxAtStartPar cell2\sphinxhyphen{}3 \\ -\hline +\sphinxbottomrule \end{longtable}\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 a0e7ecfcd07..97ed0413374 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,7 @@ \label{\detokenize{longtable:longtable-having-verbatim}} \begin{savenotes}\sphinxatlongtablestart\begin{longtable}[c]{|*{2}{\X{1}{2}|}} -\hline +\sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar header1 @@ -9,12 +9,12 @@ \sphinxAtStartPar header2 \\ -\hline +\sphinxmidrule \endfirsthead \multicolumn{2}{c}% {\makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}}\\ -\hline +\sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar header1 @@ -22,10 +22,10 @@ \sphinxAtStartPar header2 \\ -\hline +\sphinxmidrule \endhead -\hline +\sphinxbottomrule \multicolumn{2}{r}{\makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}}\\ \endfoot @@ -38,19 +38,19 @@ \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{longtable}\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 cdd0e7a2b32..43de6ffe65a 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,7 @@ \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}}}% +\sphinxtoprule\noalign{\phantomsection\label{\detokenize{longtable:namedlongtable}}\label{\detokenize{longtable:mylongtable}}}% \sphinxstyletheadfamily \sphinxAtStartPar header1 @@ -9,12 +9,12 @@ \sphinxAtStartPar header2 \\ -\hline +\sphinxmidrule \endfirsthead \multicolumn{2}{c}% {\makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}}\\ -\hline +\sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar header1 @@ -22,10 +22,10 @@ \sphinxAtStartPar header2 \\ -\hline +\sphinxmidrule \endhead -\hline +\sphinxbottomrule \multicolumn{2}{r}{\makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}}\\ \endfoot @@ -37,21 +37,21 @@ \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{longtable}\sphinxatlongtableend\end{savenotes} \sphinxAtStartPar 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 ea868ffe4ea..5a193d7c909 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,7 @@ \label{\detokenize{longtable:longtable-having-both-widths-and-problematic-cell}} \begin{savenotes}\sphinxatlongtablestart\begin{longtable}[c]{|\X{30}{100}|\X{70}{100}|} -\hline +\sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar header1 @@ -9,12 +9,12 @@ \sphinxAtStartPar header2 \\ -\hline +\sphinxmidrule \endfirsthead \multicolumn{2}{c}% {\makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}}\\ -\hline +\sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar header1 @@ -22,10 +22,10 @@ \sphinxAtStartPar header2 \\ -\hline +\sphinxmidrule \endhead -\hline +\sphinxbottomrule \multicolumn{2}{r}{\makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}}\\ \endfoot @@ -44,19 +44,19 @@ \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{longtable}\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 426086de5ce..feab1f62e1c 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,7 @@ \label{\detokenize{longtable:longtable-with-tabularcolumn}} \begin{savenotes}\sphinxatlongtablestart\begin{longtable}[c]{|c|c|} -\hline +\sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar header1 @@ -9,12 +9,12 @@ \sphinxAtStartPar header2 \\ -\hline +\sphinxmidrule \endfirsthead \multicolumn{2}{c}% {\makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}}\\ -\hline +\sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar header1 @@ -22,10 +22,10 @@ \sphinxAtStartPar header2 \\ -\hline +\sphinxmidrule \endhead -\hline +\sphinxbottomrule \multicolumn{2}{r}{\makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}}\\ \endfoot @@ -37,19 +37,19 @@ \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{longtable}\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 a06bfb1cfad..01ba7681608 100644 --- a/tests/roots/test-latex-table/expects/simple_table.tex +++ b/tests/roots/test-latex-table/expects/simple_table.tex @@ -3,7 +3,7 @@ \begin{savenotes}\sphinxattablestart \centering \begin{tabulary}{\linewidth}[t]{|T|T|} -\hline +\sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar header1 @@ -11,28 +11,28 @@ \sphinxAtStartPar header2 \\ -\hline +\sphinxmidrule \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 \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 33a5f1d8fdb..e57f4725ffb 100644 --- a/tests/roots/test-latex-table/expects/table_having_caption.tex +++ b/tests/roots/test-latex-table/expects/table_having_caption.tex @@ -7,7 +7,7 @@ \sphinxcaption{caption for table}\label{\detokenize{tabular:id1}} \sphinxaftertopcaption \begin{tabulary}{\linewidth}[t]{|T|T|} -\hline +\sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar header1 @@ -15,28 +15,28 @@ \sphinxAtStartPar header2 \\ -\hline +\sphinxmidrule \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 \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 c5c57e2f758..e11a45f7290 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 @@ -3,7 +3,7 @@ \begin{savenotes}\sphinxattablestart \centering \begin{tabular}[t]{|*{2}{\X{1}{2}|}} -\hline +\sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar header1 @@ -11,7 +11,7 @@ \sphinxAtStartPar header2 \\ -\hline\begin{itemize} +\sphinxmidrule\begin{itemize} \item {} \sphinxAtStartPar item1 @@ -25,21 +25,21 @@ \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 \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 13c48a21322..68a485519d4 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 @@ -3,7 +3,7 @@ \begin{savenotes}\sphinxattablestart \centering \begin{tabular}[t]{|*{3}{\X{1}{3}|}} -\hline +\sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar header1 @@ -14,7 +14,7 @@ \sphinxAtStartPar header3 \\ -\hline\sphinxstyletheadfamily \begin{itemize} +\sphinxmidrule\sphinxstyletheadfamily \begin{itemize} \item {} \sphinxAtStartPar instub1\sphinxhyphen{}1a @@ -31,7 +31,7 @@ \sphinxAtStartPar notinstub1\sphinxhyphen{}3 \\ -\hline\sphinxstyletheadfamily +\sphinxhline\sphinxstyletheadfamily \sphinxAtStartPar cell2\sphinxhyphen{}1 &\sphinxstyletheadfamily @@ -41,7 +41,7 @@ \sphinxAtStartPar cell2\sphinxhyphen{}3 \\ -\hline +\sphinxbottomrule \end{tabular} \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 c1a440558e6..2ea24d37309 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 @@ -3,12 +3,12 @@ \begin{savenotes}\sphinxattablestart \centering \begin{tabulary}{\linewidth}[t]{|T|} -\hline +\sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar header1 \\ -\hline +\sphinxmidrule \sphinxAtStartPar cell1\sphinxhyphen{}1\sphinxhyphen{}par1 @@ -18,7 +18,7 @@ \sphinxAtStartPar cell1\sphinxhyphen{}1\sphinxhyphen{}par3 \\ -\hline +\sphinxbottomrule \end{tabulary} \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 23faac55e19..de90c32b113 100644 --- a/tests/roots/test-latex-table/expects/table_having_verbatim.tex +++ b/tests/roots/test-latex-table/expects/table_having_verbatim.tex @@ -3,7 +3,7 @@ \begin{savenotes}\sphinxattablestart \centering \begin{tabular}[t]{|*{2}{\X{1}{2}|}} -\hline +\sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar header1 @@ -11,7 +11,7 @@ \sphinxAtStartPar header2 \\ -\hline +\sphinxmidrule \begin{sphinxVerbatimintable}[commandchars=\\\{\}] \PYG{n}{hello} \PYG{n}{world} \end{sphinxVerbatimintable} @@ -19,21 +19,21 @@ \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 \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 d01a40576bb..6891df9abde 100644 --- a/tests/roots/test-latex-table/expects/table_having_widths.tex +++ b/tests/roots/test-latex-table/expects/table_having_widths.tex @@ -4,7 +4,7 @@ \centering \phantomsection\label{\detokenize{tabular:namedtabular}}\label{\detokenize{tabular:mytabular}}\nobreak \begin{tabular}[t]{|\X{30}{100}|\X{70}{100}|} -\hline +\sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar header1 @@ -12,28 +12,28 @@ \sphinxAtStartPar header2 \\ -\hline +\sphinxmidrule \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 \sphinxattableend\end{savenotes} 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 ca6b697e5ec..b81c9867b02 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 @@ -3,7 +3,7 @@ \begin{savenotes}\sphinxattablestart \centering \begin{tabular}[t]{|\X{30}{100}|\X{70}{100}|} -\hline +\sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar header1 @@ -11,7 +11,7 @@ \sphinxAtStartPar header2 \\ -\hline\begin{itemize} +\sphinxmidrule\begin{itemize} \item {} \sphinxAtStartPar item1 @@ -25,21 +25,21 @@ \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 \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 596ba4868e3..90e6b9dc19e 100644 --- a/tests/roots/test-latex-table/expects/tabular_having_widths.tex +++ b/tests/roots/test-latex-table/expects/tabular_having_widths.tex @@ -3,7 +3,7 @@ \begin{savenotes}\sphinxattablestart \raggedright \begin{tabular}[t]{|\X{30}{100}|\X{70}{100}|} -\hline +\sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar header1 @@ -11,28 +11,28 @@ \sphinxAtStartPar header2 \\ -\hline +\sphinxmidrule \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 \sphinxattableend\end{savenotes} diff --git a/tests/roots/test-latex-table/expects/tabularcolumn.tex b/tests/roots/test-latex-table/expects/tabularcolumn.tex index c020e0cb4eb..8274ae2382c 100644 --- a/tests/roots/test-latex-table/expects/tabularcolumn.tex +++ b/tests/roots/test-latex-table/expects/tabularcolumn.tex @@ -3,7 +3,7 @@ \begin{savenotes}\sphinxattablestart \centering \begin{tabulary}{\linewidth}[t]{|c|c|} -\hline +\sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar header1 @@ -11,28 +11,28 @@ \sphinxAtStartPar header2 \\ -\hline +\sphinxmidrule \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 \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 0b42fb0cfa3..939a7f67a49 100644 --- a/tests/roots/test-latex-table/expects/tabulary_having_widths.tex +++ b/tests/roots/test-latex-table/expects/tabulary_having_widths.tex @@ -3,7 +3,7 @@ \begin{savenotes}\sphinxattablestart \raggedleft \begin{tabulary}{\linewidth}[t]{|T|T|} -\hline +\sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar header1 @@ -11,28 +11,28 @@ \sphinxAtStartPar header2 \\ -\hline +\sphinxmidrule \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 \sphinxattableend\end{savenotes} diff --git a/tests/test_build_latex.py b/tests/test_build_latex.py index 8f7a2e85acc..4581d637684 100644 --- a/tests/test_build_latex.py +++ b/tests/test_build_latex.py @@ -723,7 +723,7 @@ 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\\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,8 +731,8 @@ 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' + 'footnote in table not in header\n%\n\\end{footnote}\n\\\\\n' + '\\sphinxbottomrule\n\\end{tabulary}\n' '\\par\n\\sphinxattableend\\end{savenotes}\n') in result From dcc70dd43848814cb1cefa8f42a26c56fd2f6757 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20B?= <2589111+jfbu@users.noreply.github.com> Date: Sun, 7 Aug 2022 20:33:30 +0200 Subject: [PATCH 03/16] Fix typo in doc --- doc/usage/configuration.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/usage/configuration.rst b/doc/usage/configuration.rst index 6550c35890d..00c3ba8f67c 100644 --- a/doc/usage/configuration.rst +++ b/doc/usage/configuration.rst @@ -2241,7 +2241,7 @@ These options influence LaTeX output. .. versionadded:: 1.8 -.. confval:: latex_use_booktabs_package +.. confval:: latex_use_booktabs If ``True``, render tables without vertical rules and horizontal rules of varying thickness (with additional space above and below) using the From a3498c6a28ecc5083bf0501043c6e892dd582311 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20B?= <2589111+jfbu@users.noreply.github.com> Date: Sun, 7 Aug 2022 21:42:10 +0200 Subject: [PATCH 04/16] Extend testing to cover usage of booktabs --- sphinx/writers/latex.py | 6 +++--- tests/test_build_latex.py | 17 ++++++++++++++++- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py index 638f65b7624..7b21d6fd6cd 100644 --- a/sphinx/writers/latex.py +++ b/sphinx/writers/latex.py @@ -872,9 +872,9 @@ def visit_table(self, node: Element) -> None: logger.info(__('both tabularcolumns and :widths: option are given. ' ':widths: is ignored.'), location=node) if '|' in self.table.colspec and self.table.booktabs: - logger.info(__('tabularcolumns argument contains | which conflicts with' - 'latex_use_booktabs = True. This may cause layout problems' - 'in PDF output.'), location=node) + logger.info(__('tabularcolumns argument contains | and ' + 'latex_use_booktabs is True. Expect gaps between vertical ' + 'and horizontal rules in this table.'), location=node) self.next_table_colspec = None def depart_table(self, node: Element) -> None: diff --git a/tests/test_build_latex.py b/tests/test_build_latex.py index 4581d637684..cf6b40d9756 100644 --- a/tests/test_build_latex.py +++ b/tests/test_build_latex.py @@ -22,7 +22,8 @@ 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' @@ -90,6 +91,8 @@ 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_use_booktabs = True app.builder.init() LaTeXTranslator.ignore_missing_images = True @@ -1315,6 +1318,18 @@ def get_expected(name): assert actual == expected +@pytest.mark.sphinx('latex', testroot='latex-table', + confoverrides={'latex_use_booktabs': True}) +def test_latex_table_with_booktabs(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'\begin{tabulary}{\linewidth}[t]{TTTTT}' 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): From 993e970ad5b7f88d426d8079387527636bfe0d83 Mon Sep 17 00:00:00 2001 From: Stefan Wiehler Date: Mon, 26 Aug 2019 12:00:43 +0200 Subject: [PATCH 05/16] Cherry-pick: Add support for zebra-striped tables to LaTeX builder Render tables with alternating background colors for even and odd rows (so called "zebra striping"). --- doc/latex.rst | 12 ++++++++++++ doc/usage/configuration.rst | 9 +++++++++ sphinx/builders/latex/__init__.py | 1 + sphinx/texinputs/sphinx.sty | 4 +++- sphinx/writers/latex.py | 8 ++++++++ 5 files changed, 33 insertions(+), 1 deletion(-) diff --git a/doc/latex.rst b/doc/latex.rst index c46ab6e29b6..17698fcce85 100644 --- a/doc/latex.rst +++ b/doc/latex.rst @@ -841,6 +841,18 @@ Do not use quotes to enclose values, whether numerical or strings. Default: ``{rgb}{0.216,0.439,0.388}`` +``RowEvenColor`` + default ``{rgb}{0.85,0.85,0.85}``. Background color for even rows in + tables, if option :confval:`latex_zebra_stripes` is set to ``True``. + + .. versionadded:: 2.1 + +``RowOddColor`` + default ``{rgb}{1,1,1}``. Background color for odd rows in tables, if + option :confval:`latex_zebra_stripes` is set to ``True``. + + .. versionadded:: 2.1 + ``VerbatimColor`` The background colour for :rst:dir:`code-block`\ s. diff --git a/doc/usage/configuration.rst b/doc/usage/configuration.rst index 00c3ba8f67c..898d2fa4825 100644 --- a/doc/usage/configuration.rst +++ b/doc/usage/configuration.rst @@ -2251,6 +2251,15 @@ These options influence LaTeX output. .. versionadded:: 5.2.0 +.. confval:: latex_zebra_stripes + + If ``True``, render tables with alternating background colors for even and + odd rows (so called "zebra striping"). See :ref:`latexsphinxsetup` + ``RowEvenColor`` and ``RowOddColor`` for changing the default white-grey + color scheme. + + .. versionadded:: 2.1 + .. confval:: latex_elements .. versionadded:: 0.5 diff --git a/sphinx/builders/latex/__init__.py b/sphinx/builders/latex/__init__.py index f02e69483e6..a2478ad9684 100644 --- a/sphinx/builders/latex/__init__.py +++ b/sphinx/builders/latex/__init__.py @@ -519,6 +519,7 @@ def setup(app: Sphinx) -> Dict[str, Any]: app.add_config_value('latex_use_latex_multicolumn', False, None) app.add_config_value('latex_use_xindy', default_latex_use_xindy, None, [bool]) app.add_config_value('latex_use_booktabs', False, None) + app.add_config_value('latex_zebra_stripes', False, None) app.add_config_value('latex_toplevel_sectioning', None, None, ENUM(None, 'part', 'chapter', 'section')) app.add_config_value('latex_domain_indices', True, None, [list]) diff --git a/sphinx/texinputs/sphinx.sty b/sphinx/texinputs/sphinx.sty index dabe1d37b75..0077543d999 100644 --- a/sphinx/texinputs/sphinx.sty +++ b/sphinx/texinputs/sphinx.sty @@ -43,7 +43,7 @@ % checked at 5.0.0) \fcolorbox is used for admonitions (sphinxheavybox) % and appears also in Pygmentize output mark-up. \IfFileExists{xcolor.sty}{ - \RequirePackage{xcolor} + \RequirePackage[table]{xcolor} }{ \RequirePackage{color} } @@ -153,6 +153,8 @@ \sphinxDeclareColorOption{OuterLinkColor}{{rgb}{0.216,0.439,0.388}} \sphinxDeclareColorOption{VerbatimColor}{{rgb}{1,1,1}} \sphinxDeclareColorOption{VerbatimBorderColor}{{rgb}{0,0,0}} +\sphinxDeclareColorOption{RowEvenColor}{{rgb}{0.85,0.85,0.85}} +\sphinxDeclareColorOption{RowOddColor}{{rgb}{1,1,1}} % now the colours defined with "sphinx" prefix in their names \newcommand*{\sphinxDeclareSphinxColorOption}[2]{% % set the initial default diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py index 7b21d6fd6cd..8424ac5ce4c 100644 --- a/sphinx/writers/latex.py +++ b/sphinx/writers/latex.py @@ -926,6 +926,14 @@ def visit_row(self, node: Element) -> None: self.table.col = 0 _colsep = '' if self.table.booktabs else '|' + if self.builder.config.latex_zebra_stripes and not isinstance(node.parent, nodes.thead): + if self.table.row % 2 == 0: + self.body.append( + '\\rowcolor{RowEvenColor}[\\dimexpr\\tabcolsep+0.1pt\\relax]') + else: + self.body.append( + '\\rowcolor{RowOddColor}[\\dimexpr\\tabcolsep+0.1pt\\relax]') + # fill columns if the row starts with the bottom of multirow cell while True: cell = self.table.cell(self.table.row, self.table.col) From c99f1504747de4e7f2b62398c0caa86bffd14441 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20B?= <2589111+jfbu@users.noreply.github.com> Date: Mon, 8 Aug 2022 19:09:29 +0200 Subject: [PATCH 06/16] Fix flake8 reported errors in previous cherry-picked commit --- sphinx/writers/latex.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py index 8424ac5ce4c..cd565e362db 100644 --- a/sphinx/writers/latex.py +++ b/sphinx/writers/latex.py @@ -926,13 +926,18 @@ def visit_row(self, node: Element) -> None: self.table.col = 0 _colsep = '' if self.table.booktabs else '|' - if self.builder.config.latex_zebra_stripes and not isinstance(node.parent, nodes.thead): + if ( + self.builder.config.latex_zebra_stripes and + not isinstance(node.parent, nodes.thead) + ): if self.table.row % 2 == 0: self.body.append( - '\\rowcolor{RowEvenColor}[\\dimexpr\\tabcolsep+0.1pt\\relax]') + '\\rowcolor{RowEvenColor}[\\dimexpr\\tabcolsep+0.1pt\\relax]' + ) else: self.body.append( - '\\rowcolor{RowOddColor}[\\dimexpr\\tabcolsep+0.1pt\\relax]') + '\\rowcolor{RowOddColor}[\\dimexpr\\tabcolsep+0.1pt\\relax]' + ) # fill columns if the row starts with the bottom of multirow cell while True: From bb98869660ed51d911b06fbe9318fd7644fa623d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20B?= <2589111+jfbu@users.noreply.github.com> Date: Mon, 8 Aug 2022 19:19:53 +0200 Subject: [PATCH 07/16] latex_table_style configuration, support booktabs, colorrows, borderless This is a combination of 28 commits... - 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). - Refactor and trim doc about LaTeX tables... to make room for more, later - Enlarge allowed syntax for colour assignments via 'sphinxsetup' - latex_table_style new configuration value and coloured rows For the user interface 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! - Update LaTeX table tests and templates Modify longtable templates to put LaTeX macros each on its line Table body insertion without removing previous EOL may give output which contain some empty lines but longtable defines \par token to be same as \empty. - Work-around an incompatibility of \cline with row colours, improve docs - Reverse priority of classes to allow overruling booktabs by standard after parsing source but before letting LaTeX writer act - Closes #8220 Commit https://github.com/sphinx-doc/sphinx/commit/bb859c669679baebd8cc8d10c99382478c0d1647 already improved a bit, this finishes it (as :rst:dir:`rst-class` was actually not linking to anywhere). - Update CHANGES for PR #10759 - Let booktabs style defaults to *not* using \cmidrule. They actually don't make much sense there, as all \hline's are removed. - Enhance customizability at LaTeX code level (via code executed prior to table rendering, e.g. from a container class environment). - Patch booktabs \cmidrule, as if it used via \sphinxcline, there is a vertical space problem in case of there are two in the same row due to booktabs \futurelet not knowing \sphinxcline - 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 - Needed to also detect if a '|' is in tabularcolumns, tests updated - Fix refactoring in this series which broke table.colsep update - Add test which would have shown regression regarding table.colsep - Fix another regression regarding \sphinxcline + booktabs Can not add test for that, because it shows only after PDF build. - Final testing and code comments update --- CHANGES | 2 + doc/conf.py | 3 +- doc/extdev/deprecated.rst | 4 +- doc/latex.rst | 71 ++- doc/usage/configuration.rst | 114 +++- doc/usage/restructuredtext/basics.rst | 17 +- doc/usage/restructuredtext/directives.rst | 147 ++--- doc/usage/theming.rst | 2 +- sphinx/builders/latex/__init__.py | 7 +- sphinx/templates/latex/latex.tex_t | 8 +- sphinx/templates/latex/longtable.tex_t | 38 +- sphinx/templates/latex/tabular.tex_t | 27 +- sphinx/templates/latex/tabulary.tex_t | 27 +- sphinx/texinputs/sphinx.sty | 115 ++-- sphinx/texinputs/sphinxlatextables.sty | 586 ++++++++++++++++-- sphinx/writers/latex.py | 55 +- tests/roots/test-latex-table/complex.rst | 23 + .../expects/complex_spanning_cell.tex | 6 +- .../test-latex-table/expects/gridtable.tex | 5 +- .../expects/gridtable_with_tabularcolumn.tex | 73 +++ .../test-latex-table/expects/longtable.tex | 12 +- .../expects/longtable_having_align.tex | 11 +- .../expects/longtable_having_caption.tex | 11 +- .../longtable_having_problematic_cell.tex | 11 +- ...ving_stub_columns_and_problematic_cell.tex | 11 +- .../expects/longtable_having_verbatim.tex | 11 +- .../expects/longtable_having_widths.tex | 14 +- ...ble_having_widths_and_problematic_cell.tex | 11 +- .../expects/longtable_with_tabularcolumn.tex | 12 +- .../test-latex-table/expects/simple_table.tex | 4 +- .../expects/table_having_caption.tex | 4 +- .../expects/table_having_problematic_cell.tex | 6 +- ...ving_stub_columns_and_problematic_cell.tex | 6 +- ...ving_threeparagraphs_cell_in_first_col.tex | 4 +- .../expects/table_having_verbatim.tex | 4 +- .../expects/table_having_widths.tex | 8 +- ...ble_having_widths_and_problematic_cell.tex | 6 +- .../expects/tabular_having_widths.tex | 4 +- .../expects/tabularcolumn.tex | 7 +- .../expects/tabulary_having_widths.tex | 4 +- tests/roots/test-latex-table/longtable.rst | 2 +- tests/roots/test-latex-table/tabular.rst | 3 +- tests/test_build_latex.py | 29 +- 43 files changed, 1215 insertions(+), 310 deletions(-) create mode 100644 tests/roots/test-latex-table/expects/gridtable_with_tabularcolumn.tex diff --git a/CHANGES b/CHANGES index 6bffea6940c..5ee400a751d 100644 --- a/CHANGES +++ b/CHANGES @@ -15,6 +15,8 @@ Features added - #10286: C++, support requires clauses not just between the template parameter lists and the declaration. +- #10759: LaTeX: add :confval:`latex_table_style` and support the + ``'booktabs'``, ``'borderless'``, and ``'colorrows'`` styles. Bugs fixed ---------- diff --git a/doc/conf.py b/doc/conf.py index a721508debf..e146bbd0cae 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -77,7 +77,7 @@ {\begin{sphinxtheindex}\end{sphinxtheindex}} ''', 'sphinxsetup': """% -VerbatimColor={RGB}{242,242,242},% +VerbatimColor=black!5,% tests 5.2.0 extended syntax VerbatimBorderColor={RGB}{32,32,32},% pre_border-radius=3pt,% pre_box-decoration-break=slice,% @@ -85,6 +85,7 @@ } 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 18b0e6d04e3..ef34f2b87d3 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 * - ``sphinx.util.path_stabilize`` diff --git a/doc/latex.rst b/doc/latex.rst index 17698fcce85..56a9a7807b4 100644 --- a/doc/latex.rst +++ b/doc/latex.rst @@ -819,16 +819,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.2.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``. @@ -841,18 +856,6 @@ Do not use quotes to enclose values, whether numerical or strings. Default: ``{rgb}{0.216,0.439,0.388}`` -``RowEvenColor`` - default ``{rgb}{0.85,0.85,0.85}``. Background color for even rows in - tables, if option :confval:`latex_zebra_stripes` is set to ``True``. - - .. versionadded:: 2.1 - -``RowOddColor`` - default ``{rgb}{1,1,1}``. Background color for odd rows in tables, if - option :confval:`latex_zebra_stripes` is set to ``True``. - - .. versionadded:: 2.1 - ``VerbatimColor`` The background colour for :rst:dir:`code-block`\ s. @@ -875,6 +878,40 @@ Do not use quotes to enclose values, whether numerical or strings. Starting with this colour, and for all others following, the names declared to "color" or "xcolor" are prefixed with "sphinx". +``TableRowColorHeader`` + Background colour for (all) the header rows. This (as the next + ``Table...`` colours) applies conditionnally + on either ``'colorrows'`` being contained in :confval:`latex_table_style` + or on the table receiving ``colorrows`` as class. + + Default: ``{gray}{0.86}`` + + There is also ``TableMergeColorHeader`` which as long as it is not + defined (either globally via ``'sphinxsetup'`` interface or locally + via :dudir:`raw` directive and ``\sphinxsetup`` LaTeX macro) will keep + in sync with ``TableRowColorHeader``. + + .. versionadded:: 5.2.0 + +``TableRowColorOdd`` + Background colour for odd rows in tables (the row count starts at ``1`` + at the first non-header row). + + Default: ``{gray}{0.92}`` + + There is also ``TableMergeColorOdd``. + + .. versionadded:: 5.2.0 + +``TableRowColorEven`` + Background colour for even rows in tables. + + Default ``{gray}{0.98}`` + + There is also ``TableMergeColorEven``. + + .. versionadded:: 5.2.0 + ``verbatimsep`` The separation between code lines and the frame. diff --git a/doc/usage/configuration.rst b/doc/usage/configuration.rst index 898d2fa4825..38234873c15 100644 --- a/doc/usage/configuration.rst +++ b/doc/usage/configuration.rst @@ -2210,6 +2210,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 body rows are rendered with alternating background + colours, see the :ref:`latexsphinxsetup` keys ``TableRowColorOdd`` and + ``TableRowColorEven`` for configuration. And ``TableRowColorHeader`` + for the header rows. + + 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{}}``, + 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_). + + When using both ``'booktabs'`` and ``'colorrows'`` there is a small + white gap between the bottom row and the bottom rule, and between the + first body row and the (mid or top) rule above it. It is possible to + extend the background colouring to touch the rules, via some extra LaTeX + coding. This may be added to Sphinx in case of feature request, but + this whitespace is considered currently a quality rather than a defect. + + .. _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 @@ -2241,25 +2336,6 @@ These options influence LaTeX output. .. versionadded:: 1.8 -.. confval:: latex_use_booktabs - - If ``True``, render tables without vertical rules and horizontal rules of - varying thickness (with additional space above and below) using the - booktabs_ package. - - .. _booktabs: https://ctan.org/pkg/booktabs - - .. versionadded:: 5.2.0 - -.. confval:: latex_zebra_stripes - - If ``True``, render tables with alternating background colors for even and - odd rows (so called "zebra striping"). See :ref:`latexsphinxsetup` - ``RowEvenColor`` and ``RowOddColor`` for changing the default white-grey - color scheme. - - .. versionadded:: 2.1 - .. confval:: latex_elements .. versionadded:: 0.5 diff --git a/doc/usage/restructuredtext/basics.rst b/doc/usage/restructuredtext/basics.rst index c846dc145f6..824b59ee2c2 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 4029b04e67b..44e4b5ffead 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 ` directive instead and add an + appropriate style. .. rst:directive:: hlist @@ -1045,114 +1046,78 @@ Use :ref:`reStructuredText 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 ` for other tables. Math ---- diff --git a/doc/usage/theming.rst b/doc/usage/theming.rst index 0e4b4a64dde..c33c7d4770d 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/builders/latex/__init__.py b/sphinx/builders/latex/__init__.py index a2478ad9684..da2a5dfc2eb 100644 --- a/sphinx/builders/latex/__init__.py +++ b/sphinx/builders/latex/__init__.py @@ -170,7 +170,9 @@ def init_context(self) -> None: self.context.update(self.config.latex_elements) self.context['release'] = self.config.release self.context['use_xindy'] = self.config.latex_use_xindy - self.context['use_booktabs'] = self.config.latex_use_booktabs + 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 @@ -518,8 +520,6 @@ def setup(app: Sphinx) -> Dict[str, Any]: app.add_config_value('latex_appendices', [], None) app.add_config_value('latex_use_latex_multicolumn', False, None) app.add_config_value('latex_use_xindy', default_latex_use_xindy, None, [bool]) - app.add_config_value('latex_use_booktabs', False, None) - app.add_config_value('latex_zebra_stripes', False, None) app.add_config_value('latex_toplevel_sectioning', None, None, ENUM(None, 'part', 'chapter', 'section')) app.add_config_value('latex_domain_indices', True, None, [list]) @@ -527,6 +527,7 @@ def setup(app: Sphinx) -> Dict[str, Any]: app.add_config_value('latex_show_pagerefs', False, None) app.add_config_value('latex_elements', {}, None) app.add_config_value('latex_additional_files', [], None) + app.add_config_value('latex_table_style', [], None, [list]) app.add_config_value('latex_theme', 'manual', None, [str]) app.add_config_value('latex_theme_options', {}, None) app.add_config_value('latex_theme_path', [], None, [list]) diff --git a/sphinx/templates/latex/latex.tex_t b/sphinx/templates/latex/latex.tex_t index 1cebac93418..deb030504db 100644 --- a/sphinx/templates/latex/latex.tex_t +++ b/sphinx/templates/latex/latex.tex_t @@ -26,9 +26,15 @@ \makeatletter\@ifclassloaded{memoir} {\ifdefined\memhyperindexfalse\memhyperindexfalse\fi}{}\makeatother <% endif %> -<% if use_booktabs -%> +<% if booktabs -%> \PassOptionsToPackage{booktabs}{sphinx} <% endif -%> +<% if borderless -%> +\PassOptionsToPackage{borderless}{sphinx} +<% endif -%> +<% if colorrows -%> +\PassOptionsToPackage{colorrows}{sphinx} +<% endif -%> <%= passoptionstopackages %> \PassOptionsToPackage{warn}{textcomp} <%= inputenc %> diff --git a/sphinx/templates/latex/longtable.tex_t b/sphinx/templates/latex/longtable.tex_t index a96c2003775..9f722a71387 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,12 +34,10 @@ <%- if table.caption -%> \sphinxthelongtablecaptionisattop \caption{<%= ''.join(table.caption) %>\strut}<%= labels %>\\*[\sphinxlongtablecapskipadjust] -\sphinxtoprule <% elif labels -%> -\sphinxtoprule\noalign{\phantomsection<%= labels %>}% -<% else -%> -\sphinxtoprule +\noalign{\phantomsection<%= labels %>}% <% endif -%> +\sphinxtoprule <%= ''.join(table.header) -%> <%- if table.header -%> \sphinxmidrule @@ -36,6 +58,10 @@ \endfoot \endlastfoot +\sphinxtableatstartofbodyhook <%= ''.join(table.body) -%> \sphinxbottomrule -\end{longtable}\sphinxatlongtableend\end{savenotes} +\end{longtable} +\sphinxtableafterendhook +\sphinxatlongtableend +\end{savenotes} diff --git a/sphinx/templates/latex/tabular.tex_t b/sphinx/templates/latex/tabular.tex_t index d1a0b97f488..0a9310a5ed2 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 @@ -23,9 +45,10 @@ <%= ''.join(table.header) -%> <%- if table.header -%> \sphinxmidrule -<%- endif -%> +<% 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 f71214f5491..6ebcec6d264 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 @@ -23,9 +45,10 @@ <%= ''.join(table.header) -%> <%- if table.header -%> \sphinxmidrule -<%- endif -%> +<% 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 0077543d999..be8965e2561 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/10 v5.2.0 LaTeX package (Sphinx markup)] % provides \ltx@ifundefined % (many packages load ltxcmds: graphicx does for pdftex and lualatex but @@ -43,15 +43,40 @@ % checked at 5.0.0) \fcolorbox is used for admonitions (sphinxheavybox) % and appears also in Pygmentize output mark-up. \IfFileExists{xcolor.sty}{ - \RequirePackage[table]{xcolor} + \RequirePackage{xcolor} }{ \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.2.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 +\def\spx@colorlet#1\relax{% + \PackageWarning{sphinx}{% +Sorry, defining \spx@definedcolor\space to be #1\MessageBreak +via \protect\colorlet syntax requires package xcolor.sty.\MessageBreak +The color \spx@definedcolor\space will be set to {rgb}{0,0,1}\MessageBreak +\protect\definecolor}% + \expandafter\definecolor\spx@definedcolor{rgb}{0,0,1}}% + }% end of xcolor not found branch + % Handle options via "kvoptions" (later loaded by hyperref anyhow) \RequirePackage{kvoptions} @@ -59,6 +84,9 @@ % Optional usage of booktabs package for tables \DeclareBoolOption[false]{booktabs} +\DeclareBoolOption[false]{borderless} +% Coloured table rows +\DeclareBoolOption[false]{colorrows} % Sphinx legacy text layout: 1in margins on all four sides \ifx\@jsc@uplatextrue\@undefined \DeclareStringOption[1in]{hmargin} @@ -146,21 +174,41 @@ % first, some colours with no prefix, for backwards compatibility \newcommand*{\sphinxDeclareColorOption}[2]{% \definecolor{#1}#2% - \define@key{sphinx}{#1}{\definecolor{#1}##1}% + \define@key{sphinx}{#1}{\spx@defineorletcolor{#1}##1\relax}% }% +% only \definecolor syntax for the defaults here! \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}} -\sphinxDeclareColorOption{RowEvenColor}{{rgb}{0.85,0.85,0.85}} -\sphinxDeclareColorOption{RowOddColor}{{rgb}{1,1,1}} % now the colours defined with "sphinx" prefix in their names \newcommand*{\sphinxDeclareSphinxColorOption}[2]{% % set the initial default \definecolor{sphinx#1}#2% % set the key handler. The "value" ##1 must be acceptable by \definecolor. - \define@key{sphinx}{#1}{\definecolor{sphinx#1}##1}% + \define@key{sphinx}{#1}{\spx@defineorletcolor{sphinx#1}##1\relax}% +}% +% only \definecolor syntax for the defaults here! +% table row colors +\sphinxDeclareSphinxColorOption{TableRowColorHeader}{{gray}{0.86}} +\sphinxDeclareSphinxColorOption{TableRowColorOdd}{{gray}{0.92}} +\sphinxDeclareSphinxColorOption{TableRowColorEven}{{gray}{0.98}} +% if not defined "MergeColor" will keep in sync with "RowColor" +\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}} @@ -296,21 +344,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 @@ -416,17 +464,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{% @@ -576,9 +624,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 @@ -599,6 +650,8 @@ \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 @@ -729,36 +782,6 @@ %% TABLES % \input{sphinxlatextables.sty} -% Those two are produced by the latex writer -\def\sphinxhline{\hline} -\def\sphinxcline{\cline} -% Those three are inserted by the table templates -\def\sphinxtoprule{\hline} -\def\sphinxmidrule{\hline} -\def\sphinxbottomrule{\hline} -% \def\sphinxarrayrulewidth{\arrayrulewidth}% already done -\ifspx@opt@booktabs - \RequirePackage{booktabs} - \def\sphinxarrayrulewidth{\z@}% (attention! Do NOT assign to \sphinxarrayrulewidth - % this would modify \z@ and break all of LaTeX...) - \let\sphinxhline\@empty - \def\sphinxcline{\cmidrule(lr)}% - \def\sphinxtoprule{\toprule}% - \def\sphinxmidrule{\midrule}% - \def\sphinxbottomrule{\bottomrule}% -\fi -\AtBeginDocument -{\@ifpackageloaded{booktabs}% - {\ifspx@opt@booktabs\else - \AtEndDocument{% -\PackageWarningNoLine{sphinx}{% - Package booktabs is detected but configuration option\MessageBreak - latex_use_booktabs is False. Tables will not use booktabs styling}% -}% - \fi}% - {}% -}% - %% NUMBERING OF FIGURES, TABLES, AND LITERAL BLOCKS diff --git a/sphinx/texinputs/sphinxlatextables.sty b/sphinx/texinputs/sphinxlatextables.sty index bc4cdc44583..76d29d1c719 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}[2022/08/07 tables]% +\ProvidesFile{sphinxlatextables.sty}[2022/08/10 tables]% % Provides support for this output mark-up from Sphinx latex writer % and table templates: @@ -25,12 +25,28 @@ % - \sphinxtablestrut % - \sphinxthecaptionisattop % - \sphinxthelongtablecaptionisattop +% - \sphinxhline +% - \sphinxcline +% - \sphinxtoprule +% - \sphinxmidrule +% - \sphinxbottomrule +% - \sphinxtableatstartofbodyhook +% - \sphinxtableafterendhook +% - \sphinxthistablewithglobalstyle +% - \sphinxthistablewithbooktabsstyle +% - \sphinxthistablewithborderlessstyle +% - \sphinxthistablewithstandardstyle +% - \sphinxthistablewithcolorrowsstyle +% - \sphinxthistablewithnocolorrowsstyle +% - \sphinxthistablewithvlinesstyle +% - \sphinxthistablewithnovlinesstyle % % Executes \RequirePackage for: % % - tabulary % - longtable % - varwidth +% - colortbl % % Extends tabulary and longtable via patches and custom macros to support % merged cells possibly containing code-blocks in complex tables @@ -42,11 +58,14 @@ % sphinxpackagemulticell.sty % X or S (Sphinx) may have meanings if some table package is loaded hence % \X was chosen to avoid possibility of conflict -\def\sphinxarrayrulewidth{\arrayrulewidth}% will be set to \z@ if booktabs option \newcolumntype{\X}[2]{p{\dimexpr - (\linewidth-\sphinxarrayrulewidth)*#1/#2-\tw@\tabcolsep-\sphinxarrayrulewidth\relax}} + (\linewidth-\spx@arrayrulewidth)*#1/#2-\tw@\tabcolsep-\spx@arrayrulewidth\relax}} \newcolumntype{\Y}[1]{p{\dimexpr - #1\dimexpr\linewidth-\sphinxarrayrulewidth\relax-\tw@\tabcolsep-\sphinxarrayrulewidth\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.2.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 @@ -168,6 +187,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.2.0) + %%%%%%%%%%%%%%%%%%%%% % --- MULTICOLUMN --- % standard LaTeX's \multicolumn @@ -209,9 +233,15 @@ % \arrayrulewidth space for each column separation in its estimate of available % width). % -% EDIT: Sphinx 5.2.0 uses \sphinxarrayrulewidth which is \z@ if booktabs -% option has been used. Do not mix booktabs option with usage of | in -% tabularcolumns directive. +% Update at 5.2.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 @@ -234,7 +264,15 @@ % 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.2.0 adds a check for multirow as single-row multi-column will allow a row +% colour but multi-row multi-column should not. +\def\sphinxstartmulticolumn#1#2{% + \ifx\sphinxmultirow#2% #2 is either \sphinxmultirow or \begin + \def\spx@table@hackCT@inmergedcell{\spx@table@hackCT@nocolor}% + \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 @@ -290,34 +328,23 @@ \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-\sphinxarrayrulewidth)/\sphinx@tempa - -\tw@\tabcolsep-\sphinxarrayrulewidth\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+\sphinxarrayrulewidth}% - % hack the \vline and the colortbl macros - \sphinx@hack@vline\sphinx@hack@CT&\relax + {\the\dimexpr\sphinx@multiwidth+\sphinx@tempb+\tw@\tabcolsep+\spx@arrayrulewidth}% + % simulate the \vline added width + \spx@table@fakevline + % prevent column colours to interfere with our multi-column but allow row + % colour; sadly we can't infere a \cellcolor and propagate it to the + % merged cell as it has not be seen yet at this stage which is preparatory + % to the varwidth environment execution... and the background colour panels + % are injected by colortbl now when the & is met... + \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: -% (5.2.0 sets \sphinxarrayrulewidth to expand to \z@ if booktabs option has been -% made use of, the \arrayrulewidth\z@ serves then nothing but shoud not hurt). -\def\sphinx@hack@vline{\ifnum\currentgrouptype=6\relax - \kern\sphinxarrayrulewidth\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 @@ -327,11 +354,11 @@ \else \xdef\sphinx@multiwidth{\the\dimexpr\sphinx@multiwidth+ (\ifx\TY@final\@undefined\linewidth\else - \sphinx@TY@tablewidth\fi-\sphinxarrayrulewidth)/\sphinx@tempa - -\tw@\tabcolsep-\sphinxarrayrulewidth\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 + \aftergroup\spx@table@hackCT@inmergedcell }% \newcommand*\sphinxcolwidth[2]{% % this dimension will always be used for varwidth, and serves as maximum @@ -352,8 +379,8 @@ \linewidth \else % l, c, r columns. Do our best. - \dimexpr(\linewidth-\sphinxarrayrulewidth)/#2- - \tw@\tabcolsep-\sphinxarrayrulewidth\relax + \dimexpr(\linewidth-\spx@arrayrulewidth)/#2- + \tw@\tabcolsep-\spx@arrayrulewidth\relax \fi \else % in tabulary \ifx\equation$%$% first pass @@ -364,8 +391,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-\sphinxarrayrulewidth)/#2- - \tw@\tabcolsep-\sphinxarrayrulewidth\relax + \dimexpr(\sphinx@TY@tablewidth-\spx@arrayrulewidth)/#2- + \tw@\tabcolsep-\spx@arrayrulewidth\relax \fi \fi \fi @@ -375,7 +402,140 @@ % \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 - -\sphinxarrayrulewidth)*#2-\tw@\tabcolsep-\sphinxarrayrulewidth\relax}% + -\spx@arrayrulewidth)*#2-\tw@\tabcolsep-\spx@arrayrulewidth\relax}% + +% \spx@table@fakevline +% 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 +% induces an empty space of the width corresponding to a \vline. Then it +% 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) +\def\spx@table@fakevline{\ifnum\currentgrouptype=6\relax + \kern\spx@arrayrulewidth\arrayrulewidth\z@\else\aftergroup\spx@table@fakevline\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.2.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.2.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.2.0 this mechanism +% is relaxed a bit to allow row colour for a single-row merged cell. +% +% \spx@table@hackCT@inmergedcell +% \spx@table@hackCT@nocolor +% \spx@table@hackCT@norowcolor +% +% \let\spx@original@CT@setup\CT@setup is done after the loading of colortbl +% package +% +% inmergedcell +\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 added at 5.2.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 + \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 +} +% +% sphinxcolormix (commented-out) +% this works but then I found out about \blendcolors in xcolor doc, so I provided +% rather \sphinxcolorblend, the code is kept in case it can be reused in future +% \@ifpackageloaded{xcolor}{% +% \def\spx@table@hackCT@colormix{% +% \ifnum\currentgrouptype=6\relax +% \ifx\CT@column@color\relax +% \else +% \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 +% \else +% \colorlet{spxcolumncolor}{.}% +% \spx@saved@CT@row@color +% \colorlet{spxrowcolor}{.}% +% \color{spxcolumncolor!\spx@colormixparam!spxrowcolor}% +% \fi +% }% patched \CT@row@color +% \fi +% \fi +% \else +% \aftergroup\spx@table@hackCT@colormix +% \fi +% }% +% }{\let\spx@table@hackCT@colormix\@empty}% no-op if no xcolor as \colorlet needed +% \def\sphinxcolormix#1{\gdef\spx@colormixparam{#1}\spx@table@hackCT@colormix} +% +% \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 +} +% 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}% + {}% + {\let\spx@table@hackCT@colorblend\@empty}% no-op if no xcolor +\def\sphinxcolorblend#1{\gdef\spx@colorblendparam{{#1}}\spx@table@hackCT@colorblend} + %%%%%%%%%%%%%%%%%% % --- MULTIROW --- @@ -397,9 +557,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.2.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...) @@ -417,6 +590,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 verticale adjustement... +% % 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 @@ -482,7 +664,331 @@ \@width\z@ \endgroup % we need this to avoid colour panels hiding bottom parts of multirow text - \sphinx@hack@CT + % whether they originate in \columncolor or \rowcolor (or even \cellcolor + % even though it can be only in top cell, but we could hijack it). + \spx@table@hackCT@nocolor +}% + +%%%%%%%%%%%%%%%%%% +% --- STYLING --- +% + +% the initialization macros executed before the table environments +% their scope is limited by a wrapper "savenotes" environment +% +% 0) color 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 +% +% 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). +% +\let\sphinxtabletoprulehook \@empty +\let\sphinxtableatstartofbodyhook\@empty +\let\sphinxtableafterendhook \@empty +% +% 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 +% +% - 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} + +% set the colours according to row parity; a priori #1 is \rownum, but +% the macro can be used in user 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 +} + +% this will start the alternating colours, by letting \everycr increment the +% \rownum counter and reset the colours according to \sphinxSwitchCaseRowColor\rownum +\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 inihibit colours in the header rows + }% end of noalign contents +} + +\def\sphinxrowcolorON{% the colours here must have been defined, and this is done + % via \sphinxtabletoprulehook default action + \gdef\CT@row@color{\ifspx@table@inmergedcell + \CT@color{sphinxTableMergeColor}% + \else + \CT@color{sphinxTableRowColor}% + \fi + \@tempdimb\dimexpr\col@sep+\sphinxcolorpanelextraoverhang\relax + \@tempdimc\@tempdimb + }% }% +\def\sphinxrowcolorOFF{\global\let\CT@row@color\relax}% +\def\sphinxnorowcolor{\spx@table@hackCT@norowcolor}% inhibits row colour in one cell only +\def\spx@table@resetcolortbl{% can be executed from inside or outside a table + \global\let\CT@row@color\relax +% we should probably be more cautious and not hard-code here the colortbl set-up + \global\CT@everycr{\noalign{\global\let\CT@row@color\relax}\the\everycr}% +} + +\def\spx@table@@toprulehook{% + \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 + }% +}% + +% this macro is needed in color tables as each \cline or \cmidrule (booktabs) +% consumes one \cr, offsetting the rownum parity. +\def\spx@table@@decrementrownum{\noalign{\global\advance\rownum\m@ne}} +\let\sphinxtabledecrementrownum\@empty + +% At last the style macros + +% \spx@toprule is what the styles define; the colorrows class will prepend +% some code in \sphinxtabletoprulehook +\def\sphinxtoprule{\spx@toprule\sphinxtabletoprulehook} + +% 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}% + % 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 ultimate customization, e.g. via a container class, of the +% widths (aka thickness) associated with the booktabs rule (advanced users may +% even employ \specialrule here to control vertical spacing). +\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 +% also include the \sphinxtabledecrementrownum token like e.g. this +% \def\sphinxbooktabscmidrule{\sphinxtabledecrementrownum\cmidrule} +% and it must be first due to internals of the \cmidrule usage of \futurelet, +% if the table uses row colours. + +\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 \@gobble + \def\spx@toprule {\sphinxbooktabstoprule}% + \def\sphinxmidrule {\sphinxbooktabsmidrule}% + \def\sphinxbottomrule{\sphinxbooktabsbottomrule}% + \def\spx@arrayrulewidth{\z@}% +} +\AtBeginDocument{\@ifpackageloaded{booktabs}% + {}% + {\def\sphinxthistablewithbooktabsstyle{% + \PackageWarning{sphinx}{% +Please add \string\usepackage{booktabs} to the preamble\MessageBreak +to allow local use of booktabs table style}% + \textcolor{red}{\bfseries ADD LOADING OF booktabs TO THE 'preamble' KEY OF + latex\textunderscore elements}\par + \sphinxthistablewithstandardstyle + }}% +}% + +% borderless style +\def\sphinxthistablewithborderlessstyle{% + \let\sphinxhline \@empty + \let\sphinxcline \@gobble + \let\spx@toprule \@empty + \let\sphinxmidrule \@empty + \let\sphinxbottomrule \@empty + \def\spx@arrayrulewidth{\z@}% +}% + +% colorrows style +% +% this is defined to auto-silence itself (in the surrounding scope-limiting +% environment) after one execution +\def\sphinxthistablewithcolorrowsstyle{% + \let\sphinxthistablewithcolorrowsstyle\@empty +% + \let\spx@table@toprulehook \spx@table@@toprulehook + \let\spx@table@startbodycolorrows \spx@table@@startbodycolorrows + \let\sphinxtabledecrementrownum \spx@table@@decrementrownum + \spx@prepend\spx@table@toprulehook \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{% +% 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@toprulehook \@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 also we could also have not bothered with the +% \sphinxtabledecrementrownum as its \rownum decrement, if active, is harmless +% in non-colorrows context +} + +% 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 adjustement of \spx@arrayrulewidth +\def\sphinxthistablewithvlinesstyle{% + \def\spx@arrayrulewidth{\arrayrulewidth}% +}% +\def\sphinxthistablewithnovlinesstyle{% + \def\spx@arrayrulewidth{\z@}% +}% + +% 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/writers/latex.py b/sphinx/writers/latex.py index cd565e362db..730453cb5e0 100644 --- a/sphinx/writers/latex.py +++ b/sphinx/writers/latex.py @@ -97,9 +97,24 @@ def __init__(self, node: Element) -> None: 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.booktabs = False + 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 @@ -152,7 +167,7 @@ def get_colspec(self) -> str: if self.colspec: return self.colspec - _colsep = '' if self.booktabs else '|' + _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] @@ -865,16 +880,22 @@ def visit_table(self, node: Element) -> None: (self.curfilestack[-1], node.line or '')) self.tables.append(Table(node)) - self.table.booktabs = self.builder.config.latex_use_booktabs + 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) - if '|' in self.table.colspec and self.table.booktabs: - logger.info(__('tabularcolumns argument contains | and ' - 'latex_use_booktabs is True. Expect gaps between vertical ' - 'and horizontal rules in this table.'), location=node) self.next_table_colspec = None def depart_table(self, node: Element) -> None: @@ -924,21 +945,7 @@ def depart_tbody(self, node: Element) -> None: def visit_row(self, node: Element) -> None: self.table.col = 0 - _colsep = '' if self.table.booktabs else '|' - - if ( - self.builder.config.latex_zebra_stripes and - not isinstance(node.parent, nodes.thead) - ): - if self.table.row % 2 == 0: - self.body.append( - '\\rowcolor{RowEvenColor}[\\dimexpr\\tabcolsep+0.1pt\\relax]' - ) - else: - self.body.append( - '\\rowcolor{RowOddColor}[\\dimexpr\\tabcolsep+0.1pt\\relax]' - ) - + _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) @@ -978,7 +985,7 @@ def visit_entry(self, node: Element) -> None: self.table.add_cell(node.get('morerows', 0) + 1, node.get('morecols', 0) + 1) cell = self.table.cell() context = '' - _colsep = '' if self.table.booktabs else '|' + _colsep = self.table.colsep if cell.width > 1: if self.config.latex_use_latex_multicolumn: if self.table.col == 0: @@ -1025,7 +1032,7 @@ def depart_entry(self, node: Element) -> None: cell = self.table.cell() self.table.col += cell.width - _colsep = '' if self.table.booktabs else '|' + _colsep = self.table.colsep # fill columns if next ones are a bottom of wide-multirow cell while True: diff --git a/tests/roots/test-latex-table/complex.rst b/tests/roots/test-latex-table/complex.rst index fa84f8266cf..d648ff194c4 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 81fc939067b..b511b88dad0 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 @@ \begin{savenotes}\sphinxattablestart +\sphinxthistablewithglobalstyle +\sphinxthistablewithstandardstyle \centering \begin{tabulary}{\linewidth}[t]{|T|T|T|T|T|} \sphinxtoprule -\sphinxmultirow{3}{1}{% +\sphinxtableatstartofbodyhook\sphinxmultirow{3}{1}{% \begin{varwidth}[t]{\sphinxcolwidth{1}{5}} \sphinxAtStartPar cell1\sphinxhyphen{}1 @@ -63,5 +65,5 @@ \\ \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 f5780a5ea3c..8e37575c9df 100644 --- a/tests/roots/test-latex-table/expects/gridtable.tex +++ b/tests/roots/test-latex-table/expects/gridtable.tex @@ -1,6 +1,8 @@ \label{\detokenize{complex:grid-table}} \begin{savenotes}\sphinxattablestart +\sphinxthistablewithglobalstyle +\sphinxthistablewithnocolorrowsstyle \centering \begin{tabulary}{\linewidth}[t]{|T|T|T|} \sphinxtoprule @@ -15,6 +17,7 @@ header3 \\ \sphinxmidrule +\sphinxtableatstartofbodyhook \sphinxAtStartPar cell1\sphinxhyphen{}1 &\sphinxmultirow{2}{5}{% @@ -66,5 +69,5 @@ \\ \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 00000000000..909879ae8a0 --- /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}\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}\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} +\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 2654962f523..7809aef464a 100644 --- a/tests/roots/test-latex-table/expects/longtable.tex +++ b/tests/roots/test-latex-table/expects/longtable.tex @@ -1,6 +1,10 @@ \label{\detokenize{longtable:longtable}} -\begin{savenotes}\sphinxatlongtablestart\begin{longtable}[c]{|l|l|} +\begin{savenotes} +\sphinxatlongtablestart +\sphinxthistablewithglobalstyle +\sphinxthistablewithborderlessstyle +\begin{longtable}[c]{ll} \sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar @@ -30,6 +34,7 @@ \endfoot \endlastfoot +\sphinxtableatstartofbodyhook \sphinxAtStartPar cell1\sphinxhyphen{}1 @@ -52,4 +57,7 @@ cell3\sphinxhyphen{}2 \\ \sphinxbottomrule -\end{longtable}\sphinxatlongtableend\end{savenotes} +\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 08819526218..68ffac40296 100644 --- a/tests/roots/test-latex-table/expects/longtable_having_align.tex +++ b/tests/roots/test-latex-table/expects/longtable_having_align.tex @@ -1,6 +1,9 @@ \label{\detokenize{longtable:longtable-having-align-option}} -\begin{savenotes}\sphinxatlongtablestart\begin{longtable}[r]{|l|l|} +\begin{savenotes} +\sphinxatlongtablestart +\sphinxthistablewithglobalstyle +\begin{longtable}[r]{|l|l|} \sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar @@ -30,6 +33,7 @@ \endfoot \endlastfoot +\sphinxtableatstartofbodyhook \sphinxAtStartPar cell1\sphinxhyphen{}1 @@ -52,4 +56,7 @@ cell3\sphinxhyphen{}2 \\ \sphinxbottomrule -\end{longtable}\sphinxatlongtableend\end{savenotes} +\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 04f4e29d669..232e8ecca42 100644 --- a/tests/roots/test-latex-table/expects/longtable_having_caption.tex +++ b/tests/roots/test-latex-table/expects/longtable_having_caption.tex @@ -1,6 +1,9 @@ \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] \sphinxtoprule @@ -32,6 +35,7 @@ \endfoot \endlastfoot +\sphinxtableatstartofbodyhook \sphinxAtStartPar cell1\sphinxhyphen{}1 @@ -54,4 +58,7 @@ cell3\sphinxhyphen{}2 \\ \sphinxbottomrule -\end{longtable}\sphinxatlongtableend\end{savenotes} +\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 810fd59d18c..9c15d319ea0 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,6 +1,9 @@ \label{\detokenize{longtable:longtable-having-problematic-cell}} -\begin{savenotes}\sphinxatlongtablestart\begin{longtable}[c]{|*{2}{\X{1}{2}|}} +\begin{savenotes} +\sphinxatlongtablestart +\sphinxthistablewithglobalstyle +\begin{longtable}[c]{|*{2}{\X{1}{2}|}} \sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar @@ -30,6 +33,7 @@ \endfoot \endlastfoot +\sphinxtableatstartofbodyhook \begin{itemize} \item {} \sphinxAtStartPar @@ -59,4 +63,7 @@ cell3\sphinxhyphen{}2 \\ \sphinxbottomrule -\end{longtable}\sphinxatlongtableend\end{savenotes} +\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 37309a892d1..21f36b50d78 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,6 +1,9 @@ \label{\detokenize{longtable:longtable-having-both-stub-columns-and-problematic-cell}} -\begin{savenotes}\sphinxatlongtablestart\begin{longtable}[c]{|*{3}{\X{1}{3}|}} +\begin{savenotes} +\sphinxatlongtablestart +\sphinxthistablewithglobalstyle +\begin{longtable}[c]{|*{3}{\X{1}{3}|}} \sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar @@ -36,6 +39,7 @@ \endfoot \endlastfoot +\sphinxtableatstartofbodyhook \sphinxstyletheadfamily \begin{itemize} \item {} \sphinxAtStartPar @@ -64,4 +68,7 @@ cell2\sphinxhyphen{}3 \\ \sphinxbottomrule -\end{longtable}\sphinxatlongtableend\end{savenotes} +\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 97ed0413374..4e66d9e91a1 100644 --- a/tests/roots/test-latex-table/expects/longtable_having_verbatim.tex +++ b/tests/roots/test-latex-table/expects/longtable_having_verbatim.tex @@ -1,6 +1,9 @@ \label{\detokenize{longtable:longtable-having-verbatim}} -\begin{savenotes}\sphinxatlongtablestart\begin{longtable}[c]{|*{2}{\X{1}{2}|}} +\begin{savenotes} +\sphinxatlongtablestart +\sphinxthistablewithglobalstyle +\begin{longtable}[c]{|*{2}{\X{1}{2}|}} \sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar @@ -30,6 +33,7 @@ \endfoot \endlastfoot +\sphinxtableatstartofbodyhook \begin{sphinxVerbatimintable}[commandchars=\\\{\}] \PYG{n}{hello} \PYG{n}{world} @@ -53,4 +57,7 @@ cell3\sphinxhyphen{}2 \\ \sphinxbottomrule -\end{longtable}\sphinxatlongtableend\end{savenotes} +\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 43de6ffe65a..7b9cd11ba01 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}|} -\sphinxtoprule\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 @@ -30,6 +34,7 @@ \endfoot \endlastfoot +\sphinxtableatstartofbodyhook \sphinxAtStartPar cell1\sphinxhyphen{}1 @@ -52,7 +57,10 @@ cell3\sphinxhyphen{}2 \\ \sphinxbottomrule -\end{longtable}\sphinxatlongtableend\end{savenotes} +\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 5a193d7c909..6450a455d62 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,6 +1,9 @@ \label{\detokenize{longtable:longtable-having-both-widths-and-problematic-cell}} -\begin{savenotes}\sphinxatlongtablestart\begin{longtable}[c]{|\X{30}{100}|\X{70}{100}|} +\begin{savenotes} +\sphinxatlongtablestart +\sphinxthistablewithglobalstyle +\begin{longtable}[c]{|\X{30}{100}|\X{70}{100}|} \sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar @@ -30,6 +33,7 @@ \endfoot \endlastfoot +\sphinxtableatstartofbodyhook \begin{itemize} \item {} \sphinxAtStartPar @@ -59,4 +63,7 @@ cell3\sphinxhyphen{}2 \\ \sphinxbottomrule -\end{longtable}\sphinxatlongtableend\end{savenotes} +\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 feab1f62e1c..40efe23e36b 100644 --- a/tests/roots/test-latex-table/expects/longtable_with_tabularcolumn.tex +++ b/tests/roots/test-latex-table/expects/longtable_with_tabularcolumn.tex @@ -1,6 +1,10 @@ \label{\detokenize{longtable:longtable-with-tabularcolumn}} -\begin{savenotes}\sphinxatlongtablestart\begin{longtable}[c]{|c|c|} +\begin{savenotes} +\sphinxatlongtablestart +\sphinxthistablewithglobalstyle +\sphinxthistablewithvlinesstyle +\begin{longtable}[c]{|c|c|} \sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar @@ -30,6 +34,7 @@ \endfoot \endlastfoot +\sphinxtableatstartofbodyhook \sphinxAtStartPar cell1\sphinxhyphen{}1 @@ -52,4 +57,7 @@ cell3\sphinxhyphen{}2 \\ \sphinxbottomrule -\end{longtable}\sphinxatlongtableend\end{savenotes} +\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 01ba7681608..7bd85c737b2 100644 --- a/tests/roots/test-latex-table/expects/simple_table.tex +++ b/tests/roots/test-latex-table/expects/simple_table.tex @@ -1,6 +1,7 @@ \label{\detokenize{tabular:simple-table}} \begin{savenotes}\sphinxattablestart +\sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{|T|T|} \sphinxtoprule @@ -12,6 +13,7 @@ header2 \\ \sphinxmidrule +\sphinxtableatstartofbodyhook \sphinxAtStartPar cell1\sphinxhyphen{}1 & @@ -34,5 +36,5 @@ \\ \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 e57f4725ffb..f2ce5536021 100644 --- a/tests/roots/test-latex-table/expects/table_having_caption.tex +++ b/tests/roots/test-latex-table/expects/table_having_caption.tex @@ -1,6 +1,7 @@ \label{\detokenize{tabular:table-having-caption}} \begin{savenotes}\sphinxattablestart +\sphinxthistablewithglobalstyle \centering \sphinxcapstartof{table} \sphinxthecaptionisattop @@ -16,6 +17,7 @@ header2 \\ \sphinxmidrule +\sphinxtableatstartofbodyhook \sphinxAtStartPar cell1\sphinxhyphen{}1 & @@ -38,5 +40,5 @@ \\ \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 e11a45f7290..7d7ad4b715b 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,6 +1,7 @@ \label{\detokenize{tabular:table-having-problematic-cell}} \begin{savenotes}\sphinxattablestart +\sphinxthistablewithglobalstyle \centering \begin{tabular}[t]{|*{2}{\X{1}{2}|}} \sphinxtoprule @@ -11,7 +12,8 @@ \sphinxAtStartPar header2 \\ -\sphinxmidrule\begin{itemize} +\sphinxmidrule +\sphinxtableatstartofbodyhook\begin{itemize} \item {} \sphinxAtStartPar item1 @@ -41,5 +43,5 @@ \\ \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 68a485519d4..fbd797a1bd3 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,6 +1,7 @@ \label{\detokenize{tabular:table-having-both-stub-columns-and-problematic-cell}} \begin{savenotes}\sphinxattablestart +\sphinxthistablewithglobalstyle \centering \begin{tabular}[t]{|*{3}{\X{1}{3}|}} \sphinxtoprule @@ -14,7 +15,8 @@ \sphinxAtStartPar header3 \\ -\sphinxmidrule\sphinxstyletheadfamily \begin{itemize} +\sphinxmidrule +\sphinxtableatstartofbodyhook\sphinxstyletheadfamily \begin{itemize} \item {} \sphinxAtStartPar instub1\sphinxhyphen{}1a @@ -43,5 +45,5 @@ \\ \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 2ea24d37309..9acd9a86d46 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,6 +1,7 @@ \label{\detokenize{tabular:table-with-cell-in-first-column-having-three-paragraphs}} \begin{savenotes}\sphinxattablestart +\sphinxthistablewithglobalstyle \centering \begin{tabulary}{\linewidth}[t]{|T|} \sphinxtoprule @@ -9,6 +10,7 @@ header1 \\ \sphinxmidrule +\sphinxtableatstartofbodyhook \sphinxAtStartPar cell1\sphinxhyphen{}1\sphinxhyphen{}par1 @@ -20,5 +22,5 @@ \\ \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 de90c32b113..a002de58618 100644 --- a/tests/roots/test-latex-table/expects/table_having_verbatim.tex +++ b/tests/roots/test-latex-table/expects/table_having_verbatim.tex @@ -1,6 +1,7 @@ \label{\detokenize{tabular:table-having-verbatim}} \begin{savenotes}\sphinxattablestart +\sphinxthistablewithglobalstyle \centering \begin{tabular}[t]{|*{2}{\X{1}{2}|}} \sphinxtoprule @@ -12,6 +13,7 @@ header2 \\ \sphinxmidrule +\sphinxtableatstartofbodyhook \begin{sphinxVerbatimintable}[commandchars=\\\{\}] \PYG{n}{hello} \PYG{n}{world} \end{sphinxVerbatimintable} @@ -35,5 +37,5 @@ \\ \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 6891df9abde..fe5f4c44d72 100644 --- a/tests/roots/test-latex-table/expects/table_having_widths.tex +++ b/tests/roots/test-latex-table/expects/table_having_widths.tex @@ -1,9 +1,12 @@ \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}|} +\begin{tabular}[t]{\X{30}{100}\X{70}{100}} \sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar @@ -13,6 +16,7 @@ header2 \\ \sphinxmidrule +\sphinxtableatstartofbodyhook \sphinxAtStartPar cell1\sphinxhyphen{}1 & @@ -35,7 +39,7 @@ \\ \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 b81c9867b02..1baf92c1ae6 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,6 +1,7 @@ \label{\detokenize{tabular:table-having-both-widths-and-problematic-cell}} \begin{savenotes}\sphinxattablestart +\sphinxthistablewithglobalstyle \centering \begin{tabular}[t]{|\X{30}{100}|\X{70}{100}|} \sphinxtoprule @@ -11,7 +12,8 @@ \sphinxAtStartPar header2 \\ -\sphinxmidrule\begin{itemize} +\sphinxmidrule +\sphinxtableatstartofbodyhook\begin{itemize} \item {} \sphinxAtStartPar item1 @@ -41,5 +43,5 @@ \\ \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 90e6b9dc19e..15321d693cf 100644 --- a/tests/roots/test-latex-table/expects/tabular_having_widths.tex +++ b/tests/roots/test-latex-table/expects/tabular_having_widths.tex @@ -1,6 +1,7 @@ \label{\detokenize{tabular:table-having-align-option-tabular}} \begin{savenotes}\sphinxattablestart +\sphinxthistablewithglobalstyle \raggedright \begin{tabular}[t]{|\X{30}{100}|\X{70}{100}|} \sphinxtoprule @@ -12,6 +13,7 @@ header2 \\ \sphinxmidrule +\sphinxtableatstartofbodyhook \sphinxAtStartPar cell1\sphinxhyphen{}1 & @@ -34,5 +36,5 @@ \\ \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 8274ae2382c..fcb01be3f50 100644 --- a/tests/roots/test-latex-table/expects/tabularcolumn.tex +++ b/tests/roots/test-latex-table/expects/tabularcolumn.tex @@ -1,8 +1,10 @@ \label{\detokenize{tabular:table-with-tabularcolumn}} \begin{savenotes}\sphinxattablestart +\sphinxthistablewithglobalstyle +\sphinxthistablewithnovlinesstyle \centering -\begin{tabulary}{\linewidth}[t]{|c|c|} +\begin{tabulary}{\linewidth}[t]{cc} \sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar @@ -12,6 +14,7 @@ header2 \\ \sphinxmidrule +\sphinxtableatstartofbodyhook \sphinxAtStartPar cell1\sphinxhyphen{}1 & @@ -34,5 +37,5 @@ \\ \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 939a7f67a49..24634163010 100644 --- a/tests/roots/test-latex-table/expects/tabulary_having_widths.tex +++ b/tests/roots/test-latex-table/expects/tabulary_having_widths.tex @@ -1,6 +1,7 @@ \label{\detokenize{tabular:table-having-align-option-tabulary}} \begin{savenotes}\sphinxattablestart +\sphinxthistablewithglobalstyle \raggedleft \begin{tabulary}{\linewidth}[t]{|T|T|} \sphinxtoprule @@ -12,6 +13,7 @@ header2 \\ \sphinxmidrule +\sphinxtableatstartofbodyhook \sphinxAtStartPar cell1\sphinxhyphen{}1 & @@ -34,5 +36,5 @@ \\ \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 bace9d4d2d8..da6fa5c5cec 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 7f090954004..15db823a05b 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/test_build_latex.py b/tests/test_build_latex.py index cf6b40d9756..db0e67fc4a4 100644 --- a/tests/test_build_latex.py +++ b/tests/test_build_latex.py @@ -92,7 +92,9 @@ 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_use_booktabs = True + app.config.latex_table_style = ['booktabs'] + elif engine == 'lualatex': + app.config.latex_table_style = ['colorrows'] app.builder.init() LaTeXTranslator.ignore_missing_images = True @@ -726,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 ('\\sphinxmidrule%\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 ' @@ -736,7 +739,7 @@ def test_footnote(app, status, warning): '\\begin{footnote}[6]\\sphinxAtStartFootnote\n' 'footnote in table not in header\n%\n\\end{footnote}\n\\\\\n' '\\sphinxbottomrule\n\\end{tabulary}\n' - '\\par\n\\sphinxattableend\\end{savenotes}\n') in result + '\\sphinxtableafterendhook\\par\n\\sphinxattableend\\end{savenotes}\n') in result @pytest.mark.sphinx('latex', testroot='footnotes') @@ -764,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 @@ -1312,6 +1316,13 @@ def get_expected(name): 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') @@ -1319,12 +1330,16 @@ def get_expected(name): @pytest.mark.sphinx('latex', testroot='latex-table', - confoverrides={'latex_use_booktabs': True}) -def test_latex_table_with_booktabs(app, status, warning): + 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'\begin{tabulary}{\linewidth}[t]{TTTTT}' 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 From 03292da10c67fd4c3ccae65576ad12c420546123 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20B?= <2589111+jfbu@users.noreply.github.com> Date: Mon, 15 Aug 2022 11:34:59 +0200 Subject: [PATCH 08/16] Workaround LaTeX's \cline features and other grid tables matters This is a combination of 7 commits. - LaTeX command \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. - Fix regression from a \kern erroneous displacement; and other problems with merged cells and colours - LaTeX code comments and rearrangements of code order --- doc/latex.rst | 30 +- sphinx/texinputs/sphinx.sty | 74 ++- sphinx/texinputs/sphinxlatexstyleheadings.sty | 3 +- sphinx/texinputs/sphinxlatextables.sty | 438 +++++++++++------- sphinx/texinputs/sphinxpackagefootnote.sty | 3 +- sphinx/writers/latex.py | 25 +- .../expects/complex_spanning_cell.tex | 4 +- .../test-latex-table/expects/gridtable.tex | 6 +- .../expects/gridtable_with_tabularcolumn.tex | 6 +- 9 files changed, 381 insertions(+), 208 deletions(-) diff --git a/doc/latex.rst b/doc/latex.rst index 56a9a7807b4..f98d2797093 100644 --- a/doc/latex.rst +++ b/doc/latex.rst @@ -879,23 +879,29 @@ Do not use quotes to enclose values, whether numerical or strings. names declared to "color" or "xcolor" are prefixed with "sphinx". ``TableRowColorHeader`` - Background colour for (all) the header rows. This (as the next - ``Table...`` colours) applies conditionnally - on either ``'colorrows'`` being contained in :confval:`latex_table_style` - or on the table receiving ``colorrows`` as class. + Sets the background colour for (all) the header rows. + + This (as the other ``Table...`` colour keys) applies to all tables if + ``'colorrows'`` is contained in :confval:`latex_table_style`, except to + those with ``nocolorrows`` class; in absence of ``'colorrows'`` in + :confval:`latex_table_style` it will apply to tables with ``colorrows`` + class. + + As for the other ``'sphinxsetup'`` keys, it can be set or modified inside + the document from a ``\sphinxsetup{...}`` LaTeX command inserted via the + :dudir:`raw` directive, or from a LaTeX environment associated to a + `container class `_. Default: ``{gray}{0.86}`` - There is also ``TableMergeColorHeader`` which as long as it is not - defined (either globally via ``'sphinxsetup'`` interface or locally - via :dudir:`raw` directive and ``\sphinxsetup`` LaTeX macro) will keep - in sync with ``TableRowColorHeader``. + There is also ``TableMergeColorHeader``. If used, sets a specific colour + for merged single-row cells in the header. .. versionadded:: 5.2.0 ``TableRowColorOdd`` - Background colour for odd rows in tables (the row count starts at ``1`` - at the first non-header row). + Sets the background colour for odd rows in tables (the row count starts + at ``1`` at the first non-header row). Default: ``{gray}{0.92}`` @@ -904,7 +910,7 @@ Do not use quotes to enclose values, whether numerical or strings. .. versionadded:: 5.2.0 ``TableRowColorEven`` - Background colour for even rows in tables. + Sets the background colour for even rows in tables. Default ``{gray}{0.98}`` @@ -1464,6 +1470,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/sphinx/texinputs/sphinx.sty b/sphinx/texinputs/sphinx.sty index be8965e2561..070a896026e 100644 --- a/sphinx/texinputs/sphinx.sty +++ b/sphinx/texinputs/sphinx.sty @@ -6,7 +6,7 @@ % \NeedsTeXFormat{LaTeX2e}[1995/12/01] -\ProvidesPackage{sphinx}[2022/08/10 v5.2.0 LaTeX package (Sphinx markup)] +\ProvidesPackage{sphinx}[2022/08/15 v5.2.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 @@ -67,14 +104,16 @@ % \@ifpackageloaded{xcolor}% {}% - {% xcolor not loaded + {% xcolor not loaded because it was not found in the LaTeX installation \def\spx@colorlet#1\relax{% + \sphinxbuildwarning{coloursyntax}% \PackageWarning{sphinx}{% -Sorry, defining \spx@definedcolor\space to be #1\MessageBreak -via \protect\colorlet syntax requires package xcolor.sty.\MessageBreak -The color \spx@definedcolor\space will be set to {rgb}{0,0,1}\MessageBreak -\protect\definecolor}% - \expandafter\definecolor\spx@definedcolor{rgb}{0,0,1}}% +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 @@ -173,28 +212,28 @@ The color \spx@definedcolor\space will be set to {rgb}{0,0,1}\MessageBreak % 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% + % set the key handler to accept both \definecolor and \colorlet syntax \define@key{sphinx}{#1}{\spx@defineorletcolor{#1}##1\relax}% }% -% only \definecolor syntax for the defaults here! \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. + % set the key handler to accept both \definecolor and \colorlet syntax \define@key{sphinx}{#1}{\spx@defineorletcolor{sphinx#1}##1\relax}% }% -% only \definecolor syntax for the defaults here! % table row colors \sphinxDeclareSphinxColorOption{TableRowColorHeader}{{gray}{0.86}} \sphinxDeclareSphinxColorOption{TableRowColorOdd}{{gray}{0.92}} \sphinxDeclareSphinxColorOption{TableRowColorEven}{{gray}{0.98}} -% if not defined "MergeColor" will keep in sync with "RowColor" +% 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 @@ -751,11 +790,8 @@ The color \spx@definedcolor\space will be set to {rgb}{0,0,1}\MessageBreak {\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 fa9be82b44d..a54980bc03b 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 76d29d1c719..1746b2783f1 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}[2022/08/10 tables]% +\ProvidesFile{sphinxlatextables.sty}[2022/08/15 tables]% % Provides support for this output mark-up from Sphinx latex writer % and table templates: @@ -27,6 +27,8 @@ % - \sphinxthelongtablecaptionisattop % - \sphinxhline % - \sphinxcline +% - \sphinxvlinecrossing +% - \sphinxfixclines % - \sphinxtoprule % - \sphinxmidrule % - \sphinxbottomrule @@ -47,6 +49,7 @@ % - 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 @@ -266,9 +269,13 @@ % % 5.2.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% #2 is either \sphinxmultirow or \begin - \def\spx@table@hackCT@inmergedcell{\spx@table@hackCT@nocolor}% + \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% }% @@ -334,13 +341,11 @@ \noindent\kern\sphinx@tempb\relax \xdef\sphinx@multiwidth {\the\dimexpr\sphinx@multiwidth+\sphinx@tempb+\tw@\tabcolsep+\spx@arrayrulewidth}% - % simulate the \vline added width - \spx@table@fakevline + \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; sadly we can't infere a \cellcolor and propagate it to the - % merged cell as it has not be seen yet at this stage which is preparatory - % to the varwidth environment execution... and the background colour panels - % are injected by colortbl now when the & is met... + % 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}% @@ -357,7 +362,8 @@ \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 + % last cell of the multi-column + \aftergroup\spx@table@hackCT@fixcolorpanel \aftergroup\spx@table@hackCT@inmergedcell }% \newcommand*\sphinxcolwidth[2]{% @@ -404,15 +410,17 @@ (\ifx\TY@final\@undefined\linewidth\else\sphinx@TY@tablewidth\fi -\spx@arrayrulewidth)*#2-\tw@\tabcolsep-\spx@arrayrulewidth\relax}% -% \spx@table@fakevline +% \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 -% induces an empty space of the width corresponding to a \vline. Then it % 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) -\def\spx@table@fakevline{\ifnum\currentgrouptype=6\relax - \kern\spx@arrayrulewidth\arrayrulewidth\z@\else\aftergroup\spx@table@fakevline\fi}% +% \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: @@ -432,17 +440,21 @@ % covered by colour panels at various places. At 5.2.0 this mechanism % is relaxed a bit to allow row colour for a single-row merged cell. % -% \spx@table@hackCT@inmergedcell -% \spx@table@hackCT@nocolor -% \spx@table@hackCT@norowcolor -% -% \let\spx@original@CT@setup\CT@setup is done after the loading of colortbl -% package +% 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 -\def\spx@table@hackCT@inmergedcell{\ifnum\currentgrouptype=6\relax +% \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 + \else\aftergroup\spx@@table@hackCT@inmergedcell\fi }% \newif\ifspx@table@inmergedcell \def\spx@CT@setup@inmergedcell #1\endgroup{% @@ -468,9 +480,10 @@ } \def\spx@CT@setup@nocolor#1\endgroup{% \global\let\CT@cell@color\relax - % the above added at 5.2.0 + % the above fix was added at 5.2.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 + % 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 @@ -488,36 +501,6 @@ \else\aftergroup\spx@table@hackCT@norowcolor\fi } % -% sphinxcolormix (commented-out) -% this works but then I found out about \blendcolors in xcolor doc, so I provided -% rather \sphinxcolorblend, the code is kept in case it can be reused in future -% \@ifpackageloaded{xcolor}{% -% \def\spx@table@hackCT@colormix{% -% \ifnum\currentgrouptype=6\relax -% \ifx\CT@column@color\relax -% \else -% \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 -% \else -% \colorlet{spxcolumncolor}{.}% -% \spx@saved@CT@row@color -% \colorlet{spxrowcolor}{.}% -% \color{spxcolumncolor!\spx@colormixparam!spxrowcolor}% -% \fi -% }% patched \CT@row@color -% \fi -% \fi -% \else -% \aftergroup\spx@table@hackCT@colormix -% \fi -% }% -% }{\let\spx@table@hackCT@colormix\@empty}% no-op if no xcolor as \colorlet needed -% \def\sphinxcolormix#1{\gdef\spx@colormixparam{#1}\spx@table@hackCT@colormix} -% % \sphinxcolorblend \def\spx@table@hackCT@colorblend{% \ifnum\currentgrouptype=6\relax @@ -529,12 +512,20 @@ \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}% {}% - {\let\spx@table@hackCT@colorblend\@empty}% no-op if no xcolor -\def\sphinxcolorblend#1{\gdef\spx@colorblendparam{{#1}}\spx@table@hackCT@colorblend} + {\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}% + }% + } %%%%%%%%%%%%%%%%%% @@ -597,7 +588,7 @@ % % 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 verticale adjustement... +% a suitable vertical adjustment... % % The contents, which is a varwidth environment, has been captured in % \box0 (a \hbox). @@ -664,8 +655,6 @@ \@width\z@ \endgroup % we need this to avoid colour panels hiding bottom parts of multirow text - % whether they originate in \columncolor or \rowcolor (or even \cellcolor - % even though it can be only in top cell, but we could hijack it). \spx@table@hackCT@nocolor }% @@ -673,41 +662,6 @@ % --- STYLING --- % -% the initialization macros executed before the table environments -% their scope is limited by a wrapper "savenotes" environment -% -% 0) color 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 -% -% 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). -% -\let\sphinxtabletoprulehook \@empty -\let\sphinxtableatstartofbodyhook\@empty -\let\sphinxtableafterendhook \@empty % % Support for colour in table % @@ -715,6 +669,95 @@ % 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 @@ -765,21 +808,46 @@ % 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}% -% set the colours according to row parity; a priori #1 is \rownum, but -% the macro can be used in user 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 -} +% \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 + }% +}% -% this will start the alternating colours, by letting \everycr increment the -% \rownum counter and reset the colours according to \sphinxSwitchCaseRowColor\rownum +% \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 @@ -798,52 +866,82 @@ \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 inihibit colours in the header rows + % to inhibit colours in the header rows }% end of noalign contents } - -\def\sphinxrowcolorON{% the colours here must have been defined, and this is done - % via \sphinxtabletoprulehook default action - \gdef\CT@row@color{\ifspx@table@inmergedcell - \CT@color{sphinxTableMergeColor}% - \else - \CT@color{sphinxTableRowColor}% - \fi - \@tempdimb\dimexpr\col@sep+\sphinxcolorpanelextraoverhang\relax - \@tempdimc\@tempdimb - }% -}% -\def\sphinxrowcolorOFF{\global\let\CT@row@color\relax}% -\def\sphinxnorowcolor{\spx@table@hackCT@norowcolor}% inhibits row colour in one cell only -\def\spx@table@resetcolortbl{% can be executed from inside or outside a table - \global\let\CT@row@color\relax -% we should probably be more cautious and not hard-code here the colortbl set-up - \global\CT@everycr{\noalign{\global\let\CT@row@color\relax}\the\everycr}% +% 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 } -\def\spx@table@@toprulehook{% - \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 - }% -}% - -% this macro is needed in color tables as each \cline or \cmidrule (booktabs) -% consumes one \cr, offsetting the rownum parity. +% 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 -% At last the style macros +% \sphinxtableafterendhook will be modified by colorrows class to execute +% this after the table +\def\spx@table@resetcolortbl{% + \sphinxrowcolorOFF + \spx@table@reset@CTeverycr +} +\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... -% \spx@toprule is what the styles define; the colorrows class will prepend -% some code in \sphinxtabletoprulehook +% 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{% @@ -852,6 +950,9 @@ % \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}% @@ -888,16 +989,18 @@ \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 +% 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} -% and it must be first due to internals of the \cmidrule usage of \futurelet, -% if the table uses row colours. +% \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 \@gobble + \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}% @@ -907,10 +1010,9 @@ {}% {\def\sphinxthistablewithbooktabsstyle{% \PackageWarning{sphinx}{% -Please add \string\usepackage{booktabs} to the preamble\MessageBreak -to allow local use of booktabs table style}% - \textcolor{red}{\bfseries ADD LOADING OF booktabs TO THE 'preamble' KEY OF - latex\textunderscore elements}\par +Add \string\usepackage{booktabs} to the preamble to allow\MessageBreak +local use of booktabs table style}% + \sphinxbuildwarning{booktabs}% \sphinxthistablewithstandardstyle }}% }% @@ -919,6 +1021,8 @@ to allow local use of booktabs table 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 @@ -927,15 +1031,16 @@ to allow local use of booktabs table style}% % colorrows style % +\def\sphinxthistablewithcolorrowsstyle{% % this is defined to auto-silence itself (in the surrounding scope-limiting % environment) after one execution -\def\sphinxthistablewithcolorrowsstyle{% \let\sphinxthistablewithcolorrowsstyle\@empty % - \let\spx@table@toprulehook \spx@table@@toprulehook + \let\spx@table@toprule@rowcolorON \spx@table@@toprule@rowcolorON \let\spx@table@startbodycolorrows \spx@table@@startbodycolorrows \let\sphinxtabledecrementrownum \spx@table@@decrementrownum - \spx@prepend\spx@table@toprulehook \to\sphinxtabletoprulehook +% 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 @@ -948,28 +1053,39 @@ to allow local use of booktabs table style}% \toks@\expandafter\expandafter\expandafter{\expandafter\the\expandafter\toks@#2}% \edef#2{\the\toks@}% }% +% give it a global definition so we can test from inside user hooks if +% colorrows is not activated simply by \ifx\spx@table@toprule@rowcolorON\@empty +\let\spx@table@toprule@rowcolorON\@empty \def\sphinxthistablewithnocolorrowsstyle{% % 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@toprulehook \@empty + \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 also we could also have not bothered with the +% 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 } % The \spx@arrayrulewidth is used for some complex matters of merged -% cells size computations +% cells size computations. % tabularcolumns argument will override any global or local style and -% trigger the appropriate adjustement of \spx@arrayrulewidth +% 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 diff --git a/sphinx/texinputs/sphinxpackagefootnote.sty b/sphinx/texinputs/sphinxpackagefootnote.sty index 6a7884f83bd..39d8cfacf20 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.2.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/latex.py b/sphinx/writers/latex.py index 730453cb5e0..094eb763e34 100644 --- a/sphinx/writers/latex.py +++ b/sphinx/writers/latex.py @@ -971,12 +971,23 @@ def depart_row(self, node: Element) -> None: 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'\sphinxcline{%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: @@ -1040,16 +1051,16 @@ def depart_entry(self, node: Element) -> None: 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 + # 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 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 b511b88dad0..d2d61894251 100644 --- a/tests/roots/test-latex-table/expects/complex_spanning_cell.tex +++ b/tests/roots/test-latex-table/expects/complex_spanning_cell.tex @@ -51,7 +51,7 @@ \vskip-\baselineskip\vbox{\hbox{\strut}}\end{varwidth}% }% \\ -\sphinxcline{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 @@ -59,7 +59,7 @@ \vskip-\baselineskip\vbox{\hbox{\strut}}\end{varwidth}% }% &\sphinxtablestrut{4}&\sphinxtablestrut{5}\\ -\sphinxcline{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 \\ diff --git a/tests/roots/test-latex-table/expects/gridtable.tex b/tests/roots/test-latex-table/expects/gridtable.tex index 8e37575c9df..407abe7f2c8 100644 --- a/tests/roots/test-latex-table/expects/gridtable.tex +++ b/tests/roots/test-latex-table/expects/gridtable.tex @@ -31,7 +31,7 @@ \sphinxAtStartPar cell1\sphinxhyphen{}3 \\ -\sphinxcline{1-1}\sphinxcline{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 @@ -42,7 +42,7 @@ \sphinxAtStartPar cell2\sphinxhyphen{}3 \\ -\sphinxcline{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 @@ -55,7 +55,7 @@ }% \sphinxstopmulticolumn \\ -\sphinxcline{1-1} +\sphinxcline{1-1}\sphinxfixclines{3} \sphinxAtStartPar cell4\sphinxhyphen{}1 &\multicolumn{2}{l|}{\sphinxtablestrut{9}}\\ diff --git a/tests/roots/test-latex-table/expects/gridtable_with_tabularcolumn.tex b/tests/roots/test-latex-table/expects/gridtable_with_tabularcolumn.tex index 909879ae8a0..c77b99041ff 100644 --- a/tests/roots/test-latex-table/expects/gridtable_with_tabularcolumn.tex +++ b/tests/roots/test-latex-table/expects/gridtable_with_tabularcolumn.tex @@ -31,7 +31,7 @@ \sphinxAtStartPar cell1\sphinxhyphen{}3 \\ -\sphinxcline{1-1}\sphinxcline{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 @@ -42,7 +42,7 @@ \sphinxAtStartPar cell2\sphinxhyphen{}3 \\ -\sphinxcline{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 @@ -55,7 +55,7 @@ }% \sphinxstopmulticolumn \\ -\sphinxcline{1-1} +\sphinxcline{1-1}\sphinxfixclines{3} \sphinxAtStartPar cell4\sphinxhyphen{}1 &\multicolumn{2}{l}{\sphinxtablestrut{9}}\\ From abab0bf1e43d8ce809bc62452f58930b628731a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20B?= <2589111+jfbu@users.noreply.github.com> Date: Wed, 17 Aug 2022 18:58:08 +0200 Subject: [PATCH 09/16] Add booktabscolorizegaps sphinxsetup option Perhaps this should actually be default behaviour for booktabs + colorrows at sphinx-doc/sphinx#10759 ? Then it would not be an option at all and would not need documentation. On seeing output in our own document PDF, I find this rather nice actually. Perhaps it is indeed better than leaving the white gaps. --- sphinx/texinputs/sphinx.sty | 1 + sphinx/texinputs/sphinxlatextables.sty | 80 ++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) diff --git a/sphinx/texinputs/sphinx.sty b/sphinx/texinputs/sphinx.sty index 070a896026e..9f9555e6eec 100644 --- a/sphinx/texinputs/sphinx.sty +++ b/sphinx/texinputs/sphinx.sty @@ -124,6 +124,7 @@ will be set to white}% % Optional usage of booktabs package for tables \DeclareBoolOption[false]{booktabs} \DeclareBoolOption[false]{borderless} +\DeclareBoolOption[false]{booktabscolorizegaps} % Coloured table rows \DeclareBoolOption[false]{colorrows} % Sphinx legacy text layout: 1in margins on all four sides diff --git a/sphinx/texinputs/sphinxlatextables.sty b/sphinx/texinputs/sphinxlatextables.sty index 1746b2783f1..bbc78ef6688 100644 --- a/sphinx/texinputs/sphinxlatextables.sty +++ b/sphinx/texinputs/sphinxlatextables.sty @@ -1069,6 +1069,86 @@ local use of booktabs table style}% % in non-colorrows context } +% (not so easy) implementation of the booktabscolorizegaps option +% As it is used via \sphinxsetup its 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 colorizegaps is. +% +% We will use macros such as \sphinxbooktabstoprule which are supposedly +% customizable by user, but here we pre-empt them. Any modification will +% break our code... +% +% We need a helper conditional +\def\spx@ifbooktabscoloredgaps@TF{% + \if1\ifspx@opt@booktabscolorizegaps + \ifx\spx@table@toprule@rowcolorON\@empty0\fi + 1\else0\fi + \expandafter\@firstoftwo + \else\expandafter\@secondoftwo + \fi +} +\def\sphinxbooktabstoprule{% + \spx@ifbooktabscoloredgaps@TF + {\spx@booktabs@specialtoprule}% + {\toprule}% +}% +\def\spx@booktabs@specialtoprule\sphinxtabletoprulehook{% + \specialrule{\heavyrulewidth}{\abovetopsep}{\z@}% + \sphinxtabletoprulehook% contains color init code + % 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@ + \gdef\CT@arc@{\color{sphinxTableRowColor}}% + }% + \specialrule{\belowrulesep}{\z@}{\z@}% already in a \noalign... + \noalign{\global\let\CT@arc@\spx@@@@saved@CT@arc@}% +}% +\def\sphinxbooktabsmidrule{% + \spx@ifbooktabscoloredgaps@TF + {\spx@booktabs@specialmidrule}% + {\midrule}% +}% +\def\spx@booktabs@specialmidrule{% + \noalign{\global\let\spx@@@@saved@CT@arc@\CT@arc@ + \gdef\CT@arc@{\color{sphinxTableRowColor}}% this is RowColorHeader + }% + \specialrule{\aboverulesep}{\z@}{\z@}% + \noalign{\global\let\CT@arc@\spx@@@@saved@CT@arc@}% + \specialrule{\lightrulewidth}{\z@}{\z@}% + \noalign{\gdef\CT@arc@{\color{sphinxTableRowColorOdd}}}% + \specialrule{\belowrulesep}{\z@}{\z@}% + \noalign{\global\let\CT@arc@\spx@@@@saved@CT@arc@}% +}% +\def\sphinxbooktabsbottomrule{% + \spx@ifbooktabscoloredgaps@TF + {\spx@booktabs@specialbottomrule}% + {\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 +\def\spx@booktabs@specialbottomrule{% + \noalign{\global\let\spx@@@@saved@CT@arc@\CT@arc@ + \sphinxSwitchCaseRowColor{\numexpr\rownum-\@ne\relax}% + \gdef\CT@arc@{\color{sphinxTableRowColor}}% holds current row colour + }% + \specialrule{\aboverulesep}{\z@}{\z@}% + \noalign{\global\let\CT@arc@\spx@@@@saved@CT@arc@}% + \specialrule{\heavyrulewidth}{\z@}{\belowbottomsep}% +}% + % The \spx@arrayrulewidth is used for some complex matters of merged % cells size computations. % tabularcolumns argument will override any global or local style and From 765ccda6f0a5001f61ea6d5b1d68f3f7af0198f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20B?= <2589111+jfbu@users.noreply.github.com> Date: Wed, 17 Aug 2022 22:26:41 +0200 Subject: [PATCH 10/16] Fix colour for booktabs gap after top rule if no header Relates sphinx-doc/sphinx#10759 --- sphinx/texinputs/sphinxlatextables.sty | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/sphinx/texinputs/sphinxlatextables.sty b/sphinx/texinputs/sphinxlatextables.sty index bbc78ef6688..57122adc3dd 100644 --- a/sphinx/texinputs/sphinxlatextables.sty +++ b/sphinx/texinputs/sphinxlatextables.sty @@ -1105,16 +1105,36 @@ local use of booktabs table style}% {\spx@booktabs@specialtoprule}% {\toprule}% }% -\def\spx@booktabs@specialtoprule\sphinxtabletoprulehook{% +\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\spx@booktabs@specialtoprule\sphinxtabletoprulehook#1{% \specialrule{\heavyrulewidth}{\abovetopsep}{\z@}% \sphinxtabletoprulehook% contains color init code % 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@ - \gdef\CT@arc@{\color{sphinxTableRowColor}}% - }% + \gdef\CT@arc@{\color{sphinxTableRowColor% this is in fact Header color +% this crazy code relies on \color using here expansion only and it expands +% to "Odd" if #1 is one of \endfirsthead, \endhead or +% \sphinxtableatstartofbodyhook else it expands to nothing. + \spx@table@crazyfork + #1\endhead\sphinxtableatstartofbodyhook{Odd}% + \endfirsthead#1\sphinxtableatstartofbodyhook{Odd}% + \endfirsthead\endhead#1{Odd}% + \endfirsthead\endhead\sphinxtableatstartofbodyhook{}% + \@nil + }% end of crazy color name build + }% end of \CT@arc@ def + }% end of \noalign \specialrule{\belowrulesep}{\z@}{\z@}% already in a \noalign... \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{% \spx@ifbooktabscoloredgaps@TF From 0e76aaab6a90b27b968fb83c0b9d199a3888f8f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20B?= <2589111+jfbu@users.noreply.github.com> Date: Thu, 18 Aug 2022 09:58:28 +0200 Subject: [PATCH 11/16] \sphinxbooktabsspecialruleoverhang for perfect same-colour-joins This avoids at high level of zooming, depending on PDF viewers a line of non-coloured or anti-aliased pixels at the joining of two rectangles of same colour due to rounding effects. Nota Bene: the background colour panels extend a tiny bit beyond left and right limits of table due to another parameter used for similar reasons motivated by horizontally merged cells: \sphinxcolorpanelextraoverhang (also defaulting to 0.1pt) Relates sphinx-doc/sphinx#10759 This is a combination of 4 commits - some code comments for future edit if this is to be used upstream - safer usage of \spx@table@crazyfork in case #1 turns out to be \par - add \sphinxifthistablewithcolorrowsTF to simplify coding - \sphinxbooktabsspecialruleoverhang for perfect same-colour-joins --- sphinx/texinputs/sphinxlatextables.sty | 54 ++++++++++++++++---------- 1 file changed, 33 insertions(+), 21 deletions(-) diff --git a/sphinx/texinputs/sphinxlatextables.sty b/sphinx/texinputs/sphinxlatextables.sty index 57122adc3dd..0b4315c2c11 100644 --- a/sphinx/texinputs/sphinxlatextables.sty +++ b/sphinx/texinputs/sphinxlatextables.sty @@ -1031,9 +1031,11 @@ local use of booktabs table style}% % 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 +% environment) after one execution ("colorrows" can never follow "nocolorrows") \let\sphinxthistablewithcolorrowsstyle\@empty % \let\spx@table@toprule@rowcolorON \spx@table@@toprule@rowcolorON @@ -1053,11 +1055,9 @@ local use of booktabs table style}% \toks@\expandafter\expandafter\expandafter{\expandafter\the\expandafter\toks@#2}% \edef#2{\the\toks@}% }% -% give it a global definition so we can test from inside user hooks if -% colorrows is not activated simply by \ifx\spx@table@toprule@rowcolorON\@empty -\let\spx@table@toprule@rowcolorON\@empty \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 @@ -1091,11 +1091,17 @@ local use of booktabs table style}% % customizable by user, but here we pre-empt them. Any modification will % break our code... % -% We need a helper conditional +% MEMO: if this is merged and default behaviour I should then use names such +% as \sphinxbooktabsspecialtoprule (or perhaps a better one) which would +% receive the meaning attributed below to \sphinxbooktabstoprule, and the code +% would do here once \def\sphinxbooktabstoprule{\sphinxbooktabsspecialtoprule} +% rather so a user custom one (or an option) could simply do for example +% \def\sphinxbooktabstoprule {\toprule or whatever} to undo this behaviour. +% Same for midrule and bottomrule. \def\spx@ifbooktabscoloredgaps@TF{% \if1\ifspx@opt@booktabscolorizegaps - \ifx\spx@table@toprule@rowcolorON\@empty0\fi - 1\else0\fi + \sphinxifthistablewithcolorrowsTF{1}{0}% + \else0\fi \expandafter\@firstoftwo \else\expandafter\@secondoftwo \fi @@ -1105,6 +1111,7 @@ local use of booktabs table style}% {\spx@booktabs@specialtoprule}% {\toprule}% }% +\def\sphinxbooktabsspecialruleoverhang{0.1pt}% avoid pixel/rounding effects \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 @@ -1117,20 +1124,22 @@ local use of booktabs table style}% % 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@ - \gdef\CT@arc@{\color{sphinxTableRowColor% this is in fact Header color -% this crazy code relies on \color using here expansion only and it expands -% to "Odd" if #1 is one of \endfirsthead, \endhead or -% \sphinxtableatstartofbodyhook else it expands to nothing. +% \@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 - #1\endhead\sphinxtableatstartofbodyhook{Odd}% - \endfirsthead#1\sphinxtableatstartofbodyhook{Odd}% - \endfirsthead\endhead#1{Odd}% - \endfirsthead\endhead\sphinxtableatstartofbodyhook{}% +% 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 - }% end of crazy color name build - }% end of \CT@arc@ def + {\gdef\CT@arc@{\color{sphinxTableRowColor}}}% Header color + {\gdef\CT@arc@{\color{sphinxTableRowColorOdd}}}% }% end of \noalign - \specialrule{\belowrulesep}{\z@}{\z@}% already in a \noalign... + % \specialrule uses \noalign itself + \specialrule{\dimexpr\belowrulesep+\sphinxbooktabsspecialruleoverhang\relax}% + {\z@}{-\sphinxbooktabsspecialruleoverhang}% \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 @@ -1145,11 +1154,13 @@ local use of booktabs table style}% \noalign{\global\let\spx@@@@saved@CT@arc@\CT@arc@ \gdef\CT@arc@{\color{sphinxTableRowColor}}% this is RowColorHeader }% - \specialrule{\aboverulesep}{\z@}{\z@}% + \specialrule{\dimexpr\aboverulesep+\sphinxbooktabsspecialruleoverhang\relax\relax}% + {-\sphinxbooktabsspecialruleoverhang}{\z@}% \noalign{\global\let\CT@arc@\spx@@@@saved@CT@arc@}% \specialrule{\lightrulewidth}{\z@}{\z@}% \noalign{\gdef\CT@arc@{\color{sphinxTableRowColorOdd}}}% - \specialrule{\belowrulesep}{\z@}{\z@}% + \specialrule{\dimexpr\belowrulesep+\sphinxbooktabsspecialruleoverhang\relax\relax}% + {\z@}{-\sphinxbooktabsspecialruleoverhang}% \noalign{\global\let\CT@arc@\spx@@@@saved@CT@arc@}% }% \def\sphinxbooktabsbottomrule{% @@ -1164,7 +1175,8 @@ local use of booktabs table style}% \sphinxSwitchCaseRowColor{\numexpr\rownum-\@ne\relax}% \gdef\CT@arc@{\color{sphinxTableRowColor}}% holds current row colour }% - \specialrule{\aboverulesep}{\z@}{\z@}% + \specialrule{\dimexpr\aboverulesep+\sphinxbooktabsspecialruleoverhang\relax}% + {-\sphinxbooktabsspecialruleoverhang}{\z@}% \noalign{\global\let\CT@arc@\spx@@@@saved@CT@arc@}% \specialrule{\heavyrulewidth}{\z@}{\belowbottomsep}% }% From c816b7f050d3213497527f449662e9ea3749cf6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20B?= <2589111+jfbu@users.noreply.github.com> Date: Fri, 19 Aug 2022 20:30:19 +0200 Subject: [PATCH 12/16] Suppress expression of header row color in longtable continuations One reason in particular is that the colour is applied only up to the long table width, but the continuation hints may be larger than this width (but this width is hidden to not influence the table cells layout). --- sphinx/templates/latex/longtable.tex_t | 9 ++++++--- tests/roots/test-latex-table/expects/longtable.tex | 9 ++++++--- .../test-latex-table/expects/longtable_having_align.tex | 9 ++++++--- .../expects/longtable_having_caption.tex | 9 ++++++--- .../expects/longtable_having_problematic_cell.tex | 9 ++++++--- ...ongtable_having_stub_columns_and_problematic_cell.tex | 9 ++++++--- .../expects/longtable_having_verbatim.tex | 9 ++++++--- .../test-latex-table/expects/longtable_having_widths.tex | 9 ++++++--- .../longtable_having_widths_and_problematic_cell.tex | 9 ++++++--- .../expects/longtable_with_tabularcolumn.tex | 9 ++++++--- 10 files changed, 60 insertions(+), 30 deletions(-) diff --git a/sphinx/templates/latex/longtable.tex_t b/sphinx/templates/latex/longtable.tex_t index 9f722a71387..f5cb522cef3 100644 --- a/sphinx/templates/latex/longtable.tex_t +++ b/sphinx/templates/latex/longtable.tex_t @@ -44,8 +44,9 @@ <% endif -%> \endfirsthead -\multicolumn{<%= table.colcount %>}{c}% -{\makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} <%= _('continued from previous page') %>}}}\\ +\multicolumn{<%= table.colcount %>}{c}{\sphinxnorowcolor + \makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} <%= _('continued from previous page') %>}}% +}\\ \sphinxtoprule <%= ''.join(table.header) -%> <%- if table.header -%> @@ -54,7 +55,9 @@ \endhead \sphinxbottomrule -\multicolumn{<%= table.colcount %>}{r}{\makebox[0pt][r]{\sphinxtablecontinued{<%= _('continues on next page') %>}}}\\ +\multicolumn{<%= table.colcount %>}{r}{\sphinxnorowcolor + \makebox[0pt][r]{\sphinxtablecontinued{<%= _('continues on next page') %>}}% +}\\ \endfoot \endlastfoot diff --git a/tests/roots/test-latex-table/expects/longtable.tex b/tests/roots/test-latex-table/expects/longtable.tex index 7809aef464a..754d10249e1 100644 --- a/tests/roots/test-latex-table/expects/longtable.tex +++ b/tests/roots/test-latex-table/expects/longtable.tex @@ -16,8 +16,9 @@ \sphinxmidrule \endfirsthead -\multicolumn{2}{c}% -{\makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}}\\ +\multicolumn{2}{c}{\sphinxnorowcolor + \makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}% +}\\ \sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar @@ -30,7 +31,9 @@ \endhead \sphinxbottomrule -\multicolumn{2}{r}{\makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}}\\ +\multicolumn{2}{r}{\sphinxnorowcolor + \makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}% +}\\ \endfoot \endlastfoot 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 68ffac40296..dcf8f83a1a2 100644 --- a/tests/roots/test-latex-table/expects/longtable_having_align.tex +++ b/tests/roots/test-latex-table/expects/longtable_having_align.tex @@ -15,8 +15,9 @@ \sphinxmidrule \endfirsthead -\multicolumn{2}{c}% -{\makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}}\\ +\multicolumn{2}{c}{\sphinxnorowcolor + \makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}% +}\\ \sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar @@ -29,7 +30,9 @@ \endhead \sphinxbottomrule -\multicolumn{2}{r}{\makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}}\\ +\multicolumn{2}{r}{\sphinxnorowcolor + \makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}% +}\\ \endfoot \endlastfoot 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 232e8ecca42..dd2a87fa68f 100644 --- a/tests/roots/test-latex-table/expects/longtable_having_caption.tex +++ b/tests/roots/test-latex-table/expects/longtable_having_caption.tex @@ -17,8 +17,9 @@ \sphinxmidrule \endfirsthead -\multicolumn{2}{c}% -{\makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}}\\ +\multicolumn{2}{c}{\sphinxnorowcolor + \makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}% +}\\ \sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar @@ -31,7 +32,9 @@ \endhead \sphinxbottomrule -\multicolumn{2}{r}{\makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}}\\ +\multicolumn{2}{r}{\sphinxnorowcolor + \makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}% +}\\ \endfoot \endlastfoot 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 9c15d319ea0..8258612f50c 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 @@ -15,8 +15,9 @@ \sphinxmidrule \endfirsthead -\multicolumn{2}{c}% -{\makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}}\\ +\multicolumn{2}{c}{\sphinxnorowcolor + \makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}% +}\\ \sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar @@ -29,7 +30,9 @@ \endhead \sphinxbottomrule -\multicolumn{2}{r}{\makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}}\\ +\multicolumn{2}{r}{\sphinxnorowcolor + \makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}% +}\\ \endfoot \endlastfoot 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 21f36b50d78..44114ce78c2 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 @@ -18,8 +18,9 @@ \sphinxmidrule \endfirsthead -\multicolumn{3}{c}% -{\makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}}\\ +\multicolumn{3}{c}{\sphinxnorowcolor + \makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}% +}\\ \sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar @@ -35,7 +36,9 @@ \endhead \sphinxbottomrule -\multicolumn{3}{r}{\makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}}\\ +\multicolumn{3}{r}{\sphinxnorowcolor + \makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}% +}\\ \endfoot \endlastfoot 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 4e66d9e91a1..fc78914a9cf 100644 --- a/tests/roots/test-latex-table/expects/longtable_having_verbatim.tex +++ b/tests/roots/test-latex-table/expects/longtable_having_verbatim.tex @@ -15,8 +15,9 @@ \sphinxmidrule \endfirsthead -\multicolumn{2}{c}% -{\makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}}\\ +\multicolumn{2}{c}{\sphinxnorowcolor + \makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}% +}\\ \sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar @@ -29,7 +30,9 @@ \endhead \sphinxbottomrule -\multicolumn{2}{r}{\makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}}\\ +\multicolumn{2}{r}{\sphinxnorowcolor + \makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}% +}\\ \endfoot \endlastfoot 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 7b9cd11ba01..5bf1507a7a4 100644 --- a/tests/roots/test-latex-table/expects/longtable_having_widths.tex +++ b/tests/roots/test-latex-table/expects/longtable_having_widths.tex @@ -16,8 +16,9 @@ \sphinxmidrule \endfirsthead -\multicolumn{2}{c}% -{\makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}}\\ +\multicolumn{2}{c}{\sphinxnorowcolor + \makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}% +}\\ \sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar @@ -30,7 +31,9 @@ \endhead \sphinxbottomrule -\multicolumn{2}{r}{\makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}}\\ +\multicolumn{2}{r}{\sphinxnorowcolor + \makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}% +}\\ \endfoot \endlastfoot 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 6450a455d62..bf9192009ca 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 @@ -15,8 +15,9 @@ \sphinxmidrule \endfirsthead -\multicolumn{2}{c}% -{\makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}}\\ +\multicolumn{2}{c}{\sphinxnorowcolor + \makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}% +}\\ \sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar @@ -29,7 +30,9 @@ \endhead \sphinxbottomrule -\multicolumn{2}{r}{\makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}}\\ +\multicolumn{2}{r}{\sphinxnorowcolor + \makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}% +}\\ \endfoot \endlastfoot 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 40efe23e36b..6383d9d5667 100644 --- a/tests/roots/test-latex-table/expects/longtable_with_tabularcolumn.tex +++ b/tests/roots/test-latex-table/expects/longtable_with_tabularcolumn.tex @@ -16,8 +16,9 @@ \sphinxmidrule \endfirsthead -\multicolumn{2}{c}% -{\makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}}\\ +\multicolumn{2}{c}{\sphinxnorowcolor + \makebox[0pt]{\sphinxtablecontinued{\tablename\ \thetable{} \textendash{} continued from previous page}}% +}\\ \sphinxtoprule \sphinxstyletheadfamily \sphinxAtStartPar @@ -30,7 +31,9 @@ \endhead \sphinxbottomrule -\multicolumn{2}{r}{\makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}}\\ +\multicolumn{2}{r}{\sphinxnorowcolor + \makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}% +}\\ \endfoot \endlastfoot From 866692d41baaba264b6e26146a57fc603d13d7b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20B?= <2589111+jfbu@users.noreply.github.com> Date: Sat, 20 Aug 2022 15:33:32 +0200 Subject: [PATCH 13/16] Rename some macros to use no @, make colorgaps true per default This way, custom user replacement code for \sphinxbooktabs{top,mid,bottom}rule is relatively painless to inject in preamble or via container class. Also, it was needed to add some LaTeX code to the longtable template in order to avoid a colour-related problem with \sphinxbottomrule. The 'sphinxsetup' key now named booktabscolorgaps defaults to being true and is left only as a way to provide an easy "turn-off" if the issue with the longtable colours after the mid rule and above the bottom rule is blocking to some. But a priori I envision at 6.0.0 to simply remove this undocumented option as the said issue is not serious and more to be considered a fact-of-life. Besides using booktabs+colorrows is strictly opt-in at this time. I considered various LaTeX ways around this longtable thing (it constructs headers and footers once and for all, one can not let them depend on some "dynamic" context; there is no easy way for a body row to know it is first on the page after header, and anyway would require adding mark-up or considerably complicate the \everycr)) but none of them are even remotely reasonable. Also, a non-documented booktabsnogaps 'sphinxsetup' key has been added: it suppresses all the extra spacing booktabs injects around its top, mid, and bottom rules. Will solve the booktabs+colorrows+longtable conundrum from previous paragraph. --- doc/usage/configuration.rst | 7 - sphinx/templates/latex/longtable.tex_t | 2 +- sphinx/texinputs/sphinx.sty | 15 ++- sphinx/texinputs/sphinxlatextables.sty | 125 ++++++++++-------- .../test-latex-table/expects/longtable.tex | 2 +- .../expects/longtable_having_align.tex | 2 +- .../expects/longtable_having_caption.tex | 2 +- .../longtable_having_problematic_cell.tex | 2 +- ...ving_stub_columns_and_problematic_cell.tex | 2 +- .../expects/longtable_having_verbatim.tex | 2 +- .../expects/longtable_having_widths.tex | 2 +- ...ble_having_widths_and_problematic_cell.tex | 2 +- .../expects/longtable_with_tabularcolumn.tex | 2 +- 13 files changed, 97 insertions(+), 70 deletions(-) diff --git a/doc/usage/configuration.rst b/doc/usage/configuration.rst index 38234873c15..106a5ddc1f5 100644 --- a/doc/usage/configuration.rst +++ b/doc/usage/configuration.rst @@ -2294,13 +2294,6 @@ These options influence LaTeX output. 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_). - When using both ``'booktabs'`` and ``'colorrows'`` there is a small - white gap between the bottom row and the bottom rule, and between the - first body row and the (mid or top) rule above it. It is possible to - extend the background colouring to touch the rules, via some extra LaTeX - coding. This may be added to Sphinx in case of feature request, but - this whitespace is considered currently a quality rather than a defect. - .. _booktabs: https://ctan.org/pkg/booktabs .. _colortbl: https://ctan.org/pkg/colortbl .. _xcolor: https://ctan.org/pkg/xcolor diff --git a/sphinx/templates/latex/longtable.tex_t b/sphinx/templates/latex/longtable.tex_t index f5cb522cef3..27c887ab921 100644 --- a/sphinx/templates/latex/longtable.tex_t +++ b/sphinx/templates/latex/longtable.tex_t @@ -53,7 +53,7 @@ \sphinxmidrule <% endif -%> \endhead - +\noalign{\global\rownum2 }% \sphinxbottomrule \multicolumn{<%= table.colcount %>}{r}{\sphinxnorowcolor \makebox[0pt][r]{\sphinxtablecontinued{<%= _('continues on next page') %>}}% diff --git a/sphinx/texinputs/sphinx.sty b/sphinx/texinputs/sphinx.sty index 9f9555e6eec..748f8b977b1 100644 --- a/sphinx/texinputs/sphinx.sty +++ b/sphinx/texinputs/sphinx.sty @@ -124,7 +124,20 @@ will be set to white}% % Optional usage of booktabs package for tables \DeclareBoolOption[false]{booktabs} \DeclareBoolOption[false]{borderless} -\DeclareBoolOption[false]{booktabscolorizegaps} +\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 diff --git a/sphinx/texinputs/sphinxlatextables.sty b/sphinx/texinputs/sphinxlatextables.sty index 0b4315c2c11..1d90f12ce7a 100644 --- a/sphinx/texinputs/sphinxlatextables.sty +++ b/sphinx/texinputs/sphinxlatextables.sty @@ -980,12 +980,13 @@ \spx@original@@xcmidrule}% \fi } -% wrappers to allow ultimate customization, e.g. via a container class, of the -% widths (aka thickness) associated with the booktabs rule (advanced users may -% even employ \specialrule here to control vertical spacing). +% 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: @@ -1069,10 +1070,16 @@ local use of booktabs table style}% % in non-colorrows context } -% (not so easy) implementation of the booktabscolorizegaps option -% As it is used via \sphinxsetup its status is not known here and may -% change locally. So it must be implemented via delayed or conditional -% code. +% (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 @@ -1085,45 +1092,40 @@ local use of booktabs table style}% % % 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 colorizegaps is. -% -% We will use macros such as \sphinxbooktabstoprule which are supposedly -% customizable by user, but here we pre-empt them. Any modification will -% break our code... -% -% MEMO: if this is merged and default behaviour I should then use names such -% as \sphinxbooktabsspecialtoprule (or perhaps a better one) which would -% receive the meaning attributed below to \sphinxbooktabstoprule, and the code -% would do here once \def\sphinxbooktabstoprule{\sphinxbooktabsspecialtoprule} -% rather so a user custom one (or an option) could simply do for example -% \def\sphinxbooktabstoprule {\toprule or whatever} to undo this behaviour. -% Same for midrule and bottomrule. -\def\spx@ifbooktabscoloredgaps@TF{% - \if1\ifspx@opt@booktabscolorizegaps +% 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{% - \spx@ifbooktabscoloredgaps@TF - {\spx@booktabs@specialtoprule}% + \sphinxifbooktabswithcolorgapsTF + {\sphinxbooktabsspecialtoprule}% {\toprule}% }% -\def\sphinxbooktabsspecialruleoverhang{0.1pt}% avoid pixel/rounding effects +\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\spx@booktabs@specialtoprule\sphinxtabletoprulehook#1{% +\long\def\sphinxbooktabsspecialtoprule\sphinxtabletoprulehook#1{% \specialrule{\heavyrulewidth}{\abovetopsep}{\z@}% - \sphinxtabletoprulehook% contains color init code + % 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@ + \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 @@ -1134,52 +1136,71 @@ local use of booktabs table style}% \endfirsthead\endhead#1\@secondoftwo \endfirsthead\endhead\sphinxtableatstartofbodyhook\@firstoftwo \@nil - {\gdef\CT@arc@{\color{sphinxTableRowColor}}}% Header color + {\gdef\CT@arc@{\color{sphinxTableRowColor}}}% {\gdef\CT@arc@{\color{sphinxTableRowColorOdd}}}% }% end of \noalign % \specialrule uses \noalign itself - \specialrule{\dimexpr\belowrulesep+\sphinxbooktabsspecialruleoverhang\relax}% - {\z@}{-\sphinxbooktabsspecialruleoverhang}% - \noalign{\global\let\CT@arc@\spx@@@@saved@CT@arc@}% + \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{% - \spx@ifbooktabscoloredgaps@TF - {\spx@booktabs@specialmidrule}% + \sphinxifbooktabswithcolorgapsTF + {\sphinxbooktabsspecialmidrule}% {\midrule}% }% -\def\spx@booktabs@specialmidrule{% - \noalign{\global\let\spx@@@@saved@CT@arc@\CT@arc@ +\def\sphinxbooktabsspecialmidrule{% + \noalign{\global\let\spx@@saved@CT@arc@\CT@arc@ \gdef\CT@arc@{\color{sphinxTableRowColor}}% this is RowColorHeader }% - \specialrule{\dimexpr\aboverulesep+\sphinxbooktabsspecialruleoverhang\relax\relax}% - {-\sphinxbooktabsspecialruleoverhang}{\z@}% - \noalign{\global\let\CT@arc@\spx@@@@saved@CT@arc@}% + \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+\sphinxbooktabsspecialruleoverhang\relax\relax}% - {\z@}{-\sphinxbooktabsspecialruleoverhang}% - \noalign{\global\let\CT@arc@\spx@@@@saved@CT@arc@}% + \specialrule{\dimexpr\belowrulesep+\sphinxbooktabscolorgapsoverhang\relax\relax}% + {\z@}{-\sphinxbooktabscolorgapsoverhang}% + \noalign{\global\let\CT@arc@\spx@@saved@CT@arc@}% }% \def\sphinxbooktabsbottomrule{% - \spx@ifbooktabscoloredgaps@TF - {\spx@booktabs@specialbottomrule}% + \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 -\def\spx@booktabs@specialbottomrule{% - \noalign{\global\let\spx@@@@saved@CT@arc@\CT@arc@ +% 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 has not been reset and could be arbitrary. So we had +% to set it to "2" in the longtable templates :-(. Not "0" in order to avoid +% \sphinxSwitchCaseRowColor having to know how to handle negative inputs, +% although the Sphinx definition has no issue with that. (there is no easy +% official way from longtable to know the macro is expanded in a "foot" box). +% So 2-1=1 and in longtable the colour will always be the "Odd" one, except at +% very end of longtable, where it will match colour of the last row. +\def\sphinxbooktabsspecialbottomrule{% + \noalign{\global\let\spx@@saved@CT@arc@\CT@arc@ \sphinxSwitchCaseRowColor{\numexpr\rownum-\@ne\relax}% - \gdef\CT@arc@{\color{sphinxTableRowColor}}% holds current row colour + \gdef\CT@arc@{\color{sphinxTableRowColor}}% }% - \specialrule{\dimexpr\aboverulesep+\sphinxbooktabsspecialruleoverhang\relax}% - {-\sphinxbooktabsspecialruleoverhang}{\z@}% - \noalign{\global\let\CT@arc@\spx@@@@saved@CT@arc@}% + \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. diff --git a/tests/roots/test-latex-table/expects/longtable.tex b/tests/roots/test-latex-table/expects/longtable.tex index 754d10249e1..93b8dbae4df 100644 --- a/tests/roots/test-latex-table/expects/longtable.tex +++ b/tests/roots/test-latex-table/expects/longtable.tex @@ -29,7 +29,7 @@ \\ \sphinxmidrule \endhead - +\noalign{\global\rownum2 }% \sphinxbottomrule \multicolumn{2}{r}{\sphinxnorowcolor \makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}% 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 dcf8f83a1a2..1de4a05df60 100644 --- a/tests/roots/test-latex-table/expects/longtable_having_align.tex +++ b/tests/roots/test-latex-table/expects/longtable_having_align.tex @@ -28,7 +28,7 @@ \\ \sphinxmidrule \endhead - +\noalign{\global\rownum2 }% \sphinxbottomrule \multicolumn{2}{r}{\sphinxnorowcolor \makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}% 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 dd2a87fa68f..6540d3513d9 100644 --- a/tests/roots/test-latex-table/expects/longtable_having_caption.tex +++ b/tests/roots/test-latex-table/expects/longtable_having_caption.tex @@ -30,7 +30,7 @@ \\ \sphinxmidrule \endhead - +\noalign{\global\rownum2 }% \sphinxbottomrule \multicolumn{2}{r}{\sphinxnorowcolor \makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}% 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 8258612f50c..4874280dd35 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 @@ -28,7 +28,7 @@ \\ \sphinxmidrule \endhead - +\noalign{\global\rownum2 }% \sphinxbottomrule \multicolumn{2}{r}{\sphinxnorowcolor \makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}% 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 44114ce78c2..6a81f074c61 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 @@ -34,7 +34,7 @@ \\ \sphinxmidrule \endhead - +\noalign{\global\rownum2 }% \sphinxbottomrule \multicolumn{3}{r}{\sphinxnorowcolor \makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}% 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 fc78914a9cf..fa640229965 100644 --- a/tests/roots/test-latex-table/expects/longtable_having_verbatim.tex +++ b/tests/roots/test-latex-table/expects/longtable_having_verbatim.tex @@ -28,7 +28,7 @@ \\ \sphinxmidrule \endhead - +\noalign{\global\rownum2 }% \sphinxbottomrule \multicolumn{2}{r}{\sphinxnorowcolor \makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}% 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 5bf1507a7a4..77427c17a7d 100644 --- a/tests/roots/test-latex-table/expects/longtable_having_widths.tex +++ b/tests/roots/test-latex-table/expects/longtable_having_widths.tex @@ -29,7 +29,7 @@ \\ \sphinxmidrule \endhead - +\noalign{\global\rownum2 }% \sphinxbottomrule \multicolumn{2}{r}{\sphinxnorowcolor \makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}% 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 bf9192009ca..f38cc40d2ff 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 @@ -28,7 +28,7 @@ \\ \sphinxmidrule \endhead - +\noalign{\global\rownum2 }% \sphinxbottomrule \multicolumn{2}{r}{\sphinxnorowcolor \makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}% 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 6383d9d5667..63c2a78ee60 100644 --- a/tests/roots/test-latex-table/expects/longtable_with_tabularcolumn.tex +++ b/tests/roots/test-latex-table/expects/longtable_with_tabularcolumn.tex @@ -29,7 +29,7 @@ \\ \sphinxmidrule \endhead - +\noalign{\global\rownum2 }% \sphinxbottomrule \multicolumn{2}{r}{\sphinxnorowcolor \makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}% From cd5c20356ccf82662f40c08b4d5a931bb00f1aa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20B?= <2589111+jfbu@users.noreply.github.com> Date: Sat, 20 Aug 2022 19:02:59 +0200 Subject: [PATCH 14/16] Move \rownum reset away from longtable template into afterendhook This is better not to overload our template. Besides it makes it easier for user to use another longtable template. --- sphinx/templates/latex/longtable.tex_t | 2 +- sphinx/texinputs/sphinxlatextables.sty | 17 ++++++++++------- .../test-latex-table/expects/longtable.tex | 2 +- .../expects/longtable_having_align.tex | 2 +- .../expects/longtable_having_caption.tex | 2 +- .../longtable_having_problematic_cell.tex | 2 +- ...having_stub_columns_and_problematic_cell.tex | 2 +- .../expects/longtable_having_verbatim.tex | 2 +- .../expects/longtable_having_widths.tex | 2 +- ...table_having_widths_and_problematic_cell.tex | 2 +- .../expects/longtable_with_tabularcolumn.tex | 2 +- 11 files changed, 20 insertions(+), 17 deletions(-) diff --git a/sphinx/templates/latex/longtable.tex_t b/sphinx/templates/latex/longtable.tex_t index 27c887ab921..f5cb522cef3 100644 --- a/sphinx/templates/latex/longtable.tex_t +++ b/sphinx/templates/latex/longtable.tex_t @@ -53,7 +53,7 @@ \sphinxmidrule <% endif -%> \endhead -\noalign{\global\rownum2 }% + \sphinxbottomrule \multicolumn{<%= table.colcount %>}{r}{\sphinxnorowcolor \makebox[0pt][r]{\sphinxtablecontinued{<%= _('continues on next page') %>}}% diff --git a/sphinx/texinputs/sphinxlatextables.sty b/sphinx/texinputs/sphinxlatextables.sty index 1d90f12ce7a..247ad7a7674 100644 --- a/sphinx/texinputs/sphinxlatextables.sty +++ b/sphinx/texinputs/sphinxlatextables.sty @@ -892,6 +892,10 @@ \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 @@ -1174,13 +1178,12 @@ local use of booktabs table style}% % 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 has not been reset and could be arbitrary. So we had -% to set it to "2" in the longtable templates :-(. Not "0" in order to avoid -% \sphinxSwitchCaseRowColor having to know how to handle negative inputs, -% although the Sphinx definition has no issue with that. (there is no easy -% official way from longtable to know the macro is expanded in a "foot" box). -% So 2-1=1 and in longtable the colour will always be the "Odd" one, except at -% very end of longtable, where it will match colour of the last row. +% 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}% diff --git a/tests/roots/test-latex-table/expects/longtable.tex b/tests/roots/test-latex-table/expects/longtable.tex index 93b8dbae4df..754d10249e1 100644 --- a/tests/roots/test-latex-table/expects/longtable.tex +++ b/tests/roots/test-latex-table/expects/longtable.tex @@ -29,7 +29,7 @@ \\ \sphinxmidrule \endhead -\noalign{\global\rownum2 }% + \sphinxbottomrule \multicolumn{2}{r}{\sphinxnorowcolor \makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}% 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 1de4a05df60..dcf8f83a1a2 100644 --- a/tests/roots/test-latex-table/expects/longtable_having_align.tex +++ b/tests/roots/test-latex-table/expects/longtable_having_align.tex @@ -28,7 +28,7 @@ \\ \sphinxmidrule \endhead -\noalign{\global\rownum2 }% + \sphinxbottomrule \multicolumn{2}{r}{\sphinxnorowcolor \makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}% 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 6540d3513d9..dd2a87fa68f 100644 --- a/tests/roots/test-latex-table/expects/longtable_having_caption.tex +++ b/tests/roots/test-latex-table/expects/longtable_having_caption.tex @@ -30,7 +30,7 @@ \\ \sphinxmidrule \endhead -\noalign{\global\rownum2 }% + \sphinxbottomrule \multicolumn{2}{r}{\sphinxnorowcolor \makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}% 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 4874280dd35..8258612f50c 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 @@ -28,7 +28,7 @@ \\ \sphinxmidrule \endhead -\noalign{\global\rownum2 }% + \sphinxbottomrule \multicolumn{2}{r}{\sphinxnorowcolor \makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}% 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 6a81f074c61..44114ce78c2 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 @@ -34,7 +34,7 @@ \\ \sphinxmidrule \endhead -\noalign{\global\rownum2 }% + \sphinxbottomrule \multicolumn{3}{r}{\sphinxnorowcolor \makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}% 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 fa640229965..fc78914a9cf 100644 --- a/tests/roots/test-latex-table/expects/longtable_having_verbatim.tex +++ b/tests/roots/test-latex-table/expects/longtable_having_verbatim.tex @@ -28,7 +28,7 @@ \\ \sphinxmidrule \endhead -\noalign{\global\rownum2 }% + \sphinxbottomrule \multicolumn{2}{r}{\sphinxnorowcolor \makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}% 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 77427c17a7d..5bf1507a7a4 100644 --- a/tests/roots/test-latex-table/expects/longtable_having_widths.tex +++ b/tests/roots/test-latex-table/expects/longtable_having_widths.tex @@ -29,7 +29,7 @@ \\ \sphinxmidrule \endhead -\noalign{\global\rownum2 }% + \sphinxbottomrule \multicolumn{2}{r}{\sphinxnorowcolor \makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}% 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 f38cc40d2ff..bf9192009ca 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 @@ -28,7 +28,7 @@ \\ \sphinxmidrule \endhead -\noalign{\global\rownum2 }% + \sphinxbottomrule \multicolumn{2}{r}{\sphinxnorowcolor \makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}% 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 63c2a78ee60..6383d9d5667 100644 --- a/tests/roots/test-latex-table/expects/longtable_with_tabularcolumn.tex +++ b/tests/roots/test-latex-table/expects/longtable_with_tabularcolumn.tex @@ -29,7 +29,7 @@ \\ \sphinxmidrule \endhead -\noalign{\global\rownum2 }% + \sphinxbottomrule \multicolumn{2}{r}{\sphinxnorowcolor \makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}% From 97d2b49ef60acb0007c29a67f52eb8917945bedc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20B?= <2589111+jfbu@users.noreply.github.com> Date: Sun, 25 Sep 2022 08:25:22 +0200 Subject: [PATCH 15/16] Update CHANGES for PR #10759 --- CHANGES | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 4f97532014a..334d5cd34cc 100644 --- a/CHANGES +++ b/CHANGES @@ -13,6 +13,9 @@ Deprecated Features added -------------- +* #10759: LaTeX: add :confval:`latex_table_style` and support the + ``'booktabs'``, ``'borderless'``, and ``'colorrows'`` styles. + Bugs fixed ---------- @@ -41,8 +44,6 @@ Features added ``type of type``. Example: ``tuple of int``. * #10286: C++, support requires clauses not just between the template parameter lists and the declaration. -* #10759: LaTeX: add :confval:`latex_table_style` and support the - ``'booktabs'``, ``'borderless'``, and ``'colorrows'`` styles. * #10755: linkcheck: Check the source URL of raw directives that use the ``url`` option. * #10781: Allow :rst:role:`ref` role to be used with definitions and fields. From 31fd0bf656c60a306d587aee0e1f843f2437b647 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20B?= <2589111+jfbu@users.noreply.github.com> Date: Thu, 6 Oct 2022 22:29:18 +0200 Subject: [PATCH 16/16] Improve documentation of new latex_table_style regarding colours Remove in passing a note from latex.rst which was of no real use to Sphinx LaTeX users. --- doc/latex.rst | 29 +++++++++++++---------------- doc/usage/configuration.rst | 15 +++++++++++---- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/doc/latex.rst b/doc/latex.rst index 07186179ba3..e467ac4e9a8 100644 --- a/doc/latex.rst +++ b/doc/latex.rst @@ -877,24 +877,19 @@ Do not use quotes to enclose values, whether numerical or strings. .. versionadded:: 1.6.6 - .. note:: - - Starting with this colour, and for all others following, the - names declared to "color" or "xcolor" are prefixed with "sphinx". +.. _tablecolors: ``TableRowColorHeader`` - Sets the background colour for (all) the header rows. + Sets the background colour for (all) the header rows of tables. - This (as the other ``Table...`` colour keys) applies to all tables if - ``'colorrows'`` is contained in :confval:`latex_table_style`, except to - those with ``nocolorrows`` class; in absence of ``'colorrows'`` in - :confval:`latex_table_style` it will apply to tables with ``colorrows`` - class. + 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. - As for the other ``'sphinxsetup'`` keys, it can be set or modified inside - the document from a ``\sphinxsetup{...}`` LaTeX command inserted via the - :dudir:`raw` directive, or from a LaTeX environment associated to a - `container class `_. + 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 `_ and using such ``\sphinxsetup{...}``. Default: ``{gray}{0.86}`` @@ -904,8 +899,10 @@ Do not use quotes to enclose values, whether numerical or strings. .. versionadded:: 5.2.0 ``TableRowColorOdd`` - Sets the background colour for odd rows in tables (the row count starts - at ``1`` at the first non-header row). + 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}`` diff --git a/doc/usage/configuration.rst b/doc/usage/configuration.rst index cce595624a1..b2196a9e5af 100644 --- a/doc/usage/configuration.rst +++ b/doc/usage/configuration.rst @@ -2242,10 +2242,17 @@ These options influence LaTeX output. - ``'borderless'``: no lines whatsoever. - - ``'colorrows'``: the body rows are rendered with alternating background - colours, see the :ref:`latexsphinxsetup` keys ``TableRowColorOdd`` and - ``TableRowColorEven`` for configuration. And ``TableRowColorHeader`` - for the header rows. + - ``'colorrows'``: the table rows are rendered with alternating background + colours. The interface to customize them is via :ref:`dedicated keys + ` 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 ` keys. Default: ``[]``