我有一个程序\foreach
,它应该从文件中读取数据点。这些点的存储方式使得只需简单的复制粘贴即可。事实上,我不想做比复制粘贴更多的事情(如果可能的话)。我发现这\input
行不通。有几个解决方案,但它们似乎比复制粘贴做得更多。有没有一种“简单”的方法来实现这一点?
文档.tex:
\documentclass[border=5mm]{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\foreach \from/\to in { \input{data}; } %input does not work...
{\draw [->] \from -- \to;}
\end{tikzpicture}
\end{document}
数据.dat:
{(1,1)}/{(3,3)},
{(-1,1)}/{(-3,3)},
{(1,-1)}/{(3,-3)}%
答案1
您可以使用catchfile
:
\begin{filecontents*}{\jobname.dat}
{(1,1)}/{(3,3)},
{(-1,1)}/{(-3,3)},
{(1,-1)}/{(3,-3)}%
\end{filecontents*}
\documentclass[border=5mm]{standalone}
\usepackage{tikz}
\usepackage{catchfile}
\newcommand\loaddata[1]{\CatchFileDef\loadeddata{#1}{\endlinechar=-1}}
\begin{document}
\begin{tikzpicture}
\loaddata{\jobname.dat}
\foreach \from/\to in \loadeddata{\draw [->] \from -- \to;}
\end{tikzpicture}
\end{document}
这样\endlinechar=-1
我们就有效地删除了已加载文件中的行尾。
答案2
有趣的方法。您遇到的问题源于每个段都在单独的行上,data.dat
并且\foreach
应该首先扩展参数。以下读取data.dat
文件的内容(\loaddata
命令基于这个答案) 并将每行附加到命令末尾\loadeddata
,从而将所有数据放在一行上({(1,1)}/{(3,3)},{(-1,1)}/{(-3,3)},{(1,-1)}/{(3,-3)}%
在您的示例中)。然后将其展开并用作调用中的参数\foreach
。
\begin{filecontents*}{data.dat}
{(1,1)}/{(3,3)},
{(-1,1)}/{(-3,3)},
{(1,-1)}/{(3,-3)}%
\end{filecontents*}
\documentclass[border=5mm]{standalone}
\usepackage{tikz}
\makeatletter
\newread\dataread
\def\loaddata#1{%
\gdef\loadeddata{}%
\openin\dataread=#1
\begingroup\endlinechar=-1
\@whilesw\unless\ifeof\dataread\fi{%
\read\dataread to \dataline
\edef\rslt{\noexpand\g@addto@macro\noexpand\loadeddata{\dataline}}%
\rslt%expanded argument
}%
\endgroup
\closein\dataread
}%
\makeatother
\begin{document}
\begin{tikzpicture}
\loaddata{data.dat}
\edef\expfor{\noexpand\foreach \noexpand\from/\noexpand\to in {\loadeddata}}
\expfor{\draw [->] \from -- \to;}
\end{tikzpicture}
\end{document}
答案3
为什么要重新发明轮子?文本合并可以使用以下代码合并数据:
\documentclass[tikz,border=10pt,multi]{standalone}
\usepackage{textmerg}
\begin{document}
\tikzset{%
make line/.code args={#1/#2}{%
\draw [->] #1 -- #2;
},
}
\Fields{\myline}
\newcommand*\makeline[1]{%
\tikzset{make line=#1}}
\begin{tikzpicture}
\Merge{\jobname.dat}{
\expandafter\makeline\expandafter{\myline}
}
\end{tikzpicture}
\end{document}