[Tex/LaTex] How to trim the length of \toprule

booktabsrulestables

I want to be able to trim the left and the right of a \toprule and \bottomrule as you can do with \cmidrule(lr){<column range>}. My attempted solution using \cmidrule[\heavyrulewidth]{<column range>} comes pretty close, but unfortunately does not quite align vertically with what a \toprule/\bottomrule produces.

So, the desired output is the table on the left (which uses \MyToprule and \MyBottomrule), but with the vertical alignment of the table on the right (which uses \toprule and \bottomrule).

enter image description here

Note:

  • This question was asked before as How to trim the length of \toprule?, but that was closed as a duplicate either because the title was not exactly what was desired or a workaround was sufficient.
  • If there is an easier way to obtain the desired output that would be useful.

Code:

\documentclass{article}
\usepackage{booktabs}

\newcounter{MyCounter}

\newcommand*{\NumberRow}{\stepcounter{MyCounter}\arabic{MyCounter}.}%
\newcommand*{\MyToprule}[1]{% #1 = 2-<last column>
    \cmidrule[\heavyrulewidth]{#1}%
}%
\newcommand*{\MyBottomrule}[1]{% #1 = 2-<last column>
    \cmidrule[\heavyrulewidth]{#1}%
}%
\newenvironment{MyTabular}[2][]{%
    \setcounter{MyCounter}{0}%
    \tabular[#1]{#2}%
}{%
    \endtabular
}%

\newcommand*{\TabularContent}{%
               & Item Heading & Text Heading \\
               \cmidrule(lr){2-2}
               \cmidrule(lr){3-3}
    \NumberRow & Item 1  & Some Text \\
               & Item 1a & Some other Text \\
    \NumberRow & Item 2  & Some Text \\
}%


\begin{document}
\begin{MyTabular}{cll}
    \MyToprule{2-3}
       &\multicolumn{2}{c}{Using MyToprule and MyBottomrule} \\
       \TabularContent
    \MyBottomrule{2-3}
\end{MyTabular}%
\begin{MyTabular}{cll}
    \toprule
       &\multicolumn{2}{c}{Using toprule and bottomrule} \\
       \TabularContent
    \bottomrule
\end{MyTabular}%
\end{document}

Best Answer

I'm not sure why you'd want such a layout: the top and bottom rules are meant to delimit the table from the context, so they should cover also the row numbers. The column with row numbers can have no header, if the role of numbers is clear either from the caption or the headers above the other columns.

If you want to go on with this, just don't define \MyToprule and \MyBottomrule to have an argument and leave to \cmidrule the scanning for arguments.

Note that I fixed the definition of MyTabular for the treatment of the optional argument.

\documentclass{article}
\usepackage{booktabs}

\newcounter{MyCounter}

\newcommand*{\NumberRow}{\stepcounter{MyCounter}\arabic{MyCounter}.}

\newcommand*{\MyToprule}{%
  \cmidrule[\heavyrulewidth]%
}

\newcommand*{\MyBottomrule}{%
  \cmidrule[\heavyrulewidth]%
}
\newenvironment{MyTabular}[2][c]{% Default is centering
    \setcounter{MyCounter}{0}%
    \tabular[#1]{#2}%
}{%
    \endtabular
}

\newcommand*{\TabularContent}{%
               & Item Heading & Text Heading \\
               \cmidrule(lr){2-2}
               \cmidrule(lr){3-3}
    \NumberRow & Item 1  & Some Text \\
               & Item 1a & Some other Text \\
    \NumberRow & Item 2  & Some Text \\
}


\begin{document}
\begin{MyTabular}{rll}
\MyToprule(lr){2-3} & \multicolumn{2}{c}{Using MyToprule} \\
\TabularContent
\MyBottomrule(lr){2-3}
\end{MyTabular}
\end{document}

(I changed the double column header to avoid it adding space to the second column.)

enter image description here


Fancier version where the vertical alignment is the same for the customized environment and the normal one (assuming default values for the parameters of booktabs).

\documentclass{article}
\usepackage{booktabs,xparse}

\newcounter{MyCounter}

\newcommand*{\NumberRow}{\stepcounter{MyCounter}\arabic{MyCounter}.}

\newcommand*{\MyToprule}{%
  \addlinespace[-\aboverulesep]%
  \addlinespace[\heavyrulewidth]
  \addlinespace[-2\cmidrulewidth]
  \cmidrule[\heavyrulewidth]%
}

\DeclareExpandableDocumentCommand{\MyBottomrule}{d()m}{%
  \IfNoValueTF{#1}
   {\cmidrule[\heavyrulewidth]{#2}}
   {\cmidrule[\heavyrulewidth](#1){#2}}%
  \addlinespace[-\belowrulesep]
}
\newenvironment{MyTabular}[2][c]{%
    \setcounter{MyCounter}{0}%
    \tabular[#1]{#2}%
}{%
    \endtabular
}

\newcommand*{\TabularContent}{%
               & Item Heading & Text Heading \\
               \cmidrule(lr){2-2}
               \cmidrule(lr){3-3}
    \NumberRow & Item 1  & Some Text \\
               & Item 1a & Some other Text \\
    \NumberRow & Item 2  & Some Text \\
}


\begin{document}
\setlength{\parindent}{0pt} % just for the example

Top alignment:

\begin{MyTabular}[t]{rll}
\MyToprule(lr){2-3} & \multicolumn{2}{c}{Using MyToprule} \\
\TabularContent
\MyBottomrule(lr){2-3}
\end{MyTabular}\quad
\begin{tabular}[t]{rll}
\toprule & \multicolumn{2}{c}{Using MyToprule} \\
\TabularContent
\bottomrule
\end{tabular}

\bigskip

Center alignment:\medskip

\begin{MyTabular}{rll}
\MyToprule(lr){2-3} & \multicolumn{2}{c}{Using MyToprule} \\
\TabularContent
\MyBottomrule(lr){2-3}
\end{MyTabular}\quad
\begin{tabular}{rll}
\toprule & \multicolumn{2}{c}{Using MyToprule} \\
\TabularContent
\bottomrule
\end{tabular}

\bigskip

Bottom alignment:\medskip

\begin{MyTabular}[b]{rll}
\MyToprule(lr){2-3} & \multicolumn{2}{c}{Using MyToprule} \\
\TabularContent
\MyBottomrule(lr){2-3}
\end{MyTabular}\quad
\begin{tabular}[b]{rll}
\toprule & \multicolumn{2}{c}{Using MyToprule} \\
\TabularContent
\bottomrule
\end{tabular}

\end{document}

enter image description here