使用 xstring 将参数文件名传递给 \openin 的正确方法

使用 xstring 将参数文件名传递给 \openin 的正确方法

我想根据文件名以编程方式在 latex 中打开文件。例如,如果文件名以“0”开头,我知道路径在某个文件夹中,如果以“1”开头,我知道路径在另一个文件夹中。为此,我使用包 xstring。这是由于旧的文件夹结构现在无法更改。

这是一个 MWE(可能还可以减少)

\documentclass{article}
\usepackage{xstring}

\begin{document}  
\newcommand{\ifA}[2]{\StrBefore{#1}{.}[\stripprefix]\if\ifnum\stripprefix<100 T\else F\fi T%
    #2\fi%    
}    
\newcommand{\ifB}[2]{\StrBefore{#1}{.}[\stripprefix]\if\ifnum\stripprefix>100 T\else F\fi T%
    #2\fi%    
}    

\newcommand{\sourcePath}[1]{%
    \ifA{#1}{a}%    
    \ifB{#1}{b}%    
}    

\newcommand{\procedureFile}[1]{%
    \sourcePath{#1}/#1% 
}    

\newread\fid    
\newcommand{\procRef}[1]{
    \openin\fid=\procedureFile{#1}%
        \read\fid to \instring%
    \closein\fid%   
}    

\procedureFile{012.345} \par
\procedureFile{112.345} \par
\procRef{112.345} 
\instring    
\end{document}

文件夹结构如下:

./main.tex
./a/012.345.tex    <--- contain string 'AAA'
./b/112.345.tex    <--- contain string 'BBB'

如果我编译,我会得到

a/012.345
b/112.345
b/112.345

而我期望的是

a/012.345
b/112.345
BBB

我怀疑这与 \procRef 中 \procedureFile 的扩展有关,但我无法进一步调试或解决它。在此先感谢您的帮助。

答案1

\StrBefore不可扩展,您需要通过纯扩展来访问文件名。

\documentclass{article}

\makeatletter
\newcommand{\chooseAB}[3]{%
  \chooseAB@aux{#2}{#3}#1\@nil
}
\def\chooseAB@aux#1#2#3.#4\@nil{%
  \ifnum#3<100 #1\else #2\fi
}
\makeatother

\newcommand{\sourcePath}[1]{%
  \chooseAB{#1}{a}{b}%
}    

\newcommand{\procedureFile}[1]{%
  \sourcePath{#1}/#1%
}

\newread\fid
\newcommand{\procRef}[1]{%
  \openin\fid=\procedureFile{#1}%
  \read\fid to \instring
  \closein\fid
}    

\begin{document}

\procedureFile{012.345} \par
\procedureFile{112.345} \par
\procRef{112.345} 
\instring    

\end{document}

在此处输入图片描述

如果需要更多情况,最好使用“字符串切换”;选择是根据参数的第一个字符进行的,而不是整数。

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

% here the correspondence between digits and directories
% is defined
\cs_new:Nn \dabbede_proc_dirfromfile:n
 {
  \str_case_x:nnF { \tl_head:n { #1 } }
   {
    {0}{a}
    {1}{b}
    {2}{c}
   }
   {???}
 }

\ior_new:N \g_dabbede_proc_read_stream

\NewExpandableDocumentCommand{\procFile}{m}
 {
  \dabbede_proc_dirfromfile:n { #1 } / #1
 }

\NewDocumentCommand{\procRef}{m}
 {
  \ior_open:Nx \g_dabbede_proc_read_stream
   {% build the file name
    \dabbede_proc_dirfromfile:n { #1 } / #1
   }
  \ior_map_inline:Nn \g_dabbede_proc_read_stream { ##1 \par }
  \ior_close:N \g_dabbede_proc_read_stream
 }
\cs_generate_variant:Nn \ior_open:Nn { Nx }

\ExplSyntaxOff

\begin{document}

\procFile{012.345} \par
\procFile{112.345} \par
\procFile{223.567} \par
\procRef{012.345} \par
\procRef{112.345} \par
\procRef{223.567} \par

\end{document}

在此处输入图片描述

相关内容