1
2
3\environment detailsenvironment
4
5\startcomponent detailstextbackgrounds
6
7\start \setuphead [chapter] [after=] \startchapter[title={Backgrounds behind text}]
8
9\startbuffer[setupa]
10\definetextbackground
11 [intro]
12 [backgroundcolor=infogray,
13 backgroundoffset=.25cm,
14 frame=off,
15 location=paragraph,
16 color=red]
17\stopbuffer
18
19\startbuffer[setupb]
20\definetextbackground
21 [subintro]
22 [backgroundcolor=textgray,
23 backgroundoffset=0pt,
24 frame=off,
25 location=text,
26 color=blue]
27\stopbuffer
28
29\startbuffer[demoa]
30\starttextbackground[intro]
31A rather common way to draw attention to a passage, is to add a
32background. In this chapter we will therefore discuss how to enhance your
33document with \starttextbackground [subintro] those colorful areas that either
34or not follow the shape of your paragraph. \stoptextbackground\ Be
35warned: this chapter has so many backgrounds that you might start to
36dislike them.
37\stoptextbackground
38\stopbuffer
39
40\getbuffer[setupa,setupb,demoa]
41
42\blank
43
44In the previous paragraph we demonstrated two important features of the
45background handler: you can nest backgrounds and backgrounds can be tight or
46wide. Features like this will often be used in combination with others, like
47special section headers. The raw coding of the previous paragraph is therefore
48not representative.
49
50\typebuffer[demoa]
51
52The outer background commands is defined as follows:
53
54\typebuffer[setupa]
55
56Here, the \type {paragraph} option ensures that the background covers the width
57of the body text. The inner background is defined in a similar way, but this time
58we choose \type {text} location.
59
60\typebuffer[setupb]
61
62In this document we use protruding characters (hanging punctuation) so weve
63chosen a rather large offset, one that also matches the rest of the page design.
64
65Those who are familiar with the way \TEX\ works will probably see what problems
66can occur with backgrounds like this. What happens for instance when we cross
67page boundaries, and how will more complicated paragraph shapes be handled?
68
69The current implementation tries to handle page breaks and paragraph shapes as
70good as possible. This works well in normal onecolumn mode as well as in
71columns.
72
73\startbuffer[setupc]
74\definetextbackground [A] [backgroundcolor=infogray]
75\definetextbackground [B] [backgroundcolor=textgray]
76
77\setuptextbackground
78 [backgroundoffset=0pt,
79 offset=0pt,
80 frame=off,
81 location=text]
82\stopbuffer
83
84\getbuffer[setupc]
85
86\startbuffer[demob]
87\placefigure[left]{}{\externalfigure[detcow][width=2cm]}
88
89\starttextbackground [A]
90 In this example, the paragraph shape is determined by the graphic placed
91 left of the text.
92 \starttextbackground [B]
93 This feature is implemented using the \type {\hangindent} and \type
94 {\hangafter} primitives, which means that we need to keep track of
95 their state. In addition, we need to handle the indentation directives
96 \type {\leftskip}, \type {\rightskip} and \type {\parindent}.
97 \stoptextbackground\
98 Because backgrounds end up in a different background overlay, nesting
99 them is no problem, and it is even possible to move them to the front
100 and back, as we will demonstrate later on. While the mechanism discussed
101 here will always be improved when we find border cases, the fundaments
102 it is built upon are quite stable.
103\stoptextbackground
104\stopbuffer
105
106{\setupalign[nothanging]\getbuffer[demob]\par}
107
108\typebuffer[demob]
109
110The backgrounds were defined as:
111
112\typebuffer[setupc]
113
114\startbuffer[setupd]
115\setuptextbackground [B] [backgroundcolor=darkgray,level=2]
116\stopbuffer
117
118{\setupalign[nothanging]\getbuffer[setupd,demob]\par}
119
120This time we moved the inner background a few levels up. By default they reside
121at \type {level=1}. This way, by using a non transparent color, we can hide
122information.
123
124\typebuffer[setupd]
125
126Unless you mess around too much with boxes, backgrounds work as expected in most
127situations. According to the MerriamWebster on the authors laptop:
128
129\startbuffer
130\starttabulate[lpl]
131\NC background \NC \starttextbackground [A] the part of a
132 painting representing what lies behind objects is the
133 \starttextbackground [B] foreground \stoptextbackground
134 \stoptextbackground \NC one \NC \NR
135\TB [halfline]
136\NC foreground \NC \starttextbackground [A] the part of a
137 scene or representation that is nearest to and in front
138 of the \starttextbackground [B] spectator
139 \stoptextbackground \stoptextbackground \NC two \NC \NR
140\TB [halfline]
141\NC spectator \NC \starttextbackground [A] one who looks
142 on or watches \stoptextbackground \NC three \NC \NR
143\stoptabulate
144\stopbuffer
145
146\getbuffer
147
148This is coded similar to normal running text. A table like this is in a way still
149part of the text flow. As floating body (see \in {table} [tab:back]) it can
150virtually end up everywhere. We add a frame to make clear where the boundaries are.
151
152\start
153
154 \setupfloat
155 [table]
156 [frame=on,framecolor=red,rulethickness=1pt]
157
158 \placetable
159 [here] [tab:back]
160 {} {\hsize.75\textwidth\getbuffer}
161
162 \definefloat
163 [mytable]
164 [table]
165
166 \setupfloat
167 [mytable]
168 [leftmargindistance=\innermargintotal]
169
170 \placemytable
171 [left,high,low]
172 [tab:backm]
173 {}
174 {\hsize.5\textwidth\getbuffer}
175
176 Keeping track of the state of a paragraph in a table in combination with
177 background is not entirely trivial. The current implementation evolved from
178 less clever ones and, unless you start doing complicated box manipulations
179 with the float content, works quite well. One reason why we made backgrounds
180 work in tables (and especially floating tables) is that is was needed for
181 typesetting books for primary and secundary education. In there, we want to
182 be able to hide the answers that students are supposed to fill in.
183
184 \flushsidefloats
185
186\stop
187
188In \in {figure} [fig:columns:1] you can see an advanced example of backgrounds
189running over columns. If you look carefully, you will notice that the background
190depends on the kind of background at hand:
191
192\startitemize[n,packed]
193\item the text starts and flows on
194\item the text flows on (or stands alone)
195\item the text flows on and ends
196\stopitemize
197
198This information is available when you want to draw your own backgrounds. Here
199the graphic was defined as follows:
200
201\startplacefigure [reference=fig:columns:1]
202 \startcombination[4*1]
203 {\externalfigure[back4.pdf][page=1,width=\distributedhsize\textwidth\emwidth4]}{Page 1}
204 {\externalfigure[back4.pdf][page=2,width=\distributedhsize\textwidth\emwidth4]}{Page 2}
205 {\externalfigure[back4.pdf][page=3,width=\distributedhsize\textwidth\emwidth4]}{Page 3}
206 {\externalfigure[back4.pdf][page=4,width=\distributedhsize\textwidth\emwidth4]}{Page 4}
207 \stopcombination
208\stopplacefigure
209
210\starttyping
211\startuseMPgraphic{mpos:par:color}
212 for i=1 upto nofmultipars :
213 fill multipars[i] withcolor
214 if multikind[i]="single" : "darkgray" ;
215 elseif multikind[i]="first" : "red" ;
216 elseif multikind[i]="middle" : "green" ;
217 elseif multikind[i]="last" : "blue" ;
218 else : "black" ;
219 fi ;
220 endfor ;
221\stopuseMPgraphic
222\stoptyping
223
224This graphic is hooked into the background setup by setting the \type {mp}
225variable.
226
227\starttyping
228\definetextbackground
229 [shade]
230 [location=paragraph,
231 mp=mpos:par:color,
232 before=\blank,
233 after=\blank]
234\stoptyping
235
236A variant is the following. This time we use a shade:
237
238\starttyping
239\startuseMPgraphic{mpos:par:columnset:shade}
240 numeric h ;
241 for i=1 upto nofmultipars :
242 h := bbheight(p) ;
243 if multikind[i] = "single" :
244 fill multipars[i] topenlarged -.5h
245 withshademethod "linear"
246 withshadedirection shadedup
247 withcolor boxfillcolor shadedinto .8white ;
248 fill multipars[i] bottomenlarged -.5h
249 withshademethod "linear"
250 withshadedirection shadedup
251 withcolor .8white shadedinto boxfillcolor ;
252 elseif multikind[i] = "first" :
253 fill multipars[i]
254 withshademethod "linear"
255 withshadedirection shadedup
256 withcolor boxfillcolor shadedinto .8white ;
257 elseif multikind[i] = "middle" :
258 fill multipars[i] topenlarged -.5h
259 withshademethod "linear"
260 withshadedirection shadedup
261 withcolor boxfillcolor shadedinto .8white ;
262 fill multipars[i] bottomenlarged -.5h
263 withshademethod "linear"
264 withshadedirection shadedup
265 withcolor .8white shadedinto boxfillcolor ;
266 elseif multikind[i] = "last" :
267 fill multipars[i]
268 withshademethod "linear"
269 withshadedirection shadedup
270 withcolor .8white shadedinto boxfillcolor ;
271 fi ;
272 endfor ;
273\stopuseMPgraphic
274\stoptyping
275
276When we hook it into the background we get \in {figure} [fig:columns:2] as result:
277
278\starttyping
279\definetextbackground
280 [shade]
281 [location=paragraph,
282 backgroundcolor=shadecolor,
283 mp=mpos:par:columnset:shade,
284 before=\blank,
285 after=\blank]
286\stoptyping
287
288\startplacefigure [reference=fig:columns:2]
289 \startcombination[4*1]
290 {\externalfigure[back5.pdf][page=1,width=\distributedhsize\textwidth\emwidth4]}{Page 1}
291 {\externalfigure[back5.pdf][page=2,width=\distributedhsize\textwidth\emwidth4]}{Page 2}
292 {\externalfigure[back5.pdf][page=3,width=\distributedhsize\textwidth\emwidth4]}{Page 3}
293 {\externalfigure[back5.pdf][page=4,width=\distributedhsize\textwidth\emwidth4]}{Page 4}
294 \stopcombination
295\stopplacefigure
296
297The complexity of the backgrounds mechanism is partly due to the fact that we
298want to use arbitrary \METAPOST\ code to render the background. For instance, we
299want to have a proper shape so that not only the filled shape but also the drawn
300shape comes out right. You can compare this to a glyph in a font: when rendered
301filled the outline can be anything as it will not be drawn but when we use the
302outline we can run into overlaps and such. Where glyphs can use the oddeven
303filling methods, background can only use that for simple cases.
304
305When a background is rectangular its all quite easy but as soon as some holes
306occur we need to do more work. Holes can be the result of a image placed next to
307the running text, or an image flushed at a page break or in the middle of a
308background. Paragraph shapes are another example. Backgrounds can cross page
309boundaries too. Yet another property is nesting and in such cases the shape is
310a bit more complex as we cross lines partially.
311
312In \MKII\ the background mechanism already was quite useable but it had some
313limitations. Calculating the background was mostly delegated to \METAPOST\ which
314is reasonable. In \MKIV\ some work is delegated to \LUA\ instead but that doesnt
315mean that the code is cleaner or easier to understand. So, to summarize, there
316are several cases that we need to take into account, like:
317
318\startitemize
319 \startitem
320 A background can run behind a paragraph in which case the start is
321 leftmost and end rightmost. In this case inserts (like floats) have to be
322 dealt with after the shape has been calculated.
323 \stopitem
324 \startitem
325 A background can be inline (the \type {text} location variant) in
326 which case we need to follow the paragraph shape, if set. In that case we
327 have a mix of calculating the background shape and afterwards
328 compensating for inserts.
329 \stopitem
330 \startitem
331 A third case is tabulation and tables where we have dedicated regions to
332 deal with. When these float we need to make sure that the backgrounds are
333 adapted to the where they end up.
334 \stopitem
335 \startitem
336 Yet another case is in columns, where we hape multiple regions to deal
337 with.
338 \stopitem
339 \startitem
340 As mentioned, floats need special treatment and they can be part of the
341 page flow but also end up left or right of the text (either or not
342 shifted) but also in the margins, edges, back or cutspace. Their
343 placement influences the way backgrounds are calculated so additional
344 information needs to travel with them.
345 \stopitem
346
347\stopitemize
348
349We distinguish between a paragraph background, which runs between the left and right skip
350areas and a text background which follows a shape. In \in {figure} [fig:columns:3] we see a
351test case with several such shapes.
352
353\startplacefigure [reference=fig:columns:3]
354 \startcombination[4*3]
355 {\externalfigure[back2.pdf][page=1, width=\distributedhsize\textwidth\emwidth4]}{Page 1}
356 {\externalfigure[back2.pdf][page=2, width=\distributedhsize\textwidth\emwidth4]}{Page 2}
357 {\externalfigure[back2.pdf][page=3, width=\distributedhsize\textwidth\emwidth4]}{Page 3}
358 {\externalfigure[back2.pdf][page=4, width=\distributedhsize\textwidth\emwidth4]}{Page 4}
359 {\externalfigure[back2.pdf][page=5, width=\distributedhsize\textwidth\emwidth4]}{Page 5}
360 {\externalfigure[back2.pdf][page=6, width=\distributedhsize\textwidth\emwidth4]}{Page 6}
361 {\externalfigure[back2.pdf][page=7, width=\distributedhsize\textwidth\emwidth4]}{Page 7}
362 {\externalfigure[back2.pdf][page=8, width=\distributedhsize\textwidth\emwidth4]}{Page 8}
363 {\externalfigure[back2.pdf][page=9, width=\distributedhsize\textwidth\emwidth4]}{Page 9}
364 {\externalfigure[back2.pdf][page=10,width=\distributedhsize\textwidth\emwidth4]}{Page 10}
365 {\externalfigure[back2.pdf][page=11,width=\distributedhsize\textwidth\emwidth4]}{Page 11}
366 {\externalfigure[back2.pdf][page=12,width=\distributedhsize\textwidth\emwidth4]}{Page 12}
367 \stopcombination
368\stopplacefigure
369
370In the case of side floats the following cases occur. Of course multiple such
371cases can follow each order so in practice we have to deal with an accumulation.
372
373\startlinecorrection[blank]
374\startMPcode
375 linejoin := linecap := butt ;
376
377 numeric u ; u := 1mm ;
378 numeric lw ; lw := u2 ;
379
380 pickup pencircle scaled 2lw ;
381
382 def example (expr n) (text t) (text l) =
383 path b ; b := boundingbox image (
384 for i=t : draw ( 0u,i2u) -- (20u,i2u) ; endfor ;
385 for i=l : draw ( 0u,i2u) -- (20u,i2u) ; endfor ;
386 ) ;
387 picture p ; p := image (
388 for i=t : draw ( 0u,i2u) -- (20u,i2u) ; endfor ;
389 for i=l : draw (11u,i2u) -- (20u,i2u) ; endfor ;
390 ) ;
391 setbounds p to b ;
392 path q ; q := unitsquare xysized(10u,10u) shifted (0,4u) ;
393 draw image (
394 fill boundingbox p leftenlarged lw rightenlarged lw withcolor "blue" ;
395 draw p withcolor .5white ;
396 fill q withcolor "red" ;
397 draw textext("\bf " & decimal n) shifted (center q) withcolor white ;
398 ) shifted ((n-1)30u,0) ;
399 enddef ;
400
401 example (1) (1) (2,3,4) ;
402 example (2) (1,8) (2,3,4,5,6,7) ;
403 example (3) (8) (5,6,7) ;
404 example (4) () (3,4,5,6) ;
405
406 currentpicture := currentpicture ysized(3LineHeight StrutDepth) ;
407
408\stopMPcode
409\stoplinecorrection
410
411As often in \TEX\ coming up with a solution is not a the problem but interference
412is. You can cook up a solution for one case that fails in another. Backgrounds
413fall into this category, as do side floats. In the next pages we will demonstrate
414a few cases. In practice you can probably always come up with something that
415works out well, but in an automated workflow (like unattended \XML\ to \PDF\
416conversion) you can best play safe. We show some examples on the next pages.
417
418\blank
419
420\definetextbackground
421 [demobg]
422 [backgroundcolor=blue,
423 color=white,
424 frame=off,
425 location=paragraph]
426
427\setupfloatcaption
428 [color=black]
429
430\definesimulatewords
431 [demo]
432 [n=50,
433 m=\simulatewordsparameter{n},
434 min=1,
435 max=5,
436 color=text,
437 line=yes,
438 random=100]
439
440\startbuffer
441\placefigure
442 [left]
443 {case 1}
444 {\blackrule[width=12cm,height=1cm,color=red]}
445\simulatewords[demo][n=10]
446\starttextbackground[demobg]
447 \simulatewords[demo][n=30]
448\stoptextbackground
449\flushsidefloats
450
451\blank
452
453\starttextbackground[demobg]
454 \simulatewords[demo][n=40]
455 \placefigure
456 [left]
457 {case 2}
458 {\blackrule[width=12cm,height=1cm,color=red]}
459 \simulatewords[demo][n=40]
460\stoptextbackground
461\flushsidefloats
462
463\blank
464
465\placefigure
466 [left]
467 {case 3}
468 {\blackrule[width=4cm,height=15mm,color=red]}
469\starttextbackground[demobg]
470 \simulatewords[demo][n=40]
471\stoptextbackground
472\simulatewords[demo][n=40]
473\flushsidefloats
474
475\blank
476
477\simulatewords[demo][n=35]
478\placefigure
479 [left]
480 {case 4}
481 {\blackrule[width=4cm,height=1cm,color=red]}
482\simulatewords[demo][n=20]
483\starttextbackground[demobg]
484 \simulatewords[demo][n=25]
485\stoptextbackground
486\simulatewords[demo][n=40]
487\flushsidefloats
488
489\blank
490
491\stopbuffer
492
493\start \setupwhitespace[none] \getbuffer \stop \blank
494
495The previous examples were typeset with:
496
497\typebuffer
498
499Regular (page flow) floats are a different story. Here we have the problem that a
500float might be postpones because there is no room on the current page and they
501are moved forward (which is why theyre called float). Again we show some
502examples.
503
504
505
506\startbuffer[sample]
507One problem introduced by the internet is that one can view music online. Well,
508its actually not really a problem as it is fun to do, but it does interfere with
509development of code: one can enter distraction mode quite easily.
510\stopbuffer
511
512\startbuffer
513\starttextbackground[demobg]
514 \par \getbuffer[sample] \par
515 \placefigure{}{\blackrule[width=4cm,height=1cm,color=red]}
516 \par \getbuffer[sample] \par
517 \placefigure{}{\blackrule[width=4cm,height=3cm,color=red]}
518 \par \getbuffer[sample] \par
519 \placefigure{}{\blackrule[width=4cm,height=2cm,color=red]}
520 \par \getbuffer[sample] \par
521\stoptextbackground
522\stopbuffer
523
524\blank \getbuffer \blank
525
526The input is:
527
528\typebuffer
529
530A combination of both background avoiding mechanisms is shown on the next page
531(we flush a few more grapohics so that we cross a page boundary):
532
533
534
535\startbuffer
536\starttextbackground[demobg]
537 \placefigure{}{\blackrule[width=4cm,height=2cm,color=red]}
538 \par \input ward \par
539 \placefigure[left]{}{\blackrule[width=4cm,height=2cm,color=red]}
540 \par \input ward \par
541 \placefigure{}{\blackrule[width=4cm,height=2cm,color=red]}
542 \placefigure{}{\blackrule[width=4cm,height=2cm,color=red]}
543 \placefigure{}{\blackrule[width=4cm,height=2cm,color=red]}
544 \placefigure{}{\blackrule[width=4cm,height=2cm,color=red]}
545 \placefigure{}{\blackrule[width=4cm,height=2cm,color=red]}
546 \placefigure{}{\blackrule[width=4cm,height=2cm,color=red]}
547 \par \input ward \par
548 \placefigure{}{\blackrule[width=4cm,height=2cm,color=red]}
549 \par \input ward \par
550\stoptextbackground
551\stopbuffer
552
553\blank \getbuffer \blank
554
555This is the result from:
556
557\typebuffer
558
559You can control the interaction between backgrounds and floars with the \type
560{freeregion} parameter.
561
562\startbuffer
563\starttextbackground[demobg]
564 \simulatewords[demo][n=40]
565 \startplacefigure
566 [location=left,
567 title={free}]
568 \blackrule[width=12cm,height=1cm,color=red]
569 \stopplacefigure
570 \simulatewords[demo][n=40]
571 \startplacefigure
572 [location=left,
573 title={nonfree},
574 freeregion=no,
575 color=textcolor]
576 \blackrule[width=12cm,height=1cm,color=red]
577 \stopplacefigure
578 \simulatewords[demo][n=40]
579 \startplacefigure
580 [location=here,
581 title={free}]
582 \blackrule[width=12cm,height=1cm,color=red]
583 \stopplacefigure
584 \simulatewords[demo][n=40]
585 \startplacefigure
586 [location=here,
587 title={nonfree},
588 freeregion=no,
589 color=textcolor]
590 \blackrule[width=12cm,height=1cm,color=red]
591 \stopplacefigure
592 \simulatewords[demo][n=40]
593\stoptextbackground
594\stopbuffer
595
596\typebuffer
597
598The next pages show the result, first with some tracing enabled sop that you
599can see what gets freed. This visual effect is enabled with:
600
601\starttyping
602\enabletrackers[floats.freeregion]
603\stoptyping
604
605We now move to the next page.
606
607\page
608 \getbuffer
609\page
610 \enabletrackers[floats.freeregion]
611 \getbuffer
612 \disabletrackers[floats.freeregion]
613\page
614
615We have some control over side float placement and of course that will interfere
616with backgrounds. Say that we have this:
617
618\startbuffer
619\definefloat
620 [demofigureleft]
621 [figure]
622 [default=left,
623 margin=1cm,
624 leftmargindistance=2cm,
625 rightmargindistance=2cm]
626
627\definefloat
628 [demofigureright]
629 [demofigureleft]
630 [default=right]
631\stopbuffer
632
633\typebuffer \getbuffer
634
635Combined with the following we get the result on the next pages.
636
637\startbuffer
638\starttextbackground[demobg]
639 \startplacefloat[figure][location=left]
640 \blackrule[width=12cm,height=1cm,color=red]
641 \stopplacefigure
642 \simulatewords[demo][n=40]
643 \blank
644 \startplacefloat[figure][location=right]
645 \blackrule[width=12cm,height=1cm,color=red]
646 \stopplacefigure
647 \simulatewords[demo][n=40]
648 \blank
649 \startplacefloat[demofigureleft]
650 \blackrule[width=10cm,height=1cm,color=red]
651 \stopplacefigure
652 \simulatewords[demo][n=40]
653 \blank
654 \startplacefloat[demofigureright]
655 \blackrule[width=10cm,height=1cm,color=red]
656 \stopplacefigure
657 \simulatewords[demo][n=40]
658 \startplacefloat[figure]
659 \blackrule[width=12cm,height=1cm,color=red]
660 \stopplacefigure
661 \simulatewords[demo][n=40]
662\stoptextbackground
663\stopbuffer
664
665\typebuffer
666
667\page
668
669\start
670 \enabletrackers[floats.freeregion]
671 \setupwhitespace[none]
672 \getbuffer
673 \disabletrackers[floats.freeregion]
674\stop
675
676\page
677
678\start
679 \setupwhitespace[none]
680 \getbuffer
681\stop
682
683\page
684
685\stop \stopchapter
686
687\stopcomponent
688 |