我只是想格式化一个.csv
文件,所以我做了一个测试(1),如下所示:
\global\let\xpar=\par
\def\format#1,#2,#3\par{$#1\times #2=#3$\xpar}
\begingroup
\everypar={\format}\obeylines%
11,2,22
13,9,117
a,b,c
\endgroup
\end
但它不起作用,TeX 抱怨说
! File ended while scanning use of \format.
<inserted text>
\par
所以我删除了\obeylines
,做了另一个测试(2):
\global\let\xpar=\par
\def\format#1,#2,#3\par{$#1\times #2=#3$\xpar}
\begingroup
\format 11,2,22
\format 13,9,117
\format a,b,c
\endgroup
\end
运行正常。谁能告诉我测试(1)哪里错了?
答案1
\obeylines
简而言之
{\catcode`\^^M=\active % these lines must end with %
\gdef\obeylines{\catcode`\^^M\active \let^^M\par}%
\global\let^^M\par}
也就是说,它使行尾处于活动状态,let
并且\par
这意味着您需要通过活动^^M
而不是\par
标记来分隔您的宏,\par
标记不在被扫描的流中,只有行尾标记扩展时才会生成。
\begingroup
\everypar={\format}\obeylines%
\def\format#1,#2,#3^^M{$#1\times #2=#3$\par}%
11,2,22
13,9,117
a,b,c
\endgroup
\end
答案2
如果文件brooks.csv
包含
11,2,22
13,9,117
a,b,c
那么逐行阅读可能更好。这需要 e-TeX,但也可以在 Knuth TeX 中实现。
\def\format#1,#2,#3\format{$#1\times#2=#3$\par}
\newread\brooksread
\hsize=.5\hsize % just for the example
\noindent X\hrulefill X\par
\openin\brooksread=brooks.csv
\begingroup\endlinechar=-1
\loop\unless\ifeof\brooksread
\read\brooksread to \test \show\test
\unless\ifx\test\empty
\expandafter\format\test\format
\fi
\repeat
\endgroup
\noindent X\hrulefill X\par
\bye