21

I was wondering how \etoolbox's \expandonce does what it does. So I looked up how it was defined and found

\unexpanded\expandafter{#1}

But no matter where I look, I cannot find a definition for \unexpanded. I've tried

 texdef -t latex unexpanded -s

which returns the following:

Source code definition of 'unexpanded' could not be found.
\unexpanded is defined by (La)TeX.

\unexpanded:
\unexpanded

I've also tried looking in the source2e documentation, but there's nothing there about \unexpanded.

Could someone point me in the right direction of where to find the documentation?

6
  • I think the texbook goes over it, but I can't quite remember. You won't find it in source2e. Oct 26, 2013 at 15:55
  • 2
    \unexpanded is an eTeX primitive, have a look at the eTeX manual
    – cgnieder
    Oct 26, 2013 at 15:55
  • @cgnieder That's the answer here: please post as such
    – Joseph Wright
    Oct 26, 2013 at 16:03
  • @cgnieder How do I find the source code for eTeX stuff? Or how would I used texdef to show the source code?
    – A.Ellett
    Oct 26, 2013 at 16:04
  • 1
    @A.Ellett Trying to use texdef for \unexpanded is the same as trying to use it for say \def or \relax: you won't get anything. As it's a primitive, the source is in WEB (a form of Pascal), but unless you really need the detail then I'd go with the engine manual (eTeX in this case).
    – Joseph Wright
    Oct 26, 2013 at 16:17

2 Answers 2

22

\unexpanded is an ε-TeX primitive. If you do

\documentclass{article}
\begin{document}
\show\unexpanded
\end{document}

you'll get in the log:

> \unexpanded=\unexpanded.
l.3 \show\unexpanded

which seems to be redundant information but actually tells you that it is a primitive control sequence. Primitives are listed in the TeX Book or TeX by Topic but you won't find \unexpanded there because it is an ε-TeX primitive. It is described in the e-TeX manual, though:

\unexpanded<general text>.

The expansion is the token list <balanced text>.

[...]

When building an expanded token list, the tokens resulting from the expansion of \unexpanded are not expanded further (this is the same behaviour as is exhibited by the tokens resulting from the expansion of \the<token> variable in both TeX and ε-TeX).

25

As cgnieder's excellent answer says, \unexpanded is a primitive of e-TeX, that is, an extension of the original TeX language. Primitives don't have a definition, they're commands directly understood by the engine. Some of them are expandable, that is, they don't reach TeX's “stomach” because they are expanded just like macros (the same happens to the conditionals, for example); \unexpanded is one of these macros.

It's a generalization of \noexpand which, in the context of an \edef or a \write, has a null expansion but also the effect of making the next token unexpandable for the task at hand. Thus

\def\foo{something}
\def\baz{else}
\edef\x{\foo\noexpand\baz}

would be equivalent to

\def\x{something\baz}

With \unexpanded you can protect from expansion in an \edef (or \xdef) or \write an entire token list, without the need to prepend \noexpand to all expandable tokens.

Since \unexpanded follows the pattern

\unexpanded <general text>

it has an interesting feature. When TeX wants to expand it, it looks forward to find a <general text> which is defined as

<filler> { <balanced text> <right brace>

and expands tokens to recognize a <filler> and, eventually, the {. A <filler> is just an arbitrary sequence of \relax and space tokens which are simply ignored. The { is an explicit or implicit token of category code 1.

A consequence of this is that

\unexpanded\expandafter{\cs}

will cause the expansion of \cs before the { that starts the list of tokens which will not be expanded any more. Indeed, the definition of \expandonce is

\newcommand{\expandonce}[1]{\unexpanded\expandafter{#1}}

Also \detokenize (another expandable primitive of e-TeX) has the same properties.

Beware of the <filler>: it can cause some unexpected effects under certain circumstances as shown in Get the lion to run in loops. Tersely

4
  • In an expansion context, things like \def, \expandafter, \noexpand are treated as though their expansion was \relax, right? So, in the context of \unexpanded, when expanding the <filler>, TeX finds \expandafter, expands it and sees what amounts to \relax. Am I understanding this correctly?
    – A.Ellett
    Oct 26, 2013 at 19:44
  • 1
    @A.Ellett Sorry, you're not understanding this correctly. In an expansion context, unexpandable tokens are simply not expanded (they can't be); \expandafter and \noexpand are expandable and they are expanded. The expansion of both is null, but before this null expansion, they do their respective action.
    – egreg
    Oct 26, 2013 at 20:25
  • What's the role of <filler> here? Does \unexpanded reads and executes the filler until it reaches a {? What if there is a { in the filler?
    – Cyker
    Jun 27, 2020 at 7:28
  • 1
    @Cyker The <filler> is any sequence of tokens that, after macro expansion, only consists of \relax or space tokens. Any other token ends it and, if it is not {, an error is issued.
    – egreg
    Jun 27, 2020 at 7:41

You must log in to answer this question.

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