Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for booktabs-style tables to LaTeX builder #6666

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 10 additions & 0 deletions doc/usage/configuration.rst
Expand Up @@ -2241,6 +2241,16 @@ 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_elements

.. versionadded:: 0.5
Expand Down
2 changes: 2 additions & 0 deletions sphinx/builders/latex/__init__.py
Expand Up @@ -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
Expand Down Expand Up @@ -517,6 +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_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])
Expand Down
3 changes: 3 additions & 0 deletions sphinx/templates/latex/latex.tex_t
Expand Up @@ -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}
Expand Down
23 changes: 15 additions & 8 deletions sphinx/templates/latex/longtable.tex_t
Expand Up @@ -10,25 +10,32 @@
<%- if table.caption -%>
\sphinxthelongtablecaptionisattop
\caption{<%= ''.join(table.caption) %>\strut}<%= labels %>\\*[\sphinxlongtablecapskipadjust]
\hline
\sphinxtoprule
<% elif labels -%>
\hline\noalign{\phantomsection<%= labels %>}%
\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') %>}}}\\
\hline
<%= ''.join(table.header) %>
\sphinxtoprule
<%= ''.join(table.header) -%>
<%- if table.header -%>
\sphinxmidrule
<% endif -%>
\endhead

\hline
\sphinxbottomrule
\multicolumn{<%= table.colcount %>}{r}{\makebox[0pt][r]{\sphinxtablecontinued{<%= _('continues on next page') %>}}}\\
\endfoot

\endlastfoot
<%= ''.join(table.body) %>
<%= ''.join(table.body) -%>
\sphinxbottomrule
\end{longtable}\sphinxatlongtableend\end{savenotes}
10 changes: 7 additions & 3 deletions sphinx/templates/latex/tabular.tex_t
Expand Up @@ -19,9 +19,13 @@
\phantomsection<%= labels %>\nobreak
<% endif -%>
\begin{tabular}[t]<%= table.get_colspec() -%>
\hline
<%= ''.join(table.header) %>
<%=- ''.join(table.body) %>
\sphinxtoprule
<%= ''.join(table.header) -%>
<%- if table.header -%>
\sphinxmidrule
<%- endif -%>
<%=- ''.join(table.body) -%>
\sphinxbottomrule
\end{tabular}
\par
\sphinxattableend\end{savenotes}
10 changes: 7 additions & 3 deletions sphinx/templates/latex/tabulary.tex_t
Expand Up @@ -19,9 +19,13 @@
\phantomsection<%= labels %>\nobreak
<% endif -%>
\begin{tabulary}{\linewidth}[t]<%= table.get_colspec() -%>
\hline
<%= ''.join(table.header) %>
<%=- ''.join(table.body) %>
\sphinxtoprule
<%= ''.join(table.header) -%>
<%- if table.header -%>
\sphinxmidrule
<%- endif -%>
<%=- ''.join(table.body) -%>
\sphinxbottomrule
\end{tabulary}
\par
\sphinxattableend\end{savenotes}
33 changes: 33 additions & 0 deletions sphinx/texinputs/sphinx.sty
Expand Up @@ -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}
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
35 changes: 21 additions & 14 deletions 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:
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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 ---
Expand Down