让数学表现得像 \mathit

让数学表现得像 \mathit

我经常使用描述性名称来表示谓词、术语和函数。但是,由于缺乏字距调整,它们看起来不太好看。

例如

$offer = surface \times force(now)$

呈现为

在此处输入图片描述

因此为了避免使用它\mathit

$\mathit{offer = surface \times force(now)}$

渲染结果为

在此处输入图片描述

可以说,它看起来更好,并且更容易阅读。

为了避免输入\mathitm,我定义了

\DeclareSymbolFont{italics}{\encodingdefault}{\rmdefault}{m}{it}

\DeclareMathSymbol{a}{\mathalpha}{italics}{`a}
...
\DeclareMathSymbol{z}{\mathalpha}{italics}{`z}
\DeclareMathSymbol{A}{\mathalpha}{italics}{`A}
...
\DeclareMathSymbol{z}{\mathalpha}{italics}{`Z}

问题)

这是做这件事的“正确”方法吗?

这种方法有什么缺点/不足?(我可以用来\mathnormal回到标准行为,并且我知道,例如,对于f和的乘积,i我必须使用f{}i它来防止连字)。

答案1

这取决于几个因素。如果你的数学公式全部构建得像那样,那么您可能有理由改变字母的数学代码,尽管我建议您不要这样做。

更喜欢语义标记:多字母标识符表示变量或函数;定义两个命令,例如\var\func,然后键入公式

\[
\var{offer}=\var{surface}\cdot\func{force}(\var{now})
\]

(请不要使用\times!)。现在您可以自由选择所需的变量和函数的任何表示形式,例如

\newcommand{\var}[1]{\mathit{#1}}
\newcommand{\func}[1]{\mathit{#1}}

当你的主管或期刊编辑告诉你“很好,但函数应该用直立字母排版”时,你会回答“等一下”,将第二行改为

\newcommand{\func}[1]{\mathrm{#1}}

并重新编译。数学代码的改变会一样吗?

打字会更困难吗?我不这么认为,特别是如果你是一位能够定义一些简写方式的 Emacs 专家。


更改所有字母的数学代码非常简单,因为代码是重复的。不要忘记重新声明,\mathit以免\DeclareSymbolFontAlphabet浪费数学家族。

\DeclareSymbolFont{italics}{\encodingdefault}{\rmdefault}{m}{it}
\DeclareSymbolFontAlphabet{\mathit}{italics}

\makeatletter
\count@=`a \advance\count@\m@ne
\@whilenum{\count@<`z}\do{%
  \advance\count@\@ne
  \begingroup\lccode`A=\count@
  \lowercase{\endgroup
    \DeclareMathSymbol{A}{\mathalpha}{italics}{`A}%
  }%
}
\count@=`A \advance\count@\m@ne
\@whilenum{\count@<`Z}\do{%
  \advance\count@\@ne
  \begingroup\lccode`A=\count@
  \lowercase{\endgroup
    \DeclareMathSymbol{A}{\mathalpha}{italics}{`A}%
  }%
}
\makeatother

循环可以简化为expl3

\usepackage{expl3}

\DeclareSymbolFont{italics}{\encodingdefault}{\rmdefault}{m}{it}
\DeclareSymbolFontAlphabet{\mathit}{italics}

\ExplSyntaxOn
\int_step_inline:nnnn { `A } { 1 } { `Z }
 {
  \group_begin:
  \char_set_lccode:nn { `A } { #1 }
  \char_set_lccode:nn { `B } { #1 + 32 }
  \tl_to_lowercase:n
   {
    \group_end:
    \DeclareMathSymbol{A}{\mathalpha}{italics}{`A}
    \DeclareMathSymbol{B}{\mathalpha}{italics}{`B}
   }
 }
\ExplSyntaxOff

需要使用该技巧的主要问题\lowercase是,这是知道字符代码的情况下生成字符标记的唯一方法。

使用最新版本expl3(2015-09-09 之后发布),可以\lowercase使用 来避免该技巧\char_generate:nn

\documentclass{article}
\usepackage{expl3}

\DeclareSymbolFont{italics}{\encodingdefault}{\rmdefault}{m}{it}
\DeclareSymbolFontAlphabet{\mathit}{italics}

\ExplSyntaxOn
\int_step_inline:nnnn { `A } { 1 } { `Z }
 {
  \exp_args:Nf \DeclareMathSymbol{\char_generate:nn{#1}{11}}{\mathalpha}{italics}{#1}
 }
\int_step_inline:nnnn { `a } { 1 } { `z }
 {
  \exp_args:Nf \DeclareMathSymbol{\char_generate:nn{#1}{11}}{\mathalpha}{italics}{#1}
 }
\ExplSyntaxOff

\begin{document}

\[
offer=surface\cdot force(now)
\]

\end{document}

答案2

另一个答案和评论中提到了为什么在数学模式下全局重新分配字母不是一个好主意。但如果你真的需要这个,那么你可以这样做:

\everymath{\it}\everydisplay{\it}

在文档开头。如果您需要保留罗马数字,则可以设置:

\def\mathcodes#1{\mathcode`#1=\numexpr\mathcode`#1-"7000\relax 
   \ifx#10\else\expandafter\mathcodes\fi}
\mathcodes1234567890

例如,这意味着:

\documentclass[12pt]{article}
\everymath{\it}\everydisplay{\it}
\def\mathcodes#1{\mathcode`#1=\numexpr\mathcode`#1-"7000\relax 
   \ifx#10\else\expandafter\mathcodes\fi}
\mathcodes1234567890
\begin{document}

$offer = surface \times force(now) + 1$

\end{document}

如果您使用的是纯 TeX,则可以使用或\itvariables之后提供的命令。此命令将所有字母的数学代码设置为文本斜体数学系列(默认)。例如:\input ams-math\input opmac

\input ams-math \itvariables

$offer = surface \times force(now) + 2$

\bye

答案3

我同意 egreg 的观点,最好让标记与此处的含义相匹配,并单独标记每个标识符。TeX 中的数学标记以及默认字体的设计理念是相邻字母是单独的变量,通常带有隐含的乘法或连接运算符。

然而,如果您不相信并且想要默认使用文本斜体字体,则无需为此分配新的数学字体,它已经设置为可供使用,\mathit您只需要使其摆脱隐含的分组即可\mathit

\documentclass{article}


\let\v\mathit
\begin{document}


$\mathit{offer = surface \times force(now)}$



$\v{offer} = \v{surface} \times \v{force}(\v{now})$%%%USE THIS

\everymath{\mathit{\xdef\tmp{\fam\the\fam\relax}}\tmp}


$offer = surface \times force(now)$

\end{document}

相关内容