Difference between revisions of "System Macros/Expansion Control"

From ConTeXt wiki
Jump to navigationJump to search
m (Basic navigation)
(general updates)
Line 1: Line 1:
 
< '''Prev:''' [[System Macros/Scratch Variables|Scratch Variables]] | '''Top:''' [[System Macros]] | '''Next:''' [[System Macros/Handling Arguments|Handling Arguments]] >
 
< '''Prev:''' [[System Macros/Scratch Variables|Scratch Variables]] | '''Top:''' [[System Macros]] | '''Next:''' [[System Macros/Handling Arguments|Handling Arguments]] >
  
== Expansion control ==
+
=== Expansion control macro shortcuts ===
  
When in unprotected mode, to be entered with <code>\unprotect</code>, one can use <code>\@EA</code> as equivalent of <code>\expandafter</code>. <code>\@EAEA</code> expands to two expandafters, <code>\@EAEAEA</code> to three, and the last one expands to <code>\@EA\@EAEAEA\@EA</code>.
+
When in unprotected mode, to be entered with <code>\unprotect</code>, one can use <code>\@NX</code> as equivalent of <code>\noexpand</code>, and <code>\@EA</code> as equivalent of <code>\expandafter</code>. <code>\@EAEA</code> expands to two expandafters, <code>\@EAEAEA</code> to three, and <code>\@EAEAEAEAEA</code> expands to <code>\@EA\@EAEAEA\@EA</code>. At first sight, these macros are simply shortcuts that are a bit easier to type and read, but there is a bit more to it. Here is an example where <code>\@EA\@EAEAEA\@EA</code> is not the same as five \expandafters in a row:
 
 
Sometimes we pass macros as arguments to commands that don't expand them before interpretation. Such commands can be enclosed by <code>\expanded</code>, like:
 
  
 
<texcode>
 
<texcode>
\expanded{\setupsomething[\alfa]}
+
\def\complexdoblank
 +
  {\flushnotes
 +
  \ifmmode
 +
    \@EA\nocomplexdoblank
 +
  \else
 +
    \ifopelkaar
 +
      \ifinpagebody
 +
        \@EA\@EAEAEA\@EA\docomplexdoblank
 +
      \else
 +
        \@EA\@EAEAEA\@EA\nocomplexdoblank
 +
      \fi
 +
    \else
 +
      \@EAEAEA\docomplexdoblank
 +
    \fi
 +
  \fi}
 
</texcode>
 
</texcode>
  
Such situations occur for instance when <code>\alfa</code> is a commalist or when data stored in macros is fed to index of list commands. If needed, one should use <code>\noexpand</code> inside the argument. Later on we will meet some more clever alternatives to this command.
+
The two commands <code>\expandoneargafter</code> and <code>\expandtwoargsafter</code> make macros more readable by hiding a lot of <code>\expandafter</code>'s. They expand the arguments after the first command.
 
 
These two commands make macros more readable by hiding a lot of <code>\expandafter</code>'s. They expand the arguments after the first command.
 
  
 
<texcode>
 
<texcode>
Line 22: Line 32:
 
</texcode>
 
</texcode>
  
These commands expect the arguments to be macros.
+
These commands expect the arguments to be macros, the \type{\full} versions do a ''deep expansion''.
 +
 
 +
=== Expanding all arguments ===
 +
 
 +
Sometimes we pass macros as arguments to commands that don't expand them before interpretation. Such commands can be enclosed by <code>\expanded</code>, like:
 +
 
 +
<texcode>
 +
\expanded{\setupsomething[\alfa]}
 +
</texcode>
 +
 
 +
Such situations occur for instance when <code>\alfa</code> is a commalist or when data stored in macros is fed to indexing or list generation commands. If needed, one could use <code>\noexpand</code> inside the argument, but some very often occuring problems with  expansion (like accents) are intercepted by a somewhat smarter version with the same basic functionality:
 +
 
 +
<texcode>
 +
\safeexpanded{\bookmark{\alfa}}
 +
</texcode>
 +
 
 +
The <code>\safe...</code> form is actually so useful that there are ''safe'' versions of <code>\edef</code> and <code>\xdef</code> avialable: <code>\safeedef</code> and <code>\safexdef</code> (only usable for definitions that do not need arguments).
 +
 
 +
=== Preventing expansion ===
  
 
When expansion of a macro gives problems we can precede it by <code>\unexpanded</code>, like so:
 
When expansion of a macro gives problems we can precede it by <code>\unexpanded</code>, like so:
Line 30: Line 58:
 
</texcode>
 
</texcode>
  
(if you are not familiar with ConTeXt: this is the same command as <code>\protect</code> in LaTeX). It seems that protection is one of the burdens of developers of packages, so maybe that's why in e-TeX protection is solved in a more robust way. ConTeXt uses that (more robust) solution if it is available, and otherwise tries it's best to emulate it using rather tricky macros.
+
This will prevent the macro from being expanded in places where no typesetting occurs, like when strings are written to the tuo file.
  
 
Expansion problems can get quite complex. There are some other internal macros that can help harnassing it, but it is fairly unlikely that you will need them. If you believe you do, read the [[source:syst-gen.tex| syst-gen.tex]] source code.
 
Expansion problems can get quite complex. There are some other internal macros that can help harnassing it, but it is fairly unlikely that you will need them. If you believe you do, read the [[source:syst-gen.tex| syst-gen.tex]] source code.

Revision as of 11:50, 25 December 2006

< Prev: Scratch Variables | Top: System Macros | Next: Handling Arguments >

Expansion control macro shortcuts

When in unprotected mode, to be entered with \unprotect, one can use \@NX as equivalent of \noexpand, and \@EA as equivalent of \expandafter. \@EAEA expands to two expandafters, \@EAEAEA to three, and \@EAEAEAEAEA expands to \@EA\@EAEAEA\@EA. At first sight, these macros are simply shortcuts that are a bit easier to type and read, but there is a bit more to it. Here is an example where \@EA\@EAEAEA\@EA is not the same as five \expandafters in a row:

\def\complexdoblank
  {\flushnotes
   \ifmmode
     \@EA\nocomplexdoblank
   \else
     \ifopelkaar
       \ifinpagebody
         \@EA\@EAEAEA\@EA\docomplexdoblank
       \else
         \@EA\@EAEAEA\@EA\nocomplexdoblank
       \fi
     \else
       \@EAEAEA\docomplexdoblank
     \fi
   \fi}

The two commands \expandoneargafter and \expandtwoargsafter make macros more readable by hiding a lot of \expandafter's. They expand the arguments after the first command.

\expandoneargafter \command{\abc}
\expandtwoargsafter\command{\abc}{\def}
\fullexpandoneargafter \command{\abc}
\fullexpandtwoargsafter\command{\abc}{\def}

These commands expect the arguments to be macros, the \type{\full} versions do a deep expansion.

Expanding all arguments

Sometimes we pass macros as arguments to commands that don't expand them before interpretation. Such commands can be enclosed by \expanded, like:

\expanded{\setupsomething[\alfa]}

Such situations occur for instance when \alfa is a commalist or when data stored in macros is fed to indexing or list generation commands. If needed, one could use \noexpand inside the argument, but some very often occuring problems with expansion (like accents) are intercepted by a somewhat smarter version with the same basic functionality:

\safeexpanded{\bookmark{\alfa}}

The \safe... form is actually so useful that there are safe versions of \edef and \xdef avialable: \safeedef and \safexdef (only usable for definitions that do not need arguments).

Preventing expansion

When expansion of a macro gives problems we can precede it by \unexpanded, like so:

\unexpanded\def\somecommand{... ... ...}

This will prevent the macro from being expanded in places where no typesetting occurs, like when strings are written to the tuo file.

Expansion problems can get quite complex. There are some other internal macros that can help harnassing it, but it is fairly unlikely that you will need them. If you believe you do, read the syst-gen.tex source code.

< Prev: Scratch Variables | Top: System Macros | Next: Handling Arguments >