pack-rul.mkiv /size: 97 Kb    last modification: 2020-07-01 14:35
1
%D \module
2
%D [ file=pack-rul, % was core-rul,
3
%D version=1998.10.16,
4
%D title=\CONTEXT\ Packaging Macros,
5
%D subtitle=Ruled Content,
6
%D author=Hans Hagen,
7
%D date=\currentdate,
8
%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
9
%C
10
%C This module is part of the \CONTEXT\ macro||package and is
11
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
12
%C details.
13 14
\writestatus
{
loading
}{
ConTeXt
Packaging
Macros
/
Ruled
Content
}
15 16
%D The code here is expanded lots of time as framed is used in many places. This is
17
%D why the code here is (and gets) optimized as much as possible. Also, by avoiding
18
%D packaging and expansion we also keep tracing reasonable. For instance, multiple
19
%D stacked backgrounds can slow down a run if not optimized this way.
20 21
\registerctxluafile
{
pack
-
rul
}{
optimize
}
22 23
\unprotect
24 25
% \definesystemvariable {ol} % OmLijnd -> check scrn-fld too
26 27
%D \macros
28
%D {linewidth, setuplinewidth}
29
%D
30
%D This module deals with rules (lines) in several ways. First we introduce two
31
%D macros that can be used to set some common characteristics.
32
%D
33
%D \showsetup{setuplinewidth}
34
%D
35
%D The linewidth is available in \type{\linewidth}. The preset value of .4pt equals
36
%D the default hard coded \TEX\ rule width.
37 38
\newdimen
\linewidth
39 40
\unexpanded
\def
\setuplinewidth
41
{
\dosingleargument
\pack_framed_setup_line_width
}
42 43
\def
\pack_framed_setup_line_width
[#
1
]
%
44
{
\assigndimension
{
#
1
}
\linewidth
{
.
2
\points
}{
.
4
\points
}{
.
6
\points
}}
45 46
%D The parameter handler:
47 48
\installcorenamespace
{
framed
}
49
\installcorenamespace
{
framedtop
}
50
\installcorenamespace
{
framedbottom
}
51
\installcorenamespace
{
framedleft
}
52
\installcorenamespace
{
framedright
}
53 54
\installcorenamespace
{
regularframed
}
55
\installcorenamespace
{
simplifiedframed
}
56 57
\installcommandhandler
\??framed
{
framed
}
\??framed
58 59
\let
\pack_framed_framedparameter
\framedparameter
60
\let
\pack_framed_framedparameterhash
\framedparameterhash
61
\let
\pack_framed_setupcurrentframed
\setupcurrentframed
62 63
\def
\pack_framed_initialize
64
{
\let
\framedparameter
\pack_framed_framedparameter
65
\let
\framedparameterhash
\pack_framed_framedparameterhash
66
\let
\setupcurrentframed
\pack_framed_setupcurrentframed
67
\inframedtrue
}
68 69
%D A helper:
70 71
\def
\frameddimension
#
1
{
\the\dimexpr
\framedparameter
{
#
1
}
\relax
}
72 73
%D Inheritance:
74 75
\def
\installinheritedframed
#
1
%
76
{
\normalexpanded
{
\doinstallinheritedframed
77
\expandafter\noexpand\csname
current
#
1
\endcsname
78
\expandafter\noexpand\csname
#
1
parameter
\endcsname
79
\expandafter\noexpand\csname
#
1
parameterhash
\endcsname
80
\expandafter\noexpand\csname
do
#
1
parameter
\endcsname
81
\expandafter\noexpand\csname
do
#
1
parentparameter
\endcsname
82
\expandafter\noexpand\csname
do
#
1
rootparameter
\endcsname
83
\expandafter\noexpand\csname
setupcurrent
#
1
\endcsname
84
\expandafter\noexpand\csname
inherited
#
1
framed
\endcsname
85
\expandafter\noexpand\csname
inherited
#
1
framedbox
\endcsname
}}
% new
86 87
\unexpanded
\def
\doinstallinheritedframed
#
1
#
2
#
3
#
4
#
5
#
6
#
7
#
8
#
9
%
88
{
\def
#
5
##
1
##
2
{
\ifx
##
1
\relax
#
6
{
##
2
}
\else
#
4
{
##
1
}{
##
2
}
\fi
}
%
89
%\def#6##1{\ifcsname\??framed:##1\endcsname\??framed:##1\else\s!empty\fi}% root
90
%\def#6##1{\ifcsname\??framed:##1\endcsname\??framed:##1\else\??empty\fi}% root
91
\def
#
6
##
1
{
\ifcsname
\??framed
:
##
1
\endcsname
\??framed
:
##
1
\else
\??empty
\fi
}
% root
92
\unexpanded
\def
#
8
%
93
{
\bgroup
94
\bgroup
95
\inframedtrue
96
\let
\currentframed
#
1
%
97
\let
\framedparameter
#
2
%
98
\let
\framedparameterhash
#
3
%
99
\let
\setupcurrentframed
#
7
%
100
\pack_framed_process_indeed
}
%
101
\unexpanded
\def
#
9
%
102
{
\bgroup
103
\inframedtrue
104
\let
\currentframed
#
1
%
105
\let
\framedparameter
#
2
%
106
\let
\framedparameterhash
#
3
%
107
\let
\setupcurrentframed
#
7
%
108
\pack_framed_process_box_indeed
}}
109 110
\unexpanded
\def
\installframedcommandhandler
#
1
#
2
#
3
%
111
{
\installcommandhandler
{
#
1
}{
#
2
}{
#
3
}
%
112
\installinheritedframed
{
#
2
}}
113 114
\unexpanded
\def
\installframedautocommandhandler
#
1
#
2
#
3
%
115
{
\installautocommandhandler
{
#
1
}{
#
2
}{
#
3
}
%
116
\installinheritedframed
{
#
2
}}
117 118
\unexpanded
\def
\installsimpleframedcommandhandler
#
1
#
2
#
3
%
119
{
\installsimplecommandhandler
{
#
1
}{
#
2
}{
#
3
}
%
120
\installinheritedframed
{
#
2
}}
121 122
% for regular framed
123 124
\setupframed
125
[
\c!width
=
\v!fit
,
126
\c!height
=
\v!broad
,
127
%\c!minheight=\zeropoint,
128
%\c!lines=,
129
\c!offset
=
.
2
5
\exheight
,
% \defaultframeoffset
130
\c!empty
=
\v!no
,
131
\c!frame
=
\v!on
,
132
%\c!topframe=,
133
%\c!bottomframe=,
134
%\c!leftframe=,
135
%\c!rightframe=,
136
\c!radius
=
.
5
\bodyfontsize
,
137
\c!rulethickness
=
\linewidth
,
138
\c!corner
=
\v!rectangular
,
139
\c!depth
=
\zeropoint
,
140
%\c!foregroundcolor=,
141
%\c!foregroundstyle=,
142
%\c!background=,
143
%\c!backgroundcolor=,
144
\c!backgroundoffset
=
\zeropoint
,
145
%\c!framecolor=,
146
\c!frameoffset
=
\zeropoint
,
147
\c!backgroundcorner
=
\framedparameter
\c!corner
,
% use \p_ here
148
\c!backgroundradius
=
\framedparameter
\c!radius
,
149
\c!backgrounddepth
=
\framedparameter
\c!depth
,
150
\c!framecorner
=
\framedparameter
\c!corner
,
151
\c!frameradius
=
\framedparameter
\c!radius
,
152
\c!framedepth
=
\framedparameter
\c!depth
,
153
%\c!component=,
154
%\c!region=,
155
%\c!align=,
156
\c!bottom
=
\vss
,
157
%\c!top=,
158
\c!strut
=
\v!yes
,
159
\c!autostrut
=
\v!yes
,
160
\c!location
=
\v!normal
,
161
%\c!orientation=,
162
\c!autowidth
=
\v!yes
,
163
%\c!setups=,
164
\c!loffset
=
\zeropoint
,
165
\c!roffset
=
\zeropoint
,
166
\c!toffset
=
\zeropoint
,
167
\c!boffset
=
\zeropoint
]
168 169
%D For backgrounds and such:
170 171
\defineframed
172
[
\??simplifiedframed
]
173
[
\c!frame
=
\v!off
,
174
\c!depth
=
\zeropoint
,
175
\c!offset
=
\v!overlay
,
176
\c!component
=
,
177
\c!region
=
,
178
\c!radius
=
.
5
\bodyfontsize
,
179
\c!rulethickness
=
\linewidth
,
180
\c!corner
=
\v!rectangular
,
181
\c!backgroundoffset
=
\zeropoint
,
182
\c!frameoffset
=
\zeropoint
,
183
\c!backgroundcorner
=
\framedparameter
\c!corner
,
% use \p_ here
184
\c!backgroundradius
=
\framedparameter
\c!radius
,
185
\c!backgrounddepth
=
\framedparameter
\c!depth
,
186
\c!framecorner
=
\framedparameter
\c!corner
,
187
\c!frameradius
=
\framedparameter
\c!radius
,
188
\c!framedepth
=
\framedparameter
\c!depth
,
189
\c!location
=
\v!normal
,
190
\c!loffset
=
\zeropoint
,
191
\c!roffset
=
\zeropoint
,
192
\c!toffset
=
\zeropoint
,
193
\c!boffset
=
\zeropoint
]
194 195
\unexpanded
\def
\definesimplifiedframed
[#
1
]
% no settings
196
{
\defineframed
[#
1
][
\??simplifiedframed
]
%
197
\expandafter\let\csname
#
1
\endcsname
\undefined
}
198 199
\expandafter\let\csname
\??simplifiedframed
\endcsname
\undefined
200 201
%D We will communicate through module specific variables, current framed
202
%D parameters and some reserved dimension registers.
203 204
\newdimen
\d_framed_target_wd
205
\newdimen
\d_framed_target_ht
206
\newdimen
\d_framed_target_dp
207
\newdimen
\d_framed_linewidth
\let
\ruledlinewidth
\d_framed_linewidth
% needed at lua end
208 209
\let
\p_framed_frame
\empty
% \framedparameter\c!frame
210
\let
\p_framed_backgroundoffset
\empty
211
\let
\p_framed_foregroundstyle
\empty
212
\let
\p_framed_autostrut
\empty
213
\let
\p_framed_location
\empty
214
\let
\p_framed_orientation
\empty
215
\let
\p_framed_autowidth
\empty
216
\let
\p_framed_franalyze
\empty
217
\let
\p_framed_backgroundcorner
\empty
218
\let
\p_framed_backgroundradius
\empty
219
\let
\p_framed_framecorner
\empty
220
\let
\p_framed_frameradius
\empty
221
\let
\p_framed_lines
\empty
222
\let
\p_framed_empty
\empty
223
\let
\p_framed_backgroundcolor
\empty
224
\let
\p_framed_framecolor
\empty
225
\let
\p_framed_component
\empty
226
\let
\p_framed_background
\empty
227
\let
\p_framed_rulethickness
\empty
228
\let
\p_framed_foregroundcolor
\empty
229
\let
\p_framed_setups
\empty
230 231
%D We don't have to stick to a \TEX\ drawn rule, but also can use rounded
232
%D or even fancier shapes, as we will see later on.
233 234
\def
\pack_framed_filled_box
235
{
\edef
\p_framed_backgroundcorner
{
\framedparameter
\c!backgroundcorner
}
%
236
\ifx
\p_framed_backgroundcorner
\v!rectangular
237
\pack_framed_filled_box_normal
238
\else
239
\pack_framed_filled_box_radius
240
\fi
}
241 242
\def
\pack_framed_filled_box_normal
243
{
\vrule
244
\s!width
\d_framed_target_wd
245
\s!height
\d_framed_target_ht
246
\s!depth
\d_framed_target_dp
247
\relax
}
248 249
\def
\pack_framed_filled_box_radius
250
{
\edef
\p_framed_backgroundradius
{
\framedparameter
\c!backgroundradius
}
%
251
\ifzeropt
\dimexpr
\p_framed_backgroundradius
\relax
% just in case of .x\bodyfontsize
252
\pack_framed_filled_box_normal
253
\else
254
\pack_framed_filled_box_round
255
\fi
}
256 257
\def
\pack_framed_filled_box_round
258
{
\raise
\d_framed_target_dp
\hpack
{
\frule
259
type
fill
260
width
\d_framed_target_wd
261
height
\d_framed_target_ht
262
depth
\d_framed_target_dp
263
line
\d_framed_linewidth
264
radius
\p_framed_backgroundradius
\space
265
corner
{
\p_framed_backgroundcorner
}
266
\relax
}}
267 268
\def
\pack_framed_stroked_box
269
{
\edef
\p_framed_framecorner
{
\framedparameter
\c!framecorner
}
%
270
\ifx
\p_framed_framecorner
\v!rectangular
271
\pack_framed_stroked_box_normal
272
\else
273
\pack_framed_stroked_box_radius
274
\fi
}
275 276
\def
\pack_framed_stroked_box_radius
277
{
\edef
\p_framed_frameradius
{
\framedparameter
\c!frameradius
}
%
278
\ifzeropt
\dimexpr
\p_framed_frameradius
\relax
% just in case of .x\bodyfontsize
279
\pack_framed_stroked_box_normal
280
\else\ifx
\p_framed_frame
\v!on
281
\pack_framed_stroked_box_round
282
\fi\fi
}
283 284
% \pack_framed_stroked_box_normal % later
285 286
\def
\pack_framed_stroked_box_round
287
{
\raise
\d_framed_target_dp
\hpack
{
\frule
288
width
\d_framed_target_wd
289
height
\d_framed_target_ht
290
depth
\d_framed_target_dp
291
line
\d_framed_linewidth
292
radius
\p_framed_frameradius
\space
293
corner
{
\p_framed_framecorner
}
294
\relax
}}
295 296
% a lot of weird corners
297
%
298
% \startTEXpage
299
% \dontleavehmode\framed
300
% [corner=0,frame=on,framecolor=green,
301
% background=color,backgroundcolor=yellow]{\tttf TEST \twodigits\recurselevel}%
302
% \vskip1em
303
% \dontleavehmode\dostepwiserecurse {1} {4}{1}{\framed
304
% [corner=\recurselevel,frame=on,framecolor=green,
305
% background=color,backgroundcolor=yellow]{\tttf TEST \twodigits\recurselevel}%
306
% \quad}
307
% \vskip1em
308
% \dontleavehmode\dostepwiserecurse {5} {8}{1}{\framed
309
% [corner=\recurselevel,frame=on,framecolor=green,
310
% background=color,backgroundcolor=yellow]{\tttf TEST \twodigits\recurselevel}%
311
% \quad}
312
% \vskip1em
313
% \dontleavehmode\dostepwiserecurse {1} {4}{1}{\framed
314
% [corner=\recurselevel,frame=on,framecolor=green]{\tttf TEST \twodigits\recurselevel}%
315
% \quad}
316
% \vskip1em
317
% \dontleavehmode\dostepwiserecurse {5} {8}{1}{\framed
318
% [corner=\recurselevel,frame=on,framecolor=green]{\tttf TEST \twodigits\recurselevel}%
319
% \quad}
320
% \vskip1em
321
% \dontleavehmode\dostepwiserecurse {9}{12}{1}{\framed
322
% [corner=\recurselevel,frame=on,framecolor=green]{\tttf TEST \twodigits\recurselevel}%
323
% \quad}
324
% \vskip1em
325
% \dontleavehmode\dostepwiserecurse{13}{16}{1}{\framed
326
% [corner=\recurselevel,frame=on,framecolor=green]{\tttf TEST \twodigits\recurselevel}%
327
% \quad}
328
% \vskip1em
329
% \dontleavehmode\dostepwiserecurse{17}{20}{1}{\framed
330
% [corner=\recurselevel,frame=on,framecolor=green]{\tttf TEST \twodigits\recurselevel}%
331
% \quad}
332
% \vskip1em
333
% \dontleavehmode\dostepwiserecurse{21}{24}{1}{\framed
334
% [corner=\recurselevel,frame=on,framecolor=green]{\tttf TEST \twodigits\recurselevel}%
335
% \quad}
336
% \vskip1em
337
% \dontleavehmode\dostepwiserecurse{25}{28}{1}{\framed
338
% [corner=\recurselevel,frame=on,framecolor=green]{\tttf TEST \twodigits\recurselevel}%
339
% \quad}
340
% \stopTEXpage
341 342
%D It won't be a surprise that we not only provide gray boxes, but also colored
343
%D ones. Here it is:
344 345
\def
\pack_framed_background_box_color
346
{
\edef
\p_framed_backgroundcolor
{
\framedparameter
\c!backgroundcolor
}
%
347
\ifx
\p_framed_backgroundcolor
\empty
\else
348
\doifcolor
\p_framed_backgroundcolor
\pack_framed_background_box_color_indeed
349
\fi
}
350 351
\def
\pack_framed_background_box_color_indeed
352
{
\hpack
{
\dousecolorparameter
\p_framed_backgroundcolor
\pack_framed_filled_box
}}
353 354
%D \macros
355
%D {defineoverlay, doifoverlayelse, overlayoffset,
356
%D overlaywidth, overlayheight, overlaydepth,
357
%D overlaycolor, overlaylinecolor, overlaylinewidth}
358
%D
359
%D Before we define the macro that actually takes card of the backgrounds, we
360
%D introduce overlays. An overlay is something that contrary to its name lays {\em
361
%D under} the text. An example of an overlay definition is:
362
%D
363
%D \startbuffer[tmp-1]
364
%D \defineoverlay
365
%D [fancy]
366
%D [{\externalfigure
367
%D [mp-cont.502]
368
%D [width=\overlaywidth,
369
%D height=\overlayheight]}]
370
%D \stopbuffer
371
%D
372
%D \typebuffer[tmp-1]
373
%D
374
%D That for instance can be uses in:
375
%D
376
%D \startbuffer[tmp-2]
377
%D \framed[backgroundachtergrond=fancy]{How Fancy!}
378
%D \framed[backgroundachtergrond=fancy,frame=off]{Even More Fancy!}
379
%D \stopbuffer
380
%D
381
%D and looks like:
382
%D
383
%D \startlinecorrection
384
%D \vbox{\baselineskip24pt\getbuffer[tmp-1]\getbuffer[tmp-2]}
385
%D \stoplinecorrection
386
%D
387
%D The formal definition is:
388
%D
389
%D \showsetup{defineoverlay}
390
%D
391
%D This macro's definition is a bit obscure, due the many non||used arguments and
392
%D the two step call that enable the setting of the width, height and depth
393
%D variables. Multiple backgrounds are possible and are specified as:
394
%D
395
%D \starttyping
396
%D \framed[background={one,two,three}]{Three backgrounds!}
397
%D \stoptyping
398
%D
399
%D Most drawing packages only know width and height. Therefore the dimensions have a
400
%D slightly different meaning here:
401
%D
402
%D \startitemize[packed]
403
%D \item \type{\overlaywidth }: width of the overlay
404
%D \item \type{\overlayheight}: height plus depth of the overlay
405
%D \item \type{\overlaydepth }: depth of the overlay
406
%D \stopitemize
407
%D
408
%D The resulting box is lowered to the right depth.
409 410
%def\overlaywidth {\the\hsize\space} % We preset the variables
411
%def\overlayheight {\the\vsize\space} % to some reasonable default
412
%def\overlaydepth {0pt } % values. The attributes
413
%let\overlayoffset \overlaydepth % of the frame can be (are)
414
%let\overlaylinewidth \overlaydepth % set somewhere else.
415
\let
\overlaycolor
\empty
416
\let
\overlaylinecolor
\empty
417 418
\def
\overlayradius
{
\framedparameter
\c!frameradius
}
419 420
\newdimen
\d_overlay_width
421
\newdimen
\d_overlay_height
422
\newdimen
\d_overlay_depth
423
\newdimen
\d_overlay_offset
424
\newdimen
\d_overlay_linewidth
425 426
\let
\m_overlay_region
\empty
427 428
% expandable ... in a future version the space will go (in my one can use Overlay*)
429 430
\def
\overlaywidth
{
\the
\d_overlay_width
\space
}
% We preset the variables
431
\def
\overlayheight
{
\the
\d_overlay_height
\space
}
% to some reasonable default
432
\def
\overlaydepth
{
\the
\d_overlay_depth
\space
}
% values.
433
\def
\overlayoffset
{
\the
\d_overlay_offset
\space
}
% of the frame can be (are)
434
\def
\overlaylinewidth
{
\the
\d_overlay_linewidth
\space
}
% set somewhere else.
435
\def
\overlayregion
{
\m_overlay_region
}
436 437
% public but kind of protected
438 439
\def
\usedoverlaywidth
{
\dimexpr
\d_overlay_width
\relax
}
440
\def
\usedoverlayheight
{
\dimexpr
\d_overlay_height
\relax
}
441
\def
\usedoverlaydepth
{
\dimexpr
\d_overlay_depth
\relax
}
442
\def
\usedoverlayoffset
{
\dimexpr
\d_overlay_offset
\relax
}
443
\def
\usedoverlaylinewidth
{
\dimexpr
\d_overlay_linewidth
\relax
}
444 445
%D The next register is used to initialize overlays.
446 447
\newtoks
\everyoverlay
448 449
%D An example of an initialization is the following (overlays can contain text
450
%D and be executed under an regime where interlineskip is off).
451 452
\installcorenamespace
{
overlay
}
453
\installcorenamespace
{
overlaybuiltin
}
454 455
\appendtoks
456
\oninterlineskip
457
\to
\everyoverlay
458 459
\prependtoks
460
\hsize
\d_overlay_width
461
\vsize
\d_overlay_height
462
\to
\everyoverlay
463 464
\unexpanded
\def
\defineoverlay
465
{
\dodoubleargument
\pack_framed_define_overlay
}
466 467
\def
\pack_framed_define_overlay
[#
1
][#
2
]
%
468
{
\def
\pack_framed_define_overlay_indeed
##
1
{
\setvalue
{
\??overlay
##
1
}{
\executedefinedoverlay
{
##
1
}{
#
2
}}}
%
469
\processcommalist
[#
1
]
\pack_framed_define_overlay_indeed
}
470 471
\unexpanded
\def
\executedefinedoverlay
#
1
#
2
% we can share the definitions
472
{
\bgroup
% redundant grouping
473
\setbox
\scratchbox
\hbox
\bgroup
474
\ifzeropt
\d_framed_target_dp
475
\the
\everyoverlay
#
2
% saves wrapping (and lua call)
476
\else
477
\lower
\d_framed_target_dp
478
\hbox
{
\the
\everyoverlay
#
2
}
%
479
\fi
480
\egroup
481
\setlayoutcomponentattribute
{
\v!overlay
:
#
1
}
%
482
\setbox
\scratchbox
\hpack
\layoutcomponentboxattribute
483
{
\kern
-
.
5
\dimexpr\wd
\scratchbox
-
\d_framed_target_wd
\relax
% was \d_overlay_width
484
\raise
-
.
5
\dimexpr\ht
\scratchbox
-
\d_framed_target_ht
\relax
% not \d_overlay_height !
485
\box
\scratchbox
}
%
486
\wd
\scratchbox
\d_framed_target_wd
487
\ht
\scratchbox
\d_framed_target_ht
488
\dp
\scratchbox
\d_framed_target_dp
489
\box
\scratchbox
490
\egroup
}
491 492
%D \macros
493
%D {overlayfakebox}
494 495
% \unexpanded\def\overlayfakebox
496
% {\hpack
497
% {\setbox\scratchbox\emptyhbox
498
% \wd\scratchbox\d_overlay_width
499
% \ht\scratchbox\d_overlay_height
500
% \box\scratchbox}}
501 502
\unexpanded
\def
\overlayfakebox
503
{
\hpack
% redundant but needs testing
504
{
\novrule
505
\s!width
\d_overlay_width
506
\s!height
\d_overlay_height
507
\s!depth
\zeropoint
}}
508 509
%D For testing we provide:
510 511
\def
\doifelseoverlay
#
1
% only tests external overlays
512
{
\ifcsname
\??overlay
#
1
\endcsname
513
\expandafter
\firstoftwoarguments
514
\else
515
\expandafter
\secondoftwoarguments
516
\fi
}
517 518
\let
\doifoverlayelse\doifelseoverlay
519 520
%D The content of the box will be (temporary) saved in a box. We also have an
521
%D extra box for backgrounds.
522 523
\newbox
\b_framed_normal
524
\newbox
\b_framed_extra
525 526
\newtoks
\everybackgroundbox
527 528
\let
\m_framed_background
\empty
% we might need a public name
529 530
\def
\pack_framed_process_background
531
{
\ifcsname
\??overlaybuiltin
\m_framed_background
\endcsname
532
\expandafter
\pack_framed_process_background_indeed_internal
\lastnamedcs
533
\else\ifcsname
\??overlay
\m_framed_background
\endcsname
534
\expandafter
\pack_framed_process_background_indeed_external
\lastnamedcs
535
\fi\fi
}
536 537
\def
\pack_framed_process_background_indeed_internal
#
1
% % : in name
538
{
\bgroup
539
\setbox
\b_framed_extra
\hpack
\bgroup
540
\ifzeropt
\framedbackgroundoffset
\else
541
\kern
-
\framedbackgroundoffset
542
\fi
543
\hbox
\bgroup
#
1
\egroup
544
\egroup
545
\wd
\b_framed_extra
\zeropoint
546
\ht
\b_framed_extra
\framedbackgroundheight
547
\dp
\b_framed_extra
\framedbackgrounddepth
548
\box
\b_framed_extra
549
\egroup
}
550 551
\def
\pack_framed_process_background_indeed_external
552
{
\pack_framed_overlay_initialize
553
\pack_framed_process_background_indeed_internal
}
554 555
\def
\pack_framed_process_backgrounds
#
1
,
#
2
% #2 gobbles spaces (we could avoid one catch if we have nextbackground)
556
{
\edef
\m_framed_background
{
#
1
}
%
557
\ifx
\m_framed_background
\s!unknown
\else
558
\pack_framed_process_background
559
\expandafter
\pack_framed_process_backgrounds
560
\fi
#
2
}
561 562
%D Beware, a backgroundbox can be empty which is another reason why we set the
563
%D width to zero instead of back-skipping.
564 565
\newdimen
\framedbackgroundwidth
566
\newdimen
\framedbackgroundheight
567
\newdimen
\framedbackgrounddepth
568
\newdimen
\framedbackgroundoffset
569 570
\def
\pack_framed_background_box_content
% fuzzy but needed hack, this \vss, otherwise
571
{
\vpack
to
\framedbackgroundheight
{
\vss\box
\b_framed_normal
\vss
}}
% vertical shift \backgroundheight
572 573
\def
\pack_framed_set_region
% experiment
574
{
\ifx
\m_overlay_region
\v!yes
575
\edef
\m_overlay_region
{
\reservedautoregiontag
}
%
576
\fi
}
577 578
\def
\pack_framed_add_region
% experiment
579
{
\anch_mark_tagged_box
\b_framed_normal
\m_overlay_region
}
580 581
\def
\pack_framed_add_background
582
{
\setbox
\b_framed_normal
\hpack
% was vbox % see also *1*
583
{
%\pack_framed_forgetall % can be relaxed
584
\boxmaxdepth
\maxdimen
585
\framedbackgroundoffset
\d_framed_backgroundoffset
586
\framedbackgroundwidth
\wd
\b_framed_normal
587
\framedbackgroundheight
\ht
\b_framed_normal
588
\framedbackgrounddepth
\dp
\b_framed_normal
589
\d_framed_target_wd
\dimexpr
\framedbackgroundwidth
+
2
\framedbackgroundoffset
\relax
590
\d_framed_target_ht
\dimexpr
\framedbackgroundheight
+
\framedbackgroundoffset
\relax
591
\d_framed_target_dp
\dimexpr
\framedbackgrounddepth
+
\framedbackgroundoffset
+
\framedparameter
\c!backgrounddepth
\relax
592
\let
\pack_framed_overlay_initialize
\pack_framed_overlay_initialize_indeed
593
\ifx
\p_framed_component
\empty
594
\resetlayoutcomponentattribute
595
\else
596
\setlayoutcomponentattribute
{
\v!background
:
\p_framed_component
}
%
597
\fi
598
\let
\foregroundbox
\pack_framed_background_box_content
599
\hpack
\layoutcomponentboxattribute
to
\framedbackgroundwidth
\bgroup
% width in case 'foreground' is used as overlay
600
\the
\everybackgroundbox
% moved
601
\expandafter
\pack_framed_process_backgrounds
\p_framed_background
,
\s!unknown
,
\relax
% hm, messy .. look into it
602
\box
\b_framed_normal
603
\hss
604
\egroup
}}
605 606
\def
\pack_framed_overlay_initialize_indeed
607
{
\d_overlay_width
\d_framed_target_wd
608
\d_overlay_height
\dimexpr
\d_framed_target_ht
+
\d_framed_target_dp
\relax
609
\d_overlay_depth
\d_framed_target_dp
610
\d_overlay_linewidth
\d_framed_linewidth
611
\d_overlay_offset
\framedbackgroundoffset
\relax
612
\edef
\overlaycolor
{
\framedparameter
\c!backgroundcolor
}
% let ?
613
\edef
\overlaylinecolor
{
\framedparameter
\c!framecolor
}
% only needed for layers
614
%\edef\overlaycorner {\framedparameter\c!backgroundcorner}%
615
%\edef\overlayradius {\framedparameter\c!backgroundradius}%
616
\let
\pack_framed_overlay_initialize
\relax
}
617 618
%D One can explictly insert the foreground box. For that purpose we introduce the
619
%D overlay \type {foreground}.
620
%D
621
%D We predefine two already familiar backgrounds:
622 623
%letvalue{\??overlaybuiltin\v!screen }\pack_framed_background_box_gray
624
\letvalue
{
\??overlaybuiltin\v!color
}
\pack_framed_background_box_color
625
\letvalue
{
\??overlaybuiltin\v!foreground
}
\pack_framed_background_box_content
% replaces: \defineoverlay[\v!foreground][\foregroundbox]
626 627
%D We can specify overlays as a comma separated list of overlays, a sometimes
628
%D handy feature.
629
%D
630
%D Besides backgrounds (overlays) we also need some macros to draw outlines (ruled
631
%D borders). Again we have to deal with square and round corners. The first category
632
%D can be handled by \TEX\ itself, the latter one depends on the driver. This macro
633
%D also support a negative offset.
634 635
\def
\pack_framed_add_outline
636
{
\setbox
\b_framed_normal
\hpack
% rules on top of box
637
{
\d_framed_target_wd
\dimexpr\wd
\b_framed_normal
+
2
\d_framed_frameoffset
\relax
638
\d_framed_target_ht
\dimexpr\ht
\b_framed_normal
+
\d_framed_frameoffset
\relax
639
\d_framed_target_dp
\dimexpr\dp
\b_framed_normal
+
\d_framed_frameoffset
+
\framedparameter
\c!framedepth
\relax
640
\ifdim
\d_framed_target_dp
<
\zeropoint
641
\advance
\d_framed_target_ht
\d_framed_target_dp
642
\scratchdimen
-
\d_framed_target_dp
643
\d_framed_target_dp
\zeropoint
644
\else
645
\scratchdimen
\zeropoint
646
\fi
647
\edef
\overlaylinecolor
{
\framedparameter
\c!framecolor
}
% twice, also in background
648
\setbox
\b_framed_extra
\hpack
649
{
\kern
-
\d_framed_frameoffset
650
\raise
\scratchdimen
651
\hpack
{
\ifx
\overlaylinecolor
\empty
\else
\dousecolorparameter
\overlaylinecolor
\fi
\pack_framed_stroked_box
}}
%
652
\wd
\b_framed_extra
\wd
\b_framed_normal
653
\ht
\b_framed_extra
\ht
\b_framed_normal
654
\dp
\b_framed_extra
\dp
\b_framed_normal
655
\wd
\b_framed_normal
\zeropoint
656
\box
\b_framed_normal
657
\box
\b_framed_extra
}}
658 659
\def
\pack_framed_stroked_box_normal_opened
660
{
\setbox
\scratchbox
\vpack
\bgroup
661
\csname
\??framedtop
\p_framed_frame
\framedparameter
\c!topframe
\endcsname
662
\nointerlineskip
% new (needed for fences)
663
\hpack
\bgroup
664
\csname
\??framedleft
\p_framed_frame
\framedparameter
\c!leftframe
\endcsname
665
\novrule
666
\s!width
\d_framed_target_wd
667
\s!height
\d_framed_target_ht
668
\s!depth
\d_framed_target_dp
669
\csname
\??framedright
\p_framed_frame
\framedparameter
\c!rightframe
\endcsname
670
\egroup
671
\nointerlineskip
% new (needed for fences)
672
\csname
\??framedbottom
\p_framed_frame
\framedparameter
\c!bottomframe
\endcsname
673
\egroup
674
\wd
\scratchbox
\d_framed_target_wd
675
\ht
\scratchbox
\d_framed_target_ht
676
\dp
\scratchbox
\d_framed_target_dp
677
\box
\scratchbox
}
678 679
\def
\pack_framed_stroked_box_normal_closed
680
{
\hpack
\bgroup
681
\scratchdimen
.
5
\d_framed_linewidth
682
\hskip
\scratchdimen
683
\clf_framedoutline
684
\dimexpr
\d_framed_target_wd
-
\d_framed_linewidth
\relax
685
\dimexpr
\d_framed_target_ht
-
\scratchdimen
\relax
686
\dimexpr
\d_framed_target_dp
-
\scratchdimen
\relax
687
\d_framed_linewidth
688
\relax
689
\egroup
}
690 691
\def
\pack_framed_stroked_box_normal
692
{
\ifx
\p_framed_frame
\v!closed
693
\pack_framed_stroked_box_normal_closed
694
\else
695
\pack_framed_stroked_box_normal_opened
696
\fi
}
697 698
\def
\pack_framed_t_rule
{
\hrule
\s!height
\d_framed_linewidth
\kern
-
\d_framed_linewidth
}
699
\def
\pack_framed_b_rule
{
\kern
-
\d_framed_linewidth
\hrule
\s!height
\d_framed_linewidth
}
700
\def
\pack_framed_r_rule
{
\kern
-
\d_framed_linewidth
\vrule
\s!width
\d_framed_linewidth
}
701
\def
\pack_framed_l_rule
{
\vrule
\s!width
\d_framed_linewidth
\kern
-
\d_framed_linewidth
}
702 703
\letvalue
{
\??framedtop
\v!on
\v!on
}
\pack_framed_t_rule
704
\letvalue
{
\??framedtop
\v!off\v!on
}
\pack_framed_t_rule
705
\letvalue
{
\??framedtop
\v!on
}
\pack_framed_t_rule
706 707
\letvalue
{
\??framedbottom\v!on
\v!on
}
\pack_framed_b_rule
708
\letvalue
{
\??framedbottom\v!off\v!on
}
\pack_framed_b_rule
709
\letvalue
{
\??framedbottom\v!on
}
\pack_framed_b_rule
710 711
\letvalue
{
\??framedleft
\v!on
\v!on
}
\pack_framed_l_rule
712
\letvalue
{
\??framedleft
\v!off\v!on
}
\pack_framed_l_rule
713
\letvalue
{
\??framedleft
\v!on
}
\pack_framed_l_rule
714 715
\letvalue
{
\??framedright
\v!on
\v!on
}
\pack_framed_r_rule
716
\letvalue
{
\??framedright
\v!off\v!on
}
\pack_framed_r_rule
717
\letvalue
{
\??framedright
\v!on
}
\pack_framed_r_rule
718 719
% no overlapping rules
720 721
\def
\pack_framed_t_rules
{
\hpack
{
\kern
\d_framed_linewidth
\vrule
\s!width
\dimexpr
\d_framed_target_wd
-
2
\d_framed_linewidth
\relax
\s!height
\d_framed_linewidth
}
\nointerlineskip
\kern
-
\d_framed_linewidth
}
722
\def
\pack_framed_b_rules
{
\kern
-
\d_framed_linewidth
\nointerlineskip
\hpack
{
\kern
\d_framed_linewidth
\vrule
\s!width
\dimexpr
\d_framed_target_wd
-
2
\d_framed_linewidth
\relax
\s!height
\d_framed_linewidth
}}
723
\def
\pack_framed_r_rules
{
\kern
-
\d_framed_linewidth
\vrule
\s!height
\dimexpr
\d_framed_target_ht
-
\d_framed_linewidth
\relax
\s!depth
-
\d_framed_linewidth
\s!width
\d_framed_linewidth
}
724
\def
\pack_framed_l_rules
{
\vrule
\s!height
\dimexpr
\d_framed_target_ht
-
\d_framed_linewidth
\relax
\s!depth
-
\d_framed_linewidth
\s!width
\d_framed_linewidth
\kern
-
\d_framed_linewidth
}
725 726
\letvalue
{
\??framedtop
\v!small\v!small
}
\pack_framed_t_rules
727
\letvalue
{
\??framedtop
\v!off
\v!small
}
\pack_framed_t_rules
728
\letvalue
{
\??framedtop
\v!small
}
\pack_framed_t_rules
729 730
\letvalue
{
\??framedbottom\v!small\v!small
}
\pack_framed_b_rules
731
\letvalue
{
\??framedbottom\v!off
\v!small
}
\pack_framed_b_rules
732
\letvalue
{
\??framedbottom\v!small
}
\pack_framed_b_rules
733 734
\letvalue
{
\??framedleft
\v!small\v!small
}
\pack_framed_l_rules
735
\letvalue
{
\??framedleft
\v!off
\v!small
}
\pack_framed_l_rules
736
\letvalue
{
\??framedleft
\v!small
}
\pack_framed_l_rules
737 738
\letvalue
{
\??framedright
\v!small\v!small
}
\pack_framed_r_rules
739
\letvalue
{
\??framedright
\v!off
\v!small
}
\pack_framed_r_rules
740
\letvalue
{
\??framedright
\v!small
}
\pack_framed_r_rules
741 742
% \framed
743
% [width=4cm,height=3cm,rulethickness=3mm,
744
% frame=off,rightframe=on,leftframe=on,topframe=on,bottomframe=on]
745
% {}
746
% \framed
747
% [width=4cm,height=3cm,rulethickness=3mm,
748
% frame=off,rightframe=small,leftframe=small,topframe=small,bottomframe=small]
749
% {}
750
% \framed
751
% [width=4cm,height=3cm,rulethickness=3mm,
752
% frame=off,rightframe=small,leftframe=small,topframe=small,bottomframe=on]
753
% {}
754 755
%D The next few macros are probably the most misused ones in \CONTEXT. They deal
756
%D with putting rules around boxes, provide backgrounds, offer alignment features,
757
%D and some more. We start with defining some booleans. These give an impression of
758
%D what we are going to take into account.
759 760
% todo : \c_framed_hasoffset
761
% faster : \let\c_framed_hasoffset\falseconditional
762 763
\newconditional
\c_framed_has_offset
764
\newconditional
\c_framed_has_width
765
\newconditional
\c_framed_has_height
766
\newconditional
\c_framed_has_format
767
\newconditional
\c_framed_is_overlaid
768
\newconditional
\c_framed_has_frame
769
\newconditional
\c_framed_has_extra_offset
770
\newconditional
\c_framed_text_location_none
771 772
\newconstant
\c_framed_has_strut
% 0=relaxes 1=pseudostruts 2=realstruts
773 774
%D \macros
775
%D {framed, setupframed}
776
%D
777
%D Ruled boxes are typeset using \type{\framed}. This command is quite versatile
778
%D and, although some users will probably seldom use it, one cannot overlook its
779
%D features.
780
%D
781
%D \showsetup{setupframed}
782
%D \showsetup{framed}
783
%D
784
%D This general macro is a special version of an even more general case, that can
785
%D easily be linked into other macros that need some kind of framing. The local
786
%D version is called with an extra parameter: the variable identifier. The reason
787
%D for passing this identifier between brackets lays in the mere fact that this way
788
%D we can use the optional argument grabbers.
789 790
\def
\defaultframeoffset
{
.
2
5
\exheight
}
791 792
\installcorenamespace
{
regularframedlevel
}
793 794
\unexpanded
\def
\installregularframed
#
1
%
795
{
\defineframed
[#
1
]
}
796 797
\unexpanded
\def
\presetlocalframed
[#
1
]
%
798
{
\defineframed
[#
1
]
}
799 800
% \presetlocalframed[\??framed]
801 802
\newcount
\c_pack_framed_nesting
803 804
\unexpanded
\def
\pack_framed_process_framed
[#
1
]
%
805
{
\bgroup
806
\iffirstargument
% faster
807
\setupcurrentframed
[#
1
]
% here !
808
\fi
809
\pack_framed_process_indeed
}
810 811
\unexpanded
\def
\framed
812
{
\bgroup
813
\advance
\c_pack_framed_nesting
\plusone
814
\expandafter\let\csname
\??framed
>
\the
\c_pack_framed_nesting
:
\s!parent
\endcsname
\??framed
815
\edef
\currentframed
{
>
\the
\c_pack_framed_nesting
}
%
816
\pack_framed_initialize
817
\dosingleempty
\pack_framed_process_framed
}
818 819
\unexpanded
\def
\startframed
820
{
\dosingleempty
\pack_framed_start_framed
}
821 822
\def
\pack_framed_start_framed
[#
1
]
%
823
{
\bgroup
824
\doifelseassignment
{
#
1
}
\pack_framed_start_framed_yes
\pack_framed_start_framed_nop
{
#
1
}}
825 826
\def
\pack_framed_start_framed_yes
#
1
%
827
{
\advance
\c_pack_framed_nesting
\plusone
828
\expandafter\let\csname
\??framed
>
\the
\c_pack_framed_nesting
:
\s!parent
\endcsname
\??framed
829
\iffirstargument
\secondargumenttrue
\fi
% dirty trick
830
\edef
\currentframed
{
>
\the
\c_pack_framed_nesting
}
%
831
\pack_framed_initialize
832
\bgroup
833
\iffirstargument
834
\secondargumenttrue
% dirty trick
835
\setupcurrentframed
[#
1
]
% here !
836
\fi
837
\pack_framed_process_indeed
838
\bgroup
839
\ignorespaces
}
840 841
\def
\pack_framed_start_framed_nop
#
1
%
842
{
\edef
\currentframed
{
#
1
}
%
843
\dosingleempty
\pack_framed_start_framed_nop_indeed
}
844 845
\def
\pack_framed_start_framed_nop_indeed
[#
1
]
%
846
{
\pack_framed_initialize
847
\bgroup
848
\iffirstargument
849
\setupcurrentframed
[#
1
]
% here !
850
\fi
851
\pack_framed_process_indeed
852
\bgroup
853
\ignorespaces
}
854 855
% till here
856 857
\unexpanded
\def
\stopframed
858
{
\removeunwantedspaces
859
\egroup
}
860 861
\unexpanded
\def
\normalframedwithsettings
[#
1
]
%
862
{
\bgroup
863
\advance
\c_pack_framed_nesting
\plusone
864
\expandafter\let\csname
\??framed
>
\the
\c_pack_framed_nesting
:
\s!parent
\endcsname
\??framed
865
\bgroup
866
\edef
\currentframed
{
>
\the
\c_pack_framed_nesting
}
%
867
\pack_framed_initialize
868
\setupcurrentframed
[#
1
]
%
869
\pack_framed_process_indeed
}
870 871
%D \startbuffer
872
%D \setupframed [framecolor=yellow] \framed{A}
873
%D \defineframed[myframed] [framecolor=blue] \myframed{B}
874
%D \setupframed [myframed] [framecolor=red] \myframed{C}
875
%D \stopbuffer
876
%D
877
%D \typebuffer \getbuffer
878
%D
879
%D \startbuffer
880
%D \presetlocalframed[myframed]
881
%D \localframed[myframed][framecolor=green]{oeps}
882
%D \stopbuffer
883
%D
884
%D \typebuffer \getbuffer
885 886
%D \macros
887
%D {ifinframed}
888
%D
889
%D The normal case first presets all parameters and next starts looking for the user
890
%D supplied ones. The first step is omitted in the local case, because these are
891
%D preset at declaration time and keep their values unless explictly changed. By
892
%D presetting the variables everytime the normal command is called, we can use this
893
%D command nested, without the unwanted side effect of inheritance. The boolean is
894
%D used to speed up the color stack.
895 896
\newif
\ifinframed
897 898
%D The next one is faster on multiple backgrounds per page. No
899
%D dimensions can be set, only frames and backgrounds.
900 901
\unexpanded
\def
\fastlocalframed
[#
1
]#
2
[#
3
]#
4
% 3-4
902
{
\bgroup
903
\edef
\currentframed
{
#
1
}
%
904
\pack_framed_initialize
905
\setbox
\b_framed_normal
\hbox
{
#
4
}
%
906
\iftrialtypesetting
\else
907
\edef
\m_overlay_region
{
\framedparameter
\c!region
}
%
908
\ifx
\m_overlay_region
\empty
\else
909
\pack_framed_set_region
910
\fi
911
\fi
912
\setupcurrentframed
[#
3
]
%
913
\edef
\p_framed_rulethickness
{
\framedparameter
\c!rulethickness
}
% also used in backgrounds
914
\d_framed_frameoffset
\framedparameter
\c!frameoffset
\relax
% also used in backgrounds
915
\edef
\p_framed_frame
{
\framedparameter
\c!frame
}
%
916
\edef
\p_framed_background
{
\framedparameter
\c!background
}
%
917
% not here, in calling macro: setups
918
\pack_framed_remove_depth
919
\ifx
\p_framed_frame
\v!overlay
\else
\ifx
\p_framed_frame
\v!none
\else
920
\ifx
\p_framed_rulethickness
\empty
\else
921
\d_framed_linewidth
\p_framed_rulethickness
\relax
922
\fi
923
\pack_framed_add_outline
% real or invisible frame
924
\fi\fi
925
\ifx
\p_framed_background
\empty
\else
926
\edef
\p_framed_backgroundoffset
{
\framedparameter
\c!backgroundoffset
}
%
927
\d_framed_backgroundoffset
928
\ifx
\p_framed_backgroundoffset
\v!frame
929
\d_framed_frameoffset
930
\else
931
\p_framed_backgroundoffset
932
\fi
933
\edef
\p_framed_component
{
\framedparameter
\c!component
}
%
934
\pack_framed_add_background
935
\fi
936
\pack_framed_restore_depth
937
\iftrialtypesetting
\else
938
\ifx
\m_overlay_region
\empty
\else
939
\pack_framed_add_region
940
\fi
941
\fi
942
\box
\b_framed_normal
943
\egroup
}
944 945
%D The next macro uses a box and takes its natural width and height so these
946
%D can better be correct.
947 948
\unexpanded
\def
\pack_framed_process_box_indeed
#
1
#
2
% component box (assumes parameters set and grouped usage)
949
{
\setbox
\b_framed_normal
\box
#
2
% could actually be \let\b_framed_normal#2
950
\edef
\m_overlay_region
{
\framedparameter
\c!region
}
%
951
\ifx
\m_overlay_region
\empty
\else
952
\pack_framed_set_region
953
\fi
954
\edef
\p_framed_rulethickness
{
\framedparameter
\c!rulethickness
}
% also used in backgrounds
955
\d_framed_frameoffset
\framedparameter
\c!frameoffset
\relax
% also used in backgrounds
956
\edef
\p_framed_frame
{
\framedparameter
\c!frame
}
%
957
\edef
\p_framed_background
{
\framedparameter
\c!background
}
%
958
\ifx
\p_framed_frame
\v!overlay
\else
\ifx
\p_framed_frame
\v!none
\else
959
\ifx
\p_framed_rulethickness
\empty
\else
960
\d_framed_linewidth
\p_framed_rulethickness
\relax
961
\fi
962
\pack_framed_add_outline
% real or invisible frame
963
\fi\fi
964
\ifx
\p_framed_background
\empty
\else
965
\edef
\p_framed_backgroundoffset
{
\framedparameter
\c!backgroundoffset
}
%
966
\d_framed_backgroundoffset
967
\ifx
\p_framed_backgroundoffset
\v!frame
968
\d_framed_frameoffset
969
\else
970
\p_framed_backgroundoffset
971
\fi
972
\edef
\p_framed_component
{
#
1
}
%
973
\pack_framed_add_background
974
\fi
975
\ifx
\m_overlay_region
\empty
\else
976
\pack_framed_add_region
977
\fi
978
\box
\b_framed_normal
979
\egroup
}
980 981
\unexpanded
\def
\localbackgroundframed
#
1
% namespace component box
982
{
\bgroup
983
\edef
\currentframed
{
#
1
}
%
984
\pack_framed_initialize
985
\pack_framed_process_box_indeed
}
% group ends here
986 987
\let
\postprocessframebox
\relax
988 989
%D A nice example by Aditya:
990
%D
991
%D \starttyping
992
%D \setupframed
993
%D [loffset=\framedparameter{hoffset},
994
%D roffset=\framedparameter{hoffset},
995
%D hoffset=\zeropoint]
996
%D
997
%D \defineframed[test][hoffset=1cm]
998
%D \stoptyping
999 1000
\newdimen
\d_framed_width
1001
\newdimen
\d_framed_height
1002
\newdimen
\d_framed_frameoffset
1003
\newdimen
\d_framed_backgroundoffset
1004
\newdimen
\d_framed_local_offset
1005 1006
% todo: protect local \framednames
1007 1008
\unexpanded
\def
\localframed
1009
{
\bgroup
1010
\dodoubleempty
\pack_framed_local
}
1011 1012
\unexpanded
\def
\pack_framed_local
[#
1
][#
2
]
%
1013
{
\bgroup
1014
\edef
\currentframed
{
#
1
}
%
1015
\pack_framed_initialize
1016
\ifsecondargument
% faster
1017
\setupcurrentframed
[#
2
]
% here !
1018
\fi
1019
\pack_framed_process_indeed
}
1020 1021
\unexpanded
\def
\directlocalframed
[#
1
]
% no optional
1022
{
\bgroup
1023
\bgroup
1024
\edef
\currentframed
{
#
1
}
%
1025
\pack_framed_initialize
1026
\pack_framed_process_indeed
}
1027 1028
\unexpanded
\def
\localframedwithsettings
[#
1
][#
2
]
% no checking (so no spaces between)
1029
{
\bgroup
1030
\bgroup
1031
\edef
\currentframed
{
#
1
}
%
1032
\pack_framed_initialize
1033
\setupcurrentframed
[#
2
]
% here !
1034
\pack_framed_process_indeed
}
1035 1036
% done
1037 1038
\def
\c!fr!analyze
{
fr
:
analyze
}
% private option
1039 1040
\let
\delayedbegstrut
\relax
1041
\let
\delayedendstrut
\relax
1042
\let
\delayedstrut
\relax
1043 1044
\let
\localoffset
\empty
1045
\let
\localwidth
\empty
1046
\let
\localheight
\empty
1047
\let
\localformat
\empty
1048
\let
\localstrut
\empty
1049 1050
\unexpanded
\def
\pack_framed_process_indeed
1051
{
\d_framed_frameoffset
\framedparameter
\c!frameoffset
1052
\edef
\p_framed_backgroundoffset
{
\framedparameter
\c!backgroundoffset
}
%
1053
\d_framed_backgroundoffset
1054
\ifx
\p_framed_backgroundoffset
\v!frame
1055
\d_framed_frameoffset
1056
\else
1057
\p_framed_backgroundoffset
1058
\fi
1059
% new, experimental dirty hook
1060
\framedparameter
\c!extras
1061
% to get the right spacing
1062
\edef
\p_framed_foregroundstyle
{
\framedparameter
\c!foregroundstyle
}
%
1063
\ifx
\p_framed_foregroundstyle
\empty
\else
\dousestyleparameter
\p_framed_foregroundstyle
\fi
1064
% beware, both the frame and background offset can be overruled
1065
%
1066
\edef
\p_framed_setups
{
\framedparameter
\c!setups
}
%
1067
% the next macros are visible
1068
\edef
\localoffset
{
\framedparameter
\c!offset
}
%
1069
\edef
\localwidth
{
\framedparameter
\c!width
}
%
1070
\edef
\localheight
{
\framedparameter
\c!height
}
%
1071
\edef
\localformat
{
\framedparameter
\c!align
}
%
1072
\edef
\localstrut
{
\framedparameter
\c!strut
}
%
1073
% these are not
1074
\edef
\p_framed_autostrut
{
\framedparameter
\c!autostrut
}
%
1075
\edef
\p_framed_frame
{
\framedparameter
\c!frame
}
%
1076
\edef
\p_framed_location
{
\framedparameter
\c!location
}
%
1077
\edef
\p_framed_orientation
{
\framedparameter
\c!orientation
}
%
1078
%
1079
\edef
\p_framed_autowidth
{
\framedparameter
\c!autowidth
}
%
1080
\edef
\p_framed_franalyze
{
\framedparameter
\c!fr!analyze
}
% experimental option
1081
%
1082
\ifx
\p_framed_frame
\v!overlay
% no frame, no offset, no framewidth
1083
\setfalse
\c_framed_has_frame
1084
\let
\localoffset
\v!overlay
1085
\else\ifx
\p_framed_frame
\v!none
% no frame, no framewidth
1086
\setfalse
\c_framed_has_frame
1087
\else
1088
\settrue
\c_framed_has_frame
1089
\fi\fi
1090
\ifconditional
\c_framed_has_frame
1091
\edef
\p_framed_rulethickness
{
\framedparameter
\c!rulethickness
}
%
1092
\ifx
\p_framed_rulethickness
\empty
\else
1093
\d_framed_linewidth
\p_framed_rulethickness
\relax
1094
\fi
1095
\else
1096
\d_framed_linewidth
\zeropoint
1097
\fi
1098
% 2013/03/12: a change of order (sizes before align
1099
\ifx
\localwidth
\v!local
1100
\setlocalhsize
1101
\fi
1102
%
1103
\forgetall
% should happen after \localwidth but before align
1104
%
1105
\ifx
\localformat
\empty
1106
\setfalse
\c_framed_has_format
1107
\else
1108
\settrue
\c_framed_has_format
1109
\dosetraggedcommand
\localformat
% not that fast
1110
\fi
1111
%
1112
\ifcsname
\??framedoffsetalternative
\localoffset
\endcsname
1113
\lastnamedcs
1114
\else
1115
\framed_offset_alternative_unknown
1116
\fi
1117
\ifcsname
\??framedwidthalternative
\localwidth
\endcsname
1118
\lastnamedcs
1119
\else
1120
\framed_width_alternative_unknown
1121
\fi
1122
\ifcsname
\??framedheightalternative
\localheight
\endcsname
1123
\lastnamedcs
1124
\else
1125
\framed_height_alternative_unknown
1126
\fi
1127
% the next check could move to heightalternative
1128
\ifconditional
\c_framed_has_height
1129
% obey user set height, also downward compatible
1130
\else
1131
\edef
\p_framed_lines
{
\framedparameter
\c!lines
}
%
1132
\ifx
\p_framed_lines
\empty
\else
1133
\ifcase
\p_framed_lines
\else
1134
\d_framed_height
\p_framed_lines
\lineheight
1135
\edef
\localheight
{
\the
\d_framed_height
}
%
1136
\settrue
\c_framed_has_height
1137
\fi
1138
\fi
1139
\fi
1140
% this is now an option: width=local
1141
%
1142
% \ifdim\d_framed_width=\hsize
1143
% \parindent\zeropoint
1144
% \setlocalhsize
1145
% \d_framed_width\localhsize
1146
% \fi
1147
% i.e. disable (colsetbackgroundproblemintechniek)
1148
\advance
\d_framed_width
-
2
\d_framed_local_offset
1149
\advance
\d_framed_height
-
2
\d_framed_local_offset
1150
\ifcsname
\??framedstrutalternative
\localstrut
\endcsname
1151
\lastnamedcs
1152
\else
1153
\framed_offset_alternative_unknown
1154
\fi
1155
% the next check could move to strutalternative
1156
\ifcase
\c_framed_has_strut
% none (not even noindent)
1157
\let
\localbegstrut
\relax
1158
\let
\localendstrut
\relax
1159
\let
\localstrut
\relax
1160
\or
% no / overlay
1161
\let
\localbegstrut
\pseudobegstrut
1162
\let
\localendstrut
\pseudoendstrut
1163
\let
\localstrut
\pseudostrut
1164
\else
1165
\let
\localbegstrut
\begstrut
1166
\let
\localendstrut
\endstrut
1167
\let
\localstrut
\strut
1168
\fi
1169
\ifx
\p_framed_autostrut
\v!yes
1170
\let
\delayedbegstrut
\relax
1171
\let
\delayedendstrut
\relax
1172
\let
\delayedstrut
\relax
1173
\else
1174
\let
\delayedbegstrut
\localbegstrut
1175
\let
\delayedendstrut
\localendstrut
1176
\let
\delayedstrut
\localstrut
1177
\let
\localbegstrut
\relax
1178
\let
\localendstrut
\relax
1179
\let
\localstrut
\relax
1180
\fi
1181
\ifconditional
\c_framed_has_height
1182
\let
\\
\pack_framed_vboxed_newline
1183
\ifconditional
\c_framed_has_width
1184
\let
\hairline
\pack_framed_vboxed_hairline
1185
\ifconditional
\c_framed_has_format
1186
\let
\next
\pack_framed_format_format_yes
1187
\else
1188
\let
\next
\pack_framed_format_format_nop
1189
\fi
1190
\else
1191
\let
\hairline
\pack_framed_hboxed_hairline
1192
\ifconditional
\c_framed_has_format
1193
\let
\next
\pack_framed_format_format_height
1194
\else
1195
\let
\next
\pack_framed_format_format_vsize
1196
\fi
1197
\fi
1198
\else
1199
\ifconditional
\c_framed_has_width
1200
\ifconditional
\c_framed_has_format
1201
\let
\hairline
\pack_framed_vboxed_hairline
1202
\let
\\
\pack_framed_vboxed_newline
1203
\let
\next
\pack_framed_format_format_width
1204
\else
1205
\let
\hairline
\pack_framed_hboxed_hairline
1206
\let
\\
\pack_framed_hboxed_newline
1207
\let
\next
\pack_framed_format_format_hsize
1208
\fi
1209
\else
1210
\let
\hairline
\pack_framed_hboxed_hairline
1211
\let
\\
\pack_framed_hboxed_newline
1212
\let
\next
\pack_framed_format_format_no_size
1213
\fi
1214
\fi
1215
\pack_framed_check_extra_offsets
1216
\edef
\p_framed_background
{
\framedparameter
\c!background
}
%
1217
% \ifx\p_framed_background\empty
1218
% \let\pack_framed_forgetall\forgetall
1219
% \else
1220
% \let\pack_framed_forgetall\relax
1221
% \forgetall
1222
% \fi
1223
\edef
\framedwidth
{
\the\ifdim
\d_framed_width
>
\zeropoint
\d_framed_width
\else
\zeropoint
\fi
}
% public
1224
\edef
\framedheight
{
\the\ifdim
\d_framed_height
>
\zeropoint
\d_framed_height
\else
\zeropoint
\fi
}
% public
1225
\edef
\framedoffset
{
\the\dimexpr
\ifconditional
\c_framed_has_offset
\localoffset
\else
\zeropoint
\fi
}
% public
1226
\ifx
\p_framed_orientation
\empty
1227
\let
\pack_framed_stop_orientation
\relax
1228
\else
1229
\pack_framed_start_orientation
1230
\fi
1231
\afterassignment
\pack_framed_restart
1232
\setbox
\b_framed_normal
\next
}
1233 1234
% alternatives for width, height, strut and offset
1235 1236
\installcorenamespace
{
framedwidthalternative
}
1237
\installcorenamespace
{
framedheightalternative
}
1238
\installcorenamespace
{
framedstrutalternative
}
1239
\installcorenamespace
{
framedoffsetalternative
}
1240 1241
% widths
1242 1243
\setvalue
{
\??framedwidthalternative
\empty
}
%
1244
{
\ifconditional
\c_framed_has_format
1245
\settrue
\c_framed_has_width
1246
\d_framed_width
\hsize
1247
\else
1248
\setfalse
\c_framed_has_width
1249
\d_framed_width
\zeropoint
1250
\fi
}
1251 1252
\setvalue
{
\??framedwidthalternative\v!fit
}
%
1253
{
\ifconditional
\c_framed_has_format
1254
\settrue
\c_framed_has_width
1255
\d_framed_width
\hsize
1256
\else
1257
\setfalse
\c_framed_has_width
1258
\d_framed_width
\zeropoint
1259
\fi
}
1260 1261
\setvalue
{
\??framedwidthalternative\v!fixed
}
% equals \v!fit but no shapebox
1262
{
\ifconditional
\c_framed_has_format
1263
\settrue
\c_framed_has_width
1264
\d_framed_width
\hsize
1265
\else
1266
\setfalse
\c_framed_has_width
1267
\d_framed_width
\zeropoint
1268
\fi
}
1269 1270
\setvalue
{
\??framedwidthalternative\v!broad
}
%
1271
{
\settrue
\c_framed_has_width
1272
\d_framed_width
\hsize
}
1273 1274
\setvalue
{
\??framedwidthalternative\v!max
}
% idem broad
1275
{
\settrue
\c_framed_has_width
1276
\d_framed_width
\hsize
}
1277 1278
\setvalue
{
\??framedwidthalternative\v!local
}
%
1279
{
\settrue
\c_framed_has_width
1280
%\setlocalhsize
1281
\d_framed_width
\localhsize
}
1282 1283
\setvalue
{
\??framedwidthalternative\s!unknown
}
%
1284
{
\settrue
\c_framed_has_width
1285
\d_framed_width
\localwidth
}
1286 1287
\def
\framed_width_alternative_unknown
1288
{
\settrue
\c_framed_has_width
1289
\d_framed_width
\localwidth
}
1290 1291
% heights
1292 1293
\setvalue
{
\??framedheightalternative
\empty
}
%
1294
{
\setfalse
\c_framed_has_height
1295
\d_framed_height
\zeropoint
}
1296 1297
\setvalue
{
\??framedheightalternative\v!fit
}
%
1298
{
\setfalse
\c_framed_has_height
1299
\d_framed_height
\zeropoint
}
1300 1301
\setvalue
{
\??framedheightalternative\v!broad
}
%
1302
{
\setfalse
\c_framed_has_height
1303
\d_framed_height
\zeropoint
}
1304 1305
\setvalue
{
\??framedheightalternative\v!max
}
%
1306
{
\settrue
\c_framed_has_height
1307
\d_framed_height
\vsize
}
1308 1309
\setvalue
{
\??framedheightalternative\s!unknown
}
%
1310
{
\settrue
\c_framed_has_height
1311
\d_framed_height
\localheight
}
1312 1313
\def
\framed_height_alternative_unknown
1314
{
\settrue
\c_framed_has_height
1315
\d_framed_height
\localheight
}
1316 1317
% struts (use let instead?)
1318 1319
\setvalue
{
\??framedstrutalternative\v!no
}
%
1320
{
\c_framed_has_strut
\plusone
}
1321 1322
\setvalue
{
\??framedstrutalternative\v!global
}
%
1323
{
\setstrut
}
1324 1325
\setvalue
{
\??framedstrutalternative\v!local
}
%
1326
{
\setfontstrut
}
1327 1328
\setvalue
{
\??framedstrutalternative\v!yes
}
%
1329
{
\setstrut
}
1330 1331
\setvalue
{
\??framedstrutalternative\s!unknown
}
%
1332
{
\setstrut
}
1333 1334
\def
\framed_strut_alternative_unknown
1335
{
\setstrut
}
1336 1337
\setvalue
{
\??framedstrutalternative\v!none
}
% not even pseudo struts
1338
{
\c_framed_has_strut
\zerocount
}
1339 1340
% offsets
1341 1342
\setvalue
{
\??framedoffsetalternative\v!none
}
%
1343
{
\setfalse
\c_framed_has_offset
1344
\c_framed_has_strut
\plusone
1345
\setfalse
\c_framed_is_overlaid
1346
\d_framed_local_offset
\d_framed_linewidth
}
1347 1348
\setvalue
{
\??framedoffsetalternative\v!overlay
}
%
1349
{
% \ifx\p_framed_frame\v!no \setfalse\c_framed_has_frame \fi % test first
1350
\setfalse
\c_framed_has_offset
1351
\c_framed_has_strut
\plusone
1352
\settrue
\c_framed_is_overlaid
1353
\d_framed_local_offset
\zeropoint
}
1354 1355
% \setvalue{\??framedoffsetalternative\v!strut}%
1356
% {\setfalse\c_framed_has_offset
1357
% \c_framed_has_strut\plustwo
1358
% \settrue\c_framed_is_overlaid
1359
% \d_framed_local_offset\zeropoint}
1360 1361
\setvalue
{
\??framedoffsetalternative\v!default
}
% new per 2-6-2000
1362
{
\settrue
\c_framed_has_offset
1363
\c_framed_has_strut
\plustwo
1364
\setfalse
\c_framed_is_overlaid
1365
\let
\localoffset
\defaultframeoffset
1366
\letframedparameter
\c!offset
\defaultframeoffset
% brrr
1367
\d_framed_local_offset
\dimexpr
\localoffset
+
\d_framed_linewidth
\relax
}
1368 1369
\def
\framed_offset_alternative_unknown
1370
{
\settrue
\c_framed_has_offset
1371
\c_framed_has_strut
\plustwo
1372
\setfalse
\c_framed_is_overlaid
1373
\let
\defaultframeoffset
\localoffset
1374
\d_framed_local_offset
\dimexpr
\localoffset
+
\d_framed_linewidth
\relax
}
1375 1376
\letvalue
{
\??framedoffsetalternative\s!unknown
}
\framed_offset_alternative_unknown
1377 1378
% so far for alternatives
1379 1380
\let
\pack_framed_stop_orientation
\relax
1381 1382
\def
\pack_framed_restart
1383
{
\aftergroup
\pack_framed_finish
}
1384 1385
\def
\pack_framed_do_top
1386
{
\raggedtopcommand
1387
\framedparameter
\c!top
1388
\edef
\p_blank
{
\framedparameter
\c!blank
}
%
1389
\ifx
\p_blank
\v!yes
\else
% auto or no
1390
\doinhibitblank
1391
\fi
}
1392 1393
\def
\pack_framed_do_bottom
1394
{
\framedparameter
\c!bottom
1395
\raggedbottomcommand
}
1396 1397
%D Careful analysis of this macro will learn us that not all branches in the last
1398
%D conditionals can be encountered, that is, some assignments to \type{\next} will
1399
%D never occur. Nevertheless we implement the whole scheme, if not for future
1400
%D extensions.
1401 1402
%D \macros
1403
%D {doassigncheckedframeoffset}
1404
%D
1405
%D Offset helper (see menus):
1406 1407
\def
\doassigncheckedframeoffset
#
1
#
2
% could be a fast \csname .. \endcsname
1408
{
\edef
\checkedframeoffset
{
#
2
}
%
1409
#
1
%
1410
\ifx
\checkedframeoffset
\empty
\zeropoint
\else
1411
\ifx
\checkedframeoffset
\v!overlay
\zeropoint
\else
1412
\ifx
\checkedframeoffset
\v!none
\zeropoint
\else
1413
\ifx
\checkedframeoffset
\v!frame
\zeropoint
\else
1414
\ifx
\checkedframeoffset
\v!default
\zeropoint
\else
1415
#
2
%
1416
\fi\fi\fi\fi\fi
1417
\relax
}
1418 1419
%D \macros
1420
%D {ifreshapeframebox}
1421
%D
1422
%D The last few lines tell what to do after the content of the box is collected and
1423
%D passed to the next macro. In the case of a fixed width and centered alignment,
1424
%D the content is evaluated and used to determine the most natural width. The rest
1425
%D of the code deals with backgrounds and frames.
1426 1427
\newif
\ifreshapeframebox
\reshapeframeboxtrue
1428 1429
%D Beware: setting \type {top} and \type {bottom} to nothing, may
1430
%D result in a frame that is larger that the given height! try:
1431
%D
1432
%D \starttyping
1433
%D \framed
1434
%D [height=3cm,top=,bottom=,offset=overlay]
1435
%D {\strut test \shapefill \strut test}
1436
%D \stoptyping
1437
%D
1438
%D This is intended behaviour and not a bug! One can always set
1439
%D
1440
%D \starttyping
1441
%D ...,bottom=\kern0pt,...
1442
%D \stoptyping
1443 1444
% experiment ... \p_framed_franalyze -> we could support 'first' as location key
1445
% option but then we will always do an analysis and reimplement the location
1446
% options (btw, beware of location settings of derived functionality that bleed
1447
% into this
1448 1449
\def
\pack_framed_finish_a
1450
{
\ifreshapeframebox
1451
\pack_framed_reshape_process
1452
\else\ifx
\p_framed_franalyze
\v!yes
1453
\pack_framed_reshape_analyze
1454
\else
1455
\pack_framed_reshape_reset
1456
\fi\fi
1457
\setfalse
\c_framed_has_width
}
1458 1459
\def
\pack_framed_finish_b
1460
{
\ifx
\p_framed_franalyze
\v!yes
1461
\pack_framed_reshape_analyze
1462
\else
1463
\pack_framed_reshape_reset
1464
\fi
1465
\setfalse
\c_framed_has_width
}
1466 1467
\def
\pack_framed_finish_c
1468
{
\ifx
\p_framed_franalyze
\v!yes
1469
\pack_framed_reshape_analyze
1470
\else
1471
\pack_framed_reshape_reset
1472
\fi
}
1473 1474
\def
\pack_framed_profile_box
1475
{
\profilegivenbox
\p_profile
\b_framed_normal
1476
\setbox
\b_framed_normal
\vpack
{
\unvbox
\b_framed_normal
}}
1477 1478
\unexpanded
\def
\pack_framed_finish
1479
{
%\pack_framed_stop_orientation % hm, wrong place ! should rotate the result (after reshape) .. moved down
1480
\pack_framed_locator_before
\p_framed_location
1481
\ifconditional
\c_framed_has_format
1482
%\ifconditional\c_framed_has_height \else
1483
% \edef\p_profile{\framedparameter\c!profile}%
1484
% \ifx\p_profile\empty\else
1485
% \pack_framed_profile_box
1486
% \fi
1487
%\fi
1488
\ifx
\p_framed_autowidth
\v!force
1489
\pack_framed_finish_a
1490
\else\ifx
\localwidth
\v!fit
1491
\ifx
\p_framed_autowidth
\v!yes
1492
\pack_framed_finish_a
1493
\else
1494
\pack_framed_finish_b
1495
\fi
1496
\else\ifx
\localwidth
\v!fixed
1497
\pack_framed_finish_b
1498
\else
1499
\pack_framed_finish_c
1500
\fi\fi\fi
1501
\ifconditional
\c_framed_has_height
\else
1502
\edef
\p_profile
{
\framedparameter
\c!profile
}
%
1503
\ifx
\p_profile
\empty
\else
1504
\pack_framed_profile_box
1505
\fi
1506
\fi
1507
\ifconditional
\page_postprocessors_needed_box
1508
% quite late
1509
\page_postprocessors_linenumbers_box
\b_framed_normal
1510
\fi
1511
\else
1512
\pack_framed_finish_c
1513
\fi
1514
\ifconditional
\c_framed_has_width
1515
\wd
\b_framed_normal
\d_framed_width
1516
\fi
1517
\ifconditional
\c_framed_has_height
1518
\ht
\b_framed_normal
\d_framed_height
1519
\else
1520
\edef
\p_framed_minheight
{
\framedparameter
\c!minheight
}
%
1521
\ifx
\p_framed_minheight
\empty
\else
1522
\ifdim
\ht
\b_framed_normal
<
\p_framed_minheight
1523
\ht
\b_framed_normal
\p_framed_minheight
1524
\fi
1525
\fi
1526
\fi
1527
\edef
\p_framed_empty
{
\framedparameter
\c!empty
}
%
1528
\ifx
\p_framed_empty
\v!yes
1529
\pack_framed_fake_box
1530
\fi
1531
\pack_framed_stop_orientation
% moved here at 2014-05-25
1532
\iftrialtypesetting
\else
1533
\edef
\m_overlay_region
{
\framedparameter
\c!region
}
%
1534
\ifx
\m_overlay_region
\empty
\else
1535
\pack_framed_set_region
1536
\fi
1537
\fi
1538
\d_framed_applied_offset
1539
\ifconditional
\c_framed_is_overlaid
1540
\zeropoint
1541
\else
1542
\d_framed_linewidth
1543
\fi
1544
\ifconditional
\c_framed_has_offset
1545
\advance
\d_framed_applied_offset
\localoffset
\relax
1546
\fi
1547
\ifconditional
\c_framed_has_extra_offset
1548
\pack_framed_apply_extra_offsets
% includes \d_framed_applied_offset
1549
\else
1550
\ifzeropt
\d_framed_applied_offset
1551
\else
1552
\pack_framed_widen_box
1553
\fi
1554
\fi
1555
%
1556
\ifx
\postprocessframebox
\relax
\else
1557
\let
\next
\postprocessframebox
1558
\let
\postprocessframebox
\relax
% prevent nesting
1559
\next
\b_framed_normal
1560
\fi
1561
\iftrialtypesetting
1562
% new
1563
\else
1564
\ifconditional
\c_framed_has_frame
% real or invisible frame
1565
\pack_framed_add_outline
1566
\fi
1567
\ifx
\p_framed_background
\empty
\else
1568
\edef
\p_framed_component
{
\framedparameter
\c!component
}
%
1569
\pack_framed_add_background
1570
\fi
1571
\fi
1572
\pack_framed_locator_after
\p_framed_location
1573
\iftrialtypesetting
\else
1574
\ifx
\m_overlay_region
\empty
\else
1575
\pack_framed_add_region
1576
\fi
1577
\fi
1578
\box
\b_framed_normal
1579
\global
\frameddimensionstate
% global so to be used directly afterwards !
1580
\ifconditional
\c_framed_has_width
1581
\ifconditional
\c_framed_has_height
\plusthree
\else
\plusone
\fi
1582
\else
1583
\ifconditional
\c_framed_has_height
\plustwo
\else
\zerocount
\fi
1584
\fi
1585
\egroup
1586
\egroup
}
1587 1588
\installcorenamespace
{
framedlocatorbefore
}
1589
\installcorenamespace
{
framedlocatorafter
}
1590 1591
\newconstant
\frameddimensionstate
% global state: 0=unknown 1=width 2=height 3=both
1592 1593
\def
\pack_framed_fake_box
1594
{
\setbox
\scratchbox
\emptyhbox
1595
\wd
\scratchbox
\wd
\b_framed_normal
1596
\ht
\scratchbox
\ht
\b_framed_normal
1597
\dp
\scratchbox
\dp
\b_framed_normal
1598
\setbox
\b_framed_normal
\box
\scratchbox
}
1599 1600
\def
\installframedlocator
#
1
#
2
#
3
%
1601
{
\setvalue
{
\??framedlocatorbefore
#
1
}{
#
2
}
%
1602
\setvalue
{
\??framedlocatorafter
#
1
}{
#
3
}}
1603 1604
\def
\pack_framed_locator_before
#
1
{
\begincsname
\??framedlocatorbefore
#
1
\endcsname
}
1605
\def
\pack_framed_locator_after
#
1
{
\begincsname
\??framedlocatorafter
#
1
\endcsname
}
1606 1607
\newdimen
\d_framed_locator_ht
1608
\newdimen
\d_framed_locator_dp
1609
\newdimen
\d_framed_locator_lo
1610
\newdimen
\d_framed_locator_ro
1611 1612
\def
\pack_framed_locator_set
#
1
%
1613
{
\d_framed_locator_ht
\dimexpr
1614
#
1
+
\d_framed_linewidth
1615
\ifconditional
\c_framed_has_offset
1616
+
\framedparameter
\c!offset
1617
\fi
1618
+
\framedparameter
\c!toffset
1619
\relax
1620
\d_framed_locator_dp
\dimexpr\ht
\b_framed_normal
-
\d_framed_locator_ht
\relax
}
1621 1622
\def
\pack_framed_locator_set_lo
1623
{
\global
\d_framed_locator_lo
\dimexpr
1624
\d_framed_linewidth
1625
\ifconditional
\c_framed_has_offset
1626
+
\framedparameter
\c!offset
1627
\fi
1628
+
\framedparameter
\c!loffset
1629
\relax
}
1630 1631
\def
\pack_framed_locator_set_ro
1632
{
\global
\d_framed_locator_ro
\dimexpr
1633
\d_framed_linewidth
1634
\ifconditional
\c_framed_has_offset
1635
+
\framedparameter
\c!offset
1636
\fi
1637
+
\framedparameter
\c!roffset
1638
\relax
}
1639 1640
% \ruledhbox
1641
% {A
1642
% \framed[width=2cm,align=middle,location=hanging]{location\\equals\\hanging}
1643
% \framed[width=2cm,align=middle,location=depth] {location\\equals\\depth}
1644
% \framed[width=2cm,align=middle,location=height] {location\\equals\\height}
1645
% B}
1646
% \vskip2cm
1647
% \ruledhbox
1648
% {A
1649
% \framed[width=2cm,align=middle,location=low] {location\\equals\\low}
1650
% \framed[width=2cm,align=middle,location=line] {location\\equals\\line}
1651
% \framed[width=2cm,align=middle,location=high] {location\\equals\\high}
1652
% B}
1653
% \vskip2cm
1654
% \ruledhbox
1655
% {A
1656
% \framed[width=2cm,align=middle,location=top] {location\\equals\\top}
1657
% \framed[width=2cm,align=middle,location=bottom] {location\\equals\\bottom}
1658
% \framed[width=2cm,align=middle,location=lohi] {location\\equals\\lohi}
1659
% \framed[width=2cm,align=middle,location=middle] {location\\equals\\middle}
1660
% B}
1661 1662
% \installframedlocator \v!hanging % best with strut=no
1663
% {}
1664
% {\dp\b_framed_normal\ht\b_framed_normal
1665
% \ht\b_framed_normal\zeropoint}
1666
%
1667
% \installframedlocator \v!depth
1668
% {}
1669
% {\ht\b_framed_normal\dimexpr\ht\b_framed_normal-\strutdp\relax
1670
% \dp\b_framed_normal\strutdp
1671
% \box\b_framed_normal}
1672
%
1673
% \installframedlocator \v!height
1674
% {}
1675
% {\dp\b_framed_normal\dimexpr\ht\b_framed_normal-\strutht\relax
1676
% \ht\b_framed_normal\strutht
1677
% \box\b_framed_normal}
1678 1679
\installframedlocator
\v!hanging
% best with strut=no *1* / see mail to list by SB
1680
{}
1681
{
\scratchdimen
\ht
\b_framed_normal
1682
\setbox
\b_framed_normal
\hpack
{
\lower
\scratchdimen
\box
\b_framed_normal
}
%
1683
\dp
\b_framed_normal
\scratchdimen
1684
\ht
\b_framed_normal
\zeropoint
1685
\box
\b_framed_normal
}
1686 1687
\installframedlocator
\v!depth
% *1*
1688
{}
1689
{
\setbox
\b_framed_normal
\hpack
{
\lower
\strutdp
\box
\b_framed_normal
}
%
1690
\ht
\b_framed_normal
\dimexpr\ht
\b_framed_normal
-
\strutdp
\relax
1691
\dp
\b_framed_normal
\strutdp
1692
\box
\b_framed_normal
}
1693 1694
\installframedlocator
\v!height
% *1*
1695
{}
1696
{
\scratchdimen
\dimexpr
\ht
\b_framed_normal
-
\strutht
\relax
1697
\setbox
\b_framed_normal
\hpack
{
\lower
\scratchdimen
\box
\b_framed_normal
}
%
1698
\dp
\b_framed_normal
\dimexpr\ht
\b_framed_normal
-
\strutht
\relax
1699
\ht
\b_framed_normal
\strutht
1700
\box
\b_framed_normal
}
1701 1702
\installframedlocator
\v!high
1703
{}
1704
{
\pack_framed_locator_set
\strutht
1705
\setbox
\b_framed_normal
\hpack
{
\lower
\d_framed_locator_dp
\box
\b_framed_normal
}
%
1706
\ht
\b_framed_normal
\strutht
1707
\dp
\b_framed_normal
\strutdp
1708
\hpack
{
\box
\b_framed_normal
}}
% why do we pack .. dange of loosing?
1709 1710
\installframedlocator
\v!line
1711
{}
1712
{
\setbox
\b_framed_normal
\hpack
{
\lower
.
5
\ht
\b_framed_normal
\box
\b_framed_normal
}
%
1713
\ht
\b_framed_normal
.
5
\lineheight
1714
\dp
\b_framed_normal
.
5
\lineheight
1715
\hpack
{
\box
\b_framed_normal
}}
% why do we pack .. dange of loosing?
1716 1717
\installframedlocator
\v!low
1718
{}
1719
{
\pack_framed_locator_set
\strutdp
1720
\setbox
\b_framed_normal
\hpack
{
\lower
\d_framed_locator_ht
\box
\b_framed_normal
}
%
1721
\ht
\b_framed_normal
\strutht
1722
\dp
\b_framed_normal
\strutdp
1723
\box
\b_framed_normal
}
1724 1725
\installframedlocator
\v!top
1726
{}
1727
{
\pack_framed_locator_set
\strutht
1728
\setbox
\b_framed_normal
\hpack
{
\lower
\d_framed_locator_dp
\box
\b_framed_normal
}
%
1729
\ht
\b_framed_normal
\d_framed_locator_ht
1730
\dp
\b_framed_normal
\d_framed_locator_dp
1731
\hpack
{
\box
\b_framed_normal
}}
% why do we pack .. dange of loosing?
1732 1733
\installframedlocator
\v!middle
1734
{}
1735
{
\scratchdimen
.
5
\ht
\b_framed_normal
1736
\setbox
\b_framed_normal
\hpack
{
\lower
\scratchdimen
\box
\b_framed_normal
}
%
1737
\ht
\b_framed_normal
\scratchdimen
1738
\dp
\b_framed_normal
\scratchdimen
1739
\hpack
{
\box
\b_framed_normal
}}
% why do we pack .. dange of loosing?
1740 1741
\installframedlocator
\v!lohi
% maybe also \v!center
1742
{
\pack_framed_locator_before
\v!middle
}
1743
{
\pack_framed_locator_after
\v!middle
}
1744 1745
\installframedlocator
\v!bottom
1746
{}
1747
{
\pack_framed_locator_set
\strutdp
1748
\setbox
\b_framed_normal
\hpack
{
\lower
\d_framed_locator_ht
\box
\b_framed_normal
}
%
1749
\ht
\b_framed_normal
\d_framed_locator_dp
1750
\dp
\b_framed_normal
\d_framed_locator_ht
1751
\hpack
{
\box
\b_framed_normal
}}
% why do we pack .. dange of loosing?
1752 1753
\installframedlocator
\v!keep
% retains height/depth
1754
{
\pack_framed_remove_depth
}
1755
{
\pack_framed_restore_depth
}
1756 1757
\newdimen
\d_framed_formula
1758 1759
\installframedlocator
\v!formula
% private, will become a more generic name
1760
{}
1761
{
\pack_framed_locator_set
\d_framed_formula
1762
\setbox
\b_framed_normal
\hpack
{
\lower
\d_framed_locator_dp
\box
\b_framed_normal
}
%
1763
\ht
\b_framed_normal
\d_framed_locator_ht
1764
\dp
\b_framed_normal
\d_framed_locator_dp
1765
\hpack
{
\box
\b_framed_normal
}}
% why do we pack .. dange of loosing?
1766 1767
% also used in fastlocalframed
1768 1769
\newdimen
\d_framed_original_wd
1770
\newdimen
\d_framed_original_ht
1771
\newdimen
\d_framed_original_dp
1772 1773
\def
\pack_framed_remove_depth
1774
{
\d_framed_original_wd
\wd
\b_framed_normal
1775
\d_framed_original_ht
\ht
\b_framed_normal
1776
\d_framed_original_dp
\dp
\b_framed_normal
1777
\ifzeropt
\d_framed_original_dp
\else
1778
\setbox
\b_framed_normal
\hpack
{
\raise
\d_framed_original_dp
\box
\b_framed_normal
}
%
1779
\fi
1780
\wd
\b_framed_normal
\d_framed_original_wd
1781
\ht
\b_framed_normal
\dimexpr
\d_framed_original_ht
+
\d_framed_original_dp
\relax
1782
\dp
\b_framed_normal
\zeropoint
}
1783 1784
\def
\pack_framed_restore_depth
1785
{
\ifzeropt
\d_framed_original_dp
\else
1786
\setbox
\b_framed_normal
\hpack
{
\lower
\d_framed_original_dp
\box
\b_framed_normal
}
%
1787
\fi
1788
\wd
\b_framed_normal
\d_framed_original_wd
1789
\ht
\b_framed_normal
\d_framed_original_ht
1790
\dp
\b_framed_normal
\d_framed_original_dp
}
1791 1792
% \framed[width=12cm,height=3cm,orientation=0]{\input ward\relax}
1793
% \framed[width=12cm,height=3cm,orientation=90]{\input ward\relax}
1794
% \framed[width=12cm,height=3cm,orientation=180]{\input ward\relax}
1795
% \framed[width=12cm,height=3cm,orientation=270]{\input ward\relax}
1796
% \framed[width=12cm,height=3cm,orientation=-90]{\input ward\relax}
1797
% \framed[width=12cm,height=3cm,orientation=-180]{\input ward\relax}
1798
% \framed[width=12cm,height=3cm,orientation=-270]{\input ward\relax}
1799 1800
\def
\pack_framed_start_orientation
1801
{
\ifcase
\p_framed_orientation
1802
\let
\pack_framed_stop_orientation
\relax
1803
\else
1804
\let
\pack_framed_stop_orientation
\pack_framed_stop_orientation_indeed
1805
\fi
}
1806 1807
\def
\pack_framed_stop_orientation_indeed
1808
{
\setbox
\b_framed_normal
\hpack
{
\dorotatebox
\p_framed_orientation
\hpack
{
\box
\b_framed_normal
}}
%
1809
\d_framed_height
\ht
\b_framed_normal
1810
\d_framed_width
\wd
\b_framed_normal
}
1811 1812
%D The last conditional takes care of the special situation of in||line \inframed
1813
%D [height=3cm] {framed} boxes. Such boxes have to be \inframed {aligned} with the
1814
%D running text.
1815 1816
\unexpanded
\def
\inframed
1817
{
\dosingleempty
\pack_framed_inline
}
1818 1819
% \def\pack_framed_inline[#1]%
1820
% {\framed[\c!location=\v!low,#1]}
1821
%
1822
% or:
1823 1824
\def
\pack_framed_inline
[
%
1825
{
\framed
[
\c!location
=
\v!low
,
}
1826 1827
%D When we set \type{empty} to \type{yes}, we get ourselves a frame and/or background,
1828
%D but no content, so actually we have a sort of phantom framed box.
1829 1830
%D \macros
1831
%D {mframed, minframed}
1832
%D
1833
%D When Tobias asked how to frame mathematical elements in formulas, Taco's posted the
1834
%D next macro:
1835
%D
1836
%D \starttyping
1837
%D \def\mframed#1%
1838
%D {\relax
1839
%D \ifmmode
1840
%D \vcenter{\hbox{\framed{$\ifinner\else\displaystyle\fi#1$}}}%
1841
%D \else
1842
%D \framed{$#1$}%
1843
%D \fi}
1844
%D \stoptyping
1845
%D
1846
%D Because \type {\ifinner} does not (always) reports what one would expect, we move the
1847
%D test to the outer level. We also want to pass arguments,
1848
%D
1849
%D \starttyping
1850
%D \def\mframed%
1851
%D {\dosingleempty\domframed}
1852
%D
1853
%D \def\domframed[#1]#2% % tzt \dowithnextmathbox ?
1854
%D {\relax
1855
%D \ifmmode
1856
%D \ifinner
1857
%D \inframed[#1]{$#2$}%
1858
%D \else
1859
%D \vcenter{\hbox{\framed[#1]{$\displaystyle#2$}}}%
1860
%D \fi
1861
%D \else
1862
%D \inframed[#1]{$#2$}%
1863
%D \fi}
1864
%D \stoptyping
1865
%D
1866
%D Still better is the next alternative, if only because it takes care of setting the super-
1867
%D and subscripts styles
1868 1869
\newcount
\c_framed_mstyle
1870 1871
\unexpanded
\def
\pack_framed_math_strut
1872
{
\Ustartmath
1873
\triggermathstyle
\c_framed_mstyle
1874
\vphantom
{
(
}
%
1875
\Ustopmath
}
1876 1877
\installcorenamespace
{
mathframed
}
1878 1879
\installframedcommandhandler
\??mathframed
{
mathframed
}
\??mathframed
1880 1881
\appendtoks
1882
\setuevalue
{
\currentmathframed
}{
\pack_framed_mathframed
{
\currentmathframed
}}
%
1883
\to
\everydefinemathframed
1884 1885
\unexpanded
\def
\pack_framed_mathframed
#
1
%
1886
{
\begingroup
1887
\edef
\currentmathframed
{
#
1
}
%
1888
\dosingleempty
\pack_framed_mathframed_indeed
}
1889 1890
\newcount
\c_pack_framed_mathframed
1891
\newtoks
\t_pack_framed_mathframed
1892 1893
\def
\pack_framed_math_pos
1894
{
\global\advance
\c_pack_framed_mathframed
\plusone
1895
\xdef
\pack_framed_mc_one
{
mcf
:
1
:
\number
\c_pack_framed_mathframed
}
%
1896
\xdef
\pack_framed_mc_two
{
mcf
:
2
:
\number
\c_pack_framed_mathframed
}
%
1897
\xypos
\pack_framed_mc_two
}
1898 1899
\def
\pack_framed_mathframed_indeed
[#
1
]#
2
% no fancy nesting supported here
1900
{
\iffirstargument
1901
\setupcurrentmathframed
[#
1
]
%
1902
\fi
1903
\c_framed_mstyle
\normalmathstyle
1904
\edef
\m_framed_location
{
\mathframedparameter
\c!location
}
%
1905
\ifx
\m_framed_location
\v!mathematics
1906
\let
\normalstrut
\pack_framed_math_pos
1907
\else\ifx
\m_framed_location
\v!low
\else
1908
\let
\normalstrut
\pack_framed_math_strut
1909
\fi\fi
1910
\inheritedmathframedframed
\bgroup
1911
\Ustartmath
1912
\triggermathstyle
\c_framed_mstyle
1913
\the
\t_pack_framed_mathframed
1914
#
2
%
1915
\Ustopmath
1916
\egroup
1917
\endgroup
}
1918 1919
\appendtoks
1920
\mathraggedstatus
\plustwo
% makes \startalign work
1921
\eqalignmode
\zerocount
% makes \startalign fit
1922
\to
\t_pack_framed_mathframed
1923 1924
\installframedlocator
\v!mathematics
1925
{}
1926
{
\lower\dimexpr
\MPy
\pack_framed_mc_two
-
\MPy
\pack_framed_mc_one
\relax
1927
\hpack
{
\xypos
\pack_framed_mc_one
\box
\b_framed_normal
}}
1928 1929
\definemathframed
[
mframed
]
1930
\definemathframed
[
inmframed
][
\c!location
=
\v!low
]
1931
\definemathframed
[
mcframed
]
[
\c!location
=
\v!mathematics
]
1932 1933
%D So instead of the rather versatile \type {\framed}, we use \type {\mframed}:
1934
%D
1935
%D \startbuffer
1936
%D \startformula
1937
%D x \times \mframed{y} \times y^{z_z}
1938
%D x \times \inmframed{y} \times y^{z_z}
1939
%D \stopformula
1940
%D \stopbuffer
1941
%D
1942
%D \typebuffer \getbuffer
1943
%D
1944
%D And:
1945
%D
1946
%D \startbuffer
1947
%D \startformula
1948
%D x \times \mframed{y} \times y^{\mframed{z}_{\mframed{z}}}
1949
%D \stopformula
1950
%D \stopbuffer
1951
%D
1952
%D \typebuffer \getbuffer
1953
%D
1954
%D As usual, one can specify in what way the text should be framed. One should be
1955
%D aware of the fact that, inorder to preserve the proper spacing, the \type
1956
%D {offset} is set to \type {overlay} and \type {frameoffset} is used used instead.
1957
%D
1958
%D \startbuffer
1959
%D \startformula
1960
%D x \times y^{\mframed[framecolor=red]{z}_{z}}
1961
%D \stopformula
1962
%D \stopbuffer
1963
%D
1964
%D \typebuffer \getbuffer
1965
%D
1966
%D For inline use, we also provide the \type {\inmframed} alternative: we want $x
1967
%D \times \inmframed{y}$ in inline math, right?
1968 1969
%D This previous framing macros needs a lot of alternatives for putting rules around
1970
%D boxes, inserting offsets and aligning text. Each step is handled by separate macros.
1971 1972
\newdimen
\d_framed_applied_offset
1973
\newdimen
\d_framed_loffset
1974
\newdimen
\d_framed_roffset
1975
\newdimen
\d_framed_toffset
1976
\newdimen
\d_framed_boffset
1977 1978
\def
\pack_framed_check_extra_offsets
% we could check h and v indepently
1979
{
\setfalse
\c_framed_has_extra_offset
1980
\d_framed_loffset
\framedparameter
\c!loffset
\relax
1981
\d_framed_roffset
\framedparameter
\c!roffset
\relax
1982
\d_framed_toffset
\framedparameter
\c!toffset
\relax
1983
\d_framed_boffset
\framedparameter
\c!boffset
\relax
1984
\ifzeropt
\d_framed_loffset
\else
\advance
\d_framed_width
-
\d_framed_loffset
\settrue
\c_framed_has_extra_offset
\fi
1985
\ifzeropt
\d_framed_roffset
\else
\advance
\d_framed_width
-
\d_framed_roffset
\settrue
\c_framed_has_extra_offset
\fi
1986
\ifzeropt
\d_framed_toffset
\else
\advance
\d_framed_height
-
\d_framed_toffset
\settrue
\c_framed_has_extra_offset
\fi
1987
\ifzeropt
\d_framed_boffset
\else
\advance
\d_framed_height
-
\d_framed_boffset
\settrue
\c_framed_has_extra_offset
\fi
}
1988 1989
\def
\pack_framed_apply_extra_offsets
1990
{
\setbox
\b_framed_normal
\vpack
\bgroup
1991
\advance
\d_framed_toffset
\d_framed_applied_offset
1992
\advance
\d_framed_boffset
\d_framed_applied_offset
1993
\advance
\d_framed_loffset
\d_framed_applied_offset
1994
\advance
\d_framed_roffset
\d_framed_applied_offset
1995
\kern
\d_framed_toffset
1996
\hpack
\bgroup
1997
\kern
\d_framed_loffset
1998
\box
\b_framed_normal
1999
\kern
\d_framed_roffset
2000
\egroup
2001
\kern
\d_framed_boffset
2002
\egroup
}
2003 2004
\def
\pack_framed_widen_box
2005
{
\setbox
\b_framed_normal
\vpack
2006
{
\kern
\d_framed_applied_offset
2007
\hpack
{
\kern
\d_framed_applied_offset
\box
\b_framed_normal
\kern
\d_framed_applied_offset
}
%
2008
\kern
\d_framed_applied_offset
}}
2009 2010
%D Let's hope that the next few examples show us enough of what needs to be
2011
%D done by the auxiliary macros.
2012
%D
2013
%D \startbuffer
2014
%D \framed[height=1cm,offset=.5cm] {rule based learning}
2015
%D \framed[height=1cm,offset=0cm] {rule based learning}
2016
%D \framed[height=1cm,offset=none] {rule based learning}
2017
%D \framed[height=1cm,offset=overlay]{rule based learning}
2018
%D \stopbuffer
2019
%D
2020
%D \typebuffer
2021
%D
2022
%D \startlinecorrection
2023
%D \hbox{\getbuffer}
2024
%D \stoplinecorrection
2025
%D
2026
%D \startbuffer
2027
%D \framed[offset=.5cm] {rule based learning}
2028
%D \framed[offset=0cm] {rule based learning}
2029
%D \framed[offset=none] {rule based learning}
2030
%D \framed[offset=overlay]{rule based learning}
2031
%D \stopbuffer
2032
%D
2033
%D \typebuffer
2034
%D
2035
%D \startlinecorrection
2036
%D \hbox{\getbuffer}
2037
%D \stoplinecorrection
2038
%D
2039
%D \startbuffer
2040
%D \framed[strut=no,offset=.5cm] {rule based learning}
2041
%D \framed[strut=no,offset=0cm] {rule based learning}
2042
%D \framed[strut=no,offset=none] {rule based learning}
2043
%D \framed[strut=no,offset=overlay]{rule based learning}
2044
%D \stopbuffer
2045
%D
2046
%D \typebuffer
2047
%D
2048
%D \startlinecorrection
2049
%D \hbox{\getbuffer}
2050
%D \stoplinecorrection
2051
%D
2052
%D \startbuffer
2053
%D \framed[width=3cm,align=left] {rule\\based\\learning}
2054
%D \framed[width=3cm,align=middle] {rule\\based\\learning}
2055
%D \framed[width=3cm,align=right] {rule\\based\\learning}
2056
%D \framed[width=fit,align=middle] {rule\\based\\learning}
2057
%D \stopbuffer
2058
%D
2059
%D \typebuffer
2060
%D
2061
%D \startlinecorrection
2062
%D \hbox{\dontcomplain\getbuffer}
2063
%D \stoplinecorrection
2064
%D
2065
%D So now we're ready for the complicated stuff. We distinguish between borders with
2066
%D straight lines and those with round corners. When using the first alternative it
2067
%D is possible to turn off one or more lines. More fancy shapes are also possible by
2068
%D specifying dedicated backgrounds. Turning lines on and off is implemented as
2069
%D efficient as possible and as a result is interface language dependant. This next
2070
%D implementation evolved from simpler ones. It puts for instance the rules on top
2071
%D of the content and provides additional offset capabilities. The lot of calls to
2072
%D other macros makes this mechanism not that easy to comprehend.
2073
%D
2074
%D We handle left, right or middle alignment as well as fixed or free widths and
2075
%D heights. Each combination gets its own macro.
2076
%D
2077
%D The following code handles one-liners: \type {align={line,flushright}}. Beware,
2078
%D since we entered a group and either or not grab the next bgroup token, we need to
2079
%D finish the group in the oneliner mode.
2080 2081
\ifdefined
\raggedonelinerstate
\else
\newconditional
\raggedonelinerstate
\fi
2082 2083
\def
\doformatonelinerbox
% beware: assumes explicit preceding bgroup
2084
{
\ifconditional
\raggedonelinerstate
2085
\expandafter
\dodoformatonelinerbox
2086
\else
2087
\expandafter
\nodoformatonelinerbox
2088
\fi
}
2089 2090
\def
\dodoformatonelinerbox
2091
{
\afterassignment
\redoformatonelinerbox
2092
\setbox
\nextbox
\hbox
}
% maybe \hpack
2093 2094
\def
\redoformatonelinerbox
2095
{
\aftergroup
\dododoformatonelinerbox
2096
\ignorespaces
}
2097 2098
\def
\dododoformatonelinerbox
2099
{
\hpack
to
\hsize
% was \hbox
2100
{
\ifcase
\raggedstatus
\or\hss\or\hss
\fi
2101
\unhbox
\nextbox
\removeunwantedspaces
2102
\ifcase
\raggedstatus
\or
\or\hss\or\hss\fi
}
%
2103
\egroup
}
2104 2105
\def
\nodoformatonelinerbox
% grabs {
2106
{
\let
\next
=
}
2107 2108
%D The handlers:
2109 2110
% Beware, we have a \noindent so an empty line is indeed an empty line and
2111
% the \synchronizeinlinedirection triggers a vbox instead of a line.
2112
%
2113
% \startTEXpage[offset=0.5ex,align={lohi,middle}]
2114
%
2115
% \vbox{\hbox{x}}
2116
% \stopTEXpage
2117
%
2118
% \startTEXpage[offset=0.5ex,align={lohi,middle}]
2119
% \vbox{\hbox{x}}
2120
% \stopTEXpage
2121 2122
% \def\pack_framed_forgetall{\forgetall}
2123 2124
\def
\pack_framed_set_foregroundcolor
2125
{
\edef
\p_framed_foregroundcolor
{
\framedparameter
\c!foregroundcolor
}
%
2126
\ifx
\p_framed_foregroundcolor
\empty
\else
\dousecolorparameter
\p_framed_foregroundcolor
\fi
}
2127 2128
\def
\pack_framed_do_setups
2129
{
\ifx
\p_framed_setups
\empty
\else
2130
\setups
[
\p_framed_setups
]
% \texsetup (or only one!)
2131
% \fastsetup\p_framed_setup % singular would have been better
2132
\fi
}
2133 2134
\def
\pack_framed_format_format_yes
2135
{
\vbox
to
\d_framed_height
2136
\bgroup
2137
\let
\postprocessframebox
\relax
2138
% \pack_framed_forgetall
2139
\iftrialtypesetting
\else
2140
\pack_framed_set_foregroundcolor
2141
\fi
2142
\oninterlineskip
2143
\hsize
\d_framed_width
2144
\vsize
\d_framed_height
2145
\pack_framed_do_setups
2146
\raggedcommand
2147
\pack_framed_do_top
2148
\bgroup
2149
\synchronizeinlinedirection
2150
\localbegstrut
2151
\aftergroup
\localendstrut
2152
\aftergroup
\pack_framed_do_bottom
2153
\aftergroup
\egroup
2154
\doformatonelinerbox
}
2155 2156
\def
\pack_framed_format_format_nop
2157
{
\vbox
to
\d_framed_height
2158
\bgroup
2159
\let
\postprocessframebox
\relax
2160
% \pack_framed_forgetall
2161
\iftrialtypesetting
\else
2162
\pack_framed_set_foregroundcolor
2163
\fi
2164
\oninterlineskip
2165
\hsize
\d_framed_width
2166
\vsize
\d_framed_height
2167
\pack_framed_do_setups
2168
\raggedcenter
2169
\vss
2170
\bgroup
2171
\synchronizeinlinedirection
2172
\localbegstrut
2173
\aftergroup
\localendstrut
2174
\aftergroup\vss
2175
\aftergroup
\egroup
2176
\doformatonelinerbox
}
2177 2178
\def
\pack_framed_format_format_height
2179
{
\vbox
to
\d_framed_height
2180
\bgroup
2181
\let
\postprocessframebox
\relax
2182
% \pack_framed_forgetall
2183
\iftrialtypesetting
\else
2184
\pack_framed_set_foregroundcolor
2185
\fi
2186
\oninterlineskip
2187
\pack_framed_do_setups
2188
\raggedcommand
2189
\vss
2190
\bgroup
2191
\aftergroup
\localendstrut
2192
\aftergroup\vss
2193
\aftergroup
\egroup
2194
\synchronizeinlinedirection
2195
\localbegstrut
2196
\doformatonelinerbox
}
2197 2198
\def
\pack_framed_format_format_width
2199
{
\vbox
2200
\bgroup
2201
\let
\postprocessframebox
\relax
2202
% \pack_framed_forgetall
2203
\iftrialtypesetting
\else
2204
\pack_framed_set_foregroundcolor
2205
\fi
2206
\oninterlineskip
2207
\hsize
\d_framed_width
2208
\pack_framed_do_setups
2209
\raggedcommand
2210
\pack_framed_do_top
2211
\bgroup
2212
\synchronizeinlinedirection
2213
\localbegstrut
2214
\aftergroup
\localendstrut
2215
\aftergroup
\pack_framed_do_bottom
2216
\aftergroup
\egroup
2217
\doformatonelinerbox
}
2218 2219
\def
\pack_framed_format_format_vsize
2220
{
\vbox
to
\d_framed_height
% no vpack .. maybe grid
2221
\bgroup
2222
\let
\postprocessframebox
\relax
2223
% \pack_framed_forgetall
2224
\iftrialtypesetting
\else
2225
\pack_framed_set_foregroundcolor
2226
\fi
2227
\vsize
\d_framed_height
2228
\pack_framed_do_setups
2229
\vss
2230
\bgroup
2231
\aftergroup\vss
2232
\aftergroup
\egroup
2233
\hbox
2234
\bgroup
2235
\aftergroup
\egroup
2236
\synchronizeinlinedirection
2237
\localstrut
2238
\doformatonelinerbox
}
2239 2240
\def
\pack_framed_format_format_hsize
2241
{
\hbox
to
\d_framed_width
2242
\bgroup
2243
\let
\postprocessframebox
\relax
2244
% \pack_framed_forgetall
2245
\iftrialtypesetting
\else
2246
\pack_framed_set_foregroundcolor
2247
\fi
2248
\pack_framed_do_setups
2249
\hss
2250
\synchronizeinlinedirection
2251
\localstrut
2252
\bgroup
2253
\aftergroup\hss
2254
\aftergroup
\egroup
2255
\doformatonelinerbox
}
2256 2257
\def
\pack_framed_format_format_no_size
2258
{
\hbox
2259
\bgroup
2260
\iftrialtypesetting
\else
2261
\pack_framed_set_foregroundcolor
2262
\fi
2263
\let
\postprocessframebox
\relax
2264
\pack_framed_do_setups
2265
\synchronizeinlinedirection
2266
\localstrut
2267
\doformatonelinerbox
}
2268 2269
%D On the next page we show some examples of how these macros come into action. The
2270
%D examples show us how \type {fit}, \type {broad} dimensions influence the
2271
%D formatting. Watch the visualized struts. \footnote {Here we used \type
2272
%D {\showstruts}.}
2273
%D
2274
%D \startpostponing
2275
%D \bgroup
2276
%D \showstruts
2277
%D \dontcomplain
2278
%D \starttabulate[|c|c|c|c|c|c|]
2279
%D % \HL
2280
%D \NC \framed[width=.2\hsize, height=.2\hsize, align=] {a\endgraf b\endgraf c}
2281
%D \NC \framed[width=.2\hsize, height=broad, align=] {a\endgraf b\endgraf c}
2282
%D \NC \framed[width=.2\hsize, height=fit, align=] {a\endgraf b\endgraf c}
2283
%D \NC \framed[width=fit, height=.2\hsize, align=] {a\endgraf b\endgraf c}
2284
%D \NC \framed[width=fit, height=broad, align=] {a\endgraf b\endgraf c}
2285
%D \NC \framed[width=fit, height=fit, align=] {a\endgraf b\endgraf c}
2286
%D \NC \NR
2287
%D % \HL
2288
%D \NC \framed[width=.2\hsize, height=.2\hsize, align=yes] {a\endgraf b\endgraf c}
2289
%D \NC \framed[width=.2\hsize, height=broad, align=yes] {a\endgraf b\endgraf c}
2290
%D \NC \framed[width=.2\hsize, height=fit, align=yes] {a\endgraf b\endgraf c}
2291
%D \NC \framed[width=fit, height=.2\hsize, align=yes] {a\endgraf b\endgraf c}
2292
%D \NC \framed[width=fit, height=broad, align=yes] {a\endgraf b\endgraf c}
2293
%D \NC \framed[width=fit, height=fit, align=yes] {a\endgraf b\endgraf c}
2294
%D \NC \NR
2295
%D % \HL
2296
%D \NC \framed[width=.2\hsize, height=.2\hsize, align=right] {a\endgraf b\endgraf c}
2297
%D \NC \framed[width=.2\hsize, height=broad, align=right] {a\endgraf b\endgraf c}
2298
%D \NC \framed[width=.2\hsize, height=fit, align=right] {a\endgraf b\endgraf c}
2299
%D \NC \framed[width=fit, height=.2\hsize, align=right] {a\endgraf b\endgraf c}
2300
%D \NC \framed[width=fit, height=broad, align=right] {a\endgraf b\endgraf c}
2301
%D \NC \framed[width=fit, height=fit, align=right] {a\endgraf b\endgraf c}
2302
%D \NC \NR
2303
%D % \HL
2304
%D \NC \framed[width=.2\hsize, height=.2\hsize, align=left] {a\endgraf b\endgraf c}
2305
%D \NC \framed[width=.2\hsize, height=broad, align=left] {a\endgraf b\endgraf c}
2306
%D \NC \framed[width=.2\hsize, height=fit, align=left] {a\endgraf b\endgraf c}
2307
%D \NC \framed[width=fit, height=.2\hsize, align=left] {a\endgraf b\endgraf c}
2308
%D \NC \framed[width=fit, height=broad, align=left] {a\endgraf b\endgraf c}
2309
%D \NC \framed[width=fit, height=fit, align=left] {a\endgraf b\endgraf c}
2310
%D \NC \NR
2311
%D % \HL
2312
%D \NC \framed[width=.2\hsize, height=.2\hsize, align=middle] {a\endgraf b\endgraf c}
2313
%D \NC \framed[width=.2\hsize, height=broad, align=middle] {a\endgraf b\endgraf c}
2314
%D \NC \framed[width=.2\hsize, height=fit, align=middle] {a\endgraf b\endgraf c}
2315
%D \NC \framed[width=fit, height=.2\hsize, align=middle] {a\endgraf b\endgraf c}
2316
%D \NC \framed[width=fit, height=broad, align=middle] {a\endgraf b\endgraf c}
2317
%D \NC \framed[width=fit, height=fit, align=middle] {a\endgraf b\endgraf c}
2318
%D \NC \NR
2319
%D % \HL
2320
%D \stoptabulate
2321
%D \egroup
2322
%D \stoppostponing
2323 2324
%D \macros
2325
%D {framednoflines, framedlastlength}
2326
%D
2327
%D It is possible to let the frame macro calculate the width of a centered box
2328
%D automatically (\type {fit}). When doing so, we need to reshape the box:
2329 2330
\newcount
\framednoflines
2331
\newdimen
\framedfirstheight
2332
\newdimen
\framedlastdepth
2333
\newdimen
\framedminwidth
2334
\newdimen
\framedmaxwidth
2335
\newdimen
\framedaveragewidth
2336 2337
\def
\pack_framed_reshape_reset
2338
{
\framednoflines
\zerocount
2339
\framedfirstheight
\zeropoint
2340
\framedlastdepth
\zeropoint
2341
\framedminwidth
\zeropoint
2342
\framedmaxwidth
\zeropoint
2343
\framedaveragewidth
\zeropoint
}
2344 2345
\def
\pack_framed_reshape_process
{
\ifvbox
\b_framed_normal
\clf_doreshapeframedbox
\b_framed_normal
\relax\fi
}
2346
\def
\pack_framed_reshape_analyze
{
\ifvbox
\b_framed_normal
\clf_doanalyzeframedbox
\b_framed_normal
\relax\fi
}
2347 2348
% torture test / strange case (much depth) / method 2 needed
2349
%
2350
% \startTEXpage[frame=on]
2351
% \startformula \startalign \NC A \NC B \NR \intertext{test} \NC C \NC D \NR \stopalign \stopformula
2352
% test outside formula
2353
% \startformula \startalign \NC A \NC B \NR \intertext{test} \NC C \NC D \NR \stopalign \stopformula
2354
% \blank[big]
2355
% \startformula \startalign \NC \int_01 \NC B \NR \intertext{test} \NC \int_01 \NC D \NR \stopalign \stopformula
2356
% test outside formula
2357
% \startformula \startalign \NC \int_01 \NC B \NR \intertext{test} \NC \int_01 \NC D \NR \stopalign \stopformula
2358
% \stopTEXpage
2359 2360
%D The examples on the next page show how one can give the frame as well as the
2361
%D background an additional offset and even a bit more depth. The blue outline is
2362
%D the frame, the red box is the background and the small black outline is the
2363
%D visualization of the resulting box, that is, we applied \type {\ruledhbox} to
2364
%D the result.
2365
%D
2366
%D \startpostponing
2367
%D \bgroup
2368
%D \unprotect
2369
%D \dontcomplain
2370
%D
2371
%D \startbuffer
2372
%D \unprotect
2373
%D \vbox to \vsize
2374
%D \bgroup
2375
%D \startalignment[middle]
2376
%D \vss
2377
%D \dontleavehmode\vbox to .8\vsize
2378
%D \bgroup
2379
%D \hsize=300pt
2380
%D \setupframed
2381
%D [background=color,
2382
%D backgroundcolorachtergrondkleur=darkred,
2383
%D width=300pt,
2384
%D height=60pt,
2385
%D framecolorkaderkleur=DemoBlue,
2386
%D rulethickness=2pt]
2387
%D \def\status%
2388
%D {backgroundoffset=\the\dimexpr\framedparameter\c!backgroundoffset\relax\\
2389
%D frameoffset=\the\dimexpr\framedparameter\c!frameoffset\relax\\
2390
%D depth=\the\dimexpr\framedparameter\c!depth\relax}
2391
%D \dontleavehmode \ruledhbox{\framed[backgroundoffset=0pt,frameoffset=0pt]{\status}}
2392
%D \vss
2393
%D \dontleavehmode \ruledhbox{\framed[backgroundoffset=5pt,frameoffset=0pt]{\status}}
2394
%D \vss
2395
%D \dontleavehmode \ruledhbox{\framed[backgroundoffset=0pt,frameoffset=5pt]{\status}}
2396
%D \vss
2397
%D \dontleavehmode \ruledhbox{\framed[backgroundoffset=2pt,frameoffset=5pt]{\status}}
2398
%D \vss
2399
%D \dontleavehmode \ruledhbox{\framed[backgroundoffset=5pt,frameoffset=2pt]{\status}}
2400
%D \vss
2401
%D \dontleavehmode \ruledhbox{\framed[backgroundoffset=5pt,frameoffset=5pt]{\status}}
2402
%D \egroup
2403
%D \vss
2404
%D \stopalignment
2405
%D \egroup
2406
%D \protect
2407
%D \stopbuffer
2408
%D
2409
%D \getbuffer \page
2410
%D
2411
%D {\setupframed[depth=4pt]\getbuffer} \page
2412
%D
2413
%D \protect
2414
%D \egroup
2415
%D \stoppostponing
2416 2417
%D We can draw lines from left to right and top to bottom by using the normal \type
2418
%D {\hairline} command. Both directions need a different treatment.
2419
%D
2420
%D \startbuffer
2421
%D \framed[width=4cm] {alfa\hairline beta\hairline gamma}
2422
%D \framed[height=2cm] {alfa\hairline beta\hairline gamma}
2423
%D \framed[width=4cm,height=2cm]{alfa\hairline beta\hairline gamma}
2424
%D \stopbuffer
2425
%D
2426
%D \typebuffer
2427
%D
2428
%D \startlinecorrection
2429
%D \hbox{\getbuffer}
2430
%D \stoplinecorrection
2431
%D
2432
%D These macros try to adapt their behaviour as good as possible to the circumstances
2433
%D and act as natural as possible.
2434 2435
\unexpanded
\def
\pack_framed_vboxed_hairline
% nasty overlay mess .. needed for autowidth
2436
{
\begingroup
2437
\scratchoffset
\ifconditional
\c_framed_has_offset
\localoffset
\else
\zeropoint
\fi
2438
\scratchwidth
\dimexpr
\scratchoffset
+
\d_framed_linewidth
\relax
2439
\par
2440
\nointerlineskip
2441
\kern
\scratchoffset
2442
\dontleavehmode
2443
\hrule
\s!height
\d_framed_linewidth
\s!depth
\zeropoint
2444
\par
2445
\kern
-
\d_framed_linewidth
2446
\dontleavehmode
2447
\hpack
to
\zeropoint
{
\hss\vrule
\s!height
\d_framed_linewidth
\s!depth
\zeropoint
\s!width
\scratchwidth
}
%
2448
\hfill
2449
\hpack
to
\zeropoint
{
\vrule
\s!height
\d_framed_linewidth
\s!depth
\zeropoint
\s!width
\scratchwidth
\hss
}
%
2450
\par
2451
\nointerlineskip
2452
\kern
\scratchoffset
2453
\nointerlineskip
2454
\endgraf
2455
\nointerlineskip
2456
\localbegstrut
2457
\endgroup
}
2458 2459
\unexpanded
\def
\pack_framed_hboxed_hairline
% use framed dimen
2460
{
\bgroup
2461
\scratchoffset
\ifconditional
\c_framed_has_offset
\localoffset
\else
\zeropoint
\fi
2462
\ifconditional
\c_framed_has_height
2463
\dimen
\scratchheight
\dimexpr
\localheight
/
\plustwo
+
\strutdp
-
\plustwo
\d_framed_linewidth
\relax
2464
\dimen
\scratchdepth
\dimexpr
\localheight
/
\plustwo
-
\strutdp
+
\plustwo
\d_framed_linewidth
\relax
2465
\else
2466
\dimen
\scratchheight
\dimexpr
\strutht
+
\scratchoffset
\relax
2467
\dimen
\scratchdepth
\dimexpr
\strutdp
+
\scratchoffset
\relax
2468
\fi
2469
\unskip
2470
\setbox
\scratchbox
\hpack
2471
{
\kern
\scratchoffset
2472
\vrule
\s!height
\dimen
\scratchheight
\s!depth
\dimen
\scratchdepth
\s!width
\d_framed_linewidth
2473
\kern
\scratchoffset
}
%
2474
\ht
\scratchbox\strutht
2475
\dp
\scratchbox\strutdp
2476
\box
\scratchbox
2477
\ignorespaces
2478
\egroup
}
2479 2480
%D The argument of the frame command accepts \type{\\} as a sort of newline signal. In
2481
%D horizontal boxes it expands to a space.
2482 2483
\unexpanded
\def
\pack_framed_vboxed_newline
2484
{
\endgraf
\ignorespaces
}
2485 2486
\unexpanded
\def
\pack_framed_hboxed_newline
2487
{
\unskip
\normalspace
\ignorespaces
}
2488 2489
%D We can set each rule on or off. The default setting is inherited from
2490
%D \type {frame}. An earlier implementation use a bit different approach, but the new
2491
%D one seems more natural:
2492
%D
2493
%D \bgroup
2494
%D \setuptyping[margin=0pt]
2495
%D \startlinecorrection
2496
%D \startbuffer
2497
%D \framed[offset=overlay,frame=on]{\darkred\blackrule}
2498
%D \stopbuffer
2499
%D \hbox{\getbuffer\vbox{\typebuffer}}
2500
%D
2501
%D \startbuffer
2502
%D \framed[offset=overlay,frame=on,bottomframe=off]{\darkred\blackrule}
2503
%D \stopbuffer
2504
%D \hbox{\getbuffer\vbox{\typebuffer}}
2505
%D
2506
%D \startbuffer
2507
%D \framed[offset=overlay,frame=on,bottomframe=on]{\darkred\blackrule}
2508
%D \stopbuffer
2509
%D \hbox{\getbuffer\vbox{\typebuffer}}
2510
%D
2511
%D \startbuffer
2512
%D \framed[offset=overlay,frame=off]{\darkred\blackrule}
2513
%D \stopbuffer
2514
%D \hbox{\getbuffer\vbox{\typebuffer}}
2515
%D
2516
%D \startbuffer
2517
%D \framed[offset=overlay,frame=off,bottomframe=off]{\darkred\blackrule}
2518
%D \stopbuffer
2519
%D \hbox{\getbuffer\vbox{\typebuffer}}
2520
%D
2521
%D \startbuffer
2522
%D \framed[offset=overlay,frame=off,bottomframe=on]{\darkred\blackrule}
2523
%D \stopbuffer
2524
%D \hbox{\getbuffer\vbox{\typebuffer}}
2525
%D \stoplinecorrection
2526
%D \egroup
2527 2528
%D \macros
2529
%D {startframedtext, setupframedtexts, defineframedtext}
2530
%D
2531
%D The general framing command we discussed previously, is not entirely suited for
2532
%D what we call framed texts, as for instance used in intermezzo's. The next
2533
%D examples show what we have in mind.
2534
%D
2535
%D \startbuffer[framed-0]
2536
%D \setupframedtexts
2537
%D [frame=off,
2538
%D width=\hsize,
2539
%D background=screen]
2540
%D
2541
%D \startframedtext
2542
%D By default the framed text is centered \dots
2543
%D \stopframedtext
2544
%D
2545
%D \startframedtext[right]
2546
%D \dots\ but we can also align left, middle and right.
2547
%D \stopframedtext
2548
%D \stopbuffer
2549
%D
2550
%D \startbuffer[framed-1]
2551
%D \defineframedtext
2552
%D [Example]
2553
%D [width=6cm,
2554
%D height=5cm]
2555
%D
2556
%D \startExample
2557
%D \typebuffer[framed-1]
2558
%D \stopExample
2559
%D \stopbuffer
2560
%D
2561
%D \startbuffer[framed-2]
2562
%D \defineframedtext
2563
%D [Example]
2564
%D [width=6cm]
2565
%D
2566
%D \startExample
2567
%D \typebuffer[framed-2]
2568
%D \stopExample
2569
%D \stopbuffer
2570
%D
2571
%D \startbuffer[framed-3]
2572
%D \defineframedtext
2573
%D [Example]
2574
%D [height=5cm]
2575
%D
2576
%D \startExample
2577
%D \typebuffer[framed-3]
2578
%D \stopExample
2579
%D \stopbuffer
2580
%D
2581
%D \startbuffer[framed-4]
2582
%D \defineframedtext
2583
%D [Example]
2584
%D [width=fit,height=broad]
2585
%D
2586
%D \Example{a very exciting example}
2587
%D \stopbuffer
2588
%D
2589
%D \bgroup \setuptyping[margin=0pt] \getbuffer[framed-0] \egroup
2590
%D \bgroup \setuptyping[margin=0pt] \getbuffer[framed-1] \egroup
2591
%D \bgroup \setuptyping[margin=0pt] \getbuffer[framed-2] \egroup
2592
%D \bgroup \setuptyping[margin=0pt] \getbuffer[framed-3] \egroup
2593
%D \bgroup \setuptyping[margin=0pt] \getbuffer[framed-4] \egroup
2594
%D
2595
%D Here we can see that we have a predefined framed text class as well as the
2596
%D tools for defining our own. So we have:
2597
%D
2598
%D \showsetup{setupframedtexts}
2599
%D
2600
%D as well as the definition command:
2601
%D
2602
%D \showsetup{defineframedtext}
2603
%D
2604
%D that generates two commands:
2605
%D
2606
%D \showsetup{start<<framedtext>>}
2607
%D \showsetup{<<framedtext>>}
2608
%D
2609
%D The next definition shows the defaults.
2610 2611
\installcorenamespace
{
framedtext
}
2612
\installcorenamespace
{
framedtextlocation
}
2613 2614
\installframedcommandhandler
\??framedtext
{
framedtext
}
\??framedtext
2615 2616
\let
\setupframedtexts\setupframedtext
2617 2618
\setupframedtext
2619
[
\c!width
=
.
7
5
\hsize
,
2620
\c!height
=
\v!fit
,
2621
\c!align
=
\v!yes
,
2622
%\c!top=,
2623
\c!bottom
=
\vfill
,
2624
\c!offset
=
1
em
,
2625
%\c!bodyfont=,
2626
%\c!style=,
2627
%\c!color=,
2628
%\c!left=,
2629
\c!right
=
\hfill
,
2630
\c!before
=
\blank
,
2631
\c!after
=
\blank
,
2632
%\c!inner=,
2633
\c!frame
=
\v!on
,
2634
%\c!topframe=,
2635
%\c!bottomframe=,
2636
%\c!leftframe=,
2637
%\c!rightframe=,
2638
\c!radius
=
.
5
\bodyfontsize
,
2639
\c!corner
=
\v!rectangular
,
2640
%\c!orientation=,
2641
%\c!indenting=,
2642
%\c!foregroundcolor=,
2643
%\c!foregroundstyle=,
2644
%\c!background=,
2645
%\c!backgroundcolor=,
2646
\c!linecorrection
=
\v!on
,
2647
\c!depthcorrection
=
\v!on
,
2648
\c!margin
=
\v!standard
]
2649 2650
\appendtoks
2651
\setuevalue
{
\e!start
\currentframedtext
}{
\pack_framed_text_start
{
\currentframedtext
}}
%
2652
\setuevalue
{
\e!stop
\currentframedtext
}{
\pack_framed_text_stop
}
%
2653
\setuevalue
{
\currentframedtext
}{
\pack_framed_text_direct
{
\currentframedtext
}}
%
2654
\to
\everydefineframedtext
2655 2656
\setvalue
{
\??framedtextlocation\v!left
}{
\letframedtextparameter
\c!left
\relax
2657
\letframedtextparameter
\c!right
\hfill
}
2658 2659
\setvalue
{
\??framedtextlocation\v!right
}{
\letframedtextparameter
\c!left
\hfill
2660
\letframedtextparameter
\c!right
\relax
}
2661 2662
\setvalue
{
\??framedtextlocation\v!middle
}{
\letframedtextparameter
\c!left
\hfill
2663
\letframedtextparameter
\c!right
\hfill
}
2664 2665
\setvalue
{
\??framedtextlocation\v!none
}{
\letframedtextparameter
\c!left
\relax
2666
\letframedtextparameter
\c!right
\relax
2667
\settrue
\c_framed_text_location_none
}
2668 2669
\unexpanded
\def
\pack_framed_text_start
#
1
%
2670
{
\bgroup
2671
\edef
\currentframedtext
{
#
1
}
%
2672
\dodoubleempty
\pack_framed_text_start_indeed
}
2673 2674
\def
\pack_framed_text_start_indeed
[#
1
][#
2
]
%
2675
{
\doifelseassignment
{
#
1
}
2676
{
\pack_framed_text_start_continue
\empty
{
#
1
}}
2677
{
\pack_framed_text_start_continue
{
#
1
}{
#
2
}}}
2678 2679
% todo: sort out first/lastline ht/dp
2680 2681
\def
\pack_framed_text_start_continue
#
1
#
2
%
2682
{
\setupframedtexts
[
\currentframedtext
][#
2
]
%
2683
\doifsomething
{
#
1
}{
\setframedtextparameter
\c!location
{
#
1
}}
% does not listen to #3
2684
\setfalse
\c_framed_text_location_none
2685
\csname
\??framedtextlocation
\framedtextparameter
\c!location
\endcsname
2686
\resetframedtextparameter
\c!location
2687
\pack_framed_text_check
2688
\setbox
\b_framed_normal
\vbox
% \vpack
2689
\startboxedcontent
2690
\hsize
\localhsize
2691
% \insidefloattrue % ? better
2692
\usebodyfontparameter
\framedtextparameter
2693
% \edef\p_framed_text_strut{\letframedtextparameter\c!strut}% to be used
2694
\letframedtextparameter
\c!strut\v!no
2695
\inheritedframedtextframed
\bgroup
2696
\let
\\
=
\endgraf
2697
\edef
\p_framed_text_depthcorrection
{
\framedtextparameter
\c!depthcorrection
}
%
2698
\ifx
\p_framed_text_depthcorrection
\v!on
2699
\pack_framed_text_start_depth_correction
2700
\else
2701
\bgroup
2702
\fi
2703
\vskip
-
\strutdp
% brrr why is this needed ... needs to be sorted out, see testcase 1
2704
\doinhibitblank
2705
\useindentingparameter
\framedtextparameter
2706
\useframedtextstyleandcolor
\c!style\c!color
2707
\framedtextparameter
\c!inner
2708
\ignorespaces
}
2709 2710
% testcase 1:
2711
%
2712
% \showstruts
2713
% \startframedtext[align={normal,tolerant},offset=0pt] \input tufte \stopframedtext
2714
% \startframedtext[align={normal,tolerant},offset=0pt,depthcorrection=off] \input tufte \stopframedtext
2715
% \startframedtext[align={normal,tolerant},offset=0pt,depthcorrection=off] \inframed{x} \stopframedtext
2716
% \framed[align={normal,tolerant},offset=0pt]{\input tufte }
2717 2718
%D The \type {none} option is handy for nested usage, as in the presentation
2719
%D styles, where we don't want interference.
2720 2721
\defineplacement
[
\??framedtext
][
\s!parent
=
\??framedtext
\currentframedtext
]
2722 2723
\unexpanded
\def
\pack_framed_text_stop
% no \baselinecorrection, see faq docs
2724
{
\endgraf
2725
\removelastskip
2726
\ifx
\p_framed_text_depthcorrection
\v!on
2727
\pack_framed_text_stop_depth_correction
2728
\else
2729
\egroup
2730
\fi
2731
\stopboxedcontent
2732
\ifconditional
\c_framed_text_location_none
2733
\egroup
2734
\box
\b_framed_normal
2735
\else
\ifinsidefloat
2736
\egroup
2737
\box
\b_framed_normal
2738
\else
2739
\egroup
2740
\placement
[
\??framedtext
][
\c!depthcorrection
=
\v!off
]
{
\box
\b_framed_normal
}
%
2741
\fi\fi
2742
\egroup
}
2743 2744
%D We define the general (and original) case by just saying:
2745 2746
\def
\pack_framed_text_check
% messy dependency
2747
{
\localhsize
\hsize
2748
\ifinsidefloat
\else
\ifdim
\d_page_sides_vsize
>
\zeropoint
% also possible: \c_page_sides_checks_done>\zeropoint
2749
% \strut % rather clean way to invoke the sidefloat OTR
2750
% \setbox0=\lastbox % and get the widths set, so from now on we
2751
% \setlocalhsize % can have framed texts alongside sidefloats
2752
\checksidefloat
2753
\setlocalhsize
2754
\fi
\fi
}
2755 2756
\def
\pack_framed_text_start_depth_correction
2757
{
\bgroup
2758
\ifhmode
2759
\par
2760
\fi
2761
\ifvmode
2762
\verticalstrut
2763
% we need \nowhitespace in case of setups setting whitespace
2764
% nb, not safe, text vs \vbox as next
2765
\vskip
-
\struttotal
2766
\nowhitespace
2767
\fi
}
% na vskip ! new 20/05/2004, fails with next content being box (\scale{..})
2768 2769
\def
\pack_framed_text_stop_depth_correction
2770
{
\ifhmode
2771
\par
2772
\fi
2773
\ifvmode
2774
\forgetall
2775
\vskip
-
\struttotal
2776
\verticalstrut
2777
\egroup
2778
\forgetall
% brrr too often
2779
\vskip
-
\lineheight
2780
\verticalstrut
2781
\else
2782
\egroup
2783
\fi
}
2784 2785
%D Placement can be ignored:
2786
%D
2787
%D \starttyping
2788
%D \hbox to \hsize \bgroup
2789
%D \startframedtext[none][width=.5\textwidth] \input tufte \stopframedtext
2790
%D \startframedtext[none][width=.5\textwidth] \input zapf \stopframedtext
2791
%D \egroup
2792
%D
2793
%D \hbox to \hsize \bgroup
2794
%D \setupframedtexts[location=none]%
2795
%D \startframedtext[width=.5\textwidth] \input zapf \stopframedtext
2796
%D \startframedtext[width=.5\textwidth] \input tufte \stopframedtext
2797
%D \egroup
2798
%D \stoptyping
2799 2800
%D The simple brace (or group) delimited case is typeset slightly different
2801
%D and is not aligned.
2802 2803
\unexpanded
\def
\pack_framed_text_direct
#
1
%
2804
{
\bgroup
2805
\edef
\currentframedtext
{
#
1
}
%
2806
\dosingleempty
\pack_framed_text_start_direct
}
2807 2808
\def
\pack_framed_text_start_direct
[#
1
]
%
2809
{
\usebodyfontparameter
\framedtextparameter
2810
\iffirstargument
2811
\setupcurrentframedtext
[#
1
]
%
2812
\fi
2813
\edef
\p_framed_text_strut
{
\framedtextparameter
\c!strut
}
%
2814
\letframedtextparameter
\c!strut\v!no
2815
\inheritedframedtextframed
\bgroup
2816
\blank
[
\v!disable
]
%
2817
\let
\\
=
\endgraf
2818
\useframedtextstyleandcolor
\c!style\c!color
2819
\vskip
-
\strutdp
% brrr why is this needed ... needs to be sorted out, see testcase 1
2820
\framedtextparameter
\c!inner
2821
\ifx
\p_framed_text_strut
\v!no
2822
\let
\pack_framed_strut
\relax
2823
\else
2824
\let
\pack_framed_strut
\strut
2825
\fi
2826
\bgroup
2827
\aftergroup
\pack_framed_text_stop_direct
2828
\afterassignment\ignorespaces
2829
\afterassignment
\pack_framed_strut
2830
\let
\next
=
}
2831 2832
\def
\pack_framed_text_stop_direct
2833
{
\removelastskip
2834
\egroup
2835
\egroup
}
2836 2837
\defineframedtext
2838
[
\v!framedtext
]
2839 2840
%D \macros
2841
%D {defineframed}
2842
%D
2843
%D One can also define simple framed texts, using:
2844
%D
2845
%D \showsetup{defineframed}
2846
%D
2847
%D As suggested by Wolfgang we can now use the new \MKIV\ inheritance model instead
2848
%D of passing a combination of arguments. This also also simplified the \type
2849
%D {\setupframed} command. There are certainly more places where such improvements
2850
%D can be made.
2851 2852
\appendtoks
2853
\ifcsname
\??regularframedlevel
\currentframed
\endcsname
2854
% already defined, keeps settings
2855
\else
2856
\expandafter
\newcount
\csname
\??regularframedlevel
\currentframed
\endcsname
2857
\fi
2858
\to
\everypresetframed
2859 2860
\appendtoks
2861
\setuevalue
\currentframed
{
\pack_framed_defined_process
[
\currentframed
]
}
%
2862
\to
\everydefineframed
2863 2864
\newcount
\c_temp_framed_crap
2865 2866
\unexpanded
\def
\pack_framed_defined_process
[#
1
]
% official (not much checking, todo: parent)
2867
{
\bgroup
2868
\ifcsname
\??regularframedlevel
#
1
\endcsname
2869
%\expandafter\let\expandafter\c_pack_framed_temp\csname\??regularframedlevel#1\endcsname
2870
\expandafter\let\expandafter
\c_pack_framed_temp
\lastnamedcs
2871
\else
2872
\let
\c_pack_framed_temp
\c_temp_framed_crap
2873
\fi
2874
\advance
\c_pack_framed_temp
\plusone
2875
\expandafter\def\csname
\??framed
#
1
>
\the
\c_pack_framed_temp
:
\s!parent
\endcsname
{
\??framed
#
1
}
% \inheritlocalframed
2876
\bgroup
2877
\edef
\currentframed
{
#
1
>
\the
\c_pack_framed_temp
}
%
2878
\pack_framed_initialize
2879
\dosingleempty
\pack_framed_defined_process_indeed
}
2880 2881
\def
\pack_framed_defined_process_indeed
[#
1
]
%
2882
{
\iffirstargument
% faster
2883
\setupcurrentframed
[#
1
]
% here !
2884
\fi
2885
\pack_framed_process_indeed
}
2886 2887
\let
\placeframed
\pack_framed_defined_process
% new per 2012/04/23
2888 2889
%D We can do:
2890
%D
2891
%D \starttyping
2892
%D \defineframed[\v!framed]
2893
%D \stoptyping
2894
%D
2895
%D but the existing one is ok as well (less csname messy too).
2896 2897
%D New, for the moment private; let's see when GB finds out about this one and its
2898
%D obscure usage. It's used in:
2899
%D
2900
%D \startbuffer
2901
%D \defineframedtext
2902
%D [tabulateframe]
2903
%D [offset=overlay,
2904
%D backgroundoffset=3pt,
2905
%D background=color,
2906
%D backgroundcolor=green]
2907
%D
2908
%D \setuptabulate
2909
%D [tabulate]
2910
%D [frame=tabulateframe]
2911
%D
2912
%D \setuptables
2913
%D [frame=tabulateframe]
2914
%D
2915
%D \input tufte
2916
%D
2917
%D \starttabulate[|l|l|]
2918
%D \NC test \NC test \NC \NR \NC test \NC test \NC \NR
2919
%D \NC test \NC test \NC \NR \NC test \NC test \NC \NR
2920
%D \stoptabulate
2921
%D
2922
%D \input tufte
2923
%D
2924
%D \starttable[|l|l|]
2925
%D \NC test \NC test \NC \AR \NC test \NC test \NC \AR
2926
%D \NC test \NC test \NC \AR \NC test \NC test \NC \AR
2927
%D \stoptable
2928
%D \stopbuffer
2929
%D
2930
%D \typebuffer
2931 2932
\installcorenamespace
{
framedcontent
}
2933 2934
\installframedcommandhandler
\??framedcontent
{
framedcontent
}
\??framedcontent
2935 2936
\setupframedcontent
2937
[
\c!leftoffset
=
\zeropoint
,
2938
%\c!rightoffset=\framedcontentparameter\c!leftoffset,
2939
\c!rightoffset
=
\scratchleftoffset
,
2940
\c!topoffset
=
\zeropoint
,
2941
%\c!bottomoffset=\framedcontentparameter\c!topoffset,
2942
\c!bottomoffset
=
\scratchtopoffset
,
2943
\c!strut
=
\v!no
,
2944
%\c!linecorrection=\v!no,
2945
%\c!left=,
2946
%\c!right=,
2947
%\c!width=\v!fit,
2948
\c!offset
=
\v!overlay
]
2949 2950
\unexpanded
\def
\startframedcontent
2951
{
\dosingleempty
\pack_framed_start_content
}
2952 2953
\def
\pack_framed_start_content
[#
1
]
%
2954
{
\bgroup
2955
\edef
\currentframedcontent
{
#
1
}
%
2956
\ifx
\currentframedcontent
\v!off
2957
\let
\stopframedcontent
\egroup
2958
\else
2959
\checkframedcontentparent
2960
\let
\stopframedcontent
\pack_framed_stop_content_indeed
2961
\expandafter
\pack_framed_start_content_indeed
2962
\fi
}
2963 2964
\def
\pack_framed_start_content_indeed
2965
{
\setbox
\b_framed_normal
\hpack
\bgroup
2966
\setlocalhsize
2967
\hsize
\localhsize
2968
\scratchleftoffset
\framedcontentparameter
\c!leftoffset
\relax
2969
\scratchrightoffset
\framedcontentparameter
\c!rightoffset
\relax
2970
\scratchtopoffset
\framedcontentparameter
\c!topoffset
\relax
2971
\scratchbottomoffset
\framedcontentparameter
\c!bottomoffset
\relax
2972
\advance\hsize\dimexpr
-
\scratchleftoffset
-
\scratchrightoffset
\relax
2973
\advance\vsize\dimexpr
-
\scratchtopoffset
-
\scratchbottomoffset
\relax
2974
\kern
\scratchleftoffset
2975
\vpack
\bgroup
2976
\vskip
\scratchtopoffset
2977
\vbox
\bgroup
2978
\forgetall
2979
\blank
[
\v!disable
]
}
2980 2981
\def
\pack_framed_stop_content_indeed
2982
{
\removelastskip
2983
\egroup
2984
\vskip
\scratchbottomoffset
2985
\egroup
2986
\kern
\scratchrightoffset
2987
\egroup
2988
\doif
{
\framedcontentparameter
\c!width
}
\v!fit
2989
{
\letframedcontentparameter
\c!width\v!fixed
}
% no shapebox
2990
\ifinsidefloat
2991
\donefalse
2992
\else
2993
\doifelse
{
\framedcontentparameter
\c!linecorrection
}
\v!yes
\donetrue\donefalse
2994
\fi
2995
% plaats ?
2996
\ifdone
\startlinecorrection
\fi
2997
\framedcontentparameter
\c!left
% new
2998
\inheritedframedcontentframed
{
\box
\b_framed_normal
}
% hm
2999
\framedcontentparameter
\c!right
% new
3000
\ifdone
\stoplinecorrection
\fi
3001
\egroup
}
3002 3003
% A shared setting.
3004 3005
\setuplinewidth
3006
[
\v!medium
]
3007 3008
%D A Goodie:
3009 3010
\def
\v!unframed
{
unframed
}
3011 3012
\defineframed
3013
[
\v!unframed
]
3014
[
\c!frame
=
\v!off
,
3015
\c!rulethickness
=
\zeropoint
,
3016
\c!foregroundstyle
=
\framedparameter
\c!style
,
3017
\c!foregroundcolor
=
\framedparameter
\c!color
]
3018 3019
%D Bonus (as defined in \type {pack-rul.lua}):
3020
%D
3021
%D \starttyping
3022
%D \setbox\scratchbox\vbox{a\par aa\par aaa\par}
3023
%D \the\dimexpr\themaxboxwidth\scratchbox\relax
3024
%D \stoptyping
3025 3026
\let
\themaxboxwidth
\clf_themaxboxwidth
3027 3028
%D New: slow but ok for most cases:
3029 3030
\unexpanded
\def
\doifelseframed
#
1
%
3031
{
\ifcase
\numexpr
\zerocount
3032
\immediateassignment\edef
\tempstring
{
#
1
\c!frame
}
\ifx
\tempstring
\v!on
+
\plusone
\fi
3033
\immediateassignment\edef
\tempstring
{
#
1
\c!topframe
}
\ifx
\tempstring
\v!on
+
\plusone
\fi
3034
\immediateassignment\edef
\tempstring
{
#
1
\c!bottomframe
}
\ifx
\tempstring
\v!on
+
\plusone
\fi
3035
\immediateassignment\edef
\tempstring
{
#
1
\c!leftframe
}
\ifx
\tempstring
\v!on
+
\plusone
\fi
3036
\immediateassignment\edef
\tempstring
{
#
1
\c!rightframe
}
\ifx
\tempstring
\v!on
+
\plusone
\fi
3037
\immediateassignment\edef
\tempstring
{
#
1
\c!background
}
\ifx
\tempstring
\empty
\else
+
\plusone
\fi
3038
\relax\expandafter
\secondoftwoarguments
\else\expandafter
\firstoftwoarguments
\fi
}
3039 3040
\protect
\endinput
3041