从本网站,我学会了如何根据我的 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}