7
\def\test{\+test\cr}
\test
\vfill
\eject

The above gives error:

...
Runaway definition?
->
! Forbidden control sequence found while scanning definition of \test.
...

3 Answers 3

5

\+ is a outer macro, it cannot be used in the definition of another macro. In plain.tex, it is defined as

\outer\def\+{\tabalign}

You can use \tabalign instead. Say,

\def\test{\tabalign test\cr}
\test
\bye
4

A different approach is to neutralize momentarily the outer macro:

\begingroup\let\+\relax
\gdef\test{\+test\cr}
\endgroup

It can be used for the outer macros that have no "inner" version like \bye, \beginsection or \proclaim.

\begingroup\let\beginsection\relax
\gdef\section#1{\beginsection#1\par}
\endgroup

\section{Title}

Of course \csname beginsection\endcsname would have worked too, as Joseph points out.

2

Another option to put an outer control sequence inside a macro is \noexpand:

\edef\test{\noexpand\+...}

The \noexpand command prevents expansion in an \edef (expanding def), and also hide "outerness".

2
  • The usual way to include an \outer control sequence inside something else is to use \csname ... \endcsname, which does not also leave you worrying about expansion.
    – Joseph Wright
    Jun 21, 2011 at 7:20
  • 1
    True. The advantage of using \noexpand is that it also allows the \outer control sequence to come in an argument, expandably: \def\foo{\expandafter\fooo\noexpand} \def\fooo#1{...} works even if #1 is normally \outer. (I saw this in a solution of one of M.Downes exercises.) Jun 21, 2011 at 15:21

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .