Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I have a command defined using xparse syntax:

\DeclareDocumentCommand \foo { O{} m } {}

Inside some other command (say, \bar), I want to call this command. The calling command (\bar) has to construct the arguments to feed to \foo. So the call is something like:

\foo [\tl_use:N \l_my_temporary_tl] {}

I want to make sure that when \foo is called, it is the actual token list and not the command that gets passed.

If \foo took two mandatory arguments then it would appear that I could just do

\exp_args:No \foo {\tl_use:N \l_my_temporary_tl} {}

(I realise that the number of expansions here might be incorrect, but that's not the point.)

Is there a similar syntax for optional arguments?

If not, how would the following look:

\cs_new:Npn \exp_opt_args:No #1[#2] { \exp_after:wN #1 \exp_after:wN [#2] }

and similar ...

share|improve this question
3  
xparse is for document commands. Could you add a concrete example of where this is needed at a document level? (Usually, a function defined by xparse should simply pass the input to a well-defined code-level function with a fixed number of mandatory arguments.) –  Joseph Wright Aug 25 '11 at 8:51
    
@Joseph: I hadn't thought of that solution, though it makes perfect sense. My actual example is pretty close to what I describe: I have a command that I sometimes call in the document (hence a DocumentCommand) but sometimes I need to call it with a bit of preprocessing (hence the wrapper command). But making both wrappers to a single code-level function would work just fine, I guess. –  Andrew Stacey Aug 25 '11 at 9:01
add comment

2 Answers

up vote 9 down vote accepted

The short answer is that there is no mechanism to do that, because we try to promote separating user interface (through xparse, and the choice of having optional, mandatory, delimited arguments and whatnot) from the coding part.

In most situations I can think of, you could convert the code to

\DeclareDocumentCommand {\foo} { o m }
  {
    \IfValueTF {#1}
      { \mypkg_foo:nn {#1} {#2} }
      { \mypkg_foo:n {#2} }
  }

Then your call would be \exp_args:NV \mypkg_foo:nn \l_my_temporary_tl {}, using the internal version and skipping the parsing. Note that I'm using a V argument type to avoid worrying about what kind of variable is used: it will insert \the when necessary. It would also be possible to use o, since token lists expand in one step. \tl_use:N is a rather odd beast, which I've never seen a use for so far.

Perhaps it is not possible in your case. Then you can use either of

\use:x { \foo [ { \exp_not:V \l_my_temporary_tl } ] { } }

where \foo is not expanded since xparse's commands are protected (unless explicitly made not to be), and \exp_not:V makes sure that the token list does not expand too far. Or,

\exp_args:NNV \foo [ \l_my_temporary_tl ] { }

which is somewhat a kludge. Note that in both cases, I put braces around the optional argument within brackets: if \l_my_temporary_tl has unbalanced brackets, the wrong optional argument would be grabbed otherwise.

share|improve this answer
    
Both yours and Joseph's have the solution that I'm now using (that of having the DocumentCommand a wrapper to an internal one) but yours gets the "accepted" for the additional explanation of the V argument type. –  Andrew Stacey Aug 25 '11 at 9:15
add comment

Broadly, creating document commands (i.e. user syntax) should always be done as a wrapper around internal functions which take only mandatory arguments. Thus is we have two functions \foo and \bar, at the document level with some relationship, then internally they should be linked using code-level functions

\DeclareDocumentCommand \foo { O{} m }
  {
    \IfNoValueTF {#1}
      { \foo_int:n {#2} }
      { \foo_int:nn {#1} {#2} }
  }
\DeclareDocumentCommand \bar { O{} m }
  {
    \tl_set:Nx \l_my_temporary_tl
      { \IfNoValueF {#1} { \exp_not:n {#1} : \exp_not:n {#2} }
    \foo_int:Vn \l_my_temporary_tl {#2}
  }

Here, I'm setting \l_my_temporary_tl in an arbitrary fashion, simply so there is something there for the demo.

(More generally, I'd expect \bar to call a separate function internally, which would then deal with the input.)

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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