我经常定义一个带有各种可选参数的宏,例如
\NewDocumentCommand{\GenericWebSite}{s O{blue} o m e_}{<code>}
并希望定义此宏的一个小变体,而不重复所有<code>
宏\GenericWebSite
。因此,例如,我想要定义
\NewDocumentCommand{\ImportantWebSite}{s o o m e_}{%
\fcolorbox{red}{gray!20}{<code>}%
}
蛮力方法(如下面的 MWE 所示)效果很好,但肯定有更简单的方法来做到这一点。
第一行是 的各种用途的输出\GenericWebSite
,第二行是传入\ImportantWebSite
相同参数的 的调用。
笔记:
\GenericWebSite
这个问题不是关于测试用例中定义的具体功能,而是一般的在 MWE 中定义一个新的xparse
宏,\ImportantWebSite
以便它可以利用现有的宏(\GenericWebSite
在本例中,该宏已经定义)。- 一个选项是传递键值标志,
\GenericWebSite
以便单身的宏可以提供所有功能。虽然在这个特定示例中,这当然是可行的,但我更愿意保留单独的宏,因为在实际用例中,我需要许多变体。
参考:
- 如何 \let 一个 xparse 定义命令?,
- xparse 中的可选参数:\IfBooleanTF 与 \IfNoValueTF
- Xparse 的新 e-type 参数(k-type 参数的替代)
- 如何在 PDF 中创建互联网链接?
代码:
\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}
\usepackage{xcolor}
\usepackage{hyperref}
\makeatletter
\newcommand*{\@DefaultWebLink}{http://tex.stackexchange.com}
\NewDocumentCommand{\GenericWebSite}{
s% * = text in #4 is already a link
O{blue}% #2 = color to use for text
o% #3 = web site to link to (Defaults to \@DefaultWebLink)
m% #4 = text to display
e_% #5 = optional subscript
}{%
\begingroup%% Keep \color{} change local
\color{#2}%
\IfBooleanTF{#1}{% no need to link web site as it is already a link
\textnormal{#4}
}{%
\IfNoValueTF{#3}{% web site to link to not provided, so use default
\href{\@DefaultWebLink}{\textnormal{#4}}%
}{% web site to link to provided
\href{#3}{\textnormal{#4}}%
}%
}%
\IfNoValueTF{#5}{}{% Include subscript since it was given
_{Note:\,#5}
}%
\endgroup
}
%% Want to make use of \GenericWebSite with some slight modifications
\NewDocumentCommand{\ImportantWebSite}{
s% * = text in #4 is already a link
o% #2 = color to use for text <--- NOTE that this does NOT have a default
o% #3 = web site to link to (Defaults to \@DefaultWebLink)
m% #4 = text to display
e_% #5 = optional subscript
}{%
\fcolorbox{red}{gray!20}{$
\IfBooleanTF{#1}{%
\IfValueTF{#2}{% #2 given so needs to be passed on
\IfValueTF{#3}{
\IfValueTF{#5}{
\GenericWebSite*[#2][#3]{#4}_{#5}
}{
\GenericWebSite*[#2][#3]{#4}
}
}{
\IfValueTF{#5}{
\GenericWebSite*[#2]{#4}_{#5}
}{
\GenericWebSite*[#2]{#4}
}
}
}{% No #2 given, so same as true case above but without the #2
\IfValueTF{#3}{
\IfValueTF{#5}{
\GenericWebSite*[#3]{#4}_{#5}
}{
\GenericWebSite*[#3]{#4}
}
}{% No #2 and #3 given, so same as true case above but without the #2 and #3
\IfValueTF{#5}{
\GenericWebSite*{#4}_{#5}
}{
\GenericWebSite*{#4}
}
}
}
}{% same as above but without the * option
\IfValueTF{#2}{% #2 given so needs to be passed on
\IfValueTF{#3}{
\IfValueTF{#5}{
\GenericWebSite[#2][#3]{#4}_{#5}
}{
\GenericWebSite[#2][#3]{#4}
}
}{
\IfValueTF{#5}{
\GenericWebSite[#2]{#4}_{#5}
}{
\GenericWebSite[#2]{#4}
}
}
}{% No #2 given, so same as true case above but without the #2
\IfValueTF{#3}{
\IfValueTF{#5}{
\GenericWebSite[#3]{#4}_{#5}
}{
\GenericWebSite[#3]{#4}
}
}{% No #2 and #3 given, so same as true case above but without the #2 and #3
\IfValueTF{#5}{
\GenericWebSite{#4}_{#5}
}{
\GenericWebSite{#4}
}
}
}
}%
$}%
}
\makeatother
\begin{document}
%% Testing various uses of \GenericWebSite
$\GenericWebSite{TeX.SE}$
$\GenericWebSite[red]{TeX.SE}$
$\GenericWebSite*[black]{\href{http://www.google.com}{The Google}}_4$
%% Testing various uses of \ImportantWebSite
\par\medskip
$\ImportantWebSite{TeX.SE}$
$\ImportantWebSite[red]{TeX.SE}$
$\ImportantWebSite*[black]{\href{http://www.google.com}{The Google}}_4$
\end{document}
答案1
您应该根据内部命令来定义这两个命令:
\documentclass{article}
\usepackage{amsmath}
\usepackage{xcolor}
\usepackage{xparse}
\usepackage{hyperref}
\ExplSyntaxOn
\NewDocumentCommand{\GenericWebSite}{sO{blue}mO{\c_grill_website_default_tl}e{+}}
{
\grill_website:nnnnnN
{ #1 }
{ #2 }
{ #3 }
{ #4 }
{ #5 }
\grill_website_generic:nn
}
\NewDocumentCommand{\ImportantWebSite}{sO{}mO{\c_grill_website_default_tl}e{+}}
{
\grill_website:nnnnnN
{ #1 }
{ #2 }
{ #3 }
{ #4 }
{ #5 }
\grill_website_important:nn
}
\tl_const:Nn \c_grill_website_default_tl { http://tex.stackexchange.com }
\cs_new_protected:Nn \grill_website_generic:nn
{
\group_begin:
\leavevmode
\color{#1}
#2
\group_end:
}
\cs_new_protected:Nn \grill_website_important:nn
{
\fcolorbox{red}{gray!20}
{
\tl_if_empty:nF { #1 } { \color{#1} }
#2
}
}
\cs_new_protected:Nn \grill_website:nnnnnN
{
% #1 = *
% #2 = optional color (for generic)
% #3 = text to display
% #4 = web site to link
% #5 = subscript
% #6 = wrapper
#6 { #2 }
{
\bool_if:nTF { #1 }
{% no need to link web site as it is already a link
\textnormal{#3}
}
{
\href{#4}{\textnormal{#3}}
}
\tl_if_novalue:nF { #5 }
{
\mode_if_math:TF { \sb } { \textsubscript } {\textnormal{Note: #5}}
}
}
}
\ExplSyntaxOff
\begin{document}
%% Testing various uses of \GenericWebSite
\GenericWebSite{TeX.SE}
\GenericWebSite[red]{TeX.SE}
\GenericWebSite*[black]{\href{http://www.google.com}{The Google}}+4
$\GenericWebSite*[black]{\href{http://www.google.com}{The Google}}+4$
\medskip
%% Testing various uses of \ImportantWebSite
\ImportantWebSite{TeX.SE}
\ImportantWebSite[red]{TeX.SE}
\ImportantWebSite*[black]{\href{http://www.google.com}{The Google}}+4
$\ImportantWebSite*[black]{\href{http://www.google.com}{The Google}}+4$
\end{document}
我改变了第二个可选参数的位置,因为两个连续的参数应该相互依赖,而你的参数是独立的。
注释+
仅出于技术原因。我会使用键值语法。