生成接受参数的命令定义

生成接受参数的命令定义

我想定义一个命令\NewSmartOp如下:

\NewSmartOp \MYOP \myop

将产生以下代码(或任何等效代码):

\makeatletter
  \def\MYOP{\@ifstar\MYOP@star\MYOP@nostar}
  \def\MYOP@star#1{\myop\!\left( #1 \right)}
  \def\MYOP@nostar#1{\myop #1}
\makeatother

我想我需要\expandafter,也许\csname … \endcsname,但除此之外,我不知道如何生成这些定义,特别是关于如何\MYOP@star从中形成一个新的命令名称\MYOP,以及如何处理这些#1必须在生成的定义中保持原样的定义(与通过生成它们的定义进行扩展相反)。

背景(可选阅读)

简单介绍一下背景:当我输入数学时,我希望尽可能地从具体语法中抽象出来。例如,对于集合的基数年代,也许我希望它被渲染为卡 S(仅在需要时使用括号,例如卡(S₁∪S₂)),但也许在未来的某个时候,我想将语法切换为|S|。因此,我会定义:

\DeclareMathOperator \card {card}
\NewSmartOp \CARD \card % option 1
%\newcommand* \CARD[1] {\left\lvert # \right\rvert} % option 2

之后

  • 我可能会直接使用运算符(低级,我的 TeX 类型反映了具体的语法):\card S\card(S)
  • 但我宁愿使用带有参数的命令,我将具体语法推迟到该参数(高级语法,我的 TeX 类型反映了抽象语法树)\CARD {S}:。

这个理想似乎很难完全实现,因为我无法自动找出何时需要括号,所以我采取的折衷方案是让这些“智能运算符”的起始版本添加括号:\CARD* {S_1 \cup S_2}

答案1

我不确定为什么不直接定义\CARD

\NewDocumentCommand{\CARD}{sm}{%
  \operatorname{card}%
  \IfBooleanT{#1}{\left(}%
  #2%
  \IfBooleanT{#1}{\right)}%
}

如果你想要一个抽象版本:

\NewDocumentCommand{\NewOP}{mm}{%
  \NewDocumentCommand{#1}{sm}{%
    \operatorname{#2}%
    \IfBooleanT{##1}{\left}(%
    ##2%
    \IfBooleanT{##1}{\right})%
  }%
}

所以你可以\NewOp{\CARD}{card}

但是,使用\left(and\right)会产生不必要的超大括号。我已警告您。

您可以使用\DeclarePairedDelimiterfrom mathtools

\documentclass{article}
\usepackage{amsmath,mathtools}

\NewDocumentCommand{\NewOp}{mm}{%
  \NewDocumentCommand{#1}{t+s}{%
    \operatorname{#2}
    \IfBooleanT{##1}{%
      \IfBooleanTF{##2}{\parentheses*}{\parentheses}%
    }%
  }%
}
\DeclarePairedDelimiter{\parentheses}{(}{)}

\NewOp{\card}{card}

\begin{document}

\begin{gather*}
\card{S} \\
\card+{S_1\cup S_2} \\
\card+{\hat{S}_1\cup\hat{S}_2} \\
\card+[\big]{\hat{S}_1\cup\hat{S}_2} \\
\card+*{\hat{S}_1\cup\hat{S}_2}
\end{gather*}

\end{document}

在命令后面加上 表示需要括号+。这将调用成对的分隔符,而*表示需要自动调整大小的分隔符。

然而,从最后一行可以看出结果并不理想。

在此处输入图片描述

答案2

这种“高级”、抽象、语义的语法或多或少正是我的包的目的semantex

\documentclass{article}

\usepackage{semantex}

\NewVariableClass\MyVar[output=\MyVar]

\NewObject\MyVar\card{\operatorname{card}}

\begin{document}

\begin{gather*}
    \card{S} \\
    \card[par]{S} \\
    \card[no par]{S} \\
    \card{ \hat{S}_1 \cup \hat{S}_2 } \\
    \card[par=\big]{ \hat{S}_1 \cup \hat{S}_2 } \\
    \card[par=auto]{ \hat{S}_1 \cup \hat{S}_2 }
\end{gather*}

\SetupObject\card{no par}

\begin{gather*}
    \card{S} \\
    \card[par]{S} \\
    \card[no par]{S} \\
    \card{ \hat{S}_1 \cup \hat{S}_2 } \\
    \card[par=\big]{ \hat{S}_1 \cup \hat{S}_2 } \\
    \card[par=auto]{ \hat{S}_1 \cup \hat{S}_2 }
\end{gather*}

\SetupObject\card{
    symbol={},
    par,
    left par=\lvert,
    right par=\rvert,
}

\begin{gather*}
    \card{S} \\
    \card[par]{S} \\
    \card[no par]{S} \\
    \card{ \hat{S}_1 \cup \hat{S}_2 } \\
    \card[par=\big]{ \hat{S}_1 \cup \hat{S}_2 } \\
    \card[par=auto]{ \hat{S}_1 \cup \hat{S}_2 }
\end{gather*}

\end{document}

在此处输入图片描述

相关内容