I often have a macro defined with with various optional parameters such as
\NewDocumentCommand{\GenericWebSite}{s O{blue} o m e_}{<code>}
and want to define a small variant of this macro, without duplicating all the <code>
of the \GenericWebSite
macro. So, for instance, I want to define
\NewDocumentCommand{\ImportantWebSite}{s o o m e_}{%
\fcolorbox{red}{gray!20}{<code>}%
}
The brute force method (illustrated in the MWE below) works fine, but there must be an easier way to do this.
The first line is the output of various uses of \GenericWebSite
and the second line is the invocation of \ImportantWebSite
passed in with the same parameters.
Notes:
- This question isn't about the specific functionality of the
\GenericWebSite
defined in the test case, but how, in general, to define a newxparse
macro,\ImportantWebSite
in the MWE, so that it can take advantage of an existing macro,\GenericWebSite
in this case, that is already defined. - One option would be to pass in key-value flags to
\GenericWebSite
so that the single macro can provide all the functionality. While in this particular example, this is certainly doable, I would prefer to keep separate macros as in may actual use case I need many variants.
References:
- How to \let an xparse defined command?,
- Optional Parameters in xparse: \IfBooleanTF vs \IfNoValueTF
- Xparse's new e-type argument (replacement for k-type argument)
- How to create internet link in PDF?
Code:
\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}
\let
or\patchcmnd
replacement for xparse declared commands, but what I mean is that you should not have hudreds of places, just one. you make have lots of \DeclareDocumentcommand\doo{sooomo}{..} but they should be calling as single macro with mandatory argumentspg_core_code_layout_thing{1}{b}{c}{d}{e}
and if you decide to redefine that to use\fcolorbox
then all your variants will use the new code. ...