当传递的参数位于变量中时,在一个字符串中接收多个参数的命令失败

当传递的参数位于变量中时,在一个字符串中接收多个参数的命令失败

我尝试使用所解释的内容在这个 Tex SE 问题中从连字符分隔的字符串中设置三个变量:

\def\parsevars#1{\parsehelper(#1)}
\def\parsehelper(#1-#2-#3) {\def\varone{#1} \def\vartwo{#2} \def\varthree{#3}}

然后,我想在我的文档中使用这些变量。这非常有效:

\parsevars{Jake-Jane-Jerry}
When \varone entered the room, \vartwo was in awful shock. \varone was wearing \varthree's clothes!

但是,如果字符串在变量中,则不起作用:

\newcommand{\myvar}{Jake-Jane-Jerry}
\parsevars{\myvar}

更具体地说,我正在尝试解析\jobname变量:

\parsevars{\jobname}

有任何想法吗?

答案1

(将我的评论转换为答案。) 在解析之前,需要扩展该参数。 这可以在 的定义中完成\parsevars

\def\parsevars#1{\expandafter\parsehelper\expandafter(#1)}

\parsevars{\myvar}
\parsevars{\jobname}

或者仅在使用时\parsevars

\expandafter\parsevars\expandafter{\myvar}
\expandafter\parsevars\expandafter{\jobname}

更多信息请见\expandafter

编辑:关于你的评论xstring,我猜你已经尝试解析\jobname然后使用了类似的东西\IfStrEq。(如果我错了,你需要编辑你的问题,以便它有一个最小的工作示例。)

问题很可能是由于 中的所有字符ab等都\jobname被赋予了类别代码12(“其他”)而不是通常的 11(“字母”)。我们可以使用以下命令模拟复制此行为的命令:

\edef\testjobname{\detokenize{Jake-Jane-Jerry}}

这只是为了测试目的来说明差异:

\documentclass{article}

\usepackage{xstring}

% simulate \jobname:
\edef\testjobname{\detokenize{Jake-Jane-Jerry}}

\newcommand{\myvar}{Jake-Jane-Jerry}

\def\parsevars#1{\expandafter\parsehelper\expandafter(#1)}
\def\parsehelper(#1-#2-#3){\def\varone{#1}\def\vartwo{#2}\def\varthree{#3}}

\begin{document}
\parsevars{\myvar}

Testing \varone: \IfStrEq{\varone}{Jake}{True}{False}.

\parsevars{\testjobname}

Testing \varone: \IfStrEq{\varone}{Jake}{True}{False}.

\end{document}

得出的结果为:

测试杰克:正确。 测试杰克:错误。

两种情况下\varone都有定义Jake,但在第一种情况下,这四个字母的类别代码为 11(与字符串匹配Jake),而在第二种情况下,它们具有类别代码 12(不匹配)。

在这种情况下,你最好使用etoolbox

\documentclass{article}

\usepackage{etoolbox}

% simulate \jobname:
\edef\testjobname{\detokenize{Jake-Jane-Jerry}}

\newcommand{\myvar}{Jake-Jane-Jerry}

\def\parsevars#1{\expandafter\parsehelper\expandafter(#1)}
\def\parsehelper(#1-#2-#3){\def\varone{#1}\def\vartwo{#2}\def\varthree{#3}}

\begin{document}
\parsevars{\myvar}

Testing \varone: \ifdefstring{\varone}{Jake}{True}{False}.

\parsevars{\testjobname}

Testing \varone: \ifdefstring{\varone}{Jake}{True}{False}.

\end{document}

得出的结果为:

测试杰克:没错。 测试杰克:没错。

如果您想要进行其他比较,则需要添加一些示例代码。

答案2

一个不同的实现expl3;文件被命名为Jake-Jane-Jerry.tex

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
% Access the various parts
\DeclareExpandableDocumentCommand{\jobnamepart}{m}
 {
  \seq_item:Nn \g_lesik_jobname_parts_seq { #1 }
 }
% Initialize
\seq_new:N \g_lesik_jobname_parts_seq
\seq_gset_split:NnV \g_lesik_jobname_parts_seq { - } \c_sys_jobname_str
\ExplSyntaxOff

\begin{document}

When \jobnamepart{1} entered the room, \jobnamepart{2} was in awful 
shock. \jobnamepart{1} was wearing \jobnamepart{3}'s clothes!

\end{document}

在此处输入图片描述

相关内容