pgf-tikz / pgfplots

pgfplots - A TeX package to draw normal and/or logarithmic plots directly in TeX in two and three dimensions with a user-friendly interface and pgfplotstable - a TeX package to round and format numerical tables. Examples in manuals and/or on web site.
http://pgfplots.sourceforge.net/
200 stars 35 forks source link

\pgfplotstablesave writes additional column depending on `col sep` #181

Open pgf-tikz-bot opened 7 years ago

pgf-tikz-bot commented 7 years ago

Migrated from SourceForge https://sourceforge.net/p/pgfplots/bugs/181/ Author: funkiest Timestamp: 2017-08-16 11:53:57.223000

I have found a bug while writing a table to a file with \pgfplotstablesave. In dependance of the col sep key, some times there is written an additional column to the file. Or more specific the col sep symbol is wrongly placed at the of the line.

To show this bug I have written the following file. The simple benchmark of writing the table to a file and reread it shows the bug.

\documentclass[parskip=half]{scrartcl}

\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}

\usepackage{pgfplotstable}
    \pgfplotsset{compat=1.15}

\usepackage{filecontents}
    \begin{filecontents}{table.csv}
A B
1 2
    \end{filecontents}

    \newcommand{\checktable}[1]{
            Test for \texttt{#1}\par
            % write to file
            \pgfplotstablesave[
                col sep = #1,
            ]{\data}{tableTemp_#1.csv}          
            % read again
            \pgfplotstableread[
            col sep = #1,]
            {tableTemp_#1.csv}\datatemp         
            % show info
            \pgfplotstableforeachcolumn\datatemp\as\col{%
                column name is ‘\col’; index is \pgfplotstablecol; \\
            }
    }

\begin{document}
    \pgfplotstableset{row sep = newline}

    % read original table
    \pgfplotstableread[
        col sep = space,
    ]{table.csv}\data

    Read directly from \texttt{table.csv} \par
    % show info
    \pgfplotstableforeachcolumn\data\as\col{%
        column name is ‘\col’; index is \pgfplotstablecol; \\
    }

    \checktable{space}

    \checktable{tab}

    \checktable{semicolon}

    \checktable{comma}

    \checktable{colon}

    \checktable{braces}

    \checktable{ampersand}

\end{document}

And the output

Read directly from table.csv column name is ‘A’; index is 0; column name is ‘B’; index is 1; Test for space column name is ‘A’; index is 0; column name is ‘B’; index is 1; Test for tab column name is ‘A’; index is 0; column name is ‘B’; index is 1; Test for semicolon column name is ‘A’; index is 0; column name is ‘B’; index is 1; column name is ‘2’; index is 2; Test for comma column name is ‘A’; index is 0; column name is ‘B’; index is 1; column name is ‘2’; index is 2; Test for colon column name is ‘A’; index is 0; column name is ‘B’; index is 1; column name is ‘2’; index is 2; Test for braces column name is ‘A’; index is 0; column name is ‘B’; index is 1; Test for ampersand column name is ‘A’; index is 0; column name is ‘B’; index is 1; column name is ‘2’; index is 2;

pgf-tikz-bot commented 7 years ago

Migrated from SourceForge https://sourceforge.net/p/pgfplots/bugs/181/#d1e5 Author: symbol-1 Timestamp: 2017-08-19 21:16:20.412000

See pgfplotstable.code.tex line 1039-1073. It does not test whether a cell is in the last column and append a comma (or colon/or semicolon/or ampersand).

You might want to do something like

    typeset cell/.code={%
        \begingroup
        \t@pgfplots@toka={##1}%
        \ifcase\pgfplotstableread@OUTCOLSEP@CASE\relax
            ....... ignored
        \or
            % col sep=comma:
            \t@pgfplots@tokb={,}%
            \ifnum\pgfplotstablecol>1
                \xdef\pgfplots@glob@TMPc{\the\t@pgfplots@tokb\the\t@pgfplots@toka}%
            \else
                \xdef\pgfplots@glob@TMPc{\the\t@pgfplots@toka}%
            \fi
        \or
            ....... ignored
        \fi
        \endgroup
        \pgfkeyslet{/pgfplots/table/@cell content}\pgfplots@glob@TMPc%
    },%

Playing code

\pgfplotstableread{table.csv}\data
\def\pgfplotstablesave@impl[#1]#2#3{%
    \pgfplotstabletypeset[%
        reset styles,%
        disable rowcol styles,%
        begin table={},%
        end table={},%
        typeset cell/.code={%
            \begingroup
            \t@pgfplots@toka={##1}%
            \ifcase\pgfplotstableread@OUTCOLSEP@CASE\relax
                ....... ignored
            \or
                % col sep=comma:
                \t@pgfplots@tokb={,}%
                \ifnum\pgfplotstablecol>1%
                    \xdef\pgfplots@glob@TMPc{\the\t@pgfplots@tokb\the\t@pgfplots@toka}%
                \else%
                    \xdef\pgfplots@glob@TMPc{\the\t@pgfplots@toka}%
                \fi
            \or
                ....... ignored
            \fi
            \endgroup
            \pgfkeyslet{/pgfplots/table/@cell content}\pgfplots@glob@TMPc%
        },%
        before row=,%
        after row=,%
        skip coltypes,%
        typeset=false,%
        string type,%
        TeX comment=,%
        columns=,%
        font=,%
        /pgfplots/table/col sep/.is choice,%
        /pgfplots/table/col sep/space/.code     = {\def\pgfplotstableread@OUTCOLSEP@CASE{0}},%
        /pgfplots/table/col sep/comma/.code     = {\def\pgfplotstableread@OUTCOLSEP@CASE{1}},%
        /pgfplots/table/col sep/semicolon/.code = {\def\pgfplotstableread@OUTCOLSEP@CASE{2}},%
        /pgfplots/table/col sep/colon/.code     = {\def\pgfplotstableread@OUTCOLSEP@CASE{3}},%
        /pgfplots/table/col sep/braces/.code    = {\def\pgfplotstableread@OUTCOLSEP@CASE{4}},%
        /pgfplots/table/col sep/tab/.code       = {\def\pgfplotstableread@OUTCOLSEP@CASE{5}},%
        /pgfplots/table/col sep/&/.code         = {\def\pgfplotstableread@OUTCOLSEP@CASE{6}},%
        /pgfplots/table/col sep/ampersand/.code = {\def\pgfplotstableread@OUTCOLSEP@CASE{6}},%
        /pgfplots/table/col sep=space,%
        /pgfplots/table/in col sep/.is choice,%
        /pgfplots/table/in col sep/space/.code      = {\def\pgfplotstableread@COLSEP@CASE{0}},%
        /pgfplots/table/in col sep/comma/.code      = {\def\pgfplotstableread@COLSEP@CASE{1}},%
        /pgfplots/table/in col sep/semicolon/.code  = {\def\pgfplotstableread@COLSEP@CASE{2}},%
        /pgfplots/table/in col sep/colon/.code      = {\def\pgfplotstableread@COLSEP@CASE{3}},%
        /pgfplots/table/in col sep/braces/.code     = {\def\pgfplotstableread@COLSEP@CASE{4}},%
        /pgfplots/table/in col sep/tab/.code        = {\def\pgfplotstableread@COLSEP@CASE{5}},%
        /pgfplots/table/in col sep/&/.code          = {\def\pgfplotstableread@COLSEP@CASE{6}},%
        /pgfplots/table/in col sep/ampersand/.code  = {\def\pgfplotstableread@COLSEP@CASE{6}},%
        /pgfplots/table/in col sep=space,%
        % WARNING: you NEED a '%' before '#1':
        #1,%
        /pgfplots/table/include outfiles=false,
        /pgfplots/table/outfile={#3}%
    ]{#2}%
}%
\pgfplotstablesave[col sep=comma
]{\data}{tableTemp_force.csv}
\pgfplotstabletypeset[col sep=comma,string type]{tableTemp_force.csv}

\end{document}