Разрушаемый tcolorbox вызывает рваное дно

Разрушаемый tcolorbox вызывает рваное дно

При использовании tcolorboxс breakableопцией это может привести к "рваному дну" в некоторых особых ситуациях. Следующий MWE демонстрирует это поведение:

\documentclass[DIV=10, BCOR=10mm, twoside]{scrreprt}

\usepackage[ngerman]{babel}
\usepackage{lmodern}
\usepackage{amsmath}
\usepackage{microtype}
\usepackage{lipsum}

\usepackage{tcolorbox}
\tcbuselibrary{theorems, skins, breakable}
\newtcbtheorem[auto counter]{mytheo}{My Theorem}{
  enhanced, breakable, colback=white, colbacktitle=black!15, coltitle=black, fonttitle=\bfseries,
  before skip=15pt plus 4pt minus 2pt,
  after skip =15pt plus 4pt minus 2pt
}{th}

\begin{document}

\lipsum[1-5]

\begin{mytheo}{This is my title}{theoexample}
\lipsum[6]
\end{mytheo}

\lipsum[6-10]

\end{document}

рваное дно

Как вы можете видеть на скриншоте, нижняя часть первой страницы не выровнена. Тем не менее, LaTeX не выводит никаких предупреждений о недозаполнении vbox. Похоже, что какая-то часть невидимого before skipнаходится внизу страницы 1, хотя сама tcolorboxона полностью находится на странице 2.

Если вы удалите эту breakableопцию, это не изменит внешний вид ящика (так как ящик в любом случае не был сломан), но LaTeX предупредит о неполном заполнении vbox, как и ожидалось.

Есть ли возможность решить эту проблему, не отказываясь от бьющихся коробок?

решение1

Следующий ответ действителен для tcolorboxверсий до 3.90 (2016/02/29). Начиная с этой версии, before skipопция не должна оставлять следов при разрыве страницы.

tcolorboxнеобходимо вставить определенный код (включая пропуск перед) перед тем, как можно будет рассчитать оставшуюся высоту. Здесь вставленный пропуск, по всей видимости, не удаляется автоматически.

Я могу предложить следующее «исправление», которое вставляет отрицательный пропуск в \pagebreak. В настоящее время у меня нет времени на дальнейшее исследование возможных негативных последствий этого исправления, но before skipследующее, похоже, работает:

\documentclass[DIV=10, BCOR=10mm, twoside]{scrreprt}

\usepackage[ngerman]{babel}
\usepackage{lmodern}
\usepackage{amsmath}
\usepackage{microtype}
\usepackage{lipsum}


\usepackage{tcolorbox}
\tcbuselibrary{theorems, skins, breakable}

%--- begin patch ---
\makeatletter

\def\tcb@undo@before{}

\tcbset{
  before skip/.style={before={%
    \ifnum\lastnodetype=-1\relax%
    \else%
      \par\ifvmode\nointerlineskip%
      \addvspace{\glueexpr#1-\parskip}%
      \def\tcb@undo@before{\addvspace{-\glueexpr#1}}%
      \fi%
    \fi%
    \lineskip=0pt\noindent%
    }},
}

\def\tcb@split@start{%
  \tcb@breakat@init%
  \tcb@comp@h@page%
  % height calculation
  \tcb@comp@h@total@standalone%
  %
  \let\tcb@split@next=\relax%
  \tcb@check@for@final@box%
  \iftcb@final@box%
    \tcb@drawcolorbox@standalone%
  \else%
    \iftcb@break@allowed%
      \ifdim\dimexpr\tcb@h@page-\tcb@h@padding-\tcb@h@padtitle<\kvtcb@breakminlines\baselineskip\relax%
        \tcb@undo@before\iftcb@multicol\columnbreak\else\pagebreak\fi%            
        \tcb@nobreak@warning%
        \tcb@enlbreak@init\tcb@break@allowedfalse%
        \tcb@comp@h@page%
        \tcb@check@for@final@box%
        \iftcb@final@box%
          \tcb@drawcolorbox@standalone%
        \else%
          \let\tcb@split@next=\tcb@split@first%
        \fi%
      \else%
        \let\tcb@split@next=\tcb@split@first%
      \fi%
    \else%
      \let\tcb@split@next=\tcb@split@first%
    \fi%
  \fi%
  \tcb@split@next%
}

\makeatother
%--- end patch ---

\newtcbtheorem[auto counter]{mytheo}{My Theorem}{
  enhanced,
  breakable,
  colback=white, colbacktitle=black!15, coltitle=black, fonttitle=\bfseries,
  before skip=15pt plus 4pt minus 2pt,
  %before=,
  after skip =15pt plus 4pt minus 2pt
}{th}

\begin{document}

\lipsum[1-5]

\begin{mytheo}{This is my title}{theoexample}
\lipsum[6]
\end{mytheo}

\lipsum[6-10]

\end{document}

Связанный контент