普通 TeX 宏包含 \par 作为参数分隔符,但不能与 \obeylines 一起使用,为什么?

普通 TeX 宏包含 \par 作为参数分隔符,但不能与 \obeylines 一起使用,为什么?

我只是想格式化一个.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

在此处输入图片描述

相关内容