I would like to be able to insert code into the definitions of my custom macros, without having to modify each macro definition. This seemed like a simple case of redefining \newcommand, but this turns out not to be so easy (well for me anyway). I end up with:
Illegal parameter number in definition of \MacroB.
to be read again
1 l.45 \newcommand*{\MacroB}[1]{b#1b}
My guess is that somewhere I need to double up the # but I don't understand why, and guessing which ones need to be doubled up did not work. So perhaps that is not the problem.
Notes:
- The MWE below compiles fine -- one needs to uncomment the
\def\EnableTrace{}to see the problem. - The goal of this is to build up a stack trace of macros as they are being called.
Code:
%\def\EnableTrace{}
\documentclass{article}
%% All packages included here...
\usepackage{xparse}
\usepackage{letltxmacro}
%% Start of custom macros...
\ifdefined\EnableTrace
\newcounter{NestingDepth}
\newcommand{\StartMacro}[1]{%
\typeout{*** DEBUG: (Depth=\arabic{NestingDepth}) Started macro "\string#1".}%
\stepcounter{NestingDepth}%
}%
\newcommand{\EndMacro}[1]{%
\addtocounter{NestingDepth}{-1}%
\typeout{*** DEBUG: (Depth=\arabic{NestingDepth}) Completed macro "\string#1".}%
}%
% --------------
\LetLtxMacro{\OldNewcommand}{\newcommand}%
\RenewDocumentCommand{\newcommand}{%
s% #1 = * (ignored for now to keep the code below simple)
m% #2 = macro name
O{1}% #3 = number of paramaters
o% #4 = default value for first optional parameter (if there is one)
m% #5 = code to execute
}{%
%
\ifnum#3=1\relax
\OldNewcommand{#2}{\StartMacro{#2}#5\EndMacro{#2}}%
\else
\IfBooleanTF{#4}{%
% first parameter of macro being defined is optional, as default value is provided
\OldNewcommand{#2}[#3][#4]{\StartMacro{#2}#5\EndMacro{#2}}%
}{%
% first parameter of macro being defined is mandatory
\OldNewcommand{#2}[#3]{\StartMacro{#2}#5\EndMacro{#2}}%
}%
\fi
}%
\fi
\newcommand{\MacroB}[1]{b#1b}%
\newcommand{\MacroA}[1]{a\MacroB{#1}a}%
\begin{document}
\MacroA{XXX}
\MacroB{YYY}
\end{document}
\ifnum#3=1…do. After checking the number of parameters is 1, you call\OldNewCommand{#2}{…}with 0 arguments. – Manuel Aug 05 '14 at 21:01\ifnumand\elseand also the corresponding\fi(i.e., leaving only the\IfBooleanTF… it compiles fine here. – Manuel Aug 05 '14 at 21:08#5withvinstead ofmhelp? (I can't try it myself for I am on my phone) – Henri Menke Aug 05 '14 at 21:09oargument, the test is not\IfBooleanTF, but\IfNoValueTFor\IfValueTF. Of course,\LetLtxMacrois not needed for\newcommand, that has no argument. – egreg Aug 05 '14 at 21:22