1

I am trying to create a command \projlib_langauge_define_multilingual_text:Nn for creating multilingual text macros. Given a macro name \<name>, and a key-value configuration of texts (english = ..., french = ...), it should create sub-macros \<name>_projlib_language_text_<languagename>, and define the main macro \<name> to refer to them accordingly.

Below is my current attempt, which produces a few errors of Undefined control sequence.

Where does it go wrong?

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

ADD: The accepted answer (alongside with his comments under the question) of David Carlisle kindly reminded the most dangerous syntax errors. The code above remains a few minor logical errors, for which the corrected version is posted below as an answer for your reference.

6
  • \tl_new:N or \tl_new:c just take the command name to be declared, not a n argument with the value, did you intende \tl_const:cn ? or \tl_new followed by tl_set ? Commented Feb 6, 2022 at 15:48
  • more generally if a comand is not documented in textdoc interface3 then it is not defined by default. Commented Feb 6, 2022 at 15:50
  • @DavidCarlisle Thank you, I confused with \cs_new:cn. But even if I change them to \tl_new followed by \tl_set, it still have several errors. Commented Feb 6, 2022 at 15:53
  • If I make that change I get ! Undefined control sequence. l.60 \seleclanguage as you have not defined that. Is this a typo for selecTlanguage? Commented Feb 6, 2022 at 15:55
  • then ! Package babel Error: You haven't defined the language 'language' yet. What did you expect \selectlanguage{language} to do? Commented Feb 6, 2022 at 15:57

2 Answers 2

0

The expl3 error is that (as the error message says) there is no tl_new:cn you need to separate thedeclaration with \tl_new and setting with \tl_set, then the remaining errors were typos in the \selectlanguage use.

\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} 
4
  • Thank you, but there should exist some other mistakes, as the edited code still can't compile. I'm getting error messages Undefined control sequence. \test_text. Commented Feb 6, 2022 at 16:02
  • @Jinwen you do not get that error with the code as above. that is why it has \tl_new:N\test_text The code posted runs without error. Commented Feb 6, 2022 at 16:07
  • Ah, the error is actually Latexmk: Log file says no output from latex, so there is no LaTeX error, but there are logical errors as \test_text shouldn't be empty. Commented Feb 6, 2022 at 16:12
  • @Jinwen ah.there is that! I get no error but no output either, but I don't really know what the code's doing I just fixed the syntax errors, I'll let you debug for a bit, ask a new question if it's not clear Commented Feb 6, 2022 at 16:16
0

There are several places in the original code that confuse c and N type argument. The correct version should be:

\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} 
2
  • it would probably be less confusing for future readers if you accepted this one (I can manage without the 15 points:-) Commented Feb 6, 2022 at 16:24
  • @DavidCarlisle I understand but surely your answer is more useful. I'm just posting the final version for future reference. Maybe it will be more helpful if I mention it under the question. Commented Feb 6, 2022 at 16:28

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.