3

I am writing an environment to format its content in a box with a background and that can be split across pages. I am using a splitting algorithm similar to the one used in the boites package.

I want to fill the background (and also do other things, like draw a frame with rounded corners) using tikz. But some unwanted vertical spacing are being inserted between some lines. This spacing does not appear when I use \colorbox to fill the background.

Here is a minimal working example that shows the problem:

\documentclass{article}
\usepackage[paperwidth=140mm,paperheight=55mm,margin=5mm]{geometry}
\usepackage{tikz}
\usepackage{multicol}
\pagestyle{plain}

\makeatletter

% The purpose of the `brbox` environment below is to typeset a box with
% a given background colour. The box may be split by page breaks.
% 
% The algorithm used is similar to the one found in the `boites`
% package:
% 
% - first the text is formatted in a vbox
%
% - then each line of the vbox is extracted from the vbox and output in
%   a colorbox.

\newbox\boxhead
\newbox\boxtail
\newbox\boxtemp
\newdimen\dimtemp
\newif\ifbrbox@continue

% split \boxtail between the first line (to be stored in \boxhead) and
% the rest (to be stored in \boxtail);
\def\@boxsplit{%
  % total height (height + depth) of original box
  \dimtemp\ht\boxtail
  \advance\dimtemp\dp\boxtail
  % split original box in order to retrieve its first line
  \setbox\boxhead\vsplit\boxtail to \z@
  % the height and depth of the first box are zero: fix them
  \setbox\boxhead\vbox{\unvbox\boxhead}%
  \wd\boxhead\linewidth%?????????????????????????????????????????????????
  \ifvoid\boxtail
  \else
    % the gap (interline space) between first line and the rest has been
    % lost; restore original size: the difference of the original total
    % height and the total height of each box
    \setbox\boxtemp\vbox{\copy\boxhead\copy\boxtail}%
    \advance\dimtemp-\ht\boxtemp
    \advance\dimtemp-\dp\boxtemp
    \advance\dimtemp\dp\boxhead
    \dp\boxhead\dimtemp
  \fi
}

% add \fboxsep to the last line
\def\brbox@addfsepdp{%
  \dimtemp\dp\boxhead
  \advance\dimtemp\fboxsep
  \dp\boxhead\dimtemp
}

\newenvironment{brbox}{%
  \setbox\boxtail\vbox\bgroup
}{%
  \egroup
  {%
    \noindent
    \splittopskip\z@ % glue inserted at the top of a box resulting from a \vsplit
    \baselineskip\z@
    \lineskiplimit\z@
    \lineskip\z@
    \vfuzz\maxdimen
    \@boxsplit
    \setbox\boxhead\vbox{\vskip\fboxsep\box\boxhead}% add \fboxsep to the first line
    \leavevmode
    \ifvoid\boxtail
      \brbox@addfsepdp % add \fboxsep to the last line
      \brbox@singleline
    \else
      \brbox@firstline
      \hfil
      \brbox@continuetrue
      \loop
        \@boxsplit
        \leavevmode
        \ifvoid\boxtail
          \brbox@addfsepdp % add \fboxsep to the last line
          \brbox@lastline
          \brbox@continuefalse
        \else
          \brbox@middleline
          \hfil
        \fi
        \ifbrbox@continue\repeat
    \fi
  }%
}


\def\brbox@tikzline{\tikz\node[inner xsep=0pt,inner ysep=0pt,fill=yellow!30](p){\copy\boxhead};}
\def\tikzlines{%
  \let\brbox@singleline \brbox@tikzline
  \let\brbox@firstline  \brbox@tikzline
  \let\brbox@middleline \brbox@tikzline
  \let\brbox@lastline   \brbox@tikzline
}
\tikzlines

% alternative: use colorbox to fill the background of the box
\def\brbox@bgline{{\fboxsep\z@ \colorbox{yellow!35}{\box\boxhead}}}

\def\bglines{%
  \let\brbox@singleline \brbox@bgline
  \let\brbox@firstline  \brbox@bgline
  \let\brbox@middleline \brbox@bgline
  \let\brbox@lastline   \brbox@bgline
}

\makeatother


\newcommand{\mytext}{%
  \LaTeX\ is a high-quality typesetting system; it includes features
  designed for the production of technical and scientific
  documentation.
  \LaTeX\ is the de facto standard for the communication and publication
  of scientific documents.
}

\begin{document}

\begin{multicols}{3}
  \mytext

  \columnbreak
  \begin{brbox} \mytext \end{brbox}

  \columnbreak
  \bglines
  \begin{brbox} \mytext \end{brbox}
\end{multicols}

\end{document}

enter image description here

How can I eliminate the extra vertical spacing that appears only when tikz is used?

This looks like a tikz bug.

  • 3
    Do you know that with tcolorbox or mdframed you can also format framed boxes with page breaks? Here you have an example – Ignasi Nov 15 '13 at 11:21
  • @Ignasi I know that. But the algorithm they use to split a box across pages have limitations that I need to overcome. For instance, it does not work with the beamer class. It also does not work with nested boxes. The algorithm I am implementing does not have such limitations. – Romildo Nov 15 '13 at 11:55
  • Did you ever report this at SourceForge? That is the place for bug reports, this site isn't. – Torbjørn T. May 7 '16 at 21:25
  • Any updates here? – Bobyandbob Feb 9 '18 at 21:37
  • @Romildo, have you considered accepting egreg's answer? – PatrickT Jan 26 at 10:48
4

You're missing a \par (and also to set \parindent to zero). I also set \hbadness in order to avoid spurious warnings.

\documentclass{article}
\usepackage[paperwidth=140mm,paperheight=55mm,margin=5mm]{geometry}
\usepackage{tikz}
\usepackage{multicol}
\pagestyle{plain}

\makeatletter

% The purpose of the `brbox` environment below is to typeset a box with
% a given background colour. The box may be split by page breaks.
% 
% The algorithm used is similar to the one found in the `boites`
% package:
% 
% - first the text is formatted in a vbox
%
% - then each line of the vbox is extracted from the vbox and output in
%   a colorbox.

\newbox\boxhead
\newbox\boxtail
\newbox\boxtemp
\newdimen\dimtemp
\newif\ifbrbox@continue

% split \boxtail between the first line (to be stored in \boxhead) and
% the rest (to be stored in \boxtail);
\def\@boxsplit{%
  % total height (height + depth) of original box
  \dimtemp\ht\boxtail
  \advance\dimtemp\dp\boxtail
  % split original box in order to retrieve its first line
  \setbox\boxhead\vsplit\boxtail to \z@
  % the height and depth of the first box are zero: fix them
  \setbox\boxhead\vbox{\unvbox\boxhead}%
  \wd\boxhead\linewidth%?????????????????????????????????????????????????
  \ifvoid\boxtail
  \else
    % the gap (interline space) between first line and the rest has been
    % lost; restore original size: the difference of the original total
    % height and the total height of each box
    \setbox\boxtemp\vbox{\copy\boxhead\copy\boxtail}%
    \advance\dimtemp-\ht\boxtemp
    \advance\dimtemp-\dp\boxtemp
    \advance\dimtemp\dp\boxhead
    \dp\boxhead\dimtemp
  \fi
}

% add \fboxsep to the last line
\def\brbox@addfsepdp{%
  \dimtemp\dp\boxhead
  \advance\dimtemp\fboxsep
  \dp\boxhead\dimtemp
}

\newenvironment{brbox}{%
  \setbox\boxtail\vbox\bgroup
}{%
  \egroup
  {%
    \parindent0pt     %<--- added
    \hbadness=10000   %<--- added
    \splittopskip\z@ % glue inserted at the top of a box resulting from a \vsplit
    \baselineskip\z@
    \lineskiplimit\z@
    \lineskip\z@
    \vfuzz\maxdimen
    \@boxsplit
    \setbox\boxhead\vbox{\vskip\fboxsep\box\boxhead}% add \fboxsep to the first line
    \leavevmode
    \ifvoid\boxtail
      \brbox@addfsepdp % add \fboxsep to the last line
      \brbox@singleline
    \else
      \brbox@firstline
      \hfil
      \brbox@continuetrue
      \loop
        \@boxsplit
        \leavevmode
        \ifvoid\boxtail
          \brbox@addfsepdp % add \fboxsep to the last line
          \brbox@lastline
          \brbox@continuefalse
        \else
          \brbox@middleline
          \hfil
        \fi
        \ifbrbox@continue\repeat
    \fi
    \par %<--- added
  }%
}


\def\brbox@tikzline{%
  \tikz\node[inner xsep=0pt,inner ysep=0pt,fill=yellow!30](p){\copy\boxhead};\hfill
}
\def\tikzlines{%
  \let\brbox@singleline \brbox@tikzline
  \let\brbox@firstline  \brbox@tikzline
  \let\brbox@middleline \brbox@tikzline
  \let\brbox@lastline   \brbox@tikzline
}
\tikzlines

% alternative: use colorbox to fill the background of the box
\def\brbox@bgline{{\fboxsep\z@ \colorbox{yellow!35}{\box\boxhead}}}

\def\bglines{%
  \let\brbox@singleline \brbox@bgline
  \let\brbox@firstline  \brbox@bgline
  \let\brbox@middleline \brbox@bgline
  \let\brbox@lastline   \brbox@bgline
}

\makeatother


\newcommand{\mytext}{%
  \LaTeX\ is a high-quality typesetting system; it includes features
  designed for the production of technical and scientific
  documentation.
  \LaTeX\ is the de facto standard for the communication and publication
  of scientific documents.
}

\begin{document}

\begin{multicols}{3}
  \mytext

  \columnbreak

  \begin{brbox} \mytext \end{brbox}

  \columnbreak

  \bglines
  \begin{brbox} \mytext \end{brbox}

\end{multicols}

\end{document}

I marked the changes with <--- added.

enter image description here

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.