我创建了一个环境,最后有三个命令。将它们放在 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
当组结束时 不再有效。有两种可能的解决方案。
转到 TeX 基元并改为编写,例如¹
\NewDocumentCommand{\loigiai}{m}{\gdef\loigiaiend{\par #1\gdef\loigiaiend{}}}
请注意,我在其定义中添加了命令的第二次重新定义,
end
这样您就不会将该值延续到未指定的其他环境中\loigiai
。²另一个想法是将对
\loigiai
et 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{} }
。考虑向环境提供三个参数并让环境本身调用
\loigiai
et al 也可能是有意义的:\NewDocumentEnvironment{ext}{ mmm } { \loigiai{#1} \dapso{#2} \dongke{#3} \begin{tcolorbox}{\refstepcounter{ex}\bfseries Ex \theex}} {\end{tcolorbox}\dapsoend\dongkeend\loigiaiend}
\theex
尽管在论点中看到这样的事情\loigiai
让我怀疑你当前的方法是否不能变得更简单。
- 继续努力,直至
\newcommand
灭绝。 - 您可能还应该将
end
命令的初始化替换为 eg\gdef\loigiaiend{}
。如果在 LaTeX 中对同一值混合使用全局和本地赋值,则会发生(已记录的)内存泄漏,尽管在这种情况下,情况并不严重。