尝试解析 \jobname 时,是什么原因导致此失控参数?

尝试解析 \jobname 时,是什么原因导致此失控参数?

我正在尝试解析我的 (Xe)LaTeX 文档的作业名称,以设置 true/false 标志以供以后使用。我遇到了此解决方案这看起来很有希望并且我已经实现了(参见下面的 MWE)。

\documentclass{report}

\newif\ifFraktur
\makeatletter%
\newcommand{\filenameparse}[1]{\expandafter\filename@parse@#1\@nil}%
\def\filename@parse@#1_#2\@nil{%
   \gdef\filenameflag{#2}%
}%
\makeatother
\filenameparse{\jobname}%

\if{f}\filenameflag{%
   \Frakturtrue}%
\else{%
   \Frakturfalse}%
\fi%

\begin{document}

\ifFraktur{We have an f document}%
\else{We have an a document.}%
\fi
\end{document}

该文件的文件名与mwe-1-0_a.tex我将要用于实际文件的名称相对应(version-m-n_f.tex其中mn是版本号的占位符,f是标志的占位符,可以是af

运行此程序,我收到以下错误:

Runaway argument?
mwe-1-0_a\@nil
! Paragraph ended before \filename@parse@ was complete.
<to be read again>
                   \par
l.11

忽略错误(点击enter)可使文档编译并且不会再出现错误。

为了弄清这个问题的真相,我决定复制已经链接答案,但我稍微修改了一下,如下所示:

\documentclass{article}

\makeatletter
\newcommand{\filenameparse}[1]{\expandafter\filename@parse@#1\@nil}
\def\filename@parse@#1_#2_#3\@nil{%
  \gdef\fileA{#1}% first part
  \gdef\fileB{#2}% middle part
  \gdef\fileC{#3}% final part
}
\makeatother

\filenameparse{\jobname}

\begin{document}

\fileA \par
\fileB \par
\fileC
\end{document}

令人惊讶的是,这不仅会产生失控参数,而且三个宏\fileA\fileB\fileC均未定义。于是,我检查了mwe-1-0_f.tex(如上所述)并意识到它可以编译,但最后一个\ifFraktur子句被评估为false

这里可能有多个问题,但目前我最感兴趣的是失控论点的原因。

答案1

中的字符\jobname有 catcode 12(如\meaning\string),因此您需要 catcode 12_

\documentclass{report}

\newif\ifFraktur
\makeatletter%
\catcode`\_=12
\newcommand{\filenameparse}[1]{\expandafter\filename@parse@#1\@nil}%
\def\filename@parse@#1_#2\@nil{%
   \gdef\filenameflag{#2}%
}%
\catcode`\_=8
\makeatother
\filenameparse{\jobname}%

\edef\testf{\string f}
\ifx\testf\filenameflag
   \Frakturtrue
\else
   \Frakturfalse
\fi%

\begin{document}

\ifFraktur
We have an f document
\else
We have an a document.
\fi
\end{document}

答案2

这是一个实现,它还允许您提取版本号,基于我的代码将文件名解析到文档中

\documentclass{article}
\usepackage{xparse,l3regex}

\ExplSyntaxOn
\cs_generate_variant:Nn \regex_split:nnN { nV }
\seq_new:N \l_liz_jobname_seq

\NewDocumentCommand{\splitjobname}{m}
 {
  \regex_split:nVN { #1 } \c_sys_jobname_str \l_liz_jobname_seq
 }

\DeclareExpandableDocumentCommand{\jobnamepart}{m}
 {
  \seq_item:Nn \l_liz_jobname_seq { #1 }
 }

\DeclareExpandableDocumentCommand{\isfrakturTF}{mm}
 {
  \str_if_eq_x:nnTF { \jobnamepart{-1} } { f } { #1 } { #2 }
 }
\ExplSyntaxOff

\splitjobname{ [ _ \- ] } % at _ or -

\begin{document}

This document's name \isfrakturTF{has}{has not} a trailing `f'.

First part: \jobnamepart{1}\par
Second part: \jobnamepart{2}\par
Third part: \jobnamepart{3}

\end{document}

如果文件名为mwe-1-0_a.tex,则输出为

在此处输入图片描述

如果名称是mwe-1-0_f.tex,则输出是

在此处输入图片描述

相关内容