\InputIfFileExists 或 \IfFileExists 的可扩展版本

\InputIfFileExists 或 \IfFileExists 的可扩展版本

来自这个问题:在表格内执行 \input 时无法使用 \toprule——为什么?我知道tabular环境中的所有内容最好都是可扩展的。下面的 MWE 表明情况\InputIfFileExists并非如此,尽管错误消息现在有所不同:

! Missing \endcsname inserted.
<to be read again> 
                   \def 
l.8       \end{tabular}

文件main.tex

\documentclass{standalone}
\usepackage{booktabs}

\begin{document}
  \begin{tabular}{ll}
  \InputIfFileExists{inp.tex}{}{}
  \end{tabular}
\end{document}

文件inp.tex

\toprule
a & b \\
c & d \\
\bottomrule

如何以可扩展的方式检查文件是否存在,如果存在则输入?

以下问题相关:为什么 \input 不可扩展?

答案1

检查文件是否存在是不可扩展的,因为使用 打开文件,\openin\somefilehandle=<filename>这会对 进行赋值\somefilehandle。然后\ifeof\somefilehandle用于检查是否已到达文件末尾 (EOF),对于不存在的文件,该值立即为真。我认为,在到达 EOF 之前,空文件至少需要读取一次。赋值不可扩展,因此测试不可扩展。但是,使用 TeX 读取整个文件\input\@@input由 LaTeX 重命名为,而\input重新定义为不可扩展的形式)不需要分配文件句柄,因此是可扩展的。

但是,您可以检查文件是否存在,tabular并有一个完全可扩展的宏,如果文件存在则包含内容,否则不执行任何其他操作。

\documentclass{standalone}
\usepackage{booktabs}

\newif\ifmyfileexists
\makeatletter
\let\originput\@@input
\makeatother

\begin{document}
  \IfFileExists{inp}{\myfileexiststrue}{\myfileexistsfalse}%
  \begin{tabular}{ll}
      \ifmyfileexists
        \originput inp
      \fi
  \end{tabular}
\end{document}

或者使用一些用户级宏:

\documentclass{standalone}
\usepackage{booktabs}

\makeatletter
\newcommand{\testfileexists}[1]{%
  \IfFileExists{#1}%
    {\def\inputtestedfile{\@@input #1 }}
    {\let\inputtestedfile\@empty}%
}
\makeatother

\begin{document}
  \testfileexists{inp}
  \begin{tabular}{ll}
      \inputtestedfile
  \end{tabular}
\end{document}

答案2

警告 这是我的第一个 LuaTeX 代码,所以请耐心等待。:)

为了完整起见,我将添加一个 LuaTeX 解决方案,正如 Joseph 在评论中提到的那样。我相信 Lua 代码是不言自明的。

假设我有一个meow.tex包含以下内容的文件:

Hello cat!

以及文件mydoc.tex

\documentclass{article}

\usepackage{luacode}

\begin{luacode}
-- Checks if file exists.
function checkFile(theFile)

    -- open a file handler
    local fileHandler = io.open(theFile,"r")

    -- check if the handler is valid
    if fileHandler then

        -- the file exists, close
        fileHandler:close()

        -- print the input command
        tex.print("\\input{" .. theFile .. "}")

    end
end
\end{luacode}

\newcommand\myinput[1]{\luadirect{checkFile(\luastring{#1})}}

\begin{document}

Hello world!

\myinput{meow.tex}

\end{document}

运行lualatex mydoc.tex,得到以下输出:

猫

meow.texwoof.tex(不存在)替换,我们得到以下输出:

狗

好了,一个不错的后备方案。:)我们甚至可以else在 Lua 代码中添加一个分支来打印有关丢失文件的消息。

答案3

不,这是不可能的,因为并非所有用于文件检查的底层原语都是可扩展的。特别是,文件检查使用\openin,它是不可扩展的,尽管文件结尾的实际测试(\ifeof)是可扩展的。

您可以使用可扩展的\input原语(由 LaTeX2e 存储为\@@input),但这无法检查文件是否存在。因此,只有当文件确实可用时,这才是安全的。

相关内容