1

For a project I am working on, I would like to write a wrapper macro \fancyTable, which communicates with pgfplotstable in the background. The user should be able to specify the column alignment as a comma separated list and the path to the file containing the table data. Additional complication is that the data is in general an arbitrary string; it can be a time stamp, parts of a sentence or a number. In the current testing phase, the wrapper macro looks like this:

\fancyTable[r,c,c,l]{FILEPATH}

The current design requirement is that it has to work for an arbitrary number of columns (so hard-coding for specific cases is not an option). However, all my attempts for procedural assignment of the column style did not work (or even worse lead to different glitches for each compilation).

Since I tried a lot of possibilities already, I decided to give a complete overview. My remaining open questions are at the very end under the section Questions. So feel free to scroll to the end.

Starting point

Currently, I managed to hard-code a table.

\documentclass{scrreprt} % standalone or minimal do not work well with longtable

\usepackage{pgfplotstable}
\usepackage{longtable}
\usepackage{colortbl}
\usepackage{booktabs}

\begin{document}
    \begin{filecontents}{pgfplotstable_proc-column-style_example.csv}
        date, time, time zone, event
        2019/01/01, 00:00, CET, server installation finished
        2019/01/01, 00:05, CET, server successfully booted
        2019/01/01, 00:06, CET, starting xyz daemon
        2019/01/01, 00:10, CET, admin login
        2019/12/31, 23:58, CET, sudo reboot
        2019/12/31, 23:59, CET, server reboot
    \end{filecontents}

    \pgfplotstabletypeset[
        begin table=\begin{longtable},%
        end table=\end{longtable},%
        header=false,% no specific header data
        col sep=comma,%
        every head row/.style={% 
            output empty row,% prevent printing of column numbers
        },%
        every odd row/.style={before row={\rowcolor[gray]{0.9}}},% highlighting of every second data row
        every first row/.append style={after row={\midrule}},% horizontal line after header
        string type,% necessary for correct processing of table content
        columns/0/.style={column type=r},%
        columns/3/.style={column type=l},%
        % modified from: https://tex.stackexchange.com/questions/130835/pgfplotstable-one-row-in-bold
        postproc cell content/.append code={% setting first row bold
            \count0=\pgfplotstablerow %
            \advance\count0 by1 %
            \ifnum\count0=1 %
            \pgfkeysalso{@cell content=\textbf{#1}}%
            \fi %
        },
    ]{pgfplotstable_proc-column-style_example.csv}
\end{document}

The compilation returns the following table: enter image description here

However, the column alignment is fixed:

columns/0/.style={column type=r},%
columns/3/.style={column type=l},%

which leads to issues if the input data is changed.

Attempt 1: pgfplotstable macros

My first idea was to use macros already provided by pgfplotstable, but I only manage to print column related content with \pgfplotstableforeachcolumn. Next, I tried to create a for-loop with \pgfplotsforeachungrouped, which also failed. As far as my limited understanding of pgf and pgfplotstable, it either did not work since I did not manage to access the table data properly or that the macro was not designed to do what I tried to ask of it.

Attempt 2: \foreach with \protected@xappto

Another idea I had was to create a string containing the alignment information in a helper macro \columnAlign and insert the content of the macro in \pgfplotstabletypeset[\columnAlign]{FILENAME}. For prototyping, I used the hacky approach of combining \foreachwith \protected@xappto, with which I had some success in the past for creating table content on-the-fly. Of course, this did not work; so the MWE will not compile...

\documentclass{minimal}

\usepackage{pgfplotstable}
\usepackage{etoolbox}

\begin{document}
    \begin{filecontents}{pgfplotstable_proc-column-style_example.csv}
        date,time,time zone, event
        2019/01/01, 00:00, CET, server installation finished
        2019/01/01, 00:05, CET, server successfully booted
        2019/01/01, 00:06, CET, starting xyz daemon
        2019/01/01, 00:10, CET, admin login
        2019/12/31, 23:58, CET, sudo reboot
        2019/12/31, 23:59, CET, server reboot
    \end{filecontents}
    
    \pgfplotstableread[header=false,col sep=comma]{pgfplotstable_proc-column-style_example.csv}\loadedtable

    \def\columnAlign{}% define empty helper macro
    \makeatletter
    \foreach \col in {0,1} {% iterate over all columns in \loadedtable
        \protected@xappto\columnAlign{% append column style definition
            columns/\col/.style=\{column type=l\}, 
        }%
    }%
    \makeatother

    \pgfplotstabletypeset[
        every head row/.style={% 
            output empty row,%
        },%
        string type,%
        \columnAlign
    ]\loadedtable
\end{document}

There were many issues with escaping characters like , = { }, which I could not fix. I tried \csname ... \endcsname, \expandafter, etc.

Attempt 3: \input{} (do not try!)

From the start, I was certain that this will break pgfplotstable; but if you do not try it, you do not know it for sure...

The idea was that I could probably load an externally generated tex-file which pgfplotstable would be able to load without the \csname and the expansion issues. Or alternatively, this might be a way to generate a pipe via \input{|"PIPE CONTENT"}.

Like expected, calling \pgfplotstable[\input{FILE1}]{FILE2} was not compiling properly. The compilation froze/looped and not even an error message was produced.

Attempt 4: custom column styles and ./list

Attempt 4 is a very similar to attempt 2. However, it tried to utilize the pgfplotstable-feature that you can define custom column styles in the output table domain, over which can be iterated.

\pgfplotstableset{%
    left column/.style={%
        /pgfplots/table/display columns/#1/.style={column type=l}%
    },%
    center column/.style={%
        /pgfplots/table/display columns/#1/.style={column type=c}%
    },%
    right column/.style={%
        /pgfplots/table/display columns/#1/.style={column type=r}%
    },%
}%

If the styles gets called, e. g. left column/.list={LIST}, the style will be applied to all column indices provided in LIST.

The styles do also accept macros as an input. This would have been a possibility to generate several "macro arrays" with \protected@xappto, containing the indices of the columns to which the style should be applied. If no column should get a certain style applied, the corresponding "style macro array" would be empty.

As a prototype, I manually created the macros.

\def\cCenter{0,1,2}
\def\cLeft{3}
\def\cRight{}

\pgfplotstabletypeset[
    left column/.list={\cLeft}, %
    center column/.list={\cCenter}, %
    right column/.list={\cRight}, %
]{FILE}

It compiled as long as the "macro array" was not empty. If the "array" was empty, the compilation halted. Using an if-case to only include column styles which should be applied, did also not work. This left no possibility to influence the column alignment procedurally.

Questions:

  1. Did I miss a pgfplotstable macro which would allow me to do what I want to do?
  2. Is there perhaps a way with the expl3 syntax?
  3. Or, in the worst case scenario, is it simply not possible with pgfplotstable to achieve my goal? If so, is there an alternative way of parsing tables from files (e.g. with datatool) which would provide similar functionality like pgfplotstable (especially preproc cell content, postproc cell content will be required for my project in the future)?

1 Answer 1

1

An alternative solution with catchfile and tabularray packages based on my answer to another question:

\documentclass{scrreprt}

%% % used to make page size smaller and therewith facilitate page break testing
%\usepackage[
%  paperheight=7.5cm, paperwidth=13cm,
%  left=0.5cm, right=0.5cm, top=0.25cm,
%  bottom=0.25cm, includeheadfoot
%]{geometry}

\usepackage{xcolor}
\usepackage{catchfile}
\usepackage{tabularray}

\ExplSyntaxOn
\group_begin:
  \catcode`\^^M=\active %
  \cs_gset_protected:Npn \NormalizeData #1 {%
    \regex_replace_once:nnN { \s * \r ? $ } {} #1
    \tl_greplace_all:Nnn #1 {^^M} {\\}%
    \tl_greplace_all:Nnn #1 {,} {&}%
  }%
\group_end:
\ExplSyntaxOff

\newcommand{\fancyTable}[2][]{
  \CatchFileDef{\mydata}{#2}{\catcode`\^^M=\active}
  \NormalizeData{\mydata}
  \begin{longtblr}[
    expand = \mydata,
    caption = {The Caption of the Table},
  ]{
    colspec = {#1},
    hline{1,Z} = {0.08em},
    hline{2} = {0.05em},
    row{even} = {gray9},
    row{1} = {font=\bfseries},
    rowhead = 1,
  }
    \mydata
  \end{longtblr}
}

\begin{document}

\begin{filecontents*}{628719.csv}
    date, time, time zone, event
    2019/01/01, 00:00, CET, server installation finished
    2019/01/01, 00:05, CET, server successfully booted
    2019/01/01, 00:06, CET, starting xyz daemon
    2019/01/01, 00:10, CET, admin login
    2019/12/31, 23:58, CET, sudo reboot
    2019/12/31, 23:59, CET, server reboot
\end{filecontents*}

%\fancyTable[r]{628719.csv}   % specify only the first column

\fancyTable[rc]{628719.csv}   % specify only the first two columns

%\fancyTable[rcc]{628719.csv} % specify only the first three columns

\fancyTable[rccl]{628719.csv} % specify all of the four columns

\end{document}

enter image description here

6
  • Thank you very much for the answer. It does what I need it to do, except when I compile it on my machine (Archlinux with newest texlive install), I get an additional empty row at the end. Additionally, the caption does not copy the styles I set with \usepackage{caption}. Manual editing of the caption did throw an error. Since I am not familiar with longtblr, could you please explain this in more details?
    – dsacre
    Jan 3, 2022 at 10:21
  • @dsacre I have tested it with the latest version 2021Q of tabularray package on Overleaf, which should be running a Linux system, and can not see an additional empty row. Please update your TeXLive to the lastest.
    – L.J.R.
    Jan 3, 2022 at 12:14
  • @dsacre You can use \SetTblrStyle and \SetTblrTemplate commands to customize the caption with tabularray package. For example, \SetTblrStyle{caption-tag}{font=\bfseries} will make the label boldface. Please read the documentation of tabularray package first. In case of trouble, you may ask a new question in this site.
    – L.J.R.
    Jan 3, 2022 at 12:22
  • @LJR I am using the TeXLive packages that ship with Archlinux. According to my package manager, they were updated to the newest version (2021). Since everything was working for me when using Overleaf, I will try a different OS with a different TeXLive-Install.
    – dsacre
    Jan 3, 2022 at 13:40
  • @LJR Now I also managed to reproduce the error of an added empty line with Overleaf. Occured only after several compilations. Will try to investigate what might be the cause.
    – dsacre
    Jan 3, 2022 at 14:10

You must log in to answer this question.

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