TeX - LaTeX Asked by Hendrik Vogt on August 17, 2020
One can use bar
to put a bar over a letter in math mode, but often the bar isn’t wide enough. An alternative is overline
, but this isn’t an accent, so it doesn’t take into account the skew of the letter. In the following example, the bar extends too far to the left:
Now the mathabx
package offers a widebar
accent, but this has several drawbacks:
mathabx
changes a lot of other things,
The widebar
sits slightly higher than bar
and overline
,
In previewers (checked with kpdf
and acroread
), the widebar
appears fuzzy, which bar
and overline
don’t.
So my question is: How can I put a wide bar over a letter in math mode without the above drawbacks?
Here's a new implementation of widebar
, based on overline
. It works by hacking into amsmath
's accent placement, so it needs that package. Here's a comparison of widebar
(first line) and overline
(second line):
I think the placement of the bars in the first line is better, except for the sin z
, where there's no difference. Note that widebar
works well together with superscripts, but not necessarily with subscripts. (overline
has the same issue.) It also works well over combined symbols like AB
in most cases.
documentclass{article}
usepackage{amsmath}
makeatletter
letsave@mathaccentmathaccent
newcommand*if@single[3]{%
setbox0hbox{${mathaccent"0362{#1}}^H$}%
setbox2hbox{${mathaccent"0362{kern0pt#1}}^H$}%
ifdimht0=ht2 #3else #2fi
}
%The bar will be moved to the right by a half of macc@kerna, which is computed by amsmath:
newcommand*rel@kern[1]{kern#1dimexprmacc@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
defmathaccent##1##2{%
%Enable nesting of accents:
letmathaccentsave@mathaccent
%If there's more than a single symbol, use the first character instead (see below):
if#32 letmacc@nucleusfirst@char fi
%Determine the italic correction:
setboxz@hbox{$macc@style{macc@nucleus}_{}$}%
setboxtw@hbox{$macc@style{macc@nucleus}{}_{}$}%
dimen@wdtw@
advancedimen@-wdz@
%Now dimen@ is the italic correction of the symbol.
dividedimen@ 3
@tempdimawdtw@
advance@tempdima-scriptspace
%Now @tempdima is the width of the symbol.
divide@tempdima 10
advancedimen@-@tempdima
%Now dimen@ = (italic correction / 3) - (Breite / 10)
ifdimdimen@>z@ dimen@0ptfi
%The bar will be shortened in the case dimen@<0 !
rel@kern{0.6}kern-dimen@
if#31
overline{rel@kern{-0.6}kerndimen@macc@nucleusrel@kern{0.4}kerndimen@}%
[email protected]@kerna
%Place the combined final kern (-dimen@) if it is >0 or if a superscript follows:
letfinal@kern#2%
ifdimdimen@<z@ letfinal@kern1fi
iffinal@kern1 kern-dimen@fi
else
overline{rel@kern{-0.6}kerndimen@#1}%
fi
}%
macc@depth@ne
letmath@bgroup@empty letmath@egroupmacc@set@skewchar
mathsurroundz@ frozen@everymath{mathgroupmacc@grouprelax}%
macc@set@skewcharrelax
letmathaccentVmacc@nested@a
%The following initialises macc@kerna and calls mathaccent:
if#31
macc@nested@arelax111{#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:
defgobble@till@marker##1endmarker{}%
futureletfirst@chargobble@till@marker#1endmarker
ifcatnoexpandfirst@char Aelse
deffirst@char{}%
fi
macc@nested@arelax111{first@char}%
fi
endgroup
}
makeatother
newcommandtest[1]{%
$#1{M}$ $#1{A}$ $#1{g}$ $#1{beta}$ $#1{mathcal A}^q$
$#1{AB}^sigma$ $#1{H}^C$ $#1{sin z}$ $#1{W}_n$}
begin{document}
testwidebar
testoverline
end{document}
Here is my previous simpler implementation; the intended use is for single symbols. It also works when applied to several symbols, but then the placement of the bar may not be appropriate (see AW
at the end). Moreover, subsequent superscripts may be placed too close to the bar.
documentclass{article}
usepackage{amsmath}
makeatletter
newcommand*rel@kern[1]{kern#1dimexprmacc@kerna}
newcommand*widebar[1]{%
begingroup
defmathaccent##1##2{%
rel@kern{0.8}%
overline{rel@kern{-0.8}macc@nucleusrel@kern{0.2}}%
rel@kern{-0.2}%
}%
macc@depth@ne
letmath@bgroup@empty letmath@egroupmacc@set@skewchar
mathsurroundz@ frozen@everymath{mathgroupmacc@grouprelax}%
macc@set@skewcharrelax
letmathaccentVmacc@nested@a
macc@nested@arelax111{#1}%
endgroup
}
makeatother
begin{document}
$widebar{M}$ $widebar{A}$ $widebar{mathcal A}$ $widebar{g}$ $widebar{beta}$
$widebar{AB}$ $widebar{AW}$
$overline{M}$ $overline{A}$ $overline{mathcal A}$ $overline{g}$ $overline{beta}$
$overline{AB}$ $overline{AW}$
end{document}
Correct answer by Hendrik Vogt on August 17, 2020
1) You can use only widebar
through:
% from mathabx.sty and mathabx.dcl
DeclareFontFamily{U}{mathx}{hyphencharfont45}
DeclareFontShape{U}{mathx}{m}{n}{
<5> <6> <7> <8> <9> <10>
<10.95> <12> <14.4> <17.28> <20.74> <24.88>
mathx10
}{}
DeclareSymbolFont{mathx}{U}{mathx}{m}{n}
DeclareFontSubstitution{U}{mathx}{m}{n}
DeclareMathAccent{widebar}{0}{mathx}{"73}
or simpler (with example):
documentclass{article}
DeclareFontFamily{U}{mathx}{hyphencharfont45}
DeclareFontShape{U}{mathx}{m}{n}{<-> mathx10}{}
DeclareSymbolFont{mathx}{U}{mathx}{m}{n}
DeclareMathAccent{widebar}{0}{mathx}{"73}
begin{document}
$widebar M = widebar{abcd}$
end{document}
2) I don't think it matters much, bar h
is also higher than bar a
. Just remember not to use bar M
and widebar M
together.
3) Maybe bad hinting. I've no idea.
Answered by Leo Liu on August 17, 2020
I show my solution for this problem for plain TeX, where amsmath.sty
isn't loaded, because the first line of this macro file says: NeedsTeXFormat{LaTeX2e}
. I leaved the skewchar
calculation because this is more suitable for accents like dot. My ẅidebar
begins by left slanted border (by default) and ends at the same place as overline
. If the first token is non-letter then normal overline
is used.
But there are many exceptions for this rule declared in widebarE
macro. If you feel that you are able to do better look of widebar
, then you can simply re-define the widecharE
or add to this macro more exceptions for more characters.
newcounttmpnum newdimentmpdim
{lccode`?=`p lccode`!=`t lowercase{gdefignorept#1?!{#1}}}
edefwidecharS{expandafterignoreptthefontdimen1textfont1}
defwidebar#1{futureletnextwidebarA#1widebarA}
defwidebarA#1widebarA{%
deftmp{0}ifcatnoexpandnext Adeftmp{1}fi
widebarE
ifdimtmp pt=0pt overline{#1}%
else {mathpalettewidebarB{#1}}fi
}
defwidebarB#1#2{%
setbox0=hbox{$#1overline{#2}$}%
tmpdim=tmpht0 advancetmpdim by-.4pt
tmpdim=widecharStmpdim
kerntmpdimoverline{kern-tmpdim#2}%
}
defwidebarC#1#2 {ifx#1end else
ifx#1nextdeftmp{#2}widebarD
elseexpandafterexpandafterexpandafterwidebarC
fifi
}
defwidebarD#1end. {fifi}
defwidebarE{widebarC A1.4 J1.2 L.6 O.8 T.5 U.7 V.3 W.1 Y.2
a.5 b.2 d1.1 h.5 i.5 k.5 l.3 m.4 n.4 o.6 p.4 r.5 t.4 v.7 w.7 x.8 y.8
alpha1 beta1 gamma.6 delta.8 epsilon.8 varepsilon.8 zeta.6 eta.4
theta.8 vartheta.8 iota.5 kappa.8 lambda.5 mu1 nu.5 xi.7 pi.6
varpi.9 rho1 varrho1 sigma.7 varsigma.7 tau.6 upsilon.7 phi1
varphi.6 chi.7 psi1 omega.5 cal1 end. }
deftest#1{$let.=#1 .M, .A, .g, .beta, .{cal A}^q, .{AB}^sigma,
.H^C, .{sin z}, .W_{!n}$}
testwidebar
testoverline
bye
First line shows the widechar
, second line is normal overline
.
Answered by wipet on August 17, 2020
I confronted a similar problem with a need for a pretty bar over various characters with mathbf, mathcal, mathfrak, etc. By "pretty," I mean that the bar seems very appropriate to the character shape and size, and this means adjusting the length and placement (left and right offsets) until it looks right. Further, the commands used must be compatible with MathJax in HTML after the TeX file is converted to XML for conversion to HTML on the Springer website.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Program for "manually" adjusting the bar over capital letters %
% or any other character to put a bar over. You specify the %
% character and two offset lengths. The program calculates the %
% the bar length such that the character with a bar has the same %
% same length as the character without a bar. %
% %
% Specify the character and initial offsets below. Produce a pdf %
% and zoom in to see the barred character full screen. Return to %
% the TeX file and change the offsets until you are happy with %
% with the resulting appearance. Then zoom out with the pdf viewer %
% and copy the command for pasting wherever you want to save it. %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
documentclass[letterpaper]{article}
usepackage[vmargin=0.25in]{geometry}
usepackage[tbtags]{amsmath}
usepackage{amsfonts,amssymb}
usepackage{calc}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% If you want to use a character from another font (e.g., Euler) %
% then add the needed package above. %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
newlength{charlength}
newlength{leftoffset}
newlength{rightoffset}
newlength{overlength}
newlength{backlength} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% User settings %
newcommand{testchar}{mathcal{S}} % Set the character you want %
newcommand{printchar}{textbackslash mathcal{S}}% twice, slightly different. %
setlength{leftoffset}{0.71pt} % Set the left offset and the %
setlength{rightoffset}{0.71pt} % right offset for the bar. %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
settowidth{charlength}{$testchar$}
setlength{overlength}{charlength - leftoffset - rightoffset}
setlength{backlength}{charlength - rightoffset}
pagestyle{empty}
begin{document}
vspace*{25mm}
$overset{kernleftoffsetunderline{kernoverlength}kernrightoffset}{testchar}$
$text{textbackslash overset{textbackslash kerntheleftoffsettextbackslash underline{textbackslash kerntheoverlength}textbackslash kerntherightoffset}{printchar}}$
bigskip
$kernleftoffsetoverline{vphantom{testchar}kernoverlength}kern-backlengthtestchar$
$text{textbackslash kerntheleftoffsettextbackslash overline{textbackslash vphantom{printchar}textbackslash kerntheoverlength}textbackslash kern--thebacklengthprintchar}$
end{document}
One drawback is that you must the character you want in the program twice in slightly different ways. For example, if you want a nice bar on mathfrak{C}, then in the program, which is now set for mathcal{S}, you must change S => C twice and change cal => frak twice.
But the payback for the double effort is that you get the command to save or put into another TeX file by copying the command from the pdf in your reader (I use SumatraPDF because the pdf file stays open in the reader while I change the TeX, and when I make the new pdf in WinEdt, it transfers me back to reader looking at the changed pdf in exactly the same place, etc., as when I left it to edit the TeX file).
The program gives two variants: with overset and with overline of a phantom. The separation from the character with overset is about 20% greater than the separation with overline. On my screen with the so-called widebar{mathcal{S}} occupying the full 23.5 cm height of the reader view, the separation is 3 cm for overset and 2.5 cm for overline.
Suppose you have adjusted the left and right offsets for a pretty barfrakC, but you now need a double bar. What to do?
Copy the line newcommandbarfrakC{...} and paste it in the TeX file, change the mathfrak{C} test character (and print character) to barfrakC, and so on to get what you need to paste into newcommanddbarfrakC{}.
Answered by Bill Everett on August 17, 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