5

How to define a formatting to use for (individual) rows of a table?

Example: (For each row) the first column is always bold, and the second column has an italic "title" and some text and possibly something more (e.g. a list). After each row I want to add some additional vertical space. Like so:

\documentclass[a4paper, 10pt]{scrartcl}

\begin{document}
  \begin{tabular*}{\textwidth}{p{0.4\textwidth}@{}p{0.6\textwidth}@{}}  
    \textbf{1st column entry, row 1} &  \textit{2nd column title} -- 2nd column entry, row 1 
                                        \begin{itemize}
                                            \item{some list}
                                            \item{items here}
                                        \end{itemize} \\
    \multicolumn{2}{c}{\vspace{2.0em}} \\
    \textbf{1st column entry, row 2} &  \textit{2nd column title} -- 2nd column entry, row 2
                                        \newline (maybe only a note here) \\
    \multicolumn{2}{c}{\vspace{2.0em}} \\
  \end{tabular*}
\end{document}

For a large document with a lot of these tables, it is quite tedious to write all of these formatting commands. What I would like to do is to define a \newenvironment such that each row of the table can be entered like this

\begin{TableRow}{1st column entry}{2nd column title}{2nd column entry}
  %more stuff here, like, e.g., a list:
  \begin{itemize}
    \item{some}
    \item{items}
  \end{itemize}
\end{TableRow}

Note that I want to define the layout just for the text of the rows. Such that I can use the environment in each 2-column table, regardless of the column-widths.

This is my non-working attempt so far:

\documentclass[a4paper, 10pt]{scrartcl}

\newenvironment{TableRow}[3]
{
  \textbf{#1} & \textit{#2} -- #3
}
{
  \\
  \multicolumn{2}{c}{\vspace{2.0em}} \\
}

\begin{document}
  \begin{tabular*}{\textwidth}{p{0.4\textwidth}@{}p{0.6\textwidth}@{}}  
    \begin{TableRow}{1st column entry, row 1}{2nd column title}{2nd column entry, row 1}
      \begin{itemize}
        \item{some}
        \item{items}
      \end{itemize} \\
    \end{TableRow}

    \begin{TableRow}{1st column entry, row 2}{2nd column title}{2nd column entry, row 2}
        \newline (maybe only a note here) \\
    \end{TableRow}

  \end{tabular*}
\end{document}

In my minimal example, there are 24 errors, the first of which is "! Extra } or forgotten \endgroup".

(I suspect, that the 2nd block of my \newenvironment definition is also faulty ("\\"?) but I also get this error, when I leave the 2nd block empty.)

  • It seems like what I am looking for is a command with parameters that just simply fills in the parameters in the code and pastes the code into the document before "Latex-evaluating" it. Is there such a thing? – stack_horst Apr 4 '15 at 12:41
4

You can't have a normal environment to straddle two table cells, because you would have \begin{env} in one cell and \end{env} in another one and cells form groups.

You can do what you want with environ and \aftergroup trickery:

\documentclass[a4paper, 10pt]{scrartcl}

\usepackage{environ}

\NewEnviron{TableRow}[3]{%
  \toks0=\expandafter{\BODY}%
  \toks2={\textbf{#1} & \textit{#2} -- #3}%
  \xdef\TableRowContents{\the\toks2 \the\toks0 }%
  \aftergroup\TableRowContents
}

\begin{document}

\noindent
\begin{tabular}{@{}p{0.4\textwidth}@{}p{0.6\textwidth}@{}}
\begin{TableRow}{1st column entry, row 1}{2nd column title}{2nd column entry, row 1}
  \begin{itemize}
  \item{some list}
  \item{items here}
  \end{itemize}
\end{TableRow}
\\[3ex]
\begin{TableRow}{1st column entry, row 2}{2nd column title}{2nd column entry, row 2}
  \newline (maybe only a note here)
\end{TableRow}
\end{tabular}
\end{document}

Note that \multicolumn{2}{c}{\vspace{2em}}\\ is the wrong way to add vertical space between rows: \\[<dimen>] is the correct method.

Also a tabular* doesn't seem necessary, as you're filling the text width anyway.

enter image description here

The TableRow environment defined via \NewEnviron grabs the content, then builds the table row in a macro that is delivered after the implicit group started by \begin{TableRow} has ended, using \aftergroup.

  • Works like a charm, thank you. Also for explaining HOW it works. Two Questions: 1) "\multicolumn{2}{c}{\vspace{2em}}\\ is the wrong way to add vertical space between rows" because it additionally adds the inter-row-spacing? 2) Is there any way to also include the \\[3ex] in the definition so you don't need to type it after each table row? – stack_horst Apr 4 '15 at 12:51
  • 2
    @stack_horst It could be added automatically, but it would also be after the last row. If you want it, just add \noexpand\\[3ex] after \the\toks0 (leaving a space before \noexpand). The “wrong method” also adds a full row height. – egreg Apr 4 '15 at 12:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.