255 lines
10 KiB
TeX
255 lines
10 KiB
TeX
% framed.sty v 0.8a 21-Jul-2003
|
|
% Copyright (C) 1992-2003 by Donald Arseneau
|
|
% These macros may be freely transmitted, reproduced, or modified
|
|
% provided that this notice is left intact.
|
|
%
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
% Create framed or shaded regions that can break across pages using
|
|
% \begin{framed} ... \end{framed} -- ordinary frame box (box at margin)
|
|
% \begin{shaded} ... \end{shaded} -- shaded background (into margin)
|
|
% ... leftbar ... -- line on left side
|
|
% \begin{MakeFramed}{settings} ... \end{MakeFramed}
|
|
% -- generic frame (for new environments)
|
|
%
|
|
% The "framed" environment puts the text into "\fbox" with the
|
|
% settings "\fboxrule=\FrameRule" and "\fboxsep=\FrameSep".
|
|
% You can change these lengths (using "\setlength") and you
|
|
% can even change the definition of "\FrameCommand" to use
|
|
% much fancier boxes.
|
|
%
|
|
% In fact, the "shaded" environment just redefines "\FrameCommand"
|
|
% to use "\colorbox{shadecolor}" (and you have to define the
|
|
% color "shadecolor": \newcolor{shadecolor}...).
|
|
%
|
|
% A page break is allowed, and even encouraged, before the framed
|
|
% environment. If you want to attach some text (a box title) to the
|
|
% frame, then the text should be inserted by \FrameCommand
|
|
%
|
|
% The contents of the framed regions are restricted:
|
|
% Floats, footnotes, marginpars and head-line entries will be lost.
|
|
% (Some of these may be handled in a later version.)
|
|
% This package will not work with the page breaking of multicol.sty,
|
|
% or other systems that perform column-balancing.
|
|
%
|
|
% The MakeFramed environment does the work. Its "settings" argument
|
|
% should contain any adjustments to the text width (applied to \hsize,
|
|
% and using the "\width" of the frame itself) as well as a `restore'
|
|
% command -- \@parboxrestore or \FrameRestore or something similar.
|
|
%
|
|
% Expert commands:
|
|
% \MakeFramed, \endMakeFramed: the "MakeFramed" environment
|
|
% \FrameCommand: command to draw the frame around its argument
|
|
% \FrameRestore: restore some text settings, but fewer than \@parboxrestore
|
|
% \FrameRule: length register; \fboxrule for default "framed".
|
|
% \FrameSep: length register; \fboxsep for default "framed".
|
|
% \FrameHeightAdjust: macro; height of frame above baseline at top of page
|
|
%
|
|
% This is still a `pre-production' version because I can think of many
|
|
% features/improvements that should be made. Nevertheless, starting
|
|
% with version 0.5 it should be bug-free.
|
|
%
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
|
\ProvidesPackage{framed}[2003/07/21 v 0.8a:
|
|
framed or shaded text with page breaks]
|
|
|
|
\newenvironment{framed}% using default \FrameCommand
|
|
{\MakeFramed {\advance\hsize-\width \FrameRestore}}%
|
|
{\endMakeFramed}
|
|
|
|
\newenvironment{shaded}{%
|
|
\def\FrameCommand{\colorbox{shadecolor}}%
|
|
\MakeFramed {\FrameRestore}}%
|
|
{\endMakeFramed}
|
|
|
|
\newenvironment{leftbar}{%
|
|
\def\FrameCommand{\vrule width 3pt \hspace{10pt}}%
|
|
\MakeFramed {\advance\hsize-\width \FrameRestore}}%
|
|
{\endMakeFramed}
|
|
|
|
\chardef\FrameRestore=\catcode`\| % for debug
|
|
\catcode`\|=\catcode`\% % (debug: insert space after backslash)
|
|
|
|
\def\MakeFramed#1{\par
|
|
% measure added width and height; call result \width and \height
|
|
\setbox\z@\vbox{\vskip-1in \hbox{\hskip-1in
|
|
\FrameCommand{\hbox{\vrule \@height .7in \@depth.3in \@width 1in}}}%
|
|
\vskip\z@skip}%
|
|
\def\width{\wd\z@}\def\height{\ht\z@}%
|
|
\edef\fb@frw{\the\width}\edef\fb@frh{\the\height}%
|
|
% insert pre-penalties and skips
|
|
\begingroup
|
|
\skip@\lastskip
|
|
\if@nobreak\else
|
|
\penalty9999 % updates \page parameters
|
|
\ifdim\pagefilstretch=\z@ \ifdim\pagefillstretch=\z@
|
|
\edef\@tempa{\the\skip@}%
|
|
\ifx\@tempa\zero@glue \penalty-30
|
|
\else \vskip-\skip@ \penalty-30 \vskip\skip@
|
|
\fi\fi\fi
|
|
\penalty\z@
|
|
% Give a stretchy breakpoint that will always be taken in preference
|
|
% to the \penalty 9999 used to update page parameters. The cube root
|
|
% of 10000/100 indicates a multiplier of 0.21545, but the maximum
|
|
% calculated badness is really 8192, not 10000, so the multiplier
|
|
% is 0.2301.
|
|
\advance\skip@ \z@ plus-.5\baselineskip
|
|
\advance\skip@ \z@ plus-.231\height
|
|
\advance\skip@ \z@ plus-.231\skip@
|
|
\advance\skip@ \z@ plus-.231\topsep
|
|
\vskip-\skip@ \penalty 1800 \vskip\skip@
|
|
\fi
|
|
\addvspace{\topsep}%
|
|
\endgroup
|
|
% clear out pending page break
|
|
\penalty\@M \vskip 2\baselineskip \vskip\height
|
|
\penalty9999 \vskip -2\baselineskip \vskip-\height
|
|
\penalty9999 % updates \pagetotal
|
|
|\message{After clearout, \pagetotal=\the\pagetotal, \pagegoal=\the\pagegoal. }%
|
|
\fb@adjheight
|
|
\setbox\@tempboxa\vbox\bgroup
|
|
#1% Modifications to \hsize (can use \width and \height)
|
|
\textwidth\hsize \columnwidth\hsize
|
|
}
|
|
|
|
\def\endMakeFramed{\par
|
|
\kern\z@ \penalty-100 % put depth into height
|
|
\egroup
|
|
\begingroup \put@frame \endgroup
|
|
}
|
|
|
|
% \put@frame takes the contents of \@tempboxa and puts all, or a piece,
|
|
% of it on the page with a frame (\FrameCommand). It recurses until
|
|
% all of \@tempboxa has been used up. (\@tempboxa must have zero depth.)
|
|
|
|
\def\put@frame{\relax
|
|
\ifdim\pagegoal=\maxdimen \pagegoal\vsize \fi
|
|
| \message{=============== Entering putframe ====================^^J
|
|
| \pagegoal=\the\pagegoal, \pagetotal=\the\pagetotal. }%
|
|
\ifinner \else
|
|
\dimen@\pagegoal \advance\dimen@-\pagetotal % natural space left on page
|
|
\ifdim\dimen@<2\baselineskip
|
|
| \message{Page has only \the\dimen@\space room left; eject. }%
|
|
\eject \fb@adjheight \put@frame
|
|
\else % there's appreciable room left on the page
|
|
| \message{\string\pagetotal=\the\pagetotal,
|
|
| \string\pagegoal=\the\pagegoal,
|
|
| \string\pagestretch=\the\pagestretch,
|
|
| \string\pageshrink=\the\pageshrink,
|
|
| \string\fb@frh=\fb@frh. \space}
|
|
| \message{Box of size \the\ht\@tempboxa\space + \fb@frh}%
|
|
\begingroup % temporarily set \dimen@ to be...
|
|
\advance\dimen@.8\pageshrink % maximum space available on page
|
|
\advance\dimen@-\fb@frh\relax % space available for frame's contents
|
|
\expandafter\endgroup
|
|
% restore \dimen@ to real room left on page
|
|
\ifdim\dimen@>\ht\@tempboxa % whole box does fit
|
|
| \message{fits in \the\dimen@. }%
|
|
\else % box must be split
|
|
| \message{must be split to fit in \the\dimen@. }%
|
|
\setbox\@tempboxa\vbox{% simulate frame and flexiblity of the page:
|
|
\vskip \fb@frh \@plus\pagestretch \@minus.8\pageshrink
|
|
\kern137sp\kern-137sp\penalty-30
|
|
\unvbox\@tempboxa}%
|
|
\edef\fb@resto@set{\boxmaxdepth\the\boxmaxdepth \splittopskip\the\splittopskip}%
|
|
\boxmaxdepth\z@ \splittopskip\z@
|
|
\setbox\tw@\vsplit\@tempboxa to\dimen@
|
|
\setbox\tw@\vbox{\unvbox\tw@}% natural-sized
|
|
| \message{Box of size \the\ht\@tempboxa\space split to \the\dimen@.
|
|
| Natural height of split box is \the\ht\tw@. }%
|
|
% If the split-to size > (\vsize-\topskip), then set box to full size
|
|
\begingroup
|
|
\advance\dimen@\topskip
|
|
\expandafter\endgroup
|
|
\ifdim\dimen@>\pagegoal
|
|
| \message{Frame is big -- Use up the full column. }%
|
|
\dimen@ii\pagegoal
|
|
\advance\dimen@ii -\topskip
|
|
\advance\dimen@ii \FrameHeightAdjust\relax
|
|
\else % suspect this is wrong:
|
|
% If the split-to size > feasible room_on_page, rebox it smaller.
|
|
\advance\dimen@.8\pageshrink
|
|
\ifdim\ht\tw@>\dimen@
|
|
| \message{Box too tall; rebox it to \the\dimen@. }%
|
|
\dimen@ii\dimen@
|
|
\else % use natural size
|
|
\dimen@ii\ht\tw@
|
|
\fi
|
|
\fi
|
|
% Re-box contents to desired size \dimen@ii
|
|
\advance\dimen@ii -\fb@frh
|
|
\setbox\tw@\vbox to\dimen@ii \bgroup
|
|
% remove simulated frame and page flexibility:
|
|
\vskip -\fb@frh \@plus-\pagestretch \@minus-.8\pageshrink
|
|
\unvbox\tw@ \unpenalty\unpenalty
|
|
\ifdim\lastkern=-137sp % whole box went to next page
|
|
| \message{box split at beginning! }%
|
|
\egroup \fb@resto@set \eject % (\vskip for frame size was discarded)
|
|
\fb@adjheight
|
|
\else %
|
|
\egroup \fb@resto@set
|
|
\ifvoid\@tempboxa % it all fit after all
|
|
| \message{box split at end! }%
|
|
\setbox\@tempboxa\box\tw@
|
|
\else % it really did split
|
|
| \message{box split as expected. Its reboxed height is \the\ht\tw@. }%
|
|
\ifdim\wd\tw@>\z@
|
|
\centerline{\FrameCommand{\box\tw@}}% ??? \centerline bad idea
|
|
\else
|
|
| \message{Zero width means likely blank. Don't frame it (guess)}%
|
|
\box\tw@
|
|
\fi
|
|
\hrule \@height\z@
|
|
\eject
|
|
\fb@adjheight
|
|
\put@frame
|
|
\fi\fi\fi\fi\fi
|
|
\ifvoid\@tempboxa\else
|
|
\centerline{\FrameCommand{\box\@tempboxa}}%
|
|
\nointerlineskip \null %{\showoutput \showlists}
|
|
\penalty-30 \vskip\topsep
|
|
\fi}
|
|
|
|
\def\fb@adjheight{%
|
|
\vbox to\FrameHeightAdjust{}% get proper baseline skip from above.
|
|
\penalty\@M \nointerlineskip
|
|
\vskip-\FrameHeightAdjust
|
|
\penalty\@M} % useful for tops of pages
|
|
|
|
\edef\zero@glue{\the\z@skip}
|
|
|
|
\catcode`\|=\FrameRestore
|
|
|
|
% Provide configuration commands:
|
|
\providecommand\FrameCommand{\fboxrule=\FrameRule \fboxsep=\FrameSep \fbox}
|
|
\@ifundefined{FrameRule}{\newdimen\FrameRule \FrameRule=\fboxrule}{}
|
|
\@ifundefined{FrameSep} {\newdimen\FrameSep \FrameSep =3\fboxsep}{}
|
|
|
|
% Height of frame above first baseline when frame starts a page:
|
|
\providecommand\FrameHeightAdjust{6pt}
|
|
|
|
% \FrameRestore has parts of \@parboxrestore. See how it is used in the
|
|
% "settings" argument of \MakeFrame. Previous behavior can be restored by
|
|
% using \@parboxrestore there, or redefining:
|
|
% \makeatletter \renewcommand\FrameRestore{\@parboxrestore} \makeatother
|
|
\def\FrameRestore{%
|
|
\let\if@nobreak\iffalse
|
|
\let\if@noskipsec\iffalse
|
|
% \let\par\@@par ??
|
|
\let\-\@dischyph
|
|
\let\'\@acci\let\`\@accii\let\=\@acciii
|
|
% \parindent\z@ \parskip\z@skip Definitely omit!
|
|
% \everypar{}% ??
|
|
\linewidth\hsize
|
|
% \@totalleftmargin\z@
|
|
% \leftskip\z@skip \rightskip\z@skip \@rightskip\z@skip
|
|
% \parfillskip\@flushglue \lineskip\normallineskip
|
|
% \baselineskip\normalbaselineskip
|
|
\sloppy
|
|
% \let\\\@normalcr
|
|
}
|
|
|
|
% Compatibility with previous versions (temporary!):
|
|
\let\fram@d=\MakeFramed \let\endfram@d=\endMakeFramed
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|