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.
References:
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:- I have two temp files
foo.tex
andgoo.tex
as test cases. - The macros
\ExtractMyTokenA
and\ExtractMyTokenA
are pretty much identical: Once calls\DisablePreamble
and the other does not.
- I have two temp files
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
%% https://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}
\makeatletter
required?