仅当设置了环境变量时如何包含第二个文件?

仅当设置了环境变量时如何包含第二个文件?

我有一个 LaTeX 文档,有两个版本,一个短版,一个长版。长版在文档中间插入了一个附加章节。我想要做的是,如果我设置了环境变量,则在相关位置包含附加文件。所以我这样做(在 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}

我知道它可以正确读取环境变量,所以我知道问题出在条件上,但不确定我到底做错了什么。当我使用 INCLUDE=yes 运行此程序时,会打印值 yes,但不会显示 file2 的内容。

(这就像这个问题,但这个问题没有解决环境变量问题。我的环境变量代码来自这个答案,但由于我可以正确打印环境变量,所以我不认为这是问题所在。)

答案1

编辑

改良版

基本上有两个问题:

  1. \ifstrequal没有扩展其论点
  2. 环境变量的内容末尾有一个空格,表示yes将变为yes' ',因此测试失败。我到现在都找不到原因。

通过使用xstringpackage 命令\StrGobbleRight\ifdefstringfrom etoolboxpackage,可以解决这个问题,但愿只是末尾的一个字符需要删除。在输出文档顶部的诊断中可以看到效果,当\temp\newtemp宏输出时——如果删除了空格,环境变量的内容和后面的文本应该会粘在一起。

我重新定义了该getenv命令,\newgetenv并使用了扩展\edef\temp以使该\ifdefstring命令与文字值一起工作yes

\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}

该文件file2.tex仅包含以下行

\textbf{Hello World}

enter image description here

另一个版本(感谢 H. Oberdiek 的提示)

\endlinechar可以通过将结尾的空格 ( ) 用作命令\endlinechar=-1\relax的第三个参数来省略它。这简化了环境变量宏的处理,并且可以删除包\CatchFileEdef的使用。xstring

\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}

我没有更新屏幕截图,输出中没有任何本质变化。

答案2

另一种不需要 shell 转义的方法。假设您的文件名为file1.tex。那么您可以按如下方式组织它:

\documentclass{book}

\providecommand{\INCLUDE}[1]{}

\begin{document}
First paragraph of first file.

\INCLUDE{file2}

Last paragraph of first file.
\end{document}

如果你调用 LaTeX 运行

pdflatex "$INCLUDE\input{file1}"

那么,如果你没有INCLUDE在环境中设置,结果将是\INCLUDE无效的。另一方面,设置

export INCLUDE='\let\INCLUDE\input'

与之前相同的命令行将输入file2

答案3

您正在使用带有章节的书籍类。然后很容易\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}

include.cfg您还可以使用仅包含以下行的外部文件\includeonly{...}

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

相关内容