2

Inspired by the answer https://tex.stackexchange.com/a/37484, I tried to create a table with a key-value interface. Using \pgfkeys only outside of the tabular environment works as intended, but if it is used inside the environment, it starts an additional row as in my first and second approach:

\documentclass{article}
\usepackage{pgfkeys, pgffor}

% set up
\pgfkeys{table/.is family, table, 
    list of fields/.initial={foo, bar},
    add field/.style={#1/.value required, #1/.initial={undefined}},
    add field/.list/.expanded=\pgfkeysvalueof{/table/list of fields}
}

% first approach
\pgfkeys{table,
    print row/.code = {#1 & \pgfkeysvalueof{/table/#1} \\\hline},
    print table/.style = {print row/.list/.expanded = \pgfkeysvalueof{/table/list of fields}}
}

% second approach
\pgfkeys{table,
    content/.initial={},
    print content/.code=\pgfkeysvalueof{/table/content},
    add row/.style = {
        % 3 pairs of braces are needed if pgfkeys is called within a table
        content/.append={{{#1 & \pgfkeysvalueof{/table/#1} \\\hline}}},
    }, 
    fill content/.style = {add row/.list/.expanded = \pgfkeysvalueof{/table/list of fields}},
    create table/.style = {fill content, print content}
}

\parindent=0pt 
\begin{document}
    \pgfkeys{table, foo=1}

    first approach:\\
    \begin{tabular}{|l | l |}
        \hline
        \pgfkeys{table, print table}%
    \end{tabular}       

    \bigskip    
    second approach:\\
    \begin{tabular}{|l | l |}
        \hline
        \pgfkeys{table, create table}% here 3 braces are needed, see above
    \end{tabular}

    \bigskip
    use key directly:\\
    \pgfkeys{table, fill content}% would work with single pair of braces
    \begin{tabular}{|l | l |}
        \hline
        \pgfkeysvalueof{/table/content}
    \end{tabular}

\end{document}

What causes the additional row and how can it be removed? Also I wonder why three pairs of braces are necessary for appending a row inside the table, while normally it works fine with just a single pair.

Edit:

I realized that many things can add a new row at the end of a table, e.g.,

\begin{tabular}{|l|l|}
    \hline
    a & b \\\hline\relax
\end{tabular}

It seems that the following hack works, but I guess avoiding \pgfkeys at the end of a table is the easier solution:

\pgfkeys{table,
    print head/.code = {\begin{tabular}{|l | l |}\hline\bgroup},
    print foot/.code = {\egroup\end{tabular}},
    print row/.code = {\egroup#1 & \pgfkeysvalueof{/table/#1} \\\hline\noalign\bgroup},
    print table/.style = {print head, print row/.list/.expanded = \pgfkeysvalueof{/table/list of fields}, print foot}
}

\pgfkeys{table, print table}
tim
  • 501
  • you are trying to reinvent the pgfplotstable package. – percusse Apr 11 '16 at 18:05
  • Maybe the pgfplotstable package can be used as well for the underlying problem, i.e., providing a macro like \createtable{field1 = foo, field2 = bar, ...}. But this was already solved in the answer I referenced in the beginning. In this question, I just wanted to understand the special behavior of \pgfkeys inside the tabular environment, as I use it a lot and was suprised that my approaches didn't work. – tim Apr 11 '16 at 19:17
  • I agree that pgfplotstable provides a nice interface for the input of tabled data. However, if I want to handle missing or misspelled entries, I don't know how to do that with pgfplotstable, but it can be done easily with pgfkeys. – tim Apr 12 '16 at 18:06

1 Answers1

1

After some trial and error I have learned that all(?) but empty commands add an additional row if they are called at the end of a tabular environment, even if they have no visible effect on the output otherwise. An arbitrary example is:

\begin{tabular}{|l | l |}
    \hline
    a & b \\\hline\stepcounter{count}
\end{tabular}

Table with additional row

If one does not want to avoid a command at the end of the last row, \noalign can be used to suppress the additional row, e.g.,

\begin{tabular}{|l | l |}
    \hline
    a & b \\\hline\noalign{\stepcounter{count}}
\end{tabular}

This can even be used from inside \pgfkeys, see the edit of my question. A simple example for this is:

\pgfkeys{row/.code={a & b\\\noalign\bgroup}}
\begin{tabular}{|l | l |}
    \hline
    \pgfkeys{row}\egroup
    \hline
\end{tabular}

I am still interested in an explanation, but at the moment I will just accept this as another mystery of (La)Tex.

tim
  • 501