有没有一种简单的方法可以在将一个术语装箱之前捕获数学类(\mathord
,,\mathrel
...),然后在使用时将其重新应用到该框中?
在下面的例子中,我希望两个方程中有相同的间距。
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{ \highlight }{ m }{
\hbox_set:Nn \l_tmpa_box { #1 }
\box_use:N \l_tmpa_box
}
\ExplSyntaxOff
\begin{document}
\[ a + b \]
\[ a \highlight{+} b \]
\end{document}
我知道有bm.sty
个诀窍(另见 David 的回答\fbox 的非侵入式替代品?) 来做到这一点,但我不知道它是如何工作的,也无法弄清楚如何将它转移到我的代码中。
笔记:我知道我的例子有点不对,因为框不允许数学内容,它只能+
在文本模式下工作(\int
例如在这里会失败)。在我的实际代码中,如果在保存框时对正确的模式和数学样式进行测试,但我在这里省略了它以使示例尽可能简短。我只是在寻找一种解决方案来捕获类并像那样应用它\mathCLASS { \box_use:N \l_tmpa_box }
。
背景:我需要这个来做以下事情:\highlight
应该给内容上色,但由于我使用浅色字体,所以对于突出显示的三个字体也应该选择更粗的字体。为了使其不具侵入性,我使用了类似
\NewDocumentCommand{ \highlight }{ m }{
\begingroup
\color { red }
\bfseries
#1
\endgroup
}
但这不适用于数学,因为\bfseries
数学模式禁止这样做。有,\boldmath
但它不能只应用于方程的一部分,所以我想出了这样的代码
\NewDocumentCommand{ \highlight }{ m }{
\tobi_set_text_or_math_hbox:Nnn \l_tmpa_box { \color { red } \bfseries \boldmath } { #1 }
\box_use:N \l_tmpa_box
}
需要\tobi_set_text_or_math_hbox
注意的是,框内容要设置为正确的字体和模式,必要时还要应用正确的数学样式。但是数学模式下的间距不再起作用,所以我正在寻找添加正确间距的方法\mathord
。\mathrel
这些是我的数学样式保存(需要 LuaTeX)和装箱宏的定义:
\cs_new_eq:NN \tobi_saved_math_style: \textstyle
\cs_new:Npn \tobi_save_math_style: {
\int_case:nn { \mathstyle } {
{ \displaystyle } { \cs_set_eq:NN \tobi_saved_math_style: \displaystyle }
{ \textstyle } { \cs_set_eq:NN \tobi_saved_math_style: \textstyle }
{ \scriptstyle } { \cs_set_eq:NN \tobi_saved_math_style: \scriptstyle }
{ \scriptscriptstyle } { \cs_set_eq:NN \tobi_saved_math_style: \scriptscriptstyle }
}
}
% #1 = box register
% #2 = font macros (always outside math mode)
% #3 = box content
\cs_new:Npn \tobi_set_text_or_math_hbox:nnn #1#2#3 {
\mode_if_math:TF {
\tobi_save_math_style:
\hbox_gset:Nn #1 {
#2
\(
\m@th
\tobi_saved_math_style:
#3
\)
}
} {
\hbox_set:Nn #1 {
#2 #3
}
}
}
答案1
这是我的想法:做一个简单的测试,看看盒子里有什么,然后应用正确的数学类。测试肯定不会总是给出正确/想要的结果,因此\highlight
有一个可选参数来手动设置类。
% !TeX program = lualatex
\documentclass[11pt]{scrartcl}
\usepackage{xparse}
\usepackage{amsmath}
\usepackage{xcolor}
\usepackage{tikz}
\ExplSyntaxOn\makeatletter
\cs_new_eq:NN \tobi_saved_math_style: \textstyle
\cs_new:Npn \tobi_save_math_style: {
\int_case:nn { \mathstyle } {
{ \displaystyle } { \cs_set_eq:NN \tobi_saved_math_style: \displaystyle }
{ \textstyle } { \cs_set_eq:NN \tobi_saved_math_style: \textstyle }
{ \scriptstyle } { \cs_set_eq:NN \tobi_saved_math_style: \scriptstyle }
{ \scriptscriptstyle } { \cs_set_eq:NN \tobi_saved_math_style: \scriptscriptstyle }
}
}
% - #1: Box register
% - #2: font switches (always outside math)
% - #3: box content
\cs_new:Npn \tobi_set_text_or_math_hbox:nnn #1#2#3 {
\mode_if_math:TF {
\tobi_save_math_style:
\hbox_gset:Nn #1 {
#2
\(
\m@th
\tobi_saved_math_style:
#3
\)
}
} {
\hbox_set:Nn #1 {
#2 #3
}
}
}
\cs_generate_variant:Nn \tobi_set_text_or_math_hbox:nnn { Nnn, NNN, NnN, NNn }
\tikzset {
highlight~node/.style = {
fill = yellow,
inner~sep = \z@,
},
}
\tl_new:N \tobi_current_math_class_tl
\tl_set:Nn \tobi_current_math_class_tl { ord }
\cs_generate_variant:Nn \tl_if_in:NnT { Nf }
\cs_generate_variant:Nn \tl_if_in:NnF { Nf }
\cs_generate_variant:Nn \tl_if_in:NnTF { Nf }
\tl_const:Nx \c_tobi_math_rel_symbols_tl { \tl_to_str:n { = < > \neq } }
\tl_const:Nx \c_tobi_math_bin_symbols_tl { \tl_to_str:n { + - \cdot \times } }
\tl_const:Nx \c_tobi_math_open_symbols_tl { \tl_to_str:n { ( [ \{ } }
\tl_const:Nx \c_tobi_math_close_symbols_tl { \tl_to_str:n { ) ] \} } }
\tl_const:Nx \c_tobi_math_operator_symbols_tl { \tl_to_str:n { \int \sum \prod } }
% - #1: content (text or math)
% - #2 (optional): manual math class = rel|op|bin|ord|close|open
\NewDocumentCommand{ \highlight }{ m o }{
\tobi_set_text_or_math_hbox:Nnn \l_tmpa_box { \color { red } \bfseries \boldmath } { #1 }
\tl_set:Nn \tobi_current_math_class_tl { ord }
\IfNoValueTF { #2 } {
\tl_if_in:NfTF \c_tobi_math_rel_symbols_tl { \tl_to_str:n { #1 } } {
\tl_set:Nn \tobi_current_math_class_tl { rel }
} {
\tl_if_in:NfTF \c_tobi_math_bin_symbols_tl { \tl_to_str:n { #1 } } {
\tl_set:Nn \tobi_current_math_class_tl { bin }
} {
\tl_if_in:NfTF \c_tobi_math_open_symbols_tl { \tl_to_str:n { #1 } } {
\tl_set:Nn \tobi_current_math_class_tl { open }
} {
\tl_if_in:NfTF \c_tobi_math_close_symbols_tl { \tl_to_str:n { #1 } } {
\tl_set:Nn \tobi_current_math_class_tl { close }
} {
\tl_if_in:NfT \c_tobi_math_operator_symbols_tl { \tl_to_str:n { #1 } } {
\tl_set:Nn \tobi_current_math_class_tl { operator }
}
}
}
}
}
} {
\tl_set:Nn \tobi_current_math_class_tl { #2 }
}
\tobi_add_math_class_maybe_if_math_mode:Vn \tobi_current_math_class_tl {
\begin{tikzpicture} [ baseline = (N.base) ]
\node [ highlight~node ] (N) {
\box_use:N \l_tmpa_box
% \textsubscript{\tobi_current_math_class_tl}
};
\end{tikzpicture}
}
}
\cs_new:Npn \tobi_add_math_class_maybe_if_math_mode:nn #1#2 {
\mode_if_math:TF {
\use:c { math #1 } { #2 }
} {
#2
}
}
\cs_generate_variant:Nn \tobi_add_math_class_maybe_if_math_mode:nn { Vn }
\ExplSyntaxOff\makeatother
\begin{document}
%\tl_const:Nx \c_tobi_math_rel_symbols_tl { \tl_to_str:n { = < > \neq } }
$\highlight{=}$
$\highlight{<}$
$\highlight{>}$
$\highlight{\neq}$
%\tl_const:Nx \c_tobi_math_bin_symbols_tl { \tl_to_str:n { + - \cdot \times } }
$\highlight{+}$
$\highlight{-}$
$\highlight{\cdot}$
$\highlight{\times}$
%\tl_const:Nx \c_tobi_math_open_symbols_tl { \tl_to_str:n { ( [ \{ } }
$\highlight{(}$
$\highlight{[}$
$\highlight{\{}$
%\tl_const:Nx \c_tobi_math_close_symbols_tl { \tl_to_str:n { ) ] \} } }
$\highlight{)}$
$\highlight{]}$
$\highlight{\}}$
%\tl_const:Nx \c_tobi_math_operator_symbols_tl { \tl_to_str:n { \int \sum \prod } }
$\highlight{\int}$
$\highlight{\sum}$
$\highlight{\prod}$
$\highlight{a+b}$
$\highlight{=}[ord]$
Text \highlight{highlighted} Text
\[ \highlight{-}3 m\highlight{2a}th \highlight{+} math = \highlight{\int}_0^5 math \, \highlight{\mathrm{d}x} \]
\[ -3 m2ath + math = \int_0^5 math \, \mathrm{d}x \]
\end{document}