0

This code compiles correctly as long as I don't put spaces around arguments #3 and #4 in the definition of \vec. I can't find anything about this in the xparse documentation, and I have been under the impression that spaces in such places are the preferred style in LaTeX3 so I'd like to know why this happens. I have a feeling it may be trivial, but I'm not seeing it.

My MWE (contains code originally by @egreg):

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

% A smarter \vec command.
% Why doesn't it work when I put spaces around #3 or #4?
\RenewDocumentCommand{\vec}{ s m e{_^} }{%
  \ensuremath{%
    \IfBooleanTF {#1}
      {\vv{#2}}
      {\boldsymbol{#2}}
    _{\IfValueT{#3}{#3}\vphantom{\smash[b]{|}}}
    ^{\IfValueT{#4}{#4}\vphantom{\smash[t]{\big|}}}
  }%
}%

\begin{document}
\[
  \vec{E}_{\textup{ball}}
  \qquad
  \vec{E}_{_{\textup{ball}}}
\]
\[
  \vec{p}_{\textup{ball}}
  \qquad
  \vec{p}_{_{\textup{ball}}}
  \qquad
\]
\[
  \vec{F}
  \qquad
  \vec{F}_{\textup{proton}}
  \qquad
  \vec{F}^{\textup{elec}}
  \qquad
  \vec{F}^{\textup{elec}}_{\textup{proton}}
  \qquad
  \vec{F}_{\textup{proton}}^{\textup{elec}}
\]
\[
  \vec{F}
  \qquad
  \vec{F}_{21}
  \qquad
  \vec{F}_{21}^{\textup{contact}}
  \qquad
  \vec{F}_{\textup{table on ball}}^{\textup{contact}}
  \qquad
  \vec{F}^{\textup{contact}}_{\textup{table on ball}}
\]
\end{document}

Here is the result without the spaces in question:

Output without spaces around #3 and #4

And here is the result WITH the spaces in question:

Output with spaces around #3 and #4

6
  • If you want to use \IfValueT{ #3 }{<true code>}, then you need to surround definition of \vec in between \ExplSyntaxOn and \ExplSyntaxOff pair. You can find the documentation of them in manual of expl3. Commented Jul 23, 2020 at 2:59
  • @muzimuzhiZ UPDATE: I just tried your suggestion and it doesn't work. I get an error that \dn isn't defined. I'll just do without the spaces for now. Commented Jul 23, 2020 at 4:01
  • 1
    Ah, the situation is a bit tricky. \ExplSyntaxOn changes the category code of _, hence the _ used in definition of \veb in between \ExplSyntaxOn and ...Off now has catcode 11 (letter) while the _ used in document has its normal catcode 8 (subscript). This makes \vec expecting a _ (letter) but actually _ (subscript) is met. Commented Jul 23, 2020 at 5:24
  • 3
    Unrelated: note that \text is the wrong command to use to make those -scripts upright. \text does not do what you think it does (it will be italic if the text outside math is italic, not what you wanted). In this case \textup is probably better. Sadly we see a lot of people misusing \text like this. You should only use it for textual comments in displayed math. This is not a comment but a textual sup-/superscript
    – daleif
    Commented Jul 23, 2020 at 6:31
  • 1
    Regarding italics: think theorems of definitions, these are normally in italics. It is just better overall to not promote a bad solution to others who comeby this question. A lot of people don't know it's bad
    – daleif
    Commented Jul 23, 2020 at 19:41

1 Answer 1

2

(continue from this comment)

An ugly workaround:

  • tokenize e{^_} before \ExplSyntaxOn, in order to frozen the catcode of _, and
  • replace _ (required) and ^ (just for consistent) by their command form \sb (sub-script) and \sp (super-script), respectively.
\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}
\usepackage{esvect}

% A smarter \vec command.
% Why doesn't it work when I put spaces around #3 or #4?

\def\temp{ \RenewDocumentCommand{\vec}{ s m e{_^} } }

\ExplSyntaxOn
\temp{%
  \ensuremath{%
    \IfBooleanTF {#1}
      {\vv{#2}}
      {\boldsymbol{#2}}
    \sb{\IfValueT{ #3 }{#3}\vphantom{\smash[b]{|}}}
    \sp{\IfValueT{ #4 }{#4}\vphantom{\smash[t]{\big|}}}
  }%
}%
\ExplSyntaxOff

\begin{document}
\[
  \vec{E}_{\textup{ball}}
  \qquad
  \vec{E}_{_{\textup{ball}}}
\]
\[
  \vec{p}_{\textup{ball}}
  \qquad
  \vec{p}_{_{\textup{ball}}}
  \qquad
\]
\[
  \vec{F}
  \qquad
  \vec{F}_{\textup{proton}}
  \qquad
  \vec{F}^{\textup{elec}}
  \qquad
  \vec{F}^{\textup{elec}}_{\textup{proton}}
  \qquad
  \vec{F}_{\textup{proton}}^{\textup{elec}}
\]
\[
  \vec{F}
  \qquad
  \vec{F}_{21}
  \qquad
  \vec{F}_{21}^{\textup{contact}}
  \qquad
  \vec{F}_{\textup{table on ball}}^{\textup{contact}}
  \qquad
  \vec{F}^{\textup{contact}}_{\textup{table on ball}}
\]
\end{document}
6
  • You don’t need the \expandafter; category code are frozen once you define \temp
    – egreg
    Commented Jul 23, 2020 at 8:51
  • @egreg Thanks, you're right. Answer changed. Commented Jul 23, 2020 at 8:56
  • @muzimuzhiZ You say this is an "ugly" workaround. What would be a more elegant one? Commented Jul 23, 2020 at 19:31
  • @LaTeXereXeTaL I'm afraid there is no simple (not much to patch) and elegant (without losing the readability) solution here. Commented Jul 23, 2020 at 21:55
  • @muzimuzhiZ Just to clarify, this workaround is just to use spaces around those two arguments. As long as I don't do that, there shouldn't be a problem, correct? I have changed \text to \textup and learned about \sb and \sp so it's been instructive. Commented Jul 24, 2020 at 3:06

You must log in to answer this question.

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