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?

Jinwen
  • 8,518

2 Answers2

7

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

egreg
  • 1,121,712
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}

Mico
  • 506,678