14

I know that, whenever I want to see how some control sequence, say \mycontrolsequence, is defined, I can use

\show\mycontrolsequence

then compile my code and look up the .log file. However, robust commands seem impervious to \show. For instance, if I compile the following code,

\documentclass{article}

\newcommand\mycommand{foo} \show\mycommand

\DeclareRobustCommand{\myrobustcommand}{bar} \show\myrobustcommand

\begin{document} hello \end{document}

my log file contains

\mycommand=\long macro:
->foo.
l.4 \show\mycommand

\myrobustcommand=macro: ->\protect \myrobustcommand . l.7 \show\myrobustcommand

Note that, whereas the definition of \mycommand is exposed (foo), nothing transpires of \myrobustcommand's definition.

Of course, in practice, I could always identify in which file a given robust command is defined and look up its definition there. However, finding the file in question may not be obvious. Hence my question:

Is there an alternative way of peering into the definition of a robust command?

jub0bs
  • 58,916
  • 1
    \usepackage{xpatch}\xshowcmd\mycommand – egreg Jun 01 '13 at 16:51
  • @egreg I just looked up the xpatch package. That's cheating, egreg: you're the maintainer of that package :p Your comment answers my question completely. Do you want to post it as an answer? – jub0bs Jun 01 '13 at 16:55
  • I'm pretty sure there's already something about this on the site. I'll try finding it; failing, I'll write an answer. – egreg Jun 01 '13 at 16:56

2 Answers2

15

Commands defined with \DeclareRobustCommand are defined in an indirect way; when you say

\DeclareRobustCommand{\foo}{...}

LaTeX defines \foo as

\expandafter\def\expandafter\foo\expandafter{\expandafter\protect\csname foo \endcsname}

so that it internally uses a \foo  command (with a trailing space in its name) and does

\@namedef{foo }{...}

This is a rough approximation, actually. So, to find the actual definition you have to say

\expandafter\show\csname foo \endcsname

The situation is much more complicated when you do

\DeclareRobustCommand{\foo}[1][default]{...}

because the command above would not answer anything sensible.

You can load the xpatch command (or regexpatch) and use

\xshowcmd\foo

which will do the right thing for you.

If you load regexpatch you'll have also a *-variant that shows more information. For example, after

\DeclareRobustCommand\foo[1][default]{something with #1}

you'll get, from \xshowcmd\foo the output

> \\foo =\long macro:
[#1]->something with #1.

while \xshowcmd*\foo will tell

*************************************************
* xpatch message
* `\foo' is a control word defined with `\DeclareRobustCommand' and a default
* optional argument `default'
*************************************************
> \\foo =\long macro:
[#1]->something with #1.
egreg
  • 1,121,712
7

A quick work-around is to define

\def\pshow#1{{\let\protect\show #1}}

which "intercepts" the \protection. Note the localized redefinition of \protect.

\documentclass{article}
\def\pshow#1{{\let\protect\show #1}}

\newcommand\mycommand{foo} \show\mycommand

\DeclareRobustCommand{\myrobustcommand}{bar} \pshow\myrobustcommand

\begin{document} hello \end{document}

The .log file shows:

> \mycommand=\long macro:
->foo.
l.5 \show\mycommand

> \myrobustcommand =\long macro: ->bar. \myrobustcommand ->\protect \myrobustcommand

l.8 \pshow\myrobustcommand

David Carlisle
  • 757,742
Werner
  • 603,163
  • Let me one more question. Suppose I (or some package) made a command through \newcommand. Say, \newcommand{\mycmd}[2][1st]{foo}. Is it possible to watch how did LaTeX internaly created it? I tested this by \pshow but no avail. Latex returns something like @protected@testopt ... –  Feb 13 '16 at 08:24
  • 1
    @maximav: For this you should \usepackage{xpatch} and then you can use \xshowcmd\mycmd. – Werner Feb 14 '16 at 01:06