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