3

This command come from the question Equivalent of \show to display the LaTeX code in the document, the standard \meaning correctly says a command is undefined,

\documentclass{article}

\makeatletter
\newcommand\meaningbody[1]{%
  {\ttfamily
    \expandafter\strip@prefix\meaning#1}%
}
\makeatother

\begin{document}

\meaningbody\sectio

\end{document}

But that \meaningbody throw the errors when the command is undefined:

! Argument of \strip@prefix has an extra }.
<inserted text> 
                \par 
l.12 \meaningbody\sectio

Then I tried this to fix:

\documentclass{article}

\makeatletter
\newcommand{\meaningbody}[1]
{%
    {\ttfamily
    \ifdefined#1
        \expandafter\strip@prefix\meaning#1
    \else
        Command #1 undefined.
    \fi}%
}
\makeatother

\begin{document}

\meaningbody\sectio

\end{document}

But still do errors:

! Undefined control sequence.
<argument> \sectio 

l.17 \meaningbody\sectio

Related questions:

  1. What is the meaning of \meaning?
  2. How to undo a \def (i.e., Need a \undef capability)
user
  • 4,745

2 Answers2

5

You are putting the undefined command into the message, use \string to render it safe.

\documentclass{article}

\makeatletter

\newcommand{\meaningbody}[1]
{%
    {\ttfamily
    \ifdefined#1%
        \expandafter\strip@prefix\meaning#1%
    \else
        Command \string#1 undefined.%
    \fi}%
}
\makeatother

\begin{document}

\meaningbody\sectio

\end{document}

A more complete version, that copes with primitives as well as macros and undefined commands so @egreg can finally find the meaning of \box

\documentclass{article}

\makeatletter
\def\mystripprefix#1>#2{%
  \ifx\relax#2%
    #1 (not macro)%
   \else
    \expandafter\zaplessrelax\expandafter#2%
   \fi}
\def\zaplessrelax#1>\relax{#1}

\newcommand{\meaningbody}[1]
{%
    {\ttfamily
    \ifdefined#1%
        \expandafter\mystripprefix\meaning#1>\relax
    \else
        Command \string#1 undefined.%
    \fi}%
}
\makeatother

\begin{document}

A \meaningbody\sectio


B \meaningbody\section

C \meaningbody\box

\end{document}
David Carlisle
  • 757,742
2

A fairly general version that shows more information about macros and doesn't choke with other control sequences. A test whether the argument is a single control sequence could be added.

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\meaningbody}{m}
 {
  \texttt
   {
    \egreg_meaning_body:N #1
   }
 }

\cs_new:Nn \egreg_meaning_body:N
 {
  \cs_if_exist:NTF #1
   {
    \__egreg_meaning_body:N #1
   }
   {
    Command~\token_to_str:N #1~undefined
   }
 }

\cs_new:Nn \__egreg_meaning_body:N
 {
  \token_if_macro:NTF #1
   {
    Command~\token_to_str:N #1~is~a~macro;~
    \str_if_eq_x:nnTF { \token_get_prefix_spec:N #1 } { }
     {
      no prefix;~
     }
     {
      prefix:~\token_get_prefix_spec:N #1;~
     }
    parameter~text:~\token_get_arg_spec:N #1;~
    replacement~text:~\token_get_replacement_spec:N #1.
   }
   {
    Command~\token_to_str:N #1~means~\token_to_meaning:N #1
   }
 }
\ExplSyntaxOff

\begin{document}

\raggedright

\meaningbody\sectio

\meaningbody\mbox

\newcommand*\foo[1]{Whatever #1}
\meaningbody\foo

\meaningbody\box

\meaningbody\alpha

\end{document}

enter image description here

egreg
  • 1,121,712