3

The command \DeclarePairedDelimiter (from the mathtools package) allows to use the delimiter size commands \big,\Big,\bigg,\Bigg, and allows to define custom paired delimiters. For example, the macro\DeclarePairedDelimiter{\Paren}{\lparen}{\rparen} (which uses the mathtools commands \lparen and \rparen) allows to write expressions like \Paren[\Bigg]{x}, whose output is the letter "x" enclosed by the biggest parentheses (not a very interesting example of "custom" paired delimiters, of course).

However, sometimes one might want to invoke the custom opening and closing delimiters with independent commands: for example, I prefer this whenever the content between the delimiters is too long, like

\customleftdelimiter A very long math expression \customrightdelimiter

instead of

\customdelimiter{A very long long math expression}

In the mathtools user manual (version 2022/06/29), p. 28, one reads:

Note 2: If you want to define your own manual scaler macros, it is important that you besides \foo also define \fool and \foor. When a scaler is specified, in say \abs[\big]{〈arg〉}, we actually use \bigl and \bigr.

The problem is that no instructions are given to do this. Perhaps a DeclareOpeningDelimiter command exists, but it is not described in the mathtools documentation.

Question

How to define the \fool and \foor commands, in the spirit of the mathtools package?

Note: This is a rephrasing of a previous question I asked, which I deleted because it was mixed with another issue (I will ask a separate question about that).

5
  • you can not make scalable characters in tex, they are part of the font, any font package will give commands for the characters it provides, so there isn't a general answer to your question Mar 25 at 18:50
  • 2
    \abs[\big] is \bigl | A very long long math expression \bigr | is that what you are looking for? Mar 25 at 18:52
  • @DavidCarlisle I edited the question. Mar 25 at 20:30
  • I still can not guess what answer you want. if the character is available in the font, just use it, if it is not then you can not make one in tex. Mar 25 at 20:35
  • I think you're effectively asking the same as Difference between \big[ and \bigl[
    – Dai Bowen
    Mar 26 at 0:13

2 Answers 2

3

Here's a version that respects the nesting levels.

\documentclass{article}
\usepackage{mathtools}

\ExplSyntaxOn

\NewDocumentCommand{\definegenericpaired}{mmm}
 {% #1 = name, #2 = left delimiter, #3 = right delimiter
  \chibchas_lr_new:nnn { #1 } { #2 } { #3 }
 }

\int_new:N \g__chibchas_lr_nestlevel_int

\cs_new_protected:Nn \chibchas_lr_new:nnn
 {
  \ExpandArgs{c}\NewDocumentCommand{#1l}{so}
   {
    % store the star or the optional argument
    \tl_gclear_new:c { g__chibchas_lr_\int_to_arabic:n { \g__chibchas_lr_nestlevel_int }_tl }
    \IfBooleanTF{##1}
     {
      \tl_gset:cn { g__chibchas_lr_\int_to_arabic:n { \g__chibchas_lr_nestlevel_int }_tl } { \right }
     }
     {
      \IfNoValueF{##2}
       {
        \tl_gset:cn { g__chibchas_lr_\int_to_arabic:n { \g__chibchas_lr_nestlevel_int }_tl }
          { \use:c { \cs_to_str:N ##2 r } }
       }
     }
    % increase the nest level
    \int_gincr:N \g__chibchas_lr_nestlevel_int
    % deliver the left delimiter
    \IfBooleanTF{##1}
     { \left }
     { \IfNoValueF{##2} { \use:c { \cs_to_str:N ##2 l } } }
    #2
   }
  \ExpandArgs{c}\NewDocumentCommand{#1r}{}
   {
    % decrease the nest level
    \int_gdecr:N \g__chibchas_lr_nestlevel_int
    % deliver the right delimiter
    \tl_use:c { g__chibchas_lr_\int_to_arabic:n { \g__chibchas_lr_nestlevel_int }_tl } #3
   }
 }

\ExplSyntaxOff

\definegenericpaired{foo}{(}{)}
\definegenericpaired{baz}{[}{]}


\begin{document}

\[
\fool* \frac{1}{2} + \bazl[\Big] x + \fool y \foor - z \bazr - 1 \foor
\]

\end{document}

For each left delimiter, the requested size is saved in a global token list variable, so it can be used at the matching right delimiter. If you forget some, you're doomed…

enter image description here

1

You can use \customldel and \customrdel to define left and right delimiters. The left delimiter can take a parameter like \big in order to scale the delimiter and whatever right delimiter it is paired with.

You need to match up left and right delimiters (ie. every custom left delimiter must be paired with a custom right delimiter), but you can use the predefined \lempty and \rempty custom delimiters for null delimiters (\lempty can also be used to set the scale of whatever right delimiter it is paired with).

\documentclass{article}

\def\noscale#1{\ifx.#1 \else#1\fi}

\makeatletter
\def\mstrip{\expandafter\@gobble\string}
\let\customscale=\noscale
\def\customldel#1#2{%
    \expandafter\def\csname \mstrip#1@help\endcsname[##1]{%
        \begingroup%
        \edef\customscale{\expandafter\noexpand\csname \mstrip##1r\endcsname}%
        \csname \mstrip##1l\endcsname{#2}%
    }%
    \def#1{\@ifnextchar[ {\csname \mstrip#1@help\endcsname}%
                         {\begingroup\let\customscale=\noscale#2}}%
}

\def\customrdel#1#2{%
        \def#1{\customscale{#2}\endgroup}%
}
\makeatother

\begin{document}

\customldel{\lempty}.
\customrdel{\rempty}.
\customldel{\lcparen}(
\customrdel{\rcparen})

\[ \lempty[\bigg]\lcparen[\big] a\lcparen b\rempty c \rcparen\rcparen \]
\[ \bigl( a(b c \bigr) \biggr) \]

\end{document}

display custom delimiters

This works by storing the current amount of scale in a register \customscale, which is reverted after a custom right delimiter. \noscale is used in the case that there is no scaling, and it checks for the null delimiter (.) and prints if not.

1
  • You could of course use \newcommand with optional arguments instead of \def, but this was intended to be a plain TeX answer, I just didn't feel like defining \@ifnextchar
    – Slurp
    Mar 25 at 21:14

You must log in to answer this question.

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