# Spacing depending on optional subscripts and superscripts

I am totally new to LaTeX (use it for 2 days), so I am sorry if this has already been asked, but I spent the last 6 hours searching for a solution, but to no avail. (I stumbled upon a package xpeek which might be able to do what I want (or maybe not), but the documentation was way to complex for me to get anything out of it.)

I am using the ansmath package to write some formulas. I want to introduce a new command for formating my matrix variables. My first attempt was:

\newcommand{\mtrx}[1]{\boldsymbol{#1}}


which looks fine, except when I use subscripting. In this case, my lower indices are too far away to look nice. E.g. $\mtrx{P}_{\mu\nu}$ Because P is in italics, the space between the P and the subscript is disturbingly large. Using $\mtrx{P\!}_{\mu\nu}$ looks fine, but I get into trouble when using a superscript too: In $\mtrx{P\!}_{\mu\nu}^{*}$, the * is way too close, and in $\mtrx{P}_{\mu\nu}^{*}$ the space between P and \mu is too large.

So, my desired behaviour is to write my macro \mtrx in a way, that it has a look at the tokens after the macro. If there is a subscript present, it inserts a \! after the #1. If there is a subscript and a superscript, it inserts a \; in the superscript. If there is no subscript nothing is changed.

I tried a bit with

\makeatletter
\newcommand{\mtrx}[1]{%
\@ifnextchar_{\boldsymbol{#1}\!}{\boldsymbol{#1}}}
\makeatother


but was not able to detect if there is also a superscript present - or at all how to read past the first character after the macro. I guess, this should somehow be possible with \@car and \@cdr, but I have no real clue on how to use them.

Any help is appreciated. Thank you for your time.

[EDIT]

Ok, finally I found a solution. I stumbled upon a version of \@ifnextchar which removes the character in case of a match here. I have no clue how it works, but it works.

By using it to remove the _ and ^ characters, I was able to call some other macros turning A_{B} into something like \@mtrx@sub{A}{B}.

Just in case, someone is searching for a similar problem, here is my solution.

1. \removeifnextchar is taken from the link above and acts similar to \@ifnextchar, except it removes the character on match.
2. \mtrx only formates its argument into bold face and calls \@mtrx@chk to check for sub- and superscripts
3. \@mtrx@chk peeks the next character using \removeifnextchar and calls \@mtrxsub or \@mtrx@sup, respectively, or returns its argument in case the next character is neither _ nor ^.
4. \@mtrx@sub and \@mtrx@sup take 2 arguments each, attach them in subscript or superscript fashion and call \@mtrx@chk again with this new argument in order to evaluate the next sub- or superscript.

Maybe this is not the best solution, but I am really glad that I finally found it. Anyway, in order to learn from this, please feel free to comment and/or improve.

\makeatletter
\newcommand{\removeifnextchar}[3]{%
\begingroup
\ltx@LocToksA{\endgroup#2}%
\ltx@LocToksB{\endgroup#3}%
\ltx@ifnextchar{#1}{%
\def\next{\the\ltx@LocToksA}%
\afterassignment\next
\let\scratch= %
}{%
\the\ltx@LocToksB
}%
}

\newcommand{\mtrx}[1]{
\ensuremath
\@mtrx@chk{\boldsymbol{#1}}
}
\def\@mtrx@chk#1{%
\removeifnextchar{_} %
{\@mtrx@sub{#1}}
{ \removeifnextchar{^} %
{\@mtrx@sup{#1}}
{#1}
}
}
\def\@mtrx@sub#1#2{%
\@mtrx@chk{#1_{\!#2}}
}
\def\@mtrx@sup#1#2{%
\@mtrx@chk{#1^{\:#2}}
}
\makeatother

-
Well, the spacing does not look so bad in my opinion. Also, if you were to implement that particular command, it would not work so well with, say, A instead of P. But if you really want to, you could use a macro with 2 arguments like so : \boldsymbol{#1}_{\!#2}. I think it is a little bit awkward, but maybe it can help. –  zuggg Jun 19 '13 at 5:27
You seem to be a fast learner after only two days with LaTeX! impressive... –  jfbu Jun 19 '13 at 6:59
Thank you for the compliment ^__^. –  Ineluki Jun 19 '13 at 7:07

\boldsymbol internally boxes the character and sets it in a new math list. This prevents the font-specified subscript correction being applied. If instead you use the alternative mechanism in the bm package the P is set as a bold letter in the current math list and then TeX will correct the subscript position by an amount set in the font parameters for the font being used:

\documentclass{article}

\usepackage{bm}
\usepackage{amsmath}

\newcommand{\mtrx}[1]{\bm{#1}}

\begin{document}

$\mtrx{P}_{\mu\nu}$

\end{document}

-
Thanks! This really helps a lot. Using this approach there is no need to worry about matrices like "R" which seem to connect with my indices. And the solution is a lot easier, too. –  Ineluki Jun 20 '13 at 16:06

Something like this:

\documentclass{article}
\usepackage{amsmath}

\newtoks\ilktoks
\makeatletter
\def\mtrx #1{\ilktoks{\mtrx@a{#1}}\@ifnextchar_{\mtrx@A}%
{\@ifnextchar^{\mtrx@B}{\mtrx@end}}}

\def\mtrx@A _#1{\ilktoks\expandafter {\the\ilktoks_{#1}}%
\@ifnextchar^{\mtrx@AB}{\mtrx@endsub}}

\def\mtrx@B ^#1{\ilktoks\expandafter {\the\ilktoks^{\mtrx@sup #1}}%
\@ifnextchar_{\mtrx@BA}{\mtrx@endsup}}

\def\mtrx@AB ^#1{\ilktoks\expandafter{\the\ilktoks^{\;#1}}\mtrx@endsubsup }

\def\mtrx@BA _#1{\ilktoks\expandafter{\the\ilktoks_{#1}}\mtrx@endsubsup }

\def\mtrx@end    {\def\mtrx@a ##1{\boldsymbol{##1}}\the\ilktoks }

\def\mtrx@endsub {\def\mtrx@a ##1{{\boldsymbol{##1}\!}}\the\ilktoks }

\def\mtrx@endsup {\def\mtrx@a ##1{{\boldsymbol{##1}}}\def\mtrx@sup {}%
\the\ilktoks }

\def\mtrx@endsubsup {\def\mtrx@a ##1{{\boldsymbol{##1}\!}}%
\def\mtrx@sup {\;}\the\ilktoks }
\makeatother

\begin{document}\thispagestyle{empty}

\ttfamily
$\mtrx {P}Q$ (with \string\mtrx)

$\boldsymbol{P}Q$ (without)

$\mtrx {P}_{\mu\nu}Q$ (with \string\mtrx)

${\boldsymbol{P}}_{\mu\nu}Q$ (without)

$\mtrx {P}^{*}Q$ (with \string\mtrx)

${\boldsymbol{P}}^{*}Q$ (without)

$\mtrx {P}_{\mu\nu}^{*}Q$ (with \string\mtrx; sub first)

${\boldsymbol{P}}_{\mu\nu}^{*}Q$ (without)

$\mtrx {P}^{*}_{\mu\nu}Q$ (with \string\mtrx; sup first)

${\boldsymbol{P}}^{*}_{\mu\nu}Q$ (without)

\end{document}


-