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}
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}
Answered by Phelype Oleinik on December 6, 2020
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP