如何创建可隐藏的环境

如何创建可隐藏的环境

我对编写 LaTeX 包还比较陌生。我想创建一个环境,以便在生成输出时可以忽略该环境中包含的任何内容。所需的行为如下:

\documentclass{article}
\usepackage[hide]{MyPackage}
\begin{document}
This should always show up.
\begin{Hidden}
This should show up unless the [hide] option is used.
\end{Hidden}
\end{document}

一种可能的用例:如果我为一个班级编写一个问题集,我可以将解决方案写入隐藏环境中包装的同一文档中。这样,我可以使用 [隐藏] 选项进行编译以生成学生的问题集,并且可以不使用 [隐藏] 选项进行重新编译以生成解决方案集。

这是我目前用来实现这一点的代码。它曾经借用过一个提供类似功能的软件包,但不幸的是我不记得原来的软件包了。

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{MyPackage}
\RequirePackage{ifthen}
\newboolean{MyPackage@hidden}
\setboolean{MyPackage@hidden}{false}
\DeclareOption{hide}{\setboolean{MyPackage@hidden}{true}}
\ProcessOptions\relax
\newenvironment{Hidden}
    {\ifthenelse{\boolean{MyPackage@hidden}}
    {\setbox\z@\vbox\bgroup}{}}
    {\ifthenelse{\boolean{MyPackage@hidden}}{\egroup}{}}

这段代码已经可以正常工作,但主要存在三个问题。首先,当我将图形放入 Hidden 环境中时会出现错误。(在编写家庭作业问题的解决方案时,这是一个相当常见的需求。)以下代码无法编译:

\documentclass{amsart}

\usepackage{amsmath}
\usepackage{tikz}
\usepackage[hidden]{hideexample}

\begin{document}

This always shows up.

\begin{Hidden}
\begin{figure}[h]
\begin{tikzpicture}

\draw (0,0) circle (2cm);

\end{tikzpicture}
\caption{This shows up when not hidden, but causes an error when the [hide] option is used.}
\end{figure}
\end{Hidden}

\end{document}

第二个问题是我想实现多个可隐藏的环境。(扩展家庭作业用例,我可能还想为评分者创建关于如何分配部分学分的说明。因此,我希望能够独立隐藏/显示解决方案和评分者评论。)我不知道如何调整上述代码来实现这一点。我从来没有真正理解过代码的作用,只是它(部分)起作用了。

第三个“问题”实际上不是功能问题,而是另一个特性问题。如果不是 [隐藏]/[显示] 选项,而是 [解决方案] 选项(或类似选项),那么编译文档将同时生成作业集和解决方案集,这将非常方便。(因此,我将处理 HW.tex,编译将同时生成 HW.pdf 和 HW_solutions.pdf。)这样的事情可能吗?

提前致谢。


后续:修改了 Werner 的以下答案后,我使用的代码

\if@hidden
  \long\gdef\hide[#1]#2\ehide{\vspace{#1}}%
\else
  \long\gdef\hide[#1]#2\ehide{#2}%
\fi

这允许以下用途:

\hide[4in]
%stuff
\ehide

当我不使用全局 [hide] 选项时,这会显示 %stuff。当我使用 [hide] 选项时,%stuff 被隐藏,而是显示 4 英寸的垂直空白空间(作为 %stuff 的占位符)。唯一的问题是,这种用法使 [4in] 看起来像是一个可选参数。由于 \def 需要精确的调用匹配,因此该参数实际上是必需的。我如何使这个参数成为可选的(即,以 0in 作为默认值)?

答案1

看起来你试图隐藏相当常见的文档元素。为此,我建议使用以下方法捕获环境内容:environ

在此处输入图片描述

\documentclass{article}

\usepackage{filecontents}

\begin{filecontents*}{MyPackage.sty}
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{MyPackage}
\RequirePackage{environ}
\newif\if@hidden% \@hiddenfalse
\DeclareOption{hide}{\global\@hiddentrue}
\ProcessOptions\relax
\NewEnviron{Hidden}
  {\if@hidden\else\BODY\fi}
\end{filecontents*}

\usepackage[hide]{MyPackage}

\begin{document}

This should always show up.
\begin{Hidden}
This should show up unless the [hide] option is used.
\end{Hidden}

\end{document}

我使用了基本的 TeX 条件语句,而不是xifthen,但这取决于你。参见该包为何ifthen过时了?


如果您希望使用缩写形式隐藏内容,则必须以逐字方式指定它。也就是说,如果您想要\hide定义\ehide要隐藏/不隐藏的捕获内容的开始和结束子句,那么您必须按原样使用它们。以下是包含可选参数的示例,以便\hide您可以指定在选项下留下的垂直间隙[hide]

\documentclass{article}

\usepackage{filecontents}

\begin{filecontents*}{MyPackage.sty}
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{MyPackage}
\newif\if@hidden% \@hiddenfalse
\DeclareOption{hide}{\global\@hiddentrue}
\ProcessOptions\relax
\gdef\hide{\@ifnextchar[\hide@{\hide@[]}}
\if@hidden
  \long\gdef\hide@[#1]#2\ehide{\ifx\relax#1\relax\else\par\rule{0pt}{#1}\fi}% Gobble content between \hide...\ehide
\else
  \long\gdef\hide@[#1]#2\ehide{#2}% Release content between \hide...\ehide (ignore [.]
\fi
\end{filecontents*}

\usepackage[hide]{MyPackage}

\begin{document}

This should always show up.
\hide[2in]
This should show up unless the [hide] option is used.
\ehide

This should also show up.
\hide
This should show up unless the [hide] option is used.
\ehide

This will show up.
\end{document}

请注意,在这些情况下嵌套将不起作用。

相关内容