5

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!

  • Since the only way to differentiate mds from nms (both have 3 arguments) is to force explicit use of the commas (or else the n=, m= style), is it your intent that a plain \norm invocation would be \norm[,,,]{}? That is to say, it would be helpful for us to see how you envision the invocation style for each of the 6 variations. – Steven B. Segletes Jun 16 '17 at 10:33
  • I am asking you to explicitly provide us a sample invocation that you would like have to produce the \normmds style, the \normnms style, etc. – Steven B. Segletes Jun 16 '17 at 10:39
  • im not sure i fully understand your question! for the plain norm ill just use the ordinary macro \norm defined above (with some renaming of course), so NO i guess. – cesare borgia Jun 16 '17 at 10:39
  • aha i see, so i don't know if its possible, but id like to have \normmds{u} W {p} {\Omega} as \norm[p,\Omega,W] {u} or if thats not possible as \norm[m=p,d=\Omega,s=W] {u} – cesare borgia Jun 16 '17 at 10:43
  • But how do I know that \norm[p,\Omega,W] {u} doesn't imply \norm[n=p,m=\Omega,s=W] {u}? They both have 3 arguments... – Steven B. Segletes Jun 16 '17 at 10:45
7

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.

  • merci monsieur! – cesare borgia Jun 16 '17 at 11:04
  • how would i make sense out of something like ` \ifx \norm@s m \mathcal L \fi? is this the right command to compare a key? or do i have to use \if \norm@s = W` or \ifx \norm@s @W – cesare borgia Jun 16 '17 at 12:34
  • 1
    @cesareborgia Define a command: \def\norm@param{m} and compare: \ifx\norm@s\norm@param ... s has value m ... \else ... otherwise ... \fi – Heiko Oberdiek Jun 16 '17 at 12:39
3

A listofitems approach to obtain the key values. Thanks to Heiko for the test tabular.

\documentclass{article}
\usepackage{listofitems,amsmath}
\newcommand{\normplain}[1]{\left\lVert #1 \right\rVert}
\newcommand\norm[2][\relax]{\normplain{#2}\ifx\relax#1\relax\else\normaux{#1}\fi}
\newcommand\normaux[1]{%
  \def\nnormdata{1}% DEFAULT
  \def\mnormdata{p}% DEFAULT
  \def\dnormdata{\relax}% DEFAULT
  \def\snormdata{W}% DEFAULT
  \setsepchar{,/=}%
  \readlist*\normdata{#1}%
  \foreachitem\x\in\normdata[]{%
    \expandafter\edef\csname\normdata[\xcnt,1]normdata\endcsname{\normdata[\xcnt,2]}%
  }%
  _{\snormdata^{\nnormdata,\mnormdata}\expandafter\ifx\dnormdata\relax\else(\dnormdata)\fi}
}
\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}

enter image description here

3

A flexible key-value interface, also with choice of size (avoid automatic \left and right):

\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand{\norm}{O{}m}
 {
  \group_begin:
  \keys_set:nn { cesareborgia/norm } { #1 }
  \cesareborgia_norm:n { #2 }
  \group_end:
 }

\keys_define:nn { cesareborgia/norm }
 {
  s .tl_set:N = \l_cesareborgia_norm_spc_tl,
  n .tl_set:N = \l_cesareborgia_norm_exp_tl,
  d .tl_set:N = \l_cesareborgia_norm_dom_tl,
  m .tl_set:N = \l_cesareborgia_norm_mlt_tl,
  size .tl_set:N = \l_cesareborgia_norm_size_tl,
 }

\cs_new_protected:Nn \cesareborgia_norm:n
 {
  \__cesareborgia_norm_lsize:V \l_cesareborgia_norm_size_tl
  #1
  \__cesareborgia_norm_rsize:V \l_cesareborgia_norm_size_tl
  \tl_if_empty:NF \l_cesareborgia_norm_spc_tl
   {
    \sb
     {
      \l_cesareborgia_norm_spc_tl
      \tl_if_empty:NF \l_cesareborgia_norm_exp_tl
       {
        \sp
         {
          \l_cesareborgia_norm_exp_tl
          \tl_if_empty:NF \l_cesareborgia_norm_mlt_tl
           {
            ,\l_cesareborgia_norm_mlt_tl
           }
         }
        \tl_if_empty:NF \l_cesareborgia_norm_dom_tl
         {
          (\l_cesareborgia_norm_dom_tl)
         }
       }
     }
   }
 }
\cs_new_protected:Nn \__cesareborgia_norm_lsize:n
 {
  \str_case:nnF { #1 }
   {
    {*}{\left}
    {}{}
   }
   { \use:c { #1l } }
  \|
 }
\cs_generate_variant:Nn \__cesareborgia_norm_lsize:n { V }
\cs_new_protected:Nn \__cesareborgia_norm_rsize:n
 {
  \str_case:nnF { #1 }
   {
    {*}{\right}
    {}{}
   }
   { \use:c { #1r } }
  \|
 }
\cs_generate_variant:Nn \__cesareborgia_norm_rsize:n { V }
\ExplSyntaxOff

\begin{document}

\begin{gather}
 \norm[n=1,m=p,d=\Omega,s=W]{u}+
 \norm[n=1,m=p,d=\Omega,s=W,size=Big]{u}+
 \norm[n=1,m=p,d=\Omega,s=W,size=*]{\dfrac{u}{2}}
\\
 \norm[n=1,m=p,s=W]{u}+
 \norm[size=big,n=1,m=p,s=W]{u}+
 \norm[size=*,n=1,m=p,s=W]{\dfrac{u}{2}}
\\
 \norm[n=1,s=W]{u}+
 \norm[n=1,s=W,size=bigg]{u}+
 \norm[n=1,s=W,size=*]{\dfrac{u}{2}}
\\
 \norm[n=1,s=W,d=\Omega]{u}+
 \norm[n=1,s=W,d=\Omega,size=Bigg]{u}+
 \norm[n=1,s=W,d=\Omega,size=*]{\dfrac{u}{2}}
\\
 \norm[s=W]{u}+
 \norm[s=W,size=big]{u}+
 \norm[s=W,size=*]{\dfrac{u}{2}}
\\
 \norm{u}+
 \norm[size=Bigg]{u}+
 \norm[size=*]{\dfrac{u}{2}}
\end{gather}

\end{document}

enter image description here

0

heres now what i had in mind! finally solved it thank you all guys!

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

\def\ks{w}
\def\kc{c}
\def\kh{h}
\def\km{m}


\usepackage{kvoptions}


\SetupKeyvalOptions{family=snorm, prefix=snorm@}
\DeclareStringOption{n}
\DeclareStringOption{m}
\DeclareStringOption{d}
\DeclareStringOption{s}


\makeatletter
\newcommand*{\snorm}[2][]{%
\begingroup
\kvsetkeys{snorm}{#1}%
\left \lVert #2\right \rVert
\ifnum0\ifx\snorm@m\@empty\else1\fi
       \ifx\snorm@n\@empty\else1\fi
       \ifx\snorm@d\@empty\else1\fi
       \ifx\snorm@s\@empty\else1\fi
       >0 %            
% sob   
      \ifx \snorm@s\ks %
        _{W^{%
            \ifx\norm@n\@empty 1\else\norm@n\fi,%
            \ifx\norm@m\@empty p\else\norm@m\fi
            } %
          \ifx\snorm@d\@empty %
          \else %
          (\snorm@d)%
          \fi %\ifx\snorm@d\@empty
          } %_{W^{     
       \fi %\ifx \snorm@s\ks
% cam    
      \ifx \snorm@s\kc %
        _{\mathcal L^{%
          \ifx\norm@n\@empty p\else\norm@n\fi,%
          \ifx\norm@m\@empty \lambda \else\norm@m\fi
          } %
          \ifx\snorm@d\@empty %
          \else %
          (\snorm@d)%
          \fi %\ifx\snorm@d\@empty
          } %_{\mathcal L^{ 
       \fi %\ifx \snorm@s\kc  
% hol
        \ifx\snorm@s \kh %
          _{C
            \ifnum0\ifx\snorm@m\@empty\else1\fi %
                \ifx\snorm@n\@empty\else1\fi =0 ^0 %
                \else %
                  \ifx\snorm@n\@empty %
                  ^{\snorm@m} %
                  \else %
                  ^{\snorm@n, \ifx\snorm@m\@empty \alpha\else\snorm@m\fi}%
                  \fi %
                \fi %\ifnum
            \ifx\snorm@d\@empty %
            \else %
            (\snorm@d)%
            \fi %\ifx\snorm@d\@empty
            } %_{C
        \fi % \ifx\snorm@s \kh
% mor
      \ifx \snorm@s\km 
        _{L^{%
            \ifx\norm@n\@empty 2\else\norm@n\fi,%
            \ifx\norm@m\@empty \mu \else\norm@m\fi
            } %    
          \ifx\snorm@d\@empty
          \else
          (\snorm@d)%
          \fi %\ifx\snorm@d\@empty
          } %_{L^{
       \fi %\ifx \snorm@s\km
    \fi %ifnum
  \endgroup
}
\makeatother 


\begin{document}
\def\test#1\\{%
  \texttt{\detokenize{#1}} & $#1$ \\%
}
\begin{tabular}{ll}
  \test\snorm{u}\\
  \test\snorm[n=1,s=w]{u}\\
  \test\snorm[n=1,s=h]{u}\\
  \test\snorm[n=2,s=h]{u}\\
  \test\snorm[d=\Omega,s=h]{u}\\
  \test\snorm[m=\alpha,s=h]{u}\\
  \test\snorm[n=n,s=m]{u}\\
  \test\snorm[m=p,s=c]{u}\\
  \test\snorm[m=m,s=c]{u}\\
  \test\snorm[n=n, m=m,s=w]{u}\\
  \test\snorm[s=c,d=\Omega]{u}\\
  \test\snorm[n=1, m=p, d=\Omega, s=c]{u}\\
  \test\snorm[n=n, m=m, d=d, s=m]{u}\\
\end{tabular}
\end{document}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.