Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I've just played with expl3 for a couple of hours. Many things are much more convenient than with 2e. There are functions for things that I thought to be impossible with LaTeX. However, I am missing one function.

I would love to have a function, maybe execute_after:NN <macroA> <macroB> that first executes macroA, lets it take as much tokens from the input stream as it likes and then executes macroB. So assuming \macroA and \macroB both take 2 arguments, \execute_after:NN \macroA \macroB abcdefg would be equivalent to \macroA{a}{b}\macroB{c}{d}efg.

share|improve this question
1  
When TeX expands a macro, it looks for the arguments and does the replacement according to the macro's definition; the macro and its arguments are removed from the input stream and there's no "here the arguments to \macroA ended" mark. –  egreg Jul 2 '13 at 18:00
add comment

1 Answer

"Simple" case: Arguments defined as parameter of macro \macroA

Formally macro arguments are specified in the definition of the macro (parameter text), e.g.

\def\foo[#1]#2{...}

It defines macro foo with the parameter text [#1]#2 containing two parameters, #1, delimited by ] and an undelimited parameter #2. There are two ways to learn about the parameter text of macro \foo:

  • Applying \meaning to a macro expands to a string with its definition. \meaning\foo expands to macro:[#1]#2->.... However this is a plain text string, the characters are character tokens with catcode 12 (other) with the exception of the space character, which has catcode 10 (space). Thus the information about the original tokens and catcodes are lost.

    \catcode\[=\$ \catcode\]=\& \def\funny[#1]#2{...}

    defines a macro \funny, where [ and ] has unusual catcodes. However \meaning\funny expands to the same string as \meaning\foo exactly.

  • A macro can be defined and compared to the unknown macro. If the test with \ifx is true, then the parameter text is known.

Since the result of \meaning is finite, it is possible to iterate over all byte/token/catcode combinations to define all the macros, whose \meaning expands to the exact same string. The right macro can then be found by comparison via \ifx.

Then \execute_after:NN can parse the input stream to get the parameters according to the parameter text of the macro, call the macro with the parameters and insert \macroB afterwards.

However this is of very limited use:

  • It is non-trivial to enumerate over all possible macro definitions.
  • Efficiency: horrible.
  • Often the "arguments" are read at later expansion or execution steps, e.g.: \section is formally defined as parameterless macro. It expands to \@startsection that does some things and eventually checks for a star token, looks for an optional argument and ...

  • "Arguments" are not well defined. For example, \begin has one argument. It calls the start environment macro that can have further arguments. Also there is an environment body with the closing \end{...} marker. Inserting \macroB after \begin{tabular} or \begin{verbatim} is probably not the best choice.

Executing \macroA

\execute_after:NN can store macro \macroB somewhere and execute \macroA. But then \execute_after:NN is history and there is no code that will execute the stored \macroB. See the comment of egreg.

Analyzing the execution of \macroA

Instead of executing \execute_after:NN could inspect the macro definition of \macroA and further macros to analyze, which parameters it might read, when executed. Because of the turing completeness of TeX's language is it very likely that such an analyzing algorithm exists (Rice's theorem/halting problem).

What would be possible?

There are two cases, where TeX allows the insertion of code in the future:

  • \aftergroup remembers tokens that are called right after the end of the current group. It can be called several times and the tokens are appended in the execution order of \aftergroup.

  • \afterassignment remembers one token that is executed right after the next assignment. Later executions of \afterassignment overwrites the remembered token.

Both cases cannot be applied here, because it would restrict \macroA to a macro that ends the current group or it executes exact one assignment at the last step.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.