我想知道是否有办法暂时改变数学字体,类似于在文本模式下执行的方式:
{\ttfamily Some text in typewriter font.}
有没有办法可以做到$\ttfamily a + b = c$
呢?
我知道我可以做到$\mathtt{a + b = c}$
,就像我可以做到的那样\texttt{text}
,但有时另一种方式会产生更干净的代码。
请注意,我并不是在寻找类似的东西,$\texttt{monospace} \textit{ in math.}$
我希望能够编写复杂的公式而不必在每个单词中都提及字体,就像我所做的那样,例如$\Sigma_{\mathtt{i} = 1}^{\mathtt{n}}$
。
答案1
如果您只需要使用等宽字母作为变量:
\documentclass{article}
\usepackage{xpatch}
\DeclareMathVersion{ttmath}
\SetSymbolFont{letters}{ttmath}{OT1}{\ttdefault}{m}{n}
\xapptocmd{\ttfamily}{\mathversion{ttmath}}{}{}
\begin{document}
This is normal math: $a+b=c$
{\ttfamily This is tt math: $a+b=c$}
\texttt{This is tt math: $a+b=c$}
\end{document}
为了获得更完整的设置,您可以使用具体字体来补充等宽文本字体(但是,它们仅以位图格式可用)。
\documentclass{article}
\usepackage{xpatch}
\DeclareMathVersion{ttmath}
\DeclareSymbolFont{latinletters}{OT1}{\ttdefault}{m}{n}
%\SetSymbolFont{latinletters}{ttmath}{OT1}{\ttdefault}{m}{n}
\SetSymbolFont{letters}{ttmath}{OML}{ccm}{m}{it}
\SetSymbolFont{symbols}{ttmath}{OMS}{ccsy}{m}{n}
\SetSymbolFont{largesymbols}{ttmath}{OMX}{ccex}{m}{n}
\newcommand{\changeletters}{%
\count255=`a
\advance\count255 -1
\loop\ifnum\count255<`z
\advance\count255 1
\mathcode\count255=\numexpr\number\symlatinletters*256+\count255\relax
\repeat
\count255=`0
\advance\count255 -1
\loop\ifnum\count255<`9
\advance\count255 1
\mathcode\count255=\numexpr\number\symlatinletters*256+\count255\relax
\repeat
}
\xapptocmd{\ttfamily}{\mathversion{ttmath}\changeletters}{}{}
\begin{document}
This is normal math: $a+b=\alpha$
{\ttfamily This is tt math: $a+b=\alpha$}
\texttt{This is tt math: $a+b=\alpha$}
\bigskip
$\displaystyle\frac{1}{2\pi i}\oint \frac{1}{z}\,dz$
{\ttfamily$\displaystyle\frac{1}{2\pi i}\oint \frac{1}{z}\,dz$}
\end{document}
答案2
您可以使用旧的字体命令\tt
。
警告:不建议使用这些旧的字体命令(
\rm
、\tt
等等),尤其是因为一些文档类明确禁止使用它们(KOMA、memoir
)。
\documentclass{article}
\begin{document}
$\tt a + b = c$
\end{document}
答案3
我很遗憾地说,@egreg 似乎误解了我的批评,而我的批评本意是建设性的(另一方面,我必须承认,我喜欢通过指出他答案中的小缺陷来取笑他,这种情况很少见)。我特别指的是一条评论我在其中指出,他忘记将新的\mathcode
拉丁字母 s 分配给第 7 类(\mathalpha
NFSS 用语中为 )。我认为这是一个缺陷的原因在于,它抑制了使用明确指定的数学字母表来表示这些字母的可能性,如以下示例代码所示:
\documentclass{article}
\usepackage{xpatch}
% \DeclareMathVersion{ttmath}
\DeclareSymbolFont{latinletters}{OT1}{\ttdefault}{m}{n}
% % \SetSymbolFont{latinletters}{ttmath}{OT1}{\ttdefault}{m}{n}
% \SetSymbolFont{letters}{ttmath}{OML}{ccm}{m}{it}
% \SetSymbolFont{symbols}{ttmath}{OMS}{ccsy}{m}{n}
% \SetSymbolFont{largesymbols}{ttmath}{OMX}{ccex}{m}{n}
\newcommand*{\changeletters}{%
\count255=`a
\advance\count255 -1
\loop\ifnum\count255<`z
\advance\count255 1
\mathcode\count255=\numexpr\number\symlatinletters*256+\count255\relax
\repeat
\count255=`0
\advance\count255 -1
\loop\ifnum\count255<`9
\advance\count255 1
\mathcode\count255=\numexpr\number\symlatinletters*256+\count255\relax
\repeat
}
\xapptocmd{\ttfamily}{%
% \mathversion{ttmath}%
\changeletters
}{}{}
\begin{document}
This is normal math: $a+b+C=\alpha+\mathit{b}+\mathcal{C}$
{\ttfamily This is tt math: $a+b+C=\alpha+\mathit{b}+\mathcal{C}$}
\texttt{This is tt math: $a+b+C=\alpha+\mathit{b}+\mathcal{C}$}
\bigskip
$\displaystyle\frac{1}{2\pi i}\oint \frac{1}{z}\,dz$
{\ttfamily$\displaystyle\frac{1}{2\pi i}\oint \frac{1}{z}\,dz$}
\end{document}
此代码重现了@egreg的第二种解决方案,但有两点不同:
我已经禁用了具体字体,以避免使用这些位图字体(事实上,它们与正在提出的观点无关,而另一方面,它们很乱
$TEXMFVAR/fonts/
);我(尝试)利用数学字母
\mathit
和\mathcal
。
嗯,你可以检查一下,输出是
您会看到,在电传打字机中排版的两个方程式的右侧,字母“b”(小写)不符合字体要求\mathit
(它保留在电传打字机中),而字母“C”(大写,未经过@egreg 的\mathcode
修改)确实更改为\mathcal
字体。请注意,很难说保留使用不同数学字母的能力无关紧要,因为它不仅提供了一种逃避“电传打字机变量”约定的方法,并偶尔获得例如以数学斜体排版的变量,而且还提供了编写诸如 之类的内容z\in\mathbb{C}
。
这个缺陷(实际上只不过是一个小小的疏忽)可以通过对@egreg的代码进行微小的修改来纠正。然而,他已经下降我建议我应用它,同时鼓励我发布自己的答案。由于已经过去了将近两天,他都没有改变主意,所以我现在接受了这种鼓励;不过,我想强调的是,接下来的内容只是对@egreg 的代码进行了微小的修改。
除了纠正“ \mathalpha
class ”问题之外,以下代码与@egreg 的代码在其他几个方面有所不同:
由于上述原因,它不使用具体的字体;如果需要,请取消注释包含双百分号 (
% %
) 的行;它
\mathcode
也将该变化应用于大写字母;\teletypemath
它通过提供必须明确调用的声明,将字母的数学字体的选择与主文本字体的选择“分离” ;它预先计算“类+家族”前缀,而不是在每次迭代时重新计算;
它使用辅助宏将补丁应用于几个范围的字符。
代码:
% My standard header for TeX.SX answers:
\documentclass[a4paper]{article} % To avoid confusion, let us explicitly
% declare the paper format.
\usepackage[T1]{fontenc} % Not always necessary, but recommended.
% End of standard header. What follows pertains to the problem at hand.
\usepackage{amsmath,amsfonts} % compatibility test
\DeclareSymbolFont{latinletters}{\encodingdefault}{\ttdefault}{m}{n}
% % \DeclareMathVersion{teletype}
% % \SetSymbolFont{letters}{teletype}{OML}{ccm}{m}{it}
% % \SetSymbolFont{symbols}{teletype}{OMS}{ccsy}{m}{n}
% % \SetSymbolFont{largesymbols}{teletype}{OMX}{ccex}{m}{n}
\makeatletter
\@ifdefinable\@teletype@class@family{\mathchardef\@teletype@class@family =
\numexpr 28672 +\symlatinletters*\@cclvi \relax} % 28672 = 7*4096
\newcommand*\@changerange[2]{%
\count@ `#1%
\advance \count@ \m@ne
\loop \ifnum \count@<`#2%
\advance \count@ \@ne
\mathcode\count@ \numexpr \@teletype@class@family+\count@ \relax
\repeat
}
\newcommand*{\changeletters}{%
\@changerange az%
\@changerange AZ%
\@changerange 09%
}
% The following declaration avoids wasting an entry in TeX's very limited table
% of math fonts when the "\mathtt" is explicitly used:
\DeclareSymbolFontAlphabet{\mathtt}{latinletters}
\makeatother
\newcommand*{\teletypemath}{%
% % \mathversion{teletype}%
\changeletters
}
\begin{document}
This is normal math: $a+b+C+1=\alpha+\mathit{b}+\mathcal{C}-2$;
and $z\in\mathbb{C}$.
{\teletypemath This is tt math: $a+b+C+1=\alpha+\mathit{b}+\mathcal{C}-2$;
and $z\in\mathbb{C}$.}
\bigskip
$\displaystyle\frac{1}{2\pi i}\oint \frac{1}{z}\,dz$
{\teletypemath$\displaystyle\frac{1}{2\pi i}\oint \frac{1}{z}\,dz$}
\bigskip
Explicit use of \verb|\mathtt|: $x\neq\mathtt{x}$.
\end{document}
输出:
如您所见,现在对不同数学字母的请求已得到正确满足。
它是如何工作的(或者为什么不工作)
自从重新定义数学家族以来已被证明可能造成混乱,我认为有必要补充几句解释和建议。
首先,我们来分析一下@egreg的原始解决方案:
\documentclass{article}
\usepackage{xpatch}
\DeclareMathVersion{ttmath}
\SetSymbolFont{letters}{ttmath}{OT1}{\ttdefault}{m}{n}
\xapptocmd{\ttfamily}{\mathversion{ttmath}}{}{}
\begin{document}
This is normal math: $a+b=c$
{\ttfamily This is tt math: $a+b=c$}
\texttt{This is tt math: $a+b=c$}
\end{document}
首先,
\DeclareMathVersion{ttmath}
声明一个新的数学版本,类似于bold
数学版本,称为ttmath
;然后是
\SetSymbolFont{letters}{ttmath}{OT1}{\ttdefault}{m}{n}
告诉 LaTeX,在数学版本letters
中排版数学时,要将用于绘制字母和数字的字体设置为由编码、与等宽字体的默认系列相对应的系列(;但请注意,实际上不能保证该系列通过编码进行编码)、中等重量()和正常(即直立)形状( )ttmath
标识的组合。OT1
\ttdefault
OT1
m
n
为什么这个设置会导致问题?不幸的是,除了字母和数字之外,还有其他符号是从字体中提取的letters
;例如,LaTeX 内核包含声明
\DeclareMathSymbol{\alpha}{\mathord}{letters}{"0B}
它将\alpha
符号定义为在数学字母表命令中使用时不会改变的普通符号\mathcal
(实际上,第二个参数是\mathord
;如果符号必须遵循数学字母表的变化,\mathalpha
则会在这里使用),并且位于 字体"0B
的插槽中。现在,这依赖于字体通过所谓的编码进行编码的letters
事实(其中插槽 实际上对应于小写希腊字母“α”),就像在正常设置中一样,将字体分配给系列;但如果我们将其更改为 OT1 编码的字体,如,(*),该命令将产生在新的编码插槽中找到的任何符号 。letters
OML
"0B
letters
cmmi
cmtt
\alpha
"0B
我的解决方案(让我再重复一次,除了“class 7/ \mathalpha
”问题之外,实际上与@egreg的第二个解决方案一致)通过引入一个全新的系列(称为)解决了这个问题,latinletters
该系列链接到默认的等宽字体(在默认编码中),然后执行与以下一系列声明等效的操作,
\DeclareMathSymbol{a}{\mathalpha}{latinletters}{`a}
...
\DeclareMathSymbol{z}{\mathalpha}{latinletters}{`z}
\DeclareMathSymbol{A}{\mathalpha}{latinletters}{`A}
...
\DeclareMathSymbol{Z}{\mathalpha}{latinletters}{`Z}
\DeclareMathSymbol{0}{\mathalpha}{latinletters}{`0}
...
\DeclareMathSymbol{9}{\mathalpha}{latinletters}{`9}
指示 LaTeX 从新字体中获取字母(大写和小写)和数字,而不会影响从letters
字体中提取的其他符号。在我们的代码中,上述声明的作用由命令扮演\changeletters
,这些命令利用数学字体选择在低级实现的知识,通过循环迭代实现相同的结果。
(*) 实际上,该cmtt
系列遵循 Knuth 决定用于等宽字体的编码的特定变体OT1
。严格来说,不存在唯一的“OT1
编码”,只有其变体。