检查空的 tex 文件来决定是否分支

检查空的 tex 文件来决定是否分支

客观的:

我正在尝试输入文件内容的存在(评论是可以接受的,我正在尝试输入将在构建的 PDF 中显示的内容)来确定要采取什么路径。

如果 .tex 文件具有可显示的内容,则执行 ActionA。如果 .tex 文件实际上是空的(只有注释和空行),则执行 ActionB。

我拥有的:

\documentclass[12pt]{book}
\usepackage{catchfile}
\usepackage{ifthen}

\begin{document}

\newcommand{\isFileEmpty}[1]{
  \setbox0=\hbox{#1\unskip}\ifdim\wd0=0pt%
    \boolean{true}%
  \else
    \boolean{false}%
  \fi
}

\CatchFileDef\filecontent{catchfile}{}%

Macro test line: \isFileEmpty\expandafter{\filecontent }

\ifthenelse{\isFileEmpty\expandafter{\filecontent }}%   <-- This is where the error occurs
{Do stuff with file}
{Do something else}

\end{document}



示例 my_tex_file.tex 内容如下:


%% commented line
Actual text


示例空白my_tex_file.tex:

%% Commented line


我看到的错误是:

<to be read again>
                  \setbox
l.106 ...ifthenelse{ \isFileEmpty{\filecontent }}

!  ==> Fatal error occured, no output PDF produced!

参考:

我一直在参考https://archive.org/details/B-001-002-139/page/n383/mode/2uphttps://www.overleaf.com/learn/latex/Articles/How_does_%5Cexpandafter_work:_An_introduction_to_TeX_tokens

我所在的位置: 我相信我可以使用额外的\expandafters 来实现这一点,但我一直没有成功。我理解 的基本概念,\expandafter但我缺乏让这个特定用例发挥作用的经验。

任何帮助实现此方法的帮助都将不胜感激。任何替代此方法的方法也同样值得感激。

在此先感谢您的帮助。

答案1

您的示例中的-test\isFileEmpty似乎旨在将捕获到的宏放入一个盒子中,并测量该盒子的宽度,如果宽度为 0,则“假定”为空。

此类测试可能会被欺骗/被识破,例如,通过放置包含可显示内容的深度/高度/宽度 0pt 的过满框:

\documentclass{article}
\usepackage{ifthen}
\usepackage{catchfile}

\begin{filecontents*}{filetocatch.tex}
\newbox\mybox
\setbox\mybox=\vbox{\hbox{Hello, world!}\hbox{Hello, world!}\hbox{Hello, world!}}%
\wd\mybox=0pt %
\ht\mybox=0pt %
\dp\mybox=0pt %
\box\mybox
\end{filecontents*}

\newboolean{IsFileEmpty}%
\newcommand{\isFileEmpty}[1]{%
  \setbox0=\hbox{#1\unskip}%
  \ifdim\wd0=0pt%
    \setboolean{IsFileEmpty}{true}%
  \else
    \setboolean{IsFileEmpty}{false}%
  \fi
  \ifthenelse{\boolean{IsFileEmpty}}%
}%

\parindent=0ex
\parskip=\baselineskip

\begin{document}
This is the result of the emptiness-test after catching the content
of the file \verb|filetocatch.tex| into the macro \verb|\filecontent|:

\CatchFileDef{\filecontent}{filetocatch.tex}{}%
\isFileEmpty{\filecontent}{File is empty!}{File is not empty!}

\bigskip

This is the result of carrying out the macro \verb|\filecontent|:

\filecontent

\end{document}

在此处输入图片描述


浮点数也可能是一个问题:

\documentclass{article}
\usepackage{ifthen}
\usepackage{catchfile}

\begin{filecontents*}{filetocatch.tex}
\begin{figure}[h]
This is a figure.
\caption{This is the figure's caption.}
\end{figure}
\end{filecontents*}

\newboolean{IsFileEmpty}%
\newcommand{\isFileEmpty}[1]{%
  \setbox0=\hbox{#1\unskip}%
  \ifdim\wd0=0pt%
    \setboolean{IsFileEmpty}{true}%
  \else
    \setboolean{IsFileEmpty}{false}%
  \fi
  \ifthenelse{\boolean{IsFileEmpty}}%
}%

\parindent=0ex
\parskip=\baselineskip

\begin{document}

\listoffigures

\CatchFileDef{\filecontent}{filetocatch.tex}{}%

This is the result of carrying out the macro \verb|\filecontent|:

\filecontent

\bigskip

Carrying out the emptiness-test after catching the content
of the file \verb|filetocatch.tex| into the macro \verb|\filecontent|
leads to an error-message on the terminal/console:

\verb|! LaTeX Error: Not in outer par mode.|

Subsequent error-messages follow.

Besides this you erroneously get as result:

\isFileEmpty{\filecontent}{File is empty!}{File is not empty!}

\end{document}

在此处输入图片描述


逐字逐句(verbatim-environments/ \verb|...|-commands)对于-test来说也会是个问题\isFileEmpty

\documentclass{article}
\usepackage{ifthen}
\usepackage{catchfile}

\begin{filecontents*}{filetocatch.tex}
\begin{verbatim}
This is verbatim
\end{verbatim}
\end{filecontents*}

\newboolean{IsFileEmpty}%
\newcommand{\isFileEmpty}[1]{%
  \setbox0=\hbox{#1\unskip}%
  \ifdim\wd0=0pt%
    \setboolean{IsFileEmpty}{true}%
  \else
    \setboolean{IsFileEmpty}{false}%
  \fi
  \ifthenelse{\boolean{IsFileEmpty}}%
}%

\parindent=0ex
\parskip=\baselineskip

\begin{document}

\CatchFileDef{\filecontent}{filetocatch.tex}{}%

% Carrying out the emptiness-test after catching the content
% of the file filetocatch.tex into the macro \filecontent
% leads to error-messages on the terminal/console.
% 
% \verb|! LaTeX Error: Something's wrong--perhaps a missing \item.|
%
% Subsequent error-messages follow.
% 
% You get neither a result nor a proper output-file/.pdf-file 
% because LaTeX does not leave verbatim-mode and therefore 
% does not even find the \end{document}-directive.
%

\isFileEmpty{\filecontent}{File is empty!}{File is not empty!}

\end{document}

如果您想知道文件中是否存在除空格字符、换行符(通常是 Return / CR 或 CR+LF)和以 开头的行以外的其他字符%,您可以切换到 verbatim-catcode-régime 并通过 的第三个参数将整数参数切换\endlinechar为负值\CatchFileDef

这不是可显示内容的测试。这是可标记化以供 TeX 进一步处理的内容的测试,该内容由空格字符/换行符/空行/注释行以外的内容组成。

\documentclass{article}

\usepackage{catchfile}
\usepackage{listings} % Used only for displaying files
\lstset{numbers=left, numberstyle=\tiny, numbersep=5pt, 
        basicstyle=\ttfamily, language={}, frame=single}

\begin{filecontents*}{filetocatchA.tex}
This is some content.
\end{filecontents*}

\begin{filecontents*}{filetocatchB.tex}
% This is some comment



% This is some comment
  % 

\end{filecontents*}

\begin{filecontents*}{filetocatchC.tex}
\newbox\mybox
\setbox\mybox=\vbox{%
                     \hbox{Hello, world!}%
                     \hbox{Hello, world!}%
                     \hbox{Hello, world!}%
                   }%
\wd\mybox=0pt %
\ht\mybox=0pt %
\dp\mybox=0pt %
\box\mybox
\end{filecontents*}

\begin{filecontents*}{filetocatchD.tex}
\begin{figure}[h]
This is a figure.
\caption{This is the figure's caption.}
\end{figure}
\end{filecontents*}


\begin{filecontents*}{filetocatchE.tex}
{\def\empty{}\empty\empty\empty}%
\end{filecontents*}


\begin{filecontents*}{filetocatchF.tex}
}}}}{{{
Unbalanced braces.
\end{filecontents*}


\makeatletter
%%-----------------------------------------------------------------------------
%% Check whether argument contains no tokens/is empty:
%%.............................................................................
%% \UD@CheckWhetherNull{<Argument which is to be checked>}%
%%                     {<Tokens to be delivered in case that argument
%%                       which is to be checked contains no tokens/is
%%                       empty>}%
%%                     {<Tokens to be delivered in case that argument
%%                       which is to be checked contains some tokens/
%%                       is not empty>}%
%%
%% The gist of this macro comes from Robert R. Schneck's \ifempty-macro:
%% <https://groups.google.com/forum/#!original/comp.text.tex/kuOEIQIrElc/lUg37FmhA74J>
%%
%% The way in which this macro works is explained in my answer to the
%% TeX-LaTeX-StackExchange-Question "Expandable test for an empty token
%% list—methods, performance, and robustness" at
%% <https://tex.stackexchange.com/a/522506>
%% In that answer it is named \CheckWhetherEmpty.
\newcommand\UD@CheckWhetherNull[1]{%
  \romannumeral0\expandafter\@secondoftwo\string{\expandafter
  \@secondoftwo\expandafter{\expandafter{\string#1}\expandafter
  \@secondoftwo\string}\expandafter\@firstoftwo\expandafter{\expandafter
  \@secondoftwo\string}\@firstoftwo\expandafter{} \@secondoftwo}%
  {\@firstoftwo\expandafter{} \@firstoftwo}%
}%
%%-----------------------------------------------------------------------------
%% Check whether argument is blank (empty/no tokens at all or only
%% explicit space tokens (character code 32/category code 10)):
%%-----------------------------------------------------------------------------
%% -- Take advantage of the fact that TeX discards space tokens when
%%    "fetching" _un_delimited arguments: --
%% \UD@CheckWhetherBlank{<Argument which is to be checked>}%
%%                      {<Tokens to be delivered in case that
%%                        argument which is to be checked is blank>}%
%%                      {<Tokens to be delivered in case that argument
%%                        which is to be checked is not blank>}%
\newcommand\UD@CheckWhetherBlank[1]{%
  \romannumeral\expandafter\expandafter\expandafter\@secondoftwo
  \expandafter\UD@CheckWhetherNull\expandafter{\@firstoftwo#1{}.}%
}%

\newcommand{\isFileEmpty}[1]{%
  \begingroup
  \CatchFileDef{\filecontent}{#1}{%
    \let\do\@makeother
    \dospecials
    \catcode`\%=14 %
    \catcode`\ =10 %
    \catcode`\^^I=12 %
    \endlinechar=-1 %
  }%
  \expandafter\endgroup
  \expandafter\UD@CheckWhetherBlank
  \expandafter{\filecontent}%
}%
\makeatother

\parindent=0ex
\parskip=\baselineskip

\begin{document}

This is the content of \verb|filetocatchA.tex|:

\lstinputlisting{filetocatchA.tex}

This is the result of the empty-test:

\isFileEmpty{filetocatchA.tex}{File is empty!}{File is not empty!}

\leavevmode\hrule height .5\ht\strutbox\hfill

This is the content of \verb|filetocatchB.tex|:

\lstinputlisting{filetocatchB.tex}

This is the result of the empty-test:

\isFileEmpty{filetocatchB.tex}{File is empty!}{File is not empty!}

\leavevmode\hrule height .5\ht\strutbox\hfill

This is the content of \verb|filetocatchC.tex|:

\lstinputlisting{filetocatchC.tex}

This is the result of the empty-test:

\isFileEmpty{filetocatchC.tex}{File is empty!}{File is not empty!}

\leavevmode\hrule height .5\ht\strutbox\hfill

This is the content of \verb|filetocatchD.tex|:

\lstinputlisting{filetocatchD.tex}

This is the result of the empty-test:

\isFileEmpty{filetocatchD.tex}{File is empty!}{File is not empty!}

\leavevmode\hrule height .5\ht\strutbox\hfill

This is the content of \verb|filetocatchE.tex|:

\lstinputlisting{filetocatchE.tex}

This is the result of the empty-test:

\isFileEmpty{filetocatchE.tex}{File is empty!}{File is not empty!}

\leavevmode\hrule height .5\ht\strutbox\hfill

This is the content of \verb|filetocatchF.tex|:

\lstinputlisting{filetocatchF.tex}

This is the result of the empty-test:

\isFileEmpty{filetocatchF.tex}{File is empty!}{File is not empty!}

\end{document}

在此处输入图片描述

在此处输入图片描述

相关内容