环境内的 \if 语句

环境内的 \if 语句

理想情况下,我想写

\newif\ifhint
\hintfalse
\newenvironment{myhint}{\ifhint}{\fi}

但是,但是,然后\fi就没有读取!我只想把这整堆东西放在评论中,欢迎任何其他解决方案,除了更改我的 34 个子文件中的所有这些环境——

提前致谢,有些日子我为此而苦苦挣扎!祝好,O。

答案1

\ifhint把里面的命令放进去:

\newif\ifhint
\hintfalse
\newcommand\myhint[1]{\ifhint #1\fi}

如果你喜欢使用环境,那么可以使用-argument 说明\NewDocumentEnvironment符来定义一个环境b解析包裹:

\usepackage{xparse}
\NewDocumentEnvironment{MyHint}{ +b }{\ifhint#1\fi}{}

-argumentb说明符指示环境的主体,并+b允许主体包含段落分隔符。

为了完整起见,这里是 MWE:

\documentclass{article}
\usepackage{xparse}

\newif\ifhint\hintfalse
\newcommand\myhint[1]{\ifhint #1\fi}

\NewDocumentEnvironment{MyHint}{ +b }{\ifhint#1\fi}{}

\begin{document}

  \myhint{This hint is hidden}

  \begin{MyHint}
    This hint is hidden
  \end{MyHint}

  \hinttrue

  \myhint{This hint is not hidden}

  \begin{MyHint}
    This hint is not hidden
  \end{MyHint}

\end{document}

答案2

除了安德鲁的精彩回答之外,了解以下信息可能很有用为什么你没有得到预期的结果。

当你这样做

\newenvironment{foo}{<begin code>}{<end code>}

TeX 在扩展时\begin{foo}会做几件事,其中包括记录它已经开始的环境(以避免不良嵌套),然后进行此项和其他簿记活动,然后将它放入<begin code>输入流中,开始扩展或执行命令。

类似地,当 TeX 扩展时,\end{foo}它会进行一些其他的记录,然后放入<end code>输入流中。

在你的情况下,<begin code>只是\ifhint。当它由于前一个 而返回 true 时\hinttrue,效果是 TeX 记录条件的存在(内部为\iftrue),以便当它找到匹配项时,\fi它将得到满足(基本上,内部计数器会逐步增加,尽管内部工作有点复杂)。宏和命令将正常扩展或执行。

然而,当\ifhint返回 false 时,相同的内部计数器会逐步查找匹配的\fi。但是标记将被丢弃,不做任何解释;仅会注意(原始)条件,以便匹配相应的\else\fi

具体来说,代币\end{myhint}(在你的情况下)将被丢弃,并且不是展开,所以\fi永远不会看到。LaTeX 运行将转到文件末尾,除非\fi出现一些杂散(对于格式良好的代码来说这是不可能的)。

为什么

\NewDocumentEnvironment{myhint}{+b}{\ifhint#1\fi}{}

有效吗?因为b参数类型告诉 TeX 寻找\end{myhint}存储在内存中的所有内容。当它找到时\end{myhint},它将停止存储并将整个内容传递给#1。因此

\begin{myhint}
Some text
\end{myhint}

将会实现

\ifhint Some text\fi

在输入流中。即使返回 false,匹配\fi也不再隐藏。\ifhint

实际上还做了更多的事情,例如,后面的结束行\begin{myhint}不会在输出中添加空格,前面的结束行也不会\end{myhint}导致输出中出现空格。

相关内容