在另一个环境中更新命令

在另一个环境中更新命令

我创建了一个环境,最后有三个命令。将它们放在 tcolorbox 末尾时,它们不会被编译。请解释为什么下面的代码是错误的?如何纠正它们。

\documentclass{article}
\usepackage{multido}
\newcommand{\dapso}[1]{\renewcommand{\dapsoend}{\par #1}}
\newcommand{\dongke}[1]{\renewcommand{\dongkeend}
    {\multido{}{#1}{\newline.\dotfill}}}
\newcommand{\loigiai}[1]{\renewcommand{\loigiaiend}{\par #1}}
\newcommand{\loigiaiend}{}
\newcommand{\dapsoend}{}
\newcommand{\dongkeend}{}
\newcounter{ex}
\usepackage{tcolorbox}
\newenvironment{ext}{{\refstepcounter{ex}\bfseries Ex \theex}}{\dapsoend\dongkeend\loigiaiend}
\newenvironment{ex}{\begin{tcolorbox}{\refstepcounter{ex}\bfseries Ex \theex}}
    {\end{tcolorbox}\dapsoend\dongkeend\loigiaiend}
\begin{document}
\begin{ext}
    Contents
    \loigiai{Solution \theex}
    \dapso{Answer \theex}
    \dongke{4}
\end{ext}

\begin{ex}
    Contents
    \loigiai{Solution \theex}
    \dapso{Answer \theex}
    \dongke{4}
\end{ex}

\textbf{\large\color{blue}Hope  below results}
\begin{tcolorbox}
\textbf{Ex \theex} Contents
\end{tcolorbox}
\par Solution \theex
\par Answer \theex
\multido{}{4}{\newline.\dotfill}
\end{document}

在此处输入图片描述

答案1

\renewcommand问题在于(和\newcommand)的效果是局部的,并且\begin...\end会创建一个组,因此\renewcommand当组结束时 不再有效。有两种可能的解决方案。

  1. 转到 TeX 基元并改为编写,例如¹

    \NewDocumentCommand{\loigiai}{m}{\gdef\loigiaiend{\par #1\gdef\loigiaiend{}}}
    

    请注意,我在其定义中添加了命令的第二次重新定义,end这样您就不会将该值延续到未指定的其他环境中\loigiai。²

  2. 另一个想法是将对\loigiaiet al. 的调用从环境主体移到环境本身的参数。您的定义将更改为

    \NewDocumentEnvironment{ext}{ m }
        {#1\begin{tcolorbox}{\refstepcounter{ex}\bfseries Ex \theex}}
        {\end{tcolorbox}\dapsoend\dongkeend\loigiaiend}
    

    然后你可以用

    \begin{ext}{%
        \loigiai{Solution \theex}
        \dapso{Answer \theex}
        \dongke{4}
       }
        Contents
    \end{ext}
    

    顺便说一句,\NewDocumentEnvironment的优点在于您可以通过将{ m }定义中的更改为 轻松地将其更改为可选参数{ O{} }

    考虑向环境提供三个参数并让环境本身调用\loigiaiet al 也可能是有意义的:

    \NewDocumentEnvironment{ext}{ mmm }
        {
          \loigiai{#1}
          \dapso{#2}
          \dongke{#3}
          \begin{tcolorbox}{\refstepcounter{ex}\bfseries Ex \theex}}
        {\end{tcolorbox}\dapsoend\dongkeend\loigiaiend}
    

    \theex尽管在论点中看到这样的事情\loigiai让我怀疑你当前的方法是否不能变得更简单。


  1. 继续努力,直至\newcommand灭绝。
  2. 您可能还应该将end命令的初始化替换为 eg \gdef\loigiaiend{}。如果在 LaTeX 中对同一值混合使用全局和本地赋值,则会发生(已记录的)内存泄漏,尽管在这种情况下,情况并不严重。

相关内容