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}
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
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP