3

Why does \@ifnextchar\end{tabular}{}{\midrule} not work while \midrule works fine within tables?

I am interested especially in a canonical answer to satisfy my curiosity.

However, my intention was to write code that automatically eliminates the \hline after the last row. I am open to suggestions.

Code

\documentclass{article}
\usepackage{fontspec}% xelatex
\usepackage{booktabs}% \midrule

\catcode`@=11 % or \makeatletter to change category code of @ to 11 and temporarily to access kernel macro \@tabularcr
\let \clone@tabularcr \@tabularcr
\def\@tabularcr{\clone@tabularcr \midrule}% first version
%\def\@tabularcr{\clone@tabularcr \@ifnextchar\end{tabular}{}{}}% <-- this line works, injecting no tokens
%\def\@tabularcr{\clone@tabularcr \@ifnextchar\end{tabular}{}{\midrule}}% <-- this does not work, injecting hopefully just a \midrule as in first version
\catcode`@=12 % or \makeatother to restore category code of @ to 12

\begin{document}
\begin{tabular}{lll}
Meaning & col2 & col3 \\
\meaning\\ & col2 & col3 \\
col1 & col2 & col3 \\
\end{tabular}
\end{document}
5
  • 1
    To begin with, you're saying that if the next token is \end, then {tabular} should be used, otherwise nothing. But it's not the only problem.
    – egreg
    Nov 14, 2016 at 13:02
  • Perhaps \let\cloneendtabular\endtabular \def\endtabular{\midrule\cloneendtabular} would accomplish your goal instead. Nov 14, 2016 at 13:05
  • @StevenB.Segletes Nice suggestion. I will consider it, although I am not sure I want to take that route for compatibility reasons. It depends on the document I suppose. Nov 14, 2016 at 13:10
  • @egreg I was thinking of macros being one token when I typed \end{tabular}, but of course \end is the macro! \endtabular is what I should have written. Nov 14, 2016 at 13:14
  • @macmadness86 There's no expansion done by \@ifnextchar so \endtabular would not be seen at all. However, the main problem is that you're starting a cell, because \@ifnextchar does assignments, so it is too late for adding \midrule.
    – egreg
    Nov 14, 2016 at 13:15

1 Answer 1

4

The error is

! Misplaced \noalign.
\midrule ->\noalign 

which isn't that related to \@ifnextchar you get the same from

\documentclass{article}
\usepackage{fontspec}% xelatex
\usepackage{booktabs}% \midrule

\begin{document}
\begin{tabular}{lll}
Meaning & col2 & col3 \\
\meaning\\ & col2 & col3 \\
col1 & col2 & col3 \\
\relax\midrule
\end{tabular}
\end{document}

\midrule like \hline and several other table commands must be the first thing in the row (after expansion) as it uses the \noalign primitive.

So any non-expandable token will generate an error, \@ifnextchar involves several \def assignments internally while making the tests.

2
  • Exactly what I was looking for. When \@ithnextchar is expanded, some \defs (non-expandable) are put before \noalign and trigger an error. My idea then would be to use TeX or TeX wrapped in a LaTeX macro to check for \endtabular (or whatever the closing token is). e.g. \futurelet or something. I rarely need to do that, so I'd have to do some self-study. tug.org/TUGboat/tb09-3/tb22bechtolsheim.pdf Nov 14, 2016 at 15:18
  • @macmadness86 \futurelet is non expandable so you can't use that (unless you hide it in \noalign) Nov 14, 2016 at 15:29

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .