This is a follow-up to How to ignore everything in the document environment?.

The code below is intended to extract the value of a token that occurs before \begin{document}. For some reason, there is a problem with the \DisablePreamble macro that I can not figure out. Surprisingly, it seems to have been working in my actual use case, but not when I try to make a MWE (in an attempt to reproduce another problem).

File goo.tex is an extremely simplified test case as it does not have any preamble so it doesn't need to invoke \DisablePreamble -- and this works. But, in my real use case (as in foo.tex), there is a preamble and a complete document environment that needs to be ignored, and hence the need for \DisablePreamble.

The example below produces:

MyToken=goobar

MyToken=goobar

as the \ExtractMyTokenA line is commented, but with \ExtractMyTokenA uncommented it should yield (note change in second line):

MyToken=goobar

MyToken=foobar

When the call to \ExtractMyTokenA is uncommented, this yields:

./TeX-SE.tex:75: LaTeX Error: Command \env already defined.
Or name \end... illegal, see p.192 of the manual.


## Notes:

• To get the given MWE to failure you need to uncomment the \ExtractMyTokenA line.
• The actual problem is in \DisablePreamble, but this MWE seems more complicated than it really is as:
1. I have two temp files foo.tex and goo.tex as test cases.
2. The macros \ExtractMyTokenA and \ExtractMyTokenA are pretty much identical: Once calls \DisablePreamble and the other does not.

## Code:

\documentclass{article}
\usepackage{environ}

%  This file is ONLY needed once we get past the error message.
%\usepackage{filecontents}% Comment out so as to NOT overwrite foo.tex and goo.tex.
\begin{filecontents*}{foo.tex}
\documentclass{standalone}
\usepackage{MyStandardPackages}
\input{MyStandardSetup}

\MyToken={foobar}%   <----- Only this line should be executed. ALL other lines in foo.tex are to be ignored.

\begin{document}
lots of text here

\SetSomeVarable{\SomeVar}{Some Value}

\begin{SomeEnvironment}
lots more stuff here as well
\end{SomeEnvironment}
\end{document}
\end{filecontents*}

% This file does not have a preamble so won't need a call to "\DisablePreamble"
\begin{filecontents*}{goo.tex}
\MyToken={goobar}%   <----- Only this line should be executed. ALL other lines in foo.tex are to be ignored.
\end{filecontents*}

%% ------------------------------
%% Problem is in here somewhere!!  Shows up once we uncomment "\ExtractMyToken{foo}" below.
\newcommand{\DisablePreamble}{%
\renewcommand{\documentclass}[2][]{}%  remove def'n of \documentclass
%% http://tex.stackexchange.com/questions/165258/how-to-ignore-everything-in-the-document-environment
\providecommand{\env@document@save@env}{}% To keep environ happy
\providecommand{\env@document@process}{}%
\RenewEnviron{document}{}% Ignore everything within the "document" environment.
\renewcommand{\usepackage}[2][]{}%
}%

\newtoks{\MyToken}
\newcommand{\FileWithPath}{}%
\newcommand{\ExtractMyTokenA}[1]{% Same as \ExtractMyTokenB, except invokes "\DisablePreamble"
% #1 = File Name with path
\begingroup%
\DisablePreamble%
% -----------
\let\OldInput\input%         Need to redefine \input as the file being read uses
\renewcommand*{\input}[1]{}% \input before \begin{document}.
% -----------
\edef\FileWithPath{#1}%
\OldInput{\FileWithPath}%
\global\MyToken=\expandafter{\the\MyToken}
\endgroup%
}%

\newcommand{\ExtractMyTokenB}[1]{% Same as \ExtractMyTokenA, except "\DisablePreamble" is commented.
% #1 = File Name with path
\begingroup%
%\DisablePreamble% This works great for the case where there is no preamble.
% -----------
\let\OldInput\input%         Need to redefine \input as the file being read uses
\renewcommand*{\input}[1]{}% \input before \begin{document}.
% -----------
\edef\FileWithPath{#1}%
\OldInput{\FileWithPath}%
\global\MyToken=\expandafter{\the\MyToken}
\endgroup%
}%

\begin{document}
\ExtractMyTokenB{goo}%  <----- This does not invoke \DisablePreamble, and works
MyToken=\the\MyToken\par
% ------------
%\ExtractMyTokenA{foo}%   <----- This invokes \DisablePreamble, which fails
MyToken=\the\MyToken\par
\end{document}

-
– Werner Apr 27 '14 at 5:22

 \providecommand{\env@document@save@env}{}% To keep environ happy


It would make it happier if that defined \env@document@save@env rather than \env :-)

\documentclass{article}
\usepackage{environ}

%  This file is ONLY needed once we get past the error message.
%\usepackage{filecontents}% Comment out so as to NOT overwrite foo.tex and goo.tex.
\begin{filecontents*}{foo.tex}
\documentclass{standalone}
\usepackage{MyStandardPackages}
\input{MyStandardSetup}

\MyToken={foobar}%   <----- Only this line should be executed. ALL other lines in foo.tex are to be ignored.

\begin{document}
lots of text here

\SetSomeVarable{\SomeVar}{Some Value}

\begin{SomeEnvironment}
lots more stuff here as well
\end{SomeEnvironment}
\end{document}
\end{filecontents*}

% This file does not have a preamble so won't need a call to "\DisablePreamble"
\begin{filecontents*}{goo.tex}
\MyToken={goobar}%   <----- Only this line should be executed. ALL other lines in foo.tex are to be ignored.
\end{filecontents*}

%% ------------------------------
%% Problem is in here somewhere!!  Shows up once we uncomment "\ExtractMyToken{foo}" below.
\makeatletter% <---- This was missing!!!!!
\newcommand{\DisablePreamble}{%
\renewcommand{\documentclass}[2][]{}%  remove def'n of \documentclass
%% http://tex.stackexchange.com/questions/165258/how-to-ignore-everything-in-the-document-environment
\providecommand{\env@document@save@env}{}% To keep environ happy
\providecommand{\env@document@process}{}%
\RenewEnviron{document}{\endgroup\begingroup}% Ignore everything within the "document" environment.
\renewcommand{\usepackage}[2][]{}%
}%
\makeatother

\newtoks{\MyToken}
\newcommand{\FileWithPath}{}%
\newcommand{\ExtractMyTokenA}[1]{% Same as \ExtractMyTokenB, except invokes "\DisablePreamble"
% #1 = File Name with path
\begingroup%
\DisablePreamble%
% -----------
\let\OldInput\input%         Need to redefine \input as the file being read uses
\renewcommand*{\input}[1]{}% \input before \begin{document}.
% -----------
\edef\FileWithPath{#1}%
\OldInput{\FileWithPath}%
\global\MyToken=\expandafter{\the\MyToken}
\endgroup%
}%

\newcommand{\ExtractMyTokenB}[1]{% Same as \ExtractMyTokenA, except "\DisablePreamble" is commented.
% #1 = File Name with path
\begingroup%
%\DisablePreamble% This works great for the case where there is no preamble.
% -----------
\let\OldInput\input%         Need to redefine \input as the file being read uses
\renewcommand*{\input}[1]{}% \input before \begin{document}.
% -----------
\edef\FileWithPath{#1}%
\OldInput{\FileWithPath}%
\global\MyToken=\expandafter{\the\MyToken}
\endgroup%
}%

\begin{document}
\ExtractMyTokenB{goo}%  <----- This does not invoke \DisablePreamble, and works
MyToken=\the\MyToken\par
% ------------
\ExtractMyTokenA{foo}%   <----- This invokes \DisablePreamble, which fails
MyToken=\the\MyToken\par
\end{document}

-
So basically I forgot the \makeatletter...\makeatother.. I had a feeling this was probably going to be embarrassing, but didn't think it was that obvious!!!! Thanks again David. – Peter Grill Apr 27 '14 at 2:08