带有可选参数的函数

带有可选参数的函数

我已经使用 TeX 有一段时间了,但从未真正用它“编写代码”;请忍耐一下 ;-)

我目前正在写一些涉及许多不同规范的东西,我想编写一个可以简化 TeX 操作的宏/函数。

我声明了标准宏

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

现在,我不再为每个规范定义一个宏,而是使用

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

(其中s表示空间,即W下标中的 d代表域,所以我的意思是$s(d)$n代表下标中的第一个指数,如$s^{n,m}(d)$

我想要这样的东西:

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

现在提出论点:

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

屈服\norm {u}_{W^{1,p}(\Omega)}

或者

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

屈服\norm {u}_{W^{1,p}(\Omega)}

我希望我的问题有意义,如果没有,请告诉我!

任何帮助深表感谢!

答案1

键值方法,键为nmd、 。如果设置了其中一个,则会出现下标。然后,如果未指定键,则s使用n( 1)、m( p) 和s( ) 的默认值。W

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

结果

  • 定义\DeclareStringOption{foo}宏。如果可选参数中未使用键,\norm@foo则为。\@empty

  • \kvsetkeys{norm}{#1}(也\setkeys可以使用)在组内部调用来保存参数宏的初始设置\norm@...

  • \norms我尝试从命令和朋友的定义中获取有用的算法和默认值。

答案2

listofitems获取键值的方法。感谢 Heiko 提供的测试表格。

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

在此处输入图片描述

答案3

灵活的键值接口,也可以选择大小(避免自动\leftright):

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

在此处输入图片描述

答案4

这就是我的想法!终于解决了,谢谢大家!

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

相关内容