带有分隔参数的 \NewDocumentCommand

带有分隔参数的 \NewDocumentCommand

如何用\NewDocumentCommand?实现以下命令:

\def\bracket<#1|#2>{
    \left\langle #1 \right|\left. #2 \right\rangle
}

平均能量损失

\documentclass[]{article}

\def\bracket<#1|#2>{
    \left\langle #1 \right|\left. #2 \right\rangle
}

\begin{document}

\begin{equation}
    \bracket<\phi|\phi>
\end{equation}

\end{document}

答案1

我认为这不是什么意义,但是如果你想要:

\documentclass{article}

\makeatletter
\NewDocumentCommand{\bracket}{r<|}{%
  \typeout{TRACE1: \detokenize{#1}}%
  \@bracket{#1}|%
}
\NewDocumentCommand{\@bracket}{mr|>}{%
  \left\langle #1\middle|#2\right\rangle
}
\makeatother

\begin{document}

\begin{equation}
    \bracket<\phi|\phi>
\end{equation}

\end{document}

或者使用一个宏:

\documentclass{article}

\NewDocumentCommand{\bracket}{e{<}r|>}{%
  \left\langle #1\middle|#2\right\rangle
}

\begin{document}

\begin{equation}
    \bracket<\phi|\phi>
\end{equation}

\end{document}

但依我之见,更好的做法是这样的:

\documentclass{article}

\ExplSyntaxOn
\NewDocumentCommand{\bracket}{r<>}
  {
    \seq_set_split:Nnn \l_tmpa_seq { | } { #1 }
    \seq_pop_left:NN \l_tmpa_seq \l_tmpa_tl
    \left\langle \l_tmpa_tl
      \seq_map_inline:Nn \l_tmpa_seq { \middle | ##1 }
    \right\rangle
  }
\ExplSyntaxOff

\begin{document}

\begin{equation}
  \bracket<\phi|\phi>
  \bracket<\phi>
  \bracket<>
  \bracket<\phi|\phi|\phi>
\end{equation}

\end{document}

或者更简单:

\documentclass{article}

\ExplSyntaxOn
\NewDocumentCommand{\bracket}{r<>}
  {
    \tl_set:Nn \l_tmpa_tl { #1 }
    \tl_replace_all:Nnn \l_tmpa_tl { | } { \middle | }
    \left\langle \l_tmpa_tl \right\rangle
  }
\ExplSyntaxOff

\begin{document}

\begin{equation}
  \bracket<\phi|\phi>
  \bracket<\phi>
  \bracket<>
  \bracket<\phi|\phi|\phi>
\end{equation}

\end{document}

两者的结果是:

在此处输入图片描述

答案2

相信我:你不会想要自动调整大小。只需看看最后两个例子。

\documentclass[twocolumn]{article}
\usepackage{amsmath}
\usepackage{mleftright}

\NewDocumentCommand{\bracket}{s O{} >{\SplitArgument{1}{|}}r<>}{%
  % #1 = optional * for \left and \right
  % #2 = optional size command \big \Big ...
  % #3 = the main argument (required to be in <>)
  \IfBooleanTF{#1}{% automatic sizing
    \mleft\langle\makebracket{\;\middle|\;}#3\mright\rangle
  }{% no automatic sizing
    \mathopen{#2\langle}\makebracket{\mathrel{#2|}}#3\mathclose{#2\rangle}%
  }%
}
\NewDocumentCommand{\makebracket}{mmm}{%
  % #1 = middle delimiter
  % #2 = before |
  % #3 = after | (if present)
  #2 \IfValueT{#3}{#1 #3}%
}

\begin{document}

\begin{gather}
\bracket<a> \\
\bracket<a|b> \\
\bracket[\big]<a> \\
\bracket[\big]<a | b> \\
\bracket[\bigg]<\sum_{k=1}^n a_k | x> \\
\bracket*<\sum_{k=1}^n a_k | x>
\end{gather}

\end{document}

注:twocolumn只是为了制作一张较小的图片。

可选参数和必需参数(最后一个在里面分隔<>)经过预处理,然后将控制权传递给\makebracket对内部部分进行排版。

在此处输入图片描述

答案3

一般来说,ltcmd旨在提供“常规” LaTeX 语法,尽管它确实允许一些更灵活的形式。在这里,我会将请求解读为要求分隔参数分为两部分:与图片模式类似(..,..)

\documentclass{article}

\NewDocumentCommand\bracket{>{\SplitArgument{1}{|}} R<>{|}}
  {\bracketaux#1}
\newcommand*\bracketaux[2]{\left\langle #1 \right|\left. #2 \right\rangle}
\begin{document}

\begin{equation}
    \bracket<\phi|\phi>
\end{equation}

\end{document}

答案4

我找到了一种方法(不知道是否有更好的方法):

\documentclass[]{article}


\NewDocumentCommand{\bracket}{e<d|>}{
    \left\langle #1 \right|\left. #2 \right\rangle
}
\begin{document}

\begin{equation}
    \bracket<\phi|\phi>
\end{equation}


\end{document}

相关内容