这是我上一个问题的直接后续问题:覆盖matrix
以在内部工作align
(使用mtpro2
括号和大括号)。尽管这个问题是独立的,但我鼓励任何感兴趣的人先阅读那篇文章。
我的目标是覆盖mathtools
包dcases*
和朋友,以便可以使用 MathTime Pro 2 字体的大花括号自动地。请注意,尽管 MTPro2 的“完整”版本是非免费的,但“精简”版本(包含大括号)是 免费提供。
请注意pmatrix
,Bmatrix
和 cases
来自 amsmath
;和pmatrix*
和 Bmatrix*
来自 mathtools
在我自己的答案,基于@egreg 的精彩回答有两个明显的改进。
要求
对于dcases*
和朋友来说,只有一个要求:
curlybraces
如果将包选项传递给 , 则使用大花括号mtpro2
。否则,对于选项morphedbraces
或straightbraces
,使用大直的牙套。
有用的信息
大括号可以通过mtpro2
命令访问
\LEFTRIGHT<left delimiter><right delimiter>{<contents>}% `mtpro2' exclusive
而大直支架可以通过以下方式获得
\left<left delimiter> <contents> \right<right delimiter>
此外,3 个括号形封装选项声明为
% From `mtpro2.sty'
\DeclareOption{curlybraces}{\let\mtp@br=c}
\DeclareOption{morphedbraces}{\let\mtp@br=m}
\DeclareOption{straightbraces}{\let\mtp@br=s}
我的尝试
思路和@egreg 的回答和我自己的:1)将箱内物品存放在盒子中 \mtp@casesbox
。2)在盒子上打印 \LEFTRIGHT
(curlybraces
设置时)。
但是,mathtools
创建dcases*
和 朋友的方式与amsmath
重新定义 的 方式不同cases
。因此,我使用了两个新的构建宏\MTP_MT_start_cases:nnn
和\MTP_MH_end_cases:
,以及两个新命令\mtp@newcases
和\mtp@renewcases
。顾名思义,这两个命令是内部命令故意。
\documentclass{article}
\usepackage{mathtools}% loads `amsmath'
\usepackage{newtxtext}
\usepackage[scaled=0.861,lining]{FiraMono}
\def\bracesshape{curlybraces}% change here to obtain different braces
% curlybraces
% morphedbraces
% straightbraces
\usepackage[lite,\bracesshape]{mtpro2}
% Patches begin
\makeatletter
\newsavebox{\mtp@casesbox}
% Activate `mathtools' syntax
\MHInternalSyntaxOn
% Curly braces are used only if `curlybraces' is set
% From `mtpro2.sty': \DeclareOption{curlybraces}{\let\mtp@br=c}
\MH_if_meaning:NN \mtp@br c
\def\MTP_MT_start_cases:nnn #1#2#3{ % #1=sep,#2=lpreamble,#3=rpreamble
\RIfM@\else
\nonmatherr@{\begin{\@currenvir}}
\fi
\MH_group_align_safe_begin:
\setbox\mtp@casesbox=\hbox\bgroup$% <- put contents in `\mtp@casesbox'
\vcenter \bgroup
\Let@ \chardef\dspbrk@context\@ne \restore@math@cr
\let \math@cr@@\AMS@math@cr@@
\spread@equation
\ialign\bgroup
\strut@#2 \strut@
#3
\crcr
}
\def\MTP_MH_end_cases:{\crcr\egroup
\restorecolumn@
\egroup
$\egroup% <- close the `\hbox'
\MH_group_align_safe_end:
}
\newcommand*\mtp@newcases[6]{% #1=name, #2=sep, #3=lpreamble, #4=rpreamble, #5=left, #6=right
\newenvironment{#1}
{\MTP_MT_start_cases:nnn {#2}{#3}{#4}}
{\MTP_MH_end_cases:\LEFTRIGHT#5#6{\copy\mtp@casesbox}}
}
\newcommand*\mtp@renewcases[6]{
\renewenvironment{#1}
{\MTP_MT_start_cases:nnn {#2}{#3}{#4}}
{\MTP_MH_end_cases:\LEFTRIGHT#5#6{\copy\mtp@casesbox}}
}
\mtp@renewcases{dcases}{\quad}{%
$\m@th\displaystyle{##}$\hfil}{$\m@th\displaystyle{##}$\hfil}{\lbrace}{.}
\mtp@renewcases{dcases*}{\quad}{%
$\m@th\displaystyle{##}$\hfil}{{##}\hfil}{\lbrace}{.}
\mtp@renewcases{rcases}{\quad}{%
$\m@th{##}$\hfil}{$\m@th{##}$\hfil}{.}{\rbrace}
\mtp@renewcases{rcases*}{\quad}{%
$\m@th{##}$\hfil}{{##}\hfil}{.}{\rbrace}
\mtp@renewcases{drcases}{\quad}{%
$\m@th\displaystyle{##}$\hfil}{$\m@th\displaystyle{##}$\hfil}{.}{\rbrace}
\mtp@renewcases{drcases*}{\quad}{%
$\m@th\displaystyle{##}$\hfil}{{##}\hfil}{.}{\rbrace}
\mtp@renewcases{cases*}{\quad}{%
$\m@th{##}$\hfil}{{##}\hfil}{\lbrace}{.}
\MH_fi:
% Deactivate `mathtools' syntax
\MHInternalSyntaxOff
\makeatother
% Patches end
\newcommand*\showopendelimitersizes[1]{%
#1\bigl#1\Bigl#1\biggl#1\Biggl#1}
\begin{document}
\section*{\texttt{dcases*} in \texttt{align} work?}
\verb|dcases*| and friends from \verb|mathtools| work,
iff \verb|curlybraces| is set.
\subsection*{Package \texttt{mtpro2} options: \texttt{lite,\bracesshape}}
\begin{align*}
\showopendelimitersizes{\lbrace}
\begin{dcases*}
\int_a^b f(x) \, \mathrm{d}x & Nothing to see here \\
\sum_{n=1}^\infty \frac{1}{n^2} & Otherwise
\end{dcases*}
\end{align*}
With \verb|morphedbraces| or \verb|straightbraces|,
errors appear.
\end{document}
问题
我的实施有效当且仅当使用了包选项 curlybraces
。如果使用了包选项 morphedbraces
或 straightbraces
,则会出现以下错误:
% Hit <compile>
! Package amsmath Error: \begin{document} allowed only in math mode.
See the amsmath package documentation for explanation.
Type H <return> for immediate help.
...
l.21 \nonmatherr@{\begin{\@currenvir}}
% Hit <return>
! Only one # is allowed per tab.
l.31 #
3
% Hit <return>
! Extra \fi.
l.64 \MH_fi:
% Hit <return>
! Undefined control sequence.
\dcases* ->\MTP_MT_start_cases:nnn
{\quad }{$\m@th \displaystyle {##}$\hfil ...
l.85 \end{align*}
...
- 主要问题:为什么会出现这些错误?添加:我的有根据的猜测:这些错误很可能是由 TeX 处理条件的方式引起的。
- 小问题:我是否将
\setbox\mtp@casesbox=\hbox\bgroup$
和 插入到正确的位置?我问这个,是因为在原始和$\egroup
的定义中 ,\newcases
\renewcases
\left#4
后\MH_group_align_safe_begin:
但\right#6
也会后\MH_group_align_safe_end:
?! 这真是令人惊讶:我以为\right#6
应该来前\MH_group_align_safe_end:
。
替代解决方案非常受欢迎(对于这个问题以及我以前的)!
答案1
问题是,它\RIfM@
扩展为一个条件,但从 TeX 的角度来看它本身并不是一个条件。因此,如果 TeX 试图跳过这个块,则\fi
结束条件块将被视为\fi
结束块\MH_if_meaning:NN
,因此不会扩展它。可以通过将条件代码移动到宏参数中来解决这个问题,该宏参数根据条件进行评估或吞噬:
\documentclass{article}
\usepackage{mathtools}% loads `amsmath'
\usepackage{newtxtext}
\usepackage[scaled=0.861,lining]{FiraMono}
\def\bracesshape{straightbraces}% change here to obtain different braces
% curlybraces
% morphedbraces
% straightbraces
\usepackage[lite,\bracesshape]{mtpro2}
% Patches begin
\makeatletter
\newsavebox{\mtp@casesbox}
% Activate `mathtools' syntax
\MHInternalSyntaxOn
% Curly braces are used only if `curlybraces' is set
% From `mtpro2.sty': \DeclareOption{curlybraces}{\let\mtp@br=c}
\MH_if_meaning:NN \mtp@br c
\expandafter\@firstofone
\MH_else:
\expandafter\@gobble
\MH_fi:{
\def\MTP_MT_start_cases:nnn #1#2#3{ % #1=sep,#2=lpreamble,#3=rpreamble
\RIfM@\else
\nonmatherr@{\begin{\@currenvir}}
\fi
\MH_group_align_safe_begin:
\setbox\mtp@casesbox=\hbox\bgroup$% <- put contents in `\mtp@casesbox'
\vcenter \bgroup
\Let@ \chardef\dspbrk@context\@ne \restore@math@cr
\let \math@cr@@\AMS@math@cr@@
\spread@equation
\ialign\bgroup
\strut@#2 \strut@
#3
\crcr
}
\def\MTP_MH_end_cases:{\crcr\egroup
\restorecolumn@
\egroup
$\egroup% <- close the `\hbox'
\MH_group_align_safe_end:
}
\newcommand*\mtp@newcases[6]{% #1=name, #2=sep, #3=lpreamble, #4=rpreamble, #5=left, #6=right
\newenvironment{#1}
{\MTP_MT_start_cases:nnn {#2}{#3}{#4}}
{\MTP_MH_end_cases:\LEFTRIGHT#5#6{\copy\mtp@casesbox}}
}
\newcommand*\mtp@renewcases[6]{
\renewenvironment{#1}
{\MTP_MT_start_cases:nnn {#2}{#3}{#4}}
{\MTP_MH_end_cases:\LEFTRIGHT#5#6{\copy\mtp@casesbox}}
}
\mtp@renewcases{dcases}{\quad}{%
$\m@th\displaystyle{##}$\hfil}{$\m@th\displaystyle{##}$\hfil}{\lbrace}{.}
\mtp@renewcases{dcases*}{\quad}{%
$\m@th\displaystyle{##}$\hfil}{{##}\hfil}{\lbrace}{.}
\mtp@renewcases{rcases}{\quad}{%
$\m@th{##}$\hfil}{$\m@th{##}$\hfil}{.}{\rbrace}
\mtp@renewcases{rcases*}{\quad}{%
$\m@th{##}$\hfil}{{##}\hfil}{.}{\rbrace}
\mtp@renewcases{drcases}{\quad}{%
$\m@th\displaystyle{##}$\hfil}{$\m@th\displaystyle{##}$\hfil}{.}{\rbrace}
\mtp@renewcases{drcases*}{\quad}{%
$\m@th\displaystyle{##}$\hfil}{{##}\hfil}{.}{\rbrace}
\mtp@renewcases{cases*}{\quad}{%
$\m@th{##}$\hfil}{{##}\hfil}{\lbrace}{.}
}
% Deactivate `mathtools' syntax
\MHInternalSyntaxOff
\makeatother
% Patches end
\newcommand*\showopendelimitersizes[1]{%
#1\bigl#1\Bigl#1\biggl#1\Biggl#1}
\begin{document}
\section*{\texttt{dcases*} in \texttt{align} work?}
\verb|dcases*| and friends from \verb|mathtools| work,
iff \verb|curlybraces| is set.
\subsection*{Package \texttt{mtpro2} options: \texttt{lite,\bracesshape}}
\begin{align*}
\showopendelimitersizes{\lbrace}
\begin{dcases*}
\int_a^b f(x) \, \mathrm{d}x & Nothing to see here \\
\sum_{n=1}^\infty \frac{1}{n^2} & Otherwise
\end{dcases*}
\end{align*}
With \verb|morphedbraces| or \verb|straightbraces|,
errors appear.
\end{document}