13

Wondering if there is any way to print out (for debugging purposes) the file name and the line number from where a macro is invoked (not where it is defined). My attempt to use the currfile package only shows the main file name in the output:

**** ------ Enabling macro trace
**** DEBUG: (Depth=0) (File=TeX-SE.tex, Line=0) Started macro `\MacroA'.
**** DEBUG: (Depth=1) (File=TeX-SE.tex, Line=0) Started macro `\MacroB'.
**** DEBUG: (Depth=2) (File=TeX-SE.tex, Line=0) Started macro `\MacroC'.
**** DEBUG: (Depth=2) (File=TeX-SE.tex, Line=0) Completed macro `\MacroC'.
**** DEBUG: (Depth=1) (File=TeX-SE.tex, Line=0) Completed macro `\MacroB'.
**** DEBUG: (Depth=0) (File=TeX-SE.tex, Line=0) Completed macro `\MacroA'.
**** ------ Disabling macro trace

The desired output is something like:

**** ------ Enabling macro trace
**** DEBUG: (Depth=0) (File=TeX-SE.tex, Line=59) Started macro `\MacroA'.
**** DEBUG: (Depth=1) (File=MyMacros.sty, Line=7) Started macro `\MacroB'.
**** DEBUG: (Depth=2) (File=MyMacros.sty, Line=3) Started macro `\MacroC'.
**** DEBUG: (Depth=2) (File=MyMacros.sty, Line=3) Completed macro `\MacroC'.
**** DEBUG: (Depth=1) (File=MyMacros.sty, Line=7) Completed macro `\MacroB'.
**** DEBUG: (Depth=0) (File=TeX-SE.tex, Line=59) Completed macro `\MacroA'.
**** ------ Disabling macro trace

Notes:

Code:

%\RequirePackage{filecontents}% <--- Commented out to prevent overwriting an existing file.
\begin{filecontents*}{MyMacros.sty}
    \newcommand*{\MacroC}[1]{cc#1cc}
    \newcommand*{\MacroB}[1]{\MacroC{CC}b#1b}
    \newcommand*{\MacroA}[1]{a\MacroB{#1}a}
\end{filecontents*}
%
\documentclass{article}
\usepackage{xparse}
\usepackage{currfile}

%\usepackage{letltxmacro}
%\LetLtxMacro{\OldUsepackage}{\usepackage}
%\renewcommand{\usepackage}[2][]{\edef\currfilename{#2}\OldUsepackage[#1]{#2}}%


\newcommand*{\CurrentLineNumber}{0}%

\newif\ifEnableTrace
\newcounter{NestingDepth}
\let\latexnewcommand\newcommand


\newcommand{\StartMacro}[1]{%
  \ifEnableTrace
    \typeout{**** DEBUG: (Depth=\arabic{NestingDepth}) (File=\currfilename, Line=\CurrentLineNumber) Started macro `\string#1'.}%
    \stepcounter{NestingDepth}%
  \fi
}
\newcommand{\EndMacro}[1]{%
  \ifEnableTrace
    \addtocounter{NestingDepth}{-1}%
    \typeout{**** DEBUG: (Depth=\arabic{NestingDepth}) (File=\currfilename, Line=\CurrentLineNumber) Completed macro `\string#1'.}%
  \fi
}

\NewDocumentCommand{\NewCommand}{smO{0}om}{%
  \IfBooleanTF{#1}
    {\IfNoValueTF{#4}{\latexnewcommand*{#2}[#3]}{\latexnewcommand*{#2}[#3][#4]}}%
    {\IfNoValueTF{#4}{\latexnewcommand{#2}[#3]}{\latexnewcommand{#2}[#3][#4]}}%
  {\StartMacro{#2}#5\EndMacro{#2}}%
}

% if you want to enable tracing
\let\newcommand\NewCommand

\usepackage{MyMacros}

\begin{document}

\MacroA{XXX}
\MacroB{YYY}

\EnableTracetrue
\typeout{**** ------ Enabling macro trace}
\MacroA{XXX}

\typeout{**** ------ Disabling macro trace}
\EnableTracefalse
\MacroB{YYY}

\end{document}
3
  • 2
    \the\inputlineno
    – egreg
    Aug 6, 2014 at 19:42
  • @egreg: That's definitely a good start -- seems to get the line number where the \MacroA is invoked, not where \MacroB is invoked, at least with my naive usage of it: Line=\the\inputlineno. Aug 6, 2014 at 19:52
  • If \MacroA invokes \MacroB, then \MacroB will show the same line number as \MacroA, in that call.
    – egreg
    Aug 6, 2014 at 19:58

1 Answer 1

3

In general the answer here (such as it is) is 'no'. TeX's macro expansion means that when \macroA is read it is replaced by the definition, which is then 'there'. Where that definition comes from, what it is, etc. is unimportant. So from TeX's point of view \macroA => \macroB means that \macroB is 'here' whether it's defined here or not. At the same time, you have to bear in mind that any clever re-definitions to help trace material have to keep expandable macros expandable, and that means no assignments, writing to the log, etc., which limits what can be achieved.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.