创造一个将东西存放在盒子里的环境

创造一个将东西存放在盒子里的环境

我试图创建一个环境,它既能显示文本,又能将内容存储在一个框中以供日后使用。为此,我需要使用环境的输入参数来生成命令名称,即\#1。出于某种原因,我无法在 latex 中使用它。

\documentclass{article}
\newenvironment{testenv}[1]
    {   \textbf{Test Environment}
         \newsavebox{\#1}
         \begin{lrbox}{\#1}
    }
    {
        \end{lrbox} \usebox{\#1}
    }


\begin{document}

\begin{pattern}{aaa}
test
\end{pattern}

\usebox{\aaa}

\end{document}

答案1

尝试这个:

\documentclass{article}
\newenvironment{pattern}[1]
 {%
  \newsavebox#1%
  \lrbox#1
 }
 {%
  \endlrbox
 }


\begin{document}

\begin{pattern}{\aaa}
test
\end{pattern}

\usebox{\aaa}

\end{document}

您的代码的最大问题是您无法通过将反斜杠附加到未知文本(如#1)来构造宏名称。这与 TeX 读取其输入的方式有关;当它看到中的内容时#1,它已经停止构造名称了。您可以通过编写来解决这个问题\csname#1\endcsname,但这有一些技术细节,不值得处理,因为您可以首先要求环境的参数pattern是宏名称。

我要做的一个小改动(除了它不能按书面形式编译,因为你做了定义testenv但使用了pattern环境)是直接使用\lrboxand\endlrbox而不是\beginand\end结构。这允许 LaTeX 正确跟踪它是你的打开的环境,而不是lrbox您在其中使用的环境。(如果您搞砸了,它会告诉您lrbox没有正确关闭,这在技术上是正确的,但如果您没有lrbox在文档中明确写出,则并不总是有用的)。

答案2

节省盒子的问题环境是环境内的所有代码通常都是本地的。'lrbox' 环境实际上脱离了其自己的组,以确保框分配是周围范围的一部分。这使得将其作为其他环境的一部分包含起来很困难。使用“纯 TeX 样式” \lrbox..\endlrbox会因为特殊的组处理而导致问题。

您可以复制内部代码lrbox(参见文件latex.ltx),也可以使用全局分配,这将使您的 B 级分数减分,但实现起来要简单得多,并且可能适合您的情况。您可以使用较低级别的 TeX 代码(\setbox使用\bgroup\egroup而不是括号)来存储环境内容。您需要添加内部颜色分组语句,以确保所有颜色宏(如果有)也正确存储在框中。

\documentclass{article}

\makeatletter
\newenvironment{patternn}[1]{%
  \par % I think you should start a paragraph first, but it's up to you
  \textbf{Pattern}%
  \newsavebox{#1}%
  \global\setbox#1\hbox\bgroup\color@setgroup
}{%
  \color@endgroup\egroup
  \usebox{#1}%
}
\makeatother

\begin{document}

\begin{patternn}{\aaa}
test
\end{patternn}

And now try again:
\usebox{\aaa}

\end{document}

答案3

感谢大家的回复,我确实学到了很多关于宏/环境工作原理的知识。我将你们的回答结合到以下内容中,让它完全按照我想要的方式工作!:)

\documentclass{article}

\usepackage{environ}

\NewEnviron{patternn}[1]

{ \textbf{Pattern} \BODY \newsavebox{#1}  \global\sbox{#1}{\BODY} \usebox{#1}}

\begin{document}

\begin{patternn}{\aaa}
test
\end{patternn}

And now try again:
\usebox{\aaa}

\end{document}

相关内容