The general problem of finding where a command is defined has no viable solution. Macros can and do change their meaning; a typical example is \\
. This simple document
\documentclass{article}
\begin{document}
\show\\
{\centering\show\\}
\begin{tabular}{c}
\show\\
\end{tabular}
\end{document}
gives the following output in the terminal window:
> \\=macro:
->\x@protect \\\protect \\ .
l.4 \show\\
?
> \\=macro:
->\ifhmode \unskip \else \@nolnerr \fi \par \@ifstar {\nobreak \@xcentercr }\@xcentercr .
l.6 {\centering\show\\
}
?
> \\=macro:
->{\ifnum 0=`}\fi \@ifstar \@xtabularcr \@xtabularcr .
l.9 \show\\
Thus, besides caching your entire preamble, a safe routine should also compile your document in order to get the actual meaning of a macro.
Another example. Suppose you load siunitx
and do \show\SI
; the output is
> \SI=\protected macro:
->\int_zero:N \l__xparse_processor_int \tl_set:Nn \l__xparse_args_tl {\SI code }\tl_set:Nn \l__xparse_fn_tl {\SI }\__xparse_grab_D:w []{-NoValue-}\__xparse_grab_m_1:w \__xparse_grab_D:w []{-NoValue-}\__xparse_grab_m_1:w \l__xparse_args_tl .
the usefulness of which is very dubious.
Another example. Suppose you're using amsmath
and want to access the definition of \bar
; a \show
command would print
> \bar=macro:
->\protect \mathaccentV {bar}016.
but you'll never find where this definition is performed, because there's no \def
, \newcommand
or any other similar command that does it: indeed in amsmath.sty
you find (line numbers for convenience)
574 \def\set@mathaccent#1#2#3#4{%
575 \xdef#2{\@nx\protect\@nx\mathaccentV
576 {\@xp\@gobble\string#2}\hexnumber@#1#4}%
577 }
578 \def\@tempa#1{\@xp\@tempb\meaning#1\@nil#1}
579 \def\@tempb#1>#2#3 #4\@nil#5{%
580 \@xp\ifx\csname#3\endcsname\mathaccent
581 \@tempc#4?"7777\@nil#5%
582 \else
583 \PackageWarningNoLine{amsmath}{%
584 Unable to redefine math accent \string#5}%
585 \fi
586 }
587 \def\@tempc#1"#2#3#4#5#6\@nil#7{%
588 \chardef\@tempd="#3\relax\set@mathaccent\@tempd{#7}{#2}{#4#5}}
589 \@tempa{\hat}
590 \@tempa{\check}
591 \@tempa{\tilde}
592 \@tempa{\acute}
593 \@tempa{\grave}
594 \@tempa{\dot}
595 \@tempa{\ddot}
596 \@tempa{\breve}
597 \@tempa{\bar}
598 \@tempa{\vec}
and it's line 597 that performs the redefinition from the kernel's meaning
\mathaccent "7016\relax
that's assigned in fontmath.ltx
by the high level instruction
\DeclareMathAccent{\bar}{\mathalpha}{operators}{"16}
Final example. You can't even guess the syntax of a command from its definition: here's the output of \show\makebox
> \makebox=macro:
->\leavevmode \@ifnextchar (\@makepicbox {\@ifnextchar [\@makebox \mbox }.
\show\blob
– David Carlisle May 9 '13 at 14:58texdef -t latex -p longtable -p tabularx longtable
which returns the definition, texdef has options to return instead the filename at which the definition was found (it has lots of options:-) – David Carlisle May 9 '13 at 15:33\bar
as redefined byamsmath
; would you believe me when I say that the redefinition byamsmath
is performed by\@tempa{\bar}
? Really, apart from very simple cases, this is impossible. – egreg May 13 '13 at 8:36