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 create a command that will take an index n as a parameter, and generate the the expanded form of this {a_1, a_2, a_3,...,a_n}.

For my first attempt, I tried to use the syntax suggested in pgffor: Special treatment for last item in \foreach-list and http://stackoverflow.com/questions/2561791/iteration-in-latex to create code that would output a_1 if the index was 1, and output a "," followed by a_n, if the index was not 1.

\usepackage{pgffor}
\newcommand{\sigi}[1]{\foreach \n [count=\ni] in {1,...#1}{%
    \ifnum\ni=1%
        \sigma_#1%
    \else%
        ,\sigma_#1%
}}

Unfortunately, I have worked with neither LaTeX for loops nor the pgffor package before, so I am unclear about how to interpret the compile error that occurs when I try to use this command as follows:

$\sigi{1}$

Error message:

! Undefined control sequence.
\pgffor@count@@parse ...mathresult }\pgfmathparse
                                                  {int(#3-1)}\let #1=\pgfmat...
l.363 \sigi{1}
share|improve this question
add comment

2 Answers 2

up vote 2 down vote accepted

The idea was ok, but there were several mistakes in your code. Here's a fixed version:

\documentclass{article}
\usepackage{pgffor,pgfmath}

\begin{document}

\newcommand{\sigi}[1]{\foreach \ni in {1,...,#1}{%
    \ifnum\ni=1
        \sigma_{\ni}%
    \else%
        ,\sigma_{\ni}%
    \fi
}}

$\sigi{12}$

\end{document}

The problems were:

  • missing pgfmath package
  • missing comma after ...
  • superfluous % after \ifnum\ni=1
  • the subscript of \sigma should be \ni, not #1, and it should be enclosed in braces (important when #1>9)
  • missing \fi
  • \foreach \n [count=\ni] was ok, but \foreach \ni is simpler
share|improve this answer
    
The superfluity of the % is somewhat minor, no? :-) (and your last point is quite true, but your corrected version does not take it into account) –  Mariano Suárez-Alvarez Feb 7 '13 at 21:00
1  
Regarding %: I was just trying to be thorough. A space (or \relax) after a numeral (which % inhibits) makes sure that TeX stops expanding the number. In the above case, TeX tried to expand \sigma, which was truly not problematic --- but I think that writing space after numerals is still a good habit to develop, because once the lack of it does cause trouble, you'll be debugging for hours ... trust me, I know ;-) –  Sašo Živanović Feb 7 '13 at 21:24
    
Thanks for reminding me of the last point ... I did some asynchronous processing :-) –  Sašo Živanović Feb 7 '13 at 21:25
add comment

Here's a rather customizable version using LaTeX3.

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
% the user level macro
\NewDocumentCommand{\sigi}{ s O{a} D<>{2} m }
 {
  \{ % initial delimiter
  \IfBooleanTF{#1}
   {
    \merlin_sigi_nodots:nn { #2 } { #3 }, \dots, #2\sb{#4}
   }
   {
    \merlin_sigi:nnn { #2 } { #3 } { #4 }
   }
  \} % final delimiter
 }
% the inner main function that decides if dots are necessary or not
\cs_new_protected:Npn \merlin_sigi:nnn #1 #2 #3
 {
  \int_compare:nTF { #3 < #2 }
   {\merlin_sigi_nodots:nn { #1 } { #3 } }
   {
    \int_compare:nTF { #3 <= #2 + 2 }
     { \merlin_sigi_nodots:nn { #1 } { #3 } }
     { \merlin_sigi_dots:nnn   { #1 } { #2 } { #3 } }
   }
 }
% the loop for printing the sequence when no dots are required
\cs_new_protected:Npn \merlin_sigi_nodots:nn #1 #2
 {
  \int_step_inline:nnnn { 1 } { 1 } { #2 - 1 } { #1\sb{##1}, }
  #1\sb{#2}
 }
% the loop for printing the sequence when dots are required
\cs_new_protected:Npn \merlin_sigi_dots:nnn #1 #2 #3
 {
  \int_step_inline:nnnn { 1 } { 1 } { #2 } { #1\sb{##1}, }
  \dots,
  #1\sb{#3}
 }
\ExplSyntaxOff

\begin{document}
$\sigi{3}$

$\sigi{4}$

$\sigi[b]{5}$

$\sigi<3>{10}$

$\sigi[c]<4>{20}$

$\sigi<5>{4}$

$\sigi{1}$

$\sigi{2}$

\bigskip

$\sigi*{n}$

$\sigi*[b]{m}$

$\sigi*[c]<3>{k}$
\end{document}

enter image description here enter image description here

You can specify both the variable name (default a) and the number of initial indexed elements (default 2). If the number given as argument is less than the default number or one or two bigger, the full list is printed, as a list

{a1,a2,…,a4}

would be rather awkward.

Specification

The \sigi macro has

  • One optional argument (in brackets) representing the variable name (default a)
  • One optional argument (between < and >) representing the number of elements spelled out at the beginning
  • A mandatory argument (in braces, as usual) representing the final number

Non positive integer input in the second optional argument or in the mandatory argument will cause errors.

However the macro admits also a *-variant for a "generic" last argument, as shown in the last three lines of input. The syntax is the same for the optional arguments; the mandatory argument can be anything.

share|improve this answer
    
Cool! I wrote a rather simpler LaTeX3 version myself ... just for fun (and learning!). A question, however: isn't the D argument specifier supposed to mean "do not use"? :-) –  Sašo Živanović Feb 7 '13 at 21:53
1  
@SašoŽivanović It's "do not use" in functions (that is after a colon in the "inner" macros). For \NewDocumentCommand it specifies an optional argument delimited by different characters than brackets. –  egreg Feb 7 '13 at 21:56
    
new data overload ... thanks for explaining! –  Sašo Živanović Feb 8 '13 at 2:19
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.