% \iffalse %% %% File `dashbox.dtx'. %% Copyright (C) 1997-2001 Reuben Thomas (rrt@sc3d.org) %% This file is distributed under the LaTeX Project Public License, %% and comes with no warranty. %% % %<*dtx> \ProvidesFile{dashbox.dtx} % % \ProvidesFile{dashbox.drv} % \fi % % \iffalse %<*driver> \documentclass{ltxdoc} \usepackage{url,dashbox} \begin{document} \DocInput{dashbox.dtx} \end{document} % % \fi % % \GetFileInfo{dashbox.dtx} % \CheckSum{336} % % \MakeShortVerb{\|} % % \changes{v1.00}{7 Mar 97}{First version (unreleased)} % \changes{v1.10}{97}{Layered boxes added} % \changes{v1.11}{2 Jun 97}{Minor formatting improvements; first release} % \changes{v1.12}{28 Jul 01}{Made into a doc package; documentation % added. Default number of layers changed to 3, and at signs inserted % into private macro names. Tidied up some infelicities.} % \changes{v1.13}{8 Aug 01}{Uncommented the TeX lines from % |\NeedsTeXFormat| onwards; oops! Renamed to dashbox to avoid % confusion.} % \changes{v1.14}{11 Dec 01}{Changed ``dashed'' to ``dash'' in command % names, to avoid confusion. Changed default number of layers back to 2.} % % \title{Dashed and layered boxes} % \author{Reuben Thomas\\\url{rrt@sc3d.org}} % \date{11th December 2001} % \maketitle % % \begin{abstract} % |dashbox| provides new commands similar to |\framebox| and |\fbox| % to typeset dashed and layered boxes. % \end{abstract} % % % \section{User interface} % % The following commands are provided: % % \begin{itemize} % \item[]\hskip-\leftmargin % \DescribeMacro{\dbox} % |\dbox{|\textit{text}|}| works like |\fbox|, but the box is drawn % with \dbox{dashed lines}. % \item[]\hskip-\leftmargin % \DescribeMacro{\dashbox} % |\dashbox[|\textit{width}|][|\textit{pos}|]{|\textit{text}|}| % works like |\framebox|, but the box is drawn with % \dashbox[5cm][c]{dashed lines}. % \item[]\hskip-\leftmargin % \DescribeMacro{\lbox} % |\lbox[|\textit{layers}|]{|\textit{text}|}| draws a % \lbox{\fbox{stack of boxes}} around its contents, with the number % of layers given by the first parameter (default 2). % \item[]\hskip-\leftmargin % \DescribeMacro{\dlbox} % |\dlbox[|\textit{layers}|]{|\textit{text}|}| works like |\lbox|, % but the boxes are drawn with \dlbox[2]{\dbox{dashed lines}}. % \end{itemize} % % The following style parameters are available: % % \begin{itemize} % \item[]\hskip-\leftmargin % \DescribeMacro{\dashlength} % |\dashlength| gives the length of a dash plus the following % gap. The default is 6pt. % \item[]\hskip-\leftmargin % \DescribeMacro{\dashdash} % |\dashdash| gives the length of a dash. The default is 3pt. % \item[]\hskip-\leftmargin % \DescribeMacro{\layersize} % |\layersize| gives the protrusion of each layer below the previous % one. The default is |\dashdash|. % \end{itemize} % % The following standard parameters are also observed: % % \begin{itemize} % \item[]\hskip-\leftmargin % \DescribeMacro{\fboxrule} % |\fboxrule| gives the width of the dashes. % \item[]\hskip-\leftmargin % \DescribeMacro{\fboxsep} % |\fboxsep| gives the separation between the box and text inside it. % \end{itemize} % \StopEventually{} % % % \section{Implementation} % % \subsection{Preliminaries} % % Make sure we've got what we need, and announce the package. % % \begin{macrocode} %<*package> \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{dashbox} [2001/12/11 v1.14 Dashed and layered boxes] \RequirePackage{calc} \RequirePackage{ifthen} % \end{macrocode} % % \subsection{Style parameters} % % Define and give the default values of the style parameters. % % \begin{macro}{\dashlength} % \begin{macrocode} \newlength{\dashlength} \setlength{\dashlength}{6pt} % \end{macrocode} % \end{macro} % \begin{macro}{\dashdash} % \begin{macrocode} \newlength{\dashdash} \setlength{\dashdash}{3pt} % \end{macrocode} % \end{macro} % \begin{macro}{\layersize} % \begin{macrocode} \newlength{\layersize} \setlength{\layersize}{\dashdash} % \end{macrocode} % \end{macro} % % \subsection{Dashes} % % We need two new commands for drawing horizontal and vertical dashes. % % \begin{macro}{\hd@shrule} % |\hd@shrule| takes one argument, the rule's width. The thickness of % the dash is given by |\fboxrule|. % % \begin{macrocode} \newcommand{\hd@shrule}[1]{% \hbox to #1% {\vrule height \fboxrule width \dashdash% \cleaders\hbox to \dashlength% {\hfill\rule{\dashdash}{\fboxrule}\hfill}\hfill% \ifthenelse{\lengthtest{#1 > 2\dashdash}}% {\vrule height \fboxrule width \dashdash}{}% }} % \end{macrocode} % \end{macro} % % \begin{macro}{\vd@shrule} % |\vd@shrule| takes one argument, the rule's height. The thickness of % the dash is given by |\fboxrule|. % % \begin{macrocode} \newcommand{\vd@shrule}[1]{% \vbox to #1% {\hrule height \dashdash width \fboxrule% \cleaders\vbox to \dashlength% {\vfill\rule{\fboxrule}{\dashdash}\vfill}\vfill% \ifthenelse{\lengthtest{#1 > 2\dashdash}}% {\hrule height \dashdash width \fboxrule}{}% }} % \end{macrocode} % \end{macro} % % \subsection{Dashed boxes} % % A private save box and some lengths are defined. |\d@ashedsavebox| % is a box to hold the contents of a dashed box. |\d@shedboxwidth| is % the box's width, and |\d@shedboxtotalheight| is the height plus the % depth. % % \begin{macro}{\d@shedsavebox} % \begin{macrocode} \newsavebox{\d@shedsavebox} % \end{macrocode} % \end{macro} % \begin{macro}{\d@shedboxwidth} % \begin{macrocode} \newlength{\d@shedboxwidth} % \end{macrocode} % \end{macro} % \begin{macro}{\d@shedboxtotalheight} % \begin{macrocode} \newlength{\d@shedboxtotalheight} % \end{macrocode} % \end{macro} % % \begin{macro}{\m@kedashbox} % |\m@kedashbox| is where the work is actually done. It puts the box % together piece by piece. It requires |\d@shedboxwidth| to be set by % its caller. % % \begin{macrocode} \newcommand{\m@kedashbox}{% % \end{macrocode} % % The height plus depth of the box is calculated. % % \begin{macrocode} \setlength{\d@shedboxtotalheight}% {\dp\d@shedsavebox+\ht\d@shedsavebox+\fboxsep*2+\fboxrule*2}% % \end{macrocode} % % The box is raised an appropriate amount, and drawn in a |b|-aligned % parbox. % % \begin{macrocode} \raisebox{-\fboxrule-\fboxsep-\dp\d@shedsavebox}{% \parbox[b]{\d@shedboxwidth}{% % \end{macrocode} % % Inter-line and inter-paragraph skip are disabled. % % \begin{macrocode} \offinterlineskip% \parskip=0pt% % \end{macrocode} % % The top line is drawn; the kern makes the left and right sides line % up properly. % % \begin{macrocode} \hd@shrule{\d@shedboxwidth}% \kern-\fboxrule% \par% % \end{macrocode} % % The left-hand side is now drawn, in a parbox of the correct width. % % \begin{macrocode} \parbox{\fboxrule}{\vd@shrule{\d@shedboxtotalheight}}% % \end{macrocode} % % Now the inside of the box is set in a parbox, with |\fboxsep| space % top and bottom. The kerns add |\fboxsep| space at the left and % right. % % \begin{macrocode} \kern\fboxsep% \parbox{\wd\d@shedsavebox}% {\vspace{\fboxsep}\usebox{\d@shedsavebox}\vspace{\fboxsep}}% \kern\fboxsep% % \end{macrocode} % % The right-hand side is drawn just like the left-hand side, and the % bottom just like the top. % % \begin{macrocode} \parbox{\fboxrule}{\vd@shrule{\d@shedboxtotalheight}}% \par% \kern-\fboxrule% \hd@shrule{\d@shedboxwidth}}% }} % \end{macrocode} % \end{macro} % % \begin{macro}{\dbox} % |\dbox| is just a wrapper around |\m@kedashbox| which saves its % argument and then calculates the width according to that of its % argument. % % \begin{macrocode} \newcommand{\dbox}[1]{% \sbox{\d@shedsavebox}{#1}% \setlength{\d@shedboxwidth}{\wd\d@shedsavebox+\fboxsep*2+\fboxrule*2}% \m@kedashbox} % \end{macrocode} % \end{macro} % % \begin{macro}{\dashbox} % The code for |\dashbox| is partly taken from that for |\framebox|. % Depending on whether any optional arguments are given, it either % simply calls |\dbox|, or sets the width to that given and does the % typesetting via |\savebox| and |\m@kedashbox|. % % \begin{macrocode} \def\dashbox{\@ifnextchar[\@dashbox\dbox} \def\@dashbox[#1]{\@ifnextchar[{\@idashbox[#1]}{\@idashbox[#1][c]}} \long\def\@idashbox[#1][#2]#3% {\setlength{\d@shedboxwidth}{#1}% \savebox{\d@shedsavebox}[#1-\fboxsep*2-\fboxrule*2][#2]{#3}% \m@kedashbox} % \end{macrocode} % \end{macro} % % \subsection{Layers} % % Another series of private variables are required for layers: % |\l@yersavebox| holds the text to be set in a layer, % |\l@yerwidth| holds the total width of the layer, % |\l@yerboxwidth| the width of the layer box, % |\l@yertotalheight| the height plus depth of the layer. % |\l@yerlineheight| the lift of the top right-hand line, and % |\l@yervoffset| the lift of the layer below the baseline. % % \begin{macro}{\l@yersavebox} % \begin{macrocode} \newsavebox{\l@yersavebox} % \end{macrocode} % \end{macro} % \begin{macro}{\l@yerwidth} % \begin{macrocode} \newlength{\l@yerwidth} % \end{macrocode} % \end{macro} % \begin{macro}{\l@yerboxwidth} % \begin{macrocode} \newlength{\l@yerboxwidth} % \end{macrocode} % \end{macro} % \begin{macro}{\l@yertotalheight} % \begin{macrocode} \newlength{\l@yertotalheight} % \end{macrocode} % \end{macro} % \begin{macro}{\l@yerlineheight} % \begin{macrocode} \newlength{\l@yerlineheight} % \end{macrocode} % \end{macro} % \begin{macro}{\l@yervoffset} % \begin{macrocode} \newlength{\l@yervoffset} % \end{macrocode} % \end{macro} % % \begin{macro}{\m@kelayer} % |\m@kelayer| makes a solid layer. % % \begin{macrocode} \newcommand{\m@kelayer}[1]{% % \end{macrocode} % % The various lengths are calculated. The argument gives the number of % the layer, i.e.\ how far down it should be offset from its contents % as a multiple of |\layersize|. % % \begin{macrocode} \setlength{\l@yertotalheight}% {\dp\l@yersavebox+\ht\l@yersavebox+\layersize-#1\layersize}% \setlength{\l@yerlineheight}% {\ht\l@yersavebox-#1\layersize-\fboxrule}% \setlength{\l@yervoffset}% {-\layersize-\dp\l@yersavebox}% \setlength{\l@yerboxwidth}% {\wd\l@yersavebox+\layersize-#1\layersize}% % \end{macrocode} % % The layer is set in a parbox of width |\l@yerwidth|. % % \begin{macrocode} \parbox{\l@yerwidth}{% % \end{macrocode} % % Inter-line and inter-paragraph spacing are turned off. % % \begin{macrocode} \offinterlineskip% \parskip=0pt% % \end{macrocode} % % The contents of the layer is set first. % % \begin{macrocode} \usebox{\l@yersavebox}% % \end{macrocode} % % The extra ``corner'' is added on to the bottom right. % % \begin{macrocode} \rule[\l@yerlineheight]{\layersize}{\fboxrule}% \kern-\fboxrule% \rule[\l@yervoffset]{\fboxrule}{\l@yertotalheight}% \kern-\wd\l@yersavebox\kern-\layersize\kern#1\layersize \rule[\l@yervoffset]{\fboxrule}{\layersize}% \kern-\fboxrule \rule[\l@yervoffset]{\l@yerboxwidth}{\fboxrule}% }} % \end{macrocode} % \end{macro} % % \begin{macro}{\l@yer} % |\l@yer| draws a layer. The first argument gives the number of the % layer, and the second its contents. % % \begin{macrocode} \newcommand{\l@yer}[2]{% \sbox{\l@yersavebox}{#2}% \setlength{\l@yerwidth}{\wd\l@yersavebox+\layersize}% \m@kelayer{#1}} % \end{macrocode} % \end{macro} % % \begin{macro}{\m@kedashlayer} % |\m@kedashlayer| makes a dashed layer. The code is the same as for % |\m@kelayer| except for the dash commands. % % \begin{macrocode} \newcommand{\m@kedashlayer}[1]{% \setlength{\l@yertotalheight}% {\dp\l@yersavebox+\ht\l@yersavebox+\layersize-#1\layersize}% \setlength{\l@yerlineheight}{\ht\l@yersavebox-#1\layersize-\fboxrule}% \setlength{\l@yervoffset}{-\layersize-\dp\l@yersavebox}% \setlength{\l@yerboxwidth}% {\wd\l@yersavebox+\layersize-#1\layersize}% \parbox{\l@yerwidth}{% \offinterlineskip% \parskip=0pt% \usebox{\l@yersavebox}% \raisebox{\l@yerlineheight}{\hd@shrule{\layersize}}% \kern-\fboxrule% \raisebox{\l@yervoffset}% {\parbox[b]{\fboxrule}{\vd@shrule{\l@yertotalheight}}}% \kern-\wd\l@yersavebox\kern-\layersize\kern#1\layersize \raisebox{\l@yervoffset}% {\parbox[b]{\fboxrule}{\vd@shrule{\layersize}}}% \kern-\fboxrule \raisebox{\l@yervoffset}% {\hd@shrule{\l@yerboxwidth}}% }} % \end{macrocoode} % \end{macro} % % \begin{macro}{\dl@yer} % |\dl@yer| draws a dashed layer, just like |\l@yer| draws a solid % one. % % \begin{macrocode} \newcommand{\dl@yer}[2] {\sbox{\l@yersavebox}{#2}% \setlength{\l@yerwidth}{\wd\l@yersavebox+\layersize}% \m@kedashlayer{#1}} % \end{macrocode} % \end{macro} % % \subsection{Stacks} % % Finally, the commands for drawing a stack of layers. % % |l@yercount| counts the number of layers drawn by the stack drawing % \begin{macro}{l@yercount} % \begin{macrocode} \newcounter{l@yercount} % \end{macrocode} % \end{macro} % % \begin{macro}{\l@yers} % |\l@yers| draws a stack of layers; it is parametrized on the command % used to draw a layer (third argument). The first argument is number % of layers, and the second is the text to set. The layers are drawn % in in a loop, using |\l@yersavebox| as an accumulator, and the % result is typeset. % % \begin{macrocode} \newcommand{\l@yers}[3] {\setcounter{l@yercount}{1}% \sbox{\l@yersavebox}{#2}% \whiledo{\not\(\value{l@yercount} > #1\)}% {\sbox{\l@yersavebox}% {#3{\value{l@yercount}}{\usebox{\l@yersavebox}}}% \stepcounter{l@yercount}}% \usebox{\l@yersavebox}% } % \end{macrocode} % \end{macro} % % |\lbox| and |\dlbox| are just wrappers for |\l@yers|. They both % default to drawing two layers. % % \begin{macro}{\lbox} % \begin{macrocode} \newcommand{\lbox}[2][2]{% \l@yers{#1}{#2}{\l@yer}} % \end{macrocode} % \end{macro} % \begin{macro}{\dlbox} % \begin{macrocode} \newcommand{\dlbox}[2][2]{% \l@yers{#1}{#2}{\dl@yer}} % % \end{macrocode} % \end{macro} % % \Finale \endinput