如何在逐行读取外部文件时检测 TeX 插入的空白行?

如何在逐行读取外部文件时检测 TeX 插入的空白行?

我想制作一个宏来导入包含该宏的输入文件所在的目录中的所有 TeX 输入文件。读取外部文件时,TeX 在最后一次迭代后附加一个空行

在下面的代码中,我使用了一个糟糕的算法,因为有两个循环。第一个用于查找整个文件,另一个用于执行主要工作。

\documentclass{article}
\usepackage{listings}

\lstset{language={[LaTeX]TeX},breaklines=true}


\def\X
{%
    \immediate\write18{cmd /c dir /b *.tex > \jobname-temp.txt}%
    \newread\myfile
    \openin\myfile=\jobname-temp.txt
    \newcount\counter
    \counter=0
    \loop
        \unless\ifeof\myfile
        \read\myfile to\mydata
        \advance \counter by 1
    \repeat
    \closein\myfile
    \openin\myfile=\jobname-temp.txt
    \advance \counter by -1
    \loop
        \ifnum \counter > 0
        \read\myfile to\mydata
        \section\mydata
        \lstinputlisting{"\mydata"}\newpage
        \advance \counter by -1
    \repeat
    \closein\myfile
}


\begin{document}
\X
\end{document}

我想使用单循环来提高性能。

如何在逐行读取外部文件时检测 TeX 插入的空白行?

答案1

读完该行后,只需再次检查 EOF。

最低限度工作示例:

\documentclass{article}
\usepackage{filecontents}

\begin{filecontents*}{\jobname.dat}
first
second
third
fourth
\end{filecontents*}

\newread\myfile

\newcommand*\readfile{%
    \immediate\openin\myfile=\jobname.dat\relax
     \loop\unless\ifeof\myfile
        \read\myfile to\mydata
        \ifeof\myfile\else
            \section\mydata
        \fi
    \repeat
    \immediate\closein\myfile
}

\begin{document}
\readfile
\end{document}

如果您想避免双重 EOF 检查,请使用如下递归宏:

\newcommand*\readfile{%
    \immediate\openin\myfile=\jobname.dat\relax
    \ifeof\myfile\else% file exists?
       \expandafter\readoneline
    \fi
    \immediate\closein\myfile
}

\def\readoneline{%
    \read\myfile to\mydata
    \ifeof\myfile\else
        \section\mydata
        % ...
        \expandafter\readoneline
    \fi
}

\par如果(原始)外部行以换行符结尾(2x 换行符 => \par,一如既往),则添加的空行将添加一个。因此\mydata将包含\par(如果您像我之前告诉过的那样使用\show它来调试它,您就会知道)。您可以使用以下方法测试这一点:

\def\lastline{\par}

%...

\ifx\mydata\lastline
  %...
\fi

当然,这个测试对于输入文件中的任何其他隐式或显式行也适用\par,因此测试 EOF 实际上通常更安全,但在这里您无论如何都想避免所有这样的输入行(并不是说它们会出现在您的示例中的任何其他地方)。

答案2

我改进了 Martin 的算法。我不使用递归方法,因为如果文件太多,它可能会因堆栈溢出(没有 .com)而损坏。我也不针对 EOF 使用双重测试。:-)

\def\X
{%
    \immediate\write18{cmd /c dir /b *.txt > \jobname-temp.dat}%
    \newread\myfile
    \openin\myfile=\jobname-temp.dat\relax
    \loop   
        \read\myfile to \mydata 
        \unless\ifeof\myfile                
        \section\mydata
        \lstinputlisting{"\mydata"}\newpage
    \repeat
    \closein\myfile
}

相关内容