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

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.
–
egregDec 29 '12 at 10:19

2 Answers
2

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}