3

I would like to use some macros as arguments with xparse. I need it because I use siunitx. Here is a simplified code which compiles:

\documentclass[a4paper]{article} 
\usepackage{xparse} 
\usepackage{siunitx} 
 
\ExplSyntaxOn 
 
\NewDocumentCommand{\onemacro}{m}{ 
        Length~is~ \qty{8}{#1}. 
} 
\NewDocumentCommand{\multiplemacro}{m}{ 
 
        \clist_new:N \l_my_clist 
        \clist_set:Nn \l_my_clist {#1} 
 
        first~length: \qty{5}{\clist_item:Nn \l_my_clist {1}} \par 
        second~length: \qty{8}{\clist_item:Nn \l_my_clist {2}} 
 
} 
\ExplSyntaxOff 
 
\begin{document} 
 
\onemacro{\candela} 
 
\multiplemacro{cm,candela} 
 
\end{document} 

When I use a list with more than one argument, it only works if the arguments are not macros. As soon as I change to

\multiplemacro{\cm,\candela}

Here I have two macros as arguments, I get:

! Undefined control sequence.
\cm ->\ERROR 
             
l.25 \multiplemacro{\cm,\candela}

How is it possible to pass more than one macro as arguments to another macro. Or: how can I convert some strings to macros. For example: how to convert the string cm to the macro \cm for siunitx.

5
  • Seems like a common case of user not understanding how expansion works in TeX. Try \exp_args:Nnx \qty{5}{\clist_item:Nn \l_my_clist {1}}.
    – user202729
    May 3, 2022 at 5:50
  • @user202729 I would like to understand better the problem. What is the best way ? To open another question ? Or could you describe the problem briefly. If I open another question, it would be in a few days, it's the necessary time for me to better understand the expansion.
    – Luc Armand
    May 4, 2022 at 21:27
  • Well you can post another question. Try to make it canonical/easy to find (it does annoy me a bit we don't have a canonical -- or at least I can't easily find one. Intend to for a while Should we post a general question regarding "why can't I use this macro inside this other macro"? - TeX - LaTeX Meta Stack Exchange (your case is case 3.) but didn't have the motivation to...)
    – user202729
    May 5, 2022 at 5:38
  • the alternative is to read the books and learn yourself. Generally people agree that Knuth did a good job explaining, for those who are willing to devote effort into learning an unconventional programming language. // (okay the next part is a bit irrelevant) There's also the issue that the experienced people spend lots of effort writing answer to specific questions, but doesn't make a canonical one... so they just fell into obscurity. (and the maybe-way-too-relaxed attitude towards duplicate closure etc.)
    – user202729
    May 5, 2022 at 5:39
  • Thank you! I think I need first to take time to read the book. After that, if the question remains, I could think about posting a new one.
    – Luc Armand
    May 5, 2022 at 5:46

2 Answers 2

3

This relates to how siunitx checks if a unit is entirely symbolic. I have traditionally used expansion, but that can fail in some cases. I will therefore switch to a double-expansion approach. Pending release as v3.1.1, you can use

\prg_set_protected_conditional:Npnn \__siunitx_unit_if_symbolic:n #1 { TF }
  {
    \group_begin:
      \bool_set_true:N \l__siunitx_unit_test_bool
      \protected@edef \l__siunitx_unit_tmp_tl {#1}
      \protected@edef \l__siunitx_unit_tmp_tl { \l__siunitx_unit_tmp_tl }
    \exp_args:NNV \group_end:
    \tl_if_blank:nTF \l__siunitx_unit_tmp_tl
      { \prg_return_true: }
      { \prg_return_false: }
  }

to import the updated code into an older v3.1.x or v3.0.x siunitx.


If you are wondering 'why not a trial-typesetting approach', that fails to catch input such as \second{}, which is not strictly correct but which would give zero-width output. It would also hinder running the formatter in the preamble: one of the design aims in v3 was that this really should be workable.

2

This works, but it might be something Joseph Wright should look at:

\documentclass[a4paper]{article}
\usepackage{xparse}
\usepackage{siunitx}

\ExplSyntaxOn

\NewDocumentCommand{\onemacro}{m}
 {
  Length~is~ \qty{8}{#1}.
 }

\NewDocumentCommand{\multiplemacro}{m}
 {
  first~length:~ \exp_args:Nnx \qty{5}{\clist_item:nn {#1}{1}} \par
  second~length:~ \exp_args:Nnx \qty{8}{\clist_item:nn {#1}{2}}
 }
\ExplSyntaxOff

\begin{document}

\onemacro{\candela}

\multiplemacro{\cm,\candela}

\end{document}

enter image description here

Note that you don't need to set a clist; anyhow, \clist_new:N should be outside the definition of the command.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .