一段时间以来,我一直试图想出一个宏,它可以正确格式化积分(我喜欢的方式)。同时给它一些可以选择的选项,例如\int
和\oint
。到目前为止,代码中出现了一个小问题。当您\oint
通过在参数中添加来选择时,就会出现这种情况。它确实带有右积分,但极限有点错误,因为它在极限中*
包含了太多。*
我的积分宏和一个示例如下所示
\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}
\usepackage{xstring}
\NewDocumentCommand{\Int}{ >{\SplitList{;}}o}{%
\IfValueT{#1}{\ProcessList{#1}{\IntLimitONE}}\,%
}
\NewDocumentCommand{\IntLimitONE}{m}{%
\IfSubStr{#1}{*}{\oint\IntSplitLimits{#1}\!}{\int\IntSplitLimits{#1}\!}
}
\NewDocumentCommand{\IntSplitLimits}{ >{\SplitArgument{1}{,}}m}{%
\IfValueT{#1}{\IntLimits#1}%
}
\NewDocumentCommand{\IntLimits}{mm}{%
_{#1}^{\IfNoValueTF{#2}{}{#2\!\!}}%
}
\begin{document}
\begin{equation}
\Int[a,b;*c,d;e,f] f(x,y,z) dxdydz \quad , \quad \Int[*a,b] f(x) dx
\end{equation}
\end{document}
我尝试了几种方法来解决这个问题,但没有一种能完全满足我的需求。我尝试过的一种方法是使用\xstring
命令\StrSubstitute
\NewDocumentCommand{\IntLimitONE}{m}{%
\StrSubstitute{#1}{*}{}[\temp]%
\IfSubStr{#1}{*}{\oint\IntSplitLimits{\temp}}{\int\IntSplitLimits{#1}}
}
它确实消除了*
限制,但上限已移至下限。
我似乎不明白这里出了什么问题?任何帮助我都感激不尽 :)
答案1
问题是,您\temp
尝试的修复被读取为一个标记,并且无法正确解析。插入几个\expandafter
s 可以修复此问题:
\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}
\usepackage{xstring}
\NewDocumentCommand{\Int}{ >{\SplitList{;}}o}{%
\IfValueT{#1}{\ProcessList{#1}{\IntLimitONE}}\,%
}
\NewDocumentCommand{\IntLimitONE}{m}{%
\IfSubStr{#1}{*}{\StrSubstitute{#1}{*}{}[\temp]\oint\expandafter\IntSplitLimits\expandafter{\temp}}{\int\IntSplitLimits{#1}}
}
\NewDocumentCommand{\IntSplitLimits}{ >{\SplitArgument{1}{,}}m}{%
\IfValueT{#1}{\IntLimits#1}%
}
\NewDocumentCommand{\IntLimits}{mm}{%
_{#1}^{\IfNoValueTF{#2}{}{#2\!\!}}%
}
\begin{document}
\begin{equation}
\Int[a,b;*c,d;e,f] f(x,y,z) dxdydz \quad , \quad \Int[*a,b] f(x) dx
\end{equation}
\end{document}
答案2
外觀很好。
为了决定是否*
出现,我\SplitArgument
最多使用一次*
;这将产生两个参数,其中第二个参数是-NoValue-
在没有出现星号的情况下。
其余部分只是在逗号处分开。
\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}
\NewDocumentCommand{\Int}{>{\SplitList{;}}O{}}{%
\ProcessList{#1}{\IntA}%
}
\NewDocumentCommand{\IntA}{>{\SplitArgument{1}{*}}{m}}{%
\IntB#1%
}
\NewDocumentCommand{\IntB}{mm}{%
\IfNoValueTF{#2}
{\IntC{\int}{#1}}% no *
{\IntC{\oint}{#2}}% *
}
\NewDocumentCommand{\IntC}{m >{\SplitArgument{1}{,}}m}{%
\IntD{#1}#2%
}
\NewDocumentCommand{\IntD}{mmm}{%
#1_{#2}^{#3}%
}
\begin{document}
\begin{equation}
\Int[a,b;*c,d;e,f] f(x,y,z) \,dx\,dy\,dz \quad , \quad \Int[*a,b] f(x)\,dx
\end{equation}
\end{document}
使用expl3
函数,您可以将参数拆分为;
并映射到由此获得的序列上。如果项目以 开头*
,则丢弃它并选择\oint
,否则选择\int
。
\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\Int}{O{}}
{
\simon_int:n { #1 }
}
\seq_new:N \l_simon_int_args_seq
\cs_new_protected:Nn \simon_int:n
{
\seq_set_split:Nnn \l_simon_int_args_seq { ; } { #1 }
\seq_map_inline:Nn \l_simon_int_args_seq
{
\str_if_eq_x:nnTF { \tl_head:n { ##1 } } { * }
{% * case
\simon_int_inner:Nf \oint { \tl_tail:n { ##1 } }
}
{% no * case
\simon_int_inner:Nn \int { ##1 }
}
}
}
\cs_new_protected:Nn \simon_int_inner:Nn
{
#1 \sb{ \clist_item:nn { #2 } { 1 } }
\sp{ \clist_item:nn { #2 } { 2 } }
}
\cs_generate_variant:Nn \simon_int_inner:Nn { Nf }
\ExplSyntaxOff
\begin{document}
\begin{equation}
\Int[a,b;*c,d;e,f] f(x,y,z) \,dx\,dy\,dz \quad , \quad \Int[*a,b] f(x)\,dx
\end{equation}
\end{document}
即使星号不在项目前面,也检查星号的变体:
\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\Int}{O{}}
{
\simon_int:n { #1 }
}
\seq_new:N \l__simon_int_args_seq
\tl_new:N \l__simon_int_ast_tl
\cs_new_protected:Nn \simon_int:n
{
\seq_set_split:Nnn \l__simon_int_args_seq { ; } { #1 }
\seq_map_inline:Nn \l__simon_int_args_seq
{
\tl_if_in:nnTF { ##1 } { * }
{% * case
\tl_set:Nn \l__simon_int_ast_tl { ##1 }
\tl_remove_once:Nn \l__simon_int_ast_tl { * }
\simon_int_inner:NV \oint \l__simon_int_ast_tl
}
{% no * case
\simon_int_inner:Nn \int { ##1 }
}
}
}
\cs_new_protected:Nn \simon_int_inner:Nn
{
#1 \sb{ \clist_item:nn { #2 } { 1 } }
\sp{ \clist_item:nn { #2 } { 2 } }
}
\cs_generate_variant:Nn \simon_int_inner:Nn { NV }
\ExplSyntaxOff
\begin{document}
\begin{equation}
\Int[a,b;*c,d;e*,f] f(x,y,z) \,dx\,dy\,dz \quad , \quad \Int[*a,b] f(x)\,dx
\end{equation}
\end{document}