Datatool gobbling spaces
This does not fix the datatool
bug, but rather shows an alternate approach using readarray
. It creates an array \Sentence[<i>,<j>]
, where i
and j
are the row and column of the \Sentence
array.
\documentclass{article}
\usepackage{readarray,tikz}
\begin{filecontents*}{\jobname.csv}
The child played a new game.,He played it three times with his friends.,He loved the game.
I visited my childhood home last week.,It's just as I remembered it.,My house has always been white.
It's just as I remembered it.,I visited my childhood home last week.,My house has always been white.
\end{filecontents*}
\readarraysepchar{,}
\begin{document}
\readdef{\jobname.csv}\Sentences
\readarray\Sentences\Sentence[-,\ncols]
\foreach\x in {1,2,...,\SentenceROWS}
{\foreach\y in {1,2,...,\SentenceCOLS}{\Sentence[\x,\y]\par}}
\end{document}
I propose a different patch than Nicola’s.
\RequirePackage{filecontents}
\begin{filecontents}{\jobname.csv}
Sentence1,Sentence2,Sentence3
The child played a new game.,He played it three times with his friends.,He loved the game.
I visited my childhood home last week.,It's just as I remembered it.,My house has always been white.
It's just as I remembered it.,I visited my childhood home last week.,My house has always been white.
{}A visited my childhood home last week.,It's just as I remembered it.,My house has always been white.
{Bbb} visited my childhood home last week.,It's just as I remembered it.,My house has always been white.
X,X,X
X
\end{filecontents}
\documentclass{article}
\usepackage{datatool}
\makeatletter
\let\saved@dtl@starttrim\@dtl@starttrim
\long\def\@dtl@starttrim#1{%
\def\fix@dtl@starttrim@first{#1}%
\futurelet\next\fix@dtl@starttrim@second
}
\def\fix@dtl@starttrim@second{%
\if\noexpand\next\@sptoken
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
{\expandafter\saved@dtl@starttrim\expandafter{\fix@dtl@starttrim@first}{}}%
{\expandafter\saved@dtl@starttrim\expandafter{\fix@dtl@starttrim@first}}%
}
\makeatother
\DTLloaddb{sentences}{\jobname.csv}
\begin{document}
\DTLforeach{sentences}{%
\sOne=Sentence1,\sTwo=Sentence2,\sThree=Sentence3}
{%
\sOne\par
\sTwo\par
\sThree\par\kern1pt\hrule\kern1pt
}
\end{document}
The trimming macro checks whether the first token is followed by a space, but absorbing just one token (or braced group). It takes different actions according to whether the token is a space or not.
This bug has now been fixed. If you encounter it, make sure you have the latest version of datatool
.
Original answer
The problem is with \dtl@trim
which is supposed to trim the trailing space at the end of each line (caused by the end of line character). It's also supposed to discard the terminating \par
that occurs on the final \read
before the end of file is reached.
I think the following patch should fix the problem (but I need to test further to make sure it doesn't cause any unwanted side-effects). The argument of \dtl@trim
is always a control sequence (set by \read
for \DTLloaddb
).
\makeatletter
\renewcommand{\dtl@trim}[1]{%
\if#1\par
\def\@dtl@trmstr{}%
\else
\expandafter\@dtl@start@trim#1\@dtl@end@trim
\fi
\let#1=\@dtl@trmstr
}
\def\@dtl@start@trim#1 \@dtl@end@trim{%
\def\@dtl@trmstr{#1}%
}
\makeatother
Complete MWE:
\begin{filecontents}{\jobname.csv}
Sentence1,Sentence2,Sentence3
The child played a new game.,He played it three times with his friends.,He loved the game.
I visited my childhood home last week.,It's just as I remembered it.,My house has always been white.
It's just as I remembered it.,I visited my childhood home last week.,My house has always been white.
\end{filecontents}
\documentclass{article}
\usepackage{datatool}
\makeatletter
\renewcommand{\dtl@trim}[1]{%
\if#1\par
\def\@dtl@trmstr{}%
\else
\expandafter\@dtl@start@trim#1\@dtl@end@trim
\fi
\let#1=\@dtl@trmstr
}
\def\@dtl@start@trim#1 \@dtl@end@trim{%
\def\@dtl@trmstr{#1}%
}
\makeatother
\DTLloaddb{sentences}{\jobname.csv}
\begin{document}
\DTLforeach{sentences}{%
\sOne=Sentence1,\sTwo=Sentence2,\sThree=Sentence3}
{%
\sOne\par
\sTwo\par
\sThree\par
}
\end{document}