判断文件名是否属于文件名列表

判断文件名是否属于文件名列表

本网站,我学会了如何根据我的 latex 文件的名称进行条件判断。当且仅当文件名为 test.tex 时,以下代码才会返回条件的第一行

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

不幸的是,我需要判断文件名是否属于列表文件名,在此文件外部指定。有没有办法让 latex 读取外部文件,获取文件名列表,然后判断 \jobname 是否属于该列表?我意识到这似乎要求太多了,但是...

答案1

你可以用 以各种方式来实现expl3。既然你想使用\jobname,我们必须将所有内容字符串化并进行全面扩展。

如果只需检查几次,我们可以每次都读取文件:

% 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}

终端上输出:

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! 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 输出

在此处输入图片描述

然而,如果必须进行多次检查,则成本会太高。

这是一种间接方式。文件列表在使用前被读入,最方便的方式是在前言中,但这不是强制性的。你可以有多个列表。该命令\readfilelist有一个可选参数;如果存在,它将创建一个新列表,你可以在\checkfileinlistTF类似

\readfilelist[newlist]{<filename>

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

这是完整的代码。

% 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}

相关内容