TransWikia.com

Why do I have to put braces around my macro for subscripts / indices?

TeX - LaTeX Asked by Marc Krass on December 6, 2020

I want to define a macro ind which let’s me set in math mode a subscript in upright letters and when starred (ind*) in italic letters. Additionally, an optional argument allows me to adjust the kerning between letter and index, i.e. W_{ind[-2mu]{x}}. This works quite well. But surprisingly, I have to put braces around the ind-command in order to make it run.

Can someone explain me why I have to put braces around the command and how I can modify the macro to avoid this? It’s a super big deal but I would like to understand the mechanism behind it.

The error is always that a { and a } is missing.

MWE:

documentclass{article}

makeatletter
newcommandind{@ifstar{ind@star}{ind@nostar}}
newcommandind@star[2][]{mkern muexpr 0mu #1  #2}
newcommandind@nostar[2][]{mathrm{mkern muexpr 0mu #1  #2}}
makeatother

begin{document}
    $sigma_{ind{xy}}$  % works
    $sigma_ind{xy}$    % does not work
end{document}

2 Answers

Well they are missing. Not to worry, though, you can easily add them since you don't need the literal brace characters used for delimiting macro/command arguments, but can use bgroup and egroup.

makeatletter
newcommandind{bgroup@ifstar{ind@star}{ind@nostar}}
newcommandind@star[2][]{mkern muexpr 0mu #1  #2egroup}
newcommandind@nostar[2][]{mathrm{mkern muexpr 0mu #1  #2}egroup}
makeatother

At some future time, or with some unknown package, the subscript and superscript signal characters (_ and ^) could conceivably be implemented as "active" character commands that take arguments, in which case explicit brace grouping would be required.

Correct answer by Donald Arseneau on December 6, 2020

Subscripts (and superscripts—what I say here is valid for both) in TeX only work without braces for single tokens (or some special low-level cases like char<number>; not really LaTeX syntax), so you can write 2^n rather than the comparatively long 2^{n}. If next unexpandable token (except relax) after a superscript character is a { (or other begin-group character token), then TeX takes a balanced list of tokens for the superscript. TeX also expands tokens after a superscript, so you can define shorthands like deffunny#1{{#1+n}} then write 2^funny{1} (funny{1} expands to {1+n} and the braces are there).

However some commands don't expand properly to a neatly braced list of tokens like funny or mathrm do: they are designed to work in subscripts without surrounding braces by expanding to a braced list of tokens. In your command, the first unexpandable token is a let (in the definition of @ifnextchar, in the definition of @ifstar) so when TeX sees it, it knows that a let alone doesn't work and tells you that you forgot a { at that point:

! Missing { inserted.
<to be read again> 
                   let 
l.16     $sigma_ind
                     {xy}$    % does not work
?

If you are bold, you can ignore this error and the next one. TeX will try to recover and in this one particular situation it will add the two missing braces, making both lines essentially the same.

Use braces: that's the proper syntax!


That said :-)

With xparse you can define a version of that command that looks for optional arguments expandably, then adds the missing braces in the definition:

documentclass{article}

usepackage{xparse}
makeatletter
NewExpandableDocumentCommand ind { s O{} m}
  {{% <- extra set of braces
    IfBooleanF{#1}{mathrm}% If no star argument
      {mkern muexpr 0mu #2 #3}%
  }}
makeatother

begin{document}
    $sigma_{ind{xy}}$     % works
    $sigma_ind{xy}$       % works
    $sigma_ind[-5mu]{xy}$ % also works
end{document}

enter image description here

Answered by Phelype Oleinik on December 6, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP