经管之家App
让优质教育人人可得
立即打开
全部版块
我的主页
›
论坛
›
计量经济学与统计论坛 五区
›
计量经济学与统计软件
›
LATEX论坛
LaTeX 笔记:NFSS
楼主
oliyiyi
1897
2
收藏
2016-06-19
由 latexstudio
[url=][/url]
通过
LaTeX 工作室
[url=][/url]
零、
我就不写成《LaTeX 笔记(一):NFSS 那点事儿》了,省得你们指望还有二……
本文比较靠近 TeXnique 这个主题。想理解本文的内容,至少也得读一下 TeXbook 或者 TeX by topic 之类的。
一、
NFSS 框架是 LaTeX2e 的核心内容,占了 LaTeX2e 源码的 30% 左右的篇幅。如果你不理解它的重要性,还有一个数据:在完全安装的 TeX Live 发行版中,各类字体宏包编写的字体定义文件 (*.fd) 有 3000+。有了 NFSS,大家才能快乐地使用 \bfseries \itshape 等命令切换字体,随心所欲不逾矩了。
那么没有 NFSS 的情况下怎么切换字体呢?如果你像第 0 条里面说的,读过了两本书之一,那么你就知道是这么来的:
% 以 txfonts 宏包的字体 txr 为例 \font\txrm=txr at 12pt \txrm Hello, \TeX\ and its fonts!需要定义一个控制序列(命令)为字体,然后在切换字体的时候用一下。plain TeX 已经定义了一些,如 \bf \it \tt 之类。问题在于,\bf 是直立的粗体,\it 是普通字重的意大利斜体,如果你想要粗斜体,这个字体跟它俩一毛钱关系都没有,必须你自己重新定义个诸如 \bfit 之类的字体命令才行。
就连不同字号的字体,都需要重新定义
。
那么话说回来,其实 \bfseries \itshape 和 \mdseries \itshape 、\bfseries \upshape 等命令给出的字体也全都不一样啊,这怎么搞的?往下看。
<!– 往下看之前建议仔细看看 TeX 发行版里两篇重要的文档 encguide 和 fntguide。–>
<!– 什么,你看完了?–>
<!– 我也不知道你真看完了还是假看完了,好吧,继续 –>
二、
上面让看的两篇文档,介绍了 NFSS 重要的属性——坐标。一个字体有 encoding / family / series / shape 和字号这五个坐标,比如默认字体,10pt 的 Computer Modern Roman (cmr10),在 NFSS 的坐标是 OT1/cmr/m/n/10。这里就不铺开讲了,需要你真的看完那两篇文档。
哦,你似乎在哪儿见到过这么一串写法?对了,在 Overfull \hbox 等信息里满都是这种写法。好了,是时候告诉你真相了:在调用这个字体前,实际上就有这么个定义:
\global\expandafter\font\csname OT1/cmr/m/n/10\endcsname=cmr10也就是说,真实的字体命令,是由这些坐标拼起来构建的。不同的坐标会构造出来不同的字体,你每切换一次坐标,很可能就要生成一个新的字体命令。
三、
真的就是把字体坐标拼起来这么简单?当然不止,LaTeX 需要额外的信息找到上面代码里等号后面要赋值的字体名。把坐标与字体名称建立映射的东西,就是每个字体宏包必不可少的 .fd 文件。这个放到后面穿插着说。
四、
现在要提到 NFSS 里的一个比较核心的命令——\selectfont。在 \bfseries \itshape 或者 \small \large 等的定义里都有它。你光用 \fontseries{bx} 或者 \fontsize{10}{12} 改坐标还起不到改字体的作用,它只是把坐标信息存到了一些内部宏,如 \f@encoding \f@series 等。\selectfont 才是改变字体的实际操作。
那么 \selectfont 主要干了些啥呢?
\DeclareRobustCommand\selectfont {% \ifx\f@linespread\baselinestretch \else \set@fontsize\baselinestretch\f@size\f@baselineskip \fi \xdef\font@name{% \csname\curr@fontshape/\f@size\endcsname}% \pickup@font \font@name \size@update \enc@update }定义里,前两行先不细看,它的作用是处理修改行距的两个命令 \linespread{***} 和 \renewcommand {\baselinestretch}{***} 可能导致的冲突;
第3-4行就是定义出来所谓的 \OT1/cmr/m/n/10 了,这里定义了一个全局的 \font@name,后面很多地方用得着,另外一个重要的内部宏是 \curr@fontshape,它储存着前四个坐标。
第6行则是使用这个 \OT1/cmr/m/n/10 改变字体了;第7行起到的作用是更新 \baselineskip 等一系列工作;第8行是改了 encoding 之后的一些处理。
重点看第5行:
\def\pickup@font{% \expandafter \ifx \font@name \relax \define@newfont \fi}意思不难,如果 \OT1/cmr/m/n/10 已经定义过,拿来现成用就好,否则需要定义新字体了。接下来看:
\def\define@newfont{% \begingroup \let\typeout\@font@info \escapechar\m@ne \expandafter\expandafter\expandafter \split@name\expandafter\string\font@name\@nil \try@load@fontshape % try always \expandafter\ifx \csname\curr@fontshape\endcsname \relax \wrong@fontshape\else \extract@font\fi \endgroup}group 之内,第一行影响到向终端输出的信息;第2-4行是对 \font@name 内容的一个拆包,把它里头的字体坐标存进 \f@encoding \f@seris 等。为什么不直接用那几个缓存的结果呢,不得而知,可能有考虑 \font@name 本身被动过手脚,跟缓存的结果不一致的情况。
后面的一个关键宏是 \try@load@fontshape:
\def\try@load@fontshape{% \expandafter \ifx\csname \f@encoding+\f@family\endcsname\relax \@font@info{Try loading font information for \f@encoding+\f@family}% \global\expandafter\let \csname\f@encoding+\f@family\endcsname\@empty \nfss@catcodes \let\nfss@catcodes\relax \edef\reserved@a{% \lowercase{% \noexpand\InputIfFileExists{\f@encoding\
f@family.fd
}}}% \reserved@a\relax {\@input@{\f@encoding\
f@family.fd
}}% \fi}我们可以看到,这个宏起到的作用就是载入 .fd 字体定义文件了。在此解释两个宏:
\csname \f@encoding+\f@family\endcsname,形如 \OT1+cmr。它的定义标志着 .fd 文件被载入。它是 .fd 文件里 \DeclareFontEncoding 命令定义出来的。
\csname \curr@fontshape\endcsname,形如 \OT1/cmr/m/n,它的定义标志着 .fd 文件被载入,并且前四个坐标被 .fd 文件里的 \DeclareFontFamily 命令定义过,这样就可以拿来把最后一块拼图,也就是字号信息拼上。
那么好了,往下走,如果 .fd 文件载入了,各条 \DeclareFontFamily 也过了一遍,仍然找不到对应的字体怎么办?这就表明,字体包里可能没有定义你要的坐标,这时就要进行回退(fallback),这个工作由 \wrong@fontshape 完成。每个 encoding 的定义文件如 t1enc.def 里,都会用 \DeclareFontSubstitution 命令给出用来回退的三个坐标(OT1 的是在 LaTeX2e 内核里给的)。
\wrong@fontshape 的代码就不继续贴了,举个例子,如果我弄了一个错误的坐标出来, \OT1/cmr/xxx/xxx,LaTeX 载入了 ot1cmr.fd 发现没有这个坐标,它就回退到 \OT1/cmr/xxx/n,还找不到,就回退到 \OT1/cmr/m/n。如果进行了回退,你会看到 “Font shape *** undefined, use *** instead” 的提示。
如果找到了前四个坐标的信息,或者回退到了合适的前四个坐标,接下来就要通过字号这个坐标去找字体(TFM)了。这个功能由 \extract@font 完成,它调用了 \get@external@font 去解析 \DeclareFontShape 命令里各种复杂的字号和 tfm 映射关系的定义式,后者内部用了 \try@size@range 完成实际的解析,用 \try@size@substitution 完成字号的 fallback。
五、
啰啰嗦嗦地写完了,不知道有多少人有足够的耐心看到这儿,以及为了看懂它去看更多的书。LaTeX 对字体的这套解决方案也许不是最优的,不过恐怕是无法替代的,不然那乌泱乌泱的字体宏包都得改。
嗯我不是说了有 30% 的代码是 NFSS 嘛?事实上今天讨论到的这部分连 5% 都占不到。其余的大头是被 encoding 和数学字体占了。encoding 的部分,要解决的是不同字体编码下的一些命令和重音的实现,比如 OT1 下的 \”o 是两个字符拼起来的,而 T1 则可以找到单个的字符。数学字体就不在这里说了,要说起来肯定要另开一帖。
\endinput
作者:Louis Stuart
链接:
https://zhuanlan.zhihu.com/p/21339128
转载:
LaTeX工作室
»
LaTeX技巧850:LaTeX 笔记:NFSS 那点事儿
扫码加我 拉你入群
请注明:姓名-公司-职位
以便审核进群资格,未注明则拒绝
全部回复
沙发
2009116226
2016-7-3 13:17:48
楼主,tex系列的哪个产品可以免费使用呀?还是说全都是要交钱的?
扫码加我 拉你入群
请注明:姓名-公司-职位
以便审核进群资格,未注明则拒绝
藤椅
oliyiyi
2016-7-3 20:29:55
2009116226 发表于 2016-7-3 13:17
楼主,tex系列的哪个产品可以免费使用呀?还是说全都是要交钱的?
tex基本上全是免费的
扫码加我 拉你入群
请注明:姓名-公司-职位
以便审核进群资格,未注明则拒绝
相关推荐
LaTeX圣经
LATEX排版
在哪里下载个靠谱的latex软件啊
LaTeX表格求助
latex的感悟
【latex】关于图片浮动
LaTeX中的宽度
vim的LaTeX插件-LaTeX Box
LaTEX 的读音和书写
Latex 问题求助
栏目导航
LATEX论坛
行为经济学与实验经济学
市场行情分析
学术道德监督
站务与外事
经管文库(原现金交易版)
热门文章
CDA 数据分析师:特征处理核心指南
电子行业深度报告:量子深潜-计算篇:从比特 ...
制造业全要素生产率(2000-2024年)
从知识图谱到认知智能
中物联:全球供应链发展趋势蓝皮书(2025)
企业降低融资成本白皮书(2025)
2025年最值得关注的公司-放射配体创新者开启 ...
中国能源统计年鉴1986-2023
签个到
安永2025年全球财务主管DNA调查(英)
推荐文章
AI狂潮席卷学术圈,不会编程也能打造专属智 ...
10月重磅来袭|《打造Coze/Dify专属学术智能 ...
最快1年拿证,学费不足5W!热门美国人工智能 ...
关于如何利用文献的若干建议
关于学术研究和论文发表的一些建议
关于科研中如何学习基础知识的一些建议 (一 ...
一个自编的经济学建模小案例 --写给授课本科 ...
AI智能体赋能教学改革: 全国AI教育教学应用 ...
2025中国AIoT产业全景图谱报告-406页
关于文献求助的一些建议
说点什么
分享
微信
QQ空间
QQ
微博
扫码加好友,拉您进群
各岗位、行业、专业交流群