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}
16
  • 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. May 6, 2015 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, 2015 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, 2015 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. May 6, 2015 at 12:04
  • 1
    sure but [][][] is the wrong input syntax for that (irrespective of coding and efficiency issues) May 6, 2015 at 12:30

1 Answer 1

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}
5
  • 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 May 7, 2015 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. May 7, 2015 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? May 7, 2015 at 8:52
  • @macmadness86 backwards compatible with what? the only code there is the definition of a new command. May 7, 2015 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. May 14, 2015 at 7:18

You must log in to answer this question.

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