%
% \iffalse meta-comment
%
% delimset.dtx Copyright (C) 2016-2025 Niklas Beisert
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
% of this license or (at your option) any later version.
% The latest version of this license is in
%   https://www.latex-project.org/lppl.txt
% and version 1.3c or later is part of all distributions of LaTeX
% version 2008 or later.
%
% This work has the LPPL maintenance status `maintained'.
%
% The Current Maintainer of this work is Niklas Beisert.
%
% This work consists of the files delimset.dtx and delimset.ins
% and the derived files delimset.sty and dlmssamp.tex.
%
%<package|sample>\NeedsTeXFormat{LaTeX2e}[1996/12/01]
%<package>\ProvidesPackage{delimset}[2025/03/25 v2.2.1 convenient size control for delimiter sets]
%<sample>\ProvidesFile{dlmssamp.tex}[2025/03/25 v2.2.1 sample for delimset]
%<*driver>
\def\thedate#1{2025/03/25}\def\theversion#1{v2.2.1}
\ProvidesFile{delimset.dtx}[\thedate{} \theversion{} delimset reference manual file]
\PassOptionsToClass{10pt,a4paper}{article}
\documentclass{ltxdoc}

\usepackage[margin=35mm]{geometry}
\usepackage[hyperindex=false]{hyperref}
\usepackage{hyperxmp}
\usepackage[usenames]{color}
\usepackage{amsmath,amsfonts}

\AddToHook{begindocument/before}{\hypersetup{colorlinks=false}}
\hypersetup{urlbordercolor={.5 1 1}}
\hypersetup{linkbordercolor={1 .7 .7}}
\AddToHook{begindocument/before}{\hypersetup{pdfstartview=FitH}}
\hypersetup{keeppdfinfo=true}
\hypersetup{pdfsource={}}
\hypersetup{pdflang={en-UK}}
\hypersetup{pdfurl={https://ctan.org/pkg/delimset}}
\hypersetup{pdfcopyright={Copyright 2016-2025 Niklas Beisert.
  This work may be distributed and/or modified under the
  conditions of the LaTeX Project Public License, either version 1.3
  of this license or (at your option) any later version.}}
\hypersetup{pdflicenseurl={https://www.latex-project.org/lppl.txt}}
\hypersetup{pdfcontactaddress={ETH Zurich, ITP, HIT K,
  Wolfgang-Pauli-Strasse 27}}
\hypersetup{pdfcontactpostcode={8093}}
\hypersetup{pdfcontactcity={Zurich}}
\hypersetup{pdfcontactcountry={Switzerland}}
\hypersetup{pdfcontactemail={nbeisert@itp.phys.ethz.ch}}
\hypersetup{pdfcontacturl={https://people.phys.ethz.ch/\xmptilde nbeisert/}}

\newcommand{\markpkg}[1]{\textsf{#1}}
\newcommand{\secref}[1]{\hyperref[#1]{section \ref*{#1}}}
\newcommand{\ctanref}[2]{\href{https://ctan.org/#1}{#2}}
\newcommand{\ctanpkg}[1]{\ctanref{pkg/#1}{\markpkg{#1}}}

\def\textvert{\texttt{\char"7C}}

\parskip1ex
\parindent0pt
\let\olditemize\itemize
\def\itemize{\olditemize\parskip0pt}

\begin{document}

\title{The \markpkg{delimset} Package}
\hypersetup{pdftitle={The delimset Package}}
\author{Niklas Beisert\\[2ex]
  Institut f\"ur Theoretische Physik\\
  Eidgen\"ossische Technische Hochschule Z\"urich\\
  Wolfgang-Pauli-Strasse 27, 8093 Z\"urich, Switzerland\\[1ex]
  \href{mailto:nbeisert@itp.phys.ethz.ch}
  {\texttt{nbeisert@itp.phys.ethz.ch}}}
\hypersetup{pdfauthor={Niklas Beisert}}
\hypersetup{pdfsubject={Manual for the LaTeX2e Package delimset}}
\date{\thedate{}, \theversion{}\\[1ex]
\url{https://ctan.org/pkg/delimset}}
\maketitle

\begin{abstract}\noindent
\markpkg{delimset} is a \LaTeXe{} package
to typeset and declare sets of delimiters in math mode
whose size can be adjusted conveniently.
\end{abstract}

\begingroup
\parskip0ex
\tableofcontents
\endgroup

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Introduction}

In ordinary \TeX{} and \LaTeX{}, delimiters in math and physics expressions
(brackets such as parentheses, braces, but also
absolute values, sets, pairings, bra-kets and quantum expectation values,
commutators, \ldots)
are typically coded by their respective symbols.
For example:
%
\[
\begin{aligned}
|[(ax+b)x+c]| &\to [(ax+b)x+c]
\\
|\{1,2,3,\ldots\}| &\to \{1,2,3,\ldots\}
\\
|(v,w)| &\to (v,w)
\\
|\langle\psi|\textvert|M|\textvert|\psi\rangle|
&\to \langle\psi\vert M\vert\psi\rangle
\\
|(x^2+px+q)|\textvert|_{-p/2}| &\to (x^2+px+q)\vert_{-p/2}
\\&\ldots
\end{aligned}
\]
%
In order to adjust the size of delimiters, the modifiers
|\big|, |\Big|, |\bigg|, |\Bigg| are used.
More importantly the construct
{|\left*| \ldots [|\middle*|] \ldots |\right*|}
adjusts the size of delimiters to the contents:
%
\[
\Bigg[\bigg[\Big[\big[[*]\big]\Big]\bigg]\Bigg],
\qquad
\left\{\frac{p}{q} \middle\vert p,q\in\mathbb{Z}, q\neq 0 \right\}
\]
%
These modifiers allow to construct expressions involving delimiters
conveniently and with a large amount of flexibility.

However, once an expression has been typeset in this way,
it takes some efforts to modify, if needed.
At least, one has to take care of both delimiters at the same time
and change their size or type accordingly.
For example, $\hat X$ in the expression |(A\hat{X}+B)|
has an extended height that calls for bigger delimiters.
Ideally, one would use |\left(...\right)|
to find the correct size.
Unfortunately, in this case, the smallest size of delimiters
that covers the height of $\hat X$ is equivalent to |\Big|,
which feels somewhat too big. For aesthetic reasons one might thus prefer
the size |\big(...\big)|:
%
\[
\begin{aligned}
|(A\hat{X}+B)|
&\to(A\hat{X}+B)
\\
|\left(A\hat{X}+B\right)|
&\to\left(A\hat{X}+B\right)
\\
|\Big(A\hat{X}+B\Big)|
&\to\Big(A\hat{X}+B\Big)
\\
|\big(A\hat{X}+B\big)|
&\to\big(A\hat{X}+B\big)
\end{aligned}
\]

The package \ctanpkg{delimset} provides mechanisms to declare sets of delimiters
whose size can be adjusted conveniently by adding simple flag parameters.
For example, it provides a general purpose bracket |\brk|
which can be used as follows:
%
\[
\begin{aligned}
|\brk{A\hat{X}+B}|&\to(A\hat{X}+B)
\\
|\brk*{A\hat{X}+B}|&\to\mathopen{}\mathclose{\left(A\hat{X}+B\right)}
\\
|\brk^2{A\hat{X}+B}|&\to\Bigl(A\hat{X}+B\Bigr)
\\
|\brk!{A\hat{X}+B}|&\to\bigl(A\hat{X}+B\bigr)
\end{aligned}
\]
%
It also allows to change the type of bracket conveniently:
%
\[
\begin{aligned}
|\brk{ax+b}|
&\to(ax+b)
\\
|\brk[s]{ax+b}|
&\to[ax+b]
\\
|\brk[c]{ax+b}|
&\to\{ax+b\}
\\
|\brk[a]{ax+b}|
&\to\langle ax+b\rangle
\end{aligned}
\]
%
These features can be combined and used, e.g., in nested brackets
in order to distinguish the levels by shape and size:
%
\[
|\brk[s]!{\brk{ax+b}x+c}|
\to\bigl[(ax+b)x+c\bigr]
\]
%
All of this can of course be achieved with the conventional
tools of \TeX{} with comparable effort,
but the more complicated and nested the expressions get,
the more difficult it will be to adjust them
to obtain a visually acceptable result.

The main functionality of the package is based on a
versatile mechanism to specify sets of delimiters,
e.g.:
%
\[
\begin{aligned}
|\delim<>{ax+b}|
&\to\langle ax+b\rangle
\\
|\delimpair[{*,}[!{a}{b}|
&\to \bigl[a, b\bigr[
\\
|\delimtriple<|\textvert\textvert|>*{\psi}{A^\dagger}{\psi}|
&\to\left\langle\psi\middle\vert A^\dagger\middle\vert \psi\right\rangle
\end{aligned}
\]
%
The command |\delim| can be used on the fly, but also
in definitions of custom delimiter sets such as:
%
\[
|\newcommand{\comm}{\delimpair{[}{*,}{]}}|
\]
%
Note that the definition of |\comm| does not specify any arguments.
They are nevertheless read by the incomplete definition of |\delimpair|
from what follows |\comm|.
In particular, this incomplete definition
enables the correct parsing of the optional size specifier flag,
e.g.:
%
\[
|\comm!{P}{\psi(x)}| \to \bigl[P,\psi(x)\bigr]
\]
%
The package also provides a mechanism to declare
delimited sets more flexibly.
The above definition could be written as follows:
%
\[
\begin{aligned}
&|\DeclareMathDelimiterSet{\comm}[2]|
\\
&\qquad |{\selectdeliml{[}{#1},{#2}\selectdelimr{]}}|
\end{aligned}
\]

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Delimiter Sizes for Math Styles}

In plain \LaTeXe{}
the size modifiers |\big|, |\Big|, |\bigg|, |\Bigg| have the shortcoming
that they are based on a fixed font size of 10pt.
More precisely, they use a vertical phantom of
height 8.5pt, 11.5pt, 14.5pt or 17.5pt, respectively
to set the height of the delimiter.
The package \ctanpkg{amsmath} corrects for font size
by instead placing a (centred) vertical phantom of
height 1.2, 1.8, 2.4 or 3 times the size
of the currently selected math font
(height plus depth of |\Mathstrutbox@|).

Unfortunately, it does not account for
the currently selected math style.
Therefore, the size of delimiters in sub/superscripts
cannot be adjusted appropriately
(an arguably better typesetting practice is
to avoid complicated expressions in sub/superscripts in the first place),
they come out way too big:
%
\[
|e^{\big(ax+b\big)}| \to e^{\big(ax+b\big)}
\]
%
This package modifies the definitions of
the size modifiers (of \ctanpkg{amsmath})
to automatically adjust to sub/superscripts
(subject to availability in the font):
%
\[
\makeatletter
|e^{\big(ax+b\big)}| \to e^{\left(\vcenter to 0.7\big@size{}ax+b\right)}
\makeatother
\]

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Spacing and Math Classes}
\label{sec:spacing}

Another shortcoming of the variable-size delimiters is that
the spacing is noticeably different from their fixed-size counterparts:
%
\[
\begin{aligned}
|\square(ax+b)\square|
&\to \square(ax+b)\square
\\
|\square\bigl(ax+b\bigr)\square|
&\to \square\bigl(ax+b\bigr)\square
\\
|\square\left(ax+b\right)\square|
&\to \square\left(ax+b\right)\square
\\
|\square\left(ax+\big.b\right)\square|
&\to \square\left(ax+\big.b\right)\square
\end{aligned}
\]
%
Often the construct |\left*| \ldots|\right*|
leaves a large amount of space around it.
A suitable way to fix this problem
is to adjust the math class as follows:
%
\[
\begin{aligned}
|\square(ax+b)\square|
&\to \square(ax+b)\square
\\
|\square\mathopen{}\mathclose{\left(ax+b\right)}\square|
&\to \square\mathopen{}\mathclose{\left(ax+b\right)}\square
\end{aligned}
\]
%
This makes the expression look like |\mathopen| from the left
and like |\mathclose| from the right. Importantly,
the delimited expression should be contained in
the |\mathclose| block so as to place any following
sub/superscripts at the appropriate height.
Unfortunately, the fix is too elaborate
in comparison to the benefits of appropriate spacing.
For practical purposes, consistent spacing can only be achieved
by a more convenient mechanism.

On a related note, it is important to correctly specify
the math class (such as |\mathopen| or |\mathclose|)
for the delimiters, for example:
%
\[
\begin{aligned}
|\big(-1\big)| &\to \big(-1\big)
\\
|\bigl(-1\bigr)| &\to \bigl(-1\bigr)
\end{aligned}
\]
%
The math class can also make a major difference for intermediate delimiters,
e.g.:
%
\[
\begin{aligned}
|\bigl<\psi\big|\textvert|\psi\bigr>|
&\to \bigl<\psi\big\vert\psi\bigr>
\\
|\bigl<\psi\mathpunct\big|\textvert|\psi\bigr>|
&\to \bigl\langle\psi\mathpunct\big\vert\psi\bigr>
\\
|\bigl<\psi\mathinner\big|\textvert|\psi\bigr>|
&\to \bigl\langle\psi\mathinner\big\vert\psi\bigr>
\\
|\bigl<\psi\mathbin\big|\textvert|\psi\bigr>|
&\to \bigl\langle\psi\mathbin\big\vert\psi\bigr>
\\
|\bigl<\psi\bigm|\textvert|\psi\bigr>|
&\to \bigl\langle\psi\bigm\vert\psi\bigr>
\end{aligned}
\]
%
Depending on the particular situation,
any of these expressions may be the most appropriate representation.

The package \ctanpkg{delimset} automatically takes care of the math classes
of the left and right delimiters. It also offers several choices for
intermediate delimiters to take the context into account.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Compounds and Broken Lines}

The mechanism provided by the package requires the delimited expression
to appear as an uninterrupted compound. In particular, the expression cannot
span several lines in a multi-line equation or several columns in a matrix.
The same restriction applies to the elementary |\left| and |\right| construct.
In cases where delimited expressions are torn apart across several blocks,
the delimiters have to be typeset individually.
The package offers a mechanism to display individual delimiters
of a given delimiter set. It also assists in maintaining
the same type and size across blocks.
Being able to display individual delimiters of defined delimiter sets
offers a broad range of (ab)use.

Individual delimiters of a set can be selected and displayed
by specifying appropriate flags,
for example:
%
\[
|\brk(|\to{(},\qquad
|\brk)|\to{)}
\]
%
These flags can be combined with the size specifier
or other bracket modifiers,
e.g.:
%
\[
|\brk^3(|\to{\biggl(},\qquad
|\brk[s]^2)|\to{\Bigr]}
\]
%
This enables to conveniently split delimited expressions over blocks of code,
e.g.:
%
\[
|\brk[s]^3(\frac{A}{B}|\ldots\Big/\mkern-9mu\Big/\ldots|\frac{C}{D}\brk[s]^3)|
\to
\biggl[\frac{A}{B}\cdots\bigg/\mkern-12mu\bigg/\cdots\frac{C}{D}\biggr]
\]
%
Here, the type and modifiers specifying the delimiter set
are repeated for all individual delimiters.
To simplify such expressions and their maintenance,
the package provides global registers which store
the type and size of delimiters.
With those, the above expression can be abbreviated as:
%
\[
|\brk[s]^3[|\ldots\big/\mkern-6mu\big/\ldots|\usedelim]|
\quad\text{or}\quad
|\brk[s]^3[|\ldots\big/\mkern-6mu\big/\ldots|\brk]|
\]
%
Here, |\usedelim]|, alternatively |\brk]|,
closes the delimiter set with
the type and options previously specified by |\brk...[|.
This mechanism respects nesting, and for even broader control
there exists a more elaborate solution using registers, see below.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Philosophy}

Semantic typesetting is one of the philosophies behind \LaTeX{}:
The author should focus on the content
while the layout is taken care of by the engine.
The (body of a) source file largely codes the contents of the document,
while the layout is largely specified
by the kernel, classes, styles and macro definitions
(in the preamble).
In order for the separation of content and layout to work well,
the meaning of the content must be accurately specified by the source file
so that the appropriate layout can be applied to it.
For example, a left bracket `|(|' can have many meanings,
which the engine could not possibly guess.
Even a simple compound expression such as |[A,B]| could
have different meanings depending on context
such as a compact interval or a commutator.
A semantic coding of the latter two concepts
such as |\intv{A}{B}| vs.\ |\comm{A}{B}|
clearly distinguishes between them.
This allows the typesetting engine to represent them appropriately
in every situation.
It also allows to consistently define or adjust
the typeset representation globally
according to one's taste, such as $[A,B]$ vs.\ $[A;B]$.
The price to pay is a larger number of abstract commands
(which possibly evaluate to the same expression)
and using them to specify the semantics throughout the source file
(or at least where practical and useful).
Conversely, the price to pay for an immediate typesetting scheme is that
all notations need to be fixed at the start, and later adjustments require
an elaborate search and replacement
of (somewhat ambiguous) patterns like |[|$x$|,|$y$|]|.

Another distinction between \TeX{} and \LaTeX{} is that the former
frequently uses free-format expressions such as $|{x\over y}|$
whereas the latter normally uses structured commands with arguments
such as $|\frac{x}{y}|$.
In that sense, the construct {|\left(ax+b\right)|}
belongs to the world of \TeX{}, whereas an expression like
{|\delim()*{ax+b}|} fits the \LaTeX{} framework better.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Related CTAN Packages}

There are at least three other packages which offer a similar functionality:
%
\begin{itemize}
\item
The package \ctanpkg{delim} supplies a command
|\delimdef| to declare a set of delimiters
which is similar to the present |\DeclareMathDelimiterSet|.
The size of delimiters to be used in each case
is then specified by a prefix command such as |\mbig| or |\mauto|.
\item
The package \ctanpkg{mathtools}
supplies commands |\DeclarePairedDelimiter...| (among many other things)
which are similar to the present |\DeclareMathDelimiterSet|.
The size of delimiters to be used in each case
is then specified by an optional argument
such as `|*|' or |[\big]|.
\item
The package \ctanpkg{delimseasy}
defines a collection of useful delimiters such as |\prn| for
round parentheses or |\sqpr| square parentheses.
Modifier letters can be prepended and appended to adjust their size.
\end{itemize}
%
A functionality of the present package
not offered by any of the above packages is
to typeset delimiters on the fly,
e.g.:
%
\[
|\delim<|\textvert|>!{\psi}{\psi}|
\to\bigl<\psi\big\vert\psi\bigr>
\]
%
The mechanism to specify the size is leaner in the sense that it uses
only a single character and a single command.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Usage}

To use the package \ctanpkg{delimset} add the command
\begin{center}|\usepackage{delimset}|\end{center}
to the preamble of your \LaTeX{} document.
If not yet present,
the package \ctanpkg{amsmath} will be loaded automatically.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Delimiter Sets and Presentation Flags}
\label{sec:flags}

The package provides commands to represent various delimiter sets,
see \secref{sec:inline} and \secref{sec:declare} below.
Their display can be modified systematically by specifying flags.
A delimiter set |\|\emph{name}, e.g.\ |\brk|, is typically invoked by
a sequence like:
%
\[
|\|\emph{name}\ \emph{flags}\ |{|\emph{expr1}|}||{|\emph{expr2}|}|\ldots
\]
%
where \emph{expr(n)} are the terms to be enclosed by the delimiters
and the optional \emph{flags} adjust the presentation of delimiters.
The \emph{flags} are described as follows:

First, a size modifier flag controls the size of the delimiters
to be displayed. It can take one of the following values:
%
\[
\begin{aligned}
|0|&\qquad \text{default size}
\text{ (0.96 times default line height)}
\\
|!|, |+|, |^1|&\qquad \text{size }|\big|
\text{ (1.2 times default line height)}
\\
|^2|&\qquad \text{size }|\Big|
\text{ (1.8 times default line height)}
\\
|^3|&\qquad \text{size }|\bigg|
\text{ (2.4 times default line height)}
\\
|^4|&\qquad \text{size }|\Bigg|
\text{ (3.0 times default line height)}
\\
|^|\emph{n}, |^{|\emph{x}|}|&\qquad \text{flexible size adjustment
(\emph{n}=|0|\ldots|9|; \emph{x}: decimal number)}
\\
|_{|\emph{h}|}|&\qquad \text{adjustment to absolute height \emph{h} (centred)}
\\
|*|&\qquad \text{variable size }|\left...\right|
\end{aligned}
\]
%
The intended delimiter size is stored as the dimension variable:
%
\[
|\delimsize|
\]
%
It may be used to adjust spacing within the delimiter set
proportional to the size of the delimiters.
Note that the actual size of delimiters may deviate
depending on availability within the given font.
Note further that the size cannot be determined for variable-size delimiters
(`|*|') and thus size |\Big| is assumed for this case.
Note finally that the sub/superscript styles are not taken into
account and |\delimsize| applies to the default case |\textstyle|.
The package also supplies a macro to add horizontal glue
proportional to the intended delimiter size:
%
\[
|\kerndelim{|\emph{width}|}|
\]
%
Here, \emph{width} is the amount of horizontal glue
in units of mu scaled by the ratio of |\delimsize|
and the current math font height.
The macro does adjust for the selected script style.

Second, a delimiter selection flag is used to pick out
and display just one individual delimiter within the set.
It can take one of the following values:
%
\[
\begin{aligned}
|(|&\qquad \text{left delimiter}
\\
\textvert, |,|&\qquad \text{first intermediate delimiter}
\\
|?|\emph{n}&\qquad \text{\emph{n}-th delimiter (starting with |0|: left)}
\\
|)|&\qquad \text{right delimiter}
\end{aligned}
\]

Third, register flags store and retrieve delimiter sets
for splitting them across blocks or lines:
%
\[
\begin{aligned}
|[|&\qquad \text{push delimiter type to register stack, display left delimiter
(similar to `|>.(|')}
\\
|]|&\qquad \text{pop delimiter type from stack, display right delimiter
(similar to `|<.)|')}
\\
|>|\emph{r}, |>{|\emph{reg}|}|&\qquad \text{store delimiter type
to register \emph{r} or \emph{reg}}
\\
|<|\emph{r}, |<{|\emph{reg}|}|&\qquad \text{retrieve delimiter type
from register \emph{r} or \emph{reg}}
\end{aligned}
\]
%
A register stores the type of delimiter set (|\|\emph{name}),
the desired size (except for variable size `|*|')
as well as the math class of the compound (`|'|' vs. `|"|', see below).
The register stack enables convenient access to nested delimiter sets,
and the special register `|.|' points to the top of the stack.
A stored register can be retrieved and displayed by the macro:
%
\[
|\usedelim|\,\emph{r}\ \emph{flags}\ \emph{sel}
\quad\text{or}\quad
|\usedelim|\{\emph{reg}\}\,\emph{flags}\ \emph{sel}
\quad\text{or}\quad
|\usedelim|\,\emph{sel}
\]
%
Here, \emph{sel}
is a flag to select an individual delimiter
(`|(|', `\textvert', `|,|', `|?|\emph{n}', `|)|' or `|]|'), see above.
The abbreviated form without register specification operates
on the top of the register stack.

In addition, there are some general purpose flags:
%
\[
\begin{aligned}
|.|&\qquad \text{terminates flag processing}
\\
|:|&\qquad \text{enclose delimiter set in block
(for using total box dimensions)}
\\
|'|&\qquad \text{render delimiter set as }|\mathopen|\text{ and }|\mathclose|
\\
|"|&\qquad \text{render delimiter set as }|\mathinner|
\\
|-|&\qquad \text{display phantom delimiters (for individual delimiters)}
\end{aligned}
\]

Please note the following:
%
\begin{itemize}
\item
A delimiter selector (including the combined flags `|[|' and `|]|')
terminates flag processing,
therefore all relevant flags must be specified before it.
\item
Parsing also stops with the opening of the first term argument
by means of the opening brace `|{|'.
\item
Parsing can also be terminated manually by specifying the flag `|.|'
(in case the opening brace `|{|' for arguments is missing for whatever reason).
\item
Any other letter or token at the location of \emph{flags}
is interpreted as an unrecognised flag and triggers a compiler error.
For instance, |\brk{x}| must not be abbreviated as |\brk x|
because `|x|' would be interpreted as a flag
(it might be abbreviated as |\brk.x|).
\item
The legacy size modifier flags `|1|' \ldots `|4|'
provided for backward compatibility have the same effect as `|^1|'\ldots`|^4|'.
\item
The phantom delimiter flag `|-|' does not work for variable size.
It is intended for reserving space for individual delimiters
when they are composed manually into sets (e.g.\ across lines).
\item
Technically, individual delimiters can be produced in the variable size version
(even though it may defeat the purpose of the delimiter selection mechanism).
One has to pay attention when using
only the opening or only the closing delimiters from the package
and counterbalancing it by direct code for the opposite side.
This is because `|*(|' and `|*)|' do not directly translate to
|\left|\emph{delim} and |\right|\emph{delim}
due to proper spacing, see \secref{sec:spacing}.
Instead, they translate to:
%
\[
\begin{aligned}
|*(|&\to|\mathopen{}\mathclose\bgroup\left|\emph{delim}
\\
|*)|&\to|\right|\emph{delim}|\egroup|
\end{aligned}
\]
%
One should use analogous code to complete the manual variable size block.

Note that similar restrictions apply to using the flag `|:|'
for block enclosure which uses |\bgroup| and |\egroup| as well.

As it does not make much sense to use variable-size (`|*|')
and block (`|:|') compounds for individual delimiter selection,
the state of these flags is not stored in the global registers.

\item
The delimiter selectors `|[|' and `|]|' implement a stack,
and they must be properly balanced.
Technically, they access the register `|.|\emph{n}'
with the stack counter \emph{n}=1,2,3\ldots\ a global variable
which is increased or decreased, respectively.
The special register `|.|' points to the current top of the stack
to enable access to intermediate delimiters.
\end{itemize}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Inline Declarations}
\label{sec:inline}

The package provides three general purpose commands
to compose delimiter sets with one, two or three encapsulated expressions:
%
\[
\begin{aligned}
&|\delim{|\emph{l}|}{|\emph{r}|}|\emph{flags}|{|\emph{expr}|}|
\\
&|\delimpair{|\emph{l}|}{|\emph{m}|}{|\emph{r}|}|
\emph{flags}|{|\emph{expr1}|}{|\emph{expr2}|}|
\\
&|\delimtriple{|\emph{l}|}{|\emph{m}|}{|\emph{n}|}{|\emph{r}|}|
\emph{flags}|{|\emph{expr1}|}{|\emph{expr2}|}{|\emph{expr3}|}|
\end{aligned}
\]
%
The expression(s) \emph{expr(n)} will be surrounded by the
delimiters \emph{l} and \emph{r}
and, in the case of more than one expression,
they will be separated by the delimiters \emph{m}, \emph{n}:
%
\[
\emph{l}\ \emph{expr}\ \emph{r},
\qquad
\emph{l}\ \emph{expr1}\ \emph{m}\ \emph{expr2}\ \emph{r},
\qquad
\emph{l}\ \emph{expr1}\ \emph{m}\ \emph{expr2}\
\emph{n}\ \emph{expr3}\ \emph{r}
\]

Here, \emph{l}, \emph{r}, \emph{m}, \emph{n}
should be math delimiters \emph{delim}
(elementary symbols which can be used for |\left| and |\right|)
or the dot `|.|' for the null delimiter.
The delimiter set expression can be adjusted in two ways:

First, size adjustment
for the delimiters \emph{l}, \emph{r}, \emph{m}, \emph{n}
can be suppressed by a starred variant:
%
\[
|{*|\emph{token}|}|
\qquad\text{or}\qquad
|{*{|\emph{expr}|}}|
\]
%
This allows to use an arbitrary \emph{token}
or a compound expression \emph{expr} in place of a delimiter \emph{delim}.
This is useful when a delimiter character should not adjust in size
(e.g.\ commas), or if a flexible-size version of the character
is not available. One might also use a compound expression
to create a null delimiter with non-zero width
(the width may be specified by |\kerndelim|
to make it proportional to the delimiter size).

Second, the intended math class
of the intermediate delimiters \emph{m}, \emph{n}
may be adjusted in order to achieve a more appropriate automatic spacing
by using |{[|\emph{class}|]|\emph{delim}|}|.
Here, \emph{class} specifies
the intended math class of the delimiter \emph{delim}
according to:
%
\[
\begin{aligned}
\left.\begin{array}{r}
\emph{delim}\\|{|\emph{delim}|}|
\end{array}\right\}
&\qquad
\left\{\begin{array}{l}
\text{no glue for size-adjusted delimiters (same as }|[o]|\text{)}
\\
\text{determined by expression for unadjusted size (}|*|\text{ variant)}
\end{array}\right.
\\
|{[o]|\emph{delim}|}|
&\qquad
\text{no glue, similar to }|\big|, |\mathord|, |\mathopen|, |\mathclose|
\\
|{[p]|\emph{delim}|}|&\qquad
\text{followed by }|\thinmuskip|\text{, similar to }|\bigp|, |\mathpunct|
\\
|{[i]|\emph{delim}|}|&\qquad
\text{surrounded by }|\thinmuskip|\text{, similar to }|\bigi|, |\mathinner|
\\
|{[b]|\emph{delim}|}|&\qquad
\text{surrounded by }|\medmuskip|\text{, similar to }|\bigb|, |\mathbin|
\\
|{[m]|\emph{delim}|}|&\qquad
\text{surrounded by }|\thickmuskip|\text{, similar to }|\bigm|, |\mathrel|
\end{aligned}
\]

Please note the following:
%
\begin{itemize}
\item
The left and right delimiters \emph{l} and \emph{r}
are assigned to special classes:
They leave no initial and final glue on the enclosed expressions
(same as |\mathopen| and |\mathclose|).
From the outside, the delimiter set appears
either as a combination of |\mathopen|+|\mathclose| (flag `|'|')
or as |\mathinner| (flag `|"|').
\item
The legacy class |[.]| provided for backward compatibility
specifies delimiters with unadjusted size:
the compound |{[.]|\emph{expr}|}| has the same effect as |{*{|\emph{expr}|}}|.
\item
The legacy class |[c]| provided for backward compatibility
has the same effect as |[o]|.
\item
Unadjusted-size delimiters can be combined with math classes as:
%
\[
|{[|\emph{class}|]*|\emph{token}|}|
\qquad\text{or}\qquad
|{[|\emph{class}|]*{|\emph{expr}|}}|
\]
%
\item
The opening square bracket `|[|'
takes the dual role of indicating the optional |[|\emph{class}|]| argument.
To avoid conflicts on intermediate delimiters,
opening square bracket delimiters should be encoded as
`|{{[}}|' (for |\delim...|) or `|{[}|' (for |\selectdelim|)
rather than `|[|'.
\end{itemize}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Declarations}
\label{sec:declare}

The above constructs can be used to define new delimiter commands via:
%
\[
\begin{aligned}
&|\newcommand{\|\emph{name}|}{\delim{|\emph{l}|}{|\emph{r}|}|
\emph{flags}|}|
\\
&|\newcommand{\|\emph{name}|}{\delimpair{|\emph{l}|}{|\emph{m}|}{|\emph{r}|}|
\emph{flags}|}|
\\
&|\newcommand{\|\emph{name}|}{\delimtriple{|\emph{l}|}{|\emph{m}|}|
|{|\emph{n}|}{|\emph{r}|}|\emph{flags}|}|
\end{aligned}
\]
%
Here it makes sense to drop all arguments
starting at the optional \emph{flags} argument from the definition.
The \TeX{} parsing mechanism will then automatically
use the tokens following |\|\emph{name} including the optional size modifier.
If any of the encapsulated expression(s) are to be passed as
explicit arguments to |\|\emph{name},
one will have to find an alternative way to pass \emph{flags}.
However, it is possible to predefine \emph{flags}
which can be overridden by further \emph{flags} specified by the user.

The above declarations via |\delim...|
should be sufficient for most situations.
However, there is an even more flexible way to declare delimiter sets:
%
\[
|\DeclareMathDelimiterSet{\|\emph{name}|}[|\emph{narg}|]{|\emph{compositor}|}|
\]
%
The syntax of this command is equivalent to the one of |\newcommand|.
The difference is that the command |\|\emph{name} first looks
for the \emph{flags} argument as
described above in \secref{sec:inline}.
It remembers the desired size for evaluating
the macro expression \emph{compositor}.
Then it parses the arguments as if the command
was declared by |\newcommand|.

As usual, the macro expression \emph{compositor} contains the command arguments
specified by |#1|, |#2|, \ldots. Note that these should
be encapsulated in groups |{#1}|, |{#2}|, \ldots,
in order to prevent them from overwriting definitions
at the level of the current group.
It should also contain the desired math delimiters
specified by:
%
\[
\begin{aligned}
&|\selectdeliml|[|*|]|{|\emph{delim}|}|
\\
&|\selectdelim[|\emph{class}|]|[|*|]|{|\emph{delim}|}|
\\
&|\selectdelimr|[|*|]|{|\emph{delim}|}|
\end{aligned}
\]
%
The three commands must be in proper sequence
starting with |\selectdeliml| followed by arbitrarily many
|\selectdelim| and terminated by |\selectdelimr|.
The math classes \emph{class} and starred variants
are defined analogously to \secref{sec:inline}.
Here, the sizes are adjusted automatically
according to the previously specified modifier.

Picking out individual delimiters from a set
declared by |\DeclareMathDelimiterSet|
cannot be achieved automatically.
Instead, a selector method may be specified manually (where needed) by:
%
\[
\begin{aligned}
&|\DeclareMathDelimiterSel{\|\emph{name}|}|
\\
&|  {\selectdeliml{|\emph{l}|}|[|\||or\selectdelim{|\emph{m}|}|\ldots]|}|
\\
&|  {\selectdelimr{|\emph{r}|}}|
\end{aligned}
\]
%
As many intermediate delimiters as needed can be specified
at the end of the first argument; each one must start with `|\||or|'.

\makeatletter
For example, one might declare a set of double square brackets
$[\kern-0.06\big@size[*]\kern-0.06\big@size]$ using:
\makeatother
%
\[
\begin{aligned}
&|\DeclareMathDelimiterSet{\dsb}[1]|
\\
&|  {\selectdeliml{[}\kerndelim{-1.75}\selectdelim[o]{[}{#1}|
\\
&|  \selectdelim[o]{]}\kerndelim{-1.75}\selectdelimr{]}}|
\end{aligned}
\]
%
Here, the command |\kerndelim{-1.75}| reduces the spacing
between the two square brackets by approximately 1.75\,mu in default size.
This could be used for:
%
\[
\makeatletter
|\dsb^4{\dsb^3{\dsb^2{\dsb^1{\dsb{*}}}}}|
\to
\Biggl[\kern-0.20\big@size\Biggl[
\biggl[\kern-0.16\big@size\biggl[
\Bigl[\kern-0.12\big@size\Bigl[
\bigl[\kern-0.08\big@size\bigl[
[\kern-0.06\big@size[*
]\kern-0.06\big@size]
\bigr]\kern-0.08\big@size\bigr]
\Bigr]\kern-0.12\big@size\Bigr]
\biggr]\kern-0.16\big@size\biggr]
\Biggr]\kern-0.20\big@size\Biggr],
\quad
|\dsb*|\ldots\to
\left[\kern-0.12\big@size\middle[\frac{x}{y}
\middle]\kern-0.12\big@size\right]
\makeatother
\]
%
An appropriate selector method for displaying individual
delimiters reads:
%
\[
\begin{aligned}
&|\DeclareMathDelimiterSel{\dsb}|
\\
&|  {\selectdeliml{[}\kerndelim{-1.75}\selectdelim[o]{[}}|
\\
&|  {\selectdelim[o]]\kerndelim{-1.75}\selectdelimr{]}}|
\end{aligned}
\]

Finally, towards a very flexible manual composition
of delimiter sets, there is the macro:
%
\[
|\parsedelimflags{|\emph{compositor}|}{|\emph{selector}|}|\emph{flags}
\]
%
It parses the modifier flags as described in \secref{sec:flags}.
The argument \emph{compositor} is code that displays the
composited delimiter set whereas \emph{selector} is a macro
that displays the delimiter number |\selecteddelim| of the set.
The \emph{flags} follow immediately and should be terminated by
an opening brace `|{|', the terminating flag `|.|'
or a delimiter selection flag.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Default Declarations}
\label{sec:defaultcommands}

The package predefines four commonly used sets of delimiters:
%
\begin{itemize}
\item
|\brk[|\emph{type}|]|\emph{flags}|{|\emph{expr}|}| represents
a standard bracket around a single expression \emph{expr}.
The type of bracket can be specified by the optional
argument \emph{type}:
%
\[
\text{\emph{empty} or |[r]|: round }(x),\quad
\text{|[s]|: square }[x],\quad
\text{|[c]|: curly }\{x\},\quad
\text{|[a]|: angle }\langle x\rangle
\]
%
\item
|\eval[|\emph{type}|]|\emph{flags}|{|\emph{expr}|}| represents
evaluation of a functional expression \emph{expr}.
The type of bracket can be specified by the optional
argument \emph{type}:
%
\[
\text{\emph{empty} or |[v]|: }f(x)\vert_{a},\qquad
\text{|[s]|: }[f(x)]_{a}^{b}
\]
%
\item
|\abs|\emph{flags}|{|\emph{expr}|}| represents
the absolute value $\lvert\emph{expr}\rvert$.
\item
|\norm|\emph{flags}|{|\emph{expr}|}| represents
the norm $\lVert\emph{expr}\rVert$.
\end{itemize}
%
The above definitions can be suppressed by
setting the package option |stddef| to |false|,
see \secref{sec:packageoptions}.
The package also defines some extended sets of delimiters as follows:
%
\begin{itemize}
\item
|\pair|\emph{flags}|{|\emph{expr1}|}{|\emph{expr2}|}| represents
a pair(ing) $(\emph{expr1},\emph{expr2})$.
\item
|\set|\emph{flags}|{|\emph{expr}|}| represents
the set $\{\emph{expr}\}$.
\item
|\setcond|\emph{flags}|{|\emph{expr}|}{|\emph{cond}|}| represents
a set with condition $\{\emph{expr}\vert\emph{cond}\}$.
\item
|\intv[|\emph{type}|]|\emph{flags}|{|\emph{expr1}|}{|\emph{expr2}|}| represents
an interval from \emph{expr1} to \emph{expr2}.
The in/\hspace{0pt}exclusion of the bounds can be specified by the optional
argument \emph{type}:
%
\[
\text{\emph{empty} or |[c]|: closed }[a,b],\qquad
\text{|[o]|: open }]a,b[,\qquad
\begin{array}{l}
\text{|[l]|: left-open }]a,b]
\\
\text{|[r]|: right-open }[a,b[
\end{array}
\]
%
\item
|\avg|\emph{flags}|{|\emph{expr}|}| represents
some average $\langle\emph{expr}\rangle$.
\item
|\corr|\emph{flags}|{|\emph{expr}|}| represents
some correlator $\langle\emph{expr}\rangle$.
\item
|\comm|\emph{flags}|{|\emph{expr1}|}{|\emph{expr2}|}| represents
the commutator $[\emph{expr1},\emph{expr2}]$.
\item
|\acomm|\emph{flags}|{|\emph{expr1}|}{|\emph{expr2}|}| represents
the anti-commutator $\{\emph{expr1},\emph{expr2}\}$.
\item
|\bra|\emph{flags}|{|\emph{expr}|}| represents
a bra-vector $\langle\emph{expr}\rvert$ in quantum mechanics.
\item
|\ket|\emph{flags}|{|\emph{expr}|}| represents
a ket-vector $\lvert\emph{expr}\rangle$ in quantum mechanics.
\item
|\braket|\emph{flags}|{|\emph{expr1}|}{|\emph{expr2}|}| represents
a bra-ket contraction $\langle\emph{expr1}\vert\emph{expr2}\rangle$.
\item
|\lfrac[|\emph{type}|]|\emph{flags}|{|\emph{expr1}|}{|\emph{expr2}|}| describes
the linear representation $\emph{expr1}/\emph{expr2}$ of a fraction.
An optional argument \emph{type} taking values |[r]|, |[s]|, |[c]|, |[a]|
encloses the fraction in round, square, curly or angle brackets as for |\brk|.
\end{itemize}
%
The extended definitions need to be activated by
the package option |extdef|, see \secref{sec:packageoptions}.

If the representations of the above delimiters do not suit the purpose
or taste of the user, they can be redefined with |\renewcommand|.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Auxiliary Commands}
\label{sec:auxcommands}

In addition to the |\bigl|, |\bigr| and |\bigm| commands
(as well as their |\Big.|, |\bigg.| and |\Bigg.| counterparts),
the package defines three additional sets |\bigp|, |\bigb| and |\bigi|
(and counterparts).
Here |\bigp| implies the math class |\mathpunct|,
|\bigb| the class |\mathbin| and |\bigi| the class |\mathinner|.

Furthermore, the package overloads the size calculation in the |\big...|
commands to properly account for the math styles in sub/superscripts
(|\scriptstyle|) and nested sub/\hspace{0pt}superscripts (|\scriptscriptstyle|).
The latter behaviour can be controlled by
the package option |scriptstyle|, see \secref{sec:packageoptions}.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Package Options}
\label{sec:packageoptions}

Options can be passed to the package by:
%
\[
|\usepackage[|\emph{opts}|]{delimset}|
\qquad
\text{or}
\qquad
|\PassOptionsToPackage{|\emph{opts}|}{delimset}|
\]
%
Here \emph{opts} is a comma-separated list of the available options:
%
\begin{itemize}
\item
|stddef|[|=true|\textbar|false|]
controls the activation of standard delimiter definitions specified in
\secref{sec:defaultcommands}.
If no value is given |true| is assumed; initially set to |true|.
\item
|extdef|[|=true|\textbar|false|]
controls the activation of extended delimiter definitions specified in
\secref{sec:defaultcommands}.
If no value is given |true| is assumed; initially set to |false|.
\item
|scriptstyle|[|=true|\textbar|false|]
controls the overwriting of size modifiers explained
in \secref{sec:auxcommands}.
If no value is given |true| is assumed; initially set to |true|.
\end{itemize}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Information}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Copyright}

Copyright \copyright{} 2016--2025 Niklas Beisert

This work may be distributed and/or modified under the
conditions of the \LaTeX{} Project Public License, either version 1.3
of this license or (at your option) any later version.
The latest version of this license is in
  \url{https://www.latex-project.org/lppl.txt}
and version 1.3 or later is part of all distributions of \LaTeX{}
version 2005/12/01 or later.

This work has the LPPL maintenance status `maintained'.

The Current Maintainer of this work is Niklas Beisert.

This work consists of the files |README.txt|, |delimset.ins| and |delimset.dtx|
as well as the derived files |delimset.sty|, |dlmssamp.tex| and |delimset.pdf|.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Files and Installation}

The package consists of the files
%
\begin{center}
\begin{tabular}{ll}
    |README.txt|   & readme file \\
    |delimset.ins| & installation file \\
    |delimset.dtx| & source file \\
    |delimset.sty| & package file \\
    |dlmssamp.tex| & sample file \\
    |delimset.pdf| & manual
\end{tabular}
\end{center}
%
The distribution consists of the files
|README.txt|, |delimset.ins| and |delimset.dtx|.
%
\begin{itemize}
\item
Run (pdf)\LaTeX{} on |delimset.dtx|
to compile the manual |delimset.pdf| (this file).
\item
Run \LaTeX{} on |delimset.ins| to create the package |delimset.sty|
and the sample |dlmssamp.tex|.
Copy the file |delimset.sty| to an appropriate directory of your \LaTeX{}
distribution, e.g.\ \textit{texmf-root}|/tex/latex/delimset|.
\end{itemize}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Interaction with CTAN Packages}

The package is related to other packages available at CTAN:
\begin{itemize}
\item
Compatibility with the \ctanpkg{amsmath} package
has been tested with v2.15d (2016/06/28) and v2.17t (2024/11/05).
\item
This package uses the package \ctanpkg{keyval} from the
\ctanpkg{graphics} bundle to process optional arguments to the package options.
Compatibility with the \ctanpkg{keyval} package
has been tested with v1.15 (2014/10/28).
\item
The package \ctanpkg{icomma} modifies the spacing behaviour
of the comma character in math mode
which leads to inadequate spacing when it is used as a middle delimiter.
To achieve proper spacing in sample code,
use |{[p]*,}| rather than |{*,}|.
The extended commands |\intv|, |\comm|, |\acomm| and |\pair|
are compatible with the \ctanpkg{icomma} package
has been tested with v2.0+ (2002/03/10).
\end{itemize}
%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%\subsection{Feature Suggestions}

% make optional arguments work for DeclareMathDelimiterSet?
%  (must go before parsing, but how to process and react?)
% make unadjusted size have right height
% automatic nesting of bracket types? -> depth stack?
% handle cramped style properly (perhaps impossible)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Revision History}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\iffalse
\paragraph{vN.N.N+:} 20YY/MM/NN

\begin{itemize}
\item
\ldots
\end{itemize}
\fi

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\paragraph{v2.2.1:} 2025/03/25

\begin{itemize}
\item
maintenance and manual update
\end{itemize}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\paragraph{v2.2:} 2025/02/27

\begin{itemize}
\item
replicate the \ctanpkg{amsmath} mechanism for tracking the
vertical height of a default delimiter in order to
be independent of \ctanpkg{amsmath}
\end{itemize}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\paragraph{v2.1:} 2025/01/05

\begin{itemize}
\item
the flags `|[|' and `|]|' now implement a register stack
for convenient individual access to nested delimiter sets
\item
syntax of |\usedelim| extended for direct access to top of register stack
\end{itemize}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\paragraph{v2.0:} 2024/07/17

\begin{itemize}
\item
option to display individual delimiters
and to store them in global registers across blocks
(columns, lines, etc.)
\item
more general handling of unadjusted-size delimiters
\item
more general size adjustments
\item
added inner math class for intermediate delimiters
\item
added flag to enclose by open/close and inner math class
\item
added flag to display phantom delimiters
\item
selected size accessible by |\delimsize|
and add proportional kerning by |\kerndelim|.
\item
added extended definition |\lfrac| for plain inline fractions
\item
null delimiter now properly has zero width for variable size
\item
internal mechanisms revised
\item
compatibility with \ctanpkg{icomma} package
(thanks to Olivier Godin for pointing out the issue)
\end{itemize}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\paragraph{v1.1:} 2018/12/30

\begin{itemize}
\item
classes added, class and size selection mechanism simplified
\end{itemize}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\paragraph{v1.01:} 2018/01/17

\begin{itemize}
\item
manual rearranged
\end{itemize}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\paragraph{v1.0:} 2016/11/01

\begin{itemize}
\item
extended standard definitions
\item
manual and installation package added
\item
first version published on CTAN
\end{itemize}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\paragraph{v0.5--0.7:} 2016/05/08 -- 2016/09/04

\begin{itemize}
\item
basic functionality
\item
standard definitions
\end{itemize}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\appendix

\settowidth\MacroIndent{\rmfamily\scriptsize 000\ }

 \DocInput{delimset.dtx}

\end{document}
%</driver>
% \fi
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \section{Sample File}
%\iffalse
%<*sample>
%\fi
%
% In this section we provide a \LaTeX{} example how to use
% some of the \ctanpkg{delimset} features.
%
% Preamble and beginning of document body:
%
%    \begin{macrocode}
\documentclass[12pt]{article}

\usepackage[margin=2cm]{geometry}
\usepackage{amsfonts}
\usepackage{delimset}

\begin{document}
%    \end{macrocode}

sizes for default brackets:
%    \begin{macrocode}
\[
\brk^0{x},\quad
\brk^1{x},\quad
\brk^2{x},\quad
\brk^3{x},\quad
\brk^4{x}
\]
%    \end{macrocode}

styles for default brackets:
%    \begin{macrocode}
\[
\brk[r]{x},\quad
\brk[s]{x},\quad
\brk[c]{x},\quad
\brk[a]{x}
\]
%    \end{macrocode}

nested brackets:
%    \begin{macrocode}
\[
\brk[c]^2{\brk[s]!{\brk{ax+b}x+c}x+d}
\]
%    \end{macrocode}

default absolute value, norm and default evaluations:
%    \begin{macrocode}
\[
\abs*{\frac{ax+b}{cx+d}},\qquad
\norm*{\frac{ax+b}{cx+d}},\qquad
\eval*{\frac{ax+b}{cx+d}}_{x=0},\qquad
\eval[s]*{\frac{ax+b}{cx+d}}_{x=0}^{x=\infty}
\]
%    \end{macrocode}

outer delimiter spacing:
%    \begin{macrocode}
\[\begin{array}{ll}
\square\brk^0{x}\square,&\square\brk^1{A^k}\square,
\\
\square\brk*{x}\square,&\square\brk*{A^k}\square
\end{array}\]
%    \end{macrocode}

delimiter sizes in exponents:
%    \begin{macrocode}
\[
e^{\brk{ax+b}},\qquad
e^{\brk!{ax+b}}
\]
%    \end{macrocode}

delimiter declaration:
%    \begin{macrocode}
\DeclareMathDelimiterSet{\braket}[2]
  {\selectdeliml<#1\selectdelim|#2\selectdelimr>}
\[
\braket!{\psi}{\psi},
\quad
\braket*{\psi}{\psi\big.}
\]
%    \end{macrocode}

delimiter usage:
%    \begin{macrocode}
\[
\delimpair<|>!{\psi}{\psi}
\]
%    \end{macrocode}

conditional set, alternative layouts:
%    \begin{macrocode}
\[
\delimpair\{{[m]|}\}!{2n}{n\in\mathbb{Z}},
\quad
\delimpair\{{[b]|}\}!{2n}{n\in\mathbb{Z}},
\quad
\delimpair\{{[i]|}\}!{2n}{n\in\mathbb{Z}},
\quad
\delimpair\{{[p]|}\}!{2n}{n\in\mathbb{Z}},
\quad
\delimpair\{|\}!{2n}{n\in\mathbb{Z}},
\quad
\delimpair\{{*;}\}!{2n}{n\in\mathbb{Z}}
\]
conditional set, alternative layouts with variable size:
\[
\delimpair\{{[m]|}\}*{2n}{n\in\mathbb{Z}\big.},
\quad
\delimpair\{{[b]|}\}*{2n}{n\in\mathbb{Z}\big.},
\quad
\delimpair\{{[i]|}\}*{2n}{n\in\mathbb{Z}\big.},
\quad
\delimpair\{{[p]|}\}*{2n}{n\in\mathbb{Z}\big.},
\quad
\delimpair\{|\}*{2n}{n\in\mathbb{Z}\big.},
\quad
\delimpair\{{*;}\}*{2n}{n\in\mathbb{Z}\big.}
\]
%    \end{macrocode}

delimiter definition:
%    \begin{macrocode}
\newcommand{\comm}{\delimpair[{*,}]}
\[
\comm!{\comm{A}{B}}{C}
+\comm!{\comm{B}{C}}{A}
+\comm!{\comm{C}{A}}{B}
=0
\]
%    \end{macrocode}

alternative representation:
%    \begin{macrocode}
\renewcommand{\comm}{\delimpair[{*;}]}
\[
\comm!{\comm{A}{B}}{C}
+\comm!{\comm{B}{C}}{A}
+\comm!{\comm{C}{A}}{B}
=0
\]
%    \end{macrocode}

display individual delimiters of a set with nesting:
%    \begin{macrocode}
\renewcommand{\braket}{\delimpair<|>}
\[
\braket{A}{B}
\to \braket( A \braket| B \braket),
\quad
\braket*( A\big. \braket*| B_{} \braket*),
\quad
\braket^1( A \braket^3| B \braket^2),
\quad
\braket^2[ \brk[s]^1[ A \brk] \usedelim| B \usedelim]
\]
%    \end{macrocode}

placing indices before a bracket
(does not work in variable-size mode because
the final size is not available for the enclosed expressions):
%    \begin{macrocode}
\DeclareMathDelimiterSet{\quadindex}[5]
  {\selectdeliml.^{#2}_{#3}\mathord{}\selectdelim[o][
  {#1}\selectdelim[o]]^{#4}_{#5}\selectdelimr.}
\[
\quadindex^2{\frac{x}{y}}{1}{2}{3}{4}
\]
%    \end{macrocode}

% End of document body:
%    \begin{macrocode}
\end{document}
%    \end{macrocode}
%\iffalse
%</sample>
%\fi
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \section{Implementation}
%\iffalse
%<*package>
%\fi
%
% In this section we describe the package |delimset.sty|.

% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \paragraph{Required Packages.}
%
% The package loads the package \ctanpkg{keyval} if not yet present.
% \ctanpkg{keyval} is used for extended options processing.
%
%    \begin{macrocode}
\RequirePackage{keyval}
%    \end{macrocode}

% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \paragraph{Package Options.}
%
% The package has some boolean \ctanpkg{keyval} options
% which can be set to |true| or |false|.
%
%    \begin{macrocode}
\newif\ifdlm@std\dlm@stdtrue
\newif\ifdlm@ext\dlm@extfalse
\newif\ifdlm@script\dlm@scripttrue

\def\dlm@group{dlm@}
\define@key{\dlm@group}{stddef}[true]{\csname dlm@std#1\endcsname}
\define@key{\dlm@group}{extdef}[true]{\csname dlm@ext#1\endcsname}
\define@key{\dlm@group}{scriptstyle}[true]{\csname dlm@script#1\endcsname}

\DeclareOption*{\expandafter\setkeys\expandafter\dlm@group%
  \expandafter{\CurrentOption}}
\ProcessOptions
%    \end{macrocode}

% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \paragraph{Improved Size Adjustments.}
%
% Overwrite the \ctanpkg{amsmath} command |\bBigg@|
% to select the size according to the present math style
% (uses the \ctanpkg{amsmath} definitions |\@mathmeasure| and |\big@size|).
% This code is activated only if
% the package option |scriptstyle| is set to |true|.
%
%    \begin{macrocode}
\ifdlm@script
\ifdefined\bBigg@
\def\bBigg@choice#1#2#3#4{%
  {\@mathmeasure\z@{\nulldelimiterspace\z@}%
     {#1\left#4\vcenter to#3\dimexpr#2\big@size\relax{}\right.}%
   \box\z@}}
\def\bBigg@#1#2{\leavevmode@ifvmode{\mathchoice%
  {\bBigg@choice{\displaystyle}{1}{#1}{#2}}%
  {\bBigg@choice{\textstyle}{1}{#1}{#2}}%
  {\bBigg@choice{\scriptstyle}{0.7}{#1}{#2}}%
  {\bBigg@choice{\scriptscriptstyle}{0.5}{#1}{#2}}}}
\fi
\fi
%    \end{macrocode}

% Define punctuation marks (|\bigp|, etc.),
% binary operators (|\bigb|, etc.)
% and inner class (|\bigi|, etc.).
%
%    \begin{macrocode}
\providecommand{\bigp}{\mathpunct\big}
\providecommand{\Bigp}{\mathpunct\Big}
\providecommand{\biggp}{\mathpunct\bigg}
\providecommand{\Biggp}{\mathpunct\Bigg}
\providecommand{\bigb}{\mathbin\big}
\providecommand{\Bigb}{\mathbin\Big}
\providecommand{\biggb}{\mathbin\bigg}
\providecommand{\Biggb}{\mathbin\Bigg}
\providecommand{\bigi}{\mathinner\big}
\providecommand{\Bigi}{\mathinner\Big}
\providecommand{\biggi}{\mathinner\bigg}
\providecommand{\Biggi}{\mathinner\Bigg}
%    \end{macrocode}

% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \paragraph{Size Adjustment Definitions.}
%
% Replicate the \ctanpkg{amsmath} implementation for
% tracking the vertical size of a default delimiter in the current font.
% Our |\dlm@size| matches with |\big@size| in \ctanpkg{amsmath}
% which is 1.2 times the vertical size of `(':
%    \begin{macrocode}
\newlength\dlm@size
%    \end{macrocode}
% The macros |\dlm@size@setchar| and |\dlm@size@scan|
% scan the font and code point
% in unicode (xetex/luatex) vs.\ \TeX\ (etex) engines:
%    \begin{macrocode}
\ifdefined\Umathcharnumdef
  \def\dlm@size@setchar{\Umathcharnumdef\dlm@size@char\Umathcodenum`\(\relax}
  \def\dlm@size@scan#1"#2"#3"#4\relax{\dlm@size@get{#3}{#4}}
\else
  \def\dlm@size@setchar{\mathchardef\dlm@size@char\mathcode`\(\relax}
  \def\dlm@size@scan#1"#2#3#4\relax{\dlm@size@get{#3}{#4}}
\fi
%    \end{macrocode}
% The macro |\dlm@size@get| computes 1.2 times the vertical height of `(':
%    \begin{macrocode}
\def\dlm@size@get#1#2{%
  \dlm@size\fontcharht\textfont"#1"#2\relax%
  \advance\dlm@size\fontchardp\textfont"#1"#2\relax%
  \global\dlm@size1.2\dlm@size}
%    \end{macrocode}
% The macro |\dlm@size@reset| updates |\dlm@size|:
%    \begin{macrocode}
\newcommand{\dlm@size@reset}{%
  \dlm@size@setchar\expandafter\dlm@size@scan\meaning\dlm@size@char\relax}
%    \end{macrocode}
% We can hook onto the \ctanpkg{amsmath} mechanism if already present:
%    \begin{macrocode}
\ifdefined\big@size
\def\dlm@size{\big@size}
\else
\addto@hook\every@math@size{\dlm@size@reset}
\fi
%    \end{macrocode}

% The macro |\dlm@setvar| enables variable size,
% the macro |\dlm@setsize| sets a fixed size.
% Delimiter sizes are implented by |\dlm@big@|.
% The macro |\kerndelim| adds some kerning proportional
% to the chosen fixed size of the delimiters
% (the spacing is merely an approximation,
% and it does not actually scale for flexible size).
%
%    \begin{macrocode}
\newlength\delimsize
\newcommand{\dlm@setvar}{\let\dlm@ifvar\@firstoftwo\delimsize1.5\dlm@size}
\newcommand{\dlm@setsize}[1]{\let\dlm@ifvar\@secondoftwo%
  \delimsize#1\dlm@size\advance\delimsize\dlm@size\delimsize0.5\delimsize}
\newcommand{\dlm@setabssize}[1]{\let\dlm@ifvar\@secondoftwo\delimsize#1\relax}
\newcommand{\dlm@big@}[1]{{\mathchoice%
  {\dlm@big@choice\displaystyle{1}{#1}}%
  {\dlm@big@choice\textstyle{1}{#1}}%
  {\dlm@big@choice\scriptstyle{0.7}{#1}}%
  {\dlm@big@choice\scriptscriptstyle{0.5}{#1}}}}
\newcommand{\dlm@big@choice}[3]{\hbox{$\m@th\nulldelimiterspace\z@%
  #1\left#3\vcenter to#2\delimsize{}\right.$}}
\newcommand{\kerndelim}[1]{{\delimsize#1\delimsize%
  \mkern\muexpr1.2mu*\delimsize/\dlm@size\relax}}
%    \end{macrocode}

% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \paragraph{Math Classes Processing.}
%
% Define class selectors for fixed and unadjusted sizes.
%
%    \begin{macrocode}
\newcommand{\dlm@big}[2]{\dlm@plain{#1}{\dlm@big@#2}}
\newcommand{\dlm@plain}[2]{\dlm@class{#1}{\dlm@phantom{#2}}}
\newcommand{\dlm@class}[1]{\csname dlm@class@#1\endcsname}
\let\dlm@class@\@firstofone
\let\dlm@class@o\mathord
\let\dlm@class@c\mathord
\let\dlm@class@p\mathpunct
\let\dlm@class@i\mathinner
\let\dlm@class@b\mathbin
\let\dlm@class@m\mathrel
%    \end{macrocode}

% Define class selector for variable size.
% The macro |\dlm@var@null| removes the extra space from
% variable-size null delimiters
% (|\left.|, |\middle.| and |\right.| apply the value
% of |\nulldelimiterspace| only at the end of math processing,
% even across blocks).
% The macro |\dlm@var@kern| applies kerning unless in the script styles.
%
%    \begin{macrocode}
\newcommand{\dlm@var@null}[1]{\if.#1\kern-\nulldelimiterspace\fi}
\newcommand{\dlm@var@kern}[1]{\nonscript\mkern#1}
\newcommand{\dlm@var}[1]{\csname dlm@var@#1\endcsname}
\newcommand{\dlm@var@}[1]{\dlm@var@null#1\middle#1}
\let\dlm@var@o\dlm@var@
\let\dlm@var@c\dlm@var@
\newcommand{\dlm@var@p}[1]{\dlm@var@#1\dlm@var@kern\thinmuskip}
\newcommand{\dlm@var@i}[1]{\dlm@var@kern\thinmuskip%
  \dlm@var@#1\dlm@var@kern\thinmuskip}
\newcommand{\dlm@var@b}[1]{\dlm@var@kern\medmuskip%
  \dlm@var@#1\dlm@var@kern\medmuskip}
\newcommand{\dlm@var@m}[1]{\dlm@var@kern\thickmuskip%
  \dlm@var@#1\dlm@var@kern\thickmuskip}
%    \end{macrocode}

% Definitions for selecting outer math class
% |\mathopen|+|\mathclose| vs. |\mathinner|.
%
%    \begin{macrocode}
\newcommand{\dlm@open@i}{\mathinner{}\mathclose{}\mathopen}
\newcommand{\dlm@close@i}{\mathclose{}\mathopen{}\mathinner}
\newcommand{\dlm@inner@oc}{\mathopen{}\mathclose}
\newcommand{\dlm@enclose@openclose}{%
  \let\dlm@open\mathopen\let\dlm@close\mathclose\let\dlm@inner\dlm@inner@oc}
\newcommand{\dlm@enclose@inner}{%
  \let\dlm@open\dlm@open@i\let\dlm@close\dlm@close@i\let\dlm@inner\mathinner}
%    \end{macrocode}

% Definitions for selecting inline vs. block insertion.
%
%    \begin{macrocode}
\newcommand{\dlm@inline@l}[1]{\dlm@open{#1}}
\newcommand{\dlm@inline@r}[1]{\dlm@close{#1}}
\newcommand{\dlm@block@l}[1]{\dlm@inner\bgroup\mathopen{#1}}
\newcommand{\dlm@block@r}[1]{\mathclose{#1}\egroup}
\newcommand{\dlm@enclose@inline}{%
  \let\dlm@class@l\dlm@inline@l\let\dlm@class@r\dlm@inline@r}
\newcommand{\dlm@enclose@block}{%
  \let\dlm@class@l\dlm@block@l\let\dlm@class@r\dlm@block@r}
%    \end{macrocode}

% Opening and closing definitions.
%
%    \begin{macrocode}
\newcommand{\dlm@plain@l}[1]{\dlm@class@l{\dlm@phantom{#1}}}
\newcommand{\dlm@plain@r}[1]{\dlm@class@r{\dlm@phantom{#1}}}
\newcommand{\dlm@big@l}[1]{\dlm@plain@l{\dlm@big@#1}}
\newcommand{\dlm@big@r}[1]{\dlm@plain@r{\dlm@big@#1}}
\newcommand{\dlm@var@l}[1]{\dlm@inner\bgroup\dlm@var@null#1\left#1}
\newcommand{\dlm@var@r}[1]{\right#1\dlm@var@null#1\egroup}
\newcommand{\dlm@var@pl}[1]{\dlm@var@l.\mathopen{#1}}
\newcommand{\dlm@var@pr}[1]{\mathclose{#1}\dlm@var@r.}
%    \end{macrocode}

% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \paragraph{Delimiter Storage.}
%
% Macros for storing and retrieving delimiter types using global registers.
%
%    \begin{macrocode}
\newcount\dlm@reg@lvl
\dlm@reg@lvl\z@
\def\dlm@reg@dot{.}
\newcommand{\dlm@reg@set}[1]{\edef\dlm@reg@cur{#1}\ifx\dlm@reg@cur\dlm@reg@dot%
  \edef\dlm@reg@cur{\dlm@reg@dot\the\dlm@reg@lvl}\fi}
\newcommand{\dlm@reg@step}[1]{\global\advance\dlm@reg@lvl#1%
  \ifnum\dlm@reg@lvl<\z@\PackageError{delimset}{register stack exhausted}{}%
  \dlm@reg@lvl\z@\fi}
\newcommand{\dlm@reg@save@init}[1]{%
  \xdef#1{\delimsize\the\delimsize}\ifx\dlm@inner\mathinner%
  \expandafter\gdef\expandafter#1\expandafter{#1\dlm@enclose@inner}\fi}
\newcommand{\dlm@reg@save}[2]{\dlm@reg@set{#1}%
  \expandafter\dlm@reg@save@init\csname dlm@reg@init@\dlm@reg@cur\endcsname%
  \expandafter\gdef\csname dlm@reg@sel@\dlm@reg@cur\endcsname{#2}}
\newcommand{\dlm@reg@init}[1]{\dlm@reg@set{#1}%
  \csname dlm@reg@init@\dlm@reg@cur\endcsname}
\newcommand{\dlm@reg@sel}{\csname dlm@reg@sel@\dlm@reg@cur\endcsname}
%    \end{macrocode}

% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \paragraph{Flags Processing.}
%
% The macro |\parsedelimflags| parses the optional argument(s)
% following |\delim|\ldots\ commands to adjust the presentation.
% Parsing is terminated if the next character in line begins a group (`|{|')
% and the delimiter set is composed by executing argument |#1|.
% A size flag is stored and parsing continues.
% A delimiter selector flag immediately displays the desired delimiter
% by executing argument |#2|.
% Unknown flags produce an error message.
%
%    \begin{macrocode}
\newcommand{\parsedelimflags}{\dlm@setsize{0.6}\let\dlm@phantom\@firstofone%
  \dlm@enclose@openclose\dlm@enclose@inline\dlm@parseflags}
\newcommand{\dlm@parseflags}[2]{%
  \@ifnextchar\bgroup{#1}{\dlm@parseflag{#1}{#2}}}
\newcommand{\dlm@parseflag}[3]{\begingroup%
  \ifcsname dlm@parseflag@\string#3\endcsname%
  \def\dlm@do{\csname dlm@parseflag@\string#3\endcsname{#1}{#2}}\else%
  \def\dlm@do{\PackageError{delimset}%
  {unknown delimiter set flag `\string#3'}{}#1}%
  \fi\expandafter\endgroup\dlm@do}
\newcommand{\dlm@parsedef}[3]{%
  \expandafter\def\csname dlm@parseflag@\string#1\endcsname ##1##2#2{#3}}
%    \end{macrocode}
%
% Note that the delimited expression should be contained within a group
% such that nested delimiters will not overwrite the outer size definition.

% Flags to adjust size.
% Note that sizes 0 and 1 amount to 0.96 and 1.2 times
% the current empty math box height.
%
%    \begin{macrocode}
\dlm@parsedef{!}{}{\dlm@setsize{1}\dlm@parseflags{#1}{#2}}
\dlm@parsedef{+}{}{\dlm@setsize{1}\dlm@parseflags{#1}{#2}}
\dlm@parsedef{0}{}{\dlm@setsize{0.6}\dlm@parseflags{#1}{#2}}
\dlm@parsedef{1}{}{\dlm@setsize{1}\dlm@parseflags{#1}{#2}}
\dlm@parsedef{2}{}{\dlm@setsize{2}\dlm@parseflags{#1}{#2}}
\dlm@parsedef{3}{}{\dlm@setsize{3}\dlm@parseflags{#1}{#2}}
\dlm@parsedef{4}{}{\dlm@setsize{4}\dlm@parseflags{#1}{#2}}
\dlm@parsedef{^}{#3}{\dlm@setsize{#3}\dlm@parseflags{#1}{#2}}
\dlm@parsedef{_}{#3}{\dlm@setabssize{#3}\dlm@parseflags{#1}{#2}}
\dlm@parsedef{*}{}{\dlm@setvar\dlm@parseflags{#1}{#2}}
%    \end{macrocode}

% Flags to select individual delimiters.
%
%    \begin{macrocode}
\dlm@parsedef{(}{}{\def\selecteddelim{0}#2}
\dlm@parsedef{|}{}{\def\selecteddelim{1}#2}
\dlm@parsedef{,}{}{\def\selecteddelim{1}#2}
\dlm@parsedef{)}{}{\def\selecteddelim{9}#2}
\dlm@parsedef{?}{#3}{\def\selecteddelim{#3}#2}
%    \end{macrocode}

% Flags to access registers.
%
%    \begin{macrocode}
\dlm@parsedef{[}{}{\dlm@reg@step\@ne\dlm@reg@save\dlm@reg@dot{#2}%
  \def\selecteddelim{0}#2}
\dlm@parsedef{]}{}{\dlm@reg@init\dlm@reg@dot\dlm@reg@step\m@ne%
  \def\selecteddelim{9}\dlm@reg@sel}
\dlm@parsedef{>}{#3}{\dlm@reg@save{#3}{#2}}
\dlm@parsedef{<}{#3}{\dlm@reg@init{#3}\dlm@parseflags%
  {\PackageError{delimset}{must select delimiter}{}}{\dlm@reg@sel}}
%    \end{macrocode}

% Further flags.
%
%    \begin{macrocode}
\dlm@parsedef{.}{}{#1}
\dlm@parsedef{:}{}{\dlm@enclose@block\dlm@parseflags{#1}{#2}}
\dlm@parsedef{'}{}{\dlm@enclose@openclose\dlm@parseflags{#1}{#2}}
\dlm@parsedef{"}{}{\dlm@enclose@inner\dlm@parseflags{#1}{#2}}
\dlm@parsedef{-}{}{\let\dlm@phantom\phantom\dlm@parseflags{#1}{#2}}
%    \end{macrocode}

% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \paragraph{Delimiter Display.}
%
% The command |\selectdelim| reproduces the delimiter in argument |#2|
% using the math class given in argument |#1| and the previously stored size.
% If the class identifier is `|.|', just return the delimiter argument as is.
% The commands |\selectdeliml| and |\selectdelimr|
% implement the left and right delimiter classes, respectively.
%
%    \begin{macrocode}
\newcommand{\selectdelim}[1][]{\begingroup\def\dlm@do{\@ifstar{\dlm@plain{#1}}%
  {\dlm@ifvar{\dlm@var{#1}}{\dlm@big{#1}}}}%
  \if.#1\let\dlm@do\@empty\fi\expandafter\endgroup\dlm@do}
\newcommand{\selectdeliml}{\@ifstar%
  {\dlm@ifvar\dlm@var@pl\dlm@plain@l}{\dlm@ifvar\dlm@var@l\dlm@big@l}}
\newcommand{\selectdelimr}{\@ifstar%
  {\dlm@ifvar\dlm@var@pr\dlm@plain@r}{\dlm@ifvar\dlm@var@r\dlm@big@r}}
%    \end{macrocode}

% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \paragraph{Declaration of New Delimiter Commands.}
%
% The macro |\DeclareMathDelimiterSet| declares a new set of delimiters
% as the macro `|\|\emph{name}'.
% This macro checks for optional flags and stores the desired size.
% It then passes on to a second macro `|\dlm@dcl@|\emph{name}',
% which takes the actual code.
% If the flags select an individual delimiter,
% the macro `|\dlm@sel@|\emph{name}' is called instead.
% The latter macro should be defined via |\DeclareMathDelimiterSel|
% such that it produces the desired delimiter number |\selecteddelim|.
%
%    \begin{macrocode}
\newcommand{\DeclareMathDelimiterSet}[1]{\expandafter\dlm@declare%
  \csname dlm@dcl@\expandafter\@gobble\string#1\endcsname{#1}}
\def\dlm@declare#1#2{\expandafter\dlm@declare@%
  \csname dlm@sel@\expandafter\@gobble\string#2\endcsname{#1}{#2}}
\def\dlm@declare@#1#2#3{\newcommand{#3}{\parsedelimflags{#2}{#1}}%
  \providecommand{#1}{}\newcommand{#2}}
\newcommand{\DeclareMathDelimiterSel}[3]{\expandafter\def%
  \csname dlm@sel@\expandafter\@gobble\string#1\endcsname%
  {\ifcase\selecteddelim#2\else#3\fi}}
%    \end{macrocode}

% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \paragraph{Inline Delimiter Declarations.}
%
% Inline declaration for delimiters via |\delim...|.
% The following code is similar to the one produced by
% |\DeclareMathDelimiterSet|, but the delimiter arguments
% are processed \emph{before} the optional size modifier.
%
% |\delim| is used for a single delimited expression.
%
%    \begin{macrocode}
\newcommand{\delim}[2]{%
  \parsedelimflags{\dlm@dcl@delim{#1}{#2}}{\dlm@sel@delim{#1}{#2}}}
\newcommand{\dlm@dcl@delim}[3]{%
  \selectdeliml#1{#3}\selectdelimr#2}
\newcommand{\dlm@sel@delim}[2]{\ifcase\selecteddelim\selectdeliml#1%
  \else\selectdelimr#2\fi}
%    \end{macrocode}

% |\delimpair| is used for two delimited expressions separated
% by an intermediate delimiter.
%
%    \begin{macrocode}
\newcommand{\delimpair}[3]{%
  \parsedelimflags{\dlm@dcl@delimpair{#1}{#2}{#3}}%
  {\dlm@sel@delimpair{#1}{#2}{#3}}}
\newcommand{\dlm@dcl@delimpair}[5]{%
  \selectdeliml#1{#4}\selectdelim#2{#5}\selectdelimr#3}
\newcommand{\dlm@sel@delimpair}[3]{\ifcase\selecteddelim\selectdeliml#1%
  \or\selectdelim#2\else\selectdelimr#3\fi}
%    \end{macrocode}

% |\delimtriple| is used for three delimited expressions separated
% by two intermediate delimiters.
%
%    \begin{macrocode}
\newcommand{\delimtriple}[4]{%
  \parsedelimflags{\dlm@dcl@delimtriple{#1}{#2}{#3}{#4}}%
  {\dlm@sel@delimtriple{#1}{#2}{#3}{#4}}}
\newcommand{\dlm@dcl@delimtriple}[7]{%
  \selectdeliml#1{#5}\selectdelim#2{#6}\selectdelim#3{#7}\selectdelimr#4}
\newcommand{\dlm@sel@delimtriple}[4]{\ifcase\selecteddelim\selectdeliml#1%
  \or\selectdelim#2\or\selectdelim#3\else\selectdelimr#4\fi}
%    \end{macrocode}

% |\usedelim| retrieves a stored delimiter type.
% The arguments `|]|', `|(|', `\textvert', `|,|', `|?|\emph{n}', `|)|'
% immediately select the delimiter using the stack register.
% Otherwise the desired register must be followed
% by the delimiter selection flag.
%
%    \begin{macrocode}
\newcommand{\usedelim}{%
  \@ifnextchar]{\parsedelimflags{}{}}{%
  \@ifnextchar({\parsedelimflags{}{}<.}{%
  \@ifnextchar|{\parsedelimflags{}{}<.}{%
  \@ifnextchar,{\parsedelimflags{}{}<.}{%
  \@ifnextchar){\parsedelimflags{}{}<.}{%
  \@ifnextchar?{\parsedelimflags{}{}<.}{%
  \parsedelimflags{}{}<}}}}}}}
%    \end{macrocode}

% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \paragraph{Standard Definitions.}
%
% Define some common delimiters (by |providecommand| so as not to
% overwrite previously existing commands).
% This code is activated only if the package option |stddef| is set to |true|.
%
%    \begin{macrocode}
\ifdlm@std
\providecommand{\brk}[1][r]{\begingroup\def\dlm@use{\delim()}%
  \if r#1\def\dlm@use{\delim()}\fi%
  \if s#1\def\dlm@use{\delim[]}\fi%
  \if c#1\def\dlm@use{\delim\{\}}\fi%
  \if a#1\def\dlm@use{\delim<>}\fi%
  \expandafter\endgroup\dlm@use}
\ifdefined\rvert
\providecommand{\eval}[1][v]{\begingroup\def\dlm@use{\delim.\rvert}%
  \if v#1\def\dlm@use{\delim.\rvert}\fi%
  \if s#1\def\dlm@use{\delim[]}\fi%
  \expandafter\endgroup\dlm@use}
\else
\providecommand{\eval}[1][v]{\begingroup\def\dlm@use{\delim.\vert}%
  \if v#1\def\dlm@use{\delim.\vert}\fi%
  \if s#1\def\dlm@use{\delim[]}\fi%
  \expandafter\endgroup\dlm@use}
\fi
\ifdefined\lvert
\providecommand{\abs}{\delim\lvert\rvert}
\else
\providecommand{\abs}{\delim\vert\vert}
\fi
\ifdefined\lVert
\providecommand{\norm}{\delim\lVert\rVert}
\else
\providecommand{\norm}{\delim\Vert\Vert}
\fi
\fi
%    \end{macrocode}

% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \paragraph{Extended Definitions.}
%
% Define some extended delimiters.
% This code is activated only if the package option |extdef| is set to |true|.
%
%    \begin{macrocode}
\ifdlm@ext
\providecommand{\pair}{\delimpair({[p]*,})}
\providecommand{\set}{\delim\{\}}
\providecommand{\setcond}{\delimpair\{|\}}
\providecommand{\intv}[1][c]{\begingroup%
  \def\dlm@use{\delimpair[{[p]*,}]}%
  \if c#1\def\dlm@use{\delimpair[{[p]*,}]}\fi%
  \if l#1\def\dlm@use{\delimpair]{[p]*,}]}\fi%
  \if r#1\def\dlm@use{\delimpair[{[p]*,}[}\fi%
  \if o#1\def\dlm@use{\delimpair]{[p]*,}[}\fi%
  \expandafter\endgroup\dlm@use}
\providecommand{\avg}{\delim<>}
\providecommand{\corr}{\delim<>}
\providecommand{\comm}{\delimpair[{[p]*,}]}
\providecommand{\acomm}{\delimpair\{{[p]*,}\}}
\providecommand{\bra}{\delim<|}
\providecommand{\ket}{\delim|>}
\providecommand{\braket}{\delimpair<|>}
\providecommand{\lfrac}[1][]{\begingroup%
  \def\dlm@use{\delimpair./.}%
  \if r#1\def\dlm@use{\delimpair(/)}\fi%
  \if s#1\def\dlm@use{\delimpair[/]}\fi%
  \if c#1\def\dlm@use{\delimpair\{/\}}\fi%
  \if a#1\def\dlm@use{\delimpair</>}\fi%
  \expandafter\endgroup\dlm@use}
\fi
%    \end{macrocode}

%\iffalse
%</package>
%\fi
%
\endinput
