I'm trying to define a command to make a list of subscripted \varphi characters. Let's call it \phiseq. I want to be able to use \phiseq{1,2,3} in the body of my document to expand to $\varphi_1,\varphi_2,\varphi_3$. Any ideas? I've tried several experiments with \@for, but none of them have worked.
Asked
Active
Viewed 595 times
6
Kellvyn
- 135
4 Answers
7

\documentclass{article}
\makeatletter
\def\phiseq#1{$\let\comma\@empty\@for\tmp:=#1\do{\comma\varphi_{\tmp}\def\comma{,}}$}
\makeatother
\begin{document}
\phiseq{1,2,3}
\end{document}
David Carlisle
- 757,742
5
You can define a fairly general command with expl3.
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\cs_new_protected:Npn \kellvyn_print_seq:nnnn #1 #2 #3 #4
{% #1 = input delimiter
% #2 = output delimiter
% #3 = symbol
% #4 = list
% store the list in a sequence
\seq_set_split:Nnn \l_kellvyn_args_seq { #1 } { #4 }
% clear the auxiliary sequence
\seq_clear:N \l_kellvyn_print_seq
% process the argument list
\seq_map_inline:Nn \l_kellvyn_args_seq
{
\tl_if_eq:nnTF { ##1 } { \dots }
{% if the item is \dots, store it unchanged
\seq_put_right:Nn \l_kellvyn_print_seq { \dots }
}
{% otherwise, store "symbol_{item}"
\seq_put_right:Nn \l_kellvyn_print_seq { #3\sb{##1} }
}
}
% print the sequence
\seq_use:Nnnn \l_kellvyn_print_seq { #2 } { #2 } { #2 }
}
\NewDocumentCommand{\phiseq}{m}
{
\kellvyn_print_seq:nnnn { , } { , }{ \varphi } { #1 }
}
\NewDocumentCommand{\printseq}{O{,}mm}
{
\kellvyn_print_seq:nnnn { , } { #1 } { #2 } { #3 }
}
\ExplSyntaxOff
\begin{document}
$\phiseq{1,2,3}$
$\phiseq{1,2,\dots,n}$
$\printseq{x}{1,2,\dots,k-1,k}$
$\printseq[;]{y}{1,2,3,4}$
\end{document}
With \phiseq you get your original request, but with the bonus that a \dots input will produce dots in the output. The \printseq command is more general, the optional argument is the output delimiter. I've used also a parameter for the input delimiter for possible extensions (it's not more difficult to have it, so better be as general as possible).

egreg
- 1,121,712
2
This works for me:
\documentclass{article}
\makeatletter
\newif\if@phiseqfirst
\def\phiseq#1{%
\@phiseqfirsttrue
$\@for\ind:=#1\do{
\if@phiseqfirst\else,\fi
\varphi_{\ind}
\@phiseqfirstfalse}$}
\makeatother
\begin{document}
\phiseq{1,2,3,4}
\end{document}
The \@phiseqfirst magic is here to get rid of the spurious comma in the end (thanks to @GonzaloMedina for noting it).
Boris
- 38,129
-
1In the output, there will be a spurious comma after the last term. – Gonzalo Medina Jun 18 '13 at 16:35
-
-
You can use the kernel provided
\if@tempswa, since\@fordoesn't use it. – egreg Jun 18 '13 at 20:27
2
Yet another solution with pgffor.
\documentclass[varwidth]{standalone}
\usepackage{pgffor}
\def\seq#1#2{%
\foreach \i[count = \j] in {#2}{%
\unless\ifnum\j=1\relax, \fi$#1_{\i}$}}
\def\phiseq#1{\seq{\phi}{#1}}
\begin{document}
\seq{\psi}{1,...,5}\par
\phiseq{10,...,20}
\end{document}

cjorssen
- 10,032
- 4
- 36
- 126
\makeatletter! Thanks! – Kellvyn Jun 18 '13 at 16:45