嵌套环境问题

嵌套环境问题

我在嵌套环境方面遇到了问题。我为此创建了一个 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

您的test1test2环境必须相继使用,因此另一种策略可能更好:

\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。这是不允许的,因为通过定义和,您定义了两个新的作用域。一旦您在它们内部使用环境,您还必须完成它们test1test2test1test2在同一范围。这是一条基本的编程规则;不幸的是,你不可能像这样分解环境。

相关内容