在这个链接中有一些「偷」符号的信息。但是似乎没有介绍如何寻找cmex
这样的字体族名对「偷」的思路介绍,所以再开一个问题。
在texdoc comprehensive
得到的symbols-a4.pdf
中有:
为了让代码尽可能「轻」,减少与其他宏包如amssymb
的定义重复,我想把这个符号「偷出来」:
我使用了如下的思路:
从CTAN下载mathabx
包的.zip
文件,文件的目录结构如下:
在./texinput/mathabx.dcl
中:
% line 202
\DeclareMathSymbol{\measuredangle} {0}{mathb}{"3E}
同时 一通乱点乱搜 可以找到在./texinput/mathabx.sty
中:
% line 51
\mathabx@mathb
\DeclareFontFamily{U}{mathb}{\hyphenchar\font45}
\DeclareFontShape{U}{mathb}{m}{n}{
<5> <6> <7> <8> <9> <10> gen * mathb
<10.95> mathb10 <12> <14.4> <17.28> <20.74> <24.88> mathb12
}{}
\DeclareSymbolFont{mathb}{U}{mathb}{m}{n}
\DeclareFontSubstitution{U}{mathb}{m}{n}
\end@mathabx
然后或许得到了一个可行的MWE:
\documentclass{article}
\usepackage{amsmath}
\usepackage{amssymb}%必须放前面...
\DeclareFontFamily{U}{mathb}{\hyphenchar\font45}
\DeclareFontShape{U}{mathb}{m}{n}{
<5> <6> <7> <8> <9> <10> gen * mathb
<10.95> mathb10 <12> <14.4> <17.28> <20.74> <24.88> mathb12
}{}
\DeclareSymbolFont{mathb}{U}{mathb}{m}{n}
\DeclareFontSubstitution{U}{mathb}{m}{n}
\DeclareMathSymbol{\measuredangle} {0}{mathb}{"3E}
\begin{document}
\[ a \measuredangle b \quad \mathbb{E}(X) \]
\end{document}
cmex
、AMSa
类似的“字体族名”?\DeclareFontFamily
、\DeclareFontShape
、\DeclareSymbolFont
、\DeclareFontSubstitution
和\DeclareMathSymbol
一个不能少?\DeclareFontFamily{U}{mathb}{\hyphenchar\font45}
\DeclareFontShape{U}{mathb}{m}{n}{
<5> <6> <7> <8> <9> <10> gen * mathb
<10.95> mathb10 <12> <14.4> <17.28> <20.74> <24.88> mathb12
}{}
\DeclareSymbolFont{mathb}{U}{mathb}{m}{n}
\DeclareMathSymbol{\measuredangle} {0}{mathb}{"3E}
\DeclareFontSubstitution{U}{mathb}{m}{n}
Side-Notes: 基于unicode-math
是否有XeTeX
的(或许更便捷的)方案来偷mathabx
中的\measuredangle
呢?
\measuredangle
对应 glyph 的具体定义在文件 mathsymb.mf
的 852 行,
%%% !!!
beginchar(measured_angle,12u#+2appr#,asc_height#,asc_depth#);
"Measured angle sign";
pickup tiny.nib;
rt x1l=w-appr; lft x2l=appr; rt x3r=w-appr-hround 1.5u;
bot y1l=bot y2l=0; top y3l=h+eps; pos1(rth,90);
(x3r-x3l,y3l-y3r)=d_problem(z2l,y3l,x3r,rth-tiny);
y2r=y1r; z2r-z3r=whatever*(z2l-z3l);
filldraw stroke z1e--z2e--z3e;
%
numeric a;
y2l=y5r; rt x5r=hround max(0.6[Appr,w-Appr]+0.5rth,x2l+0.5(h+d))+eps;
pos5(rth,0);
a=x5r-x2l; 0.5 y4=-d+eps; 0.5(x4-x2l)=a+-+min((0.5(y4-y2l)),a);
0.5(z6-z2l)=a*dir min((angle(z3l-z2l)-angle(z4-z2l)),90);
numeric t[];
tmp_path:=halfcircle rotated -90 scaled 2(x5r-x2r) shifted z2r;
tmpp_path:=reverse(halfcircle rotated -90 scaled 2(x5l-x2r) shifted z2r);
t1=xpart(tmp_path intersectiontimes (z2l..z4));
t2=xpart(tmp_path intersectiontimes (z2l..z6));
z4r=point t1 of tmp_path; z6r=point t2 of tmp_path;
t3=xpart(tmpp_path intersectiontimes (z2l..z6));
t4=xpart(tmpp_path intersectiontimes (z2l..z4));
z4l=point t4 of tmpp_path; z6l=point t3 of tmpp_path;
filldraw subpath (t1,t2) of tmp_path
--subpath (t3,t4) of tmpp_path--cycle;
penlabels(1,2,3,4,5,6);
endchar;
似乎是需要用到 metatype1
? 待续 ...
再次更新, 首先把 mathprmt.mf
复制到一个单独的文件夹出来(方便后期更改), 然后再把上述 measured_angle
的定义摘抄出来, 形成如下的文件:
%%%%%%%%%%%%%% Preamble %%%%%%%%%%%%%%
% 1. variables like: 'appr#' are inside it:
input mathprmt; % load library 'mathbase.mf'
% 2. mode/math setup and function 'd_problem()' in 'mathsymb.mf'
mode_setup;
math_setup;
measured_angle := hex"3E"; % this variable must be known !!!
vardef d_problem(expr origin,top_lim,side_lim,breadth)=
save a,b,c;
a=abs((side_lim-xpart origin)/(top_lim-ypart origin));
b=abs(breadth/(top_lim-ypart origin));
begingroup
vardef f(expr c)=
(1+a**2-2a*b*c+(b*c)**2)*(c**2)<1
enddef;
c=solve f(0,breadth);
endgroup;
breadth*(c,1+-+c)
enddef;
%%%%%%%%%%% Main doc %%%%%%%%%%%%%%
beginchar(measured_angle,12u#+2appr#,asc_height#,asc_depth#);
"Measured angle sign";
pickup tiny.nib;
rt x1l=w-appr; lft x2l=appr; rt x3r=w-appr-hround 1.5u;
bot y1l=bot y2l=0; top y3l=h+eps; pos1(rth,90);
(x3r-x3l,y3l-y3r)=d_problem(z2l,y3l,x3r,rth-tiny);
y2r=y1r; z2r-z3r=whatever*(z2l-z3l);
filldraw stroke z1e--z2e--z3e;
%
numeric a;
y2l=y5r; rt x5r=hround max(0.6[Appr,w-Appr]+0.5rth,x2l+0.5(h+d))+eps;
pos5(rth,0);
a=x5r-x2l; 0.5 y4=-d+eps; 0.5(x4-x2l)=a+-+min((0.5(y4-y2l)),a);
0.5(z6-z2l)=a*dir min((angle(z3l-z2l)-angle(z4-z2l)),90);
numeric t[];
tmp_path:=halfcircle rotated -90 scaled 2(x5r-x2r) shifted z2r;
tmpp_path:=reverse(halfcircle rotated -90 scaled 2(x5l-x2r) shifted z2r);
t1=xpart(tmp_path intersectiontimes (z2l..z4));
t2=xpart(tmp_path intersectiontimes (z2l..z6));
z4r=point t1 of tmp_path; z6r=point t2 of tmp_path;
t3=xpart(tmpp_path intersectiontimes (z2l..z6));
t4=xpart(tmpp_path intersectiontimes (z2l..z4));
z4l=point t4 of tmpp_path; z6l=point t3 of tmpp_path;
filldraw subpath (t1,t2) of tmp_path
--subpath (t3,t4) of tmpp_path--cycle;
penlabels(1,2,3,4,5,6);
endchar;
end
%%%% Compile it by %%%%%%
% mf measure_angle.mf
% gftodvi measure_angle.2602gf
% dvips measure_angle.dvi
% ps2pdf measure_angle.ps
依次使用如下的命令进行编译:
mf measure_angle.mf
gftodvi measure_angle.2602gf
dvips measure_angle.dvi
ps2pdf measure_angle.ps
然后你就可以看到 measure_angle.pdf
生成了, 截图如下:
目前想要在 TeX 中使用该符号还有两个问题:
tfm
文件, 或许还需要 .pk
文件;metatype1
里面的东西;下面讲解如何在 LaTeX 中使用这个符号. 首先在生成对应的 .tfm
文件(TeX Font Metric), 使用如下命令:
mf '\mode=ljfour; input measure_angle.mf'
然后你会看到类似如下的日志输出:
$ mf '\mode=ljfour; input measure_angle.mf'
This is METAFONT, Version 2.71828182 (TeX Live 2026/dev/Arch Linux) (preloaded base=mf)
(measure_angle.mf (mathprmt.mf (mathbase.mf)) [62] )
Font metrics written on measure_angle.tfm.
Output written on measure_angle.600gf (1 character, 196 bytes).
Transcript written on measure_angle.log.
我们生成了 measure_angle.tfm
和 measure_angle.600gf
两个文件(也许你生成的后一个文件中的数字不是 600
, 或者干脆就没有 600
这个字样). 现在你就需要把上面的 *gf
文件转化为 .pk
文件(Packed Raster - 点阵), 使用如下的命令:
gftopk measure_angle.600gf measure_angle.600pk
注意: 如果你上一步生成的是measure_angle.600gf
这种格式的文件, 那么上述的.600pk
中的600
则不能省略 !
随后在当前文件夹就会生成一个名为 measure_angle.600pk
的文件, 有了:
measure_angle.600pk
measure_angle.tfm
两个文件之后我们就可以在 LaTeX 中使用这个符号了, 使用方法如下:
\documentclass{article}
\newfont{\symbolangle}{measure_angle}
\newcommand{\measureangle}{{\symbolangle\char"3E}} % slot 编号请参见 measure_angle.mf 文件
\begin{document}
A new symbol by MetaFont: \measureangle $A = 45^\circ$
\end{document}
其实也可以直接使用 *.mf
文件, 那么你的当前工作路径下必须要有:
mathbase.mf
mathprmt.mf
measure_angle.mf
三个文件(并不是那么的方便). 在第一次编译时,会自动生成对应的 tfm
和 pk
文件, 之后编译时就不需要了. 第一次的编译日志大概长这样:
This is pdfTeX, Version 3.141592653-2.6-1.40.27 (TeX Live 2026/dev/Arch Linux) (preloaded format=pdflatex)
restricted \write18 enabled.
entering extended mode
(./test.tex
LaTeX2e <2024-11-01> patch level 2
L3 programming layer <2025-01-18>
(/usr/share/texmf-dist/tex/latex/base/article.cls
Document Class: article 2024/06/29 v1.4n Standard LaTeX document class
(/usr/share/texmf-dist/tex/latex/base/size10.clo))
kpathsea: Running mktextfm measure_angle
mktextfm: Running mf-nowin -progname=mf \mode:=ljfour; mag:=1; ; nonstopmode; input measure_angle
This is METAFONT, Version 2.71828182 (TeX Live 2026/dev/Arch Linux) (preloaded base=mf)
(/home/<name>/Document/Temp/tex_program/mathabx/test/measure_angle.mf
(/home/<name>/Document/Temp/tex_program/mathabx/test/mathprmt.mf
(/home/<name>/Document/Temp/tex_program/mathabx/test/mathbase.mf)) [62] )
Font metrics written on measure_angle.tfm.
Output written on measure_angle.600gf (1 character, 196 bytes).
Transcript written on measure_angle.log.
mktextfm: /home/<name>/Document/Temp/tex_program/mathabx/test/measure_angle.tfm: successfully generated.
(/usr/share/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def) (./test.aux)
[1{/var/lib/texmf/fonts/map/pdftex/updmap/pdftex.map}] (./test.aux) ) <./measur
e_angle.600pk></usr/share/texmf-dist/fonts/type1/public/amsfonts/cm/cmr10.pfb><
/usr/share/texmf-dist/fonts/type1/public/amsfonts/cm/cmsy7.pfb>
Output written on test.pdf (1 page, 23647 bytes).
Transcript written on test.log.
第二次的编译日志大概长这样:
This is pdfTeX, Version 3.141592653-2.6-1.40.27 (TeX Live 2026/dev/Arch Linux) (preloaded format=pdflatex)
restricted \write18 enabled.
entering extended mode
(./test.tex
LaTeX2e <2024-11-01> patch level 2
L3 programming layer <2025-01-18>
(/usr/share/texmf-dist/tex/latex/base/article.cls
Document Class: article 2024/06/29 v1.4n Standard LaTeX document class
(/usr/share/texmf-dist/tex/latex/base/size10.clo))
(/usr/share/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def) (./test.aux)
[1{/var/lib/texmf/fonts/map/pdftex/updmap/pdftex.map}] (./test.aux) )</usr/shar
e/texmf-dist/fonts/type1/public/amsfonts/cm/cmmi10.pfb></usr/share/texmf-dist/f
onts/type1/public/amsfonts/cm/cmr10.pfb></usr/share/texmf-dist/fonts/type1/publ
ic/amsfonts/cm/cmsy7.pfb>
Output written on test.pdf (1 page, 31385 bytes).
Transcript written on test.log.
编译结果如下:
但是上面的符号在 pdf 里面看起来是比较奇怪的(但是它在纸张上的打印效果是很棒的), 因为它是点阵字体,想要它看起来光滑一点, 没有毛边,那么就需要去自己去修改
pdftex.map
文件, 如果你是用的是 pdfTeX
引擎xdvipdfm
的配置文件, 如果你使用的是 XeTeX
引擎.上面其实还有一个问题 -- \measureangle
不能嵌套在公式环境中, 下次解决.
所以这次就写到这里了, 待续 ...
猴!谢谢花老师!
对于
unicode-math
的方法,如果不能显式知道mathabx
的.otf
字体文件名,或者mathabx
本身就是个以type1
字体宏包的形式存在的字体,是不是就不能用range
的方法来偷呢?@u70550 这个链接的回答也有说
@u38442 指的是: https://tex.stackexchange.com/a/324207/322482?
在下面的评论中:
基于
unicode-math
感觉要混搭是不行的...另一个偷
\widecheck
的例子:https://tex.stackexchange.com/a/575581/322482