TeXLive2020 更新后 \IfFileExists 的结果不正确

TeXLive2020 更新后 \IfFileExists 的结果不正确

在使用 TeXLive2020 更新我的软件包后,我看到的行为与 TeXLive2019 不同。以下测试在目录中运行,除了名为&Testing/的文件中的 MWE 之外,仅包含 MacOS (但不包含其他文件)。foo-x-bar.texfoo-x-bar.pdf.DS_Store

使用 TeXLive 2020(应用最新更新)它输出:

在此处输入图片描述

而使用 TeXLive2019 我获得了正确的结果:

在此处输入图片描述

笔记:

  • 我对 TeXLive2020 中的软件包进行更新时必须进行的另一项更改是处理\themainfile有时会报告为 的事实./foo-x-bar.tex,而 TeXLive2019(以及软件包更新之前的早期 TeXLive2020)则是foo-x-bar.tex(即没有前导./)。 使用\IfBeginWith解决了该问题,但在此处包括它,以便此代码无论如何都可以工作。

  • 令人惊讶的是,在我的实际使用案例中,我看到了相反的结果。该文件存在,但报告称已更新 TeXLive202,因为它才不是存在!如果此解决方案不能解决我的问题,将继续尝试生成具有该结果的 MWE。

\listfiles2020

 article.cls    2020/04/10 v1.4m Standard LaTeX document class
  size10.clo    2020/04/10 v1.4m Standard LaTeX file (size option)
  xparse.sty    2020-10-27 L3 Experimental document command parser
   expl3.sty    2020-12-07 L3 programming layer (loader) 
l3backend-pdftex.def    2020-09-24 L3 backend support: PDF output (pdfTeX)
 xstring.sty    2019/02/06 v1.83 String manipulations (CT)
currfile.sty    2020/09/29 v0.7d Provides the file path elements of the current
 input file
kvoptions.sty    2020-10-07 v3.14 Key value format for package options (HO)
  keyval.sty    2014/10/28 v1.15 key=value parser (DPC)
 ltxcmds.sty    2020-05-10 v1.25 LaTeX kernel commands for general use (HO)
kvsetkeys.sty    2019/12/15 v1.18 Key value parser (HO)
filehook.sty    2020/09/29 v0.8a Hooks for input files
filehook-2020.sty    2020/09/29 v0.8a Hooks for input files
currfile-abspath.sty    2020/09/29 v0.7d Provides absolute file paths, the pare
nt working directory and the main file name

\listfiles2019

 article.cls    2019/10/25 v1.4k Standard LaTeX document class
  size10.clo    2019/10/25 v1.4k Standard LaTeX file (size option)
  xparse.sty    2019-10-11 L3 Experimental document command parser
   expl3.sty    2019-11-07 L3 programming layer (loader) 
expl3-code.tex    2019-11-07 L3 programming layer 
l3deprecation.def    2019-04-06 v L3 Deprecated functions
l3backend-pdfmode.def    2019-04-06 L3 backend support: PDF mode
 xstring.sty    2019/02/06 v1.83 String manipulations (CT)
currfile.sty    2015/04/23 v0.7c Provides the file path elements of the current
 input file
kvoptions.sty    2016/05/16 v3.12 Key value format for package options (HO)
  keyval.sty    2014/10/28 v1.15 key=value parser (DPC)
 ltxcmds.sty    2016/05/16 v1.23 LaTeX kernel commands for general use (HO)
kvsetkeys.sty    2016/05/16 v1.17 Key value parser (HO)
infwarerr.sty    2016/05/16 v1.4 Providing info/warning/error messages (HO)
etexcmds.sty    2016/05/16 v1.6 Avoid name clashes with e-TeX commands (HO)
ifluatex.sty    2019/10/25 v1.5 ifluatex legacy package. Use iftex instead.
   iftex.sty    2019/11/07 v1.0c TeX engine tests
filehook.sty    2019/10/03 v0.6 Hooks for input files
currfile-abspath.sty    2015/04/23 v0.7c Provides absolute file paths, the pare
nt working directory and the main file name

代码:

为了匹配结果,创建一个目录Testing/并将以下 MWE 保存为Testing/foo-x-bar.tex

\documentclass{article}
\usepackage{xparse}
\usepackage{xstring}
\usepackage[realmainfile]{currfile}% 


\AtBeginDocument{%
    \getmainfile
    \IfBeginWith{\themainfile}{./}{%
        \StrBetween[1,2]{\themainfile}{./}{.}[\FileNameNoExtension]%
        \typeout{Used Used \string\StrBetween}%
    }{%
        \StrBefore{\themainfile}{.}[\FileNameNoExtension]%
        \typeout{Used \string\StrBefore}%
    }%
}%

\NewDocumentCommand{\GetTexFileNameWithPath}{}{%
    ../Testing/\FileNameNoExtension.texxx%
}%

\listfiles
\begin{document}
The file name extracted from \verb|\themainfile| is \FileNameNoExtension.

\def\FileNameWithPath{\GetTexFileNameWithPath}%
\IfFileExists{\FileNameWithPath}{%
    File ``\FileNameWithPath'' exist.%
}{%
    File ``\FileNameWithPath'' does \emph{NOT} exist.%
}%
\end{document}

答案1

这里有两件奇怪的事情在发生,我不知道这是否只是你的错还是我的错(希望不是我的 ;-)

您正在使用定义文件名\NewDocumentCommand,但用该定义的命令始终\protected,并且不应在仅扩展的上下文(如文件名)中扩展,因此这在一定程度上是健壮命令不会扩展为 \input 参数。LaTeX 解析文件名的方式确实发生了变化,其中之一就是\protected宏不会扩展,因为它们应该不是的确。

在旧版本中,它之所以有效,是因为xparse支持\protected在某些扩展上下文中使用某些命令,例如在 a \csname...\endcsname(用于扩展文件名)中,并且文件名宏将正确扩展(毕竟它只是扩展为字符串)到文件名。您可以通过这个更简单的测试看到行为的差异:

\documentclass{article}
\protected\def\FileNameWithPath{../Testing/foo-x-bar.texxx}%
\begin{document}
File ``\FileNameWithPath''
\IfFileExists{\FileNameWithPath}{}{\emph{NOT} }exist.
\end{document}

所以恰当的解决问题的方法是不使用\protected定义文件名,因为至少让你做某事很奇怪需要展开来说,\protected。对于您的情况,您可以用 或\NewDocumentCommand来替换,这样可以\NewExpandableDocumentCommand更好地\newcommand避免 的开销xparse


也就是说,使用当前 LaTeX 进行上述测试的结果是的确很奇怪。我以为它会检查文件FileNameWithPath(宏的名称),然后失败。但相反,它以某种方式删除了.texxx扩展名,然后检查../Testing/foo-x-bar哪个扩展名,添加默认.tex扩展名存在,并且测试返回 true。我将调查这一点,因为它不应该这样做。

相关内容