数学字体改变和 siunitx?

数学字体改变和 siunitx?

考虑一下这个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

测试1.png

前两个\SI使用 Mathpazo 排版,符合预期(第一次是因为数学设置“泄漏”,因为mathpazo最后加载;第二次是因为明确请求了\mpmath-> \mathversion{mpazonormal})。但是一旦\mathversion{lmnormal}请求,它就不会对\SI-产生影响甚至如果\mathrm方程中的相当于数学模式下的 \mathup 直立文本) 被确认(因为它是用lmodern字体排版的)。

如果我启用所有\sisetup{detect-all},则输出如下:

测试2.png

现在所有的\SI都已排版lmodern- 即使我期望前两个用mathpazo?!排版。

那么我需要做什么,当我切换数学字体时,命令也会\SI用相同的字体排版?

答案1

好吧,经过大量的\trace思考,我想我已经解决了它:

测试3.png

...但我对这个解决方案感到很困惑,因此如果能给出更博学的答案我将不胜感激。

首先,在跟踪中注意到这一点:

\__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}

相关内容