理想情况下,我想写
\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}
导致输出中出现空格。