2

I know that \\ is a very overloaded command in LaTeX, but what exactly does it do in the tabular environment?

Following my previous question, I have redefined the description environment, effectively as a shorthand for tabular cells:

\documentclass{article}

\usepackage{environ}

\newcommand{\itemwithoptarg}[1][]{#1 &}

\let\olditem\item% Capture current definition of \item
\newcommand{\restoreitem}{\global\let\item\olditem}

\RenewEnviron{description}{%
  \gdef\item{\itemwithoptarg}% Global redefinition of \item
  \global\let\BODY\BODY% Make \BODY global
  \aftergroup\BODY% Print \BODY after description environment closes
  \aftergroup\restoreitem% Restore original \item (if you use lists, for example)
}
  
\begin{document}
\begin{tabular}{ p{6em} l }
\begin{description}
\item[2019] An entry \\
\item[2021] A later entry \\
\end{description}
\end{tabular}
\end{document}

I use this a lot in the document I'm working on, with short entries, so I thought it might be handy to code away the need for \\ at the end of each line. That shouldn't be too hard right?

Unfortunately I can't find the exact question where I found a solution very similar to this, but it looked like this:

\documentclass{article}

\usepackage{environ}

\newcommand{\itemwithoptarg}[1][]{#1 &}

\let\olditem\item% Capture current definition of \item
\newcommand{\restoreitem}{\global\let\item\olditem}

\RenewEnviron{description}{%
  \gdef\item{\itemwithoptarg}% Global redefinition of \item
  \global\let\BODY\BODY% Make \BODY global
  \aftergroup\BODY% Print \BODY after description environment closes
  \aftergroup\restoreitem% Restore original \item (if you use lists, for example)
}
  
\begin{document}
\let\par=\cr
\obeylines
\begin{tabular}{ p{6em} l }
\begin{description}
\item[2019] An entry
\item[2021] A later entry
\end{description}
\end{tabular}
\end{document}

Since \obeylines just appends \par to every line, this just redefines \par to be a separator for tables, then invokes \obeylines.

But this doesn't work -- the document won't compile. I then tested this by going back to the first MWE and replacing every \\ with \cr. This failed with similar errors. I don't know enough about LaTeX to be sure, but I imagine \obeylines is working fine, and the problem is that I haven't redefined \par correctly.

So, what does \\ do in the tabular environment (to which I should redefine \par)? How could I have found this? I tried both \meaning and \show but they both gave me errors, and I don't know much about the internals of LaTeX.

5
  • What's wrong with a simple, enumitem-based approach, such as the following? \documentclass{article} \usepackage{enumitem} \begin{document} \begin{description}[leftmargin=6em,style=nextline, font=\normalfont] \item[2019] An entry \item[2021] A later entry \item[long text] Another entry with a very long text that takes up more than one line. \end{description} \end{document}.
    – leandriis
    Jul 22, 2021 at 11:00
  • 2
    This code results in the following output: i.stack.imgur.com/rrSoc.png which looks quite similar to the one you get with your code, but has the added benefit that longer text does not overflow into the right margin, as it would be the case in your tabular-based approach.
    – leandriis
    Jul 22, 2021 at 11:03
  • Enumerate, or other alternatives are also better because allow page breaks in long list (and you don't have to finish each rows with \\ )
    – Fran
    Jul 22, 2021 at 11:32
  • It seems that \item[xyz] as a shorthand for xyz & is not actually shorter?
    – Marijn
    Jul 22, 2021 at 12:11
  • I see no reason at all for using a tabular here.
    – egreg
    Jul 22, 2021 at 16:54

1 Answer 1

1

As mentioned in the comments there are easier and more robust ways to do this.

However, since you have control over what happens at the start of \item, you can make this approach work by adding \\ before an item, which will end the previous tabular row. This is as easy as \gdef\item{\\\itemwithoptarg} without the need for \obeylines or redefining \par.

With this approach no \\ is added after the last entry, but that is actually optional in a tabular so that is not a problem. However, there is also a \\ added before the first entry, which causes unwanted vertical space above the table.

To solve that issue you can create a command that redefines itself to be \\, and use this command at the start of \item. This means that the first time the command is called nothing is done except for the redefinition, and all subsequent calls result in adding \\. At the end of the environment (in the third optional argument to \RenewEnviron) you can reset the command for the next table.

MWE:

\documentclass{article}

\usepackage{environ}

\newcommand{\itemwithoptarg}[1][]{#1 &}

\let\olditem\item% Capture current definition of \item
\newcommand{\restoreitem}{\global\let\item\olditem}

\gdef\notfirst{\gdef\notfirst{\\}}
\RenewEnviron{description}{%
  \gdef\item{\notfirst\itemwithoptarg}% Global redefinition of \item
  \global\let\BODY\BODY% Make \BODY global
  \aftergroup\BODY% Print \BODY after description environment closes
  \aftergroup\restoreitem% Restore original \item (if you use lists, for example)
}[\gdef\notfirst{\gdef\notfirst{\\}}] % reset \notfirst for next table
  
\begin{document}
Before table

\begin{tabular}{p{6em}l}
\begin{description}
\item[2019] An entry
\item[2021] A later entry
\item[2022] A future entry
\end{description}
\end{tabular}

after table
\end{document}

Result:

enter image description here

You must log in to answer this question.

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