[Tex/LaTex] function with optional arguments

macros

I have used TeX for some time, but never really 'coded' with it; please bear with me 😉

I'm currently writing something that involves a lot of different norms and I want to write a macro / function that eases up the TeX-ing.

I declared the standard macro

\newcommand{\norm}[1]{\left\lVert #1 \right\rVert}

Now instead of defining one macro for each norm I use

\newcommand{\norms}[2]{\norm{#1}_{W^{1,p}}}
\newcommand{\normds}[2]{\norm{#1}_{W^{1,p}(#2)}}
\newcommand{\normmds}[3]{\norm{#1}_{W^{1,#2}(#3)}}
\newcommand{\normnms}[3]{\norm{#1}_{W^{#2,#3}}}
\newcommand{\normnmds}[4]{\norm{#1}_{W^{#2,#3}(#4)}}

(where s signifies the space, ie. the W in the subscript,
d stands for domain so I mean $s(d)$, n stands for the first exponent in the subscript like $s^{n,m}(d)$)

I would like to have something like this:

\norm [n,m,d,s]{}

and now putting arguments:

\norm [1,p,\Omega,s]{u}

to yield \norm {u}_{W^{1,p}(\Omega)}

or

\norm [n=1,m=p,d=\Omega,s=W]{u}

to yield \norm {u}_{W^{1,p}(\Omega)}

I hope my question makes sense, if not, let me know!

Any help is much appreciated!

Best Answer

A key-value approach with keys n, m, d, s. If one of them is set, then the subscript appears. Then, default values are used for n (1), m (p) and s (W) if the key is not given.

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{amsmath}

\usepackage{kvoptions}
\SetupKeyvalOptions{family=norm, prefix=norm@}
\DeclareStringOption{n}
\DeclareStringOption{m}
\DeclareStringOption{d}
\DeclareStringOption{s}

\makeatletter
\newcommand*{\norm}[2][]{%
  \begingroup
    \kvsetkeys{norm}{#1}%
    \left\lVert#2\right\rVert
    \ifnum0\ifx\norm@m\@empty\else1\fi
           \ifx\norm@n\@empty\else1\fi
           \ifx\norm@d\@empty\else1\fi
           \ifx\norm@s\@empty\else1\fi
           >0 %
      _{%
        \ifx\norm@s\@empty W\else\norm@s\fi
        ^{%
          \ifx\norm@n\@empty 1\else\norm@n\fi,%
          \ifx\norm@m\@empty p\else\norm@m\fi
        }%
        \ifx\norm@d\@empty
        \else
          (\norm@d)%
        \fi
      }%
    \fi
  \endgroup
}
\makeatother

\begin{document}
\def\test#1\\{%
  \texttt{\detokenize{#1}} & $#1$ \\%
}
\begin{tabular}{ll}
  \test\norm{u}\\
  \test\norm[n=1]{u}\\
  \test\norm[n=n]{u}\\
  \test\norm[m=p]{u}\\
  \test\norm[m=m]{u}\\
  \test\norm[n=n, m=m]{u}\\
  \test\norm[d=\Omega]{u}\\
  \test\norm[n=1, m=p, d=\Omega, s=W]{u}\\
  \test\norm[n=n, m=m, d=d, s=s]{u}\\
\end{tabular}
\end{document}

Result

  • The \DeclareStringOption{foo} defines macro \norm@foo. It is \@empty, if the key is not used in the optional argument.

  • \kvsetkeys{norm}{#1} (also \setkeys can be used) is called inside a group to preserve the initial settings of the parameter macros \norm@....

  • I tried to get a useful algorithm and the default values from the definitions of the commands \norms and friends.