I have some formula such as z_{(h_{1},h_{2},h_{3})}
and z_{(h_{4},h_{5},h_{6})}
. How can one introduce a \newcommand{}{}
for all of such formulas?
Thanks in advance
They forgot xinttools
.
\documentclass{article}
\usepackage{xinttools}
% Thank you very much. I will be very thankful if you write the commands for
% z_{j_{1}(h_{1},h_{2})} and z_{k(h_{3},h_{4},h_{5})}
\newcommand{\zz}[2]{z_{#1(\xintFor ##1 in {#2}\do {h_{##1}\xintifForLast{}{,}})}}
\begin{document}
\[ \zz{j_{1}}{1,2} = \zz{k}{3, 4, 5}\]
\end{document}
\newcommand\zz[3]{z_{(h_{#1},h_{#2},h_{#3})}
then you can use and \zz{1}{2}{3}
and \zz{4}{5}{6}
or even \zz123
and \zz456
\zzz
, to be mildly mnemonic of the fact that it takes 3 arguments...
It's not difficult to extend it to any number of subscripts:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\zz}{m}
{
z
\sp{}\sb
{
\clist_map_inline:nn { #1 }
{
\seq_put_right:Nn \l_fahim_z_subscripts_seq { h\sb{##1} }
}
(\seq_use:Nn \l_fahim_z_subscripts_seq { , })
}
}
\seq_new:N \l_fahim_z_subscripts_seq
\ExplSyntaxOff
\begin{document}
$\zz{1,2,3}+\zz{4,5,6}=\zz{1,2,3,4,5,6}$
\end{document}
This can be generalized to different base letters and different processing of the subscripts. The trailing optional argument sets how to treat each item in the comma separated list, see the examples.
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\zz}{O{z}mO{h\sb{##1}}}
{
#1
\sp{}\sb
{
\cs_set_protected:Nn \__fahim_z_subscript:n { #3 }
\clist_map_inline:nn { #2 }
{
\seq_put_right:Nn \l_fahim_z_subscripts_seq { \__fahim_z_subscript:n { ##1 } }
}
(\seq_use:Nn \l_fahim_z_subscripts_seq { , })
}
}
\seq_new:N \l_fahim_z_subscripts_seq
\ExplSyntaxOff
\begin{document}
$\zz{1,2,3}+\zz{4,5,6}=\zz{1,2,3,4,5,6}$
$\zz[Z]{1,2,3}[k_{#1}]$
$\zz{1,2,3}[(#1)]$
\end{document}
For more complex settings, I suggest a key-value syntax. Here the keys are var
(for the name of the variable), outer
to set the overall setting (default is just adding the parentheses) and inner
for the sequence of actual subscripts. See the given examples. At any moment you can issue \zzset
to change (in the current scope) one or more of the values.
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\zz}{O{}m}
{
\group_begin:
\keys_set:nn { fahim/zz } { #1 }
\fahim_zz:n { #2 }
\group_end:
}
\NewDocumentCommand{\zzset}{m}
{
\keys_set:nn { fahim/zz } { #1 }
}
\keys_define:nn { fahim/zz }
{
var .tl_set:N = \l__fahim_zz_var_tl,
outer .code:n = \cs_set_protected:Nn \__fahim_zz_outer:n { #1 },
inner .code:n = \cs_set_protected:Nn \__fahim_zz_inner:n { #1 },
}
\seq_new:N \l__fahim_zz_subscripts_seq
\cs_new_protected:Nn \fahim_zz:n
{
\tl_use:N \l__fahim_zz_var_tl
\sp{} % a dummy superscript to lower the subscript
\sb
{
\__fahim_zz_outer:n
{
\clist_map_inline:nn { #1 }
{
\seq_put_right:Nn \l__fahim_zz_subscripts_seq { \__fahim_zz_inner:n { ##1 } }
}
\seq_use:Nn \l__fahim_zz_subscripts_seq { , }
}
}
}
\ExplSyntaxOff
% initialize
\zzset{
var=z,
outer=(#1),
inner=h_{#1},
}
\begin{document}
$\zz{1,2,3}+\zz{4,5,6}=\zz{1,2,3,4,5,6}$
$\zz[var=Z,inner=k_{#1}]{1,2,3}$
$\zz[outer=i(#1)]{1,2,3}$
$\zz[outer=i(#1),inner=k_{#1}]{1,2,3}$
\end{document}
z_{i(h_{1},h_{2},h_{3})}
and z_{k(h_{4},h_{5})}
?
It's not difficult to extend it to any number of subscripts and without using ExplSyntaxOn:
\def\zz#1{\zzA#1,,}
\def\zzA#1,{z_\bgroup(h_{#1}\zzB}
\def\zzB#1,{\ifx\end#1\end)\egroup \else ,h_{#1}\expandafter\zzB\fi}
$\zz{1,2,3}+\zz{4,5,6}=\zz{1,2,3,4,5,6}$
\bye
EDIT If you need to add an ``index letter'' (i, j like in your comment), then it is possible to do using this code:
\def\zz#1#{z_\bgroup#1\zzI}
\def\zzI#1{\zzA#1,,}
\def\zzA#1,{(h_{#1}\zzB}
\def\zzB#1,{\ifx\end#1\end)\egroup \else ,h_{#1}\expandafter\zzB\fi}
$\zz i{1,2,3}+\zz j{4,5,6}=\zz{1,2,3,4,5,6}$
\bye
z_{i(h_{1},h_{2})}
and z_{j(h_{3},h_{4},h_{5})}
?
z_{j_{1}(h_{1},h_{2})}
and z_{k(h_{3},h_{4},h_{5})}
.
Very easy with the listofitems
package:
\documentclass{article}
\usepackage{listofitems}
\newcommand\zz[1]{
z_{(
\setsepchar{,}
\readlist*\zlist{#1}
\foreachitem\i\in\zlist{\ifnum\icnt=1\relax\else,\fi h_{\i}}
)}
}
\begin{document}
$\zz{1,2,3}+\zz{4,5,6}=\zz{1,2,3,4,5,6}$
\end{document}
By the way, listofitems
works in plain TeX, as well:
\input listofitems.tex
\def\zz#1{
z_{(
\setsepchar{,}
\readlist*\zlist{#1}
\foreachitem\i\in\zlist{\ifnum\icnt=1\relax\else,\fi h_{\i}}
)}
}
$\zz{1,2,3}+\zz{4,5,6}=\zz{1,2,3,4,5,6}$
\end
You could also use e-TeX. (It seems rather simple to me.) Assuming that you have three subsequent indices every time you would say
\newcommand*\zz[1]{%
\@tempcnta\numexpr#1+1\relax
\@tempcntb\numexpr#1+2\relax
z_{(%
h_{#1}+h_{\the\@tempcnta}+h_{\the\@tempcntb}%
)}
}
and then call \zz{1}
resp. \zz{4}
.
To add in a few generalisations, i.e. arbitrary number of indices and specified indices is not a big deal:
\newcommand*\zzz[2][h]{%
\def\forplus{\def\forplus{+}}
z_{(%
\@for\i:=#2\do{\forplus#1_{\i}}%
)}
}
Note the optional parameter for the subscripts of first order:
\begin{gather*}
\zzz{1,2,3}\\
\zzz{4,5,6}\\
\zzz[p]{7,11,13,17}
\end{gather*}
If you want to you can get really sophisticated by declaring something that acts like
\indexloop[<delimiter>][<format>]{<indices>}
where <format>:='<superscript>_<opt. delimiter><subscript><opt. delimiter>'
defined by
\makeatletter
\def\defaultsup{z}
\def\defaultsub{h}
\def\defaultdll{(}
\def\defaultdlr{)}
\def\defaultsep{+}
\def\indexloop{%
\kernel@ifnextchar[
{\indexl@op}
{\indexl@op[\defaultsup_\defaultdll\defaultsub\defaultdlr]}
}
\def\indexl@op[#1]{%
\kernel@ifnextchar[
{\indexl@@p[{#1}]}
{\indexl@@p[\defaultsep][{#1}]}
}
\def\indexl@@p[#1][#2]#3{%
\def\forsep{\def\forsep{#1}}
\def\customsup{}
\def\customsub{}
\def\customdll{}
\def\customdlr{}
\process@format#2\@end
\customsup_{%
\customdll
\@for\i:=#3\do{\forsep\customsub_{\i}}%
\customdlr
}%
}
\def\process@format#1_#2\@end{%
\def\customsup{#1}
\process@sub#2\@@end
}
\def\process@sub#1{
\ifx#1\@@end\else
\ifcat#1x
\edef\customsub{\customsub#1}
\else
\ifx\customdll\@empty
\def\customdll{#1}
\else
\ifx\customdlr\@empty
\def\customdlr{#1}
\fi
\fi
\fi
\expandafter\process@sub
\fi
}
\makeatother
Here is a short test of the last solution.
\begin{gather*}
\indexloop{1,2,3}\\
\indexloop{4,5,6}\\
\indexloop[z_(p)]{7,11,13,17}\\
\indexloop[-][z_\langle x\rangle]{8,9,10,12,14,15,16}\\
\indexloop[,][{a_[i]}]{1,2}
\end{gather*}
% arara: pdflatex
\documentclass{article}
\usepackage{amsmath}
\makeatletter
\newcommand*\zz[1]{%
\@tempcnta\numexpr#1+1\relax
\@tempcntb\numexpr#1+2\relax
z_{(%
h_{#1}+h_{\the\@tempcnta}+h_{\the\@tempcntb}%
)}
}
\newcommand*\zzz[2][h]{%
\def\forplus{\def\forplus{+}}
z_{(%
\@for\i:=#2\do{\forplus#1_{\i}}%
)}
}
\def\defaultsup{z}
\def\defaultsub{h}
\def\defaultdll{(}
\def\defaultdlr{)}
\def\defaultsep{+}
\def\indexloop{%
\kernel@ifnextchar[
{\indexl@op}
{\indexl@op[\defaultsup_\defaultdll\defaultsub\defaultdlr]}
}
\def\indexl@op[#1]{%
\kernel@ifnextchar[
{\indexl@@p[{#1}]}
{\indexl@@p[\defaultsep][{#1}]}
}
\def\indexl@@p[#1][#2]#3{%
\def\forsep{\def\forsep{#1}}
\def\customsup{}
\def\customsub{}
\def\customdll{}
\def\customdlr{}
\process@format#2\@end
\customsup_{%
\customdll
\@for\i:=#3\do{\forsep\customsub_{\i}}%
\customdlr
}%
}
\def\process@format#1_#2\@end{%
\def\customsup{#1}
\process@sub#2\@@end
}
\def\process@sub#1{
\ifx#1\@@end\else
\ifcat#1x
\edef\customsub{\customsub#1}
\else
\ifx\customdll\@empty
\def\customdll{#1}
\else
\ifx\customdlr\@empty
\def\customdlr{#1}
\fi
\fi
\fi
\expandafter\process@sub
\fi
}
\makeatother
\begin{document}
\begin{gather*}
\zz{1}\\
\zz{4}
\end{gather*}
\begin{gather*}
\zzz{1,2,3}\\
\zzz{4,5,6}\\
\zzz[p]{7,11,13,17}
\end{gather*}
\begin{gather*}
\indexloop{1,2,3}\\
\indexloop{4,5,6}\\
\indexloop[z_(p)]{7,11,13,17}\\
\indexloop[-][z_\langle x\rangle]{8,9,10,12,14,15,16}\\
\indexloop[,][{a_[i]}]{1,2}
\end{gather*}
\end{document}
Even the first solution can be more sophisticated by implementing the step length:
\newcommand*\zz[2][1]{%
\@tempcnta\numexpr#2+1*#1\relax
\@tempcntb\numexpr#2+2*#1\relax
z_{(%
h_{#2}+h_{\the\@tempcnta}+h_{\the\@tempcntb}%
)}
}
\[\zz[2]{0}\]
would then compile to z_{h_0+h_2+h_4}
as expected.
z
.\zz{1}
that producesz_{(h_{1},h_{2},h_{3})}
?