# Smart subscript indexing macro

I need to go and rework a bunch of notation in a large body of work. But I might change my mind later, so I want to move to defining the notation a bit more semantically (e.g. writing \v x to represent a vector, so I can later decide to format vectors in different ways).

On thing that is currently wrong with it is that I write A_i to represent that $i^{\text {th}}$ column vector. After looking at other similar works, I have concluded that A_{:,i} would be clearer. So I have defined a macro to smartly determine if a : should be added.

I called it \i to be concise since I will be writing it often.

\documentclass{article}

\usepackage{xparse,xstring,etoolbox}

\renewcommand{\v}[1]{\tilde{#1}} % a vector

\newcommand{\ind}[2]{#1_{#2}} % indexed

%% Smart indexing and naming code

\newcommand{\ifupper}[3]{
\normalexpandarg
\exploregroups
\StrCount{ABCDEFGHIJKLMNOPQRSTUVWXYZ}{#1}[\uppercount]
\ifnumgreater{\uppercount}{0}{#2}{#3}
}

%smart index
\DeclareDocumentCommand{\i}{u{_} m}{
\ifupper{#1}%
{% just a single uppercase character, i.e. a matrix
%make sure the index is the right length
\StrCount{#2}{,}[\indcount]
\ifnumgreater{\indcount}{0}
{ % Got multiple indexes so all good
\ind{#1}{#2}
}
{ % Only 1 index so grab the column
\ind{#1}{{:,#2}}
}
}%
{% Not just a single upper case character
\ind{#1}{#2}
}
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Example document
\begin{document}

\begin{tabular}{r l}
$\i {\v x}_i$ & the $i$th element of the vector $\v x$\\
$\i{X}_{i,j}$ & the row $i$ and column $j$ element of the matrix $X$\\
$\i{X}_i$ & the $i$th column vector of the matrix $X$\\
$\i{X}_{i,:}$ & the $i$th row vector of the matrix $X$\\
\end{tabular}

\end{document}


## Example document output

Crossref

Redefining \v and \i is a bad thing. Don't, you'll regret it as soon as you want to need to cite a paper by Eduard Čech or by Erdal Arıkan.

You also have quite an inefficient usage of xstring and no error checking if a _ is forgotten.

Here's a complete implementation with xparse:

\documentclass{article}

\usepackage{xparse}

\NewDocumentCommand{\ind}{me{_}}{%
\IfNoValueTF{#2}{\doind{#1}{???}}{\doind{#1}{#2}}
}

\ExplSyntaxOn
\NewDocumentCommand{\doind}{mm}
{
\tl_if_single:nTF { #1 }
{% a single character
\str_if_eq_x:nnTF { #1 } { \str_upper_case:n { #1 } }
{% upper case, assume matrix
\lyndon_index_matrix:nn { #1 } { #2 }
}
{
\lyndon_index_do:nn { #1 } { #2 }
}
}
{% not a single character
\lyndon_index_do:nn { #1 } { #2 }
}
}

\cs_new_protected:Nn \lyndon_index_matrix:nn
{
\int_compare:nTF { \clist_count:n { #2 } > 1 }
{% Got multiple indexes so all good
\lyndon_index_do:nn { #1 } { #2 }
}
{% Only one index so grab the column
\lyndon_index_do:nn { #1 } { {:},#2 }
}
}
\cs_new_protected:Nn \lyndon_index_do:nn
{
#1\sb{#2}
}
\ExplSyntaxOff

% Example document
\begin{document}

\begin{tabular}{r l}
$\ind{A}$           & missing subscript\\
$\ind{\tilde{x}}_i$ & the $i$th element of the vector $\tilde{x}$\\
$\ind{X}_{i,j}$     & the row $i$ and column $j$ element of the matrix $X$\\
$\ind{X}_i$         & the $i$th column vector of the matrix $X$\\
$\ind{X}_{i,:}$     & the $i$th row vector of the matrix $X$\\
\end{tabular}

\end{document}


On the other hand, I see no much gain in using _ and also in doing checks for uppercase letters, which is quite limiting. I'd prefer a * version for vectors.

\documentclass{article}

\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand{\ind}{smm}
{
\IfBooleanTF{#1}
{% *, a vector
\lyndon_index_do:nn { #2 } { #3 }
}
{% normal, a matrix
\lyndon_index_matrix:nn { #2 } { #3 }
}
}
\cs_new_protected:Nn \lyndon_index_matrix:nn
{
\int_compare:nTF { \clist_count:n { #2 } > 1 }
{% Got multiple indexes so all good
\lyndon_index_do:nn { #1 } { #2 }
}
{% Only one index so grab the column
\lyndon_index_do:nn { #1 } { {:},#2 }
}
}
\cs_new_protected:Nn \lyndon_index_do:nn
{
#1\sb{#2}
}

\ExplSyntaxOff

% Example document
\begin{document}

\begin{tabular}{r l}
$\ind*{\tilde{x}}{i}$ & the $i$th element of the vector $\tilde{x}$\\
$\ind{X}{i,j}$        & the row $i$ and column $j$ element of the matrix $X$\\
$\ind{X}{i}$          & the $i$th column vector of the matrix $X$\\
$\ind{X}{i,:}$        & the $i$th row vector of the matrix $X$\\
$\ind{\Gamma}{j}$     & Greek matrix
\end{tabular}

\end{document}