4

Is it possible to define a package so that it will automatically run a LaTeX3 function on the entirety of the document environment?

If I define a function similar to the following:

\cs_new:Npn \demo #1 {
    % Do something.
}

I would normally have to wrap it around the text as follows:

\demo{Some example text.}

Is it possible to instruct the \demo function to affect the whole document environment?

5

This question is not specific to LaTeX3, as it is a more general issue about how arguments are grabbed by TeX and the wrappers that LaTeX then provides.

Grabbing an argument in the form \demo{Some text} means that TeX has to read everything before it processes it. At the same time, there is a simple rule for the parsing: count the braces and read until they balance. For environments, that's not the same: TeX does not need to grab all of the environment in one go, so there is a lot less memory usage. (Even with a modern TeX, grabbing an entire document might well be too much.) The way that the beginning and end of environments work therefore does not directly rely on 'count the start/end pairs'.

It is possible to grab all of a LaTeX environment as an argument: packages such as environ wrap this up into a package. However, I would not use this for applying some change to an entire document. Instead, I would use the approach we see with font switching commands, where each one which takes an argument (e.g. \emph) is accompanied by one that applies in an 'ongoing' sense (e.g. \itshape).

4

As Josephs stated, this is probably not a good idea for a large document.

But, as I mentioned in the comments, you can use the environ package to collect the \BODY of the document starting \AtBeginDocument through to \AtEndDocument. Then, this \BODY can be passed to the desired macro.

The following applies the macro \ApplyToEntireDocument which simply applies \textcolor{red}{} to the entire document.

enter image description here

If possible, it would be better to apply the desired changes within the environment as opposed to calling yet another macro.

Code:

\documentclass{article} 
\usepackage{etoolbox}
\usepackage{xcolor}
\usepackage{environ}

\newcommand{\ApplyToEntireDocument}[1]{\textcolor{red}{#1}}

\NewEnviron{CollectBody}{%
    \ApplyToEntireDocument{\BODY}%
}%

\AtBeginDocument{\CollectBody}
\AtEndDocument{\endCollectBody}


\begin{document}
This is the start of the document.

Here is a well know equation:
\[
    E = mc^2
\]

And another paragraph.
\end{document}
  • 1
    My point would stand here as simply \color{red} would achieve the same thing (\textcolor uses \color internally). – Joseph Wright Dec 29 '12 at 20:48
  • Yep, totally agree. The reason I used \textcolor in the MWE was to illustrate that one could pass the \BODY to a macro as a parameter. – Peter Grill Dec 29 '12 at 20:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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