考虑积分。$\int_{0}^{1} x dx$
创建一个有界限0
和的积分1
。
我定义evaluate
命令如下:
\newcommand{\evaluate}[3]{\left. #1 \right \rvert_{#2}^{#3}}
我现在可以使用:
$\evaluate{\frac{x^2}{2}}{0}{1}$
我希望能够使用这种语法:
$\evaluate{\frac{x^2}{2}}_{0}^{1}$
同样,我可以发出另一个命令:
$\integral{x dx}_{0}^{1}
这有可能吗?
答案1
这是一个稍微修改过的版本,供\integral
操作员展示定义这种“灵活”脚本的方法的一般思想。
\integral
仅接受主表达式的参数,即应该在带有脚本的积分符号之后的部分。这些存储在临时命令中\temp@expr
。我们设置积分符号,然后调用\integral@
检查下一个标记的辅助宏。如果下一个标记是下标字符_
,则调用另一个辅助宏,\integral@sub
该宏吞噬_
,读取以下参数(实际下标),生成下标输出,并\integral@
在可能跟上上标时再次调用。
如果出现上标字符 ( \integral@sup
),也会执行相同的操作。如果下一个标记既不是下标字符也不是上标字符,则积分表达式已完成,我们可以排版临时存储的表达式。通过\@ifnextchar
此处的检查,我们可以灵活地保持脚本的数量和顺序:
\documentclass{article}
\usepackage{amsmath}
\makeatletter
\def\integral#1#2{\def\temp@expr{#1\,\mathrm d#2}\int\integral@}
\def\integral@{%
\@ifnextchar{_}{\integral@sub}{%
\@ifnextchar{^}{\integral@sup}{\temp@expr}}%
}%
\def\integral@sub#1#2{_{#2}\integral@}
\def\integral@sup#1#2{^{#2}\integral@}
\makeatother
\begin{document}
\[
\integral{x^2}{x} \qquad
\integral{x^2}{x}_a \qquad
\integral{x^2}{x}^b \qquad
\integral{x^2}{x}_a^b \qquad
\integral{x^2}{x}^b_a
\]
\end{document}
输出:
答案2
我建议采用一种不同的、更灵活的方法,即使用键值语法。
的键\integral
是
lb
下限ub
为上限type
对于整数类型(默认\int
)along
(的语义别名lb
)domain
(对于多重积分,也是如此\limits
)style
用于覆盖当前的数学样式
这样,同一个命令可以用于更多用途。
该命令\evaluate
更简单;它接受lb
、ub
和size
,最后一个用于覆盖\left
和选择的样式\right
。
\documentclass{article}
\usepackage{xparse} % for expl3
\usepackage{amsmath}
\ExplSyntaxOn
\NewDocumentCommand{\diff}{} % for differentials
{
\mathop{}\!d
}
\NewDocumentCommand{\integral}{O{}m}
{
\group_begin:
\keys_set:nn { patenaude/integral } { #1 }
\patenaude_integral:n { #2 }
\group_end:
}
\NewDocumentCommand{\evaluate}{O{}m}
{
\group_begin:
\keys_set:nn { patenaude/evaluate } { #1 }
\patenaude_evaluate:n { #2 }
\group_end:
}
\keys_define:nn { patenaude/integral }
{
type .tl_set:N = \l_patenaude_integral_type_tl,
type .initial:n = \int,
lb .tl_set:N = \l_patenaude_integral_lb_tl,
ub .tl_set:N = \l_patenaude_integral_ub_tl,
along .tl_set:N = \l_patenaude_integral_lb_tl,
style .tl_set:N = \l_patenaude_integral_style_tl,
domain .code:n =
{
\tl_set:Nn \l_patenaude_integral_lb_tl { #1 }
\tl_put_right:Nn \l_patenaude_integral_type_tl { \limits }
}
}
\cs_new_protected:Nn \patenaude_integral:n
{
\l_patenaude_integral_style_tl % the math style
\l_patenaude_integral_type_tl % the chosen integral type
\tl_if_empty:NF \l_patenaude_integral_lb_tl % the lower bound or domain
{
\c_math_subscript_token { \l_patenaude_integral_lb_tl }
}
\tl_if_empty:NF \l_patenaude_integral_ub_tl % the upper bound
{
\c_math_superscript_token { \l_patenaude_integral_ub_tl }
}
#1 % the function
}
\keys_define:nn { patenaude/evaluate }
{
lb .tl_set:N = \l_patenaude_evaluate_lb_tl,
ub .tl_set:N = \l_patenaude_evaluate_ub_tl,
size .tl_set:N = \l_patenaude_evaluate_size_tl,
}
\cs_new_protected:Nn \patenaude_evaluate:n
{
\tl_if_empty:NT \l_patenaude_evaluate_size_tl % no chosen size
{
\kern-\nulldelimiterspace \left.
}
#1 % the function
\, % some space
\tl_if_empty:NTF \l_patenaude_evaluate_size_tl
{% no chosen size
\right|
}
{
\l_patenaude_evaluate_size_tl |
}
\tl_if_empty:NF \l_patenaude_evaluate_lb_tl % the lower bound or domain
{
\c_math_subscript_token { \l_patenaude_evaluate_lb_tl }
}
\tl_if_empty:NF \l_patenaude_evaluate_ub_tl % the upper bound
{
\c_math_superscript_token { \l_patenaude_evaluate_ub_tl }
}
}
\ExplSyntaxOff
\begin{document}
\[
\integral{x^2\diff x} \qquad
\integral[lb=a]{x^2\diff x} \qquad
\integral[ub=b]{x^2\diff x} \qquad
\integral[lb=a,ub=b]{x^2\diff x} \qquad
\integral[ub=b,lb=a]{x^2\diff x}
\]
\[
\integral[type=\iint,domain=\Omega]{xy\diff x\diff y} \qquad
\integral[type=\oint,along=\gamma]{f(z)\diff z}
\]
\[
\integral[style=\textstyle,lb=a,ub=b]{f(x)\diff x}
\]
\[
\evaluate[lb=0,ub=1]{\frac{x^2}{2}} \qquad
\evaluate[lb=0,ub=1,size=\Big]{\frac{x^2}{2}} \qquad
\evaluate[lb=0,ub=1]{x} \qquad
\evaluate[lb=0,ub=1,size=\big]{x}
\]
\end{document}