I run into issues trying to markup tables semantically in LaTeX.
Background
Either standard \hline
together with \firsthline
and \lasthline
from array.sty
(I think)
or \midrule
, \toprule
and \bottomrule
from recommended booktabs.sty
visually structure tables (or rather tabulars). They’re not truly semantic markup, though. For that, one would identify header, footer and (possibly multiple) bodies as is done in HTML with <thead>
, <tfoot>
and <tbody>
respectively.
Neither header nor footer should be confused with the caption, but in LaTeX that’s unlikely anyhow, because there’s an intuitively named macro \caption
for that and it is only available for floating tables by default as it should be. The footer also is not the place for local footnotes (cf. the second mandatory parameter of \ctable
or the tablenotes
environment in threeparttable.sty
). Instead, the footer usually contains rows with column sums and the like. The header most often contains column labels in its cells, which may be arranged hierarchically over several rows.
The left-most and right-most columns may have roles similar to the top-most and bottom-most rows, but since tabulars in LaTeX (like HTML) are arranged vertically first that’s hard to encode. Nevertheless, due to the mandatory way columns are defined with tabular
it’s actually easier to apply some styling to all cells in a column than to a cells in a row. It’s the other way around in HTML+CSS.
You sometimes want the same tables to look quite different in two setups, e.g. a beamer presentation (\mode<presentation>
) and its handout (\mode<article>
). Therefore it makes sense to mark it up semantically and specify the styling per mode.
I asked about that in tabular
styled like blocks in beamer
based upon booktabs
markup, but did not get an answer.
Questions
- What kind of markup should I use (out of the ones described below)?
- How can I do it with environments instead of commands?
I’m afraid the answer to 1. is “environments” (i.e. the final variant), but at the same time the answer to 2. is ”you cannot”.
Patched tabular environment
\documentclass{scrartcl}
\usepackage{booktabs}
\let\oldtabular\tabular
\let\oldendtabular\endtabular
\renewcommand\tabular[1]{\oldtabular{#1}\toprule}
\renewcommand\endtabular{\bottomrule\oldendtabular}
\newcommand\tpart{\midrule}
\begin{document}
\begin{tabular}{ll}
Header & Header \\
\tpart
Body & Body \\
Body & Body \\
\tpart
Body & Body \\
\tpart
Footer & Footer \\
\end{tabular}
\end{document}
This simple approach works, but doesn’t show much explicit semantics.
Semantic table parts as switches
\documentclass{scrartcl}
\usepackage{booktabs}
\newcommand{\tHead}{\toprule}
\newcommand{\tFoot}{\midrule}
\newcommand{\tBody}{\midrule}
\newcommand{\tEnd}{\bottomrule}
\begin{document}
\begin{tabular}{ll}
\tHead
Header & Header \\
\tBody
Body & Body \\ Body & Body \\
\tBody
Body & Body \\
\tFoot
Footer & Footer \\
\tEnd
\end{tabular}
\end{document}
This kind of aliasing does “work”, but requires an additional command \tEnd
. This seems just wrong.
Patched tabular
with semantic table parts as switches
\documentclass{scrartcl}
\usepackage{booktabs}
\let\oldtabular\tabular
\let\oldendtabular\endtabular
\renewcommand\tabular[1]{\oldtabular{#1}\toprule}
\renewcommand\endtabular{\bottomrule\oldendtabular}
\newcommand{\tHead}{}
\newcommand{\tFoot}{\midrule}
\newcommand{\tBody}{\midrule}
\begin{document}
\begin{tabular}{ll}
\tHead
Header & Header \\
\tBody
Body & Body \\ Body & Body \\
\tBody
Body & Body \\
\tFoot
Footer & Footer \\
\end{tabular}
\end{document}
This method combines the two described above and thus disposes of \tEnd
.
Semantic table parts as macros with single parameters
\documentclass{scrartcl}
\usepackage{booktabs}
\newcommand{\Thead}[1]{\toprule #1 \midrule}
\newcommand{\Tfoot}[1]{#1 \bottomrule}
\newcommand{\Tbody}[1]{#1 \midrule}
\begin{document}
\begin{tabular}{ll}
\Thead{ Header & Header \\}
\Tbody{ Body & Body \\ Body & Body \\}
\Tbody{ Body & Body \\}
\Tfoot{ Footer & Footer \\}
\end{tabular}
\end{document}
This does work, but the commands can receive very long arguments so it’s easy to lose track of the closing curly brace or what it belongs to.
Single table macros with multiple parameters
\documentclass{scrartcl}
\usepackage{booktabs}
%% \Tabular{header}{body}{footer}
\newcommand{\Tabular}[3]{%
\toprule #1 \midrule #2 \midrule #3 \bottomrule}
\begin{document}
\begin{tabular}{ll}
\Tabular%
{ Header & Header \\}%
{ Body & Body \\ Body & Body \\}%
{ Footer & Footer \\}
\end{tabular}
\end{document}
This allows only a single table body.
Semantic table parts as environments
\documentclass{scrartcl}
\usepackage{booktabs}
\newenvironment{thead}{\toprule}{\midrule}
\newenvironment{tfoot}{}{\bottomrule}
\newenvironment{tbody}{}{\midrule}
\begin{document}
\begin{tabular}{ll}
\begin{thead} Header & Header \\ \end{thead}
\begin{tbody} Body & Body \\ Body & Body \\ \end{tbody}
\begin{tbody} Body & Body \\ \end{tbody}
\begin{tfoot} Footer & Footer \\ \end{tfoot}
\end{tabular}
\end{document}
This is my preferred approach but it does not work and I don’t know why exactly. Environments inside tabular
, especially when they shall contain multiple cells or – as in this case – even rows seem problematic in general. This is why I ask question 2.