[Tex/LaTex] Dec sep align & string type cell incompatibility

pgfplotstablevertical alignment

I would like to use the dec sep align feature of pgfplotstable
while having certain cells containing text.
I tried this:

\documentclass{article}

\usepackage{pgfplotstable}
\usepackage{booktabs}

\begin{document}

\pgfplotstabletypeset[%
col sep=&, row sep=\\,header=false,
every head row/.style={before row={\toprule}, after row={\midrule}},
every last row/.style={after row=\bottomrule},
display columns/0/.style={column name={A}, string type, column type={l}},
display columns/1/.style={column name={B}, dec sep align={l}},
display columns/2/.style={column name={C}, dec sep align={l}},
every row 2  column 1/.style={string type},
every row 3  column 1/.style={string type},
]
{%
  Xyzzy ! &     208.5  &   42.01  \\
  Nothing &    7.91  &   42.1  \\
  Happens &     --   &   200.2 \\
  \ldots  &      z   &  4.54 \\
}
\end{document}

But the result turned out to be this :

Buggy table

Do you know why the separations between the text cell and the next get
swallowed?
How could I correct this behaviour?
I would welcome any suggestion that allows to produce a correctly spaced tables (with alignment on the decimal separator), even if I must part with pgfplotable for that particular one.
I would rather stick to it though so that I can keep most of my tables as is.

I exised my previous edit to make another question (see here) for fear it would be too confusing to have them together

Best Answer

The dec sep align splits its column into two sub-columns (one each for the number part before and after the decimal separator). Normally, pgfplotstable checks whether the number in a cell has a decimal separator, and if it doesn't, an empty cell is added as a placeholder for the decimal part. When you set string type for a single cell, that check doesn't take place, and the placeholder cell (which is just an &) is not added. pgfplotstable still assumes the dec sep align column to always contain two cells, though, so the first cell of the next column is used instead of the placeholder cell.

So, we'll have to add an empty placeholder cell in manually. We can't just put a & after the string in the table, because that would throw the column count off, so we'll have to be a bit more sneaky: There's a postproc cell content key, which allows us to add stuff to a cell after it's been processed. Just adding a & here wouldn't work either, though, because that would add two &s (because, as mentioned above, pgfplotstable still assumes that there are two cells in a dec sep align column, and the postproc cell content key is executed for both of these cells). Luckily, there's a macro called \pgfplotstablepartno which contains the index of the current "sub-cell", it's 0 for the part before and 1 for the part after the decimal separator. This can be used in an \ifnum to only add one &.

Wrapping that in a new style, we get

\pgfkeys{
    /pgfplots/table/string type in dec sep align/.style={
        string type,
        postproc cell content/.code={%
            \ifnum\pgfplotstablepartno=0%
                \pgfkeys{/pgfplots/table/@cell content/.add={}{&}}
            \fi
        }%
    }
}

which allows us to set a single cell in a dec sep align column to string type in dec sep align. That results in the desired output:

\documentclass{article}

\usepackage{pgfplotstable}
\usepackage{booktabs}



\begin{document}

\pgfkeys{
    /pgfplots/table/string type in dec sep align/.style={
        string type,
        postproc cell content/.code={%
            \ifnum\pgfplotstablepartno=0%
                \pgfkeys{/pgfplots/table/@cell content/.add={}{&}}
            \fi
        }%
    }
}

\pgfplotstabletypeset[%
col sep=&, row sep=\\,header=false,
every head row/.style={before row={\toprule}, after row={\midrule}},
every last row/.style={after row=\bottomrule},
display columns/0/.style={column name={A}, string type, column type={l}},
display columns/1/.style={column name={B}, dec sep align},
display columns/2/.style={column name={C}, dec sep align},
every row 2  column 1/.style={string type in dec sep align},
every row 3  column 1/.style={string type in dec sep align},
]
{%
  Xyzzy ! &     208.5  &   42.01  \\
  Nothing &    7.91  &   42.1  \\
  Happens &     --  &   200.2 \\
  \ldots  &      z   &  4.54 \\
}
\end{document}
Related Question