我已经使用 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
键值方法,键为n
、m
、d
、 。如果设置了其中一个,则会出现下标。然后,如果未指定键,则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
灵活的键值接口,也可以选择大小(避免自动\left
和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}
答案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}