8

I want to \vsplit a box with quite arbitrary content. If the content does some color changes, strange things happen.

The following MWE demonstrates the problem. The example text changes font and color of the second paragraph. When this paragraph is split, the red color bleeds outside the box, see inter text while the font change is restricted to the box.

By the way: setting the color to black before the inter text worsen the problem, because then the third paragraph and everything after the second box is painted red.

How do I have to adapt the \splitmytext macro (and maybe the \savemytext macro) to avoid this color bleeding problem?

\documentclass{article}
\usepackage{xcolor,lipsum}

\newbox\mwebox
\newbox\firstbox

\newcommand{\savemytext}[2]{%
  \setbox\mwebox\vbox{\hsize=#1\relax#2}}

\newcommand{\splitmytext}[1]{%
  \setbox\firstbox\vsplit\mwebox to #1}

\begin{document}

\savemytext{10cm}{%
  \lipsum[1]
  {\itshape\bfseries\color{red}
  \lipsum[2]
  }
  \lipsum[3]
}

\splitmytext{7cm}

\fbox{\box\firstbox}

inter text

\fbox{\box\mwebox}

after text

\end{document}

enter image description here

  • this is "as expected", but i don't have a clear idea what to do about it. the problem is that colour is always set in a group, and unset immediately after the \egroup\endgroup. i can't think, off hand, of a way of getting the end-grouping into the end of the top bit, and then add a colour command at the beginning of the bottom bit. – wasteofspace Dec 20 '13 at 10:07
  • 2
    The hardest part of latex color support was not the color package it was ensuring all the box commands in the latex format didn't break when color was loaded. Welcome to the club:-) – David Carlisle Dec 20 '13 at 10:30
6

Firstly if there is colour around you always need to make sure that your boxes are double grouped so

\setbox\mwebox\vbox{{\hsize=#1\relax#2\endgraf}}

not

  \setbox\mwebox\vbox{\hsize=#1\relax#2}}

or

  \setbox\mwebox\vbox{\color@begingroup\hsize=#1\relax#2\color@endgroup}

which adds the \endgraf for you.

The reason for that is \color{red} is really

\driver-specific-set-color{red}\aftergroup\reset@color

where \reste@color is \driver-specific-set-color{\currentcolor} or \pop-current-color depending on the back end driver.

This is what gives the colour commands the appearance of following TeX grouping, like font commands.

Without the double group, a \color command in the top level list of a saved box causes the font setting to be saved in the box, but the colour restore is placed by the \aftergroup outside the setting so tries to pop the colour stack at the point of the box save (at which point there may be no colours on the stack). Usually with pdftex this is just ignored (at this point) with dvips on early laserwiters you would crash the printer which is why latex goes to some effort to ensure this doesn't happen if you use supported latex commands (which doesn't include vbox and vsplit:-)

With the double grouping the colour restore comes at the end of the box, inside the box.

However if you then vsplit the box you end up with a color push in one half and a color pop in the other. If you know (by maintaining extra state in the macro layer) that that is the case, you can of course insert primitive pdftex colour commands to do a pop at the end of the first half and re-assert the colour (without doing a colour restore) at the start of the second half.

If however the content is arbitrary user content that may have colour commands you have a problem that in classic tex you can not query the box list to discover the colour specials as as soon as you find a whatsit you can not see past it (there is \unskip \unbox etc but no\unwhatsit. At this point you start to wonder about switching to luatex....

  • I had my fears that there might be no solving answer to my question. But you never know without asking ;-) I just wonder, if it is possible to clear the color stack completely? Let's say at the end of the last box (assumed it is on the top level) to be sure everything is alright afterwards? – Thomas F. Sturm Dec 20 '13 at 11:33
  • @ThomasF.Sturm not at the tex level, but if you commit to one back end (eg pdftex) it may be possible to inject raw pdf code in at that point to clear its colour stack but you'd need to ask on the pdftex list, if you inject pdf commands into the pdf stream being generated by pdftex you need to have a pretty good idea of the structure of that stream, and it's been a decade or two since I looked at that:-) – David Carlisle Dec 20 '13 at 11:38
  • No, for me it is enough to know that there's no TeX level solution; that keeps me from trying things which cannot work ;-) – Thomas F. Sturm Dec 20 '13 at 11:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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