I am trying to read some data from an external file and perform specific actions based on the contents of a given line.
Below is my attempt to test a read line using \ifx
– it does not work. I've also tried using \ifthenelse
from the ifthen
package and some of the generic tests from etoolbox
. As all my attempts has failed, I now have two questions:
- How do I perform a test to see if data read from an external file matches a specified sting?
- How should I debug to work out why my test fails? Based on the typeset output from the MWE below,
Line with bar
read from the external file does seem to match\linetomatch
?
As the \usepackage
statements in the preambel indicates, I would like the code to work with both LuaLaTeX and pdfLaTeX (opening the file with io.open
in a \directlua
block works and I can do the testing with Lua in LuaLaTeX. However, I would prefer a version working in pdfLaTeX too).
\documentclass{article}
\usepackage{fontspec}
%\usepackage[T1]{fontenc}
%\usepackage[utf8]{inputenc}
\usepackage{filecontents}
\begin{filecontents*}{datafile.txt}
Line with foo
Line with bar
Line with baz
\end{filecontents*}
\makeatletter
\newread\myread
\def\loaddata#1{%
\edef\linetomatch{Line with bar}%
\openin\myread=#1
\@whilesw\unless\ifeof\myread\fi{%
\readline\myread to \dataline%
\noindent"\linetomatch"
\ifx\dataline\linetomatch\relax
equals
\else
does not equal
\fi
"\dataline"\par
}%
\closein\myread
}%
\makeatother
\begin{document}
\loaddata{datafile.txt}
\end{document}
Best Answer
There are two glitches in your macros.
\readline
instead of\read
\endlinechar
The
\readline
instruction puts into\dataline
a string of category code 12 tokens (10 for spaces). Instead your\linetomatch
macro has category code 11 tokens in its replacement text. So it's better to use\read
, in general.TeX always appends the
\endlinechar
byte to the end of input lines (usually byte 13), unless this value is out of range (–1 is good for disabling it).Less serious is the empty line (with possibly only the
\endlinechar
in it) that's implicitly added at the end of all input files.