Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Framed environment with title

111 views
Skip to first unread message

Benoit RIVET

unread,
Apr 16, 2011, 9:59:11 AM4/16/11
to
I wish to define a framed environment with a title on the top frame and
which can break across pages. So far, I can create :

1. a framed box using the framed package : this environment
breaks across pages, but I can't figure out how to add a
title,
2. or a framed box with a title using fancybox,

but I can't have a single environment with a title and which can break
across pages. The framed package documentation claims that :

> If you want to attach some text (a box title) to the
> frame, then the text should be inserted by \FrameCommand.

but I did not find out how to achieve it. Here's an example of what I
achieved so far. The titi environment has a title on top, but does not
break across pages, while the Bcouleur environment has no title, but
breaks nicely across pages :

\documentclass{minimal}
\usepackage{framed, xkeyval, xcolor, fancybox, lipsum}

\makeatletter
\newcommand{\@txt@tmp}{}
\newlength{\DSFBox}
\newlength{\SSFBox}
\newlength{\DEFBox}
\newlength{\EFBox}

\define@key{BCouleur}{ctexte}{\def\CTexte{#1}}
\define@key{BCouleur}{cbord}{\def\CBord{#1}}
\define@key{BCouleur}{cfond}{\def\CFond{#1}}
\define@key{BCouleur}{sfbox}{\def\SFBox{#1}}
\define@key{BCouleur}{epaisfbox}{\def\EpaisFBox{#1}}

\setlength{\DSFBox}{5pt}
\setlength{\DEFBox}{3pt}
\setkeys{BCouleur}{ctexte=black,cbord=red,cfond=white,
sfbox=\the\DSFBox,epaisfbox=\the\DEFBox}{}

\newenvironment{BCouleur}[1][]{%
\setkeys{BCouleur}{#1}
\def\FrameCommand{\fboxrule=\FrameRule \fboxsep=\FrameSep
\color{\CTexte}\fcolorbox{\CBord}{\CFond}}
\setlength{\SSFBox}{\SFBox}
\setlength\FrameSep{\the\SSFBox}
\setlength{\EFBox}{\EpaisFBox}
\setlength\FrameRule{\the\EFBox}
\MakeFramed{\advance\hsize-\width \FrameRestore}}%
{\endMakeFramed}

\newenvironment{titi}[1][]{
\renewcommand{\@txt@tmp}{#1}
\begin{lrbox}{\@tempboxa}
\begin{minipage}{0.96\textwidth}}{%
\end{minipage}\end{lrbox}%
\bigskip \noindent
\setlength{\fboxrule}{5pt}
\boxput*(0,1){\colorbox{white}{\@txt@tmp}}
{\fcolorbox{blue}{white}{
\usebox{\@tempboxa}}}\bigskip}

\makeatother

\begin{document}

\begin{titi}[Titre]
\lipsum[1]
\end{titi}

\begin{BCouleur}[cbord=blue, epaisfbox=5pt]
\lipsum
\end{BCouleur}

\end{document}

Benoit RIVET

unread,
Apr 16, 2011, 12:52:50 PM4/16/11
to
Benoit RIVET <benoit...@libre.fr.invalid> wrote:

> I wish to define a framed environment with a title on the top frame and
> which can break across pages.

I found an ugly hack achieving what I want. Strangely enough, this hack
works with the color package and does not with xcolor.

If someone has a better solution to my problem, I would be delighted to
be able to rely on top quality code :-)

Here is the ugly hack (loading xcolor instead of color produces an ugly
output) :

\documentclass[10pt]{article}
\usepackage{framed, xkeyval, color, lipsum}

\makeatletter


\newlength{\DSFBox}
\newlength{\SSFBox}
\newlength{\DEFBox}
\newlength{\EFBox}

\define@key{BCouleur}{ctexte}{\def\CTexte{#1}}
\define@key{BCouleur}{cbord}{\def\CBord{#1}}
\define@key{BCouleur}{cfond}{\def\CFond{#1}}
\define@key{BCouleur}{sfbox}{\def\SFBox{#1}}
\define@key{BCouleur}{epaisfbox}{\def\EpaisFBox{#1}}

\setlength{\DSFBox}{5pt}
\setlength{\DEFBox}{3pt}
\setkeys{BCouleur}{ctexte=black,cbord=red,cfond=white,
sfbox=\the\DSFBox,epaisfbox=\the\DEFBox}{}

\newenvironment{BCouleur}[1][]{%
\setkeys{BCouleur}{#1}
\def\FrameCommand{\fboxrule=\FrameRule \fboxsep=\FrameSep
\color{\CTexte}\fcolorbox{\CBord}{\CFond}}
\setlength{\SSFBox}{\SFBox}
\setlength\FrameSep{\the\SSFBox}
\setlength{\EFBox}{\EpaisFBox}
\setlength\FrameRule{\the\EFBox}
\MakeFramed{\advance\hsize-\width \FrameRestore}}%
{\endMakeFramed}

\newenvironment{titi}[1][]{%
\begin{BCouleur}[cbord=blue, epaisfbox=5pt]
\raisebox{0pt}[0pt][0pt]{\raisebox{1.3ex}{\colorbox{white}{#1}}}

}
{\end{BCouleur}}
\makeatother

\begin{document}

\begin{titi}[Long and stupid title]
\lipsum
\end{titi}

\end{document}

Peter Wilson

unread,
Apr 16, 2011, 2:01:14 PM4/16/11
to

The memoir class provides the `framewithtitle' and `titledframed'
environments which produce a frame, breakable across pages, with a title
either inside or outside the frame.

There is a forthcoming Glisterings article (I think in the next
TUGboat) that describes how to add a title to frames from the framed
package.

Peter W.

GL

unread,
Apr 16, 2011, 2:07:11 PM4/16/11
to
Le 16/04/2011 18:52, Benoit RIVET a écrit :
> Benoit RIVET<benoit...@libre.fr.invalid> wrote:
>
>> I wish to define a framed environment with a title on the top frame and
>> which can break across pages.
>
> I found an ugly hack achieving what I want. Strangely enough, this hack
> works with the color package and does not with xcolor.
>
> If someone has a better solution to my problem, I would be delighted to
> be able to rely on top quality code :-)
>
> Here is the ugly hack (loading xcolor instead of color produces an ugly
> output) :

The xcolor package redefines \colorbox and \fcolorbox even with the
kernelfbox option which applies only to \fbox AFAIK

Restoring the definition of color inside the environment is possible...

% -------------------------------------------------------------------
\PassOptionsToPackage {svgnames,kernelfbox,fixpdftex,xcdraw}{xcolor}
\documentclass[10pt]{article}
\usepackage [T1]{fontenc}
\usepackage {color}\makeatletter \let\color@color@fbox \color@fbox
\usepackage{framed, xcolor, lipsum, pgfkeys,interfaces}
\pdfpageattr{/Group <</S /Transparency /I true /CS /DeviceRGB>>}

\makeatletter
\pgfqkeys{/BCouleur}{
text color/.initial =black,
border/.initial =red,
background/.initial =white,
frame sep/.code =\FrameSep\dimexpr#1\relax,
frame sep/.default =5pt,
thickness/.code =\FrameRule\dimexpr#1\relax,
thickness/.default =3pt,
title/.initial =,
}

\newenvironment{BCouleur}[1][]
{\pgfqkeys{/BCouleur}{#1}\let\color@fbox \color@color@fbox
\def\FrameCommand{%
\fboxrule=\FrameRule \fboxsep=\FrameSep
\color{\pgfkeysvalueof{/BCouleur/text color}}%

\fcolorbox{\pgfkeysvalueof{/BCouleur/border}}{\pgfkeysvalueof{/BCouleur/background}}}%


\MakeFramed{\advance\hsize-\width \FrameRestore }%

\vtop to\z@{\vss\fboxsep0pt\fboxrule0pt
\colorbox{\pgfkeysvalueof{/BCouleur/background}}

{\pgfkeysvalueof{/BCouleur/title}\strut}\par\vskip\dimexpr\ht\strutbox+\fboxrule-2pt}%
}%
{\endMakeFramed}

\newenvironment{titi}[1][]
{\BCouleur[border=blue, thickness=2pt,title={#1}]
\vtop to\z@{\vss\fboxsep0pt\fboxrule0pt
\colorbox{\pgfkeysvalueof{/BCouleur/background}}

{\pgfkeysvalueof{/BCouleur/title}\strut}\par\vskip\dimexpr\ht\strutbox+\fboxrule-2pt}%
}%
\endBCouleur
\makeatother

\begin{document}\makeatletter

\begin{BCouleur}[title=Long and stupid
title,thickness=8pt,border=MidnightBlue,background=yellow!20]
\lipsum
\end{BCouleur}

\end{document}\endinput
% -------------------------------------------------------------

GL

unread,
Apr 16, 2011, 2:09:17 PM4/16/11
to

Yes fine. The problem is that it is a class...
You can't load memoir only for a frame with title for example,
unless I'm wrong ...

Donald Arseneau

unread,
Apr 16, 2011, 9:14:05 PM4/16/11
to
benoit...@libre.fr.invalid (Benoit RIVET) writes:


> I wish to define a framed environment with a title on the top frame and
> which can break across pages. So far, I can create :
>
> 1. a framed box using the framed package : this environment
> breaks across pages, but I can't figure out how to add a
> title,
> 2. or a framed box with a title using fancybox,

If you have #2, then just use it in the definition of #1!

I have used a tabular for a labelled frame, as well as
another definition with variations I'll attach below.
I might add that definition to framed.sty.

Anyway, I assume you want the identical title repeated on each
page.

> > If you want to attach some text (a box title) to the
> > frame, then the text should be inserted by \FrameCommand.
>
> but I did not find out how to achieve it.

> Here's an example of what I achieved so far. The titi
> environment has a title on top, but does not
> break across pages, while the Bcouleur environment has no title, but
> breaks nicely across pages

Use your titi definition, or something close, as the \FrameCommand.
Or, simplify it by leaving out the \bigskips and width setting (should
be better that way).

> \newenvironment{BCouleur}[1][]{%
> \setkeys{BCouleur}{#1}
> \def\FrameCommand{\fboxrule=\FrameRule \fboxsep=\FrameSep
> \color{\CTexte}\fcolorbox{\CBord}{\CFond}}
> \setlength{\SSFBox}{\SFBox}
> \setlength\FrameSep{\the\SSFBox}
> \setlength{\EFBox}{\EpaisFBox}
> \setlength\FrameRule{\the\EFBox}
> \MakeFramed{\advance\hsize-\width \FrameRestore}}%
> {\endMakeFramed}
>
> \newenvironment{titi}[1][]{
> \renewcommand{\@txt@tmp}{#1}
> \begin{lrbox}{\@tempboxa}
> \begin{minipage}{0.96\textwidth}}{%
> \end{minipage}\end{lrbox}%
> \bigskip \noindent
> \setlength{\fboxrule}{5pt}
> \boxput*(0,1){\colorbox{white}{\@txt@tmp}}
> {\fcolorbox{blue}{white}{
> \usebox{\@tempboxa}}}\bigskip}


Yes, best to just use the frame drawing part of titi:

\newcommand\titiframe[2]{%
\setlength{\fboxrule}{5pt}% ... or \FrameRule
\setlength {\fboxsep}{6pt}% ... or \FrameSep
\boxput*(0,1){\colorbox{white}{#1}}%
{\fcolorbox{blue}{white}{#2}}}

% Best not to use \width when there is a title on the frame, because
% the title might affect the width measurement. Instead use the
% known width contributed by the frame: 2*(5+6) = 22
% Or, if you retain the absolute width seting from the previous
% titi, use that same width for \setlength{\hsize} instead
% of \addtolength.
%
\newenvironment{titi}[1][]{\relax
\def\FrameCommand{\titiframe{#1}}%
\MakeFramed {\addtolength{\hsize}{-22pt}\FrameRestore}}
{\endMakeFramed}

This could be upgraded by a test for an empty title.


Here is the titleed frame I have, which is quite specific and does
not use packages.

\newdimen\errorsize \errorsize=0.2pt % Overlap to prevent pixel-sized gaps!


% colored Frame with a label at top; label is in "reverse video"
% Perhaps explicit lengths should be used instead of \FrameRule
% and \FrameSep; 2pt and 8pt work well.
%
\newcommand\LabFrame[2]{%
\fboxrule=\FrameRule
\fboxsep=-\errorsize
\textcolor{FrameColor}{%
\fbox{%
\vbox{\nobreak
\advance\FrameSep\errorsize
\begingroup
\advance\baselineskip\FrameSep
\hrule height \baselineskip
\nobreak
\vskip-\baselineskip
\endgroup
\vskip 0.5\FrameSep
\hbox{\hskip\FrameSep \strut
\textcolor{TitleColor}{\textbf{#1}}}%
\nobreak \nointerlineskip
\vskip 1.3\FrameSep
\hbox{{\hskip\FrameSep
\normalcolor #2%
\hskip\FrameSep}}%
\vskip\FrameSep
}}%
}}
\definecolor{FrameColor}{rgb}{0.2,0.2,0.8}
\definecolor{TitleColor}{rgb}{1.0,1.0,1.0}

% Unlabelled counterpart, if we don't want to repeat the title

\newcommand\UnLabFrame[1]{%
\fboxrule=\FrameRule
\fboxsep=\FrameSep
\textcolor{FrameColor}{\fbox{%
\normalcolor #1}}}


% Simple environment making \LabFrame break across pages; label
% is repeated exactly.
%
\newenvironment{labelframe}[1]{%
\def\FrameCommand{\LabFrame{#1}}%
\MakeFramed{\advance\hsize-2\FrameRule\advance\hsize-2\FrameSep
\FrameRestore}}%
{\endMakeFramed}

% Version of labelframe that prints the label with "(cont.)"
% on subsequent pages. A different continuation label may be
% given as an optional argument.
%
\newenvironment{contlabelframe}[2][\Frame@Lab\ (cont.)]{%
% Optional continuation label defaults to the first label plus (cont.)
\def\Frame@Lab{#2}%
\def\FrameCommand{\LabFrame{#2}}%
\def\FirstFrameCommand{\LabFrame{#2}}%
\def\MidFrameCommand{\LabFrame{#1}}%
\def\LastFrameCommand{\LabFrame{#1}}%
\MakeFramed{\advance\hsize-2\FrameRule\advance\hsize-2\FrameSep
\FrameRestore}}%
{\endMakeFramed}

% Version of labelframe that prints the label only on the first page
%
\newenvironment{onelabelframe}[1]{%
\def\FrameCommand{\LabFrame{#1}}%
\def\FirstFrameCommand{\LabFrame{#1}}%
\def\MidFrameCommand{\UnLabFrame}%
\def\LastFrameCommand{\UnLabFrame}%
\MakeFramed{\advance\hsize-2\FrameRule\advance\hsize-2\FrameSep
\FrameRestore}}%
{\endMakeFramed}

--
Donald Arseneau as...@triumf.ca

Benoit RIVET

unread,
Apr 17, 2011, 6:45:11 AM4/17/11
to
I really appreciate that you took time to answer my question : your code
enables me to do exactly what I needed.

It may be really helpful to include such an example in the documentation
of the framed package (changing the silly titi name to something more
appropriate) : this may help other users know how to encapsulate a
complicated command such as \titiframe in order to create a nice framed
environment breaking across pages.

Thanks a lot for your time and patience,

--
Benoīt RIVET

Benoit RIVET

unread,
Apr 17, 2011, 6:45:11 AM4/17/11
to
Donald Arseneau <as...@triumf.ca> wrote:

> This could be upgraded by a test for an empty title.

That's a question I previously asked myself, but my code was complicated
enough, so that I did not need to include such a refinement.

For those curious about this problem, I found a piece of code on the
internet which solves the problem. The example below shows the code in
action :

\documentclass{article}
\usepackage{lipsum}

\makeatletter
\long\def\tlist@if@empty@nTF #1{%
\expandafter\ifx\expandafter\\\detokenize{#1}\\%
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
}

\newenvironment{exemple}[1][]{%
\tlist@if@empty@nTF{#1}{}{\textbf{#1}}
\par}
\makeatother

\begin{document}

\begin{exemple}
\lipsum[1]
\end{exemple}

\begin{exemple}[Title]
\lipsum[1]
\end{exemple}

GL

unread,
Apr 17, 2011, 7:14:39 AM4/17/11
to
Le 17/04/2011 12:45, Benoit RIVET a écrit :
> Donald Arseneau<as...@triumf.ca> wrote:
>
>> This could be upgraded by a test for an empty title.
>
> That's a question I previously asked myself, but my code was complicated
> enough, so that I did not need to include such a refinement.
>
> For those curious about this problem, I found a piece of code on the
> internet which solves the problem. The example below shows the code in
> action :
>
> \documentclass{article}
> \usepackage{lipsum}
>
> \makeatletter
> \long\def\tlist@if@empty@nTF #1{%
> \expandafter\ifx\expandafter\\\detokenize{#1}\\%
> \expandafter\@firstoftwo
> \else
> \expandafter\@secondoftwo
> \fi
> }

That depends if your title is an argument of a key, then spaces
are trimmed and test for emptyness is the same as test for blank,
better written as:

\ifcat $\detokenize{#1}$

Otherwise, use \ifblank from etoolbox or \ltx@ifblank from ltxcmds.sty

Yours sincerely.

0 new messages