2

Question

Is it possible to get and store a count of the optional arguments actually passed to an xparse declare argument/environment?

Purpose

Regardless of the number of arguments provided (arbitrary depending on situation), I want to do something very specific with the last one given. Because this is a variable number, I need to retrieve the count of arguments given and use that combined with # to do something with that variable.

Code

\documentclass{article}
\usepackage{fontspec}
\usepackage{xparse}

\DeclareDocumentEnvironment{myenv}{O{}O{}O{}O{}O{}O{}O{}O{}O{}O{}} % 10 optional args
{startcode}
{endcode}

\DeclareDocumentCommand{\mycom}{O{}O{}O{}O{}O{}O{}O{}O{}O{}O{}}{% 10 optional args
}%

\begin{document}

\mycom[a][b][c] % Count 3
% Do something special with #3

\begin{myenv}[a][b][c][d] % Count 4
% Do something special with #4
\end{myenv}

\end{document}
  • 1
    Simply check from the end if the optional argument has no value. But are you sure that a command with so many arguments is senseful? I avoid more then two arguments. – Ulrike Fischer May 6 '15 at 9:21
  • 3
    @macmadness86 You can't have more than nine arguments (like in all TeX macros). In any case, since the arguments would start from the beginning \IfValueTF{#9}{9 arguments}{\IfValueTF{#8}{8 arguments}{..}} would work. By the way, why not declare the last one as m mandatory, and the eight before as o? \foo[a][b][c][d]{e}. – Manuel May 6 '15 at 9:51
  • 1
    @macmadness86 If it's mandatory, it's the last one, so you know what argument you have to do the special thing to. I'm not really sure what your intentions are: surely this syntax is very clumsy and error prone. – egreg May 6 '15 at 11:38
  • 1
    using more than two optional arguments is a horrible user interface, can you not use a comma separated list? \foo[a,b,c,d,e,f] expl3 then makes it easy to count the list, iterate over it, select the last etc. – David Carlisle May 6 '15 at 12:04
  • 1
    sure but [][][] is the wrong input syntax for that (irrespective of coding and efficiency issues) – David Carlisle May 6 '15 at 12:30
4

You shouldn't use repeated [] arguments in this way. use a comma separated list for an arbitrary argument syntax.

enter image description here

\documentclass{article}

\usepackage{xparse,expl3}

\ExplSyntaxOn
\DeclareDocumentEnvironment{myenv}{O{}} 
{\doargs:n{#1}}
{}

\DeclareDocumentCommand{\mycom}{O{}}{
\doargs:n{#1}
}%
\clist_new:N\arglist

\cs_new_protected:Nn\doargs:n{{
\clist_set:Nn\arglist{#1}
[there ~are ~\clist_count:N\arglist{} ~ arguments]
[the ~last ~one ~is ~\clist_item:Nn\arglist{\clist_count:N\arglist}]
}}
\ExplSyntaxOff

\begin{document}

\mycom[a,b,c] % Count 3
% Do something special with #3

\begin{myenv}[a,b,c,d] % Count 4
% Do something special with #4
\end{myenv}

\end{document}
| improve this answer | |
  • Thank you for the excellent answer. Do you think you should show me how to iterate the parameters. e.g. My idea: user command variant and turn this: \noindent\clist_item:Nn\arglist{1},~\clist_item:Nn\arglist{2},~\clist_item:Nn\arglist{3},~\clist_item:Nn\arglist{4}\par into a loop. Each item can be put into a tabular using the trick you showed me \tabular{l{\arglist{\clist_count:N\arglist}}} (num of cols determined by clist_count). Each item (\clist_item:Nn\arglist{itemStep}) can be followed by & until column step=clist_count:N\arglist then a `\` is inserted. +1Automation – Jonathan Komar May 7 '15 at 8:38
  • 1
    @macmadness86 That's a new question really, but see texdoc interface3 from page 120 there are 10 pages of interesting functions you can apply to clists. – David Carlisle May 7 '15 at 8:48
  • +1 Thanks for the tip. I will hop to it. Just to clarify, this code with the ExplSyntaxOn/Off is fully backwards compatible? – Jonathan Komar May 7 '15 at 8:52
  • @macmadness86 backwards compatible with what? the only code there is the definition of a new command. – David Carlisle May 7 '15 at 10:07
  • I meant, can I compile this document on a machine with an older version of LaTeX, just by installing the expl3 package. I think I already found my answer though, and the answer is yes. – Jonathan Komar May 14 '15 at 7:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.