动态嵌套宏定义的问题

动态嵌套宏定义的问题

我遇到了嵌套宏定义的问题。虽然我的用例有点不同,但以下是一个最小(非)工作示例:

我想做的事:

我想动态定义一组宏\One\Two\Three。它们每个都应采用相同数量的参数,但这个参数数量也应该是可变的。通过调用

\docsvlist{mm, One(#1), Two(#1 #2)}

我希望所有宏都定义成接受两个强制参数,并且

\One{Hi}{Hello}
\Two{Hi}{Hello}
\Three{Hi}{Hello}

回来'

One: One(Hi)
Two: Two(Hi Hello)
Three: One(Hi) + Two(Hi Hello)

代码:

\usepackage{xparse}
\usepackage{etextools}    

\DeclareDocumentCommand{\myDeclare}{mmm}{
    \DeclareDocumentCommand{\One}{#1}{One: #2\par}
    \DeclareDocumentCommand{\Two}{#1}{Two: #3\par}
    \DeclareDocumentCommand{\Three}{#1}{Three: #2 + #3\par}
}
\DeclareDocumentCommand{\do}{m}{
    \DeclareDocumentCommand{\do}{m}{
        %This would work for \One:
        %\DeclareDocumentCommand{\One}{#1}{One: ##1\par}
        \DeclareDocumentCommand{\do}{m}{
            %This also works for \Two:
            %\DeclareDocumentCommand{\Two}{#1}{Two: ####1\par}
            \myDeclare{#1}{##1}{####1}
            %This also does not work for \Three:
            %\DeclareDocumentCommand{\Three}{#1}{Three: ##1 + ####1\par}
        }
    }
}
\docsvlist{mm, One(#1), Two(#1 #2)}
\One{Hi}{Hello}
\Two{Hi}{Hello}
\Three{Hi}{Hello}

这将产生以下输出:

One: One(Two(Hi Hello))
Two: Two(Hi Hello)
Three: One(Two(Hi Hello)) + Two(Hi Hello)

我真正想要的是:

One: One(Hi)
Two: Two(Hi Hello)
Three: One(Hi) + Two(Hi Hello)

我的问题:

发生了什么?我很惊讶它居然能正常工作。它\Two按我想要的方式定义,但\One只有按照我注释掉的方式定义它时,它才会被正确定义。我根本找不到\Three正确定义的方法。

在呼吁

        \myDeclare{#1}{##1}{####1}

在 的定义中,似乎从##1变为,然后又变为。One(#1)One(####1)One(Two(#1 #2))\One

但为什么呢?我该如何防止这种情况发生呢?

编辑:实际用例

我想同时定义几个数学函数或等式(或类似的东西),如(模拟)示例如下:

\MyDefine{
    aSet, {}, 
        \Omega, \subset \Reals, 
        {a nice set},
    aFunction, O{i}, 
        f^{#1}, :\aSet \to \aSet, 
        {some $#1$-th function},
    anEquality, O{i}O{j}, 
        \aFunction[#1] \leq \aFunction[#2], \text{for $#1 \leq #2$},
        {a nice inequality}
}

这应该定义(其中包括:更新):

\DeclareDocumentCommand{\aSet}{}{
    \Omega
}
\DeclareDocumentCommand{\aSetDefinition}{}{
    \subset \Reals
}
\DeclareDocumentCommand{\aSetDescription}{}{
    a nice set
}
\DeclareDocumentCommand{\aSetLabel}{}{def:aSet}
\DeclareDocumentCommand{\aFunction}{O{i}}{
    f^{#1}
}
\DeclareDocumentCommand{\aFunctionDefinition}{O{i}}{
    :\aSet \to \aSet
}
\DeclareDocumentCommand{\aFunctionDescription}{O{i}}{
    some $#1$-th function
}
\DeclareDocumentCommand{\aFunctionLabel}{}{def:aFunction}
\DeclareDocumentCommand{\anEquality}{O{i}O{j}}{
    \aFunction[#1] \leq \aFunction[#2]
}
...

以供以后使用并生成(例如):

\begin{align}
    \aSet& \aSetDefinition&& \text{\aSetDescription}\label{\aSetLabel}\\
    \aFunction& ...\\
    \anEquality& ...
\end{align}

答案1

如果需要,您可以保留逗号列表输入。etextools如果可以避免,请不要使用:expl3具有您需要的所有功能:

\documentclass{article}

\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\declaremacros}{>{\SplitArgument{2}{,}}+m}
 {
  \declaremacros:nnn #1
 }
\cs_new_protected:Nn \declaremacros:nnn
 {
  \NewDocumentCommand\One{#1}{#2}
  \NewDocumentCommand\Two{#1}{#3}
  \NewDocumentCommand\Three{#1}{#2 ~ + ~ #3}
 }
\ExplSyntaxOff

\declaremacros{mm, One(#1), Two(#1 #2)}

\begin{document}

\One{Hi}{Hello}

\Two{Hi}{Hello}

\Three{Hi}{Hello}

\end{document}

在此处输入图片描述

答案2

我可能不会同时使用 etextools 和 expl3,但在这里,你所针对的语法似乎使它变得比它本来应该的更复杂。这会产生所请求的输出

\documentclass{article}



\usepackage{xparse}


\DeclareDocumentCommand{\zz}{mmm}{%
    \DeclareDocumentCommand{\One}{#1}{One: #2\par}%
    \DeclareDocumentCommand{\Two}{#1}{Two: #3\par}%
    \DeclareDocumentCommand{\Three}{#1}{Three: #2 + #3\par}%
}

\zz{mm}{One(#1)}{Two(#1 #2)}

\begin{document}


\One{Hi}{Hello}
\Two{Hi}{Hello}
\Three{Hi}{Hello}

\end{document}

在此处输入图片描述

语法上唯一真正的区别是我使用{}{}而不是,{ , }但如果需要逗号列表,使用 expl3 列表处理器会很容易。不过括号组看起来更容易阅读。

相关内容