我正在尝试创建一个\projlib_langauge_define_multilingual_text:Nn
用于创建多语言文本宏的命令。给定一个宏名称\<name>
和文本的键值配置(english = ..., french = ...
),它应该创建子宏\<name>_projlib_language_text_<languagename>
,并定义主宏\<name>
以相应地引用它们。
下面是我当前的尝试,它产生了一些错误Undefined control sequence
。
到底哪里出了问题?
\documentclass{article}
\ExplSyntaxOn
\cs_new:Nn \projlib_langauge_define_multilingual_text:Nn
% #1 = command name
% #2 = key-value name configuration
{
\keyval_parse:nnn
{}
{
\__projlib_langauge_define_multilingual_text_do:nnn
{ \cs_to_str:N #1 }
}
{ #2 }
\tl_new:c { #1 }
\tl_set:cn { #1 }
{
\tl_use:c { #1 _projlib_language_text_ \languagename }
}
}
\cs_generate_variant:Nn \projlib_langauge_define_multilingual_text:Nn { cn }
\cs_new:Nn \__projlib_langauge_define_multilingual_text_do:nnn
% #1 = command name
% #2 = language name
% #3 = the text
{
\exp_args:Nx \tl_new:c { #1 _projlib_language_text_ \projlib_language_str_to_languagename:n { #2 } }
\exp_args:Nx \tl_set:cn { #1 _projlib_language_text_ \projlib_language_str_to_languagename:n { #2 } } { #3 }
}
\cs_new:Nn \projlib_language_str_to_languagename:n
{
\str_case_e:nn { \str_foldcase:n { #1 } }
{
{en} {english}
{english} {english}
{fr} {french}
{french} {french}
}
}
\ExplSyntaxOff
\usepackage[french,english]{babel}
\begin{document}
\ExplSyntaxOn
\projlib_langauge_define_multilingual_text:Nn \test_text
{
EN = Some english text,
FR = Quelques textes en français,
}
% Should produce \test_text_projlib_language_text_english and \test_text_projlib_language_text_french, and define \test_text to call them accordingly
\selectlanguage{french}
% Should be >> Quelques textes en français
\test_text
\selectlanguage{english}
% Should be >> Some english text
\test_text
\ExplSyntaxOff
\end{document}
添加:David Carlisle 的接受答案(以及他在问题下的评论)善意地提醒了最危险的语法错误。上面的代码仍然存在一些小的逻辑错误,对此,下面发布了更正后的版本作为答案供您参考。
答案1
错误expl3
在于(正如错误消息所说)没有tl_new:cn
您需要将声明与\tl_new
和设置与分开\tl_set
,那么其余的错误就是\selectlanguage
使用中的拼写错误。
\documentclass{article}
\ExplSyntaxOn
\cs_new:Nn \projlib_langauge_define_multilingual_text:Nn
% #1 = command name
% #2 = key-value name configuration
{
\keyval_parse:nnn
{}
{
\__projlib_langauge_define_multilingual_text_do:nnn
{ \cs_to_str:N #1 }
}
{ #2 }
\tl_set:cn { #1 }
{
\tl_use:c { #1 _projlib_language_text_ \languagename }
}
}
\cs_generate_variant:Nn \projlib_langauge_define_multilingual_text:Nn { cn }
\cs_new:Nn \__projlib_langauge_define_multilingual_text_do:nnn
% #1 = command name
% #2 = language name
% #3 = the text
{
\exp_args:Nx \tl_set:cn { #1 _projlib_language_text_ \projlib_language_str_to_languagename:n { #2 } } { #3 }
}
\cs_new:Nn \projlib_language_str_to_languagename:n
{
\str_case_e:nn { \str_foldcase:n { #1 } }
{
{en} {english}
{english} {english}
{fr} {french}
{french} {french}
}
}
\ExplSyntaxOff
\usepackage[french,english]{babel}
\begin{document}
\ExplSyntaxOn
\tl_new:N\test_text
\projlib_langauge_define_multilingual_text:Nn \test_text
{
EN = Some english text,
FR = Quelques textes en français,
}
% Should produce \test_text_projlib_language_text_english and \test_text_projlib_language_text_french, and define \test_text to call them accordingly
\selectlanguage{french}
% Should be >> Quelques textes en français
\test_text
\selectlanguage{english}
% Should be >> Some english text
\test_text
\ExplSyntaxOff
\end{document}
答案2
原始代码中有几处混淆了c
参数N
类型。正确的版本应该是:
\documentclass{article}
\ExplSyntaxOn
\cs_new:Nn \projlib_langauge_define_multilingual_text:Nn
% #1 = command name
% #2 = key-value name configuration
{
\keyval_parse:nnn
{}
{
\__projlib_langauge_define_multilingual_text_do:nnn
{ \cs_to_str:N #1 }
}
{ #2 }
\tl_set:Nn #1
{
\tl_use:c { \cs_to_str:N #1 _projlib_language_text_ \languagename }
}
}
\cs_generate_variant:Nn \projlib_langauge_define_multilingual_text:Nn { cn }
\cs_new:Nn \__projlib_langauge_define_multilingual_text_do:nnn
% #1 = command name
% #2 = language name
% #3 = the text
{
\exp_args:Nx \tl_set:cn { #1 _projlib_language_text_ \projlib_language_str_to_languagename:n { #2 } } { #3 }
}
\cs_new:Nn \projlib_language_str_to_languagename:n
{
\str_case_e:nn { \str_foldcase:n { #1 } }
{
{en} {english}
{english} {english}
{fr} {french}
{french} {french}
}
}
\ExplSyntaxOff
\usepackage[french,english]{babel}
\begin{document}
\ExplSyntaxOn
\tl_new:N\test_text
\projlib_langauge_define_multilingual_text:Nn \test_text
{
EN = Some\ english\ text,
FR = Quelques\ textes\ en\ français,
}
% Should produce \test_text_projlib_language_text_english and \test_text_projlib_language_text_french, and define \test_text to call them accordingly
\selectlanguage{french}
% Should be >> Quelques textes en français
\test_text\\
\selectlanguage{english}
% Should be >> Some english text
\test_text\\
% \cs_meaning:N \test_text\\
% \test_text_projlib_language_text_english\\
% \test_text_projlib_language_text_french\\
--
\ExplSyntaxOff
\end{document}