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 a newbie at LaTeX programming, so please be patient. :-)

I am writing a .sty file which I want to include a command \dan which is overloaded with three separate versions depending on whether called with zero, one or two arguments.

E.g. I want:

\dan

to generate

Full English

\dan{streaky}

or

\dan{back}

to generate

streaky Bacon

or

back Bacon

respectively, and

\dan{streaky}{fried}

to generate

streaky Bacon with fried Eggs.

"streaky", "fried" etc. are just examples, the users should be able to input any argument.

I have looked into the xparse package, but am finding the documentation inpenetrable. Please can you advise on how to code this?

share|improve this question
2  
Are you sure that you want that syntax (which you can implement but) It does not follow the pattern of latex syntax which never uses differing numbers of brace groups. LaTeX syntax conventions would make \dan[sreaky,fried] far more preferable. Optional, so [] not {} and taking a comma separated list. –  David Carlisle Mar 12 '12 at 22:53
1  
I'm not fully decided on syntax yet, although I have a preference for the above as I think that will be most natural for the users. Thanks for your point though that optional parameters are usually in [] parentheses, that is something we need to consider - also a comma-separated list is an excellent alternative suggestion. –  dan8394 Mar 12 '12 at 22:59
3  
I recommend to remove your question "Also, is xparse stable enough to use to build a package that you plan to release on CTAN?" from this question and to ask it as a separate question. Also, as you say "I have looked into the xparse package, but am having no success", it's always good to show what you've tried so far. On the one hand, users here can perhaps give you the decisive clue how to go on, on the other hand your question won't be in danger of appearing as a "can i have teh codez plz" question. –  doncherry Mar 12 '12 at 23:10
    
Thanks doncherry. I have modified my question as you suggested. –  dan8394 Mar 13 '12 at 9:21
add comment

4 Answers

up vote 7 down vote accepted

This is how.

\documentclass[a4paper]{article}
\usepackage{xparse}

\NewDocumentCommand{\dan}{gg}
  {\IfNoValueTF{#2}
     {\IfNoValueTF{#1}
        {Full English}
        {#1 Bacon}%
     }
     {#1 Bacon with #2 Eggs}%
  }

\begin{document}

\dan

\dan{streaky}

\dan{back}

\dan{streaky}{fried}

\end{document}

This said, I advise you against doing so. Users of your package will have a bad time figuring out how to use the commands. Just changing the argument specifier in {oo} instead of {gg} the syntax would be more in line with the LaTeX conventions:

\dan

\dan[streaky]

\dan[back]

\dan[streaky][fried]

If you can be more precise about your intentions, a different strategy may be suggested.

share|improve this answer
    
This is extremely helpful, and just what I needed. Thanks very much. –  dan8394 Mar 12 '12 at 23:11
add comment

Here is a solution using catoptions package:

\documentclass{article}
\usepackage{catoptions}
\makeatletter
\newcommand*\dan[1][full]{%
  \def\do##1{%
    \ifnum\indrisnr>\@ne
      ,\space\iflastindris and\space\fi
    \fi
    \uselivecsn{dan:##1}%
  }%
  \indrisloop{#1}\do
}
% Default inner list parser = , (comma)
% Default outer list parser = ; (semicolon)
\newcommand*\setupdan[2][,;]{%
  \def\reserved@a##1##2##3\@nil{%
    \def\do####1##1####2##1####3\@nil{%
      \csn@edef{dan:\cpttrimspace{####1}}{\cpttrimspace{####2}}%
    }%
    \def\csv@do####1{\do####1##1##1\@nil}%
    \csv@@parse[##2]{#2}%
  }%
  \reserved@a#1,;\@nil
}
\makeatother

% Example:
\setupdan{%
  full,      Full English;
  streaky,   Streaky Bacon;
  back,      Back Bacon;
  fried,     Fried Egg;
  mushrooms, Grilled Mushrooms
}

\commentBegin
% The following is also possible:
\setupdan[=,]{%
  full       =Full English,
  streaky    =Streaky Bacon,
  back       =Back Bacon,
  fried      =Fried Egg,
  mushrooms  =Grilled Mushrooms
}
\commentEnd


\begin{document}
\begin{enumerate}
\item\dan
\item\dan[streaky]
\item\dan[back]
\item\dan[streaky, fried]
\item\dan[streaky, fried, mushrooms]
%\item\dan[xstreaky] % error: undefined
\end{enumerate}
\end{document}

enter image description here

share|improve this answer
add comment

As noted in the comments it is much more preferable to use a key value interface and the answer given by David Carlisle, gives the traditional LaTeX2e way. For more complicated packages, I would lean on using a PGF style of keys. If nothing the amount of users asking questions on this site about TikZ, indicates that there is a large community of users familiar with the PGF style key value interface.

\documentclass{article}
\usepackage[latin]{babel}
\usepackage{pgfkeys}
\begin{document}
%% Step one define family
\pgfkeys{/bacon/.is family}
%% Define your keys
\pgfkeys{/bacon
     type/.store in=\type,
     type/.default=streaky,
     cook/.store in=\cook,
     cook/.default=fried
}
%% Process keys and set defaults, for later use
\def\setdefaults{\pgfkeys{/bacon  
     type,cook
  }%
}
%
\setdefaults
\newcommand{\dan}[2][]{%
  \setdefaults
  \pgfkeys{/bacon #1}
   \def\baconfoods{
      \type\ cook \cook,
   }
  \baconfoods
}
\dan[type=shoulder bacon, cook=well]{}
\dan[type=streaky,cook]{}
\dan[type=streaky]{}
\dan{}
\end{document}

You get tremendous flexibilty with this approach.

share|improve this answer
add comment

As noted in comments I'd recommend using a more conventional LaTeX syntax. @egreg has given a LaTeX3 version, so here's using a loop from LaTeX2e:

\documentclass{article}

\makeatletter

\newcommand\dan[1][full]{%
\def\dansep{\def\dansep{, }}%
\@for\x:=#1\do{%
\dansep
\@nameuse{dan:\x}}}

\@namedef{dan:full}{Full English}
\@namedef{dan:streaky}{Streaky Bacon}
\@namedef{dan:back}{Back Bacon}
\@namedef{dan:fried}{Fried Egg}
\@namedef{dan:mushrooms}{Grilled Mushrooms}

\makeatother

\begin{document}

a \dan

b \dan[streaky]

c \dan[back]

e \dan[streaky,fried]

f \dan[streaky,fried,mushrooms]

\end{document}
share|improve this answer
    
+1 for \def\dansep{\def\dansep{, }}. The author of etoolbox uses it in other contexts. –  Ahmed Musa Mar 13 '12 at 0:32
    
I don't think this is what I need. I need to take general arguments, bacon, eggs, etc. are just placeholders. Sorry for not making that clear. –  dan8394 Mar 13 '12 at 9:18
    
Yes it was clear that it was a toy example, but I also assumed that your real example might require more than two items, which is why I generalised it to an arbitrary list. –  David Carlisle Mar 13 '12 at 9:30
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.