17

The tcolorbox package provides breakable boxes. Also, a tcolorbox can be nested inside another tcolorbox, even inside a breakable one. But there is no real support for nesting a breakable box inside a breakable box. Breakability is switched off for inner boxes, but it may be switched on again by using the breakable key.

In retrospective, this feature (to switch breakability for inner boxes on) has been a permanent pitfall for users, since it's quite easy to misuse the breakable key as the following example shows:

\documentclass[a4paper]{article}

\usepackage[many]{tcolorbox}
\usepackage{lipsum}

\newtcolorbox{redbox}{colframe=red,enhanced,breakable}
\newtcolorbox{bluebox}{colframe=blue,enhanced,breakable}

\begin{document}

\begin{redbox}
\lipsum[1-4]
\end{redbox}

\begin{bluebox}
  \begin{redbox}% gives shattered boxes (until tcolorbox 3.04)
  \lipsum[1-4]
  \end{redbox}
\end{bluebox}

\end{document}

Therefore, I would like to disable the breakable key for inner boxes completely and remove this pitfall.

The only thing which worries me is loss of backward compatibility. That's the reason for this question. Under very controlled circumstances, the current feature could have been used to get breakable boxes inside breakable boxes. But to be clear: it's not possible for normal usage.

Is anything speaking against declaring this feature a misbehavior and therefore remove it?

  • 1
    Well, that is up to the developer of this nice package :-) No, seriously: I think you have a good reasons to change the semantics of the implementation. The main points to consider is how to deal with backward compatibility: Provide a class-level key that permits users to enable the old behavior, maybe with in combination with "this deprecated and will be removed in a future version" warnings. – Daniel May 23 '14 at 12:04
  • I had to do something similar in stackengine early on concerning the way I defined stacking gaps. In my case, I was able to employ an [oldsyntax] option to provide it the old way. That way, old code could break (because this option would not have already been set in old code), but a quick perusal of the docs would allow the former solution to be restored, while at the same time alerting the user to the new syntax. – Steven B. Segletes May 23 '14 at 12:06
  • 5
    I think you should be able to have a breakable tcolorbox inside a broken footnote in a longtable that's inside an outer tcolorbox, in beamer. All inter-package compatibility issues to be directed to tcolorbox, seems reasonable to me (and the kind of thing longtable users expect to work:-) – David Carlisle May 23 '14 at 12:09
  • @DavidCarlisle That request reminds me of Churchill's quote at the onset of WWII about Russia: "a riddle wrapped in a mystery inside an enigma". "Rough times lie ahead," indeed. – Steven B. Segletes May 23 '14 at 12:14
  • @DavidCarlisle That's a good point. I have to check if such kind of applications would stop working. – Thomas F. Sturm May 23 '14 at 12:19
6

Considering all the helpful comments, I think it is very unlikely but possible that existing applications could stop working as before, if inner boxes are forced to be unbreakable.

So, the answer to question is: Yes, tcolorbox should enforce inner boxes to be unbreakable, but the old behavior should be optionally accessible.

  • The next version of tcolorbox (3.05 or 3.10) will disable the breakable key for inner boxes. I expect that this helps many users avoiding trouble.
  • There will be an additional enforce breakable key which allows to set inner boxes to be breakable (as in 3.04 or before). This is intended for the unlikely cases where the old behavior is needed.

For the current version 3.04, the following patch can be applied:

% insert after tcolorbox v3.04 and the breakable library is loaded
% remove for tcolobox 3.05 or higher
\makeatletter
\def\tcb@layer@inc{%
  \stepcounter{tcblayer}%
  \ifnum\c@tcblayer>1%
    \tcbset{breakable@true/.code=}%
  \fi%
  \ifnum\c@tcblayer>\tcb@managed@layers@max%
    \tcbset{every box on higher layers}%
  \else%
    \expandafter\setbox\csname tcb@footnote@\romannumeral\c@tcblayer\endcsname\box\@mpfootins%
    \csedef{tcb@footnote@cnt@\romannumeral\c@tcblayer}{\the\c@mpfootnote}%
    \tcbset{every box on layer \number\c@tcblayer}%
  \fi%
}

\def\tcb@layer@pushup{%
  \stepcounter{tcblayer}%
  \ifnum\c@tcblayer>1%
    \tcbset{breakable@true/.code=}%
  \fi%
  \ifnum\c@tcblayer>\tcb@managed@layers@max%
    \tcbset{every box on higher layers}%
    \tcbset{every box on higher layers/.code=}%
  \else%
    \tcbset{every box on layer \number\c@tcblayer}%
    \tcbset{every box on layer \number\c@tcblayer/.code=}%
  \fi%
  \addtocounter{tcblayer}{-1}%
}

\tcbset{enforce breakable/.code={%
    \let\tcb@savebox=\tcb@vbox%
    \let\endtcb@savebox=\endtcb@vbox%
    \let\tcb@drawcolorbox=\tcb@drawcolorbox@breakable}}

\makeatother
  • Above you said that the breakable inner boxes could work under yery controlled circumstances. Maybe you could add a check for things which would break? Like, if \par would lead to problems, you could redefine \par to give an error message inside an inner breakable box. In that case, in some sense the "very controlled circumstances" could be enforced. – Stephan Lehmke May 24 '14 at 8:24
  • It's really about impossible to get satisfying results, because the computation of available space before break for the inner box will fail and could only be adjusted by hand, if you know where the outer box is positioned on the page. Instead of very controlled I should have said totally unpracticable ... – Thomas F. Sturm May 24 '14 at 8:58

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.