考虑一下这个MWE:
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[T2A, T1]{fontenc}
\usepackage{amsmath}
\usepackage{lmodern}
\usepackage{siunitx}
\usepackage{mathpazo}
\usepackage{trace}
% https://tex.stackexchange.com/questions/19255/using-declaremathversion
% note: mathpazo.sty, lmodern.sty overrides normal, bold!
%%% New math versions
\DeclareMathVersion{lmnormal}
\DeclareMathVersion{lmbold}
\DeclareMathVersion{mpazonormal}
\DeclareMathVersion{mpazobold}
\newcommand\lmmath{\mathversion{lmnormal}}
\newcommand\lmboldmath{\mathversion{lmbold}}
\newcommand\mpmath{\mathversion{mpazonormal}}
\newcommand\mpboldmath{\mathversion{mpazobold}}
%%% Math symbol fonts
% lmodern.sty
\SetSymbolFont{operators} {lmnormal}{OT1}{lmr} {m}{n}
\SetSymbolFont{letters} {lmnormal}{OML}{lmm} {m}{it}
\SetSymbolFont{symbols} {lmnormal}{OMS}{lmsy}{m}{n}
\SetSymbolFont{largesymbols}{lmnormal}{OMX}{lmex}{m}{n}
\SetSymbolFont{operators} {lmbold} {OT1}{lmr} {bx}{n}
\SetSymbolFont{letters} {lmbold} {OML}{lmm} {b}{it}
\SetSymbolFont{symbols} {lmbold} {OMS}{lmsy}{b}{n}
\SetSymbolFont{largesymbols}{lmbold} {OMX}{lmex}{m}{n}
% add for \SI?
\SetSymbolFont{upright} {lmnormal}{OT1}{lmr} {m}{n}
% mathpazo.sty
\SetSymbolFont{operators} {mpazonormal} {OT1}{ppl}{m}{n}
\SetSymbolFont{upright} {mpazonormal} {OT1}{zplm}{m}{n}
\SetSymbolFont{letters} {mpazonormal} {OML}{zplm}{m}{it}
\SetSymbolFont{symbols} {mpazonormal} {OMS}{zplm}{m}{n}
\SetSymbolFont{largesymbols}{mpazonormal} {OMX}{zplm}{m}{n}
\SetSymbolFont{operators} {mpazobold} {OT1}{ppl}{b}{n}
\SetSymbolFont{upright} {mpazobold} {OT1}{zplm}{b}{n}
\SetSymbolFont{letters} {mpazobold} {OML}{zplm}{b}{it}
\SetSymbolFont{symbols} {mpazobold} {OMS}{zplm}{b}{n}
\SetSymbolFont{largesymbols}{mpazobold}{OMX}{zplm}{m}{n}
%%% Math alphabets, at most 16 families
% lmodern.sty
\SetMathAlphabet{\mathbf}{lmnormal}{OT1}{lmr}{bx}{n}
\SetMathAlphabet{\mathsf}{lmnormal}{OT1}{lmss}{m}{n}
\SetMathAlphabet{\mathit}{lmnormal}{OT1}{lmr}{m}{it}
\SetMathAlphabet{\mathtt}{lmnormal}{OT1}{lmtt}{m}{n}
\SetMathAlphabet{\mathbf}{lmbold} {OT1}{lmr}{bx}{n}
\SetMathAlphabet{\mathsf}{lmbold} {OT1}{lmss}{bx}{n}
\SetMathAlphabet{\mathit}{lmbold} {OT1}{lmr}{bx}{it}
\SetMathAlphabet{\mathtt}{lmbold} {OT1}{lmtt}{m}{n}
% mathpazo.sty
\SetMathAlphabet{\mathit}{mpazonormal} {OT1}{ppl}{m}{it}
\SetMathAlphabet{\mathit}{mpazobold} {OT1}{ppl}{b}{it}
\SetMathAlphabet{\mathbf}{mpazonormal} {OT1}{zplm}{b}{n}
\SetMathAlphabet{\mathbold}{mpazonormal} {OML}{zplm}{b}{it}
% https://tex.stackexchange.com/questions/35287/sans-serif-font-with-siunitx
% \SI % "By default, all text is typeset in the current upright, serif math font."
% \sisetup{detect-all} %
\begin{document}
\fontfamily{lmr}\selectfont% change text font to lmodern
\renewcommand{\rmdefault}{lmr}%
% \sisetup{detect-all}
\makeatletter
This is Mathpazo font \math@version. $a^2 + b^2 = c^2; \mathrm{ms}$. $20$ ms, \fbox{\SI{20}{\meter\per\second}}
\mpmath
\def\defaultscriptratio{.76}
\def\defaultscriptscriptratio{.6}
% \sisetup{detect-all}
This is Mathpazo font \math@version. $a^2 + b^2 = c^2; \mathrm{ms}$. $20$ ms, \fbox{\SI{20}{\meter\per\second}}
\lmmath
\def\defaultscriptratio{.7}
\def\defaultscriptscriptratio{.5}
% \sisetup{detect-all}
This is LModern font \math@version. $a^2 + b^2 = c^2; \mathrm{ms}$. $20$ ms, %
% \traceon%
\fbox{\SI{20}{\meter\per\second}}%
% \traceoff
\makeatother
\end{document}
输出内容如下pdflatex
:
前两个\SI
使用 Mathpazo 排版,符合预期(第一次是因为数学设置“泄漏”,因为mathpazo
最后加载;第二次是因为明确请求了\mpmath
-> \mathversion{mpazonormal}
)。但是一旦\mathversion{lmnormal}
请求,它就不会对\SI
-产生影响甚至如果\mathrm
方程中的相当于数学模式下的 \mathup 直立文本) 被确认(因为它是用lmodern
字体排版的)。
如果我启用所有\sisetup{detect-all}
,则输出如下:
现在所有的\SI
都已排版lmodern
- 即使我期望前两个用mathpazo
?!排版。
那么我需要做什么,当我切换数学字体时,命令也会\SI
用相同的字体排版?
答案1
好吧,经过大量的\trace
思考,我想我已经解决了它:
...但我对这个解决方案感到很困惑,因此如果能给出更博学的答案我将不胜感激。
首先,在跟踪中注意到这一点:
\__siunitx_font_weight: ->\unboldmath \mdseries
\unboldmath ->\@nomath \unboldmath \mathversion {normal}
因此,无论\mathversion
您选择哪一个 -siunitx
都会切换到normal
,显然每次执行\SI
命令时都会切换到。
因此,每次更改字体时,我们基本上都需要\SetSymbolFont
重新进行数学版本;不幸的是,该命令是- 因此大多数代码实际上是一种 可以在任何地方工作的黑客提供的代码。normal
\@onlypreamble
\ReSetSymbolFont
最令人费解的是,执行\ReSetSymbolFont{upright} {normal}
不会产生任何效果 - 而实际上似乎起作用的是\ReSetSymbolFont{operators} {normal}
。我真的说不出来 - 为什么operators
(显然只有该字体) 会对 产生影响\SI
?
无论如何,这里是代码:
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[T2A, T1]{fontenc}
\usepackage{amsmath}
\usepackage{lmodern}
\usepackage{siunitx}
\usepackage{mathpazo}
\usepackage{etoolbox}% patchcmd
\usepackage{trace}
% http://tex.stackexchange.com/questions/19255/using-declaremathversion
% note: mathpazo.sty, lmodern.sty overrides normal, bold!
%%% New math versions
\DeclareMathVersion{lmnormal}
\DeclareMathVersion{lmbold}
\DeclareMathVersion{mpazonormal}
\DeclareMathVersion{mpazobold}
\newcommand\lmmath{\mathversion{lmnormal}}
\newcommand\lmboldmath{\mathversion{lmbold}}
\newcommand\mpmath{\mathversion{mpazonormal}}
\newcommand\mpboldmath{\mathversion{mpazobold}}
%%% Math symbol fonts
% lmodern.sty
\SetSymbolFont{operators} {lmnormal}{OT1}{lmr} {m}{n}
\SetSymbolFont{letters} {lmnormal}{OML}{lmm} {m}{it}
\SetSymbolFont{symbols} {lmnormal}{OMS}{lmsy}{m}{n}
\SetSymbolFont{largesymbols}{lmnormal}{OMX}{lmex}{m}{n}
\SetSymbolFont{operators} {lmbold} {OT1}{lmr} {bx}{n}
\SetSymbolFont{letters} {lmbold} {OML}{lmm} {b}{it}
\SetSymbolFont{symbols} {lmbold} {OMS}{lmsy}{b}{n}
\SetSymbolFont{largesymbols}{lmbold} {OMX}{lmex}{m}{n}
% add for \SI?
\SetSymbolFont{upright} {lmnormal}{OT1}{lmr} {m}{n}
% mathpazo.sty
\SetSymbolFont{operators} {mpazonormal} {OT1}{ppl}{m}{n}
\SetSymbolFont{upright} {mpazonormal} {OT1}{zplm}{m}{n}
\SetSymbolFont{letters} {mpazonormal} {OML}{zplm}{m}{it}
\SetSymbolFont{symbols} {mpazonormal} {OMS}{zplm}{m}{n}
\SetSymbolFont{largesymbols}{mpazonormal} {OMX}{zplm}{m}{n}
\SetSymbolFont{operators} {mpazobold} {OT1}{ppl}{b}{n}
\SetSymbolFont{upright} {mpazobold} {OT1}{zplm}{b}{n}
\SetSymbolFont{letters} {mpazobold} {OML}{zplm}{b}{it}
\SetSymbolFont{symbols} {mpazobold} {OMS}{zplm}{b}{n}
\SetSymbolFont{largesymbols}{mpazobold}{OMX}{zplm}{m}{n}
%%% Math alphabets, at most 16 families
% lmodern.sty
\SetMathAlphabet{\mathbf}{lmnormal}{OT1}{lmr}{bx}{n}
\SetMathAlphabet{\mathsf}{lmnormal}{OT1}{lmss}{m}{n}
\SetMathAlphabet{\mathit}{lmnormal}{OT1}{lmr}{m}{it}
\SetMathAlphabet{\mathtt}{lmnormal}{OT1}{lmtt}{m}{n}
\SetMathAlphabet{\mathbf}{lmbold} {OT1}{lmr}{bx}{n}
\SetMathAlphabet{\mathsf}{lmbold} {OT1}{lmss}{bx}{n}
\SetMathAlphabet{\mathit}{lmbold} {OT1}{lmr}{bx}{it}
\SetMathAlphabet{\mathtt}{lmbold} {OT1}{lmtt}{m}{n}
% mathpazo.sty
\SetMathAlphabet{\mathit}{mpazonormal} {OT1}{ppl}{m}{it}
\SetMathAlphabet{\mathit}{mpazobold} {OT1}{ppl}{b}{it}
\SetMathAlphabet{\mathbf}{mpazonormal} {OT1}{zplm}{b}{n}
\SetMathAlphabet{\mathbold}{mpazonormal} {OML}{zplm}{b}{it}
% http://tex.stackexchange.com/questions/35287/sans-serif-font-with-siunitx
% \SI % "By default, all text is typeset in the current upright, serif math font."
% \sisetup{detect-all} %
% latex.ltx - \SetSymbolFont
\makeatletter
% \cdp@list ->\@latex@error {Can be used only in preamble}\@eha
% \SetSymbolFont@ ->\@latex@error {Can be used only in preamble}\@eha
% \version@list ->\@latex@error {Can be used only in preamble}\@eha
% \group@list ->\@latex@error {Can be used only in preamble}\@eha
% \get@cdp ->\@latex@error {Can be used only in preamble}\@eha
%
% just a \let seems enough for this:
\let\Recdp@list\cdp@list
% no need for this:
% \expandafter\def\expandafter\Recdp@list\expandafter{\cdp@list}%\show\Recdp@list
%
\let\Reversion@list\version@list
\let\Regroup@list\group@list
\let\Reget@cdp\get@cdp
%
% \expandafter\def\expandafter\ReSetSymbolFont@\expandafter{\SetSymbolFont@}\show\ReSetSymbolFont@ % fails w 'Argument of \SetSymbolFont@ has an extra }.'
%
% \tracingpatches
% \let\ReSetSymbolFont@\SetSymbolFont@
% \patchcmd{\ReSetSymbolFont@}{\version@list}{\Reversion@list}{\typeout{success}}{\typeout{failure}} % -- macro cannot be retokenized cleanly; failure
%
\def\ReSetSymbolFont#1#2#3#4#5#6{%
\@tempswafalse
\edef\reserved@b{#3}%
\def\cdp@elt##1##2##3##4{\def\reserved@c{##1}%
\ifx\reserved@b\reserved@c \@tempswatrue\fi}%
\Recdp@list%\cdp@list
\if@tempswa
\expandafter\ReSetSymbolFont@
\csname mv@#2\expandafter\endcsname\csname#3/#4/#5/#6\expandafter
\endcsname \csname sym#1\endcsname
\else
\@latex@error{Encoding scheme `#3' unknown}\@eha
\fi
}
% \@onlypreamble\SetSymbolFont
% \def\@onlypreamble#1{%
% \expandafter\gdef\expandafter\@preamblecmds\expandafter{%
% \@preamblecmds\do#1}}
%
\def\ReSetSymbolFont@#1#2#3{%
\expandafter\in@\expandafter#1\expandafter{\Reversion@list}%
\ifin@
\expandafter\in@\expandafter#3\expandafter{\Regroup@list}%
\ifin@
\begingroup
\expandafter\Reget@cdp\string#2\@nil\reserved@a
\toks@{}%
\def\install@mathalphabet##1##2{%
\addto@hook\toks@{\install@mathalphabet##1{##2}}%
}%
\def\getanddefine@fonts##1##2{%
\ifnum##1=#3%
\addto@hook\toks@{\getanddefine@fonts#3#2}%
\expandafter\Reget@cdp\string##2\@nil\reserved@b
\ifx\reserved@a\reserved@b\else
\@font@info{Encoding `\reserved@b' has changed
to `\reserved@a' for symbol font\MessageBreak
`\expandafter\@gobblefour\string#3' in the
math version `\expandafter
\@gobblefour\string#1'}%
\fi
\@font@info{%
Overwriting symbol font
`\expandafter\@gobblefour\string#3' in
version `\expandafter
\@gobblefour\string#1'\MessageBreak
\@spaces \expandafter\@gobble\string##2 -->
\expandafter\@gobble\string#2}%
\else
\addto@hook\toks@{\getanddefine@fonts##1##2}%
\fi}%
#1%
\xdef#1{\the\toks@}%
\endgroup
\else
\@latex@error{Symbol font `\expandafter\@gobblefour\string#3'
not defined}\@eha
\fi
\else
\@latex@error{Math version `\expandafter\@gobblefour\string#1'
is not
defined}{You probably misspelled the name of the math
version.^^JOr you have to specify an additional package.}%
\fi
}
\makeatother
\begin{document}
\fontfamily{lmr}\selectfont% change text font to lmodern
\renewcommand{\rmdefault}{lmr}%
% \sisetup{detect-all}
% \mathversion{normal}% just testing
% \traceon
% \ReSetSymbolFont{upright} {normal}{OT1}{lmr} {m}{n} % lmnormal; nope
\ReSetSymbolFont{operators} {normal}{OT1}{lmr} {m}{n} % lmnormal - this is the one, that seemingly works?
\makeatletter
This is Lmodern font \math@version. $a^2 + b^2 = c^2; \mathrm{ms}$. $20$ ms, \fbox{\SI{20}{\meter\per\second}}
\mpmath
\def\defaultscriptratio{.76}
\def\defaultscriptscriptratio{.6}
% \sisetup{detect-all}
% \ReSetSymbolFont{upright} {normal} {OT1}{zplm}{m}{n} % mpazonormal; nope
\ReSetSymbolFont{operators} {normal} {OT1}{ppl}{m}{n} % mpazonormal
This is Mathpazo font \math@version. $a^2 + b^2 = c^2; \mathrm{ms}$. $20$ ms, \fbox{\SI{20}{\meter\per\second}}
\lmmath
\def\defaultscriptratio{.7}
\def\defaultscriptscriptratio{.5}
% \sisetup{detect-all}
% \ReSetSymbolFont{upright} {normal}{OT1}{lmr} {m}{n} % lmnormal; nope
\ReSetSymbolFont{operators} {normal}{OT1}{lmr} {m}{n} % lmnormal
This is LModern font \math@version. $a^2 + b^2 = c^2; \mathrm{ms}$. $20$ ms, %
% \traceon%
\fbox{\SI{20}{\meter\per\second}}%
% \traceoff
\makeatother
\end{document}