我在想如何在使用时减少代码重复\newcommand
。以下代码是解释事情的重点,完整的 TeX 代码可以找到这里以及编译后的 PDF这里:
\newcommand\transone{\ensuremath{\ket{2,2} \rightarrow \ket{1,1}}\xspace}
\newcommand\transtwo{\ensuremath{\ket{1,1} \rightarrow \ket{2,0}}\xspace}
\newcommand\transfull{\ensuremath{\ket{2,2} \rightarrow \ket{1,1} \rightarrow \ket{2,0}}\xspace}
\newcommand\ground[1]{\ensuremath{\ket{\text{#1}}}\xspace}
\newcommand\exited{\ensuremath{\ket{\text{e}}}\xspace}
然后你可以声明一些类似于声明的内容\newmathcommand
:
\newcommand\newmathcommand[2]{\newcommand#1{\ensuremath{ #2 } \xspace}}
然后通过以下方式声明命令
\newmathcommand\transone{\ket{2,2} \rightarrow \ket{1,1}}
以减少冗余。但是这会阻止我传递参数,例如 with \ground
。有没有办法组装一个可以传递参数的命令,以便您可以声明命令接受输入,如下所示:
\newmathcommand\ground[1]{\ket{\text{#1}}}
最好的,泰斯
答案1
其实这并不难。你只需要用一个技巧“拾取”可选参数。看这个例子:
\documentclass{article}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{xspace}
\makeatletter
\def\newmathcommand#1#{\@newmathcommand{#1}}
\def\@newmathcommand#1#2{\newcommand#1{\ensuremath{ #2 } \xspace}}
\makeatother
\newmathcommand\ground[1]{\ket\limits^{\text{#1}}}
\DeclareMathOperator\ket{ket}
\begin{document}
\ground{foo}blah
\end{document}
我使用的符号#{
是“分隔参数”的特殊形式。该构造\def\newmathcommand#1#{
意味着参数#1
将包含直到左括号的所有内容。
对于可选参数,使用通常的 LaTeX 机制可能也是可行的\newmathcommand
,但由于可选参数默认放在第一位,因此会比较麻烦。
答案2
你既不需要\ensuremath
也不需要\xspace
。输入什么好处
\documentclass{article}
\usepackage{amsmath,braket}
\newcommand\transone{\ket{2,2} \rightarrow \ket{1,1}}
\newcommand\transtwo{\ket{1,1} \rightarrow \ket{2,0}}
\newcommand\transfull{\ket{2,2} \rightarrow \ket{1,1} \rightarrow \ket{2,0}}
\newcommand\ground[1]{\ket{\text{#1}}}
\newcommand\exited{\ground{e}}
\begin{document}
We have $\transone$ and $\transtwo$ that take
us to $\transfull$ and finally to $\ground{x}$
to end with $\exited$.
\end{document}
没有$
符号?我看不出有什么用处,但我看到了使用它们的好处。例如,当使用语法着色时,它们效果更好
为了展示另一种策略,这里有一个xparse
:
\documentclass{article}
\usepackage{amsmath,braket,xspace}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\newmathcommand}{m}
{
\cs_if_exist:NTF #1 { \gobblenewmathcommand{#1} } { \donewmathcommand{#1} }
}
\NewDocumentCommand{\gobblenewmathcommand}{ moom }
{
\msg_error:nnn { newmathcommand } { already-defined } { #1 }
}
\NewDocumentCommand{\donewmathcommand}{ mO{0}om }
{
\IfNoValueTF{#3}
{ \newcommand{#1}[#2]{ \ensuremath{#4}\xspace } }
{ \newcommand{#1}[#2][#3]{ \ensuremath{#4}\xspace } }
}
\msg_new:nnnn {newmathcommand}{already-defined}
{Control~sequence~#1~already~defined.}
{The~control~sequence~#1~is~already~defined,~I'll~ignore~it}
\ExplSyntaxOff
\newmathcommand\transone{\ket{2,2} \rightarrow \ket{1,1}}
\newmathcommand\transtwo{\ket{1,1} \rightarrow \ket{2,0}}
\newmathcommand\transfull{\ket{2,2} \rightarrow \ket{1,1} \rightarrow \ket{2,0}}
\newmathcommand\ground[1]{\ket{\text{#1}}}
\newcommand\exited{\ground{e}}
\begin{document}
We have \transone and \transtwo that take
us to \transfull and finally to \ground{x}
to end with \exited.
\end{document}