\bm 与可选参数的交互

\bm 与可选参数的交互

这里发生了什么?

\documentclass{article}
\usepackage{bm}

\newcommand{\myfuncA}[0]{A}
\newcommand{\myfuncB}[1]{#1}
\newcommand{\myfuncC}[1][]{#1}

\begin{document}
\[
    \bm{\myfuncA} % works
    \bm{\myfuncB{B}} % works
    \textbf{\myfuncC[C]} % works
    \bm{\myfuncC[C]} % doesn't work
\]
\end{document}

编辑1:overleaf 上的某个人是否愿意实施 David Carlilse 答案中的解决方案?

编辑2:有人告诉我这不太可能有用。没关系。

答案1

来自文档(texdoc bm):

3.5 奇怪的失败

为了获得正确的间距,\bm必须“调查”其参数中命令的定义。某些奇怪的构造可能会“混淆”此调查。如果发生这种情况,LaTeX 几乎肯定会因奇怪的错误而停止。这不应该发生在基本 LaTeX 或 AMS 发行版中定义的任何数学符号上,或者使用普通 LaTeX 数学构造根据这些符号定义的任何命令上。但是,如果某个命令在内部不起作用,\bm您应该始终能够用一组额外的括号 \bm{{\cmd}} 而不是 \bm{\cmd} 将其括起来。 \bm 将不会尝试设置正确的间距,因此您可能需要明确设置它,例如对于关系,\bm{\mathrel{\cmd}}

对于您的示例,将最后一行更改为

\bm{{\myfuncC[C]}}

使其编译。

答案2

这里发生了什么?

具体情况是这样的

% \changes{v1.1g}{2004/01/23}{Use kernel version of
%                             \cs{@ifnextchar} (pr/3501)}

\bm使得\@ifnextchar内部或多或少是安全的,\bm但是嗯“一段时间”\newcommand没有使用\@ifnextchar

本地添加

    \let\kernel@ifnextchar\@ifnextchar

所以它们都得到了安全产品

在此处输入图片描述

\documentclass{article}
\usepackage{bm}


\makeatletter
\let\bm@end\relax
\begingroup
\catcode`\'=\active
\catcode`\_=\active
\@firstofone{\endgroup
\def\bm@general#1#2#3#4#5{%
  \begingroup
    \let\bm\@firstofone
    \let\hm\@firstofone
    \global\let\bm@command\@empty
    \let\@let@token\@empty
    \let\protect\@empty
    \let\@typeset@protect\@empty
    \def\bm@mathchoice{\bm@m@thchoice#1}%
    \def\bm@group{\bm@gr@up#1}%
    \let\bm@table#2%
    \let\left\holdinginserts
    \let\right\left
    \let\mskip\mkern
    \let\hskip\kern
    \let\bm@prime\copy
    \let_\relax
    \def'{\bm@prime\prime\relax}%
    \def\@ifnextchar##1##2##3##4{%
      \if##1##4%
        \expandafter\@firstoftwo
      \else
        \expandafter\@secondoftwo
      \fi
      {##2##4}{##3{##4}}}%
% \changes{v1.1g}{2004/01/23}{Use kernel version of
%                             \cs{@ifnextchar} (pr/3501)}
    \let\kernel@ifnextchar\@ifnextchar
    \def\GenericWarning##1##2{%
      \unvcopy{\GenericWarning{##1}{##2}}}%
    \def\GenericError##1##2##3##4{%
      \unvcopy{\GenericError{##1}{##2}{##3}{##4}}}%
    \let\DN@\copy
    \let\FN@\copy
    \let\next@\copy
    \global\let\bm@first\@empty
    \ifx\uproot@\undefined\else
       \def\root##1\of##2{{\root##1\of{##2}}}%
    \fi
    \def\mathaccentV##1{\mathaccent"\accentclass@}%
    \let\@ifnext\@ifnextchar
    \let\measure@lhs\copy
    \let \rel@break\copy
    \let \bin@break\copy
    \let \after@open\copy
    \let \after@close\copy
    \let\ifmmode\iftrue
     \let\install@mathalphabet\def
     \let\getanddefine@fonts\@gobbletwo
     #3%
    \def\select@group##1##2##3##4{{%
      \protect##1{##4}}}%
    \def\use@mathgroup##1##2##3{{%
      \protect\use@mathgroup##1{##2}{##3}}}%
    \bm@expand#5\bm@end
  \endgroup
  #4}
}
\outer\def\bm@end{\@@end}
\makeatother

\newcommand{\myfuncA}[0]{A}
\newcommand{\myfuncB}[1]{#1}
\newcommand{\myfuncC}[1][]{#1}

\begin{document}
\[
    \bm{\myfuncA} % works
    \bm{\myfuncB{B}} % works
    \textbf{\myfuncC[C]} % works
%\tracingall
    \bm{\myfuncC[C]} % doesn't work
\]
\end{document}

相关内容