TransWikia.com

Incorrect Results from IfFileExists with updates to TeXLive2020

TeX - LaTeX Asked on August 15, 2021

Following an update to my packages with TeXLive2020 I am seeing different behaviour than in TeXLive2019. The following test is run in the directory Testing/ which besides the MWE in the file entitiled foo-x-bar.tex & foo-x-bar.pdf contains only the MacOS .DS_Store (but no other files).

With TeXLive 2020 (with latest updates applied), it outputs:

enter image description here

where as with TeXLive2019 I obtain the correct results:

enter image description here

Notes:

  • The other change I had to make with an update to the packages in TeXLive2020 is to handle the fact that themainfile is sometimes reported as ./foo-x-bar.tex whereas with TeXLive2019 (and earlier TeXLive2020 before the package updates) it was foo-x-bar.tex (ie, without the leading ./). The use of IfBeginWith resolves that issue, but including it here so that this code works either way.

  • Surprisngly, in my actual use case I am seeing the opposite results. The file exists but is being reported with an updated TeXLive202 as it does not exist!! Will continue to attempt to produce an MWE with that result if the solution to this does not resolve my issue.

listfiles 2020

 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

listfiles 2019

 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

Code:

To match the results, create a directory Testing/ and save the following MWE as 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 stringStrBetween}%
    }{%
        StrBefore{themainfile}{.}[FileNameNoExtension]%
        typeout{Used stringStrBefore}%
    }%
}%

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

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

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

One Answer

Two strange things are at play here, and I don't know if the fault is only yours or mine too (hopefully not mine ;-)

You are defining a file name using NewDocumentCommand, but commands defined with that are always protected, and should not expand in expansion-only contexts (like file names), so in part this is a duplicate of Robust command not expanding as input argument. There were indeed changes to how LaTeX parses file names, and one of these changes is that protected macros do not expand, because they should not indeed.

In older versions it worked because xparse supports some protected commands to be used in some expansion contexts, like in a csname...endcsname (used to expand a file name), and your file name macro would expand correctly (after all it just expands to a string) to the file name. You can see the difference in behaviour with this simpler test:

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

So the proper solution to the problem is to not use protected to define a file name, because it is at least weird to make something that you need to expand, protected. In your case you can replace NewDocumentCommand by NewExpandableDocumentCommand or even better newcommand to avoid the overhead of xparse.


That said, the result of the test above with a current LaTeX is indeed strange. I would expect it to check for the file FileNameWithPath (the name of the macro), and fail. But instead, it is somehow dropping the .texxx extension and then checking for ../Testing/foo-x-bar which, adding the default .tex extension does exist and the test returns true. I will investigate this bit because it should not do that.

Correct answer by Phelype Oleinik on August 15, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP