# Automatically run a LaTeX3 function on the document environment

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?

-
Yes, you can use \AtBeginDocument. See for instance How to automatically add text immediately after \begin{document}. –  Peter Grill Dec 29 '12 at 2:26
What would be the best way of making that work with a function similar to the above? \AtBeginDocument{\demo{} paired with \AtEndDocument{}} does not work due to the syntax. –  Кигава Енсеи Dec 29 '12 at 6:00
To provide the context, I assume you are trying to apply a function such as the one in Defining a find and replace algorithm using LaTeX3's l3regex. –  cyberSingularity Dec 29 '12 at 8:52
If the problem is connected to the question cyberSingularity links to, then filtering the document with a scripting language such as Perl or Python would be a better choice. Reading a whole document for doing some replacement would be deadly slow. –  egreg Dec 29 '12 at 10:19

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).

-

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.

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}

-
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