12

I just wanted to format a .csv file, so I do a test (1), shown as below:

\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

but it doesn't work, TeX complain that

! File ended while scanning use of \format.
<inserted text> 
            \par 

so I remove \obeylines, do another test (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

it works fine. Who can tell me where is wrong is test (1)?

0

2 Answers 2

8

\obeylines in plain is

{\catcode`\^^M=\active % these lines must end with %
  \gdef\obeylines{\catcode`\^^M\active \let^^M\par}%
  \global\let^^M\par}

That is it makes the ends of line active and let to \par

This means you need to delimit your macro by an active ^^M not a \par token, the \par token isn't in the stream being scanned, it is only generated if the end of line token expands.

\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
0
3

If the file is brooks.csv containing

11,2,22
13,9,117
a,b,c

then reading it line by line is probably better. This requires e-TeX, but could be realized also in 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

enter image description here

0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .