Displaying page layout variables

Kent McPherson a.o.^{∗}

1995/11/23

1 Introduction

This L^{A}TEX 2ε package is a reimplementation of layout.sty by Kent McPherson. It defines the command \layout which produces an overview of the layout of the current document. The command \layout* recomputes the values it uses to produce the overview.

2 The implementation

This package prints a figure to illustrate the layout that is implemented by the document class. In the figure several words appear. They are stored in control sequences to be able to select a different language.

1 ⟨∗package⟩

 2 \DeclareOption{dutch}{%
 3 \def\Headertext{Kopregel}
 4 \def\Bodytext{Broodtekst}
 5 \def\Footertext{Voetregel}
 6 \def\MarginNotestext{Marge\\Notities}
 7 \def\oneinchtext{een inch}
 8 \def\notshown{niet getoond}
 9 }
10 \DeclareOption{english}{%
11 \def\Headertext{Header}
12 \def\Bodytext{Body}
13 \def\Footertext{Footer}
14 \def\MarginNotestext{Margin\\Notes}
15 \def\oneinchtext{one inch}
16 \def\notshown{not shown}

17 }

18 \DeclareOption{french}{%
19 \def\Headertext{Ent\^{e}te}
20 \def\Bodytext{Corps}
21 \def\Footertext{Pied de page}

∗Converted for L^{A}TEX 2ε by Johannes Braams

layout package version v1.1k as of 1995/11/23 2

22 \def\MarginNotestext{Marge\\Notes}
23 \def\oneinchtext{un pouce}
24 \def\notshown{non affich\'{e}}

25 }

26 \DeclareOption{francais}{\ExecuteOptions{french}}
27 \DeclareOption{spanish}{%
28 \def\Headertext{Encabezamiento}
29 \def\Bodytext{Cuerpo}
30 \def\Footertext{Pie de p\'agina}
31 \def\MarginNotestext{Notas\\ Marginales}
32 \def\oneinchtext{una pulgada}
33 \def\notshown{no mostradas}

34 }

35 \DeclareOption{portuguese}{%
36 \def\Headertext{Cabe\c{c}alho}
37 \def\Bodytext{Corpo}
38 \def\Footertext{Rodap\'e}
39 \def\MarginNotestext{Notas\\ Marginais}
40 \def\oneinchtext{uma polegada}
41 \def\notshown{n\~ao mostradas}

42 }

43 \DeclareOption{brazilian}{%
44 \def\Headertext{Cabe\c{c}alho}
45 \def\Bodytext{Corpo}
46 \def\Footertext{Rodap\'e}
47 \def\MarginNotestext{Notas\\ Marginais}
48 \def\oneinchtext{uma polegada}
49 \def\notshown{n\~ao mostradas}

50 }

This package has an option verbose. Using it will make the command \layout type some of the parameters on the terminal.

51 \DeclareOption{verbose}{\let\type\typeout}
52 \DeclareOption{silent}{\let\type\@gobble}

The normal behaviour of this package when showing the values of the parameters is to truncate them. However, if you want to see the real parameter values you can use the option reals to get that effect.

53 \def\lay@value{}
54 \DeclareOption{integers}{%
55 \renewcommand*{\lay@value}[2]{%
56  \expandafter\number\csname #1@#2\endcsname pt}}
57 \DeclareOption{reals}{%
58 \renewcommand*{\lay@value}[2]{\the\csname #2\endcsname}}

The default language is English, the default mode is silent and the default way of showing parameter values is to use integers.

59 \ExecuteOptions{english,silent,integers}
60 \ProcessOptions

\bs Define \bs if it is undefined, redefine it if it is already defined.

61 \@ifundefined{bs}{\newcommand\bs{\char '134 }}%
62 {\renewcommand\bs{\char '134 }}

\ConvertToCount This macro stores the value of a length register in a count register.

63 \def\ConvertToCount#1#2{%

First copy the value

64 #1=#2

Then divide it by 65536.

65 \divide #1 by 65536}

The result of this is that the count register holds the value of the length register in points.

\SetToHalf \SetToQuart Small macros used in computing positions.

66 \def\SetToHalf#1#2{#1=#2\relax\divide#1by\tw@}
67 \def\SetToQuart#1#2{#1=#2\relax\divide#1by4}

\Identify A small macro used in identifying dimensions.

68 \def\Identify#1{%
69 \put(\PositionX,\PositionY){\circle{20}}
70 \put(\PositionX,\PositionY){\makebox(0,0){\tiny #1}}

71 }

\InsideHArrow This macro is used to produce two horizontal arrows inside a box. The argument gives the width of the box.

72 \def\InsideHArrow#1{{%
73 \ArrowLength = #1
74 \divide\ArrowLength by \tw@
75 \advance\ArrowLength by -10
76 \advance\PositionX by -10
77 \ifnum\ArrowLength<\z@
78  \put(\PositionX,\PositionY){\vector(1,0){-\ArrowLength}}
79  \advance\PositionX by 20
80  \put(\PositionX,\PositionY){\vector(-1,0){-\ArrowLength}}
81 \else
82  \put(\PositionX,\PositionY){\vector(-1,0){\ArrowLength}}
83  \advance\PositionX by 20
84  \put(\PositionX,\PositionY){\vector(+1,0){\ArrowLength}}
85 \fi
86 }}

\InsideVArrow This macro is used to produce two vertical arrows inside a box. The argument gives the height of the box.

87 \def\InsideVArrow#1{{%
88 \ArrowLength = #1
89 \divide\ArrowLength by \tw@
90 \advance\ArrowLength by -10
91 \advance\PositionY by -10

 92 \put(\PositionX,\PositionY){\vector(0,-1){\ArrowLength}}
 93 \advance\PositionY by 20
 94 \put(\PositionX,\PositionY){\vector(0,+1){\ArrowLength}}
 95 }}

\OutsideHArrow This macro is used to produce two horizontal arrows to delimit a length. The first argument is the position for the right arrow, the second argument gives the length and the third specifies the length of the arrows.

 96 \def\OutsideHArrow#1#2#3{{%
 97 \PositionX = #1
 98 \advance\PositionX by #3
 99 \put(\PositionX,\PositionY){\vector(-1,0){#3}}
100 \PositionX = #1 \advance\PositionX-#2
101 \advance\PositionX by -#3
102 \put(\PositionX,\PositionY){\vector(+1,0){#3}}

103 }}

\OutsideVArrow This macro is used to produce two vertical arrows to delimit a length. The first argument is the position for the lower arrow, the second argument gives the length and the third and fourth specify the lenghts of the lower and upper arrow.

104 \def\OutsideVArrow#1#2#3#4{{%
105 \PositionY = #1
106 \advance\PositionY by -#3
107 \put(\PositionX,\PositionY){\vector(0,+1){#3}}
108 \PositionY = #1
109 \advance\PositionY#2
110 \advance\PositionY#4
111 \put(\PositionX,\PositionY){\vector(0,-1){#4}}

112 }}

\Show Macro used in the table that shows the setting of the parameters.

113 \def\Show#1#2{\bs #2 = \lay@value{#1}{#2}}

\Type Macro used to show a setting of a parameter on the terminal.

114 \def\Type#1#2{%
115 \type{#2 = \lay@value{#1}{#2}}}

\oneinch A constant, giving the length of an inch in points (approximately)

116 \newcount\oneinch
117 \oneinch=72

Because the overview of the layout is produced in a figure environment we need to allocate a number of counters that are used to store the values of various dimensions.

\cnt@paperwidth \cnt@paperheight The dimensions of the paper
118 \newcount\cnt@paperwidth
119 \newcount\cnt@paperheight
120 \ConvertToCount\cnt@paperwidth\paperwidth
121 \ConvertToCount\cnt@paperheight\paperheight

\cnt@hoffset \cnt@voffset the offsets,
122 \newcount\cnt@hoffset
123 \newcount\cnt@voffset
124 \ConvertToCount\cnt@hoffset\hoffset
125 \ConvertToCount\cnt@voffset\voffset
\cnt@textheight \cnt@textwidth dimensions of the text area,
126 \newcount\cnt@textheight
127 \newcount\cnt@textwidth
\cnt@topmargin \cnt@oddsidemargin \cnt@evensidemargin margins,
128 \newcount\cnt@topmargin
129 \newcount\cnt@oddsidemargin
130 \newcount\cnt@evensidemargin

\cnt@headheight \cnt@headsep dimensions of the running heads,

131 \newcount\cnt@headheight
132 \newcount\cnt@headsep
\cnt@marginparsep \cnt@marginparwidth \cnt@marginparpush marginal paragraphs,
133 \newcount\cnt@marginparsep
134 \newcount\cnt@marginparwidth
135 \newcount\cnt@marginparpush

\cnt@footskip the distance between the running footers and the text,

136 \newcount\cnt@footskip

and the height of the footers, which is needed here to display a box, but which isn’t used by L^{A}TEX.

\fheight
137 \newcount\fheight
138 \fheight=12

Apart from integer representations of the page layout parameters we also need registers to store reference values in.

\ref@top The position of the top of the ‘printable area’ is one inch below the top of the paper by default. The value of \ref@top is relative to the lower left corner of the picture environment that will be used.

139 \newcount\ref@top
140 \ref@top=\cnt@paperheight \advance\ref@top by -\oneinch
\ref@hoffset \ref@voffset For the offsets,
141 \newcount\ref@hoffset
142 \newcount\ref@voffset

The \hoffset and \voffset values are added to the default offset of one inch.

143 \ref@hoffset=\cnt@hoffset  \advance\cnt@hoffset by \oneinch
144 \ref@voffset=\cnt@voffset

\cnt@voffset is converted to be relative to the origin of the picture.

145 \cnt@voffset=\ref@top
146 \advance\cnt@voffset by -\ref@voffset

\ref@head and the text areas, running heads,

147 \newcount\ref@head

\ref@body body of the text

148 \newcount\ref@body

\ref@foot and running footers.

149 \newcount\ref@foot

\ref@margin \ref@marginwidth \ref@marginpar These are different for even and odd pages, so they are computed by \layout.

150 \newcount\ref@margin
151 \newcount\ref@marginwidth
152 \newcount\ref@marginpar

The following are a number of scratch registers, used in the positioning of the various pices of the picture..

153 \newcount\Interval
154 \newcount\ExtraYPos
155 \newcount\PositionX
156 \newcount\PositionY
157 \newcount\ArrowLength

\lay@getvalues All values that might change during the document are computed by calling the macro \lay@getvalues. By default this macro is executed at \begin{document}.

158 \def\lay@getvalues{%
159 \ConvertToCount\cnt@textheight\textheight
160 \ConvertToCount\cnt@textwidth\textwidth
161 \ConvertToCount\cnt@topmargin\topmargin
162 \ConvertToCount\cnt@oddsidemargin\oddsidemargin
163 \ConvertToCount\cnt@evensidemargin\evensidemargin
164 \ConvertToCount\cnt@headheight\headheight
165 \ConvertToCount\cnt@headsep\headsep
166 \ConvertToCount\cnt@marginparsep\marginparsep
167 \ConvertToCount\cnt@marginparwidth\marginparwidth
168 \ConvertToCount\cnt@marginparpush\marginparpush
169 \ConvertToCount\cnt@footskip\footskip
170 \ref@head=\ref@top
171  \advance\ref@head by -\ref@voffset
172  \advance\ref@head by -\cnt@topmargin
173  \advance\ref@head by -\cnt@headheight
174 \ref@body=\ref@head
175  \advance\ref@body by -\cnt@headsep
176  \advance\ref@body by -\cnt@textheight
177 \ref@foot=\ref@body

178  \advance\ref@foot by -\cnt@footskip

179 }

180 \AtBeginDocument{\lay@getvalues}

\computevalues \layout \layout* The command \layout makes the picture and table that display the current settings of the layout parameters.

181 \newcommand\layout{%
182 \@ifstar{\lay@getvalues\lay@xlayout}{\lay@xlayout}}
183 \def\lay@xlayout{%
184 \lay@layout
185 \if@twoside
186  \lay@layout
187 \fi}

\lay@layout The internal macro \lay@layout does all the dirty work.

188 \newcommand\lay@layout{%
189 \thispagestyle{empty}

The actions of \layout depend on the pagestyle.

190 \if@twoside
191  \ifodd\count\z@

Here we deal with an odd page in the twosided case.

192  \typeout{Two-sided document style, odd page.}
    So we compute \ref@marginwidth, \ref@marginpar and \ref@margin.
193  \ref@marginwidth=\cnt@oddsidemargin
194  \ref@marginpar=\oneinch
195  \advance\ref@marginpar by \ref@hoffset
196  \advance\ref@marginpar by \cnt@oddsidemargin
197  \ref@margin\ref@marginpar
198  \if@reversemargin
199  \advance\ref@marginpar by -\cnt@marginparsep
200  \advance\ref@marginpar by -\cnt@marginparwidth
201  \else
202  \advance\ref@marginpar by \cnt@textwidth
203  \advance\ref@marginpar by \cnt@marginparsep
204  \fi
205  \else

Here we deal with an even page in the twosided case.

206 \typeout{Two-sided document style, even page.}
    So we compute \ref@marginwidth, \ref@marginpar and \ref@margin.
207  \ref@marginwidth=\cnt@evensidemargin
208  \ref@marginpar=\oneinch
209  \advance\ref@marginpar by \ref@hoffset
210  \advance\ref@marginpar by \cnt@evensidemargin
211  \ref@margin\ref@marginpar
212  \if@reversemargin

213  \advance\ref@marginpar by \cnt@textwidth
214  \advance\ref@marginpar by \cnt@marginparsep
215  \else
216  \advance\ref@marginpar by -\cnt@marginparsep
217  \advance\ref@marginpar by -\cnt@marginparwidth
218  \fi
219  \fi
220 \else

Finally we the case for single sided printing.

221  \typeout{One-sided document style.}
222  \ref@marginwidth=\cnt@oddsidemargin
223  \ref@marginpar=\oneinch
224  \advance\ref@marginpar by \ref@hoffset
225  \advance\ref@marginpar by \cnt@oddsidemargin
226  \ref@margin\ref@marginpar
227  \if@reversemargin
228  \advance\ref@marginpar by -\cnt@marginparsep
229  \advance\ref@marginpar by -\cnt@marginparwidth
230  \else
231  \advance\ref@marginpar by \cnt@textwidth
232  \advance\ref@marginpar by \cnt@marginparsep
233  \fi
234 \fi

Now we begin the picture environment; dividing all the lengths by two is done

 by setting \unitlength to 0.5pt
235 \setlength{\unitlength}{.5pt}
236 \begin{picture}(\cnt@paperwidth,\cnt@paperheight)
237  \centering
238  \thicklines

First we have the pagebox and reference lines,

239  \put(0,0){\framebox(\cnt@paperwidth,\cnt@paperheight){\mbox{}}}
240  \put(0,\cnt@voffset){\dashbox{10}(\cnt@paperwidth,0){\mbox{}}}
241  \put(\cnt@hoffset,0){\dashbox{10}(0,\cnt@paperheight){\mbox{}}}

then the header,

242  \put(\ref@margin,\ref@head){%
243  \framebox(\cnt@textwidth,\cnt@headheight)%
244  {\footnotesize\Headertext}}

the body of the text area,

245  \put(\ref@margin,\ref@body){%
246  \framebox(\cnt@textwidth,\cnt@textheight){\Bodytext}}

the footer

247  \put(\ref@margin,\ref@foot){%
248  \framebox(\cnt@textwidth,\fheight){\footnotesize\Footertext}}

and the space for marginal notes.

249  \put(\ref@marginpar,\ref@body){%
250  \framebox(\cnt@marginparwidth,\cnt@textheight)%
251  {\footnotesize\shortstack{\MarginNotestext}}}

Then we start putting in ‘arrows’ to mark the various parameters. From here

 we use \thinlines.
252  \thinlines

\PositionX and \PositionY will be the coordinates of the center of the arrow displaying \textwidth.

253  \SetToHalf\PositionX\cnt@textwidth
254  \advance\PositionX by \ref@margin

The arrow should be a bit above the bottom of the ‘body box’.

255  \PositionY = \ref@body
256  \advance\PositionY by 50

An identifying number is put here, in a circle.

257  \Identify{8}

Then the arrow is drawn.

258  \InsideHArrow\cnt@textwidth
    Now the \textheight
259  \SetToHalf\PositionY\cnt@textheight
260  \advance\PositionY by \ref@body

The x-psition of the arrow is at 4/5 of the width of the ‘body box’.

261  \PositionX = \cnt@textwidth
262  \divide\PositionX by 5
263  \multiply \PositionX by 4
264  \advance\PositionX by \ref@margin

An identifying number is put here, in a circle.

265  \Identify{7}
266  \InsideVArrow\cnt@textheight
    The \hoffset,
267  \PositionY = \ref@foot
268  \SetToHalf\PositionX\cnt@hoffset
269  \Identify{1}
270  \InsideHArrow\cnt@hoffset

The width of the margin.

271  \SetToQuart\PositionY\cnt@textheight
272  \advance\PositionY by \ref@body
273  \OutsideHArrow\ref@margin\ref@marginwidth{20}
274  \PositionX = \cnt@hoffset
275  \advance\PositionX by -30
276  \Identify{3}

    the \marginparwidth,
277  \SetToQuart\PositionY\cnt@textheight
278  \advance\PositionY by \ref@body

This arrow has to be bit below the one for the \oddsidemargin or

 \evensidemargin.
279  \advance\PositionY by 30
280  \SetToHalf\PositionX\cnt@marginparwidth
281  \advance\PositionX by \ref@marginpar
282  \Identify{10}
283  \InsideHArrow\cnt@marginparwidth

The \marginparsep, this depends on single or double sided printing.

284  \advance\PositionY by 30
285  \if@twoside
286  \ifodd\count\z@

Twosided mode, odd page;

287  \OutsideHArrow\ref@marginpar\cnt@marginparsep{20}
288  \PositionX = \ref@marginpar
289  \else

and even page.

290  \OutsideHArrow\ref@margin\cnt@marginparsep{20}
291  \PositionX = \ref@margin
292  \fi
293  \else

Single sided mode.

294  \OutsideHArrow\ref@marginpar\cnt@marginparsep{20}
295  \PositionX = \ref@marginpar
296  \fi
297  \advance\PositionX by 30
298  \Identify{9}

Identify the \footskip. The arrow will be located on 1/8th of the \textwidth.

299  \PositionX = \cnt@textwidth
300  \divide\PositionX by 8
301  \advance\PositionX by \ref@margin
302  \OutsideVArrow\ref@foot\cnt@footskip{20}{20}
303  \PositionY = \ref@foot
304  \advance\PositionY by -30
305  \Identify{11}

Identify the \voffset. The arrow will be located a bit to the left of the edge of the paper.

306  \PositionX = \cnt@paperwidth
307  \advance\PositionX by -50
308  \PositionY = \cnt@paperheight
309  \ExtraYPos = \PositionY
310  \advance\ExtraYPos by -\cnt@voffset

311  \advance\PositionY by \cnt@voffset
312  \divide\PositionY by \tw@
313  \Identify{2}
314  \InsideVArrow\ExtraYPos
    Identify \topmargin, \headheight and \headsep.

The arrows will be located on 1/8th of the \textwidth, with intervals of the same size, stored in \Interval.

315  \Interval = \cnt@textwidth
316  \divide\Interval by 8
317  \PositionX = \ref@margin
318  \advance\PositionX by \Interval

First the \topmargin. The length of upper arrows for these three parameters dimensions are different. In the computation of these lengths we have to compensate for the diameter of the cirle.

319  \Identify{4}
320  \ExtraYPos = \ref@head
321  \advance\ExtraYPos\cnt@headheight
322  \ArrowLength = \PositionY
323  \advance\ArrowLength-\ExtraYPos
324  \advance\ArrowLength-\cnt@topmargin
325  \advance\ArrowLength-10%
326  \OutsideVArrow\ExtraYPos\cnt@topmargin{20}{\ArrowLength}
327  \advance\PositionX by \Interval
 Then the \headheight
328  \Identify{5}
329  \advance\ArrowLength\cnt@topmargin
330  \OutsideVArrow\ref@head\cnt@headheight{20}{\ArrowLength}
331  \advance\PositionX by \Interval

and finally the \headsep

332  \Identify{6}
333  \advance\ArrowLength\cnt@headheight
334  \ExtraYPos=\ref@body
335  \advance\ExtraYPos\cnt@textheight
336  \OutsideVArrow\ExtraYPos\cnt@headsep{20}{\ArrowLength}

Here we can end the picture environment and insert a little space.

337 \end{picture}

338

339 \medskip

Below the picture we put a table to show the actual values of the parameters. Note that fractional points are truncated, i.e., 72.27pt is displayed as 72pt

The table is typeset inside a box with a depth of 0 to always keep it on the same page as the picture.

340 \vtop to 0pt{%
341  \@minipagerestore\footnotesize\ttfamily
342  \begin{tabular}{@{}rl@{\hspace{20pt}}rl}

343  1 & \oneinchtext\ + \bs\texttt{hoffset}
344  & 2 & \oneinchtext\ + \bs\texttt{voffset} \\
345  3 & \if@twoside
346  \ifodd\count\z@ \Show{cnt}{oddsidemargin}
347  \else \Show{cnt}{evensidemargin}
348  \fi
349  \else
350  \Show{cnt}{oddsidemargin}
351  \fi                    & 4 & \Show{cnt}{topmargin} \\
352  5 & \Show{cnt}{headheight} & 6 & \Show{cnt}{headsep} \\
353  7 & \Show{cnt}{textheight} & 8 & \Show{cnt}{textwidth} \\
354  9 & \Show{cnt}{marginparsep}&10& \Show{cnt}{marginparwidth} \\
355  11& \Show{cnt}{footskip}   &   & \Show{cnt}{marginparpush}
356  \rlap{(\notshown)}\\
357  & \Show{ref}{hoffset}    &   & \Show{ref}{voffset} \\
358  & \Show{cnt}{paperwidth} &   & \Show{cnt}{paperheight} \\

359

360 \end{tabular}\vss}

When the option verbose was used the following lines will show dimensions on the terminal.

361 \Type{ref}{hoffset}
362 \Type{ref}{voffset}
363 \Type{cnt}{textheight}
364 \Type{cnt}{textwidth}

Finally we start a new page.

365 \newpage

366 } 367 ⟨/package⟩