# Command receiving multiple parameters in one string fails when passed parameters are in a variable

I tried to use what was explained in this Tex SE question to set three variables from a string separated by hyphens:

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


Then, I want to use these variables in my document. This works wonderfully:

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


However, if the string is in a variable, it doesn't work:

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


More specifically, I am trying to parse the \jobname variable:

\parsevars{\jobname}


Any ideas?

• You need \expandafter This could go inside the definition of \def\parsevars#1{\expandafter\parsehelper\expandafter(#1)}. – Nicola Talbot Nov 22 '16 at 15:20
• I forgot to add, Welcome to TeX.SX! :-) – Nicola Talbot Nov 22 '16 at 16:26
• Maybe you can look at tex.stackexchange.com/questions/153769/… – egreg Nov 22 '16 at 17:51
• Also, don't forget that you have a probably unintended extra space in the definition of \parsehelper before the brace: ) { should be ){. – Manuel Nov 22 '16 at 18:25
• How to treat filemames/\jobnames with closing parenteses somewhere behind the second hyphen ? Filenames and thus \jobname-expansions like CategoryA-CategoryB-CategoryC(SubCategoryC)SomeMoreCharacters are possible with nowadays' file-systems. \parsevar/\parsehelper would split this to \varone-> CategoryA and \vartwo-> CategoryB and \varthree->CategoryC(SubCategoryC and a remainder SomeMoreCharacters. – Ulrich Diez Nov 22 '16 at 23:01

(Converting my comment into an answer.) The argument needs to be expanded before being parsed. This can be done in the definition of \parsevars:

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

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


or just when using \parsevars:

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


More information on \expandafter.

Edit: regarding your comment about xstring, I'm guessing you've tried to parse \jobname and then used something like \IfStrEq. (If I'm wrong, you'll need to edit your question so that it has a minimal working example.)

The problem is most likely due to the fact that all the characters a, b, etc in \jobname are given a category code of 12 ("other") instead of their usual 11 ("letter"). We can simulate a command that replicates this behaviour using:

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


This is just for testing purposes to illustrate the difference:

\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}


This produces:

In both cases \varone has the definition Jake, but in the first case these four letters have category code 11 (which matches the string Jake) whereas in the second case they have category code 12 (which doesn't match).

In this case you're better off using etoolbox instead:

\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}


This produces:

If you want some other comparison, you'll need to add some example code.

• Thanks Nicola! For some reason when I try to compare any of the \varone, vartwo etc. with xstring.sty, it always returns false. Could this also be related to \expandafter? – Lesik2008 Nov 22 '16 at 18:01
• @Lesik2008 It sounds more like it's related to the category code used in \jobname. I've edited my answer. – Nicola Talbot Nov 22 '16 at 19:08

A different implementation with expl3; the file was named 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}
`