Parse subscript and superscript in command

macrosmath-modeparsingsubscriptssuperscripts

I am using quite a lot of notation in my text.
Thus, I decided to write some commands such as:

\newcommand{\struct}[1]{\mathsf{#1}}

The typical use is as follows:

Let $(\struct{A}_n)$ be a sequence of structures.

Notice that the subscript is outside the struct command.

My problem lies in the fact that I need to 'place' the exact name of the object to various places.
That is, to write something as long description of the structure:

(\struct{A}_n, S_{\struct{A}_n}, R_{\struct{A}_n})

See that I cannot just write a command like this:

\newcommand{\longstruct}[1]{(\mathsf{#1}, S_\mathsf{#1}, R_\mathsf{#1})}

and use it similarly:

Let $(\longstruct{A}_n)$ be a sequence of structures.

because the subscript _n would be in the wrong place.

As a solution, it would work being able to handle the 'base' of the name and subscript/superscript separately.
For example in a command like this:

% #1 Base
% #2 Subscript
% #3 Superscript
\newcommand{\longstruct}[3]{(\mathsf{#1}_{#2}^{#3}, S_{\mathsf{#1}_{#2}^{#3}}, R_{\mathsf{#1}_{#2}^{#3}})}

However it feels too cumbersome to be used in code.
Optional parameters help, but it is still not optimal.

How I would like to use the command:

Let $(\longstruct{A_n})$ be a sequence of structures.

But of course, as only A is supposed to go in \mathsf{.}, the argument needs to be parsed into the base and subscript/superscript inside the command.

Is there a way how to do that?

Note: I'm still rather an inexperienced latex user and it is quite likely that there is a better solution, which didn't even crossed my mind.
I'm open to any suggestions.
Thank you.

Edit:
The superscripts are indented to be used as in the command example with three parameters yielding the result such as this:

(\struct{A}_n^d, S_{\struct{A}_n^d}, R_{\struct{A}_n^d})

Best Answer

You can do it with \NewDocumentCommand, that's able to split the argument at a given token.

\documentclass{article}
\usepackage{amsmath}

\NewDocumentCommand{\struct}{m}{\mathsf{#1}}

\NewDocumentCommand{\longstruct}{>{\SplitArgument{1}{_}}m}{%
  (\makelongstruct#1)%
}

\NewDocumentCommand{\makelongstruct}{mm}{%
  \struct{#1}\IfValueT{#2}{_{#2}},%
  S_{\struct{#1}\IfValueT{#2}{_{#2}}},%
  R_{\struct{#1}\IfValueT{#2}{_{#2}}}%
}

\begin{document}

$\longstruct{A_n}$

$\longstruct{B}$

\end{document}

enter image description here

Explanation: with \SplitArgument{1}{_} the argument A_n becomes {A}{n} and we can pass it to an auxiliary command. If the _ is missing, we get {A}{-NoValue-} and this can be tested in order to avoid adding the subscript.

We can also accommodate superscripts:

\documentclass{article}
\usepackage{amsmath}

\NewDocumentCommand{\struct}{m}{\mathsf{#1}}

\NewDocumentCommand{\longstruct}{>{\SplitArgument{1}{_}}m}{%
  (\makelongstructA#1)%
}

\NewDocumentCommand{\makelongstructA}{mm}{%
  \IfNoValueTF{#2}{% no subscripts
    \makestruct{#1}{\kern-\scriptspace}{\kern-\scriptspace}%
  }{% there are subscripts
    \makelongstructB{#1}{#2}%
  }%
}

\NewDocumentCommand{\makelongstructB}{
  >{\SplitArgument{1}{^}}m
  >{\SplitArgument{1}{^}}m
}{%
  \makelongstructC#1#2%
}

\NewDocumentCommand{\makestruct}{mmm}{%
  \struct{#1}\IfValueT{#2}{_{#2}}\IfValueT{#3}{^{#3}},%
  S_{\struct{#1}\IfValueT{#2}{_{#2}}\IfValueT{#3}{^{#3}}},%
  R_{\struct{#1}\IfValueT{#2}{_{#2}}\IfValueT{#3}{^{#3}}}%
}

\NewDocumentCommand{\makelongstructC}{mmmm}{%
  \IfValueTF{#2}{% we had A^s_n
    \makestruct{#1}{#3}{#2}%
  }{% we had A_n^s
%\showtokens{#1,#2,#3}
    \makestruct{#1}{#3}{#4}%
  }%
}

\begin{document}

$\longstruct{A_n}$

$\longstruct{B}$

$\longstruct{C_n^k}$

$\longstruct{D^k_n}$

\end{document}

enter image description here

Related Question