When the user checks the box, the generated page will be presented as a PDF file. To implement this option, we first generate the page using the XSL-FO page description language. In addition to the quoted standard, XSL-FO by Dave Pawson (ISBN 0-596-00355-2) is invaluable for finding the right features in this huge feature set.
Here is the overall structure of the XSL-FO output. The general setup is for duplex printing on letter paper.
<root xmlns="http://www.w3.org/1999/XSL/Format">
<layout-master-set>
<simple-page-master page-height="11in" page-width="8.5in"
master-name="odd" margin-top="0.5in" margin-bottom="0.5in"
margin-left="1.5in" margin-right="0.5in">
<region-body margin-top="0.5in" margin-bottom="0in"
margin-left="0pc" margin-right="0pc"/>
<region-before region-name="odd-before" extent="3pc"/>
</simple-page-master>
<simple-page-master page-height="11in" page-width="8.5in"
master-name="even" margin-top="0.5in" margin-bottom="0.5in"
margin-left="0.5in" margin-right="1.5in">
<region-body margin-top="0.5in" margin-bottom="0in"
margin-left="0pc" margin-right="0pc"/>
<region-before region-name="even-before" extent="3pc"/>
</simple-page-master>
<page-sequence-master master-name="all">
<repeatable-page-master-alternatives>
<conditional-page-master-reference
master-reference="odd" odd-or-even="odd"/>
<conditional-page-master-reference
master-reference="even" odd-or-even="even"/>
</repeatable-page-master-alternatives>
</page-sequence-master>
</layout-master-set>
We do not use footers in this report. In the static-content/block elements for the running
heads, the text-align-last="justify"
stretches the contents of the header box to the full page
width, and the leader element serves to
fill the adjacent space. In the odd-page header, the
title appears on the left and the folio (page number) on
the right; on the even-page header, the sequence is
reversed.
<page-sequence master-reference="all">
<static-content flow-name="odd-before">
<block text-align-last="justify" font-size="9pt" font-style="italic"
font-family="Palatino, Paladino, serif">
CBC history report
<leader leader-pattern="space"/>
<page-number/>
</block>
</static-content>
<static-content flow-name="even-before">
<block text-align-last="justify" font-size="9pt" font-style="italic"
font-family="Palatino, Paladino, serif">
<page-number/>
<leader leader-pattern="space"/>
CBC history report
</block>
</static-content>
<flow flow-name="xsl-region-body">
...(main content here)...
</flow>
</page-sequence>
</root>
The main content comprises two parts: reduced primary index entries for the select circle(s), and the main table, which closely resembles the HTML layout described in Section 4.4, “The detail history report”.
Each primary index entry starts with the circle name and region codes and the center coordinates in {braces}, all boldfaced; followed by the list of years worked in square brackets. Here is a typical entry.
<block font-size="10pt" font-family="Palatino, Paladino, serif">
<inline font-size="10pt" font-weight="bold"
font-family="Palatino, Paladino, serif">
Carlsbad Caverns N.P. NM {32°10'N 104°30'W}
</inline>
[58–59,61–66,72–75,77–111]
</block>
The “°” and
“–” characters
are the degree (°) and en-dash (–)
characters, respectively.
Following these headings is the main table.
Here is the overall structure of the table:
<table border-collapse='collapse' margin-top='1pc' width='6.5in'
font-size="10pt" font-family="Palatino, Paladino, serif">
<table-column/>
<table-column column-width='3pc'/>
<table-column column-width='3pc'/>
<table-column column-width='3pc'/>
<table-column column-width='3pc'/>
<table-column column-width='3pc'/>
<table-column column-width='3pc'/>
<table-column column-width='3pc'/>
<table-column column-width='3pc'/>
<table-column column-width='3pc'/>
<table-column column-width='3pc'/>
<table-body border='3pt solid black' background-color='#ddffff'>
...
</table-body>
</table>
The border-collapse property on the
table instructs the table builder that whenever two
adjacent cells have borders, let the rendered border
be the maximum of their
thickness, not the sum. Thus we can thicken the
borders of any individual cell without worrying about
what is on the other side of that border.
The margin-top provides a separation
between the table and the preceding index.
The font properties on the table
element will be inherited throughout the table unless
lower-level elements override it.
The width attribute stretches the
entire table to fit between the margins.
The 11 table-column children of the
table element define the column
widths. The first column is auto-sized so that it
soaks up whatever is left over after the ten detail
columns. The rest are sized at half an inch.
In the table-body element, the border places a thick border around the
entire table, and sets up a default color (pale cyan).
For each kind of bird, there may be any number of rows, and the species name spans the first column of all those rows. As with the HTML design, we thicken the borders between the row heading and detail group, and also every fourth row and column, to form rows and columns into groups to make it easier for the reader to associate column positions in a logical row with the corresponding heading.
Here is a screen shot of an XSL-FO rendering of a segment similar to the “Great Skua” row shown in Section 4.5, “CSS considerations in page design”. We thicken every third column border and every second row border, but the idea is the same.

And here is the XSL-FO that produced it:
<table-body border='3pt solid black' background-color='#ddffff'>
<table-row>
<table-cell number-rows-spanned='3' background-color='#ddffdd'
border='1.5pt solid black' border-top-width='3pt'
padding='2pt'>
<block text-align='left'>Great Skua</block>
</table-cell>
<table-cell padding='2pt' border='0.5pt solid black'
border-top-width='3pt' border-left-width='1.5pt'>
<block text-align='right'>1</block>
</table-cell>
<table-cell padding='2pt' border='0.5pt solid black'
border-top-width='3pt'>
<block text-align='right'>2</block>
</table-cell>
<table-cell padding='2pt' border='0.5pt solid black'
border-top-width='3pt'>
<block text-align='right'>3</block>
</table-cell>
<table-cell padding='2pt' border='0.5pt solid black'
border-top-width='3pt' border-left-width='1.5pt'>
<block text-align='right'>4</block>
</table-cell>
<table-cell padding='2pt' border='0.5pt solid black'
border-top-width='3pt'>
<block text-align='right'>5</block>
</table-cell>
<table-cell padding='2pt' border='0.5pt solid black'
border-top-width='3pt'>
<block text-align='right'>6</block>
</table-cell>
</table-row>
<table-row>
<table-cell padding='2pt' border='0.5pt solid black'
border-left='1.5pt solid black'>
<block text-align='right'>7</block>
</table-cell>
<table-cell padding='2pt' border='0.5pt solid black'>
<block text-align='right'>8</block>
</table-cell>
<table-cell padding='2pt' border='0.5pt solid black'>
<block text-align='right'>9</block>
</table-cell>
<table-cell padding='2pt' border='0.5pt solid black'
border-left='1.5pt solid black'>
<block text-align='right'>10</block>
</table-cell>
<table-cell padding='2pt' border='0.5pt solid black'>
<block text-align='right'>11</block>
</table-cell>
<table-cell padding='2pt' border='0.5pt solid black'>
<block text-align='right'>12</block>
</table-cell>
</table-row>
<table-row>
<table-cell padding='2pt' border='0.5pt solid black'
border-top-width='1.5pt' border-left-width='1.5pt'>
<block text-align='right'>13</block>
</table-cell>
<table-cell padding='2pt' border='0.5pt solid black'
border-top-width='1.5pt'>
<block text-align='right'>14</block>
</table-cell>
<table-cell padding='2pt' border='0.5pt solid black'
border-top-width='1.5pt'>
<block text-align='right'>15</block>
</table-cell>
<table-cell padding='2pt' border='0.5pt solid black'
border-top-width='1.5pt' border-left='1.5pt solid black'>
<block text-align='right'>16</block>
</table-cell>
<table-cell padding='2pt' border='0.5pt solid black'
border-top-width='1.5pt'>
<block text-align='right'>17</block>
</table-cell>
<table-cell padding='2pt' border='0.5pt solid black'
border-top-width='1.5pt'>
<block text-align='right'>18</block>
</table-cell>
</table-row>
</table-body>
In order for all the borders to line up, it is important
to put the border properties on the table-cell elements and not in the block elements inside them.
There are three line weights. Thick rules (3pt) surround the entire table and separate logical rows. Medium rules (1.5pt) are used to form groups of rows and columns for easy navigation. Hairline rules (0.5pt) are used elsewhere.
Table cells are responsible for thickening their top or left borders if their row or column number is a multiple of the grouping factor (which is 4 here).
For each cell in a detail column, we set border='0.5 solid black' to use the default
hairline rules around the cell. Then, to thicken
a border, we use the border-top-width or
border-left-width attribute.
Row spanning for the row label is accomplished by using a
number-rows-spanned attribute on its table-cell.