嘗試解析 \jobname 時,是什麼導致了這個失控的參數?

嘗試解析 \jobname 時,是什麼導致了這個失控的參數?

我正在嘗試解析我的 (Xe)LaTeX 文件的作業名以設定真/假標誌以供以後使用。我碰到這個解決方案這看起來很有希望,我也實現了(請參閱下面的 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,則輸出為

在此輸入影像描述

相關內容