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'm defining a new command which should take an optional list of arguments (integers or ranges):

\doit[3,5-7,9]{something}

What I have so far:

\def\doit{\@ifnextchar[{\@with}{\@without}}
\def\@with[#1]#2{
  ...
}
\def\@without#1{
}

In the with case, how can I iterate over the optional arguments? How can I distinguish between integers and ranges? Do I need to do the parsing manually or there are tools which can help me?

share|improve this question
2  
I bet pgf is able to handle such things. –  canaaerus Jul 27 '12 at 11:20
    
Any pointer or minimal? –  Roberto Aloi Jul 27 '12 at 11:31
    
The package etoolbox offers \docsvlist for list-parsing. –  cgnieder Jul 27 '12 at 11:40

2 Answers 2

up vote 6 down vote accepted

If changing the - character to ,..., is feasible for you, you can directly and easily benefit from the power of the pgffor module of TikZ/PGF. Please check the manual for other types that are supported. Here is an example with also non-numeric lists:

\documentclass{article}
\usepackage{pgffor}
\makeatletter
\def\doit{\@ifnextchar[{\@with}{\@without}}
\def\@with[#1]#2{
#2 have the following list:%
\foreach \x in {#1}{
\x,%
    }
}
\def\@without#1{
#1, I have no optional arguments.
}
\makeatother

\begin{document}
\doit[1,...,5,7]{I}

\doit{Ahem}

\doit[1,3$\pi$,4$\pi$,...$\pi$,7$\pi$,e,f,...,i]{Also I}
\end{document}

enter image description here

share|improve this answer
    
This is so beautiful. –  Roberto Aloi Jul 30 '12 at 14:33

You can use the splitting argument facilities provided by xparse:

\documentclass{article}
\usepackage{xparse}
\newcommand{\doittemp}{}
\NewDocumentCommand{\doit}{>{\SplitList{,}}om}{%
  \renewcommand\doittemp{#2}%
  \IfNoValueTF{#1}
    {\par (main argument \doittemp)}
    {\ProcessList{#1}{\doitauxi}}%
}
\NewDocumentCommand{\doitauxi}{>{\SplitArgument{1}{-}}m}{\doitauxii #1}
\NewDocumentCommand{\doitauxii}{mm}{%
  \IfNoValueTF{#2}
   {\par Single number #1 (main argument \doittemp)}
   {\par Range #1--#2 (main argument \doittemp)}%
}

\begin{document}
\doit{No optional argument}
\bigskip

\doit[1,2]{Two single numbers}

\bigskip

\doit[1,3-5]{Single number and range}

\bigskip

\doit[1-3,5-10]{Two ranges}

\end{document}

enter image description here

share|improve this answer

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.