3

From this site, I've learned how to condition on the name of my latex file. This code below returns the first line of the conditional iff the file is called test.tex

\begin{document}
    \ifthenelse{\equal{\detokenize{test}}{\jobname}}
        { This is file test.tex }
        { This is NOT file test.tex  }
    \end{document}

Unfortunately, I need to condition on whether the filename belongs to a list of filenames, specified externally to this file. Is there a way of getting latex to read an external file, obtain a list of file names, then condition on whether or not \jobname belongs to that list? I realize that this seems like a lot to ask for, but ...

  • 1
    Please post a more complete example. Presumably you need a class. But you also need to give a sample external file. – cfr Mar 19 '17 at 2:33
3

You can do it in various ways with expl3. Since you want to use \jobname, we have to stringify everything and do full expansion.

If the check is to be done just a few times, we can read the file each time:

% this file is named leosimon.tex
\begin{filecontents*}{listoffiles.txt}
leosimon.tex
x-leosimon.tex
foobar.tex
\end{filecontents*}

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand {\checkfileinlistTF}{mmmm}
 { % #1 = name to test, #2 = file name, #3 = True case, #4 = False case
  \file_if_exist:nTF { #2 }
   {
    \leosimon_checkfileinlist:nnnn { #1 } { #2 } { #3 } { #4 }
   }
   {
    %error
    \msg_error:nnn { leosimon/checkfiles } { nofilelist } { #2 }
   }
 }

\tl_new:N \l_leosimon_checkfiles_list_tl
\tl_new:N \l_leosimon_checkfiles_name_tl
\msg_new:nnnn { leosimon/checkfiles } { nofilelist }
 {
  Missing~file~list~#1
 }
 {
  The~file~#1~does~not~exist,~aborting~command
 }

\cs_new_protected:Nn \leosimon_checkfileinlist:nnnn
 {
  % read the file list
  \tl_set_from_file:Nnn \l_leosimon_checkfiles_list_tl { } { #2 }
  % stringify the file list
  \tl_set:Nx \l_leosimon_checkfiles_list_tl { \tl_to_str:N \l_leosimon_checkfiles_list_tl }
  % fully expand the name
  \tl_set:Nx \l_leosimon_checkfiles_name_tl { #1 }
  % stringify the name
  \tl_set:Nx \l_leosimon_checkfiles_name_tl { \tl_to_str:N \l_leosimon_checkfiles_name_tl }
  % check
  \tl_if_in:NVTF \l_leosimon_checkfiles_list_tl \l_leosimon_checkfiles_name_tl
    {
     #3
    }
    {
     #4
    }
 }
\cs_generate_variant:Nn \tl_if_in:NnTF { NV }
\ExplSyntaxOff


\begin{document}

\checkfileinlistTF{\jobname.tex}{listoffiles.txt}
 {This is in the list}
 {This is NOT in the list}

\checkfileinlistTF{x-\jobname.tex}{listoffiles.txt}
 {This is in the list}
 {This is NOT in the list}

\checkfileinlistTF{foobar.tex}{listoffiles.txt}
 {This is in the list}
 {This is NOT in the list}

\checkfileinlistTF{hey.tex}{listoffiles.txt}
 {This is in the list}
 {This is NOT in the list}

\checkfileinlistTF{hey.tex}{wrongname}
 {This is in the list}
 {This is NOT in the list}

\end{document}

Output on the terminal:

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! leosimon/checkfiles error: "nofilelist"
! 
! Missing file list wrongname
! 
! See the leosimon/checkfiles documentation for further information.
! 
! For immediate help type H <return>.
!...............................................  

l.79  {This is NOT in the list}

? h
|'''''''''''''''''''''''''''''''''''''''''''''''
| The file wrongname does not exist, aborting command
|...............................................
? 

PDF output

enter image description here

However, this would be too expensive if the check has to be performed several times.

Here is an indirect way. The file list is read in before using it, most conveniently in the preamble, but it's not mandatory. You can have more than one list. The command \readfilelist has an optional argument; if present it will create a new list which you can use in \checkfileinlistTF like

\readfilelist[newlist]{<filename>

\checkfileinlistTF[newlist]{x.tex}{True}{False}

Here's the full code.

% this file is named leosimon.tex
\begin{filecontents*}{listoffiles.txt}
leosimon.tex
x-leosimon.tex
foobar.tex
\end{filecontents*}

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\readfilelist}{O{default}m}
 {
  \leosimon_checkfiles_read:nn { #1 } { #2 }
 }

\NewDocumentCommand {\checkfileinlistTF}{O{default}mmm}
 { % #1 = list (optional), #2 = file name, #3 = True case, #4 = False case
   \leosimon_checkfileinlist:nnnn { #1 } { #2 } { #3 } { #4 }
 }

\tl_new:N \l_leosimon_checkfiles_name_tl

\msg_new:nnnn { leosimon/checkfiles } { nofilelist }
 {
  Missing~file~list~#1
 }
 {
  The~file~#1~does~not~exist,~aborting~command
 }

\cs_new_protected:Nn \leosimon_checkfiles_read:nn
 {
  \file_if_exist:nTF { #2 }
   {
    \tl_gclear_new:c { g_leosimon_checkfiles_#1_tl }
    % read the file list
    \tl_gset_from_file:cnn { g_leosimon_checkfiles_#1_tl } { } { #2 }
    % stringify the file list
    \tl_gset:cx { g_leosimon_checkfiles_#1_tl } { \tl_to_str:c { g_leosimon_checkfiles_#1_tl } }
   }
   {
    %error
    \msg_error:nnn { leosimon/checkfiles } { nofilelist } { #2 }
   }
 }

\cs_new_protected:Nn \leosimon_checkfileinlist:nnnn
 {
  % fully expand the name
  \tl_set:Nx \l_leosimon_checkfiles_name_tl { #2 }
  % stringify the name
  \tl_set:Nx \l_leosimon_checkfiles_name_tl { \tl_to_str:N \l_leosimon_checkfiles_name_tl }
  % check
  \tl_if_in:cVTF { g_leosimon_checkfiles_#1_tl } \l_leosimon_checkfiles_name_tl
    {
     #3
    }
    {
     #4
    }
 }
\cs_generate_variant:Nn \tl_if_in:NnTF { cV }
\ExplSyntaxOff


\readfilelist{listoffiles.txt}

\readfilelist[wrong]{wrong.txt} % a new list (but it will give error if the file is not there

\begin{document}

\checkfileinlistTF{\jobname.tex}
 {This is in the list}
 {This is NOT in the list}

\checkfileinlistTF{x-\jobname.tex}
 {This is in the list}
 {This is NOT in the list}

\checkfileinlistTF{foobar.tex}
 {This is in the list}
 {This is NOT in the list}

\checkfileinlistTF{hey.tex}
 {This is in the list}
 {This is NOT in the list}

\end{document}
  • Fabulous thanks @egreg. I wasn't at all wedded to using \jobname--- it was just what I knew about----if there's a more efficient way. – Leo Simon Mar 19 '17 at 17:33
  • @LeoSimon Alternative implementation on line – egreg Mar 19 '17 at 17:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.