Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

Consider the following code.

\setbox0 \hbox{XXX}
\fbox{\copy0}

{
        \setbox0\hbox{ZZZ}
        {\wd0 0pt}
        \fbox{\copy0}
}

\fbox{\box0}

This produces three ruled boxes. The two XXXs are inside the rules, the ZZZ is not.

After \wd0 0pt, box 0 has width 0 and this assignment is global which explains why ZZZ is not entirely inside the rules. At the same time, the assignment is local in that it doesn't affect the box 0 which contains the XXX.

What is the purpose of this behavior? Alternatively, what is the utility of being able to set the dimensions of boxes outside the current group?

Edit: To be clear, this was not a question about what the behavior is, it was a question about why Knuth gave TeX this behavior. I thought there might be a use for it that I didn't see since TeX by Topic explicitly mentions it. My suspicion now is that Taco's comment about it being merely an implementation detail, not a design goal, is the right answer.

share|improve this question
add comment

3 Answers

up vote 5 down vote accepted

I am just guessing here, but I believe box dimensions are associated with each box. You don't have special dimen registers for these. This is what I believe happens here. After you enter the first group, at the moment you assign \setbox0\hbox{ZZZ}, TeX assigns a local box register. You then enter the second group, but your box register 0 is still the same \hbox{ZZZ}, TeX will not create a local copy of the box. So when you assign 0pt to \wd0, you modify the \hbox{ZZZ} from the previous group.

Try to modify your code like this:

\setbox0 \hbox{XXX}
\fbox{\copy0}

{
   \wd0 0pt
   \setbox0\hbox{ZZZ}
   {\wd0 0pt}
   \fbox{\copy0}
}

\fbox{\box0}

and see what happens.

Edit: I think the following behavior is related to this:

\setbox0 \hbox{XXX}
\fbox{\copy0}

{
   \fbox{\box0}
}

\fbox{\box0}

Notice that the \box0 inside the group empties the box register, it does not get restored at the end of the group.

share|improve this answer
    
What happens is exactly what I'd expect would happen based on my code example. My question is why does TeX have this behavior? –  TH. Sep 26 '10 at 2:59
1  
Well, the behavior makes pretty good sense to me, it seems to me consistent with the way TeX handle boxes in general. \wd0 0pt modifies an existing box, it does not create a new one. At the moment you call \wd0 0pt at the beginning of a new group (that is before calling \setbox0 ...), the box register 0 still contains the old box 0 inherited from the parent group. So that's the box that will be modified. Once you call \setbox0 ..., the old box is saved and a new one is created, so calling \wd0 0pt after that will modify the new box. –  Jan Hlavacek Sep 26 '10 at 4:54
    
Looks like a good analysis to me: run the example with tracing to see exactly the flow described. You'll see that it's the box which is restored at the end of the level 1 group, not the size and content of the box separately, and that there is no restoring at the end of the level 2 group. –  Joseph Wright Sep 26 '10 at 6:56
3  
@TH: Why TeX82 does what is does is sometimes nothing more than an implementation detail that happens to have a noticeable effect, and I think this is one of these cases. Internally, there is simply no mechanism implemented to store box dimensions as separate from the actual boxes. –  Taco Hoekwater Sep 26 '10 at 7:41
    
@Taco Hoekwater: Okay. I assumed there was some good reason for it. –  TH. Sep 26 '10 at 8:14
show 1 more comment

Maybe one could think of the following “translation” to C:

box *box0 = alloc_hbox("XXX");
fbox(box0);
{
  box *box0 = alloc_hbox("ZZZ");
  {
    /* only affects the box object pointed to by the *inner* box0 */
    box0->width = 0;
  }
  fbox(box0);
}
fbox(box0);

The inner declaration of box0 shadows the outer one, and that's why modifying the object contents (not the pointer) only affects the ZZZ box.

share|improve this answer
    
I think this is the right way to look at the problem. The register is a storage bin containing a single box, and changes to the dimension "of" the register actually change the box inside. The bin itself is never visible except as a reference. –  Ryan Reich Nov 9 '10 at 11:02
add comment

As Jan has stated: box assignments (\setbox, \copy, \box) are subject to grouping, width/height/depth assignments to a box are always connected to a particular box (these are stored inside the first box node itself).

Your second \fbox{\copy0} should be \fbox{\box0}, because it is not used after that. And the grouping in {\wd0 0pt} is useless, because grouping does not make sense here.

So exactly as Jan said.

share|improve this answer
    
I was vacillating between using \box and \copy. They both exhibit the same behavior here. I chose \copy to make clear that it wasn't a feature of TeX's making a box register void after \box. As for the grouping, that was deliberate to show that it modifies the box. It was taken almost verbatim from TeX by Topic's example about box dimension setting being global. –  TH. Sep 26 '10 at 8:08
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.