问题原因

问题原因

Hendrik Vogt 提供一个极好的替代 overline 的方法

我在将 widebar 与 bm 和 mathcal 结合使用时遇到了问题。

A类似问题已经问过了。但是,在这种情况下,仅仅切换到 bm 包来处理粗体符号的解决方法不起作用,如下例所示。

\documentclass{article}
\usepackage{amsmath}
\usepackage{bm}
\makeatletter
\let\save@mathaccent\mathaccent
\newcommand*\if@single[3]{%
  \setbox0\hbox{${\mathaccent"0362{#1}}^H$}%
  \setbox2\hbox{${\mathaccent"0362{\kern0pt#1}}^H$}%
  \ifdim\ht0=\ht2 #3\else #2\fi
  }
%The bar will be moved to the right by a half of \macc@kerna, which is computed by amsmath:
\newcommand*\rel@kern[1]{\kern#1\dimexpr\macc@kerna}
%If there's a superscript following the bar, then no negative kern may follow the bar;
%an additional {} makes sure that the superscript is high enough in this case:
\newcommand*\widebar[1]{\@ifnextchar^{{\wide@bar{#1}{0}}}{\wide@bar{#1}{1}}}
%Use a separate algorithm for single symbols:
\newcommand*\wide@bar[2]{\if@single{#1}{\wide@bar@{#1}{#2}{1}}{\wide@bar@{#1}{#2}{2}}}
\newcommand*\wide@bar@[3]{%
  \begingroup
  \def\mathaccent##1##2{%
%Enable nesting of accents:
    \let\mathaccent\save@mathaccent
%If there's more than a single symbol, use the first character instead (see below):
    \if#32 \let\macc@nucleus\first@char \fi
%Determine the italic correction:
    \setbox\z@\hbox{$\macc@style{\macc@nucleus}_{}$}%
    \setbox\tw@\hbox{$\macc@style{\macc@nucleus}{}_{}$}%
    \dimen@\wd\tw@
    \advance\dimen@-\wd\z@
%Now \dimen@ is the italic correction of the symbol.
    \divide\dimen@ 3
    \@tempdima\wd\tw@
    \advance\@tempdima-\scriptspace
%Now \@tempdima is the width of the symbol.
    \divide\@tempdima 10
    \advance\dimen@-\@tempdima
%Now \dimen@ = (italic correction / 3) - (Breite / 10)
    \ifdim\dimen@>\z@ \dimen@0pt\fi
%The bar will be shortened in the case \dimen@<0 !
    \rel@kern{0.6}\kern-\dimen@
    \if#31
      \overline{\rel@kern{-0.6}\kern\dimen@\macc@nucleus\rel@kern{0.4}\kern\dimen@}%
      \advance\[email protected]\dimexpr\macc@kerna
%Place the combined final kern (-\dimen@) if it is >0 or if a superscript follows:
      \let\final@kern#2%
      \ifdim\dimen@<\z@ \let\final@kern1\fi
      \if\final@kern1 \kern-\dimen@\fi
    \else
      \overline{\rel@kern{-0.6}\kern\dimen@#1}%
    \fi
  }%
  \macc@depth\@ne
  \let\math@bgroup\@empty \let\math@egroup\macc@set@skewchar
  \mathsurround\z@ \frozen@everymath{\mathgroup\macc@group\relax}%
  \macc@set@skewchar\relax
  \let\mathaccentV\macc@nested@a
%The following initialises \macc@kerna and calls \mathaccent:
  \if#31
    \macc@nested@a\relax111{#1}%
  \else
%If the argument consists of more than one symbol, and if the first token is
%a letter, use that letter for the computations:
    \def\gobble@till@marker##1\endmarker{}%
    \futurelet\first@char\gobble@till@marker#1\endmarker
    \ifcat\noexpand\first@char A\else
      \def\first@char{}%
    \fi
    \macc@nested@a\relax111{\first@char}%
  \fi
  \endgroup
}
\makeatother
\newcommand\test[1]{%
$#1{\bm{A}}$
$#1{\bm{\mathcal A}}$
}

\begin{document}
\test\widebar

\test\overline
\end{document}

Mathcal 上的宽线和上划线之间的区别

有没有什么简单的办法可以解决这个问题?

答案1

问题原因

\bm{A}或输入时\mathcal{A},它们将无法通过测试,从而产生不受欢迎的长条。\bm{\mathcal{A}}\widebar\if@single

解决方案

  1. 排版不带重音符号。
  2. 在符号的一个版本上添加重音符号\phantom,其中我们必须\if@single强制使用一个版本。
  3. 微调重音的\mathllap位置mathtools包装,以及一些负空间\!

平均能量损失

\documentclass{article}
\usepackage{amsmath}
\usepackage{bm}
% Hendrik Vogt's widebar: https://tex.stackexchange.com/a/60253/164314
\makeatletter
\let\save@mathaccent\mathaccent
\newcommand*\if@single[3]{%
  \setbox0\hbox{${\mathaccent"0362{#1}}^H$}%
  \setbox2\hbox{${\mathaccent"0362{\kern0pt#1}}^H$}%
  \ifdim\ht0=\ht2 #3\else #2\fi
  }
%The bar will be moved to the right by a half of \macc@kerna, which is computed by amsmath:
\newcommand*\rel@kern[1]{\kern#1\dimexpr\macc@kerna}
%If there's a superscript following the bar, then no negative kern may follow the bar;
%an additional {} makes sure that the superscript is high enough in this case:
\newcommand*\widebar[1]{\@ifnextchar^{{\wide@bar{#1}{0}}}{\wide@bar{#1}{1}}}
%Use a separate algorithm for single symbols:
\newcommand*\wide@bar[2]{\if@single{#1}{\wide@bar@{#1}{#2}{1}}{\wide@bar@{#1}{#2}{2}}}
\newcommand*\wide@bar@[3]{%
  \begingroup
  \def\mathaccent##1##2{%
%Enable nesting of accents:
    \let\mathaccent\save@mathaccent
%If there's more than a single symbol, use the first character instead (see below):
    \if#32 \let\macc@nucleus\first@char \fi
%Determine the italic correction:
    \setbox\z@\hbox{$\macc@style{\macc@nucleus}_{}$}%
    \setbox\tw@\hbox{$\macc@style{\macc@nucleus}{}_{}$}%
    \dimen@\wd\tw@
    \advance\dimen@-\wd\z@
%Now \dimen@ is the italic correction of the symbol.
    \divide\dimen@ 3
    \@tempdima\wd\tw@
    \advance\@tempdima-\scriptspace
%Now \@tempdima is the width of the symbol.
    \divide\@tempdima 10
    \advance\dimen@-\@tempdima
%Now \dimen@ = (italic correction / 3) - (Breite / 10)
    \ifdim\dimen@>\z@ \dimen@0pt\fi
%The bar will be shortened in the case \dimen@<0 !
    \rel@kern{0.6}\kern-\dimen@
    \if#31
      \overline{\rel@kern{-0.6}\kern\dimen@\macc@nucleus\rel@kern{0.4}\kern\dimen@}%
      \advance\[email protected]\dimexpr\macc@kerna
%Place the combined final kern (-\dimen@) if it is >0 or if a superscript follows:
      \let\final@kern#2%
      \ifdim\dimen@<\z@ \let\final@kern1\fi
      \if\final@kern1 \kern-\dimen@\fi
    \else
      \overline{\rel@kern{-0.6}\kern\dimen@#1}%
    \fi
  }%
  \macc@depth\@ne
  \let\math@bgroup\@empty \let\math@egroup\macc@set@skewchar
  \mathsurround\z@ \frozen@everymath{\mathgroup\macc@group\relax}%
  \macc@set@skewchar\relax
  \let\mathaccentV\macc@nested@a
%The following initialises \macc@kerna and calls \mathaccent:
  \if#31
    \macc@nested@a\relax111{#1}%
  \else
%If the argument consists of more than one symbol, and if the first token is
%a letter, use that letter for the computations:
    \def\gobble@till@marker##1\endmarker{}%
    \futurelet\first@char\gobble@till@marker#1\endmarker
    \ifcat\noexpand\first@char A\else
      \def\first@char{}%
    \fi
    \macc@nested@a\relax111{\first@char}%
  \fi
  \endgroup
}
\makeatother
\newcommand\test[1]{%
$#1{\bm{A}}$
$#1{\bm{\mathcal A}}$
}

% My implementation starts here
\usepackage{mathtools}
\makeatletter
% Forcing a \if@single version but keep the flexibility of a following superscript
\newcommand\widebarbm[1]{%
  \@ifnextchar^{%
    {\bm{#1}\mathllap{\wide@bar@{\phantom{\!\bm{#1}}}{0}{1}}}}%
  {%
    \bm{#1}\mathllap{\wide@bar@{\phantom{\!\bm{#1}}}{1}{1}}}%
}
\newcommand\widebarcal[1]{%
  \@ifnextchar^{%
    {\mathcal{#1}\mathllap{\wide@bar@{\phantom{\!\mathcal{#1}}}{0}{1}}}}%
  {%
    \mathcal{#1}\mathllap{\wide@bar@{\phantom{\!\mathcal{#1}}}{1}{1}}}%
}
\newcommand\widebarbmcal[1]{%
  \@ifnextchar^{%
    {\bm{\mathcal{#1}}\mathllap{\wide@bar@{\phantom{\!\bm{\mathcal{#1}}}}{0}{1}}}}%
  {%
    \bm{\mathcal{#1}}\mathllap{\wide@bar@{\phantom{\!\bm{\mathcal{#1}}}}{1}{1}}}%
}
\makeatother

\begin{document}
\test\widebar

\test\overline

\bigskip

New versions below: 
\begin{center}
\renewcommand\arraystretch{1.3}
\begin{tabular}{l l}
\hline
$\widebarbm{A}$       & by \verb|$\widebarbm{A}$|      \\
\hline
$\widebarbm{B}^a$     & by \verb|$\widebarbm{B}^a$|    \\
\hline
$\widebarcal{A}$      & by \verb|$\widebarcal{A}$|     \\
\hline
$\widebarcal{B}^a$    & by \verb|$\widebarcal{B}^a$|   \\
\hline
$\widebarbmcal{A}$    & by \verb|$\widebarbmcal{A}$|   \\
\hline
$\widebarbmcal{B}^a$  & by \verb|$\widebarbmcal{B}^a$| \\
\hline
\end{tabular}
\end{center}

\end{document}

输出

在此处输入图片描述

相关内容