6

In a package of mine there are many lines of code like this:

    \lowercase{\IfStrEqCase{#1}}{%
        {cn}{\PJLlang@langconfig@SC}%
        {chinese}{\PJLlang@langconfig@SC}%
        {schinese}{\PJLlang@langconfig@SC}%
        {simplifiedchinese}{\PJLlang@langconfig@SC}%
        {tc}{\PJLlang@langconfig@TC}%
        ...

The code receives a string (like "Chinese" or "SC"), converts it to the corresponding abbreviation (like "SC"), and run the corresponding command. Since code of this type appears quite a lot in this package, as an attempt to simplify the code, I defined a command \StrToABBR for this propose:

\NewDocumentCommand{\StrToABBR}{m}{%
    \expandafter\lowercase{\IfStrEqCase{#1}}{%
        {cn}{SC}%
        {chinese}{SC}%
        {schinese}{SC}%
        ...
    }%
}

However, as @moewe pointed out in the comment of this question, it is not expandable and thus cannot appear in \csname...\endcsname, thus \csname PJLlang@langconfig@\StrToABBR{#1}\endcsname won't work. In the comment of the same question, Ulrike Fischer suggests to use etoolbox or expl3. Thus I wish to ask that how should I define \StrToABBR with expl3 to allow it appear in \csname...\endcsname?

2 Answers 2

8

Here's a fully expandable version:

\documentclass{article}

\ExplSyntaxOn

\NewExpandableDocumentCommand{\StrToABBR}{m}
 {
  \str_case_e:nn { \str_foldcase:n { #1 } }
   {
    {cn}{SC}
    {chinese}{SC}
    {schinese}{SC}
   }
 }

\ExplSyntaxOff

\begin{document}

\StrToABBR{cn}
\StrToABBR{Cn}
\StrToABBR{CN}
\StrToABBR{chinese}
\StrToABBR{SChinese}

\edef\test{\StrToABBR{Chinese}}
\texttt{\meaning\test}

\end{document}

enter image description here

0
3

Here's another fully-exandable implementation of \StrToABRR. It uses Lua's powerful string.gsub function and must therefore be compiled with LuaLaTeX.

enter image description here

\documentclass{article}
\directlua{
function str2abbr ( s )
   s = string.lower ( s )
   s = s:gsub ( "s?chinese" , "SC" ) % "s?" means "0 or 1 instance of 's'"
   s = s:gsub ( "cn" , "SC" )
   return s
end
}
\newcommand\StrToABBR[1]{\directlua{tex.sprint(str2abbr("#1"))}}
 
\begin{document} 
% The body of the 'document' environment is identical to the one in 
% egreg's answer at https://tex.stackexchange.com/a/610146/5001

\StrToABBR{cn}
\StrToABBR{Cn}
\StrToABBR{CN}
\StrToABBR{chinese}
\StrToABBR{SChinese}

\edef\test{\StrToABBR{Chinese}}
\texttt{\meaning\test}
\end{document}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .