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 am trying to programme a command in x parse that has one optional argument, but which can behave in three ways in the following situations: a) no argument specified, b) optional argument specifies a specific value (p), c) optional argument specifies a different value (q).

The commands would look as follows:

\command

\command[p]

\command[q]

and would give the result

command

command preface

command q

I have tried to use the star and token arguments instead of the standard optional argument but the documentation is very sparse for the package and I cannot work out, even from looking at examples on this site, how I might achieve the above.

My attempt was as follows:

\documentclass{article}
\usepackage{xparse}

\NewDocumentCommand \command { tp } {%
    \IfNoValueTF{#1}{%
    command}%
    {{\IfBooleanTF{#1}%
    {command preface}%
    {command #1}%
    }}}

\begin{document}

\command
\command[p]
\command[10]

\end{document}
share|improve this question
    
–1: Questions only asking “do it for me” or the like are not really welcome here. Please add a MWE showing your own efforts and I’ll be happy to take my downvote back ;-) –  Tobi Nov 26 '13 at 11:14
    
xparse is meant to grab arguments: further processing of the content is left to 'other code'. What have you tried so far? –  Joseph Wright Nov 26 '13 at 11:16
    
Tobi: I thought I might get that response, but I genuinely tried and my efforts were so far from working that I didn't see much point in posting them. Truth is, I didn't really know where to start with the problem. I would have been happy with a response like "here is a site that explains xparse in more detail than the documentation" rather than an actual solution, as I could not find such a resource. –  David Rowthorn Nov 26 '13 at 11:34
    
@DavidRowthorn: Hm … showing some code even if it don’t work will help. I don’t like questions that have the “just do it for me” attitude – and your’s looks that way ;-) But as you can see in the fact that I provided an answer I’m not that upset ;-) and I redeem my downvote. (ps. Note that you need an @ in front of a name to get the user notified …) –  Tobi Nov 26 '13 at 12:06
1  
Since your interface doens’t make sense to me I can hardly tell how to improve your attempt, but see what I added to my answer. –  Tobi Nov 26 '13 at 12:18
show 3 more comments

2 Answers 2

up vote 2 down vote accepted

You don’t need xparse in that case. You can do a case switch with the xstring package:

\documentclass{article}

\usepackage{xstring}

% with xstring
\newcommand{\mycmd}[1][-no-value-]{%
   command does
   \IfStrEqCase{#1}{%
      {-no-value-}{no value}%
      {p}{preface}%
   }[#1 value]
   stuff
}

% a more clever version (see comments) with xparse
\usepackage{xparse}
\NewDocumentCommand{\myothercmd}{ o }{%
   command does
   \IfNoValueTF{#1}{no value}{%
      \IfStrEq{#1}{p}{preface}{#1}%
   }
   stuff
}

\begin{document}
\mycmd

\mycmd[p]

\mycmd[q]

\mycmd[-no-value-] is a 'wrong' argument and confuses the code.
So it should be something where you are sure that it won't be the
argument of \verb+\mycmd+

\bigskip
\myothercmd

\myothercmd[p]

\myothercmd[q]

\mycmd[-NoValue-] \texttt{xparse} know how to handle this.
\end{document}

Trying to correct your attempt gives

\NewDocumentCommand \yourcmd { t{+} o } {%
   \IfBooleanTF{#1}{command preface}{%
      \IfNoValueTF{#2}{%
         command%
      }{%
         command #2%
      }%
   }%
}

As you can see the p argument take an argument specifying the <token> that should be tested this toke cant be a letter, e.g. p, because \yourcmdp will be another command in TeX’s eyes and not \yourcmd followed by token p. The corrected version can be used as

\yourcmd
\yourcmd+
\yourcmd[q]
\yourcmd+[q]

giving

command
command preface
command q
command preface

share|improve this answer
    
Note that xparse's -NoValue- is not returned if you do \mycmd[-NoValue-], i.e (without significant effort) you can't 'confuse' the code with the 'wrong' optional argument. –  Joseph Wright Nov 26 '13 at 11:15
    
So you mean, that I should prefer the xparse way instead my own -no-value- approach? –  Tobi Nov 26 '13 at 11:16
    
Depends on the use case: usually you don't need to worry about users entering 'difficult' values, but it is at least worth being aware of. –  Joseph Wright Nov 26 '13 at 11:17
    
I was aware of the fact that my approach is confusable in that way but I wasn’t aware of the fact that xparse is more clever. Thanks! –  Tobi Nov 26 '13 at 11:24
    
I was not aware of the xstring package, but it is exactly what I needed. thanks –  David Rowthorn Nov 26 '13 at 13:43
add comment

xparse doesn't provide helpers for this situation, so going deeper with comparing strings is necessary.

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\command}{o}
 {
  \IfNoValueTF{#1}
   {
    <No optional value code>
   }
   {
    \rowthorn_check_argument:n { #1 }
   }
 }

\cs_new:Npn \rowthorn_check_argument:n #1
 {
  \str_case:nnF { #1 }
   {
    {p}{ \rowthorn_command:n { Preface } }
   }
   { \rowthorn_command:n { #1 } }
 }

\cs_new_protected:Npn \rowthorn_command:n #1
 {
  <do something with #1>
 }
\ExplSyntaxOff

\begin{document}

\command

\command[p]

\command[Introduction]

\end{document}

I don't think this is a good interface, though.

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.