Implementation 1
This code changes the x-height of the accent font for its argument. It should be fairly robust. Rather than scaling the height by 1.3, one could simply add a fixed value to it. Because of the way TeX computes accent heights, there is some minimum height of an accent and so this tends to have no discernible effect on lowercase letters.
\makeatletter
\newcommand*\wt[1]{\mathpalette\wthelper{#1}}
\newcommand*\wthelper[2]{%
\hbox{\dimen@\accentfontxheight#1%
\accentfontxheight#11.3\dimen@
$\m@th#1\widetilde{#2}$%
\accentfontxheight#1\dimen@
}%
}
\newcommand*\accentfontxheight[1]{%
\fontdimen5\ifx#1\displaystyle
\textfont
\else\ifx#1\textstyle
\textfont
\else\ifx#1\scriptstyle
\scriptfont
\else
\scriptscriptfont
\fi\fi\fi3
}
\makeatother
Implementation 2
This attempts to duplicate Rule 12 and the relevant portions of Rules 16–18 in Appendix G of The TeXbook for typesetting math accents.
Some notes on the implementation: I don't know how to compute successors, so instead I replace box y which should just be the accent and the italic correction with $\widetilde{\hphantom{...}}$
. As a result, the tilde should already be shifted by half(w+width(y)). From tex.web
, the shift amount of box y is given by
shift_amount(y):=s+half(w-width(y));
thus it suffices to compute the kerning s and shift right by that amount.
The code below contains 3 main parts.
The first thing it does is tries to parse the argument to \wt
which will appear as the nucleus of the Acc atom. This is extremely brittle. If the argument expands to any primitives other than \relax
, \bgroup
, \egroup
, \begingroup
, \endgroup
, \fam
, \
(control space), \char
(not tested), \mathchar
(not tested), \mathcode
(not tested), a letter, or a symbol, it will treat the nucleus as not a single character even if it really is. If there is an unknown control sequence, for example \let\unknown\foo
, it will fail with a mysterious error because it cannot expand \unknown
. Some effort is put into checking for changes of fonts.
If the \wt@checknucleus
macro decides that the nucleus of the Acc atom we're about to fake is just a single character, it stores the \mathcode
and notes the fact by setting \ifwt@nucleussingle
to \iftrue
. (I suppose the third part of the code could just check the saved math code instead.)
After \wt@checknucleus
is complete, it scans ahead looking for _
and ^
. If these are hidden in macros, it won't find them! Any subscripts and superscripts are saved for later processing in either Rule 12 or Rule 18.
Finally, \wt@choice
uses \mathchoice
to typeset the formula in each of the 4 styles which is done by \wt@applyrules
and then pick the appropriate one. \wt@applyrules
contains the relevant rules from The TeXbook as comments followed by some code that attempts to apply the rules.
The code is not perfect. See the output from my test at the bottom of this answer. Also, it loses crampedness because pdfTeX provides no way to test for it. It does perform the appropriate cramping where Rule 12 calls for it.
\makeatletter
\newif\ifwt@nucleussingle
\newif\ifwt@sub
\newif\ifwt@sup
\newtoks\wt@nucleus
\newtoks\wt@sub
\newtoks\wt@sup
\newcount\wt@nucleusmathcode
\newcount\wt@fam
\newdimen\wt@s
\newdimen\wt@delta
\DeclareRobustCommand*\wt[1]{%
\begingroup
\wt@nucleus{#1}%
\wt@checknucleus%
\wt@subfalse
\wt@supfalse
\futurelet\wt@temp\wt@parse
}
\def\wt@checknucleus{%
\begingroup
\wt@nucleussinglefalse
\setbox\z@\hbox{$\the\wt@nucleus
\def\use@mathgroup##1##2{\relax\math@bgroup
\mathgroup##2\relax\math@egroup}%
\expandafter\xdef\expandafter\wt@gtemp
\expandafter{\the\wt@nucleus}$}%
\expandafter\wt@checktoken\wt@gtemp\wt@sentinel
\endgroup
\wt@gtemp
}
\def\wt@sentinel{\wt@sentinel}
\def\wt@checktoken#1{%
\let\wt@temp\wt@checktoken
\ifx#1\relax
\else\ifx#1\bgroup
\bgroup
\else\ifx#1\egroup
\egroup
\else\ifx#1\begingroup
\begingroup
\else\ifx#1\endgroup
\endgroup
\else\ifx#1\fam
\let\wt@temp\fam
\afterassignment\wt@checktoken
\else\ifx#1 \else\ifx#1\wt@sentinel
\let\wt@temp\relax
\else\ifx#1\@sptoken
\else\ifcat#1a%
\wt@checksingle{\mathcode`#1}%
\else\ifcat#1/%
\wt@checksingle{\mathcode`#1}%
\else\ifx#1\char
\let\wt@temp\count@
\afterassignment\wt@checkchar
\else\ifx#1\mathchar
\let\wt@temp\count@
\afterassignment\wt@checkmathchar
\else\ifx#1\mathcode
\let\wt@temp\mathcode
\afterassignment\wt@checktoken
\else
\global\let\wt@gtemp\wt@nucleussinglefalse
\wt@nucleussingletrue % Not really true...
% In principle, this could handle every primitive.
\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
\wt@temp
}
\def\wt@checkchar{%
\wt@checksingle{\mathcode\count@}%
\wt@checktoken
}
\def\wt@checkmathchar{%
\wt@checksingle{\count@}%
\wt@checktoken
}
\def\wt@checksingle#1{%
\ifwt@nucleussingle
\global\let\wt@gtemp\wt@nucleussinglefalse
\else
\xdef\wt@gtemp{%
\noexpand\wt@nucleussingletrue
\wt@fam\the\fam\relax
\wt@nucleusmathcode\the#1\relax
}%
\wt@nucleussingletrue
\fi
}
\def\wt@parse{%
\let\wt@next\wt@choice
\ifdefmacro{\wt@temp}{}%
{%
\ifcat_\wt@temp
\ifwt@sub\else
\let\wt@next\wt@parsesub
\fi
\else\ifcat^\wt@temp
\ifwt@sup\else
\let\wt@next\wt@parsesup
\fi
\else\ifcat\@sptoken\wt@temp
\def\wt@next##1{\futurelet\wt@temp\wt@parse}%
\fi\fi\fi
}%
\wt@next
}
\def\wt@parsesub#1#2{%
\wt@sub{#2}%
\wt@subtrue
\futurelet\wt@temp\wt@parse
}
\def\wt@parsesup#1#2{%
\wt@sup{#2}%
\wt@suptrue
\futurelet\wt@temp\wt@parse
}
\def\wt@choice{%
\mathchoice{\wt@applyrules\displaystyle\textfont}%
{\wt@applyrules\textstyle\textfont}%
{\wt@applyrules\scriptstyle\scriptfont}%
{\wt@applyrules\scriptscriptstyle\scriptscriptfont}%
\endgroup
}
\def\wt@applyrules#1#2{%
% The following block comments are quotes from Knuth's The
% TeXbook. My notes appear [in brackets].
%
% Rule 12:
% If the current item is an Acc atom (from \mathaccent) [this
% is what we're constructing], just go to Rule 16 if the
% accent character doesn't exist in the current size [ignoring
% this]. Otherwise set box x to the nucleus in style C', and
% set u to the width of this box.
% [We don't need u.]
\setbox\z@\hbox{$\m@th\cramped[#1]{\the\wt@nucleus}$}%
% If the nucleus is not a single character, let s = 0;
% otherwise set s to the kern amount for the nucleus followed
% by the \skewchar of its font
\ifwt@nucleussingle
\count@\wt@nucleusmathcode
\divide\count@\@cclvi
\@tempcnta\count@
\divide\@tempcnta8
\multiply\@tempcnta8
\advance\count@-\@tempcnta
\ifnum\@tempcnta="70
\ifnum\wt@fam>\z@
\ifnum\wt@fam<16
\count@\wt@fam
\fi
\fi
\fi
\@tempcnta\wt@nucleusmathcode
\divide\@tempcnta\@cclvi
\multiply\@tempcnta\@cclvi
\advance\@tempcnta-\wt@nucleusmathcode
\@tempcnta-\@tempcnta
\edef\currentfont{\the#2\count@}%
\count@\skewchar\currentfont
\ifnum\count@=\m@ne
\wt@s\z@ % s
\else
\setbox\tw@\hbox{\currentfont\char\@tempcnta\char\count@}%
\wt@s\wd\tw@
\setbox\tw@\hbox{\currentfont\char\@tempcnta}%
\advance\wt@s-\wd\tw@
\setbox\tw@\hbox{\currentfont\char\count@}%
\advance\wt@s-\wd\tw@ % s
\fi
\else
\wt@s\z@
\fi
% If the accent character has a successor in its font whose
% width is <= u, change it to the successor and repeat this
% sentence.
% [I don't know how to do this, so I'm ignoring it.]
%
% Now set delta <- min(h(x), chi), where chi is \fontdimen5
% (the x-height in the accent font).
\edef\accentfont{\the#2\thr@@}%
\wt@delta\fontdimen5\accentfont % x-height in accent font
\ifdim\wt@delta>\ht\z@ \wt@delta\ht\z@ \fi % delta
\advance\wt@delta\p@ % Increase delta by 1pt
% If the nucleus is a single character, replace box x by a box
% containing the nucleus together with the superscript and
% subscript of the Acc atom, in style C, and make the
% sub/superscript of the Acc atom empty; also increase delta
% by the difference between the new and old values of h(x).
% [Note that we lose crampedness here since one cannot check
% for it with pdfTeX.]
\ifwt@nucleussingle
\advance\wt@delta-\ht\z@
\setbox\z@\hbox{$\m@th#1%
\the\wt@nucleus
\ifwt@sub_{\the\wt@sub}\fi
\ifwt@sup^{\the\wt@sup}\fi $}%
\wt@subfalse
\wt@supfalse
\advance\wt@delta\ht\z@
\fi
% Put the accent into a new box y, including the italic
% correction.
% [\setbox\tw@\hbox{\accentfont\char"65\/} would work except
% that I didn't find the larger accents above. Instead, use
% \widetilde and \hphantom.]
\setbox\tw@\hbox{$\m@th#1\widetilde{\hphantom{\the\wt@nucleus}}$}% box y
\wd\tw@\z@
% Let z be a vbox consisting of: boy y moved right s +
% (1/2)(u-w(y)), kern -delta, and box x.
\setbox\tw@\vbox{%
% [Since we aren't setting the accent ourself, we only
% need to move right by s since the \widetilde will
% take care of the rest.
% \moveright\dimexpr\dimen@+.5\wd\z@-.5\wd\tw@\relax\box\tw@]
\moveright\wt@s\box\tw@
\nointerlineskip
\kern-\wt@delta
\copy\z@
}% box z
% If h(z) < h(x), add a kern of h(x) - h(z) above box y and
% set h(z) <- h(x).
\ifdim\ht\tw@<\ht\z@
\dimen@\ht\z@
\advance\dimen@\ht\tw@
\setbox\tw@\vbox{%
\kern\dimen@
\unvbox\tw@
}%
\ht\tw@\ht\z@
\fi
% Finally set w(z) <- w(x),
\wd\tw@\wd\z@
% replace the nucleus of the Acc atom by box z, and continue
% with Rule 16.
%
% Rule 16:
% Change the current item to an Ord atom, and continue with
% Rule 17.
\mathord{\box\tw@}%
%
% Rule 17:
% If the nucleus of the current item is a math list [it
% isn't]...
% Then if the nucleus is not simply a symbol [it isn't], go on
% to Rule 18. ...
%
% Rule 18:
% (The remaining task for the current atom is to attach a
% possible subscript and superscript.) If both the subscript
% and superscript fields are empty, move to the next item.
% Otherwise continue with the following subrules.
% [Let's let TeX deal with subscripts and superscripts here.]
\ifwt@sub_\the\wt@sub\fi
\ifwt@sup^\the\wt@sup\fi
}
\makeatother
This requires the mathtools
package for \cramped
and etoolbox
for \ifdefmacro
.
This is my current test. Note that \mathrm
doesn't work properly for some reason.
$\widetilde{B}\wt{B}$
$\widetilde{m}\wt{m}$
$\widetilde{W}\wt{W}$
$\widetilde{w}\wt{w}$
$\widetilde{XY}\wt{XY}$
$\widetilde{\mathcal{B}}\wt{\mathcal{B}}$
$\widetilde{\mathcal{M}}\wt{\mathcal{M}}$
$\widetilde{\mathcal{W}}\wt{\mathcal{W}}$
$\widetilde{\mathcal{I}}\wt{\mathcal{I}}$
$\widetilde{\mathcal{XY}}\wt{\mathcal{XY}}$
$\widetilde{\mathrm{B}}\wt{\mathrm{B}}$
$\widetilde{\mathrm{M}}\wt{\mathrm{M}}$
$\widetilde{\mathrm{W}}\wt{\mathrm{W}}$
$\widetilde{\mathrm{I}}\wt{\mathrm{I}}$
$\widetilde{\mathrm{XY}}\wt{\mathrm{XY}}$
\newcommand\triple[2]{#1{#2}_{#1{#2}_{#1{#2}}}}
\newcommand\tw{\triple\widetilde}
\newcommand\twt{\triple\wt}
$\tw A\tw B\tw I\tw W\tw m\tw w$
$\twt A\twt B\twt I\twt W\twt m\twt w$
Here are two ways of obtaining what you're after:
\documentclass{article}
\usepackage{amsmath,array}
\begin{document}
\begin{equation}
\begin{aligned}
A & = B & \qquad C & = D \\
& = E & & = F \\
& = G & & = H \\[5mm]
I & = J & K & = L \\
& = M & & = N \\
& = O & & = P
\end{aligned}
\end{equation}
\begin{equation}
\renewcommand{\arraystretch}{1.2}
\begin{array}{r@{}>{\null}l@{\qquad}r@{}>{\null}l}
A & = B & C & = D \\
& = E & & = F \\
& = G & & = H \\[5mm]
I & = J & K & = L \\
& = M & & = N \\
& = O & & = P
\end{array}
\end{equation}
\end{document}
The first sets an equation
(resulting in a single equation number) containing an aligned
environment. This allows for the regular style align
delimiting.
The second sets an array
inside the equation
instead of an aligned
environment, with similarly formatted output. Mild horizontal spacing difference stem form the different column separation lengths.
Best Answer
To get an overline, well, just use the
\overline
macro!You might want to add some semantic meaning. E.g., define a macro
and use as
or something similar.