7

I am trying to get the subscript on $\rangle$ just right:

To me $\rangle_G$ puts the G too high, and things as $\rangle_{_G}$ or even $\rangle_{\substack{\\G}}$ do not get it right. Is there any easy way to solve this?

4
  • Do you really need \rangle? Maybe what you need is simply >_G.
    – Sigur
    May 18, 2015 at 14:16
  • 2
    Hmm, no, I think that looks rather strange for an inner product.
    – Krijn
    May 18, 2015 at 14:18
  • 3
    Welcome to TeX.SX! It's a usual problem with uppercase letters as subscripts: try with \rangle^{}_{\!G} that lowers the subscript and moves it a bit to the left.
    – egreg
    May 18, 2015 at 14:18
  • @Krijn, OK, If you want inner product, congs for using \rangle.
    – Sigur
    May 18, 2015 at 14:19

3 Answers 3

8

Here's one way, with the provided macro \subrangle{}. The 5pt can be adjusted to suit.

\documentclass{article}
\usepackage{stackengine}
\def\subrangle#1{\stackengine{5pt}{}{$\!\scriptstyle #1$}{U}{l}{F}{F}{L}}
\begin{document}
$\langle x\rangle\subrangle{G} \langle x\rangle\subrangle{xyz}$
\end{document}

enter image description here

Here it is, changing the 5pt to 4pt:

enter image description here

SUPPLEMENT: If one wished to use the _ syntax to invoke \subrangle, it could be done with the following preamble definition:

\makeatletter
\let\save@rangle\rangle
\def\rangle{\save@rangle\@ifnextchar_{\expandafter\subrangle\@gobble}{}}
\makeatother

With such a syntax, $\langle x\rangle_G \langle x\rangle_{xyz}$ would produce the desired result.

1
  • 1
    @Krijn Please see my "SUPPLEMENT" for guidance on how to obtain the result while still using the traditional underscore syntax. May 18, 2015 at 15:26
8

The usual remedy is to add a dummy superscript that lowers the subscript. I'd also add a small backing up \!.

Here are two versions. In the first one the output is fixed, with a comma separating the two vectors. In the second version the input is the same, but the output is customizable according to one's preference; as an example I used \mid for separating the vectors.

\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}

% First version (simple)
\NewDocumentCommand{\inn}{mo}{%
  \langle #1\rangle
  \IfValueT{#2}{^{}_{\mspace{-3mu}#2}}%
}

% Second version, customizable
\NewDocumentCommand{\xinn}{>{\SplitArgument{1}{,}}mo}{%
  \doinnerproduct#1
  \IfValueT{#2}{^{}_{\mspace{-3mu}#2}}%
}
\NewDocumentCommand{\doinnerproduct}{mm}{%
  \langle #1\mid #2\rangle % decide here how to typeset the two vectors
}

\begin{document}

$\inn{x,y}$ or $\inn{x,y}[G]$

$\xinn{x,y}$ or $\xinn{x,y}[G]$

\end{document}

enter image description here

This is the output when \mspace{-3mu} is changed into \mspace{-1.5mu}:

enter image description here

And this is the output without the correction:

enter image description here

3
  • 1
    The source code probably comes from an older test version, the definition of macro \inn does not fit the use case and the image. I think, it was intended something like this: \NewDocumentCommand{\inn}{mmo}{\langle#1,#2\rangle\IfValueT{#3}{^{}_{\!#3}} May 18, 2015 at 16:36
  • For my taste, \! moves the subscript a little too close to the angle bracket. Something like \mkern-.75\thinmuskip seems too look better. May 18, 2015 at 16:37
  • @HeikoOberdiek Thanks for the remark, I added two possible variations (and fixed the code).
    – egreg
    May 18, 2015 at 17:17
1

Well, shameless plug. I just wrote code yesterday to handle sub and superscripts as optional arguments so I'm going to use it here.

The solution is exactly like egreg's but instead of \inn{x,y}[G] you can write \inn{x,y}_{G} and have the exact same output.

\documentclass{scrartcl}

\usepackage{xparse}

\ExplSyntaxOn
\cs_new_protected:Npn \__xparse_count_type_k:w #1
 {
  \__xparse_single_token_check:n { #1 }
  \quark_if_recursion_tail_stop_do:Nn #1 { \__xparse_bad_arg_spec:wn }
  \__xparse_count_mandatory:N
 }
\cs_new_protected:Npn \__xparse_count_type_K:w #1 #2
 {
  \__xparse_single_token_check:n { #1 }
  \quark_if_recursion_tail_stop_do:nn { #2 } { \__xparse_bad_arg_spec:wn }
  \__xparse_count_mandatory:N
 }
\cs_new_protected:Npn \__xparse_add_type_k:w #1
 { \exp_args:NNo \__xparse_add_type_K:w #1 { \c__xparse_no_value_tl } }
\cs_new_protected:Npn \__xparse_add_type_K:w #1 #2
 {
  \__xparse_flush_m_args:
  \__xparse_add_grabber_optional:N K
  \tl_put_right:Nn \l__xparse_signature_tl { #1 { #2 } }
  \__xparse_prepare_signature:N
 }
\cs_new_protected:Npn \__xparse_add_expandable_type_k:w #1
 {
  \exp_args:NNo \__xparse_add_expandable_type_K:w #1 { \c__xparse_no_value_tl }
 }
\cs_new_protected_nopar:Npn \__xparse_add_expandable_type_K:w #1 #2
 {
  \__msg_kernel_error:nnx { xparse } { invalid-expandable-argument-type } { K }
  \__xparse_add_expandable_type_m:w
 }
\cs_new_protected:Npn \__xparse_grab_K:w #1 #2 #3 \l__xparse_args_tl
 {
  \__xparse_grab_K_aux:NnnNn #1 { #2 } { #3 } \cs_set_protected_nopar:Npn
   { _ignore_spaces }
 }
\cs_new_protected:Npn \__xparse_grab_K_long:w #1 #2 #3 \l__xparse_args_tl
 {
  \__xparse_grab_K_aux:NnnNn #1 { #2 } { #3 } \cs_set_protected:Npn
   { _ignore_spaces }
 }
\cs_new_protected:Npn \__xparse_grab_K_trailing:w #1 #2 #3 \l__xparse_args_tl
 {
  \__xparse_grab_K_aux:NnnNn #1 { #2 } { #3 } \cs_set_protected_nopar:Npn
   { _ignore_spaces }
 }
\cs_new_protected:Npn \__xparse_grab_K_long_trailing:w #1 #2 #3 \l__xparse_args_tl
 {
  \__xparse_grab_K_aux:NnnNn #1 { #2 } { #3 } \cs_set_protected:Npn
   { _ignore_spaces }
 }
\cs_new_protected:Npn \__xparse_grab_K_aux:NnnNn #1 #2 #3 #4 #5
 {
  \exp_after:wN #4 \l__xparse_fn_tl ##1
   {
    \__xparse_add_arg:n { ##1 }
    #3 \l__xparse_args_tl
   }    
  \use:c { peek_meaning_remove #5 :NTF } #1
   { \l__xparse_fn_tl }
   {
    \__xparse_add_arg:n { #2 }
    #3 \l__xparse_args_tl
   }
 }
\prop_put:Nnn \c__xparse_shorthands_prop { a } { k \sb }
\prop_put:Nnn \c__xparse_shorthands_prop { b } { k \sp }
\prop_put:Nnn \c__xparse_shorthands_prop { A } { K \sb }
\prop_put:Nnn \c__xparse_shorthands_prop { B } { K \sp }
\ExplSyntaxOff

\NewDocumentCommand{\inn}{mma}{%
  \langle #1,#2\rangle
  \IfValueT{#3}{^{}_{\!#3}}%
}

\NewDocumentCommand{\xinn}{>{\SplitArgument{1}{,}}ma}{%
  \doinnerproduct#1%
  \IfValueT{#2}{^{}_{\!#2}}%
}
\NewDocumentCommand{\doinnerproduct}{mm}{%
  \langle #1\mid #2\rangle
}

\begin{document}

$\inn{x}{y}$ or $\inn{x}{y}_{G}$

$\xinn{x,y}$ or $\xinn{x,y}_{G}$

\end{document}
2
  • Unbelievable! A lot of lines just to make that simple task. I don't understand your code but is it all necessary??!!
    – Sigur
    May 18, 2015 at 14:59
  • 1
    Well, all those lines are written inside of xparse for any argument type (like o, r, d, etc.). The fact that this is hand-made by me means that that code must come from “outside” of xparse. It wasn't really an answer to the question, but more of a “joke”; the only thing in those lines are the ability to write \inn{x,y}_{G} rather than \inn{x,y}[G] from egreg's answer.
    – Manuel
    May 18, 2015 at 15:03

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .