%D \module %D [ file=pack-rul, % was core-rul, %D version=1998.10.16, %D title=\CONTEXT\ Packaging Macros, %D subtitle=Ruled Content, %D author=Hans Hagen, %D date=\currentdate, %D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] %C %C This module is part of the \CONTEXT\ macro||package and is %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. \writestatus{loading}{ConTeXt Packaging Macros / Ruled Content} %D The code here is expanded lots of time as framed is used in %D many places. This is why the code here is (and gets) optimized %D as much as possible. Also, by avoiding packaging and expansion %D we also keep tracing reasonable. For instance, multiple stacked %D backgrounds can slow down a run if not optimized this way. % eventually this will use the commandhandler code (same trick as % with itemize) \registerctxluafile{pack-rul}{1.001} \unprotect %D \macros %D {linewidth, setuplinewidth} %D %D This module deals with rules (lines) in several ways. First %D we introduce two macros that can be used to set some common %D characteristics. %D %D \showsetup{setuplinewidth} %D %D The linewidth is available in \type{\linewidth}. The %D preset value of .4pt equals the default hard coded \TEX\ %D rule width. \newdimen\linewidth \unexpanded\def\setuplinewidth {\dosingleargument\pack_framed_setup_line_width} \def\pack_framed_setup_line_width[#1]% {\assigndimension{#1}\linewidth{.2\points}{.4\points}{.6\points}} %D \macros %D {setupscreens} %D %D Sort of obsolete: %D %D \showsetup{setupscreens} \unexpanded\def\setupscreens {\dodoubleargument\getparameters[\??rs]} %D The parameter handler: \installcorenamespace{framed} \installcorenamespace{framedtop} \installcorenamespace{framedbottom} \installcorenamespace{framedleft} \installcorenamespace{framedright} \let\currentframed\s!unknown % brrr must have a value % \def\framedparameter #1{\csname\doframedparameter\currentframed{#1}\endcsname} % \def\framedparameterhash#1{\doframedparameterhash \currentframed#1} \def\framedparameter #1{\csname\ifcsname\currentframed#1\endcsname\currentframed#1\else\expandafter\doframedparentparameter\csname\currentframed\s!parent\endcsname{#1}\fi\endcsname} \def\framedparameterhash#1{\ifcsname\currentframed#1\endcsname\currentframed\else\expandafter\doframedparentparameterhash\csname\currentframed\s!parent\endcsname#1\fi} \def\doframedparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\expandafter\doframedparentparameter \csname#1\s!parent\endcsname{#2}\fi} \def\doframedparameterhash#1#2{\ifcsname#1#2\endcsname #1\else\expandafter\doframedparentparameterhash\csname#1\s!parent\endcsname#2\fi} \def\doframedparentparameter #1#2{\ifx#1\relax\s!empty\else\doframedparameter #1{#2}\fi} \def\doframedparentparameterhash#1#2{\ifx#1\relax \else\doframedparameterhash#1#2\fi} \def\doframedparentparameter#1#2{\ifx#1\relax\doframedrootparameter#2\else\doframedparameter#1{#2}\fi} \def\doframedrootparameter #1{\ifcsname\??framed#1\endcsname\??framed#1\else\s!empty\fi} \def\useframedstyleandcolor#1#2% style color {\edef\currentstyleparameter{\framedparameter#1}% \edef\currentcolorparameter{\framedparameter#2}% \ifx\currentstyleparameter\empty\else\dousestyleparameter\currentstyleparameter\fi \ifx\currentcolorparameter\empty\else\dousecolorparameter\currentcolorparameter\fi} \def\frameddimension#1{\the\dimexpr\framedparameter{#1}\relax} % \unexpanded\def\installsomebackground#1#2{\inheritlocalframed[\??ma#1#2][\??od]} \let\normalframedparameter \framedparameter \let\normalframedparameterhash\framedparameterhash \def\pack_framed_initialize#1% will be inlined {\inframedtrue \edef\currentframed{#1}% \let\framedparameter \normalframedparameter \let\framedparameterhash\normalframedparameterhash} \def\installinheritedframed#1% {\normalexpanded{\doinstallinheritedframed \expandafter\noexpand\csname current#1\endcsname \expandafter\noexpand\csname #1parameter\endcsname \expandafter\noexpand\csname #1parameterhash\endcsname \expandafter\noexpand\csname do#1parameter\endcsname \expandafter\noexpand\csname do#1parentparameter\endcsname \expandafter\noexpand\csname do#1rootparameter\endcsname \expandafter\noexpand\csname inherited#1framed\endcsname \noexpand\??framed}} % if needed we can have a variant \unexpanded\def\doinstallinheritedframed#1#2#3#4#5#6#7#8% {\def#5##1##2{\ifx##1\relax#6{##2}\else#4##1{##2}\fi}% \def#6##1{\ifcsname#8##1\endcsname#8##1\else\s!empty\fi}% \unexpanded\def#7% {\bgroup \bgroup \inframedtrue \let\currentframed #1% not used (more for tracing) \let\framedparameter #2% \let\framedparameterhash#3% \pack_framed_process_indeed}} \unexpanded\def\installframedcommandhandler#1#2#3% {\installcommandhandler{#1}{#2}{#3}% \installinheritedframed{#2}} \unexpanded\def\installframedautocommandhandler#1#2#3% {\installautocommandhandler{#1}{#2}{#3}% \installinheritedframed{#2}} \unexpanded\def\installsimpleframedcommandhandler#1#2#3% {\installsimplecommandhandler{#1}{#2}{#3}% \installinheritedframed{#2}} % for regular framed \getparameters [\??framed] [\c!width=\v!fit, \c!height=\v!broad, %\c!lines=, \c!offset=0.25ex, % \defaultframeoffset \c!empty=\v!no, \c!frame=\v!on, %\c!topframe=, %\c!bottomframe=, %\c!leftframe=, %\c!rightframe=, \c!radius=.5\bodyfontsize, \c!rulethickness=\linewidth, \c!corner=\v!rectangular, \c!depth=\zeropoint, %\c!foregroundcolor=, %\c!foregroundstyle=, %\c!background=, %\c!backgroundscreen=, %\c!backgroundcolor=, \c!backgroundoffset=\zeropoint, %\c!framecolor=, \c!frameoffset=\zeropoint, \c!backgroundcorner=\framedparameter\c!corner, \c!backgroundradius=\framedparameter\c!radius, \c!backgrounddepth=\framedparameter\c!depth, \c!framecorner=\framedparameter\c!corner, \c!frameradius=\framedparameter\c!radius, \c!framedepth=\framedparameter\c!depth, %\c!component=, %\c!region=, %\c!align=, \c!bottom=\vss, %\c!top=, \c!strut=\v!yes, \c!autostrut=\v!yes, \c!location=\v!normal, %\c!orientation=, \c!autowidth=\v!yes, %\c!setups= \c!loffset=\zeropoint, \c!roffset=\zeropoint, \c!toffset=\zeropoint, \c!boffset=\zeropoint] % for backgrounds \getparameters [\??od] % for fast version [\c!frame=\v!off, \c!depth=\zeropoint, \c!offset=\v!overlay, %\c!component=, %\c!region=, \c!radius=.5\bodyfontsize, \c!rulethickness=\linewidth, \c!corner=\v!rectangular, \c!backgroundoffset=\zeropoint, \c!frameoffset=\zeropoint, \c!backgroundcorner=\framedparameter\c!corner, \c!backgroundradius=\framedparameter\c!radius, \c!backgrounddepth=\framedparameter\c!depth, \c!framecorner=\framedparameter\c!corner, \c!frameradius=\framedparameter\c!radius, \c!framedepth=\framedparameter\c!depth, \c!location=\v!normal, \c!loffset=\zeropoint, \c!roffset=\zeropoint, \c!toffset=\zeropoint, \c!boffset=\zeropoint] %D We will communicate through module specific variables, current %D framed parameters and some reserved dimension registers. \newdimen\d_framed_target_wd \newdimen\d_framed_target_ht \newdimen\d_framed_target_dp \newdimen\d_framed_linewidth \let\ruledlinewidth\d_framed_linewidth % needed at lua end \let\p_framed_frame \empty % \framedparameter\c!frame \let\p_framed_backgroundoffset\empty \let\p_framed_foregroundstyle \empty \let\p_framed_autostrut \empty \let\p_framed_location \empty \let\p_framed_orientation \empty \let\p_framed_autowidth \empty \let\p_framed_franalyze \empty \let\p_framed_backgroundcorner\empty \let\p_framed_backgroundradius\empty \let\p_framed_framecorner \empty \let\p_framed_frameradius \empty \let\p_framed_lines \empty \let\p_framed_empty \empty \let\p_framed_backgroundcolor \empty \let\p_framed_backgroundscreen\empty \let\p_framed_framecolor \empty \let\p_framed_component \empty \let\p_framed_region \empty \let\p_framed_background \empty \let\p_framed_rulethickness \empty \let\p_framed_foregroundcolor \empty \let\p_framed_setups \empty %D We don't have to stick to a \TEX\ drawn rule, but also can use rounded %D or even fancier shapes, as we will see later on. \def\pack_framed_filled_box {\edef\p_framed_backgroundcorner{\framedparameter\c!backgroundcorner}% \ifx\p_framed_backgroundcorner\v!rectangular \pack_framed_filled_box_normal \else \pack_framed_filled_box_radius \fi} \def\pack_framed_filled_box_normal {\vrule \!!width \d_framed_target_wd \!!height\d_framed_target_ht \!!depth \d_framed_target_dp \relax} \def\pack_framed_filled_box_radius {\edef\p_framed_backgroundradius{\framedparameter\c!backgroundradius}% \ifzeropt\dimexpr\p_framed_backgroundradius\relax % just in case of .x\bodyfontsize \pack_framed_filled_box_normal \else \pack_framed_filled_box_round \fi} \def\pack_framed_filled_box_round {\normalexpanded{\doovalbox {\the\d_framed_target_wd}% {\the\d_framed_target_ht}% {\the\d_framed_target_dp}% {\the\dimexpr\d_framed_linewidth\relax}% {\the\dimexpr\p_framed_backgroundradius\relax}% {0}% {1}% {\ifx\p_framed_backgroundcorner\v!round0\else\number\p_framed_backgroundcorner\fi}% }} \def\pack_framed_stroked_box {\edef\p_framed_framecorner{\framedparameter\c!framecorner}% \ifx\p_framed_framecorner\v!rectangular \pack_framed_stroked_box_normal \else \pack_framed_stroked_box_radius \fi} \def\pack_framed_stroked_box_radius {\edef\p_framed_frameradius{\framedparameter\c!frameradius}% \ifzeropt\dimexpr\p_framed_frameradius\relax % just in case of .x\bodyfontsize \pack_framed_stroked_box_normal \else \ifx\p_framed_frame\v!on \pack_framed_stroked_box_round \fi \fi} % \pack_framed_stroked_box_normal % later \def\pack_framed_stroked_box_round {\normalexpanded{\doovalbox {\the\d_framed_target_wd}% {\the\d_framed_target_ht}% {\the\d_framed_target_dp}% {\the\dimexpr\d_framed_linewidth\relax}% {\the\dimexpr\p_framed_frameradius\relax}% {1}% {0}% {\ifx\p_framed_framecorner\v!round0\else\number\p_framed_framecorner\fi}% }} % a lot of weird corners % % \startTEXpage % \dontleavehmode\framed % [corner=0,frame=on,framecolor=green, % background=color,backgroundcolor=yellow]{\tttf TEST \twodigits\recurselevel}% % \vskip1em % \dontleavehmode\dostepwiserecurse {1} {4}{1}{\framed % [corner=\recurselevel,frame=on,framecolor=green, % background=color,backgroundcolor=yellow]{\tttf TEST \twodigits\recurselevel}% % \quad} % \vskip1em % \dontleavehmode\dostepwiserecurse {5} {8}{1}{\framed % [corner=\recurselevel,frame=on,framecolor=green, % background=color,backgroundcolor=yellow]{\tttf TEST \twodigits\recurselevel}% % \quad} % \vskip1em % \dontleavehmode\dostepwiserecurse {1} {4}{1}{\framed % [corner=\recurselevel,frame=on,framecolor=green]{\tttf TEST \twodigits\recurselevel}% % \quad} % \vskip1em % \dontleavehmode\dostepwiserecurse {5} {8}{1}{\framed % [corner=\recurselevel,frame=on,framecolor=green]{\tttf TEST \twodigits\recurselevel}% % \quad} % \vskip1em % \dontleavehmode\dostepwiserecurse {9}{12}{1}{\framed % [corner=\recurselevel,frame=on,framecolor=green]{\tttf TEST \twodigits\recurselevel}% % \quad} % \vskip1em % \dontleavehmode\dostepwiserecurse{13}{16}{1}{\framed % [corner=\recurselevel,frame=on,framecolor=green]{\tttf TEST \twodigits\recurselevel}% % \quad} % \vskip1em % \dontleavehmode\dostepwiserecurse{17}{20}{1}{\framed % [corner=\recurselevel,frame=on,framecolor=green]{\tttf TEST \twodigits\recurselevel}% % \quad} % \vskip1em % \dontleavehmode\dostepwiserecurse{21}{24}{1}{\framed % [corner=\recurselevel,frame=on,framecolor=green]{\tttf TEST \twodigits\recurselevel}% % \quad} % \vskip1em % \dontleavehmode\dostepwiserecurse{25}{28}{1}{\framed % [corner=\recurselevel,frame=on,framecolor=green]{\tttf TEST \twodigits\recurselevel}% % \quad} % \stopTEXpage %D The oval box is drawn using a special macro, depending on %D the driver in use. \def\pack_framed_background_box_gray % avoid black rules when no gray {\edef\p_framed_backgroundscreen{\framedparameter\c!backgroundscreen}% \ifx\p_framed_backgroundscreen\empty \else \pack_framed_background_box_gray_indeed \fi} \def\pack_framed_background_box_gray_indeed % can be more direct but who cares, just compatibility {\colored[s=\p_framed_backgroundscreen]{\pack_framed_filled_box}} %D It won't be a surprise that we not only provide gray boxes, %D but also colored ones. Here it is: \def\pack_framed_background_box_color {\edef\p_framed_backgroundcolor{\framedparameter\c!backgroundcolor}% \ifx\p_framed_backgroundcolor\empty \else \doifcolor\p_framed_backgroundcolor\pack_framed_background_box_color_indeed \fi} \def\pack_framed_background_box_color_indeed {\hbox{\dousecolorparameter\p_framed_backgroundcolor\pack_framed_filled_box}} %D \macros %D {defineoverlay, doifoverlayelse, overlayoffset, %D overlaywidth, overlayheight, overlaydepth, %D overlaycolor, overlaylinecolor, overlaylinewidth} %D %D Before we define the macro that actually takes card of the %D backgrounds, we introduce overlays. An overlay is something %D that contrary to its name lays {\em under} the text. An %D example of an overlay definition is: %D %D \startbuffer[tmp-1] %D \defineoverlay %D [fancy] %D [{\externalfigure %D [mp-cont.502] %D [width=\overlaywidth, %D height=\overlayheight]}] %D \stopbuffer %D %D \typebuffer[tmp-1] %D %D That for instance can be uses in: %D %D \startbuffer[tmp-2] %D \framed[backgroundachtergrond=fancy]{How Fancy!} %D \framed[backgroundachtergrond=fancy,frame=off]{Even More Fancy!} %D \stopbuffer %D %D and looks like: %D %D \startlinecorrection %D \vbox{\baselineskip24pt\getbuffer[tmp-1]\getbuffer[tmp-2]} %D \stoplinecorrection %D %D The formal definition is: %D %D \showsetup{defineoverlay} %D %D This macro's definition is a bit obscure, due the many %D non||used arguments and the two step call that enable the %D setting of the width, height and depth variables. %D Multiple backgrounds are possible and are specified as: %D %D \starttyping %D \framed[background={one,two,three}]{Three backgrounds!} %D \stoptyping %D %D Most drawing packages only know width and height. Therefore %D the dimensions have a slightly different meaning here: %D %D \startitemize[packed] %D \item \type{\overlaywidth }: width of the overlay %D \item \type{\overlayheight}: height plus depth of the overlay %D \item \type{\overlaydepth }: depth of the overlay %D \stopitemize %D %D The resulting box is lowered to the right depth. \def\overlaywidth {\the\hsize\space} % We preset the variables \def\overlayheight {\the\vsize\space} % to some reasonable default \def\overlaydepth {0pt } % values. The attributes \let\overlayoffset \overlaydepth % of the frame can be (are) \let\overlaylinewidth \overlaydepth % set somewhere else. \let\overlaycolor \empty \let\overlaylinecolor \empty %D The next register is used to initialize overlays. \newtoks\everyoverlay %D An example of an initialization is the following (overlays %D can contain text and be executed under an regime where %D interlineskip is off). \installcorenamespace{overlay} \installcorenamespace{overlaybuiltin} \appendtoks \oninterlineskip \to \everyoverlay \prependtoks \hsize\overlaywidth \vsize\overlayheight \to \everyoverlay \unexpanded\def\defineoverlay {\dodoubleargument\pack_framed_define_overlay} \def\pack_framed_define_overlay[#1][#2]% {\def\pack_framed_define_overlay_indeed##1{\setvalue{\??overlay##1}{\executedefinedoverlay{##1}{#2}}}% \processcommalist[#1]\pack_framed_define_overlay_indeed} \unexpanded\def\executedefinedoverlay#1#2% we can share the definitions {\bgroup % redundant grouping \setbox\scratchbox\hbox\bgroup \ifzeropt\d_framed_target_dp \the\everyoverlay#2% saves wrapping (and lua call) \else \lower\d_framed_target_dp \hbox{\the\everyoverlay#2}% \fi \egroup \setlayoutcomponentattribute{\v!overlay:#1}% \setbox\scratchbox\hbox \layoutcomponentboxattribute {\kern -.5\dimexpr\wd\scratchbox-\d_framed_target_wd\relax % was \overlaywidth \raise-.5\dimexpr\ht\scratchbox-\d_framed_target_ht\relax % not \overlayheight ! \box\scratchbox}% \wd\scratchbox\d_framed_target_wd \ht\scratchbox\d_framed_target_ht \dp\scratchbox\d_framed_target_dp \box\scratchbox \egroup} %D \macros %D {overlayfakebox} \unexpanded\def\overlayfakebox {\hbox {\setbox\scratchbox\emptyhbox \wd\scratchbox\overlaywidth \ht\scratchbox\overlayheight \box\scratchbox}} %D For testing we provide: \def\doifoverlayelse#1% only tests external overlays {\ifcsname\??overlay#1\endcsname \expandafter\firstoftwoarguments \else \expandafter\secondoftwoarguments \fi} %D The content of the box will be (temporary) saved in a box. We %D also have an extra box for backgrounds. \newbox\b_framed_normal \newbox\b_framed_extra \newtoks\everybackgroundbox \let\m_framed_background\empty % we might need a public name \def\pack_framed_process_background {\ifcsname\??overlaybuiltin\m_framed_background\endcsname \pack_framed_process_background_indeed_internal \else\ifcsname\??overlay\m_framed_background\endcsname \pack_framed_process_background_indeed_external \fi\fi} \def\pack_framed_process_background_indeed_internal % : in name {\bgroup \setbox\b_framed_extra\hbox{%\bgroup \ifzeropt\framedbackgroundoffset \csname\??overlaybuiltin\m_framed_background\endcsname \else \kern-\framedbackgroundoffset \hbox{\csname\??overlaybuiltin\m_framed_background\endcsname}% \fi }%\egroup \wd\b_framed_extra\zeropoint \ht\b_framed_extra\framedbackgroundheight \dp\b_framed_extra\framedbackgrounddepth \box\b_framed_extra \egroup} \def\pack_framed_process_background_indeed_external {\pack_framed_overlay_initialize \bgroup \setbox\b_framed_extra\hbox{%\bgroup \ifzeropt\framedbackgroundoffset \csname\??overlay\m_framed_background\endcsname \else \kern-\framedbackgroundoffset \hbox{\csname\??overlay\m_framed_background\endcsname}% \fi }%\egroup \wd\b_framed_extra\zeropoint \ht\b_framed_extra\framedbackgroundheight \dp\b_framed_extra\framedbackgrounddepth \box\b_framed_extra \egroup} \def\pack_framed_process_backgrounds#1,#2% #2 gobbles spaces (we could avoid one catch if we have nextbackground) {\edef\m_framed_background{#1}% \ifx\m_framed_background\s!unknown\else \pack_framed_process_background \expandafter\pack_framed_process_backgrounds \fi#2} % beware, a backgroundbox can be empty which is another reason % why we set the width to zero instead of back-skipping \newdimen\framedbackgroundwidth \newdimen\framedbackgroundheight \newdimen\framedbackgrounddepth \newdimen\framedbackgroundoffset \def\pack_framed_background_box_content% fuzzy but needed hack, this \vss, otherwise {\vbox to \framedbackgroundheight{\vss\box\b_framed_normal\vss}} % vertical shift \backgroundheight \def\pack_framed_add_region % experiment {\anch_mark_region_box\b_framed_normal} \def\pack_framed_add_background {\setbox\b_framed_normal\hbox % was vbox {\pack_framed_forgetall % can be relaxed \boxmaxdepth\maxdimen \framedbackgroundoffset\d_framed_backgroundoffset \framedbackgroundwidth \wd\b_framed_normal \framedbackgroundheight\ht\b_framed_normal \framedbackgrounddepth \dp\b_framed_normal \d_framed_target_wd\dimexpr\framedbackgroundwidth +2\framedbackgroundoffset\relax \d_framed_target_ht\dimexpr\framedbackgroundheight+ \framedbackgroundoffset\relax \d_framed_target_dp\dimexpr\framedbackgrounddepth + \framedbackgroundoffset+\framedparameter\c!backgrounddepth\relax \let\pack_framed_overlay_initialize\pack_framed_overlay_initialize_indeed \ifx\p_framed_component\empty \resetlayoutcomponentattribute \else \setlayoutcomponentattribute{\v!background:\p_framed_component}% \fi \let\foregroundbox\pack_framed_background_box_content \hbox \layoutcomponentboxattribute to \framedbackgroundwidth\bgroup % width in case 'foreground' is used as overlay \the\everybackgroundbox % moved \expandafter\pack_framed_process_backgrounds\p_framed_background,\s!unknown,\relax % hm, messy .. look into it \box\b_framed_normal \hss \egroup}} \def\pack_framed_overlay_initialize_indeed {%\writestatus{!!!!}{<<<<<}% \edef\overlaywidth {\the\d_framed_target_wd\space}% \edef\overlayheight {\the\dimexpr\d_framed_target_ht+\d_framed_target_dp\relax\space}% \edef\overlaydepth {\the\d_framed_target_dp\space}% \edef\overlaycolor {\framedparameter\c!backgroundcolor}% let ? \edef\overlaylinecolor{\framedparameter\c!framecolor}% only needed for layers \edef\overlaylinewidth{\the\d_framed_linewidth\space}% %\edef\overlaycorner {\framedparameter\c!backgroundcorner}% %\edef\overlayradius {\framedparameter\c!backgroundradius}% \edef\overlayoffset {\the\framedbackgroundoffset\space}% \backgroundoffset % we steal this one \let\pack_framed_overlay_initialize\relax} %D One can explictly insert the foreground box. For that %D purpose we introduce the overlay \type {foreground}. %D %D We predefine two already familiar backgrounds: \letvalue{\??overlaybuiltin\v!screen }\pack_framed_background_box_gray \letvalue{\??overlaybuiltin\v!color }\pack_framed_background_box_color \letvalue{\??overlaybuiltin\v!foreground}\pack_framed_background_box_content % replaces: \defineoverlay[\v!foreground][\foregroundbox] %D We can specify overlays as a comma separated list of %D overlays, a sometimes handy feature. %D Besides backgrounds (overlays) we also need some macros to %D draw outlines (ruled borders). Again we have to deal with %D square and round corners. The first category can be handled %D by \TEX\ itself, the latter one depends on the driver. This %D macro also support a negative offset. \def\pack_framed_add_outline {\setbox\b_framed_normal\hbox % rules on top of box {\d_framed_target_wd\dimexpr\wd\b_framed_normal+2\d_framed_frameoffset\relax \d_framed_target_ht\dimexpr\ht\b_framed_normal+ \d_framed_frameoffset\relax \d_framed_target_dp\dimexpr\dp\b_framed_normal+ \d_framed_frameoffset+\framedparameter\c!framedepth\relax \ifdim\d_framed_target_dp<\zeropoint \advance\d_framed_target_ht \d_framed_target_dp \scratchdimen-\d_framed_target_dp \d_framed_target_dp\zeropoint \else \scratchdimen\zeropoint \fi \edef\overlaylinecolor{\framedparameter\c!framecolor}% twice, also in background \setbox\b_framed_extra\hbox {\kern-\d_framed_frameoffset \raise\scratchdimen \hbox{\ifx\overlaylinecolor\empty\else\dousecolorparameter\overlaylinecolor\fi\pack_framed_stroked_box}}% \wd\b_framed_extra\wd\b_framed_normal \ht\b_framed_extra\ht\b_framed_normal \dp\b_framed_extra\dp\b_framed_normal \wd\b_framed_normal\zeropoint \box\b_framed_normal \box\b_framed_extra}} \def\pack_framed_stroked_box_normal {\setbox\scratchbox\emptyhbox \wd\scratchbox\d_framed_target_wd \ht\scratchbox\d_framed_target_ht \dp\scratchbox\d_framed_target_dp \setbox\scratchbox\vbox \bgroup \csname \??framedtop\p_framed_frame\framedparameter\c!topframe \endcsname \nointerlineskip % new (needed for fences) \hbox \bgroup \csname \??framedleft\p_framed_frame\framedparameter\c!leftframe \endcsname \box\scratchbox \csname \??framedright\p_framed_frame\framedparameter\c!rightframe \endcsname \egroup \nointerlineskip % new (needed for fences) \csname \??framedbottom\p_framed_frame\framedparameter\c!bottomframe\endcsname \egroup \wd\scratchbox\d_framed_target_wd \ht\scratchbox\d_framed_target_ht \dp\scratchbox\d_framed_target_dp \box\scratchbox} \def\pack_framed_t_rule{\hrule\!!height\d_framed_linewidth\kern-\d_framed_linewidth} \def\pack_framed_b_rule{\kern-\d_framed_linewidth\hrule\!!height\d_framed_linewidth} \def\pack_framed_r_rule{\kern-\d_framed_linewidth\vrule\!!width\d_framed_linewidth} \def\pack_framed_l_rule{\vrule\!!width\d_framed_linewidth\kern-\d_framed_linewidth} \letvalue{\??framedtop \v!on \v!on}\pack_framed_t_rule \letvalue{\??framedtop \v!off\v!on}\pack_framed_t_rule \letvalue{\??framedtop \v!on }\pack_framed_t_rule \letvalue{\??framedbottom\v!on \v!on}\pack_framed_b_rule \letvalue{\??framedbottom\v!off\v!on}\pack_framed_b_rule \letvalue{\??framedbottom\v!on }\pack_framed_b_rule \letvalue{\??framedleft \v!on \v!on}\pack_framed_l_rule \letvalue{\??framedleft \v!off\v!on}\pack_framed_l_rule \letvalue{\??framedleft \v!on }\pack_framed_l_rule \letvalue{\??framedright \v!on \v!on}\pack_framed_r_rule \letvalue{\??framedright \v!off\v!on}\pack_framed_r_rule \letvalue{\??framedright \v!on }\pack_framed_r_rule % no overlapping rules \def\pack_framed_t_rules{\hbox{\kern\d_framed_linewidth\vrule\!!width\dimexpr\d_framed_target_wd-2\d_framed_linewidth\relax\!!height\d_framed_linewidth}\nointerlineskip\kern-\d_framed_linewidth} \def\pack_framed_b_rules{\kern-\d_framed_linewidth\nointerlineskip\hbox{\kern\d_framed_linewidth\vrule\!!width\dimexpr\d_framed_target_wd-2\d_framed_linewidth\relax\!!height\d_framed_linewidth}} \def\pack_framed_r_rules{\kern-\d_framed_linewidth\vrule\!!height\dimexpr\d_framed_target_ht-\d_framed_linewidth\relax\!!depth-\d_framed_linewidth\!!width\d_framed_linewidth} \def\pack_framed_l_rules{\vrule\!!height\dimexpr\d_framed_target_ht-\d_framed_linewidth\relax\!!depth-\d_framed_linewidth\!!width\d_framed_linewidth\kern-\d_framed_linewidth} \letvalue{\??framedtop \v!small\v!small}\pack_framed_t_rules \letvalue{\??framedtop \v!off \v!small}\pack_framed_t_rules \letvalue{\??framedtop \v!small }\pack_framed_t_rules \letvalue{\??framedbottom\v!small\v!small}\pack_framed_b_rules \letvalue{\??framedbottom\v!off \v!small}\pack_framed_b_rules \letvalue{\??framedbottom\v!small }\pack_framed_b_rules \letvalue{\??framedleft \v!small\v!small}\pack_framed_l_rules \letvalue{\??framedleft \v!off \v!small}\pack_framed_l_rules \letvalue{\??framedleft \v!small }\pack_framed_l_rules \letvalue{\??framedright \v!small\v!small}\pack_framed_r_rules \letvalue{\??framedright \v!off \v!small}\pack_framed_r_rules \letvalue{\??framedright \v!small }\pack_framed_r_rules % \framed % [width=4cm,height=3cm,rulethickness=3mm, % frame=off,rightframe=on,leftframe=on,topframe=on,bottomframe=on] % {} % \framed % [width=4cm,height=3cm,rulethickness=3mm, % frame=off,rightframe=small,leftframe=small,topframe=small,bottomframe=small] % {} % \framed % [width=4cm,height=3cm,rulethickness=3mm, % frame=off,rightframe=small,leftframe=small,topframe=small,bottomframe=on] % {} %D The next few macros are probably the most misused ones in %D \CONTEXT. They deal with putting rules around boxes, provide %D backgrounds, offer alignment features, and some more. We %D start with defining some booleans. These give an impression %D of what we are going to take into account. % todo : \c_framed_hasoffset % faster : \let\c_framed_hasoffset\falseconditional \newconditional\c_framed_has_offset \newconditional\c_framed_has_width \newconditional\c_framed_has_height \newconditional\c_framed_has_format \newconditional\c_framed_has_strut \newconditional\c_framed_is_overlaid \newconditional\c_framed_has_frame \newconditional\c_framed_has_extra_offset \newconditional\c_framed_text_location_none %D \macros %D {framed, setupframed} %D %D Ruled boxes are typeset using \type{\framed}. This command %D is quite versatile and, although some users will probably %D seldom use it, one cannot overlook its features. %D %D \showsetup{setupframed} %D \showsetup{framed} %D %D This general macro is a special version of an even more %D general case, that can easily be linked into other macros %D that need some kind of framing. The local version is called %D with an extra parameter: the variable identifier. The reason %D for passing this identifier between brackets lays in the %D mere fact that this way we can use the optional argument %D grabbers. \def\defaultframeoffset{.25ex} \def\presetlocalframed [#1]{\letvalue {#1\s!parent}\??framed} \def\inheritlocalframed[#1]#2[#3]{\setevalue{#1\s!parent}{#3}} \presetlocalframed[\??ol] \newcount\framednesting \unexpanded\def\framed {\bgroup \advance\framednesting\plusone \expandafter\let\csname\??ol:\the\framednesting\s!parent\endcsname\??ol \dodoubleempty\pack_framed_process[\??ol:\the\framednesting]} \unexpanded\def\startframed {\dosingleempty\pack_framed_start_framed} \def\pack_framed_start_framed[#1]% {\bgroup \advance\framednesting\plusone \expandafter\let\csname\??ol:\the\framednesting\s!parent\endcsname\??ol \iffirstargument\secondargumenttrue\fi % dirty trick \pack_framed_process[\??ol:\the\framednesting][#1]% \bgroup} \let\stopframed\egroup \unexpanded\def\setupframed {\dodoubleempty\dosetupframed} \unexpanded\def\normalframedwithsettings {\bgroup \advance\framednesting\plusone \expandafter\let\csname\??ol:\the\framednesting\s!parent\endcsname\??ol \pack_framed_process[\??ol:\the\framednesting]} % we can consider setting the parent of the regular framed to % something else in the otr so that we isolate it there \def\dosetupframed[#1][#2]% {\ifsecondargument \getparameters[\??ol#1][#2]% \else \getparameters[\??ol][#1]% \fi} %D \startbuffer %D \setupframed [framecolor=yellow] \framed{A} %D \defineframed[myframed] [framecolor=blue] \myframed{B} %D \setupframed [myframed] [framecolor=red] \myframed{C} %D \stopbuffer %D %D \typebuffer \getbuffer %D %D \startbuffer %D \presetlocalframed[myframed] %D \localframed[myframed][framecolor=green]{oeps} %D \stopbuffer %D %D \typebuffer \getbuffer %D \macros %D {ifinframed} %D %D The normal case first presets all parameters and next starts %D looking for the user supplied ones. The first step is %D omitted in the local case, because these are preset at %D declaration time and keep their values unless explictly %D changed. By presetting the variables everytime the normal %D command is called, we can use this command nested, without %D the unwanted side effect of inheritance. The boolean is %D used to speed up the color stack. \newif\ifinframed %D The next one is faster on multiple backgrounds per page. No %D dimensions can be set, only frames and backgrounds. \unexpanded\def\fastlocalframed[#1]#2[#3]#4% 3-4 {\bgroup \pack_framed_initialize{#1}% \setbox\b_framed_normal\hbox{#4}% \edef\p_framed_region{\framedparameter\c!region}% \ifx\p_framed_region\v!yes % maybe later named \pack_framed_add_region \fi \getparameters[\currentframed][#3]% no \expanded ! \edef\p_framed_rulethickness{\framedparameter\c!rulethickness}% also used in backgrounds \d_framed_frameoffset\framedparameter\c!frameoffset\relax % also used in backgrounds \edef\p_framed_frame{\framedparameter\c!frame}% \edef\p_framed_background{\framedparameter\c!background}% % not here, in calling macro: setups \pack_framed_remove_depth \ifx\p_framed_frame\v!overlay \else \ifx\p_framed_frame\v!none \else \ifx\p_framed_rulethickness\empty\else \d_framed_linewidth\p_framed_rulethickness\relax \fi \pack_framed_add_outline % real or invisible frame \fi \fi \fi \ifx\p_framed_background\empty \else \edef\p_framed_backgroundoffset{\framedparameter\c!backgroundoffset}% \d_framed_backgroundoffset \ifx\p_framed_backgroundoffset\v!frame \d_framed_frameoffset \else \p_framed_backgroundoffset \fi \edef\p_framed_component{\framedparameter\c!component}% \pack_framed_add_background \fi \pack_framed_restore_depth \box\b_framed_normal \egroup} %D The next macro uses a box and takes its natural width and %D height so these can better be correct. \def\localbackgroundframed#1#2#3% namespace component box {\bgroup \pack_framed_initialize{#1}% \setbox\b_framed_normal\box#3% \edef\p_framed_region{\framedparameter\c!region}% \ifx\p_framed_region\v!yes % maybe later named \pack_framed_add_region \fi \edef\p_framed_rulethickness{\framedparameter\c!rulethickness}% also used in backgrounds \d_framed_frameoffset\framedparameter\c!frameoffset\relax % also used in backgrounds \edef\p_framed_frame{\framedparameter\c!frame}% \edef\p_framed_background{\framedparameter\c!background}% \ifx\p_framed_frame\v!overlay \else \ifx\p_framed_frame\v!none \else \ifx\p_framed_rulethickness\empty \else \d_framed_linewidth\p_framed_rulethickness\relax \fi \pack_framed_add_outline % real or invisible frame \fi \fi \ifx\p_framed_background\empty \else \edef\p_framed_backgroundoffset{\framedparameter\c!backgroundoffset}% \d_framed_backgroundoffset \ifx\p_framed_backgroundoffset\v!frame \d_framed_frameoffset \else \p_framed_backgroundoffset \fi \edef\p_framed_component{#2}% \pack_framed_add_background \fi \box\b_framed_normal \egroup} \let\postprocessframebox\relax %D A nice example by Aditya: %D %D \starttyping %D \setupframed %D [loffset=\framedparameter{hoffset}, %D roffset=\framedparameter{hoffset}, %D hoffset=\zeropoint] %D %D \defineframed[test][hoffset=1cm] %D \stoptyping \newdimen\d_framed_width \newdimen\d_framed_height \newdimen\d_framed_frameoffset \newdimen\d_framed_backgroundoffset \newdimen\d_framed_local_offset % todo: protect local \framednames \unexpanded\def\localframed {\bgroup \dodoubleempty\pack_framed_process} \unexpanded\def\pack_framed_process[#1][#2]% assumes a \dodoubleempty (slows down), also should have leading \bgroup {\bgroup \pack_framed_initialize{#1}% \ifsecondargument % faster \getparameters[\currentframed][#2]% here ! \fi \pack_framed_process_indeed} \unexpanded\def\directlocalframed[#1]% no optional {\bgroup \bgroup \pack_framed_initialize{#1}% \pack_framed_process_indeed} \unexpanded\def\localframedwithsettings[#1][#2]% no checking (so no spaces between) {\bgroup \bgroup \pack_framed_initialize{#1}% \getparameters[\currentframed][#2]% here ! \pack_framed_process_indeed} % done \def\c!fr!analyze{fr:analyze} % private option \unexpanded\def\pack_framed_process_indeed {\d_framed_frameoffset\framedparameter\c!frameoffset \edef\p_framed_backgroundoffset{\framedparameter\c!backgroundoffset}% \d_framed_backgroundoffset \ifx\p_framed_backgroundoffset\v!frame \d_framed_frameoffset \else \p_framed_backgroundoffset \fi % new, experimental dirty hook \framedparameter\c!extras % to get the right spacing \edef\p_framed_foregroundstyle{\framedparameter\c!foregroundstyle}% \ifx\p_framed_foregroundstyle\empty\else\dousestyleparameter\p_framed_foregroundstyle\fi % beware, both the frame and background offset can be overruled % \edef\p_framed_setups{\framedparameter\c!setups}% % the next macros are visible \edef\localoffset{\framedparameter\c!offset}% \edef\localwidth {\framedparameter\c!width}% \edef\localheight{\framedparameter\c!height}% \edef\localformat{\framedparameter\c!align}% \edef\localstrut {\framedparameter\c!strut}% % these are not \edef\p_framed_autostrut {\framedparameter\c!autostrut}% \edef\p_framed_frame {\framedparameter\c!frame}% \edef\p_framed_location {\framedparameter\c!location}% \edef\p_framed_orientation{\framedparameter\c!orientation}% % \edef\p_framed_autowidth {\framedparameter\c!autowidth}% \edef\p_framed_franalyze {\framedparameter\c!fr!analyze}% experimental option % \ifx\p_framed_frame\v!overlay % no frame, no offset, no framewidth \setfalse\c_framed_has_frame \let\localoffset\v!overlay \else\ifx\p_framed_frame\v!none % no frame, no framewidth \setfalse\c_framed_has_frame \else \settrue\c_framed_has_frame \fi\fi \ifconditional\c_framed_has_frame \edef\p_framed_rulethickness{\framedparameter\c!rulethickness}% \ifx\p_framed_rulethickness\empty\else \d_framed_linewidth\p_framed_rulethickness\relax \fi \else \d_framed_linewidth\zeropoint \fi \ifx\localformat\empty \setfalse\c_framed_has_format \else \settrue\c_framed_has_format \dosetraggedcommand\localformat % not that fast \fi \csname\??framedoffsetalternative \ifcsname\??framedoffsetalternative\localoffset\endcsname \localoffset \else \s!unknown \fi \endcsname \csname\??framedwidthalternative \ifcsname\??framedwidthalternative\localwidth\endcsname \localwidth \else \s!unknown \fi \endcsname \csname\??framedheightalternative \ifcsname\??framedheightalternative\localheight\endcsname \localheight \else \s!unknown \fi \endcsname % the next check could move to heightalternative \ifconditional\c_framed_has_height % obey user set height, also downward compatible \else \edef\p_framed_lines{\framedparameter\c!lines}% \ifx\p_framed_lines\empty\else \ifcase\p_framed_lines\else \d_framed_height\p_framed_lines\lineheight \edef\localheight{\the\d_framed_height}% \settrue\c_framed_has_height \fi \fi \fi % this is now an option: width=local % % \ifdim\d_framed_width=\hsize % \parindent\zeropoint % \setlocalhsize % \d_framed_width\localhsize % \fi % i.e. disable (colsetbackgroundproblemintechniek) \advance\d_framed_width -2\d_framed_local_offset \advance\d_framed_height -2\d_framed_local_offset \csname\??framedstrutalternative \ifcsname\??framedstrutalternative\localstrut\endcsname \localstrut \else \s!unknown \fi \endcsname % the next check could move to strutalternative \ifconditional\c_framed_has_strut \let\localbegstrut\begstrut \let\localendstrut\endstrut \let\localstrut \strut \else \let\localbegstrut\pseudobegstrut % was: \relax \let\localendstrut\pseudoendstrut % was: \relax \let\localstrut \pseudostrut % was: \relax %\ifconditional\c_framed_has_height\ifdim\d_framed_height<\strutht % saveguard % \let\localbegstrut\relax % but not that % \let\localstrut \relax % save after all %\fi\fi \fi \ifx\p_framed_autostrut\v!yes \let\delayedbegstrut\relax \let\delayedendstrut\relax \let\delayedstrut \relax \else \let\delayedbegstrut\localbegstrut \let\delayedendstrut\localendstrut \let\delayedstrut \localstrut \let\localbegstrut \relax \let\localendstrut \relax \let\localstrut \relax \fi \ifconditional\c_framed_has_height \let\\\pack_framed_vboxed_newline \ifconditional\c_framed_has_width \let\hairline\pack_framed_vboxed_hairline \ifconditional\c_framed_has_format \let\next\pack_framed_format_format_yes \else \let\next\pack_framed_format_format_nop \fi \else \let\hairline\pack_framed_hboxed_hairline \ifconditional\c_framed_has_format \let\next\pack_framed_format_format_height \else \let\next\pack_framed_format_format_vsize \fi \fi \else \ifconditional\c_framed_has_width \ifconditional\c_framed_has_format \let\hairline\pack_framed_vboxed_hairline \let\\\pack_framed_vboxed_newline \let\next\pack_framed_format_format_width \else \let\hairline\pack_framed_hboxed_hairline \let\\\pack_framed_hboxed_newline \let\next\pack_framed_format_format_hsize \fi \else \let\hairline\pack_framed_hboxed_hairline \let\\\pack_framed_hboxed_newline \let\next\pack_framed_format_format_no_size \fi \fi \pack_framed_check_extra_offsets \edef\p_framed_background{\framedparameter\c!background}% \ifx\p_framed_background\empty \let\pack_framed_forgetall\forgetall \else \let\pack_framed_forgetall\relax \forgetall \fi \edef\framedwidth {\the\ifdim\d_framed_width >\zeropoint \d_framed_width \else\zeropoint\fi}% public \edef\framedheight{\the\ifdim\d_framed_height>\zeropoint \d_framed_height\else\zeropoint\fi}% public \edef\framedoffset{\the\dimexpr\ifconditional\c_framed_has_offset\localoffset \else\zeropoint\fi}% public \ifx\p_framed_orientation\empty \let\pack_framed_stop_orientation\relax \else \pack_framed_start_orientation \fi \afterassignment\pack_framed_restart \setbox\b_framed_normal\next} % alternatives for width, height, strut and offset \installcorenamespace{framedwidthalternative} \installcorenamespace{framedheightalternative} \installcorenamespace{framedstrutalternative} \installcorenamespace{framedoffsetalternative} % widths \setvalue{\??framedwidthalternative\empty}% {\ifconditional\c_framed_has_format \settrue\c_framed_has_width \d_framed_width\hsize \else \setfalse\c_framed_has_width \d_framed_width\zeropoint \fi} \setvalue{\??framedwidthalternative\v!fit}% {\ifconditional\c_framed_has_format \settrue\c_framed_has_width \d_framed_width\hsize \else \setfalse\c_framed_has_width \d_framed_width\zeropoint \fi} \setvalue{\??framedwidthalternative\v!fixed}% equals \v!fit but no shapebox {\ifconditional\c_framed_has_format \settrue\c_framed_has_width \d_framed_width\hsize \else \setfalse\c_framed_has_width \d_framed_width\zeropoint \fi} \setvalue{\??framedwidthalternative\v!broad}% {\settrue\c_framed_has_width \d_framed_width\hsize} \setvalue{\??framedwidthalternative\v!max}% idem broad {\settrue\c_framed_has_width \d_framed_width\hsize} \setvalue{\??framedwidthalternative\v!local}% {\settrue\c_framed_has_width \setlocalhsize \d_framed_width\localhsize} \setvalue{\??framedwidthalternative\s!unknown}% {\settrue\c_framed_has_width \d_framed_width\localwidth} % heights \setvalue{\??framedheightalternative\empty}% {\setfalse\c_framed_has_height \d_framed_height\zeropoint} \setvalue{\??framedheightalternative\v!fit}% {\setfalse\c_framed_has_height \d_framed_height\zeropoint} \setvalue{\??framedheightalternative\v!broad}% {\setfalse\c_framed_has_height \d_framed_height\zeropoint} \setvalue{\??framedheightalternative\v!max}% {\settrue\c_framed_has_height \d_framed_height\vsize} \setvalue{\??framedheightalternative\s!unknown}% {\settrue\c_framed_has_height \d_framed_height\localheight} % struts \setvalue{\??framedstrutalternative\v!no}% {\setfalse\c_framed_has_strut} \setvalue{\??framedstrutalternative\v!global}% {\setstrut} \setvalue{\??framedstrutalternative\v!local}% {\setfontstrut} \setvalue{\??framedstrutalternative\v!yes}% {\setstrut} \setvalue{\??framedstrutalternative\s!unknown}% {\setstrut} % offsets \setvalue{\??framedoffsetalternative\v!none}% {\setfalse\c_framed_has_offset \setfalse\c_framed_has_strut \setfalse\c_framed_is_overlaid \d_framed_local_offset\d_framed_linewidth} \setvalue{\??framedoffsetalternative\v!overlay}% {% \ifx\p_framed_frame\v!no \setfalse\c_framed_has_frame \fi % test first \setfalse\c_framed_has_offset \setfalse\c_framed_has_strut \settrue \c_framed_is_overlaid \d_framed_local_offset\zeropoint} % \setvalue{\??framedoffsetalternative\v!strut}% % {\setfalse\c_framed_has_offset % \settrue \c_framed_has_strut % \settrue \c_framed_is_overlaid % \d_framed_local_offset\zeropoint} \setvalue{\??framedoffsetalternative\v!default}% new per 2-6-2000 {\settrue \c_framed_has_offset \settrue \c_framed_has_strut \setfalse\c_framed_is_overlaid \let\localoffset\defaultframeoffset \letframedparameter\c!offset\defaultframeoffset % brrr \d_framed_local_offset\dimexpr\localoffset+\d_framed_linewidth\relax} \setvalue{\??framedoffsetalternative\s!unknown}% {\settrue \c_framed_has_offset \settrue \c_framed_has_strut \setfalse\c_framed_is_overlaid \let\defaultframeoffset\localoffset \d_framed_local_offset\dimexpr\localoffset+\d_framed_linewidth\relax} % so far for alternatives \let\pack_framed_stop_orientation\relax \def\pack_framed_restart {\aftergroup\pack_framed_finish} \def\pack_framed_do_top {\raggedtopcommand\framedparameter\c!top} \def\pack_framed_do_bottom{\framedparameter\c!bottom\raggedbottomcommand} %D Carefull analysis of this macro will learn us that not all %D branches in the last conditionals can be encountered, that %D is, some assignments to \type{\next} will never occur. %D Nevertheless we implement the whole scheme, if not for %D future extensions. %D \macros %D {doassigncheckedframeoffset} %D %D Offset helper (see menus): \def\doassigncheckedframeoffset#1#2% could be a fast \csname .. \endcsname {\edef\checkedframeoffset{#2}% #1% \ifx\checkedframeoffset\empty \zeropoint\else \ifx\checkedframeoffset\v!overlay\zeropoint\else \ifx\checkedframeoffset\v!none \zeropoint\else \ifx\checkedframeoffset\v!frame \zeropoint\else \ifx\checkedframeoffset\v!default\zeropoint\else #2% \fi\fi\fi\fi\fi \relax} %D \macros %D {ifreshapeframebox} %D %D The last few lines tell what to do after the content of the %D box is collected and passed to the next macro. In the case %D of a fixed width and centered alignment, the content is %D evaluated and used to determine the most natural width. The %D rest of the code deals with backgrounds and frames. \newif\ifreshapeframebox \reshapeframeboxtrue %D Beware: setting \type {top} and \type {bottom} to nothing, may %D result in a frame that is larger that the given height! try: %D %D \starttyping %D \framed %D [height=3cm,top=,bottom=,offset=overlay] %D {\strut test \shapefill \strut test} %D \stoptyping %D %D This is intended behaviour and not a bug! One can always set %D %D \starttyping %D ...,bottom=\kern0pt,... %D \stoptyping % experiment ... \p_framed_franalyze -> we could support 'first' as location key % option but then we will always do an analysis and reimplement the location % options (btw, beware of location settings of derived functionality that bleed % into this \def\pack_framed_finish_a {\ifreshapeframebox \pack_framed_reshape_process \else\ifx\p_framed_franalyze\v!yes \pack_framed_reshape_analyze \else \pack_framed_reshape_reset \fi\fi \setfalse\c_framed_has_width} \def\pack_framed_finish_b {\ifx\p_framed_franalyze\v!yes \pack_framed_reshape_analyze \else \pack_framed_reshape_reset \fi \setfalse\c_framed_has_width} \def\pack_framed_finish_c {\ifx\p_framed_franalyze\v!yes \pack_framed_reshape_analyze \else \pack_framed_reshape_reset \fi} \unexpanded\def\pack_framed_finish {\pack_framed_stop_orientation % hm, wrong place ! should rotate the result (after reshape) \pack_framed_locator_before\p_framed_location \ifconditional\c_framed_has_format \ifx\p_framed_autowidth\v!force \pack_framed_finish_a \else\ifx\localwidth\v!fit \ifx\p_framed_autowidth\v!yes \pack_framed_finish_a \else \pack_framed_finish_b \fi \else\ifx\localwidth\v!fixed \pack_framed_finish_b \else \pack_framed_finish_c \fi\fi\fi \ifconditional\boxcontentneedsprocessing \mkdoprocessboxcontents\b_framed_normal \fi \else \pack_framed_finish_c \fi \ifconditional\c_framed_has_width \wd\b_framed_normal\d_framed_width \fi \ifconditional\c_framed_has_height \ht\b_framed_normal\d_framed_height \fi \edef\p_framed_empty{\framedparameter\c!empty}% \ifx\p_framed_empty\v!yes \pack_framed_fake_box \fi \iftrialtypesetting \else \edef\p_framed_region{\framedparameter\c!region}% \ifx\p_framed_region\v!yes % maybe later named \pack_framed_add_region \fi \fi \d_framed_applied_offset \ifconditional\c_framed_is_overlaid \zeropoint \else \d_framed_linewidth \fi \ifconditional\c_framed_has_offset \advance\d_framed_applied_offset\localoffset \fi \ifconditional\c_framed_has_extra_offset \pack_framed_apply_extra_offsets % includes \d_framed_applied_offset \else \ifzeropt\d_framed_applied_offset \else \pack_framed_widen_box \fi \fi % \ifx\postprocessframebox\relax \else \let\next\postprocessframebox \let\postprocessframebox\relax % prevent nesting \next\b_framed_normal \fi \iftrialtypesetting % new \else \ifconditional\c_framed_has_frame % real or invisible frame \pack_framed_add_outline \fi \ifx\p_framed_background\empty \else \edef\p_framed_component{\framedparameter\c!component}% \pack_framed_add_background \fi \fi \pack_framed_locator_after\p_framed_location \box\b_framed_normal \global\frameddimensionstate % global so to be used directly afterwards ! \ifconditional\c_framed_has_width \ifconditional\c_framed_has_height \plusthree \else \plusone \fi \else \ifconditional\c_framed_has_height \plustwo \else \zerocount \fi \fi \egroup \egroup} \installcorenamespace{framedlocatorbefore} \installcorenamespace{framedlocatorafter} \newconstant\frameddimensionstate % global state: 0=unknown 1=width 2=height 3=both \def\pack_framed_fake_box {\setbox\scratchbox\emptyhbox \wd\scratchbox\wd\b_framed_normal \ht\scratchbox\ht\b_framed_normal \dp\scratchbox\dp\b_framed_normal \setbox\b_framed_normal\box\scratchbox} \def\installframedlocator#1#2#3% {\setvalue{\??framedlocatorbefore#1}{#2}% \setvalue{\??framedlocatorafter #1}{#3}} \def\pack_framed_locator_before#1{\csname\??framedlocatorbefore#1\endcsname} \def\pack_framed_locator_after #1{\csname\??framedlocatorafter #1\endcsname} \newdimen\d_framed_locator_ht \newdimen\d_framed_locator_dp \def\pack_framed_locater_set#1% {\d_framed_locator_ht\dimexpr #1+\d_framed_linewidth \ifconditional\c_framed_has_offset +\framedparameter\c!offset \fi \relax \d_framed_locator_dp\dimexpr\ht\b_framed_normal-\d_framed_locator_ht\relax} % \ruledhbox % {A % \framed[width=2cm,align=middle,location=hanging]{location\\equals\\hanging} % \framed[width=2cm,align=middle,location=depth] {location\\equals\\depth} % \framed[width=2cm,align=middle,location=height] {location\\equals\\height} % B} % \vskip2cm % \ruledhbox % {A % \framed[width=2cm,align=middle,location=low] {location\\equals\\low} % \framed[width=2cm,align=middle,location=line] {location\\equals\\line} % \framed[width=2cm,align=middle,location=high] {location\\equals\\high} % B} % \vskip2cm % \ruledhbox % {A % \framed[width=2cm,align=middle,location=top] {location\\equals\\top} % \framed[width=2cm,align=middle,location=bottom] {location\\equals\\bottom} % \framed[width=2cm,align=middle,location=lohi] {location\\equals\\lohi} % \framed[width=2cm,align=middle,location=middle] {location\\equals\\middle} % B} \installframedlocator \v!hanging % best with strut=no {} {\dp\b_framed_normal\ht\b_framed_normal \ht\b_framed_normal\zeropoint} \installframedlocator \v!depth {} {\ht\b_framed_normal\dimexpr\ht\b_framed_normal-\strutdp\relax \dp\b_framed_normal\strutdp \box\b_framed_normal} \installframedlocator \v!height {} {\dp\b_framed_normal\dimexpr\ht\b_framed_normal-\strutht\relax \ht\b_framed_normal\strutht \box\b_framed_normal} \installframedlocator \v!high {} {\pack_framed_locater_set\strutht \setbox\b_framed_normal\hbox{\lower\d_framed_locator_dp\box\b_framed_normal}% \ht\b_framed_normal\strutht \dp\b_framed_normal\strutdp \hbox{\box\b_framed_normal}} \installframedlocator \v!line {} {\setbox\b_framed_normal\hbox{\lower.5\ht\b_framed_normal\box\b_framed_normal}% \ht\b_framed_normal.5\lineheight \dp\b_framed_normal.5\lineheight \hbox{\box\b_framed_normal}} \installframedlocator \v!low {} {\pack_framed_locater_set\strutdp \setbox\b_framed_normal\hbox{\lower\d_framed_locator_ht\box\b_framed_normal}% \ht\b_framed_normal\strutht \dp\b_framed_normal\strutdp \box\b_framed_normal} \installframedlocator \v!top {} {\pack_framed_locater_set\strutht \setbox\b_framed_normal\hbox{\lower\d_framed_locator_dp\box\b_framed_normal}% \ht\b_framed_normal\d_framed_locator_ht \dp\b_framed_normal\d_framed_locator_dp \hbox{\box\b_framed_normal}} \installframedlocator \v!middle {} {\scratchdimen.5\ht\b_framed_normal \setbox\b_framed_normal\hbox{\lower\scratchdimen\box\b_framed_normal}% \ht\b_framed_normal\scratchdimen \dp\b_framed_normal\scratchdimen \hbox{\box\b_framed_normal}} \installframedlocator \v!lohi {\pack_framed_locator_before\v!middle} {\pack_framed_locator_after \v!middle} \installframedlocator \v!bottom {} {\pack_framed_locater_set\strutdp \setbox\b_framed_normal\hbox{\lower\d_framed_locator_ht\box\b_framed_normal}% \ht\b_framed_normal\d_framed_locator_dp \dp\b_framed_normal\d_framed_locator_ht \hbox{\box\b_framed_normal}} \installframedlocator \v!keep % retains height/depth {\pack_framed_remove_depth} {\pack_framed_restore_depth} % also used in fastlocalframed \newdimen\d_framed_original_wd \newdimen\d_framed_original_ht \newdimen\d_framed_original_dp \def\pack_framed_remove_depth {\d_framed_original_wd\wd\b_framed_normal \d_framed_original_ht\ht\b_framed_normal \d_framed_original_dp\dp\b_framed_normal \ifzeropt\d_framed_original_dp\else \setbox\b_framed_normal\hbox{\raise\d_framed_original_dp\box\b_framed_normal}% \fi \wd\b_framed_normal\d_framed_original_wd \ht\b_framed_normal\dimexpr\d_framed_original_ht+\d_framed_original_dp\relax \dp\b_framed_normal\zeropoint} \def\pack_framed_restore_depth {\ifzeropt\d_framed_original_dp \else \setbox\b_framed_normal\hbox{\lower\d_framed_original_dp\box\b_framed_normal}% \fi \wd\b_framed_normal\d_framed_original_wd \ht\b_framed_normal\d_framed_original_ht \dp\b_framed_normal\d_framed_original_dp} % \framed[width=12cm,height=3cm,orientation=0]{\input ward\relax} % \framed[width=12cm,height=3cm,orientation=90]{\input ward\relax} % \framed[width=12cm,height=3cm,orientation=180]{\input ward\relax} % \framed[width=12cm,height=3cm,orientation=270]{\input ward\relax} % \framed[width=12cm,height=3cm,orientation=-90]{\input ward\relax} % \framed[width=12cm,height=3cm,orientation=-180]{\input ward\relax} % \framed[width=12cm,height=3cm,orientation=-270]{\input ward\relax} \def\pack_framed_start_orientation {\ifcase\p_framed_orientation \let\pack_framed_stop_orientation\relax \else \scratchcounter\p_framed_orientation % weird .. why \divide\scratchcounter\plustwo \ifodd\scratchcounter \let\pack_framed_stop_orientation\pack_framed_stop_orientation_odd \else \let\pack_framed_stop_orientation\pack_framed_stop_orientation_even \fi \fi} \def\pack_framed_stop_orientation_odd {\swapmacros\framedwidth\framedheight \swapmacros\localwidth\localheight \swapdimens\d_framed_height\d_framed_width \pack_framed_stop_orientation_even} \def\pack_framed_stop_orientation_even {\setbox\b_framed_normal\hbox{\dorotatebox\p_framed_orientation\hbox{\box\b_framed_normal}}} %D The last conditional takes care of the special situation of %D in||line \inframed[height=3cm]{framed} boxes. Such boxes have %D to be \inframed{aligned} with the running text. \unexpanded\def\inframed {\dosingleempty\pack_framed_inline} % \def\pack_framed_inline[#1]% % {\framed[\c!location=\v!low,#1]} % % or: \def\pack_framed_inline[% {\framed[\c!location=\v!low,} %D When we set \type{empty} to \type{yes}, we get %D ourselves a frame and/or background, but no content, so %D actually we have a sort of phantom framed box. %D \macros %D {mframed, minframed} %D %D When Tobias asked how to frame mathematical elements in %D formulas, Taco's posted the next macro: %D %D \starttyping %D \def\mframed#1% %D {\relax %D \ifmmode %D \vcenter{\hbox{\framed{$\ifinner\else\displaystyle\fi#1$}}}% %D \else %D \framed{$#1$}% %D \fi} %D \stoptyping %D %D Because \type {\ifinner} does not (always) reports what %D one would expect, we move the test to the outer level. We %D also want to pass arguments, %D %D \starttyping %D \def\mframed% %D {\dosingleempty\domframed} %D %D \def\domframed[#1]#2% % tzt \dowithnextmathbox ? %D {\relax %D \ifmmode %D \ifinner %D \inframed[#1]{$#2$}% %D \else %D \vcenter{\hbox{\framed[#1]{$\displaystyle#2$}}}% %D \fi %D \else %D \inframed[#1]{$#2$}% %D \fi} %D \stoptyping %D %D Still better is the next alternative, if only because it %D takes care of setting the super- and subscripts styles \newcount\c_framed_mstyle \unexpanded\def\pack_framed_math_strut {\Ustartmath \triggermathstyle\c_framed_mstyle \vphantom{(}% \Ustopmath} % \unexpanded\def\mframed {\dosingleempty\pack_framed_math_display} % \unexpanded\def\inmframed{\dosingleempty\pack_framed_math_inline } % % \def\pack_framed_math_inline[#1]#2% % {\begingroup % \c_framed_mstyle\mathstyle % \inframed[#1]{\Ustartmath\triggermathstyle\c_framed_mstyle#2\Ustopmath}% % \endgroup} % % \def\pack_framed_math_display[#1]#2% % {\begingroup % \c_framed_mstyle\mathstyle % \let\normalstrut\pack_framed_math_strut % \framed[#1]{\Ustartmath\triggermathstyle\c_framed_mstyle#2\Ustopmath}% % \endgroup} \installcorenamespace{mathframed} \installframedcommandhandler \??mathframed {mathframed} \??mathframed \appendtoks \setuevalue{\currentmathframed}{\pack_framed_mathframed{\currentmathframed}}% \to \everydefinemathframed \unexpanded\def\pack_framed_mathframed#1% {\begingroup \edef\currentmathframed{#1}% \dosingleempty\pack_framed_mathframed_indeed} \def\pack_framed_mathframed_indeed[#1]#2% no fancy nesting supported here {\iffirstargument \setupcurrentmathframed[#1]% \fi \c_framed_mstyle\mathstyle \doifnot{\mathframedparameter\c!location}\v!low{\let\normalstrut\pack_framed_math_strut}% \inheritedmathframedframed{\Ustartmath\triggermathstyle\c_framed_mstyle#2\Ustopmath}% \endgroup} \definemathframed[mframed] \definemathframed[inmframed][\c!location=\v!low] %D So instead of the rather versatile \type {\framed}, we ue %D the \type {\mframed}. %D %D \startbuffer %D \startformula %D x \times \mframed{y} \times y^{z_z} %D x \times \inmframed{y} \times y^{z_z} %D \stopformula %D \stopbuffer %D %D \typebuffer \getbuffer %D %D And: %D %D \startbuffer %D \startformula %D x \times \mframed{y} \times y^{\mframed{z}_{\mframed{z}}} %D \stopformula %D \stopbuffer %D %D \typebuffer \getbuffer %D %D As usual, one can specify in what way the text should be %D framed. One should be aware of the fact that, inorder to %D preserve the proper spacing, the \type {offset} is set to %D \type {overlay} and \type {frameoffset} is used used %D instead. %D %D \startbuffer %D \startformula %D x \times y^{\mframed[framecolor=red]{z}_{z}} %D \stopformula %D \stopbuffer %D %D \typebuffer \getbuffer %D %D For inline use, we also provide the \type {\inmframed} %D alternative: we want $x \times \inmframed{y}$ in inline %D math, right? %D This previous framing macros needs a lot of alternatives for %D putting rules around boxes, inserting offsets and aligning %D text. Each step is handled by separate macros. \newdimen\d_framed_applied_offset \newdimen\d_framed_loffset \newdimen\d_framed_roffset \newdimen\d_framed_toffset \newdimen\d_framed_boffset \def\pack_framed_check_extra_offsets {\setfalse\c_framed_has_extra_offset \d_framed_loffset\framedparameter\c!loffset\relax \d_framed_roffset\framedparameter\c!roffset\relax \d_framed_toffset\framedparameter\c!toffset\relax \d_framed_boffset\framedparameter\c!boffset\relax \ifzeropt\d_framed_loffset\else \advance\d_framed_width -\d_framed_loffset \settrue\c_framed_has_extra_offset \fi \ifzeropt\d_framed_roffset\else \advance\d_framed_width -\d_framed_roffset \settrue\c_framed_has_extra_offset \fi \ifzeropt\d_framed_toffset\else \advance\d_framed_height-\d_framed_toffset \settrue\c_framed_has_extra_offset \fi \ifzeropt\d_framed_boffset\else \advance\d_framed_height-\d_framed_boffset \settrue\c_framed_has_extra_offset \fi} \def\pack_framed_apply_extra_offsets {\setbox\b_framed_normal\vbox\bgroup \advance\d_framed_toffset\d_framed_applied_offset \advance\d_framed_boffset\d_framed_applied_offset \advance\d_framed_loffset\d_framed_applied_offset \advance\d_framed_roffset\d_framed_applied_offset \kern\d_framed_toffset \hbox\bgroup \kern\d_framed_loffset \box\b_framed_normal \kern\d_framed_roffset \egroup \kern\d_framed_boffset \egroup} \def\pack_framed_widen_box {\setbox\b_framed_normal\vbox {\kern\d_framed_applied_offset \hbox{\kern\d_framed_applied_offset\box\b_framed_normal\kern\d_framed_applied_offset}% \kern\d_framed_applied_offset}} %D Let's hope that the next few examples show us enough of %D what needs to be done by the auxiliary macros. %D %D \startbuffer %D \framed[height=1cm,offset=.5cm] {rule based learning} %D \framed[height=1cm,offset=0cm] {rule based learning} %D \framed[height=1cm,offset=none] {rule based learning} %D \framed[height=1cm,offset=overlay]{rule based learning} %D \stopbuffer %D %D \typebuffer %D %D \startlinecorrection %D \hbox{\getbuffer} %D \stoplinecorrection %D %D \startbuffer %D \framed[offset=.5cm] {rule based learning} %D \framed[offset=0cm] {rule based learning} %D \framed[offset=none] {rule based learning} %D \framed[offset=overlay]{rule based learning} %D \stopbuffer %D %D \typebuffer %D %D \startlinecorrection %D \hbox{\getbuffer} %D \stoplinecorrection %D %D \startbuffer %D \framed[strut=nee,offset=.5cm] {rule based learning} %D \framed[strut=nee,offset=0cm] {rule based learning} %D \framed[strut=nee,offset=none] {rule based learning} %D \framed[strut=nee,offset=overlay]{rule based learning} %D \stopbuffer %D %D \typebuffer %D %D \startlinecorrection %D \hbox{\getbuffer} %D \stoplinecorrection %D %D \startbuffer %D \framed[width=3cm,align=left] {rule\\based\\learning} %D \framed[width=3cm,align=middle] {rule\\based\\learning} %D \framed[width=3cm,align=right] {rule\\based\\learning} %D \framed[width=fit,align=middle] {rule\\based\\learning} %D \stopbuffer %D %D \typebuffer %D %D \startlinecorrection %D \hbox{\dontcomplain\getbuffer} %D \stoplinecorrection %D %D So now we're ready for the complicated stuff. We distinguish %D between borders with straight lines and those with round %D corners. When using the first alternative it is possible to %D turn off one or more lines. More fancy shapes are also %D possible by specifying dedicated backgrounds. Turning lines %D on and off is implemented as efficient as possible and as a %D result is interface language dependant. This next %D implementation evolved from simpler ones. It puts for %D instance the rules on top of the content and provides %D additional offset capabilities. The lot of calls to other %D macros makes this mechanism not that easy to comprehend. %D We handle left, right or middle alignment as well as fixed %D or free widths and heights. Each combination gets its own %D macro. %D The following code handles one-liners: \type{align={line,flushright}}. %D Beware, since we entered a group and either or not grab the next %D bgroup token, we need to finish the group in the oneliner mode. \ifdefined\raggedonelinerstate \else \newconditional\raggedonelinerstate \fi \def\doformatonelinerbox % beware: assumes explicit preceding bgroup {\ifconditional\raggedonelinerstate \expandafter\dodoformatonelinerbox \else \expandafter\nodoformatonelinerbox \fi} \def\dodoformatonelinerbox {\afterassignment\redoformatonelinerbox \setbox\nextbox\hbox} \def\redoformatonelinerbox {\aftergroup\dododoformatonelinerbox \ignorespaces} \def\dododoformatonelinerbox {\hbox to \hsize {\ifcase\raggedstatus\or\hss\or\hss \fi \unhbox\nextbox \removeunwantedspaces \ifcase\raggedstatus\or \or\hss\or\hss\fi}% \egroup} \def\nodoformatonelinerbox % grabs { {\let\next=} %D The handlers: \def\pack_framed_forgetall{\forgetall} % test: (saves one forgetall) % % \edef\framedbackground{\framedparameter\c!background}% % \ifx\framedbackground\empty % \let\pack_framed_forgetall\forgetall % \else % \let\pack_framed_forgetall\relax % \forgetall % \fi \def\pack_framed_set_foregroundcolor {\edef\p_framed_foregroundcolor{\framedparameter\c!foregroundcolor}% \ifx\p_framed_foregroundcolor\empty\else\dousecolorparameter\p_framed_foregroundcolor\fi} \def\pack_framed_do_setups {\ifx\p_framed_setups\empty \else \setups[\p_framed_setups]% \texsetup \fi} \def\pack_framed_format_format_yes {\vbox to \d_framed_height \bgroup \let\postprocessframebox\relax \pack_framed_forgetall \iftrialtypesetting \else \pack_framed_set_foregroundcolor \fi \oninterlineskip \hsize\d_framed_width \vsize\d_framed_height \pack_framed_do_setups \raggedcommand \pack_framed_do_top \bgroup \localbegstrut \aftergroup\localendstrut \aftergroup\pack_framed_do_bottom \aftergroup\egroup \doformatonelinerbox} \def\pack_framed_format_format_nop {\vbox to \d_framed_height \bgroup \let\postprocessframebox\relax \pack_framed_forgetall \iftrialtypesetting \else \pack_framed_set_foregroundcolor \fi \oninterlineskip \hsize\d_framed_width \vsize\d_framed_height \pack_framed_do_setups \raggedcenter \vss \bgroup \localbegstrut \aftergroup\localendstrut \aftergroup\vss \aftergroup\egroup \doformatonelinerbox} \def\pack_framed_format_format_height {\vbox to \d_framed_height \bgroup \let\postprocessframebox\relax \pack_framed_forgetall \iftrialtypesetting \else \pack_framed_set_foregroundcolor \fi \oninterlineskip \pack_framed_do_setups \raggedcommand \vss \bgroup \aftergroup\localendstrut \aftergroup\vss \aftergroup\egroup \localbegstrut \doformatonelinerbox} \def\pack_framed_format_format_width {\vbox \bgroup \let\postprocessframebox\relax \pack_framed_forgetall \iftrialtypesetting \else \pack_framed_set_foregroundcolor \fi \oninterlineskip \hsize\d_framed_width \pack_framed_do_setups \raggedcommand \pack_framed_do_top \bgroup \localbegstrut \aftergroup\localendstrut \aftergroup\pack_framed_do_bottom \aftergroup\egroup \doformatonelinerbox} \def\pack_framed_format_format_vsize {\vbox to \d_framed_height \bgroup \let\postprocessframebox\relax \pack_framed_forgetall \iftrialtypesetting \else \pack_framed_set_foregroundcolor \fi \vsize\d_framed_height \pack_framed_do_setups \vss \bgroup \aftergroup\vss \aftergroup\egroup \hbox \bgroup \aftergroup\egroup \localstrut \doformatonelinerbox} \def\pack_framed_format_format_hsize {\hbox to \d_framed_width \bgroup \let\postprocessframebox\relax \pack_framed_forgetall \iftrialtypesetting \else \pack_framed_set_foregroundcolor \fi \pack_framed_do_setups \hss \localstrut \bgroup \aftergroup\hss \aftergroup\egroup \doformatonelinerbox} \def\pack_framed_format_format_no_size {\hbox \bgroup \iftrialtypesetting \else \pack_framed_set_foregroundcolor \fi \let\postprocessframebox\relax \pack_framed_do_setups \localstrut \doformatonelinerbox} %D On the next page we show some examples of how these macros %D come into action. The examples show us how %D \type {fit}, \type {broad} dimensions influence the %D formatting. Watch the visualized struts. \footnote {Here we %D used \type {\showstruts}.} %D %D \startpostponing %D \bgroup %D \showstruts %D \dontcomplain %D \starttabulate[|c|c|c|c|c|c|] %D % \HL %D \NC \framed[width=.2\hsize, height=.2\hsize, align=] {a\endgraf b\endgraf c} %D \NC \framed[width=.2\hsize, height=broad, align=] {a\endgraf b\endgraf c} %D \NC \framed[width=.2\hsize, height=fit, align=] {a\endgraf b\endgraf c} %D \NC \framed[width=fit, height=.2\hsize, align=] {a\endgraf b\endgraf c} %D \NC \framed[width=fit, height=broad, align=] {a\endgraf b\endgraf c} %D \NC \framed[width=fit, height=fit, align=] {a\endgraf b\endgraf c} %D \NC \NR %D % \HL %D \NC \framed[width=.2\hsize, height=.2\hsize, align=yes] {a\endgraf b\endgraf c} %D \NC \framed[width=.2\hsize, height=broad, align=yes] {a\endgraf b\endgraf c} %D \NC \framed[width=.2\hsize, height=fit, align=yes] {a\endgraf b\endgraf c} %D \NC \framed[width=fit, height=.2\hsize, align=yes] {a\endgraf b\endgraf c} %D \NC \framed[width=fit, height=broad, align=yes] {a\endgraf b\endgraf c} %D \NC \framed[width=fit, height=fit, align=yes] {a\endgraf b\endgraf c} %D \NC \NR %D % \HL %D \NC \framed[width=.2\hsize, height=.2\hsize, align=right] {a\endgraf b\endgraf c} %D \NC \framed[width=.2\hsize, height=broad, align=right] {a\endgraf b\endgraf c} %D \NC \framed[width=.2\hsize, height=fit, align=right] {a\endgraf b\endgraf c} %D \NC \framed[width=fit, height=.2\hsize, align=right] {a\endgraf b\endgraf c} %D \NC \framed[width=fit, height=broad, align=right] {a\endgraf b\endgraf c} %D \NC \framed[width=fit, height=fit, align=right] {a\endgraf b\endgraf c} %D \NC \NR %D % \HL %D \NC \framed[width=.2\hsize, height=.2\hsize, align=left] {a\endgraf b\endgraf c} %D \NC \framed[width=.2\hsize, height=broad, align=left] {a\endgraf b\endgraf c} %D \NC \framed[width=.2\hsize, height=fit, align=left] {a\endgraf b\endgraf c} %D \NC \framed[width=fit, height=.2\hsize, align=left] {a\endgraf b\endgraf c} %D \NC \framed[width=fit, height=broad, align=left] {a\endgraf b\endgraf c} %D \NC \framed[width=fit, height=fit, align=left] {a\endgraf b\endgraf c} %D \NC \NR %D % \HL %D \NC \framed[width=.2\hsize, height=.2\hsize, align=middle] {a\endgraf b\endgraf c} %D \NC \framed[width=.2\hsize, height=broad, align=middle] {a\endgraf b\endgraf c} %D \NC \framed[width=.2\hsize, height=fit, align=middle] {a\endgraf b\endgraf c} %D \NC \framed[width=fit, height=.2\hsize, align=middle] {a\endgraf b\endgraf c} %D \NC \framed[width=fit, height=broad, align=middle] {a\endgraf b\endgraf c} %D \NC \framed[width=fit, height=fit, align=middle] {a\endgraf b\endgraf c} %D \NC \NR %D % \HL %D \stoptabulate %D \egroup %D \stoppostponing %D \macros %D {framednoflines, framedlastlength} %D %D It is possible to let the frame macro calculate the width %D of a centered box automatically (\type {fit}). When %D doing so, we need to reshape the box: \newcount\framednoflines \newdimen\framedfirstheight \newdimen\framedlastdepth \newdimen\framedminwidth \newdimen\framedmaxwidth \newdimen\framedaveragewidth \def\pack_framed_reshape_reset {\framednoflines \zerocount \framedfirstheight \zeropoint \framedlastdepth \zeropoint \framedminwidth \zeropoint \framedmaxwidth \zeropoint \framedaveragewidth\zeropoint} \def\pack_framed_reshape_process{\ifvbox\b_framed_normal\ctxcommand{doreshapeframedbox(\number\b_framed_normal)}\fi} \def\pack_framed_reshape_analyze{\ifvbox\b_framed_normal\ctxcommand{doanalyzeframedbox(\number\b_framed_normal)}\fi} % torture test / strange case (much depth) / method 2 needed % % \startTEXpage[frame=on] % \startformula \startalign \NC A \NC B \NR \intertext{test} \NC C \NC D \NR \stopalign \stopformula % test outside formula % \startformula \startalign \NC A \NC B \NR \intertext{test} \NC C \NC D \NR \stopalign \stopformula % \blank[big] % \startformula \startalign \NC \int_01 \NC B \NR \intertext{test} \NC \int_01 \NC D \NR \stopalign \stopformula % test outside formula % \startformula \startalign \NC \int_01 \NC B \NR \intertext{test} \NC \int_01 \NC D \NR \stopalign \stopformula % \stopTEXpage %D The examples on the next page show how one can give the %D frame as well as the background an additional offset and %D even a bit more depth. The blue outline is the frame, the %D red box is the background and the small black outline is the %D visualization of the resulting box, that is, we applied %D \type{\ruledhbox} to the result. %D \startpostponing %D \bgroup %D \unprotect %D \dontcomplain %D %D \startbuffer %D \vbox to \vsize %D \bgroup %D \startalignment[middle] %D \vss %D \dontleavehmode\vbox to .8\vsize %D \bgroup %D \hsize=300pt %D \setupframed %D [background=color, %D backgroundcolorachtergrondkleur=darkred, %D width=300pt, %D height=60pt, %D framecolorkaderkleur=DemoBlue, %D rulethickness=2pt] %D \def\status% %D {backgroundoffset=\the\dimexpr\framedparameter\c!backgroundoffset\relax\\ %D frameoffset=\the\dimexpr\framedparameter\c!frameoffset\relax\\ %D depth=\the\dimexpr\framedparameter\c!depth\relax} %D \dontleavehmode \ruledhbox{\framed[backgroundoffset=0pt,frameoffset=0pt]{\status}} %D \vss %D \dontleavehmode \ruledhbox{\framed[backgroundoffset=5pt,frameoffset=0pt]{\status}} %D \vss %D \dontleavehmode \ruledhbox{\framed[backgroundoffset=0pt,frameoffset=5pt]{\status}} %D \vss %D \dontleavehmode \ruledhbox{\framed[backgroundoffset=2pt,frameoffset=5pt]{\status}} %D \vss %D \dontleavehmode \ruledhbox{\framed[backgroundoffset=5pt,frameoffset=2pt]{\status}} %D \vss %D \dontleavehmode \ruledhbox{\framed[backgroundoffset=5pt,frameoffset=5pt]{\status}} %D \egroup %D \vss %D \stopalignment %D \egroup %D \stopbuffer %D %D \getbuffer \page %D %D {\setupframed[depth=4pt]\getbuffer} \page %D %D \protect %D \egroup %D \stoppostponing %D We can draw lines from left to right and top to bottom by %D using the normal \type{\hairline} command. Both directions %D need a different treatment. %D %D \startbuffer %D \framed[width=4cm] {alfa\hairline beta\hairline gamma} %D \framed[height=2cm] {alfa\hairline beta\hairline gamma} %D \framed[width=4cm,height=2cm]{alfa\hairline beta\hairline gamma} %D \stopbuffer %D %D \typebuffer %D %D \startlinecorrection %D \hbox{\getbuffer} %D \stoplinecorrection %D %D These macros try to adapt their behaviour as good as %D possible to the circumstances and act as natural as %D possible. % \unexpanded\def\pack_framed_vboxed_hairline % {\bgroup % \dimen2=\ifconditional\c_framed_has_offset \localoffset \else \zeropoint \fi % \dimen4=\dimexpr\dimen2+\d_framed_linewidth\relax % \setbox0\vbox % {\advance\hsize 2\dimen4 % \vskip\dimen2 % \hrule % \!!height\d_framed_linewidth % \!!depth\zeropoint % \!!width\hsize % \vskip\dimen2}% % \endgraf\obeydepth\nointerlineskip % \moveleft\dimen4\box0 % \endgraf\nointerlineskip\localbegstrut % beware, we might kill it in a style using \vskip\lineheight % \egroup} % so this must not be changed \unexpanded\def\pack_framed_vboxed_hairline % nasty overlay mess .. needed for autowidth {\begingroup \scratchoffset\ifconditional\c_framed_has_offset \localoffset \else \zeropoint \fi \scratchwidth \dimexpr\scratchoffset+\d_framed_linewidth\relax \par \nointerlineskip \kern\scratchoffset \dontleavehmode \hrule\!!height\d_framed_linewidth\!!depth\zeropoint \par \kern-\d_framed_linewidth \dontleavehmode \hbox to \zeropoint{\normalhss\vrule\!!height\d_framed_linewidth\!!depth\zeropoint\!!width\scratchwidth}% \hfill \hbox to \zeropoint{\vrule\!!height\d_framed_linewidth\!!depth\zeropoint\!!width\scratchwidth\normalhss}% \par \nointerlineskip \kern\scratchoffset \nointerlineskip \endgraf \nointerlineskip \localbegstrut \endgroup} % todo: \unexpanded\def\pack_framed_hboxed_hairline % use framed dimen {\bgroup \dimen2=\ifconditional\c_framed_has_offset \localoffset \else \zeropoint \fi \ifconditional\c_framed_has_height \dimen4\dimexpr\localheight/2+\strutdp-2\d_framed_linewidth\relax \dimen6\dimexpr\localheight/2-\strutdp+2\d_framed_linewidth\relax \else \dimen4\dimexpr\strutht+\dimen2\relax \dimen6\dimexpr\strutdp+\dimen2\relax \fi \unskip \setbox\scratchbox\hbox {\hskip\dimen2 \vrule\!!height\dimen4\!!depth\dimen6\!!width\d_framed_linewidth \hskip\dimen2}% \ht\scratchbox\strutht \dp\scratchbox\strutdp \box\scratchbox \ignorespaces \egroup} %D The argument of the frame command accepts \type{\\} as a %D sort of newline signal. In horizontal boxes it expands to a %D space. \unexpanded\def\pack_framed_vboxed_newline {\endgraf\ignorespaces} \unexpanded\def\pack_framed_hboxed_newline {\unskip\normalspace\ignorespaces} %D We can set each rule on or off. The default setting is %D inherited from \type{frame}. An earlier implementation %D use a bit different approach, but the new one seems more %D natural: %D %D \bgroup %D \setuptyping[margin=0pt] %D \startlinecorrection %D \startbuffer %D \framed[offset=overlay,frame=on]{\darkred\blackrule} %D \stopbuffer %D \hbox{\getbuffer\vbox{\typebuffer}} %D %D \startbuffer %D \framed[offset=overlay,frame=on,bottomframe=off]{\darkred\blackrule} %D \stopbuffer %D \hbox{\getbuffer\vbox{\typebuffer}} %D %D \startbuffer %D \framed[offset=overlay,frame=on,bottomframe=on]{\darkred\blackrule} %D \stopbuffer %D \hbox{\getbuffer\vbox{\typebuffer}} %D %D \startbuffer %D \framed[offset=overlay,frame=off]{\darkred\blackrule} %D \stopbuffer %D \hbox{\getbuffer\vbox{\typebuffer}} %D %D \startbuffer %D \framed[offset=overlay,frame=off,bottomframe=off]{\darkred\blackrule} %D \stopbuffer %D \hbox{\getbuffer\vbox{\typebuffer}} %D %D \startbuffer %D \framed[offset=overlay,frame=off,bottomframe=on]{\darkred\blackrule} %D \stopbuffer %D \hbox{\getbuffer\vbox{\typebuffer}} %D \stoplinecorrection %D \egroup %D \macros %D {startframedtext, setupframedtexts, defineframedtext} %D %D The general framing command we discussed previously, is not %D entirely suited for what we call framed texts, as for %D instance used in intermezzo's. The next examples show what %D we have in mind. %D %D \startbuffer[framed-0] %D \setupframedtexts %D [frame=off, %D width=\hsize, %D background=screen] %D %D \startframedtext %D By default the framed text is centered \dots %D \stopframedtext %D %D \startframedtext[right] %D \dots\ but we can also align left, middle and right. %D \stopframedtext %D \stopbuffer %D %D \startbuffer[framed-1] %D \defineframedtext %D [Example] %D [width=6cm, %D height=5cm] %D %D \startExample %D \typebuffer[framed-1] %D \stopExample %D \stopbuffer %D %D \startbuffer[framed-2] %D \defineframedtext %D [Example] %D [width=6cm] %D %D \startExample %D \typebuffer[framed-2] %D \stopExample %D \stopbuffer %D %D \startbuffer[framed-3] %D \defineframedtext %D [Example] %D [height=5cm] %D %D \startExample %D \typebuffer[framed-3] %D \stopExample %D \stopbuffer %D %D \startbuffer[framed-4] %D \defineframedtext %D [Example] %D [width=fit,height=broad] %D %D \Example{a very exciting example} %D \stopbuffer %D %D \bgroup \setuptyping[margin=0pt] \getbuffer[framed-0] \egroup %D \bgroup \setuptyping[margin=0pt] \getbuffer[framed-1] \egroup %D \bgroup \setuptyping[margin=0pt] \getbuffer[framed-2] \egroup %D \bgroup \setuptyping[margin=0pt] \getbuffer[framed-3] \egroup %D \bgroup \setuptyping[margin=0pt] \getbuffer[framed-4] \egroup %D %D Here we can see that we have a predefined framed text class %D as well as the tools for defining our own. So we have: %D %D \showsetup{setupframedtexts} %D %D as well as the definition command: %D %D \showsetup{defineframedtext} %D %D that generates two commands: %D %D \showsetup{start<>} %D \showsetup{<>} %D %D The next definition shows the defaults. \installcorenamespace{framedtext} \installcorenamespace{framedtextlocation} \installframedcommandhandler \??framedtext {framedtext} \??framedtext \let\setupframedtexts\setupframedtext \setupframedtext [\c!width=0.75\hsize, \c!height=\v!fit, \c!align=\v!yes, %\c!top=, \c!bottom=\vfill, \c!offset=1em, %\c!bodyfont=, %\c!style=, %\c!color=, %\c!left=, \c!right=\hfill, \c!before=\blank, \c!after=\blank, %\c!inner=, \c!frame=\v!on, %\c!topframe=, %\c!bottomframe=, %\c!leftframe=, %\c!rightframe=, \c!radius=.5\bodyfontsize, \c!corner=\v!rectangular, %\c!orientation=, %\c!indenting=, %\c!foregroundcolor=, %\c!foregroundstyle=, %\c!background=, %\c!backgroundcolor=, \c!backgroundscreen=\@@rsscreen, \c!linecorrection=\v!on, \c!depthcorrection=\v!on, \c!margin=\v!standard] \appendtoks \setuevalue{\e!start\currentframedtext}{\pack_framed_text_start {\currentframedtext}}% \setuevalue{\e!stop \currentframedtext}{\pack_framed_text_stop }% \setuevalue {\currentframedtext}{\pack_framed_text_direct{\currentframedtext}}% \to \everydefineframedtext \setvalue{\??framedtextlocation\v!left }{\letframedtextparameter\c!left \relax \letframedtextparameter\c!right\hfill} \setvalue{\??framedtextlocation\v!right }{\letframedtextparameter\c!left \hfill \letframedtextparameter\c!right\relax} \setvalue{\??framedtextlocation\v!middle}{\letframedtextparameter\c!left \hfill \letframedtextparameter\c!right\hfill} \setvalue{\??framedtextlocation\v!none }{\letframedtextparameter\c!left \relax \letframedtextparameter\c!right\relax \settrue\c_framed_text_location_none} \unexpanded\def\pack_framed_text_start#1% {\bgroup \edef\currentframedtext{#1}% \dodoubleempty\pack_framed_text_start_indeed} \def\pack_framed_text_start_indeed[#1][#2]% {\doifassignmentelse{#1} {\pack_framed_text_start_continue\empty{#1}} {\pack_framed_text_start_continue{#1}{#2}}} \def\pack_framed_text_start_continue#1#2% {\setupframedtexts[\currentframedtext][#2]% \doifsomething{#1}{\setframedtextparameter\c!location{#1}}% does not listen to #3 \setfalse\c_framed_text_location_none \csname\??framedtextlocation\framedtextparameter\c!location\endcsname \resetframedtextparameter\c!location \pack_framed_text_check \setbox\b_framed_normal\vbox \startboxedcontent \hsize\localhsize % \insidefloattrue % ? better \normalexpanded{\switchtobodyfont[\framedtextparameter\c!bodyfont]}% % \startcolor[\framedtextparameter\c!color]% \letframedtextparameter\c!strut\v!no \inheritedframedtextframed\bgroup \let\\=\endgraf \framedtextparameter\c!inner % oud spul \doif{\framedtextparameter\c!depthcorrection}\v!on\pack_framed_text_start_depth_correction \doinhibitblank \setupindenting[\framedtextparameter\c!indenting]% \useframedtextstyleandcolor\c!style\c!color} %D The \type {none} option is handy for nested usage, as %D in the presentation styles, where we don't want %D interference. \defineplacement[\??framedtext][\s!parent=\??framedtext\currentframedtext] \unexpanded\def\pack_framed_text_stop % no \baselinecorrection, see faq docs {\endgraf \removelastskip \doif{\framedtextparameter\c!depthcorrection}\v!on\pack_framed_text_stop_depth_correction \stopboxedcontent % \stopcolor \ifconditional\c_framed_text_location_none \egroup \box\b_framed_normal \else\ifinsidefloat \egroup \box\b_framed_normal \else \egroup \placement[\??framedtext][\c!depthcorrection=\v!off]{\box\b_framed_normal}% \fi\fi \egroup} %D We define the general (and original) case by just saying: \def\pack_framed_text_check % messy dependency {\localhsize\hsize \ifinsidefloat \else \ifdim\d_page_sides_vsize>\zeropoint % also possible: \c_page_sides_checks_done>\zeropoint % \strut % rather clean way to invoke the sidefloat OTR % \setbox0=\lastbox % and get the widths set, so from now on we % \setlocalhsize % can have framed texts alongside sidefloats \checksidefloat \setlocalhsize \fi \fi} \def\pack_framed_text_start_depth_correction {\bgroup \ifhmode \par \fi \ifvmode \verticalstrut % we need \nowhitespace in case of setups setting whitespace % nb, not safe, text vs \vbox as next \vskip-\struttotal \nowhitespace \fi} % na vskip ! new 20/05/2004, fails with next content being box (\scale{..}) \def\pack_framed_text_stop_depth_correction {\ifhmode \par \fi \ifvmode \forgetall \vskip-\struttotal \verticalstrut \egroup \forgetall % brrr too often \vskip-\lineheight \verticalstrut \else \egroup \fi} %D Placement can be ignored: %D %D \starttyping %D \hbox to \hsize \bgroup %D \startframedtext[none][width=.5\textwidth] \input tufte \stopframedtext %D \startframedtext[none][width=.5\textwidth] \input zapf \stopframedtext %D \egroup %D %D \hbox to \hsize \bgroup %D \setupframedtexts[location=none]% %D \startframedtext[width=.5\textwidth] \input zapf \stopframedtext %D \startframedtext[width=.5\textwidth] \input tufte \stopframedtext %D \egroup %D \stoptyping %D The simple brace (or group) delimited case is typeset %D slightly different and is not aligned. \unexpanded\def\pack_framed_text_direct#1% {\bgroup \edef\currentframedtext{#1}% \dosingleempty\pack_framed_text_start_direct} \def\pack_framed_text_start_direct[#1]% {\normalexpanded{\switchtobodyfont[\framedtextparameter\c!bodyfont]}% \letframedtextparameter\c!strut\v!no \iffirstargument \setupcurrentframedtext[#1]% \fi \inheritedframedtextframed\bgroup \blank[\v!disable]% \let\\=\endgraf \framedtextparameter\c!inner \useframedtextstyleandcolor\c!style\c!color \bgroup \aftergroup\pack_framed_text_stop_direct \let\next=} \def\pack_framed_text_stop_direct {\removelastskip \egroup \egroup} \defineframedtext[\v!framedtext] %D \macros %D {defineframed} %D %D One can also define simple framed texts, using: %D %D \showsetup{defineframed} %D %D As suggested by Wolfgang we can now use the new \MKIV\ inheritance %D model instead of passing a combination of arguments. This also %D also simplified the \type {\setupframed} command. There are %D certainly more places where such improvements can be made. % actually, this can be another command handler .. todo \unexpanded\def\defineframed {\dotripleempty\pack_framed_define} \def\pack_framed_define[#1][#2][#3]% {\ifcsname\??ol:#1\endcsname % already defined, keeps settings \else \expandafter\newcount\csname\??ol:#1\endcsname % \the\everypresetframed \fi \ifsecondargument \doifassignmentelse{#2} {\getparameters[\??ol#1][\s!parent=\??ol,#2]}% {\ifcsname#2\endcsname \getparameters[\??ol#1][\s!parent=\??ol#2,#3]% \else \getparameters[\??ol#1][\s!parent=\??ol,#3]% \fi}% \else \getparameters[\??ol#1][\s!parent=\??ol,#2]% \fi \setuvalue{#1}{\pack_framed_defined_process[#1]}}% % \the\everydefineframed \newcount\c_framed_crap \unexpanded\def\pack_framed_defined_process[#1]% official (not much checking, todo: parent) {\bgroup \ifcsname\??ol:#1\endcsname \expandafter\let\expandafter\c_framed_temp\csname\??ol:#1\endcsname \else \let\c_framed_temp\c_framed_crap \fi \advance\c_framed_temp\plusone \expandafter\def\csname\??ol#1:\the\c_framed_temp\s!parent\endcsname{\??ol#1}% \inheritlocalframed \dodoubleempty\pack_framed_process[\??ol#1:\the\c_framed_temp]} \let\placeframed\pack_framed_defined_process % new per 2012/04/23 %D We can do: %D %D \starttyping %D \defineframed[\v!framed] %D \stoptyping %D %D but the existing one is ok as well (less csname messy too). %D New, for the moment private; let's see when GB finds out %D about this one and its obscure usage. It's used in: %D %D \startbuffer %D \defineframedtext %D [tabulateframe] %D [offset=overlay, %D backgroundoffset=3pt, %D background=color, %D backgroundcolor=green] %D %D \setuptabulate %D [tabulate] %D [frame=tabulateframe] %D %D \setuptables %D [frame=tabulateframe] %D %D \input tufte %D %D \starttabulate[|l|l|] %D \NC test \NC test \NC \NR \NC test \NC test \NC \NR %D \NC test \NC test \NC \NR \NC test \NC test \NC \NR %D \stoptabulate %D %D \input tufte %D %D \starttable[|l|l|] %D \NC test \NC test \NC \AR \NC test \NC test \NC \AR %D \NC test \NC test \NC \AR \NC test \NC test \NC \AR %D \stoptable %D \stopbuffer %D %D \typebuffer % to be redone \def\framedcontentparameter #1{\csname\doframedcontentparameter{\??fc\currentframedcontent}#1\endcsname} \def\doframedcontentparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\expandafter\doframedcontentparentparameter\csname#1\s!parent\endcsname#2\fi} \def\doframedcontentparentparameter#1#2{\ifx#1\relax\s!empty\else\doframedcontentparameter#1#2\fi} \def\letframedcontentparameter #1{\expandafter\let\csname\??fc\currentframedcontent#1\endcsname} \presetlocalframed[\??fc] \getparameters [\??fc] [\c!leftoffset=\zeropoint, \c!rightoffset=\framedcontentparameter\c!leftoffset, \c!topoffset=\zeropoint, \c!bottomoffset=\framedcontentparameter\c!topoffset, \c!strut=\v!no, %\c!linecorrection=\v!no, %\c!left=, %\c!right=, %\c!width=\v!fit, \c!offset=\v!overlay] \unexpanded\def\defineframedcontent {\dodoubleempty\dodefineframedcontent} \def\dodefineframedcontent[#1][#2]% {\getparameters[\??fc#1][\s!parent=\??fc,#2]} \unexpanded\def\setupframedcontent {\dodoubleempty\dosetupframedcontent} \def\dosetupframedcontent[#1][#2]% {\def\docommand##1{\getparameters[\??fc##1][#2]}% \processcommacommand[#1]\docommand} \unexpanded\def\startframedcontent {\dosingleempty\pack_framed_start_content} \def\pack_framed_start_content[#1]% {\bgroup \edef\currentframedcontent{#1}% \ifx\currentframedcontent\v!off \let\stopframedcontent\egroup \else \let\stopframedcontent\pack_framed_stop_content_indeed \expandafter\pack_framed_start_content_indeed \fi} \def\pack_framed_start_content_indeed {\setbox\b_framed_normal\hbox\bgroup \setlocalhsize \hsize\localhsize \advance\hsize\dimexpr-\framedcontentparameter\c!leftoffset-\framedcontentparameter\c!rightoffset \relax \advance\vsize\dimexpr-\framedcontentparameter\c!topoffset -\framedcontentparameter\c!bottomoffset\relax \hskip\framedcontentparameter\c!leftoffset \vbox\bgroup \vskip\framedcontentparameter\c!topoffset \vbox\bgroup \forgetall \blank[\v!disable]} \def\pack_framed_stop_content_indeed {\removelastskip \egroup \vskip\framedcontentparameter\c!bottomoffset \egroup \hskip\framedcontentparameter\c!rightoffset \egroup \doif{\framedcontentparameter\c!width}\v!fit {\letframedcontentparameter\c!width\v!fixed}% no shapebox \ifinsidefloat \donefalse \else \doifelse{\framedcontentparameter\c!linecorrection}\v!yes\donetrue\donefalse \fi % plaats ? \ifdone\startlinecorrection\fi \framedcontentparameter\c!left % new \localframed[\??fc\currentframedcontent]{\box\b_framed_normal}% hm \framedcontentparameter\c!right % new \ifdone\stoplinecorrection\fi \egroup} % A shared setting. \setuplinewidth [\v!medium] % We could omit the empty setings but that is some 10% slower due to % extra testing in the chain. \setupframed [\c!width=\v!fit, \c!height=\v!broad, %\c!lines=, \c!offset=0.25ex, % \defaultframeoffset \c!empty=\v!no, \c!frame=\v!on, %\c!topframe=, %\c!bottomframe=, %\c!leftframe=, %\c!rightframe=, \c!radius=.5\bodyfontsize, \c!rulethickness=\linewidth, \c!corner=\v!rectangular, \c!depth=\zeropoint, %\c!foregroundcolor=, %\c!foregroundstyle=, %\c!background=, \c!backgroundscreen=\@@rsscreen, %\c!backgroundcolor=, \c!backgroundoffset=\zeropoint, %\c!framecolor=, \c!frameoffset=\zeropoint, % somewhat messy \c!backgroundcorner=\framedparameter\c!corner, \c!backgroundradius=\framedparameter\c!radius, \c!backgrounddepth=\framedparameter\c!depth, \c!framecorner=\framedparameter\c!corner, \c!frameradius=\framedparameter\c!radius, \c!framedepth=\framedparameter\c!depth, % %\c!component=, %\c!region=, %\c!align=, \c!bottom=\vss, %\c!top=, \c!autostrut=\v!yes, \c!location=\v!normal, %\c!orientation=, \c!autowidth=\v!yes, %\c!setups=, \c!strut=\v!yes, %\c!loffset=\zeropoint, %\c!roffset=\zeropoint, %\c!toffset=\zeropoint, ]%\c!boffset=\zeropoint] \setupscreens [\c!screen=0.95] \protect \endinput