I take a somewhat different approach to defining a function to make subscripted variables in of the requested form. The algorithm doesn't differ substantially from the one used by Rod Lm; the difference lies in the way I use multiple function definitions, pattern matching, and destructuring of the formal argument sequences.
SetAttributes[fancySubscript, HoldFirst]
fancySubscript[var_Symbol, tag_String, index_Integer] /;
Not[ValueQ[var]] :=
Subscript[var, tag <> ToString[index]]
fancySubscript[var_Symbol, tags : {_String ..}, index_Integer] /;
Not[ValueQ[var]] :=
fancySubscript[var, #, index] & /@ tags
fancySubscript[var_Symbol, tags : {_String ..},
indices : {_Integer ..}] /; Not[ValueQ[var]] :=
fancySubscript[var, tags, #] & /@ indices
The condition Not[ValueQ[var]
ensures that fancySubscript
doesn't accept variables having values.
a = 42; fancySubscript[a, "tag", 2]
fancySubscript[a, "tag", 2]
The overloaded definitions ensure that fancySubscript
accepts all the following forms:
fancySubscript[b, "tag", 2]
$b_{\text{tag2}}$
fancySubscript[b, {"foo", "bar", "baz"}, 2]
$\left\{b_{\text{foo2}},b_{\text{bar2}},b_{\text{baz2}}\right\}$
fancySubscript[b, {"foo", "bar", "baz"}, Range@3]
$\left(
\begin{array}{ccc}
b_{\text{foo1}} & b_{\text{bar1}} & b_{\text{baz1}} \\
b_{\text{foo2}} & b_{\text{bar2}} & b_{\text{baz2}} \\
b_{\text{foo3}} & b_{\text{bar3}} & b_{\text{baz3}} \\
\end{array}
\right)$
Edit
To answer the question raised in a comment by Alex, it is easy to change fancySubscript
to do double indexing, rather than concatenating the tags and indices. The only modification required is to redefine the first definition of fancySubscript
as
fancySubscript[var_Symbol, tag_String, index_Integer] /;
Not[ValueQ[var]] :=
Subscript[var, tag, index]
With this change, for example,
fancySubscript[b, {"foo", "bar", "baz"}, 2]
gives
$\left\{b_{\text{foo},2},b_{\text{bar},2},b_{\text{baz},2}\right\}$