TransWikia.com

Iterating through CSV file - command viewed as one item

TeX - LaTeX Asked on June 12, 2021

I’m trying to iterate through a CSV file, but am running into trouble. The file is multiple lines and I want to go through the CSV items one-by-item. When using the etoolbox docsvlist, it inerprets the line break as a space. So I try to fix this (and successfully do) by replacing a space character with a comma. The only issue now is that the csv iterator interprets that command as a single item. I believe this problem has to do with expansion, and I’ve tried many edef / expandafter solutons etc. to no avail.

documentclass[11pt,a4paper]{article}
usepackage{etoolbox}
usepackage{catchfile}
usepackage{xstring}
begin{document}
    CatchFileDef{CSVdata}{FILE.csv}{}% Formatted CSV data
    newcommand{CSVdataNoSpaces}{StrSubstitute[0]{CSVdata}{ }{,}}    
    renewcommand{do}[1]{#1}% new line in between items
    expandafterdocsvlistexpandafter{CSVdataNoSpaces} % considers the command one csv item
    expandafterdocsvlistexpandafter{CSVdata} % iterates thru, but spaces are problem
end{document}

One Answer

You define CSVdataNoSpaces to expand to the token-sequence StrSubstitute[0]{CSVdata}{ }{,}.

The expandafter-chain in expandafterdocsvlistexpandafter{CSVdataNoSpaces} delivers this token-sequence, thus you get something like docsvlist{StrSubstitute[0]{CSVdata}{ }{,}}.

Thus the argument of docsvlist is the token-sequence StrSubstitute[0]{CSVdata}{ }{,}.

The token-sequence StrSubstitute[0]{CSVdata}{ }{,} does not contain any comma not nested in curly braces. Thus that entire token-sequence is considered the only element of the csv-list/of the comma-separated-values-list.

But you are in luck:

StrSubstitute takes an optional argument denoting a control-sequence-token which is to be (re-)defined to be a macro which delivers as top-level-expansion the tokens that form the result of StrSubstitute.
Thus you can do StrSubstitute[0]{CSVdata}{ }{,}[CSVdataNoSpaces]:

documentclass[11pt,a4paper]{article}
usepackage{etoolbox}
usepackage{catchfile}
usepackage{xstring}

begin{document}
    CatchFileDef{CSVdata}{FILE.csv}{}% Formatted CSV data
    % expandarg     % -> xstring-macros "hit" the 1st-token of arguments with expandafter once before processing them further. 
    % fullexpandarg % -> xstring-macros apply `edef` to the arguments before processing them further.
    % noexpandarg   % -> xstring-macros process arguments as is, without applying whatsoever expansion to them before processing them.
                     % fullexpandarg is the default.
                     % See the xstring-manual for more information.
                     % If you wish StrSubstitute to work on the result
                     % of expanding CSVdata, you need expandarg (->
                     % StrSubstitute works on CSVdata's toplevel-
                     % expansion) or fullexpandarg (-> StrSubstitute
                     % works on CSVdata's full expansion/edef-expansion) .
    StrSubstitute[0]{CSVdata}{ }{,}[CSVdataNoSpaces]%
    showCSVdata
    showCSVdataNoSpaces
    renewcommand{do}[1]{#1}% new line in between items
    expandafterdocsvlistexpandafter{CSVdataNoSpaces}% iterates thru, spaces are turned into commas which might be a problem with spaces placed into the file on purpose
    expandafterdocsvlistexpandafter{CSVdata} % iterates thru, but spaces are problem
end{document}

I recommend a different approach:

Instead of doing this StrSubstitute-game, you can "tell" CatchFileDef to append a comma instead of a space with every line-end—this might be more save because this way you won't get spaces replaced which were placed into the .csv-file on purpose:

documentclass[11pt,a4paper]{article}
usepackage{etoolbox}
usepackage{catchfile}

begin{document}
    CatchFileDef{CSVdata}{FILE.csv}{endlinechar=`,}% Formatted CSV data
    showCSVdata
    renewcommand{do}[1]{#1}% new line in between items
    expandafterdocsvlistexpandafter{CSVdata}% iterates thru.
end{document}

Depending on what data the .csv-file contains you might be interested in Dr. Nicola Talbot's datatool-package.

Correct answer by Ulrich Diez on June 12, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP