3

How can the following command be implemented with \NewDocumentCommand?:

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

MWE

\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}
6
  • Does \NewDocumentCommand\bracket{}{\brackethelp} \def\brackethelp<#1|#2>{\left\langle #1 \right|\left. #2 \right\rangle} qualify? Commented Mar 10 at 18:33
  • Why not use normal arguments? Do you think \bracket<\phi|\phi> looks that much clearer than \bracket{\phi}{\phi}? Also, please note that there is a package for braket notation named braket, maybe you want to give it a try instead fo reinventing the wheel?
    – Skillmon
    Commented Mar 10 at 18:41
  • 1
    @Skillmon I want it that way, that's my answer. Commented Mar 10 at 18:42
  • 1
    Then this is not really supported by \NewDocumentCommand, the whole idea of it is to implement standard argument types, all the more exotic ones are discouraged, better stick to \def, imho, maybe add an \@ifdefinable\racket to ensure the macro doesn't conflict with things. Also, in braket the syntax would be something like \braket{\phi|\phi}, not too far off from yours, but way more LaTeXy.
    – Skillmon
    Commented Mar 10 at 18:50
  • 2
    \left\langle #1 \right|\left. #2 \right\rangle does not ensure the < and > have the same size which is rather weird. why not \left\langle #1 \middle| #2 \right\rangle ???? Commented Mar 10 at 20:41

5 Answers 5

3

Make IMHO not really sense, but if you want:

\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}

or with one macro:

\documentclass{article}

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

\begin{document}

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

\end{document}

But IMHO better would be something like:

\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}

or easier:

\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}

Both result in:

enter image description here

4

Trust me: you don't want automatic sizing. Just look at the last two examples.

\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}

Note: twocolumn is just to make a smaller picture.

The optional and required arguments (the last one delimited inside <>) are preprocessed and control is then passed to \makebracket that typesets the inner part.

enter image description here

3

In general, ltcmd is intended for providing 'regular' LaTeX syntax, although it does allow some more flexible forms. Here, I would read the request as a require delimited argument which is split into two parts: similar to picture mode (..,..) in that sense:

\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}
3

[This is not an answer to the question of how to do it using \NewDocumentCommand from ltcmd/xparse.]

I might probably not bother using ltcmd/xparse at all.

Instead of \def I might probably just use expl3's \cs_new_protected:Npn; this way the command is protected in some expansion-contexts and you get a message in case defining implies overriding a definition already provided.

\documentclass[]{article}

\ExplSyntaxOn
\cs_new_protected:Npn\bracket<#1|#2>{\left\langle#1\middle|#2\right\rangle}
\ExplSyntaxOff

\begin{document}

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

\end{document}
1
  • This is the cleanest method.
    – yannisl
    Commented Mar 11 at 6:20
0

I found a way (don't know, if there is a better way):

\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}
1
  • 2
    \bracket<\phi^2|\phi> breaks silently. \bracket |\phi> also doesn't yield an error message. Commented Mar 10 at 20:44

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .