1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
|
.\" groff -ms -msboxes -Tpdf
.nr LL 17c
.nr PO 2c
.nr PS 11
.nr VS 13
.nr PI 3.5n
.nr HM 2c
.nr FM 2c
.nr QI 7n
.ss 12 0
.ND March 2021
.EH '%''March 2021'
.EF ''''
.OH 'Using PDF boxes with \f[I]groff\f[] and the \f[I]ms\f[] macros''%'
.OF ''''
.\" Define a quotation macro.
.de Qq
. nop \[lq]\\$1\[rq]\\$2
..
.\" Define a macro for code literals; use bold and disable hyphenation.
.de Lt
. ft B
. nh
. nop \&\\$1\c
. hy \\n[HY]
. ft
. nop \&\\$2
..
.ds FAM H
.TL
Using PDF boxes with
.BI groff
and the
.BI ms
macros
.AU
Deri James
.AI
deri@chuzzlewit.myzen.co.uk
.LP
An extension in version 1.23.0 of
.I gropdf ,
the PDF output driver for the
.I groff
document formatting system,
allows coloured rectangles to be placed beneath any output created by
.I groff .
The extension can be accessed via a device control escape sequence
.Lt "\[rs]X\[aq]pdf: background" \~.\|.\|.\|\c
.Lt \[aq]
or a convenience macro
.Lt pdfbackground
supporting the same parameters.
.QS
.BOXSTART SHADED cornsilk OUTLINED brown INDENT 2n WEIGHT 1p
\M[floralwhite]\c
.pdfbackground pagefill
\M[]\c
.B
\[rs]X\[aq]pdf: background
.BI
cmd left top right bottom weight\[aq]
.br
.Lt .pdfbackground
.BI
cmd left top right bottom weight
.LP
each produce a background rectangle on the page, where
.IP \f[I]cmd 8n \" indent enough to fit "bottom" tag
is the command, which can be any of
.Qq page|fill|box
in combination.
Thus,
.Qq pagefill
would draw a rectangle which covers the whole current page size (in
which case the rest of the parameters can be omitted because the box
dimensions are taken from the current media size).
.Qq boxfill ,
on the other hand, requires the given dimensions to place the box.
Including
.Qq fill
in the command will paint the rectangle with the current fill colour (as
with
.Lt \[rs]M[] )
and including
.Qq box
will give the rectangle a border in the current stroke colour
(as with
.Lt \[rs]m[] ).
.sp \n[PD]u
.I cmd
may also be
.Qq off
on its own, which will terminate drawing the current box.
If you have specified a page colour with
.Qq pagefill ,
it is always the first box in the stack, and if you specify it again, it
will replace the first entry.
Be aware that the
.Qq pagefill
box renders the page opaque, so tools that
.Qq watermark
PDF pages are unlikely to be successful.
To return the background to transparent, issue an
.Qq off
command with no other boxes open.
.sp \n[PD]u
Finally,
.I cmd
may be
.Qq footnote
followed by a new value for
.I bottom ,
which will be used for all open boxes on the current page.
This is to allow room for footnote areas that grow while a page is
processed (to accommodate multiple footnotes,
for instance).\m[red]\**\m[]\" FOOTNOTE
.FS
If the value is negative, it is used as an offset from the bottom of the
page.
.FE
.nr oldPD \n[PD]
.nr PD 0
.IP \f[I]left
.IP \f[I]top
.IP \f[I]right
.IP \f[I]bottom
.nr PD \n[oldPD]
are the coordinates of the box.
The
.I top
and
.I bottom
coordinates are the minimum and maximum for the box, since the actual
start of the box is
.I groff 's
drawing position when you issue the command, and the bottom of the box
is the point where you turn the box
.Qq off .
The top and bottom coordinates are used only if the box drawing extends
onto the next page; ordinarily, they would be set to the header and
footer margins.
.IP \f[I]weight
provides the line width for the border if
.Qq box
is included in the command.
.BOXSTOP
.QE
For an even more convenient interface, include
.Lt \-msboxes
on the
.I groff
command line; the
.I sboxes
package defines the macros
.Lt BOXSTART
and
.Lt BOXSTOP .
.QS
.BOXSTART SHADED cornsilk OUTLINED brown INDENT 2n WEIGHT 1p
.BOXSTART SHADED cornsilk3 INDENT 2p
.Lt .BOXSTART
.Lt SHADED
.I colour
.Lt OUTLINED
.I colour
.Lt INDENT
.I size
.Lt WEIGHT
.I size
.BOXSTOP
.LP
begins a box,
where the argument after
.Lt SHADED
gives the fill colour and that after
.Lt OUTLINED
the border colour.
Omit the former to get a borderless filled box and the latter for a
border with no fill.
The specified
.Lt WEIGHT
is used if the box is
.Lt OUTLINED .
.LP
.Lt INDENT
precedes a value which leaves a gap between the border and the contents
inside the box.
.LP
Each
.I colour
must be a defined
.I groff
colour name,
and each
.I size
a valid
.I groff
numeric expression.
The keyword/value pairs can be specified in any order.
.BOXSTOP
.QE
Boxes can be stacked, so you can start a box within another box; usually
the later boxes would be smaller than the containing box, but this is
not enforced.
When using
.Lt BOXSTART ,
the left position is the current indent minus the
.Lt INDENT
in the command,
and the right position is the left position (calculated above) plus the
current line length and twice the indent.
The synopsis of
.Lt BOXSTART
above itself uses a
.Lt BOXSTART
call without borders and with a
.Lt 2p
(two point) indent.
.QS
.BOXSTART SHADED cornsilk OUTLINED brown INDENT 2n WEIGHT 1p
.BOXSTART SHADED cornsilk3 INDENT 2p
.Lt .BOXSTOP
.BOXSTOP
.LP
takes no parameters.
It closes the most recently started box at the current vertical position
after adding its
.Lt INDENT
spacing.
.BOXSTOP
.QE
Your
.I groff
documents can conditionally exercise the
.I sboxes
macros.
The register
.Lt GSBOX
is defined if the package is loaded, and interpolates a true value if
the
.Lt pdf
output device is in use.
.LP
.I sboxes
furthermore hooks into the
.I "groff ms"
package to receive notifications when footnotes are growing, so that it
can close boxes on a page before footnotes are printed.
When that condition obtains,
.I sboxes
will close open boxes two points\**
.FS
This amount probably will not match the box's
.Lt INDENT .
.FE
above the footnote separator and re-open them on the next page.
.LP
This document was produced using the following code.
.ds FAM C
.nr PS 11
.nr VS 13
.LP
.BOXSTART SHADED white OUTLINED brown INDENT 2n WEIGHT 1p
.nf
\# REPLACEME
.BOXSTOP
.\" Local Variables:
.\" mode: nroff
.\" fill-column: 72
.\" End:
.\" vim: set filetype=groff textwidth=72:
|