在我的一个包中有很多行这样的代码:
\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 建议使用etoolbox
或expl3
。因此我想问一下我应该如何定义\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}