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.

The follow code returns -NoValue- instead of 3

It seems I'm wrong in that I thought xparse took a single argument and parsed it instead of all the arguments of a macro.

\documentclass[11pt]{book} % use larger type; default would be 10pt


\usepackage{pgffor}
\usepackage{xparse}

\begin{document}

\DeclareDocumentCommand{\Dotparse}{o m} { #1 }

% Passes each value in the array to an xparse command.
\def\Dots#1
{
    \foreach \n in {#1}{
        \Dotparse{\n}
}}

\Dots{[3]f4s3,f12s5,s2f14,[5]e,f,g,1,2,3,4,5,6,7}


\end{document}
share|improve this question

closed as too localized by egreg, Paulo Cereda, Yiannis Lazarides, Thorsten, lockstep Mar 17 '12 at 15:48

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.If this question can be reworded to fit the rules in the help center, please edit the question.

3  
Actually, \Dotparse[3]{f4s3} prints 3. \Dotparse{[3]f4s3} has no optional argument. :) –  Paulo Cereda Mar 16 '12 at 13:24
    
Ok, That makes sense... I simplified this example and didn't think about it. I'll post the full code. Actually, I had a misconception about xparse. I thought it took an argument and parsed it given the specification. –  Uiy Mar 16 '12 at 13:29
add comment

1 Answer

up vote 7 down vote accepted

First of all this is no bug. You defined a command \Dotparse with one mandatory and one optional argument.

The mandatory argument is braced by curly brackets {....} and the optional one by square brackets [...].

If you type \Dotparse{[3]f4s3} LaTeX reads only one mandatory argument because the outer brackets are {...}. So the correct form is \Dotparse[3]{f4s3} to set the optional and the mandatory argument.

The output -NoValue is a special key provided by xparse. xparse provides several optional argument types whereby o has the following meaning:

  • If no optional argument without square brackets is given the argument is set to \NoValue.
  • If square brackets are given the argument is set to this value.

Note: An empty optional arguments doesn't set \NoValue.

Based on this information you can use the conditional \IfNoValueTF to test whether an optional argument is given or not.

EDIT I can't understand your question. But your example looks really weird for me. You should tell us what's your intention.

You can do the following:

  1. Every definition of macros and functions should be done in the header.
  2. The variable \n must be expanded before the function \Dotparse works
  3. You need not to use extra brackets around the variable n.
  4. Use the argument type u which has the following syntax

    u<token>
    

    this argument type reads everything until the given token is found whereby the given token isn't part of the argument. I used the token \nil.

The whole example:

\documentclass[11pt]{book} % use larger type; default would be 10pt
\usepackage{pgffor}
\usepackage{xparse}
\DeclareDocumentCommand{\Dotparse}{o u \nil } {#1\textbullet }
\def\Dots#1
{
    \foreach \n in {#1}{
     \n\qquad \expandafter\Dotparse\n\nil \par
}}
\begin{document}
\Dots{[3]f4s3,f12s5,s2f14,[5]e,f,g,1,2,3,4,5,6,7}
\end{document}

EDIT 2:

@BrunoLeFloch suggested an alternative using \clist_map_inline:Nn. In this way you don't need the package pgffor and you don't regard any expansion.

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\Dotparse}{o u \nil } 
 {
  \IfNoValueTF { #1 }
   {no~optional~Argument~given}
   {The~optional~argument~is~#1}
   \par
 }
\clist_new:N \l_dot_store_clist
\NewDocumentCommand{\Dots}{ m }
 {
 \clist_set:Nn \l_dot_store_clist { #1 }
 \clist_map_inline:Nn \l_dot_store_clist
   {
     \Dotparse ##1 \nil 
   }
 }  
\ExplSyntaxOff
\begin{document}
\Dots{[3]f4s3,f12s5,s2f14,[5]e,f,g,1,2,3,4,5,6,7}
\end{document}
share|improve this answer
    
What does \nil do? –  Tobi Mar 16 '12 at 14:43
1  
@Tobi: \nil is a single token and the argument type u reads everything until the given token is found. You can also use \hippopotamus ;-) –  Marco Daniel Mar 16 '12 at 16:19
1  
Instead of \foreach I'd use \SplitList and \tl_map_inline, or directly \clist_map_inline. That avoids loading pgffor. –  Bruno Le Floch Mar 16 '12 at 16:47
    
@BrunoLeFloch: You mean as an alternativ of the algorithm of the OP. The benefit I can avoid the expandafter ;-) –  Marco Daniel Mar 16 '12 at 16:48
2  
Your answer is very complete. One small improvement is that you don't need to store the clist in a temporary variable: just use \clist_map_inline:nn {#1}{\Dotparse ##1\nil}. As for the choice of syntax of the OP, well, let's simply dub it "non-standard". –  Bruno Le Floch Mar 16 '12 at 19:17
show 4 more comments

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