数据工具吞噬空间

数据工具吞噬空间

我遇到了一个奇怪的问题datatool。如果一行的第一列的第一个字符后面紧跟着一个空格,那么这个空格就会被吞掉。是我做错了什么,还是这是一个错误?

\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}
\DTLloaddb{sentences}{\jobname.csv}
\begin{document}
\DTLforeach{sentences}{%
\sOne=Sentence1,\sTwo=Sentence2,\sThree=Sentence3}
{%
\sOne\par
\sTwo\par
\sThree\par
}
\end{document}

这是输出。请注意,CSV 文件第 1 列中的句子(用红色箭头标记)有被吞噬的空格,但第 2 列中的完全相同的句子(用蓝色箭头标记)没有被吞噬的空格。

代码输出

答案1

此错误现已修复。如果您遇到此问题,请确保您拥有最新版本的datatool


原始答案

问题在于,\dtl@trim它应该修剪每行末尾的尾随空格(由行尾字符引起)。它还应该丢弃在到达文件末尾之前\par发生在最后的终止符。\read

我认为以下补丁应该可以修复该问题(但我需要进一步测试以确保它不会引起任何不必要的副作用)。的参数\dtl@trim始终是一个控制序列(由\readfor设置\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

完成 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}

文件图像

答案2

这并不能修复datatool错误,而是展示了使用 的替代方法readarray。它创建一个数组\Sentence[<i>,<j>],其中ij是数组的行和列\Sentence

\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}

在此处输入图片描述

答案3

我建议使用与尼古拉不同的补丁。

\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}

修剪宏检查第一个标记后面是否跟着空格,但只吸收一个标记(或括号组)。它根据标记是否为空格采取不同的操作。

在此处输入图片描述

相关内容