6

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.)

1
  • 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? Apr 4, 2015 at 12:41

1 Answer 1

6

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.

2
  • 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? Apr 4, 2015 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, 2015 at 12:58

You must log in to answer this question.

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