我在嵌套环境方面遇到了问题。我为此创建了一个 MWE。我有环境 {env1},我想以以下方式包含环境 {env2} 和 {env3}。以下代码有什么问题?
\documentclass{article}
\newenvironment{env1}{}{}
\newenvironment{env2}{}{}
\newenvironment{env3}{}{}
\newenvironment{test1}%
{\begin{env1} \begin{env2}}%
{\end{env2}}
\newenvironment{test2}%
{\begin{env3}}%
{\end{env3} \end{env1}}
\begin{document}
\begin{test1}
This is test1
\end{test1}
\begin{test2}
This is test2
\end{test2}
\end{document}
编辑:
看来为了解决这个问题,我需要给出我冗长的代码的细节……(因为太长而想避免它)所以这就是:我尝试应用 Patrick 的补丁,因为它看起来最接近我想要的。不幸的是它不起作用。
在我的代码中,env1=block,env2=exercise*,env3=solution*,test1=exercise,test2=solution。“exercise”和“solution”宏旨在简化练习块仅包含 1 个练习和 1 个解决方案时的编写,并自动围绕练习*和解决方案*构建块。
\documentclass{article}
\usepackage{color}
\newcommand{\thickline}{\noindent\textcolor{blue}{\rule{\textwidth}{5pt}}}
\newenvironment{block}
{\bigskip\par\thickline\nopagebreak\par%
\begin{minipage}{\dimexpr\textwidth-\parindent\relax}\small}
{\end{minipage}\par\smallskip\nopagebreak\thickline\bigskip}
\newenvironment{exercise*}[1]
{\medskip\smallskip\par\noindent\textbf{Exercise (#1):}}
{\bigskip}
\newenvironment{solution*}
{\par\noindent\textbf{Solution:}}
{\medskip\smallskip}
%***Patrick's solution:*** (doesn't seem to work, see below)
\newenvironment{exercise}[1]%
{\csname block\endcsname \begin{exercise*}{#1}}%
{\end{exercise*}}
\newenvironment{solution}%
{\begin{solution*}}%
{\end{solution*} \csname endblock\endcsname}
%**************
\begin{document}
%This works. (using the 3 environments)
\begin{block}
\begin{exercise*}{hmmm}
First exercise
\end{exercise*}
\begin{solution*}
First Solution
\end{solution*}
\end{block}
%This doesn't work (Patrick's definitions with csname):
\begin{exercise}{hmmm}
exercise
\end{exercise}
\begin{solution}
solution
\end{solution}
%************
\end{document}
编辑2
如果该块由多个练习组成,我希望它们用一条细线分隔,定义为
\newcommand{\thinline}{\noindent\textcolor{red}{\rule{\textwidth}{2pt}}}
粗线位于区块的开始和结束处。因此,如果区块中有 2 个练习,则它看起来会像这样:
\粗线
练习(第一个练习):
这是练习 1
解决方案:
解决方案 1
\细线
练习(第二个练习):
这是练习 2
解决方案:
解决方案 2
\粗线
答案1
您的test1
和test2
环境必须相继使用,因此另一种策略可能更好:
\newenvironment{test}
{\begin{env1}\begin{env2}}
{\end{env3}\end{env1}}
\newcommand{\testbreak}[1]{\end{env2}#1\begin{env3}}
\begin{test}
Contents for env2
\testbreak{...}
Contents for env3
\end{test}
env2
可以在和之间设置的文本env3
可以作为的参数指定\testbreak
,并带有合适的定义。
编辑:
根据你举的例子,建议是
\newif\ifsolution
\newenvironment{exercise}[1]
{\begin{block}\begin{exercise*}{#1}}
{\ifsolution\end{solution*}\else\end{exercise*}\fi\end{block}}
\newcommand\solution{\end{exercise*}\solutiontrue\begin{solution*}}
然后可以在环境中排版练习exercise
,然后\solution
(可能不存在)开始解决方案。
\begin{exercise}{difficult}
exercise
\solution
solution
\end{exercise}
\begin{exercise}{easy}
exercise
\end{exercise}
答案2
我认为不推荐这样做,因为它没有进行适当的环境初始化/检查。一些 LaTeX 专家可以解释缺少了什么。
\documentclass{article}
\newenvironment{env1}{(begin env1)}{(end env1)}
\newenvironment{env2}{(begin env2)}{(end env2)}
\newenvironment{env3}{(begin env3)}{(end env3)}
\newenvironment{test1}%
{\csname env1\endcsname \begin{env2}}%
{\end{env2}}
\newenvironment{test2}%
{\begin{env3}}%
{\end{env3} \csname endenv1\endcsname}
\begin{document}
\begin{test1}
This is test1
\end{test1}
\begin{test2}
This is test2
\end{test2}
\end{document}
该\csname env1\endcsname
构造构建了一个控制序列\env1
,其中 1 是宏名称的一部分。当宏名称中包含数字时,您必须做出特殊安排来创建宏名称。
答案3
您不能以这种方式嵌套环境。环境必须有一个\begin{env-name}
和语句。当您将和\end{env-name}
的开头和结尾分开时,您违反了该规则env1
。这是不允许的,因为通过定义和,您定义了两个新的作用域。一旦您在它们内部使用环境,您还必须完成它们test1
test2
test1
test2
在同一范围。这是一条基本的编程规则;不幸的是,你不可能像这样分解环境。