它是如何工作的(或者为什么不工作)

它是如何工作的(或者为什么不工作)

我想知道是否有办法暂时改变数学字体,类似于在文本模式下执行的方式:

{\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 类(\mathalphaNFSS 用语中为 )。我认为这是一个缺陷的原因在于,它抑制了使用明确指定的数学字母表来表示这些字母的可能性,如以下示例代码所示:

\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

嗯,你可以检查一下,输出是

@egreg 解决方案的输出

您会看到,在电传打字机中排版的两个方程式的右侧,字母“b”(小写)不符合字体要求\mathit(它保留在电传打字机中),而字母“C”(大写,未经过@egreg 的\mathcode修改)确实更改为\mathcal字体。请注意,很难说保留使用不同数学字母的能力无关紧要,因为它不仅提供了一种逃避“电传打字机变量”约定的方法,并偶尔获得例如以数学斜体排版的变量,而且还提供了编写诸如 之类的内容z\in\mathbb{C}

这个缺陷(实际上只不过是一个小小的疏忽)可以通过对@egreg的代码进行微小的修改来纠正。然而,他已经下降我建议我应用它,同时鼓励我发布自己的答案。由于已经过去了将近两天,他都没有改变主意,所以我现在接受了这种鼓励;不过,我想强调的是,接下来的内容只是对@egreg 的代码进行了微小的修改。

除了纠正“ \mathalphaclass ”问题之外,以下代码与@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\ttdefaultOT1mn

为什么这个设置会导致问题?不幸的是,除了字母和数字之外,还有其他符号是从字体中提取的letters;例如,LaTeX 内核包含声明

\DeclareMathSymbol{\alpha}{\mathord}{letters}{"0B}

它将\alpha符号定义为在数学字母表命令中使用时不会改变的普通符号\mathcal(实际上,第二个参数是\mathord;如果符号必须遵循数学字母表的变化,\mathalpha则会在这里使用),并且位于 字体"0B的插槽中。现在,这依赖于字体通过所谓的编码进行编码的letters事实(其中插槽 实际上对应于小写希腊字母“α”),就像在正常设置中一样,将字体分配给系列;但如果我们将其更改为 OT1 编码的字体,如,(*),该命令将产生在新的编码插槽中找到的任何符号 。lettersOML"0Bletterscmmicmtt\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 编码”,只有其变体。

答案4

您可以使用包,它要求使用或unicode-math来编译文档。XeLuaLaTeX

以下是代码:

\documentclass{article}

\usepackage{unicode-math}%Load the package

\setmathfont{TeX Gyre Schola Math}%Set the font you want to use

\begin{document}

    $a+b=c$%regular

    $\symtt{a+b=c}$%some symbols support typewriter series

\end{document}

结果如下:

在此处输入图片描述

相关内容