How to include a second file only if environment variable is set?

I have a LaTeX document which exists in two versions, a short version and the long version. The long version has an additional chapter inserted in the middle of the document. What I want to do, is if I have an environment variable set, include the additional file at the relevant point. So I am doing this (in pdflatex):

\documentclass{book}
\usepackage{etoolbox}
\usepackage{catchfile}
\newcommand{\getenv}[2][]{%
\CatchFileEdef{\temp}{"|kpsewhich --var-value #2"}{}%
\if\relax\detokenize{#1}\relax\temp\else\let#1\temp\fi}
\getenv[\INCLUDE]{INCLUDE}
\begin{document}
First paragraph of first file.

Value of the INCLUDE envvar is as follows: \INCLUDE

\ifstrequal{\INCLUDE}{yes}{\input{file2}}{}

Last paragraph of first file.
\end{document}


I know it can read the environment variable correctly, so I can see the problem is with the conditional, but not sure exactly what I am doing wrong. When I run this with INCLUDE=yes, the value yes is printed, but file2's contents does not appear.

(This is like this question, but that question does not address environment variables. I got my environment variable code from this answer, but since I can print the environment variable correctly, I don't think that is the problem.)

-
Welcome to TeX.SX – Christian Hupfer Jun 15 '14 at 6:36
Something strange goes one with the former post of mine, I have deleted it and will examine. – Christian Hupfer Jun 16 '14 at 10:26
@ChristianHupfer I hope you get it working, because your answer was exactly what I was looking for, if only it worked – Simon Kissane Jun 16 '14 at 22:35
I hope, it works now ;-) – Christian Hupfer Jun 17 '14 at 5:26

Edit

Improved version

There are two basically two problems:

1. \ifstrequal does not expand its arguments
2. The content of the environment variable has a trailing whitespace character at the end, which means yes will become yes' ', so that the test fails. I could not figure out the reason up to now.

By usage of the xstring package command \StrGobbleRight and \ifdefstring from etoolbox package, it is possible to cope around, hopefully, that it is just one character at the end to be deleted. See the effect as diagnostics in the top of the output document, when \temp and \newtemp macros output -- if the whitespace is removed, the content of the environment variable and the following text should be glued together.

I redefined the getenv command to \newgetenv and used an expanded \edef\temp to make the \ifdefstring command work with the literal yes value.

\documentclass{book}%
\usepackage{etoolbox}%
\usepackage{xstring}%
\usepackage{catchfile}%

\newcommand{\getenv}[2][]{%
\CatchFileEdef{\temp}{"|kpsewhich --var-value #2"}{}%
\if\relax\detokenize{#1}\relax\temp\else\let#1\temp\fi}
%\getenv[\INCLUDE]{\string INCLUDE}

\def\newtemp{}%
\newcommand{\newgetenv}[2][]{%
\CatchFileEdef{\temp}{"|kpsewhich --var-value #2"}{}%
\StrGobbleRight{\temp}{1}[\newtemp]%  Delete the trailing whitespace character
\if\relax\detokenize{#1}\relax\temp\else\edef#1{\newtemp}\fi%
}%

\begin{document}
\newgetenv[\INCLUDE]{INCLUDE}%
%%% Diagnostics:
\temp%
Some Text%

\newtemp%
Some Text%

First paragraph of first file.

Value of the INCLUDE envvar is as follows: \INCLUDE

\ifdefstring{\INCLUDE}{yes}{\input{file2}}{Nothing to do in here}

Last paragraph of first file.

\end{document}


The file file2.tex just contains the line

\textbf{Hello World}


Another version (Thanks to the hint made by H. Oberdiek)

The trailing whitespace(\endlinechar) can be omitted by using \endlinechar=-1\relax as 3rd argument to \CatchFileEdef command. This simplifies the handling of the environment variable macro and the usage of xstring package can be dropped.

\documentclass{book}%
\usepackage{etoolbox}%
\usepackage{catchfile}%

\newcommand{\newgetenv}[2][]{%
\CatchFileEdef{\temp}{"|kpsewhich --var-value #2"}{\endlinechar=-1\relax}%
\if\relax\detokenize{#1}\relax\temp\else\edef#1{\temp}\fi%
}%

\begin{document}
\newgetenv[\INCLUDE]{INCLUDE}%

First paragraph of first file.

Value of the INCLUDE envvar is as follows: \INCLUDE

\ifdefstring{\INCLUDE}{yes}{\input{file2}}{Nothing to do in here}

Last paragraph of first file.

\end{document}


I did not update the screenshot, nothing essential has changed in the output.

-
If it works this way is just by chance; better doing it in the proper way: \expandafter\ifstrequal\expandafter{\INCLUDE}{yes}{...} – egreg Jun 15 '14 at 8:43
@egreg: Thanks, I have already suspected, that it would not be sufficient. I will update – Christian Hupfer Jun 15 '14 at 8:51
The space at the end of the command result can be avoided by using \endlinechar=-1\relax in the third argument of \CatchFileEdef. – Heiko Oberdiek Jun 17 '14 at 6:13
@HeikoOberdiek: I will update later on, but thanks for that information – Christian Hupfer Jun 17 '14 at 6:24
yes, this works and is exactly what I was looking for. Thanks! – Simon Kissane Jun 19 '14 at 4:42

You are using the book class with chapters. Then it is easy with \includeonly

\documentclass{book}
\includeonly{file2,file3}% controlls what will be included
\begin{document}
First paragraph of first file.

\include{file2}
\include{file3}

Last paragraph of first file.
\end{document}


You can also use an external file include.cfg which has only the \includeonly{...} line:

\documentclass{book}
\InputIfFileExists{include.cfg}% controlls what will be included
\begin{document}

-
I think this paginates the short version as if all the unincluded files were there. That may or may not suit the OP. – Ethan Bolker Jun 17 '14 at 13:25

An alternative way that doesn't require shell escape. Let's say your file is called file1.tex. Then you can organize it as follows:

\documentclass{book}

\providecommand{\INCLUDE}[1]{}

\begin{document}
First paragraph of first file.

\INCLUDE{file2}

Last paragraph of first file.
\end{document}


If you call the LaTeX run by

pdflatex "\$INCLUDE\input{file1}"


then, if you don't set INCLUDE in the environment the result would be that \INCLUDE has no effect. On the other hand, setting

export INCLUDE='\let\INCLUDE\input'


the same command line as before will input file2.

-