尝试定义多语言文本宏,为什么不起作用?

尝试定义多语言文本宏,为什么不起作用?

我正在尝试创建一个\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}

相关内容