Problem with command expansion
I wouldn't use long nested if-tests. This is difficult to expand.
\documentclass{article}
\ExplSyntaxOn
\tl_const:Nn \c__nvaughan_convert_es_tl{spanish}
\tl_const:Nn \c__nvaughan_convert_lat_tl{latin}
\tl_const:Nn \c__nvaughan_convert_eng_tl{english}
\tl_const:Nn \c__nvaughan_convert_deu_tl{german}
\tl_const:Nn \c__nvaughan_convert_enm_tl{spanish}
\newcommand*{\convertlang}[1]
{
\tl_if_exist:cTF {c__nvaughan_convert_#1_tl}
{ \tl_use:c {c__nvaughan_convert_#1_tl} }
{ english}
}
\newcommand*{\langtest}[1]{%
\str_if_eq:eeTF {\convertlang{#1}}{spanish}
{True}{False}}
\ExplSyntaxOff
\begin{document}
Testing: \convertlang{es} % yields: spanish
\convertlang{lat} \convertlang{blub}
\langtest{es} % should yield: True
\end{document}
I'd use the simpler interface of expl3
with \str_case:nnF
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewExpandableDocumentCommand{\convertlang}{m}
{
\nvaughan_convertlang:n { #1 }
}
\cs_new:Nn \nvaughan_convertlang:n
{
\str_case:nnF { #1 }
{
{es}{spanish}
{lat}{latin}
{eng}{english}
{deu}{german}
{enm}{spanish}
}
{english}
}
\NewExpandableDocumentCommand{\langtest}{m}
{
\str_if_eq:eeTF { \nvaughan_convertlang:n { #1 } } { spanish } { True } { False }
}
\ExplSyntaxOff
\begin{document}
Testing: \convertlang{es} % yields: spanish
\langtest{es} should yield: True
\langtest{lat} should yield: False
\end{document}
You can use the expandable and expanding string equality test \pdfstrcmp
(for portability use \pdf@strcmp
from pdftexcmds
, see for example Are there any "if" commands like "\ifnum" in LaTeX?). That command expands its test arguments and is itself expandable. (The latter is always nice, the former is not always convenient [cf. https://tex.stackexchange.com/q/230878/35864], but is what we want here.)
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{etoolbox}
\usepackage{pdftexcmds}
\makeatletter
\newcommand*{\IfStrEqualTF}[2]{%
\ifnum\pdf@strcmp{#1}{#2}=\z@
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi}
\makeatother
\newcommand*{\convertlang}[1]{%
\IfStrEqualTF{#1}{es}
{spanish}
{\IfStrEqualTF{#1}{lat}
{latin}
{\IfStrEqualTF{#1}{eng}
{english}
{\IfStrEqualTF{#1}{deu}
{german}
{\IfStrEqualTF{#1}{enm}
{spanish}
{english}}}}}}
\newcommand*{\langtest}[1]{%
\IfStrEqualTF{\convertlang{#1}}{spanish}
{True}
{False}}
\begin{document}
Testing: \convertlang{es} % yields: spanish
\langtest{es} % should yield: True
\langtest{en} % should yield: False
\end{document}
Some more details about the MWE and why it doesn't do the desired thing.
First of all, etoolbox
's \ifstrequal
is defined with \newrobustcmd
. It is therefore robust and not expandable. That means that
\edef\temp{\convertlang{#1}}
does not actually save the long language name in \temp
as we would have hoped. It just saves a cascade of \ifstrequal
tests. This means that \temp
does not contain a simple string.
\edef\temp{\convertlang{es}}%
\show\temp
gives
> \temp=macro: ->\ifstrequal {es}{es}{spanish}{\ifstrequal {es}{lat}{latin}{\ifstrequal {es}{eng}{english}{\ifstrequal {es}{deu}{german}{\ifstrequal {es}{enm}{spanish}{english}}}}}.
You need a string equality test that is expandable to allow \convertlang{#1}
to expand to the language name in an \edef
.
\pdf@strcmp
comes in handy here, since its string comparison is expandable, meaning that a command defined via this equality test can expand to the result of the comparisons in an \edef
.
The second issue is that \ifstrequal
doesn't expand its arguments, so even if \temp
contained only a string, the test wouldn't quite work as intended
\def\temp{spanish}%
\ifstrequal{\temp}{spanish}{True}{False}%
still gives 'False', since \temp
is not a string equal to spanish
, it expands to a string equal to spanish
, that is a small but significant difference.
There are several possible ways around that. Depending on what you can guarantee about \temp
it would be enough to say
\expandafter\ifstrequal\expandafter{\temp}{spanish}{True}{False}%
or
\ifdefstring{\temp}{spanish}{True}{False}%
if you know that \temp
expands to a string in one expansion step. If more steps are required or you want full expansion, other tricks are needed.
\pdf@strcmp
helps here, because it just completely expands its argument. This means that as long as \temp
does not contain anything that blows up in an expansion context, its 'ultimate expanded string value' can be compared. You need not worry about expanding it first for the test.