为什么关闭环境后盒子似乎被清空了

为什么关闭环境后盒子似乎被清空了

我试图填充环境中的框,以便在环境关闭后使用,类似于\begin{lrbox}{\boxname} ... \end{lrbox}工作原理。但是,出于某种原因,关闭环境后框中的内容似乎消失了。

\newsavebox{\somebox}

\newenvironment{myenv}
{
    \begin{lrbox}{\somebox}
}{
    \end{lrbox}
    \usebox{\somebox} % This works
}

\begin{myenv}
    Something
\end{myenv}

\usebox{\somebox} % This doesn't

在上面的例子中\usebox{\somebox}myenv的结束块似乎按预期工作,但如果在 之后使用则不行\end{myenv}。 也许我对环境和/或框有一些基本的了解,但我希望我尝试做的事情是可能的,因为这就是环境的lrbox工作方式?

答案1

环境的整个思想是它们的工作发生在它们自己的组中(就好像代码被包围一样{...}。因此,根据设计,环境中发生的事情是外部代码无法访问的,除非环境全局保存其内容。

正如 OP 从我的评论中得出的结论,通过\somebox在离开环境之前全局保存 的内容,可以使内容可访问。David 建议使用\setbox而不是\sbox,作为使分配全局化的可靠方法:

\documentclass{article}
\newsavebox{\somebox}

\newenvironment{myenv}
{
    \begin{lrbox}{\somebox}
}{
    \end{lrbox}
    \usebox{\somebox} % This works
    \global\setbox\somebox=\hbox{\usebox{\somebox}}%
}

\begin{document}
\begin{myenv}
    Something
\end{myenv}

\usebox{\somebox} % This now works with \somebox globally saved

\end{document}

问题不在于lrbox阻止其工作被重新使用,而在于的关闭myenv有效地将lrbox与主代码隔离开来。

答案2

myenv框是由 LaTeX 本地分配的,因此分配结束后就会丢失。

\newsavebox{\somebox}% for global assignment
\newsavebox{\someboxinternal}% for local assignment
\newenvironment{myenv}
 {%
  \begin{lrbox}{\someboxinternal}%
 }
 {%
  \end{lrbox}%
  \global\setbox\somebox=\hbox{\unhbox\someboxinternal}%
  %\usebox{\somebox}% <-- if you want to use it inside myenv
 }

这和史蒂文的回答

  1. 盒子寄存器\somebox仅全局分配:应避免对同一寄存器进行本地和全局分配
  2. 没有像\global\setbox\somebox=\hbox{\usebox{\somebox}}

如果我跑

\showboxbreadth=1000 \showboxdepth=1000
\tracingonline=1
\documentclass{article}

\newsavebox{\somebox}% for global assignment
\newsavebox{\someboxinternal}% for local assignment
\newenvironment{myenv}
 {%
  \begin{lrbox}{\someboxinternal}%
 }
 {%
  \end{lrbox}%
  \global\setbox\somebox=\hbox{\unhbox\someboxinternal}%
  %\usebox{\somebox}% <-- if you want to use it inside myenv
 }

\begin{document}

\begin{myenv}
abc
\end{myenv}

\showbox\somebox

\stop

控制台显示

> \box50=
\hbox(6.94444+0.0)x15.27782
.\OT1/cmr/m/n/10 a
.\OT1/cmr/m/n/10 b
.\kern0.27779
.\OT1/cmr/m/n/10 c

如果我将全局分配替换为

\global\setbox\somebox=\hbox{\usebox\someboxinternal}%

控制台显示

> \box50=
\hbox(6.94444+0.0)x15.27782
.\hbox(6.94444+0.0)x15.27782
..\OT1/cmr/m/n/10 a
..\OT1/cmr/m/n/10 b
..\kern0.27779
..\OT1/cmr/m/n/10 c

你就会看到嵌套。

答案3

另一个答案提到了问题的原因(LaTeX 环境创建了一个组)。您只能使用 TeX 基元,这样可以让您更好地控制所做的事情:

\newbox\somebox

\def\myenv{\global\setbox\somebox\hbox\bgroup\bgroup\ignorespaces}
\def\endmyenv{\unskip\egroup\egroup}

\begin{myenv}
    Something
\end{myenv}

\box\somebox % This does

由于 LaTeX 的色彩管理,这里有双重“与\bgroup” 。\egoup

答案4

我是 environ 包的粉丝,所以我将根据 Steven 的版本添加我的版本。

\documentclass{article}
\usepackage{environ} 
 
\begin{document}

\newsavebox{\somebox} 

\NewEnviron{myenv}{ 
\begin{lrbox}{\somebox} 
\BODY
\end{lrbox} 
\usebox{\somebox}
\global\setbox\somebox=\hbox{\usebox{\somebox}}
} 

Abc
\begin{myenv} Something \end{myenv} 


Def
\usebox{\somebox} 

If you only want to reuse stuff, you can go like this:

\NewEnviron{myenvII}{
\global\let\mycmd\BODY
\mycmd
} 

\begin{myenvII} Another thing \end{myenvII}

\mycmd

\end{document}

相关内容