[Tex/LaTex] Identify tcolorbox page breaks

tcolorbox

I would like to render a breakable tcolorbox with mulitple short paragraphs of text where each pair of paragraphs is separated by a rule.

\documentclass{article}

\usepackage{pgffor}
\usepackage{tcolorbox}
\tcbuselibrary{breakable}

\begin{document}

\begin{tcolorbox}[breakable]

\foreach \n in {1, ..., 10}
  {
    text\par
   \hrulefill\par
  }

\end{tcolorbox}

\end{document}

Page breaks should only occur at the rules. When a page break occurs, I would like to remove the rule that is right before or right after the page break as the paragraphs are already separated by the page break. Is there some way to identify the position at which a page break occurs within a breakable tcolorbox?

Best Answer

The short answer is:

  • Secure the text parts which should not break by putting them into a minipage.
  • Put your separating rule into a construction with e.g. \cleaders or \xleaders. This will make the line vanish at box breaks.

The long answer uses \tcbline* from the current tcolorbox development (unpublished yet; will be in version 3.10). I put this as a patch into the following source code.

This \tcbline* vanishes at box breaks. Further, its style can be set with segmentation style. My example shows two variants.

From your question, I presume that you want to have the partial boxes closed:

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

\makeatletter

%%%% begin patch for tcolorbox older than 3.10 %%%%%
\def\tcb@draw@pseudo@segmentation#1{%
\begingroup\tcb@shield@externalize\begin{tikzpicture}%
  \path[use as bounding box] (0,{\the\dimexpr-\kvtcb@middle-\kvtcb@boxsep\relax})
     rectangle (\linewidth,{\the\dimexpr\kvtcb@middle+\kvtcb@boxsep\relax});
  \node[line width=0mm,inner sep=0mm,draw=none,fill=none,rectangle,
        name=segmentation,at={({\the\dimexpr-\kvtcb@boxsep-(#1)\relax},0)},right,%
        minimum width=\tcb@innerwidth,minimum height=\the\dimexpr\kvtcb@middle*2\relax]{};
  \tcb@drawlower@path%
\end{tikzpicture}\endgroup}

\def\tcbline@star#1{%
{\parskip\z@\par\nointerlineskip}%
\xleaders\vbox{\tcb@draw@pseudo@segmentation{#1}}\vskip\dimexpr(\kvtcb@middle+\kvtcb@boxsep)*2\relax%
{\parskip\z@\par\nointerlineskip}}

\def\tcbline@#1{%
{\parskip\z@\par\nointerlineskip}%
\tcb@draw@pseudo@segmentation{#1}%
{\parskip\z@\par\nointerlineskip}}

\def\tcbline{%
  \@ifstar{\iftcb@hasLower\tcbline@star{\kvtcb@leftlower}\else\tcbline@star{\kvtcb@leftupper}\fi}%
  {\iftcb@hasLower\tcbline@{\kvtcb@leftlower+\@totalleftmargin}\else\tcbline@{\kvtcb@leftupper+\@totalleftmargin}\fi}}
%%%% end patch for tcolorbox older than 3.10 %%%%%

\makeatother

\begin{document}

%%% Example with thick complete lines
\begin{tcolorbox}[breakable,
  enhanced standard,% for segmentation style
  segmentation style={solid,line width=0.5mm},
  ]
  \foreach \n in {1,...,10}
  {
    \begin{minipage}{\linewidth}
    \lipsum[\n]
    \end{minipage}
    \tcbline*
  }
\end{tcolorbox}

\clearpage

%%% Example with hrule style line (in red, for fun)
\begin{tcolorbox}[breakable,
  enhanced standard,% for segmentation style
  segmentation style={solid,line width=0.4pt,
    shorten >=5mm,shorten <=5mm,red},
  ]
  \foreach \n in {1,...,10}
  {
    \begin{minipage}{\linewidth}
    \lipsum[\n]
    \end{minipage}
    \tcbline*
  }
\end{tcolorbox}

\end{document}

First example part with thick lines:

enter image description here

Second example part with thin red (and shorter) lines:

enter image description here

Related Question