如何使用 expl3 实现这个 \StrToABBR 以使其出现在 \csname...\endcsname 中?

如何使用 expl3 实现这个 \StrToABBR 以使其出现在 \csname...\endcsname 中?

在我的一个包中有很多行这样的代码:

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

代码接收一个字符串(如“Chinese”或“SC”),将其转换为相应的缩写(如“SC”),并运行相应的命令。由于这种类型的代码在这个包中出现得相当多,为了简化代码,我\StrToABBR为此定义了一个命令:

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

然而,正如@moewe在评论中指出的那样这个问题,它不可扩展,因此不能出现在中\csname...\endcsname,因此\csname PJLlang@langconfig@\StrToABBR{#1}\endcsname不起作用。在同一个问题的评论中,Ulrike Fischer 建议使用etoolboxexpl3。因此我想问一下我应该如何定义\StrToABBR才能expl3让它出现在中\csname...\endcsname

答案1

这是一个完全可扩展的版本:

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

在此处输入图片描述

答案2

这是 的另一个完全可扩展的实现\StrToABRR。它使用了 Lua 的强大string.gsub功能,因此必须使用 LuaLaTeX 进行编译。

在此处输入图片描述

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

相关内容