XSL-FO/CSS
Comparison
XSL-FO/CSS Comparison
XSL-FO/CSS Comparison
© 2022 Antenna House, Inc.
Antenna House, Inc.
500 Creek View Road
Suite 107
Newark, DE 19711
USA
Telephone +1 302-566-7225
sales@antennahouse.com
https://www.antennahouse.com/
This document compares XSL-FO and CSS, so it is available in two versions—formatted using XSL-FO and formatted using CSS—for you to compare. However, the results are so similar that for many pages, you will need the Antenna House Regression Testing System (AHRTS) to find the differences.
The text of this document is marked up in XHTML5 (XML-serialized HTML5). Before being formatted, the XHTML5 is augmented using XSLT to add the table of contents, side tabs, and syntax highlighting.
The CSS version applies CSS to the augmented XHTML5 using AH CSS Formatter to generate PDF. For the XSL-FO version, the augmented XHTML5 is transformed into XSL-FO markup using XSLT and is then formatted using AH XSL Formatter to generate PDF.
While every precaution has been taken in the preparation of this document, the publisher assumes no responsibility for errors or omissions, or for damages resulting from the use of information contained herein.
This document compares the specifications for XSL-FO and CSS and provides information about applicable AH Formatter extensions for one or both of XSL-FO and CSS. It is available in two versions—formatted using XSL-FO and formatted using CSS—for you to compare.
Comparing XSL-FO and CSS formatting is not straightforward. XSL implementations are not standing still: XSL formatters are still incrementally improving even though the XSL Recommendation has not been updated since 2006. CSS is definitely not standing still, although some of the modules most relevant to paged media are advancing slowly, if at all, and some paged media features have been removed in more recent Working Drafts.
The Antenna House Formatter family is available in multiple variants with different capabilities: Antenna House Formatter can both format XML or HTML documents using CSS and format XSL-FO; Antenna House XSL Formatter can format documents using XSL-FO; and Antenna House CSS Formatter can format either XML or HTML using CSS. All of these are available as a Lite variant with reduced functionality. The standalone Windows GUI versions of these offer on-screen preview of formatted documents. Please see the Antenna House website for more information.
AH XSL Formatter and AH CSS Formatter cannot be compared strictly on the specifications for XSL-FO and CSS. AH Formatter uses a common layout engine for both XSL-FO and CSS formatting, so many of the features of one technology are implemented as extensions in the other technology. Some features, however, cannot be applied to the other technology because of design decisions made in each specification. For example, XSL-FO and CSS have very different approaches both to selecting page masters and to directing content to the headers and footers on a page.
In addition, AH Formatter implements a large number of original features as extensions to both XSL-FO and CSS. However, some of the extensions can be implemented for one technology but not the other. For example, the -ah-attr-from() function for retrieving an attribute value from a named ancestor element is implemented only for CSS because, for XSL-FO, the value to use could be determined by the XSLT transformation that generates the XSL-FO.
XSL-FO/CSS Comparison is intended for you if you are exploring whether to use XSL-FO or CSS, you know one of XSL-FO or CSS and want to learn more about the other, or if you work with both and want to see where are the differences.
<style>
.float: left;
.<p>Number of this page = <span style="content: counter(page)"></span> </p> <p>Total number of pages in this document= <span style="content: counter(pages)"></span> </p>
Help us to improve this document. Please send any comments, corrections, or suggestions for improvement to support@antennahouse.com.
1
1
Some of the significant events in the development of XSL-FO, CSS, HTML, and AH Formatter are shown in the following table.
Year | XSL-FO | Antenna House | CSS | HTML |
---|---|---|---|---|
1996 | DSSSL | CSS 1 | ||
1998 | CSS 2 | XHTML 1.0 | ||
1999 | First CSS 3 drafts | |||
2001 | XSL 1.0 | AHF V1.1E | XHTML 1.1 | |
2004 | WHAT WG formed | |||
2006 |
|
HTML WG rechartered | ||
2008 | AHF V5.0 | |||
2009 | XSL-FO 2.0 Design Notes | |||
2011 | CSS 2.1 | |||
2012 | AHF V6.0 | |||
2018 | AHF V6.6 | CSS Snapshot 2018 | ||
2019 | W3C cedes HTML5 to WHAT WG | |||
2020 | AHF V7.0 | CSS Snapshot 2020 | ||
2021 |
|
Cascading Style Sheets, level 1, [CSS1] became a Recommendation in 1996. CSS was co-invented by Håkon Wium Lie and Bert Bos. CSS 1 built upon previous style sheet proposals, including earlier separate proposals by Lie and Bos. References to the earlier proposals are at: the W3C Historical Style Sheet proposals [HSSP] page; the The CSS saga [LIEBOS2E] chapter from Lie and Bos’s CSS book: and Lie’s Ph.D thesis [LIE]. The goals for CSS stated in 1995 [1995] include: “CSS supports stream-based (or ‘incremental’ formatting) where possible”; “CSS offers both readers and authors control over the style”; as well as “avoiding an uncontrolled growth of HTML extensions”.
DSSSL [DSSSL], the stylesheet language for SGML, became an International Standard in 1996. DSSSL defines a tree transformation process followed by a formatting process. In practice, the tree transformation process was not widely used. However, the most widely-used DSSSL formatter had an extension for performing a transformation as an alternative to formatting.
Styling for XML was always part of the development of XML. It was referred to by Jon Bosak, original XML Working Group (WG) Chair, in 1997 as “xml-style (Part 3 of the XML specification suite)” [XS] and “Part 3 of the W3C XML suite of specifications for the use of SGML, HyTime, and DSSSL subsets on the World Wide Web” [XSRTF].
‘xml-style’ became ‘Extensible Stylesheet Language’ (XSL). The XSL WG was formed in 1998, and its charter stated its intention “to define a style specification language that covers at least the formatting functionality of both CSS and DSSSL.” [XSLCHARTER] XSL encompasses both transformation and formatting, but transformation proved generally useful, and the transformation component was broken out as the XSLT series of Recommendations. The bulk of the XSL 1.0 and XSL 1.1 Recommendations concern the formatting objects (FO) and their properties. The transformation component is covered by a short chapter that refers to the then-current XSLT 1.0 Recommendation. The XSL properties align as much as possible with the corresponding CSS properties, in keeping with the commitment in the XSL WG charter.
The need for consistency in properties was stated to be an architectural principle for the web in the Consistency of Formatting Property Names, Values, and Semantics TAG Finding [TAG] published in 2002.
Antenna House first proposed greater compatibility between XSL-FO and CSS, especially compatibility with the CSS 3 drafts, at International Workshop on the future of the Extensible Stylesheet Language (XSL-FO) Version 2.0 [XSL2006] at Heidelberg, Germany, in 2006. That proposal was not supported by the workshop participants.
AH Formatter V5.0, released in 2008, was the first AH Formatter version to support both XSL-FO and CSS. AH Formatter is still the world’s only XSL-FO and CSS formatter, and successive releases have added features for both XSL-FO and CSS. The following figure illustrates the relative proportions of the number of properties available for XSL-FO and CSS formatting. You can see that the majority of the properties available to either XSL-FO or CSS are AH Formatter original extensions or are properties from one technology made available in the other technology.
Category | Definition |
---|---|
XSL+ | XSL-FO property |
XSL+CSS | Common to both XSL-FO and CSS 2 |
XSL+CSS3 | Common to both XSL-FO and CSS 3 |
XSL+AHF | XSL-FO property also implemented as CSS extension |
AHF+ | AH Formatter extension for XSL-FO only |
AHF+AHF | AH Formatter extension for both XSL-FO and CSS |
AHF+CSS | CSS 2 property also implemented as XSL-FO extension |
AHF+CSS3 | CSS 3 property also implemented as XSL-FO extension |
+AHF | AH Formatter extension only for CSS |
+CSS3 | CSS 3 property |
+CSS | CSS 2 property |
2
2
How a user compares XSL-FO and CSS can depend on their initial exposure to markup and styling as much as or more than on the relative merits of either technology. This is an informal summary of how users of CSS can see XSL-FO, and vice-versa.
Source XML or HTML must be transformed into the XSL-FO vocabulary
Transformation has advantages and disadvantages. CSS was designed to support stream-based or incremental formatting [1995], which is part of why CSS selectors cannot match ‘down’ into the content of the current element or ‘forward’ to the structure of following elements. A transformation stage, on the other hand, typically (although less so after XSLT 3.0 added streaming for XSLT) requires the whole document to be available, but it does allow style decisions to be made based on the whole document. Transformation also allows the content to be duplicated and reordered to, for example: generate tables of contents and indexes; sort the rows of a table; or calculate subtotals.
Formatting paged media using CSS 3 typically requires some form of transformation anyway. This includes generating the running elements that are taken out of the flow and used in headers and footers, as well as generating tables of contents and indexes.
Separate attributes for each property is verbose
XSL-FO is designed to be the result of an XSLT transformation. XSL-FO was not meant to be read, let alone authored, by humans. It does happen, of course. When XSL-FO is serialized as XML, it is straightforwardly usable in XML editors, etc., and it is as human-legible and as reasonably clear as any other XML or HTML document.
When XSL-FO is generated using XSLT, the XSLT is less verbose than the XSL-FO that it creates. An FO and its properties can be generated from literal elements and attributes inside an XSLT template, but a single XSLT template can be used many times to generate multiple copies of the FO. Attribute sets in the XSLT are defined once and are used in multiple places in the XSLT. An XSLT template can contain more than just literal elements and attributes to copy to the result: the XSLT can include as much logic as is necessary to be able to conditionally generate the correct FOs, their correct properties, and the correct property values for any given context.
JavaScript could be used instead of XSLT
Yes, JavaScript can be used to generate tables of contents, indexes, and so on by manipulating the DOM of the document, but whatever JavaScript solutions exist have been bespoke code. Over the last 20 years, there hasn’t been a standard, widely used, general purpose JavaScript library that matches both the path-matching ability of XPath and the declarative templating mechanism of XSLT. AH Formatter will format a correct XSL-FO file no matter how it was created.
XSL-FO properties inherit but do not cascade
The role of the cascade is taken by the XSLT transformation.
In XSLT:
<xsl:attribute-set>
with the same name are
aggregated, with definitions for individual attributes in an
<xsl:attribute-set>
with higher precedence overriding
definitions in other <xsl:attribute-set>
that have lower
precedence. An <xsl:attribute-set>
can also reuse
attribute definitions in other, named attribute sets. Attribute sets
are not quite the same as on-the-fly building up of the properties
to apply in a particular context based on the cascade of
@import rules and specificity of CSS selectors, but
they do make it easy to apply a group of properties in particular
contexts.FOs are like elements with fixed display property values
In CSS, all that you have is the source document (unless, as noted previously, you have augmented the original source document to create tables of contents, etc.), and the display property, like all properties, is applied as the document is formatted. With transformation before formatting, the decisions about how to format each part of the source document are part of the transformation, so there is no need for on-the-fly changes using a display property.
XSL-FO does not have variables
CSS gained variables only recently, but variables are not needed in XSL-FO. XSLT has variables (which have scope and which can be passed between templates), so any calculations based on variables or any substitution of constant values can be handled in XSLT.
XSL 1.1 defines how to handle a page that extends indefinitely in one or both dimensions and it also includes some interactive FOs, but neither of those has been widely implemented because few users have ever expressed interest in them.
The basics of CSS syntax are easy to learn, but there is an expanding list of CSS selectors and pseudo-elements to be remembered, plus many CSS properties have their own micro-syntax for expressing their value. XSLT and XSL-FO are XML vocabularies, so most of their syntax is easily understood by anyone who can read XML or HTML. However, XSLT and XSL-FO attempt more than CSS, so it is not surprising that there is more to learn. XSLT is a Turing-complete declarative language for specifying transformations, whereas CSS is a declarative language for specifying styles. People who are used to imperative programming languages where they specify every step of the program can have trouble adapting to the XSLT model where the structure of the source document can determine the program flow.
XSL-FO provides more control than CSS over, for example, the selection of page masters and the content of headers and footers, so it has more FOs and properties for those areas.
True. However, comparatively few CSS users are familiar with using CSS to generate paged media. If you want to learn more about CSS for paged media, see Introduction to CSS for Paged Media [ITCFPM], available from the Antenna House website.
CSS ‘just decorates the tree’
Decorating the tree of elements fits with the original goal of CSS to support streaming or incremental formatting. [1995] XSLT, in contrast, can use any part of the document, or of a different document, when deciding which template to use in the current context. By using modes, XSLT can process the document or parts of the document multiple times in different ways.
The structure of the XSL-FO document does not need to match the structure of the source document: the XSLT stage can generate literal elements as well as copy all or part of any node in the source document. An XSLT template can select which nodes to process next rather that just processing the children of the current node.
CSS selectors can match on the current element, its class (or classes), its attribute values, its ancestor elements, and its preceding elements. Selectors won’t, however, match on the string value of an element or on any aspect of the type and arrangement of an element’s descendent elements. In contrast, the entire document (and possibly other, external documents) is available to the XSLT processor, and style decisions can be made based on more than just the context of the current element.
CSS selectors only apply to elements. In contrast, XSLT templates can match on text nodes, text nodes with particular values, or text nodes in particular contexts (possibly with particular values) and can generate FOs based on those text nodes. XSLT can similarly match on comments and processing instructions and generate FOs.
3
3
The following table provides an overview of the differences between XSL-FO and CSS. More details are provided in the sections following the table. For ease of comparison, the sequence in both the table and the rest of this document follows the chapter sequence in Introduction to CSS for Paged Media [ITCFPM].
Features that are AH Formatter extensions are shown as .
Section | XSL-FO | CSS |
---|---|---|
Box layout | XSL and CSS both generate rectangular boxes by applying styles to markup. Their features are mostly identical. | |
Page layout |
|
|
Headers & footers |
|
|
Multiple columns |
|
|
Keeps & breaks |
|
|
Paragraph setting |
|
|
Footnotes & sidenotes |
|
|
Tables |
|
|
Lists |
|
|
Character setting | Equivalent capabilities. Many properties are common to XSL-FO and CSS. Properties that are not defined in a technology are implemented as AH Formatter extensions, plus there are multiple original AH Formatter extensions implemented for both XSL-FO and CSS. | |
Japanese text composition | Equivalent capabilities. Many properties are common to XSL-FO and CSS. Properties that are not defined in a technology are implemented as AH Formatter extensions, plus there are multiple original AH Formatter extensions implemented for both XSL-FO and CSS. | |
Cross-references |
|
|
Image positioning |
AH Formatter provides equivalent extensions for both XSL-FO and CSS that provide better capabilities than what is defined in either XSL-FO or CSS. |
|
MathML & SVG graphics |
|
|
Counters |
|
|
Color |
|
|
Borders & background | Equivalent capabilities. Many properties are common to XSL-FO and CSS. Properties that are not defined in a technology are implemented as AH Formatter extensions, plus there are multiple original AH Formatter extensions implemented for both XSL-FO and CSS. | |
PDF output |
|
|
Indexes |
|
|
AH Formatter unique features |
|
|
4
4
XSL and CSS both generate rectangular boxes by applying styles to markup. In
XSL-FO, the FO name—such as <fo:block>
or
<fo:list-item-label>
—determines what type of areas the FO generates as
well as which properties apply to the generated areas. Some FOs, however, either do
not generate any areas or simply return the areas generated by their
descendent FOs. In CSS, the display property determines the type of box
or boxes that the element generates, which also determines which properties apply to
the current element.
XSL requires that all FOs are present in the document: the XSLT stage is expected to generate all of the elements for the FOs. (XML does not allow tags to be omitted, but that is not relevant to XSL because FO documents were not expected to be serialized as XML documents before formatting.) The FOs, in turn, generate all of the areas in the formatted document. The main, barely-noticed exception is when a block-level FO contains both text and block-level FOs: any continuous run of text is contained by an ‘anonymous block’ so that areas generated by the outer FO contain only block areas and not a mixture of inline areas and block areas. Delimited runs of inline text are created for text that has a different orientation—such as Latin text in vertical Japanese text—or that has a different directionality—such as Latin text in an Arabic document.
HTML allows the start and/or end tags of some HTML elements to be omitted and the
HTML parser will infer them. XHTML requires that start-tags and end-tags match
(and that the single tag for an empty element ends with />
), but
some elements can be inferred by other content: for example,
<table>
can either directly contain <tr>
or contain
<tbody>
that contains <tr>
.
CSS, similarly to XSL, will generate anonymous boxes around runs of text as
required to ensure that a block box does not contain a mix of inline boxes and
block boxes or inline boxes and text. CSS can also generate some anonymous boxes
when formatting tables: for example, when an element with display: table;
contains an element with display: table-row;
that
contains text, the formatter will generate an anonymous row-group box and an
anonymous table-cell box so that the formatted elements are consistent with the
table model.
Most boxes in both XSL and CSS can have a border. Padding can be specified to create space between the actual content of the box and its border, and margins can be specified to create space between the border and adjacent boxes. XSL defines these in terms of rectangles whereas CSS defines them in terms of boxes with edges, but they are compatible.
A box’s margin and padding as well as border color, style, and width can be individually specified for each side. In CSS and, with an AH Formatter extension, in XSL-FO, the box can have rounded corners. The radius of each side of each rounded corner can be individually specified. Shorthand properties allow the margin, padding, or one or more border properties for multiple sides to be set at once.
CSS originally defined the padding, etc., properties based on a box’s appearance on the page (or screen). For example, padding-left and padding-right shorthand properties for the left and right paddings, respectively. For left-to-right text, such as English, these correspond to the start and end of a line of text, respectively. However, for right-to-left text, such as Arabic, they correspond to the end and start of a line of text, respectively, and for vertical Japanese text, they correspond to the sides but neither the start nor end of a line of text. There is a current CSS Working Draft that adds ‘logical’ properties—such as padding-inline-start and padding-inline-end—but that is not yet widely used. The logical properties map to the corresponding properties for the left, right, top, and bottom sides based on the values of the CSS writing-mode, direction, and text-orientation properties. For example, specifying padding-inline-start will generate the padding at the start side of a block irrespective of whether the current language is English, Arabic, or Japanese.
XSL defines padding, etc.—and even the position of the header and footer areas—in terms of relative directions. XSL defines padding-left and padding-right, etc., in common with CSS, but also defines padding-start, padding-end, padding-before, and padding-after (and so on for other border and padding properties). The correspondence between padding-left and padding-right, etc., and the relative properties depends on the value of the XSL writing-mode property. For the border and padding properties, if both an absolute and a relative property are specified for an FO, the absolute property has precedence. It is slightly more complicated for the margin properties because the values of the XSL start-indent and end-indent properties are a function of the corresponding margin, border, and padding widths.
XSL can change the orientation of a block by specifying the reference-orientation property.
Boxes can be specified to have a width and/or height. XSL shares the min-width, width, max-width, min-height, height, and max-height properties with CSS, but in XSL, these absolute properties are mapped to the relative inline-progression-dimension and block-progression-dimension properties. inline-progression-dimension and block-progression-dimension (and leader-length) can be specified as a <length-range> with minimum, optimum, and maximum components rather than a single fixed length. In CSS, non-auto width and height values specify the size of either the content rectangle or the border rectangle of the box, depending on the value of the box-sizing property.
Boxes are ordinarily positioned one after the other down the page or along the
line, with obvious exceptions for tables, list item labels, and floated
elements. The position property (which, in XSL, is a shorthand for
the relative-position and absolute-position
properties) allows a box to be offset relative to its position in the flow or
positioned relative to its reference area or to the page. In CSS,
position can be specified for any element. In XSL,
relative-position can be specified on a range of FOs, but
absolute-position can only be specified on
<fo:block-container>
. The z-index property specifies the
relative layering of areas generated from positioned elements in CSS and from
<fo:block-container>
in XSL.
5
5
Formatting on paged media obviously requires pages on which to do the formatting. XSL-FO and CSS have different mechanisms for defining the size and other characteristics of a page. Many documents use more than one type of page—for example, left-hand and right-hand pages can have different margins as well as different headers and footers—so XSL-FO and CSS each have mechanisms for choosing between page types.
A ‘page master’ is the specification of the size and overall layout of a page. A formatted document where all the pages are essentially the same could have just one page master. A formatted document could require multiple page masters if it has, for example: title page; different margins on right and left pages; one-column body text and a multi-column index; landscape pages for wide tables; or wider margins on table of contents pages.
Page masters in XSL-FO are defined using <fo:simple-page-master>
.
An <fo:simple-page-master>
can define up to five types of
regions. <fo:region-body>
receives the main content of the
document, and the other regions receive the content that makes up the
headers and footers on each page. Omitted regions do not generate any areas
when the <fo:simple-page-master>
is used to generate pages. XSL
1.1 added the ability to define multiple <fo:region-body>
on one
page and to direct one or more flows to one or more regions on the page
using <fo:flow-map>
.
Page masters in CSS are defined using an @page rule. [CSS3-Page]
XSL 1.1 specifies that the regions follow a fixed sequence in the XSL-FO. AH
Formatter relaxes this and allows the regions to appear in any sequence. AH
Formatter renders the areas for the regions in the sequence in which the
regions appear in the XSL-FO: z-index does not apply to the
regions, so the declaration sequence is a way to control which regions can
overlap other regions. If <fo:region-body>
is last, it can
overlap content from the other regions.
z-index applies to CSS page-margin boxes. It can be used to control the layering of page-margin boxes that have content that overlaps.
A ‘spread’ is two facing pages.
AH Formatter has an <axf:spread-page-master>
extension for XSL-FO.
The background of an <axf:spread-page-master>
extends across both
pages, and regions defined in the <axf:spread-page-master>
can
span across more than one page.
CSS does not have any support for specifying spreads. The AH Formatter extension is not available with CSS because CSS does not provide the same control over the sequence of page masters as in XSL-FO.
Page size in XSL is specified with the page-height and page-width properties, or with the size shorthand for setting both at once. The XSL 1.1 size is based on the CSS 2 size property, but that size was removed in CSS 2.1 and not reinstated in CSS 2.2. AH Formatter implements a superset of the CSS Paged Media Module Level 3 size property, which adds keywords for several standard page sizes.
Page size in CSS is specified using the size property. The extended set of page size keywords is similarly available in CSS.
The content in an XSL-FO document is contained in one or more
<fo:page-sequence>
FO. Each <fo:page-sequence>
specifies which <fo:simple-page-master>
to use or, indirectly,
which set of <fo:simple-page-master>
to use. The
<fo:page-sequence>
can refer to a
<fo:page-sequence-master>
that sets out which
<fo:simple-page-master>
to use and in what sequence.
The sequence of page masters can be any sequence of:
A choice between alternative page masters, possibly with a limit to the number of times that the choice can be repeated. The references to the alternative page masters each have three sub-conditions for deciding whether to use that alternative. When a new page is to be generated, the alternatives are considered in sequence, and the first alternative for which all three subconditions is true is chosen.
The sub-conditions are:
The sub-conditions are expressed as properties. The any value is the default for each property, so when choosing an alternative, you only need to specify the sub-conditions that affect the choice.
For example, a document with different margins on odd and even pages could
have two <fo:simple-page-master>
named OddPage and EvenPage.
The <fo:page-sequence-master>
for choosing the correct page
master could be:
<fo:page-sequence-master master-name="PageMaster"> <fo:repeatable-page-master-alternatives> <fo:conditional-page-master-reference master-reference="OddPage" odd-or-even="odd"/> <fo:conditional-page-master-reference master-reference="EvenPage" odd-or-even="even"/> </fo:repeatable-page-master-alternatives> </fo:page-sequence-master>
(Note that odd-or-even="even"
is not strictly necessary here
because any page that did not match the previous
odd-or-even="odd"
is, by definition, an even page.)
CSS does not have a separate mechanism for predetermining the sequence of page masters. (Even in XSL-FO, it is only partially predetermined, because which page is the last page, or which pages are blank, is not known until the document is formatted.)
In CSS, any element that can cause a page break before or after itself can cause a change in @page rule by specifying the page property with a value that is different from the value of its parent or preceding sibling element. As an extension to the current CSS definition, AH Formatter allows a sequence of multiple names in the page property, and AH Formatter uses each specified @page rule in turn when generating pages. If the element generates more pages than there are names in the page property value, AH Formatter continues to use the last name for the remainder of the pages.
XSL 1.1 does not allow page sequences to be nested: all of the page masters
to use and conditions for their sequence of use are determined by the
<fo:page-sequence-master>
referred to by an
<fo:page-sequence>
.
AH Formatter allows <fo:flow>
to contain children
<fo:page-sequence>
FOs. Formatting a nested
<fo:page-sequence>
is equivalent to ending the containing
<fo:page-sequence>
, formatting the <fo:page-sequence>
as if it were another top-level <fo:page-sequence>
, and then
formatting the FOs after the <fo:page-sequence>
as if in a copy
of the original containing <fo:page-sequence>
.
CSS does not differentiate between top-level elements and lower-level elements that can change the @page that is being used. As stated previously, any element that can cause a page break before or after itself can cause a change in the @page rule that is being used.
XSL 1.1 added the ability to define multiple <fo:region-body>
in
an <fo:simple-page-master>
and also multiple <fo:flow>
within an <fo:page-sequence>
. One or more <fo:flow>
can be directed to one or more <fo:region-body>
on a page. Which
<fo:flow>
are directed to which <fo:region-body>
, as
well as the sequence in which multiple <fo:flow>
are directed to
one (or more) <fo:region-body>
, is controlled by an
<fo:flow-map>
, which was also added in XSL 1.1.
CSS does not have a comparable feature at present.
6
6
The areas generated from the four ‘outer’ regions—<fo:region-before>
,
<fo:region-after>
, <fo:region-start>
, and
<fo:region-end>
—receive content from <fo:static-content>
.
Each region has a default name based on its type, but different
region-name values can be specified. An
<fo:static-content>
directs its content to a region with the same
region-name value as the flow-name property value of
the <fo:static-content>
. This makes it possible to set up the static
content for multiple sorts of pages and use only the applicable static content
on each page. It also makes it possible to, for example, direct the contents of
one <fo:static-content>
to the outer, left-hand region on left-hand
pages and to the outer, right-hand region on right-hand pages.
Variable content that should appear in the header or footer, such as the current chapter title,
is declared in an <fo:marker>
. Any number of
<fo:marker>
can be included as the first children of
<fo:flow>
and of many of it descendent FOs. An
<fo:marker>
can contain any combination of text, inline-level
FOs, and block-level FOs, but it does not generate any areas. Instead, its
children are available to be retrieved and formatted by an
<fo:retrieve-marker>
that is within an
<fo:static-content>
.
As stated previously, the applicable <fo:static-content>
provides
the complete content for one of the outer regions on the page, and it is
only those applicable <fo:static-content>
that actually retrieve
and format the children of an <fo:marker>
. An
<fo:static-content>
contains one or more block-level FOs. One or
more <fo:retrieve-marker>
can be present as the only content of
the <fo:static-content>
or as siblings of block-level FOs. The
block-level FO or FOs can contain any number of
<fo:retrieve-marker>
in any part of their content.
The correspondence between the
marker-class-name property on the <fo:marker>
and the
retrieve-class-name property on the <fo:retrieve-marker>
connects an <fo:marker>
and an <fo:retrieve-marker>
. Any
name token can be used; for example, chapter-title and
xyzzy are equally allowed. Sibling <fo:marker>
cannot use
the same marker-class-name value.
If the
<fo:marker>
for the chapter title
is:
<fo:marker marker-class-name="chapter-title">A<fo:inline font-variant="swash(1)">&</fo:inline>B</fo:marker>
then
the <fo:static-content>
of the header can
be:
<fo:static-content flow-name="xsl-region-before"> <fo:block font-size="10pt" text-align="center"> <fo:retrieve-marker retrieve-class-name="chapter-title" /> </fo:block> </fo:static-content>
The content of the <fo:marker>
is
formatted in place of the empty <fo:retrieve-marker>
. The content is
formatted as if it had the same ancestors as the
<fo:retrieve-marker>
; that is, the content inherits property values
from the context of the <fo:retrieve-marker>
within its
<fo:static-content>
and not from the context of the
<fo:marker>
in its parent FO.
There can be multiple
<fo:marker>
with the same marker-class-name in the FO
document (just not with the same parent FO). Multiple FOs that have
<fo:marker>
children with the same marker-class-name
could generate areas on the same page. To continue with the example, unless each
chapter starts on a new page, there could be both the end of one chapter and the
start of the next chapter on the one page, and some books have complete chapters
that are less than one page, so there could be part or all of three (or more)
chapters on one page.
An XSL formatter considers <fo:marker>
related to areas on the current page and,
possibly, on preceding pages. It chooses a preferred <fo:marker>
based on the retrieve-position and
retrieve-boundary property values of an
<fo:retrieve-marker>
:
<fo:marker>
compared to the areas generated by other
identically named <fo:marker>
. retrieve-position
can have values first-starting-within-page,
first-including-carryover,
last-starting-within-page, and
last-ending-within-page.<fo:marker>
. It can have values
page, page-sequence, and
document. retrieve-boundary can be useful to
stop a marker ‘leaking’ into pages where it is not wanted: for example,
an epilogue that does not need a running title in the header could use
the same page masters as chapters if:<fo:page-sequence>
<fo:marker>
for the
running title in the header<fo:retrieve-marker>
for the running title in the
header omits retrieve-boundary to use its initial value
of page-sequence.Page numbers in the header are generated using <fo:page-number>
.
The total number of pages shown in page numbers such as “Page 1 of 5” can be
generated by using <fo:page-number-citation-last>
with a
ref-id value that refers to the ID of the
<fo:page-sequence>
or other FO that encompasses all of the FOs
that generate those pages.
In CSS, every page has 16 page-margin boxes that are always available to receive content. The names of the page-margin boxes are fixed.
A page-margin box is generated only if it has content; that is, if the value
of its content property is not none.
none is the computed default, so page-margin boxes ordinarily
do not generate any boxes. This differs from XSL-FO, where the areas from
<fo:region-before>
, etc. can generate an area that has, for
example, borders and a background color even when it has no content
generated from an <fo:static-content>
(provided that the
extent property of the region is not 0pt).
Content can be either:
The string-set property sets one or more named strings. For example, to set the chapter named string to the text value of the current element:
H1 { string-set: chapter content(); }
The string name is followed by a list of string values that are concatenated to form the value of the named string. Setting a named string overwrites any previous value set earlier in the document. An element with display: none; can still set named strings.
string(chapter) in the content property of a page-margin box retrieves the value of the string named chapter. Multiple elements on one page can set the same named string, so string() has an optional second argument to select one of the possible strings. The defined values are first (default), start, last, and first-except.
Using position: running(name);
is similar to using
string-set, except that position: running;
takes the
current element out of the flow—similar to specifying display: none;
. content: element(name);
inserts the named running
element into the page-margin box. element() also has an optional
second argument to select one of the possible running elements with the same
name: first (default), start, last, and
first-except.
A running element inherits from its original position in the document. This
is the opposite of <fo:marker>
, where the marker contents inherit
from the position of the <fo:retrieve-marker>
in its
<fo:static-content>
.
counter(page) in the content value of a page-margin box generates the current page number.
7
7
CSS offers more flexibility than XSL in which elements or FOs may have multiple columns, how multiple columns are specified, and which elements or FOs can span all of the columns in the area. For both XSL-FO and CSS, AH Formatter supports the same range of properties for specifying the column gap and the formatting of the column rule, if present.
XSL 1.1 allows multiple columns only in <fo:region-body>
. AH Formatter
extends this by also allowing multiple columns in
<fo:block-container>
. The column-count property
specifies the fixed number of columns in the <fo:region-body>
or
<fo:block-container>
.
CSS allows any element that is a CSS ‘block container’ to possibly have multiple columns if either column-width or column-count is not auto. When column-width is a length, it specifies the optimal column width. The actual columns can be wider, to fill the available space, or can be narrower, when the available space is less than the specified column width. When column-count is an integer and column-width is auto, column-count specifies the number of columns, as with column-count in XSL. However, when column-count is an integer and column-width is a length, column-count specifies the maximum number of columns.
A block can either fit within one column or span all of the columns in the area
in both XSL and CSS. In XSL, span="all" on an <fo:block>
or <fo:block-container>
that is a child of an <fo:flow>
(or, with AH Formatter, of an <fo:block-container>
) will span all the
columns of a multi-column region. In CSS, an in-flow block-level element with
column-span: all;
spans across all columns of the nearest ancestor
multi-column area in the same block formatting context.
AH Formatter allows floats to span less than the full width of the area.
8
8
XSL-FO and CSS both have properties for keeping two adjacent areas together on the same page or column or for forcing a break between the areas. They also have a property or properties for keeping an area together on the same page or column.
XSL 1.1 defines break-before and break-after properties for specifying whether and how there should be a break before or after the areas for the FO, respectively. It also defines keep-with-previous and keep-with-next for specifying whether the first or last area for the FO should be kept with the preceding or following area, respectively, as well as keep-together for specifying whether and how the areas for the FO should be kept together.
The value of the keep properties in XSL is a distinct ‘keep’ datatype that has
three components: within-line, within-column, and
within-page. The value of each component is auto,
always, or an integer. auto and always are
self-explanatory. An integer value specifies the relative strength of the keep
component. An XSL formatter should resolve the relative keep values that apply to an
area so that conflicting specifications resolve, where possible, in favor of the
stronger keep value. The components can be specified individually by appending the
component name to the property name: for example,
keep-together.within-line="always"
. Specifying just the property
name—for example, keep-together="always"
—applies the same value to all
three components. When both the property and one or more components are specified
for an FO, the component values are used, and the property value is used for any
components that were not explicitly specified. XSL-style keep-together
is available in CSS as the -ah-keep-together extension property.
CSS defines break-before and break-after properties that combine some of the features of the XSL break-before and keep-with-previous properties or break-after and keep-with-next properties. CSS also defines a break-inside property that is similar to the XSL keep-together property. CSS does not support integer values to indicate relative strengths
Both XSL and CSS 2 define page-break-before, page-break-after, and page-break-inside properties. In XSL, these are shorthands for the other keep and break properties, and they were added to XSL only for compatibility with CSS 2. In CSS, these properties are now redefined as shorthands for some values of the other break properties.
The following tables show the values of the XSL and CSS break properties:
XSL | CSS | Description |
---|---|---|
auto | auto | Neither force nor forbid a break. |
avoid | Avoid a break. Equivalent to
keep-with-previous="always" or
keep-with-next="always" in XSL. |
|
column | column | Force a column break. |
avoid-column | Avoid a column break. Equivalent to
keep-with-previous.within-column="always" or
keep-with-next.within-column="always" in XSL. |
|
page | page | Force a page break. |
avoid-page | Avoid a page break. Equivalent to
keep-with-previous.within-page="always" or
keep-with-next.within-page="always" in XSL. |
|
even-page | Force one or two page breaks so that the next page is an even page-area. | |
odd-page | Force one or two page breaks so that the next page is an odd page-area. | |
left | Force one or two page breaks so that the next page is a left page. | |
right | Force one or two page breaks so that the next page is a right page. | |
recto | Force one or two page breaks so that the next page is a recto page in a two-page spread. Depending on the page progression, this could be a right-hand page or a left-hand page. | |
verso | Force one or two page breaks so that the next page is a verso page in a two-page spread. Depending on the page progression, this could be a left-hand page or a right-hand page. | |
region | Force a region break. Not implemented by AH Formatter. | |
avoid-region | Avoid a region break. Not implemented by AH Formatter. |
Note that in a left-to-right page progression, the first, odd-numbered page is a
right-hand page, which is a recto page, and that in a right-to-left page
progression, the first, odd-numbered page is a left-hand page, which is a also
recto page. CSS explicitly allows, for example, ‘html { break-before: always; }
’ to force the first page of a document with left-to-right page
progression to print on a left-hand page. There is no explicit support for this
in XSL, but AH Formatter can generate documents that start on a left-hand page
when, for example, ‘<axf:document-info name="pagelayout"
value="TwoPageLeft"/>
’ is specified.
The region and avoid-region values are currently at risk of being dropped from the current Candidate Recommendation version of the specification because of an absence of interoperable implementations.
keep-together | break-inside | Description |
---|---|---|
auto | auto | No conditions or constraints. |
always | avoid | Avoid breaks. |
avoid-page | Avoid a page break. Equivalent to
keep-together.within-page="always" in XSL. |
|
avoid-column | Avoid a column break. Equivalent to
keep-together.within-column="always" in XSL. |
|
avoid-region | Avoid a region break. No equivalent in XSL. Not implemented by AH Formatter. |
AH Formatter provides axf:keep-together-within-dimension and -ah-keep-together-within-dimension properties for specifying the maximum block height for which the keep on the block applies. When the block is higher than the limit, the block is broken normally as if no keep was specified. AH Formatter similarly provides axf:keep-together-within-inline-dimension and -ah-keep-together-within-inline-dimension properties for specifying the maximum width for which a keep-together.within-line condition applies.
Both XSL and CSS define widows and orphans properties that determine how many lines must be kept together before or after a break. In XSL and CSS, an ‘orphan’ is a line that is left behind when part of a block of text is carried over after a break, and a ‘widow’ is a line carries on after a break. orphans specifies the minimum number of orphan lines before a break, and widows specifies the minimum number of widow lines after a break. If formatting a block would either leave too few lines or carry over too few lines, then the formatter will force a break so that the conditions are satisfied. A block that contains fewer lines than the sum of the orphans and widows values cannot be broken because doing so would not satisfy one or both of the constraints.
AH Formatter implements extensions for controlling orphan and widows rows of a table as well as for the minimum width of the last line of a paragraph.
9
9
XSL-FO and CSS define both text-align and text-align-last properties for specifying the alignment of the text in a block and an overriding alignment for the text in the last line of a block, respectively. AH Formatter provides an extension property for specifying the alignment of the first line of a block.
XSL-FO and CSS define the text-indent property for specifying the indentation of the first line of text in a block. AH Formatter provides an extension property for the text indent to use at the top of a page or column.
Separate styling of the first line of a block is specified using
<fo:initial-property-set>
in XSL-FO or the first-line
pseudo-element in CSS. Drop capitals, raised capitals, and other styles for the
initial letter in a block is implemented as the axf:initial-letters
extension property for <fo:block>
in XSL-FO and the
-ah-initial-letters extension property for the
::first-letter
pseudo-element in CSS.
The height of the lines in a block is specified using the line-height property in both XSL-FO and CSS. XSL defines line-height-shift-adjustment for controlling whether the line height should change when the line includes content with a baseline-shift, such as superscripts or subscripts. This is available in CSS as the -ah-baseline-shift-adjustment extension property. XSL-FO also defines line-stacking-strategy for specifying the strategy for positioning adjacent lines relative to each other. This is available in CSS as the -ah-line-stacking-strategy extension property.
AH Formatter provides extensions for aligning lines in multiple blocks to a common baseline grid. Blocks can establish their own baseline grid or align to the current grid, the root grid for the entire document, or no grid at all.
XSL-FO and CSS both support leaders: XSL-FO using <fo:leader>
, and CSS
using leader() in the value of the content property.
Leaders in XSL-FO can be unaligned or aligned to the reference area or page. AH
Formatter does not support alignment to the page, but leaders can be aligned to
the start, center, or end of their area. Leaders in CSS are always aligned to
the end edge of their containing block. Leaders in XSL-FO have a specified
length (which can have minimum, optimum, and maximum components), whereas
leaders in CSS always expand to fill the available space on the line. AH
Formatter provides the axf:leader-expansion extension property for
XSL-FO leaders to expand to fill the line and the -ah-leader-length
extension property for CSS leaders to have a specified length.
An <fo:block-container>
, <fo:inline-container>
or a CSS
block can have a fixed height and/or width. It is possible for the content
of the FO or CSS block to overflow the specified dimensions. On paged media,
the content can overflow the available height or width, regardless of
whether the area has a fixed size. XSL-FO and CSS both define the
overflow property that specifies whether and how the content is
clipped when it overflows the area. XSL-FO extends the CSS
overflow by adding two more keywords.
AH Formatter extends the XSL-FO overflow with more ways to recover from an overflow. The extended overflow property is available with both XSL-FO and CSS. AH Formatter can either replace the text of the area or condense the existing text by modifying values of one or more properties until the text fits in the area. Properties that can be adjusted are font-size, font-stretch, line-height, and letter-spacing.
XSL-FO and CSS both support hyphenation: XSL-FO using hyphenate and related properties, and CSS using hyphens and related properties. AH Formatter provides some of the XSL-FO properties that do not have CSS equivalents as extension properties in CSS. AH Formatter provides additional extension properties for hyphenation in both XSL-FO and CSS.
Neither XSL-FO nor CSS define how a formatter determines where to hyphenate
words. AH Formatter implements a hyphenation algorithm for multiple languages,
and it can also use TEX hyphenation dictionaries. Hyphenation
exceptions can also be specified in an external hyphenation information file
and, for XSL-FO, <axf:hyphenation-info>
elements can be included in
<fo:declarations>
in the XSL-FO document. The AH Formatter Option
Setting File can also include a list of unbreakable words that, obviously, will
not be hyphenated.
10
10
XSL-FO and CSS both support footnotes. AH Formatter also supports sidenotes—notes that appear next to their relavent text instead of being collected in one place on the page or column—even though sidenotes are not defined in XSL 1.1 and have been removed from the current CSS Working Draft.
In both XSL-FO and CSS, the markup for sidenotes can be seen as a variation of the markup for footnotes.
An <fo:footnote>
contains both an <fo:inline>
for the
marker that is generated at the point where the <fo:footnote>
occurs and an <fo:footnote-body>
that contains the actual
footnote. The <fo:footnote-body>
includes whatever marker should
appear with the footnote: there is no specific FO for this, although the
footnote body is often formatted as an <fo:list-block>
so that a
marker can be positioned correctly.
The content of the <fo:footnote-body>
is ordinarily formatted in
the footnote-reference-area of the bottom of the
<fo:region-body>
. The footnote-reference-area is implicitly
present in every <fo:region-body>
but it is generated only if the
page contains one or more footnote areas. The footnote-reference-area cannot
be defined as part of defining an <fo:region-body>
in the
<fo:simple-page-master>
. If an footnote-reference-area is
generated, it contains any areas generated by an <fo:static-content
flow-name="xsl-footnote-separator">
in the current page sequence
followed by the areas generated from the <fo:footnote-body>
from
footnotes on the current page (as well as areas from any footnotes carried
over from previous pages). The fo:static-content is used to, for example,
generate a horizontal rule (often using an <fo:leader>
with a
fixed width) or force some white-space between the body text and the
footnotes.
While XSL 1.1 defines footnotes as appearing only in the
footnote-reference-area that spans the bottom of an
<fo:region-body>
, AH Formatter can generate footnotes that are
page-wide or column-wide or are sidenotes at the ends of lines of body text.
Page-wide footnotes can be placed on the current page or only on
odd-numbered pages or only on even-numbered pages. Column-wide footnotes can
be placed in the current column or the first, last, inside, or outside
column on the page. Sidenotes can be placed in the
<fo:region-start>
or <fo:region-end>
at the start,
end, inside, or outside of the line containing the sidenote marker.
AH Formatter can also suppress duplicates of footnotes that would appear more than once in the same page or column.
XSL 1.1 does not define a way for footnote numbers to restart on each page.
The text of the footnote marker in the <fo:inline>
and any
corresponding mark in the <fo:footnote-body>
are expected to be
generated by the XSLT that generated the XSL-FO. AH Formatter can format a
provided numeric marker using any supported number format or counter style.
Alternatively, AH Formatter can generate the footnote number to use and
format that. If desired, the generated footnote numbers can be reset at
page, odd-page, even-page, or column breaks. To reset footnote numbers, for
example, for each chapter, axf:footnote-number-initial="1"
can
be specified on each <fo:page-sequence>
.
Specifying float: footnote;
for an element removes the element
from the flow and causes it to be formatted as a footnote. Similarly,
specifying float: sidenote;
causes an element to be formatted
as a sidenote. A ::footnote-call
(or
::sidenote-call
) pseudo-element is generated in place of the
element. A ::footnote-marker
pseudo-element is placed at the
beginning of the footnote element, and the combination is formatted in the
footnote area. A ::sidenote-marker
is similarly created for a
sidenote.
CSS, like XSL 1.1, defines that footnotes appear only at the bottom of a
page. Sidenotes (when they were still in the GCPM Working Draft) were shown
as floating to the margins of the page. The footnote area is defined by an
@footnote rule in the applicable @page rule (and
the sidenote area by an @sidenote rule). In CSS, the @footnote
rule is expected (or required) to contain float: bottom;
, which
corresponds to or indicates the position of the footnotes. AH Formatter
allows the float property to be any supported value.
The default stylesheet styles the ::footnote-call
pseudo-element
as a superscript digit and the ::footnote-marker
as an inline
list-item marker. The default content of both pseudo-elements is the value
of the footnote counter. The current GCPM Working Draft states
that the footnote counter may be reset for each new page. The AH Formatter
default stylesheet does not reset the counter, so footnote numbers default
to incrementing all through the document. Footnote numbers can be formatted
using any supported counter style.
-ah-suppress-duplicate-footnote suppresses duplicate footnotes in the same page or column in CSS formatting.
11
11
XSL-FO tables and CSS tables are very similar. XSL-FO tables are based on CSS2
tables, and the CSS handling of tables has not been significantly updated since
CSS2. One difference is that CSS can infer “missing” elements around elements
that are displayed as parts of a table and generate anonymous objects so that
the CSS is working with the full set of boxes for a formatted table. In
contrast, XSL allows almost no FOs to be omitted from the XSL-FO
document. The exception is that <fo:table-row>
can be omitted when the <fo:table-cell>
specify starts-row and ends-row to indicate row breaks.
The following image shows some of the FOs and display values for tables:
Tables can have header and/or footer rows in both XSL-FO and CSS. The header and footer rows are repeated when the table breaks across a page or column. XSL 1.1 defines table-omit-header-at-break and table-omit-footer-at-break properties that specify whether the table header or footer, respectively, should be omitted when the table breaks. AH Formatter adds the column keyword for specifying that the header or footer should be omitted at column breaks but not page breaks. CSS does not define corresponding properties, but AH Formatter provides the -ah-table-omit-header-at-break and -ah-table-omit-footer-at-break extension properties for use with CSS.
An <fo:table>
can contain <fo:retrieve-table-marker>
as
a descendent of <fo:table-header>
or <fo:table-footer>
or as a child of <fo:table>
at any position where
<fo:table-header>
or <fo:table-footer>
is allowed.
<fo:retrieve-table-marker>
behaves like
<fo:retrieve-marker>
but its scope is limited to the
<fo:table>
. It has properties retrieve-class-name,
retrieve-position-within-table, and
retrieve-boundary-within-table.
<fo:retrieve-table-marker>
can retrieve multiple rows (if that is
the content of the selected <fo:marker>
), and AH Formatter
provides the axf:retrieve-table-rows extension property to set
the maximum number of retrieved rows.
A table header or footer can contain footnotes. AH Formatter provides the axf:repeat-footnote-in-table-header and axf:repeat-footnote-in-table-footer properties that specify whether footnotes should also be repeated when a table header or footer, respectively, is repeated when the table breaks. The ability to suppress repeated footnotes is not available with CSS.
AH Formatter also provides the axf:table-row-orphans and axf:table-row-widows extension properties—and -ah-table-row-orphans and -ah-table-row-widows extension CSS properties—that specify the minimum number of rows that must remain at the bottom or top, respectively, of the page (or column) when a table breaks.
For a table cell that breaks across a page or column, AH Formatter provides
extensions that either repeat the table cell contents after the break or
generate provided content after the break. axf:repeat-cell-content-at-break and -ah-repeat-cell-content-at-break specify
whether to generate another copy of the table cell’s content after a break.
<axf:table-cell-repeated-marker>
, if present in the XSL-FO,
provides alternative content that is inserted after a break instead of the
second copy of the table cell’s content. In CSS, position:
running(table-cell-repeated-marker);
on an element in a table cell
removes the element from the flow. If its parent table cell breaks, the
formatted element is inserted after the break instead of the second copy of
the table cell’s contents.
Tables can have a caption in both XSL-FO and CSS: in XSL-FO, inside an
<fo:table-and-caption>
as an <fo:table-caption>
that
precedes the <fo:table>
; in CSS, as an element with
display: table-caption;
that is the first child of the element
for the table.
XSL-FO and CSS both define the table-layout property for specifying whether table column widths should be automatically determined from the table’s content or are specified in the table’s markup. AH XSL Formatter is the only XSL formatter that supports automatic table layout, and AH CSS Formatter and the browsers all support automatic table layout.
Table column widths in XSL-FO are specified by the column-width property on <fo:table-column>
, and in CSS, by the width property of an element with display: table-column;
(and in HTML, the width
attribute on <col>
).
Both column-width and width can be a length or percentage, but while column-width in XSL specifies a fixed column width, width in CSS specifies a minimum column width.
XSL, but not CSS, also defines the proportional-column-width()
function for allocating column widths with fixed table layout: after the fixed components of the column widths are determined, the remainder of the available width is allocated in proportion to the proportional-column-width()
values. AH Formatter makes proportional-column-width()
available in CSS.
Although tables are a grid of rows and columns, the markup for both HTML and XSL-FO tables is ‘row primary’, where table cells are descendants of rows and not of columns. This obviously means that inherited properties cannot ordinarily be inherited from a column definition.
Both XSL and CSS define that border and background properties can apply to cells in the current table column. Border properties from the column definition can apply when border-collapse is collapse (or, in XSL-FO, also collapse-with-precedence).
CSS defines an algorithm for resolving the conflict when multiple border property specifications apply to an edge of a table cell; for example, conflicting border property specifications on the table cell, the table row, and the table column. In essence, the algorithm chooses the most ‘eye catching’ border style unless any of the elements specifies hidden.
XSL adopted the same algorithm for use when border-collapse is separate. When border-collapse is collapse-with-precedence, conflicts are resolved based on the integer precedence value assigned to each FO that can supply the border of a table cell. The default precedence values give priority to a table’s ‘outer’ FOs as well as prioritizing column borders over row borders: <fo:table>
, 6; <fo:table-cell>
, 5; <fo:table-column>
, 4; <fo:table-row>
, 3; <fo:table-body>
, 2; <fo:table-header>
, 1; <fo:table-footer>
, 0. However, each table FO can specify a different precedence value for each of the four edges, and can specify force to override all other precedence values.
XSL defines the from-table-column()
function that can be used on an <fo:table-cell>
or its descendants to retrieve the inherited value of a property as specified on the corresponding <fo:table-column>
.
The first line of text in multiple table cells in a table row can have the
same baseline in both XSL-FO and CSS, even when text in different cells have
different font sizes. For XSL-FO, use
relative-align="baseline"
, and for CSS, use
vertical-align: baseline;
. CSS defines this behavior for
vertical-align only for table cells. Other than on table cells,
vertical-align: baseline;
in CSS aligns the alphabetic baseline
of the element with the alphabetic baseline of its parent element. XSL 1.1
also defines vertical-align, but only as a shorthand for
multiple XSL-FO properties and only to match the non-table cell usage in
CSS.
Horizontal alignment of text in a table cell is the same in both XSL-FO and CSS when using AH Formatter. XSL 1.1 defined more values for text-align than are defined in CSS2. AH Formatter also implements the XSL 1.1 values for CSS formatting. The CSS Text Module Level 3 defines some different keywords that achieve the same effects as the XSL 1.1 text-align and related properties, except for one difference.
XSL 1.1 (and, consequently, CSS formatting in AH Formatter) allows the value
of text-align on descendents of a table cell to be a string.
Each of the blocks in one table column that have a string value for
text-align will be aligned horizontally so that all of their
strings are in the same vertical line. A typical usage is to align all of
the numbers in a table column on their decimal point (.) by specifying
text-align='"."'
or text-align: ".";
. AH Formatter
also provides the axf:text-align-string and
-ah-text-align-string extension properties for specifying the
alignment of the aligned strings within their table cells.
Entire tables and the content of individual table cells can be rotated both
in XSL-FO and in CSS with an AH Formatter extension. In XSL-FO, an
<fo:table>
can be placed in an <fo:block-container>
that specifies the reference-orientation property, and an
<fo:table-cell>
can contain an <fo:block-container>
that specifies the reference-orientation property. In CSS, the
-ah-reference-orientation extension property can be specified
on both tables and table cells.
The row-and-column grid of a table can be difficult to convey using a screen reader or other assistive technology. For XSL-FO, AH Formatter provides axf:table-summary, axf:headers, and axf:scope extension properties, and for CSS, the corresponding -ah-table-summary, -ah-headers, and -ah-scope properties. These properties bridge between attributes in HTML tables (or other XML markup) and PDF attributes in Tagged PDF and PDF/UA. For XML source that is transformed into XSL-FO, the properties can derive from the source XML or can be added by the XSLT stylesheet.
axf:table-summary and -ah-table-summary correspond
to the summary
attribute of table
in HTML 4.01.
(summary
was deprecated in HTML5 in favor of
caption
, even though caption
functions like a
heading for the table and summary
was meant to convey
information about the organization of data in the table and to help users
navigate the table. [WAI])
axf:table-summary and -ah-table-summary also
correspond to the Summary
attribute for tables in Tagged PDF
and PDF/UA that was introduced in PDF 1.7.
axf:headers and -ah-headers indicate the table head cells that apply to the current table cell. axf:scope and -ah-scope work the other way and indicate whether the current table head cell applies to following cells in the same column, following cells in the same row, or all cells ‘down’ and ‘to the right’ of the current cell.
12
12
XSL defines specialized FOs for representing lists. The FO structure for a two-item list, where indentation represents containment, is:
fo:list-block fo:list-item fo:list-item-label (%block;)+ fo:list-item-body (%block;)+ fo:list-item fo:list-item-label (%block;)+ fo:list-item-body (%block;)+
(block;)+
means one or more block-level FOs. This
includes <fo:block>
and <fo:block-container>
, but it
also includes, for example, <fo:table>
and
<fo:list-block>
. It is possible to put structured content into an
<fo:list-item-label>
as well as into an
<fo:list-item-body>
.
XSL-FO defines the relative-align property for aligning the
baselines of the first lines of an <fo:list-item-label>
and
<fo:list-item-body>
.
There is no automatic numbering of list items in XSL-FO. The list item label is expected to be generated by the XSLT transformation. The number could be copied from the source document or it could be generated based either on the structure of the source or on the logic in the stylesheet. XSLT defines a limited number of numbering schemes that can be used to format the list item label. AH Formatter provides the axf:number-transform extension property, which supports more numbering schemes than are provided by XSLT.
axf:number-transform causes the number to which it applies to be formatted as ideographic numerals, as one of the CSS-style counter styles (including symbolic styles), or as one of the styles for the format property. XSL 1.1 defines format as matching the XSLT 1.0 [XSLT10] format attribute, but AH Formatter extends this to support many more numeric, alphabetic, and symbolic sequences.
XSL-FO defines some properties and functions to make it easier to use the
same margins for all of the items in the one list. The
provisional-label-separation property of
<fo:list-block>
is part of the formula for
label-end(), which is used to determine the end-indent of an
<fo:list-item-label>
. Similarly,
provisional-distance-between-starts is part of the formula for
body-start(), which is used to determine the start-indent of an
<fo:list-item-body>
. The XSL 1.1 Recommendation does not state
why ‘provisional’ is included in the properties’ names, but the properties’
values are only one part of each formula. Also, the value of a property
where the functions are used can be an expression that adds or subtracts
other lengths or even multiplies the function value by some number.
An element with display: list-item;
generates a block box plus
a marker box. [CSS3-Display] The same
specification also says that the list-item
keyword generates a
::marker
pseudo-element with the content specified by the
‘list-style’ properties: list-style-type,
list-style-position, and list-style-image, with
list-style as the shorthand property for all three.
The content of the marker box can be a combination of text and images. More specifically, it is the first of:
The value of the content property, if that is not
normal
This can be the value of an arbitrary counter that is formatted using any counter style.
An image generated from list-style-image (followed by a space character)
String generated from list-style-type
This can be a literal string or a counter style used for formatting the value of the built-in ‘list-item’ counter.
Otherwise, there is no marker box.
13
13
The fundamental and most-used properties for setting characters—properties such as line-height, font-family, font-style, font-variant, etc.—were defined in CSS1 and CSS2 and, therefore, are also defined identically in XSL-FO. Character-level properties from CSS3 modules that AH Formatter implements are also implemented in XSL-FO as extensions. AH Formatter also implements its own extension properties for both XSL-FO and CSS. For example, CSS3-Text defines text-underline-position for specifying the position of underlines. AH Formatter implements text-underline-position for CSS and implements axf:text-underline-position for XSL-FO. In addition, it implements extension properties for specifying the color, line style, and line width of underlines in both XSL-FO and CSS.
CSS defines the @font-face rule that allows the stylesheet to automatically fetch and activate fonts instead of using only the fonts known to the formatter. XSL 1.1 does not define an equivalent feature, but AH Formatter implements the <axf:font-face>
extension element for use with XSL-FO.
14
14
Requirements for Japanese Text Layout 日本語組版処理の要件(日本語版) [JLREQ] is a comprehensive desciption of requirements for general Japanese layout. XSL-FO and CSS both define broad support for a range of writing modes and scripts, but neither sets out to address the full range of Japanese text composition described in JLReq. CSS defines more support for Japanese than does XSL-FO, including: Japanese-specific counter styles; ruby; and horizontal-in-vertical tate-chu-yoko text.
AH Formatter provides a large set of extensions for both XSL-FO and CSS to support Japanese text composition. The extensions cover:
15
15
XSL-FO generates links from <fo:basic-link>
, whereas CSS
specifications assume that the browser implements the <a>
element.
Many cross-references include the title, page number, or section number, etc.,
of the subject of the cross-reference. XSL-FO assumes that all text other than
page numbers is included in the FO tree, whereas CSS provides functions for
retrieving text content or counter values from a target element.
XSL 1.1 defines <fo:basic-link>
, which has separate
internal-destination and external-destination
properties for referring to IDs within the FO tree and external resources,
respectively. One of the properties, but not both, should be specified on an
<fo:basic-link>
.
<fo:root>
, <fo:page-sequence>
,
<fo:page-sequence-wrapper>
, and nearly every FO that can be used
within an <fo:page-sequence>
can have an id
property. <fo:change-bar-begin>
and
<fo:change-bar-end>
, for example, do not have an id
property. AH Formatter supports xml:id as an alternative to
id on FOs that can have id.
CSS relies on a browser’s implementation of the href attribute
of the <a>
element to provide linking behavior. The HTML5
specification for a UA stylesheet [WHATWG] does
not specify anything for the href
attribute. The default
html.css
file for AH Formatter defines href
as
setting the -ah-link extension property:
a[href] { -ah-link: attr(href url); }
-ah-link can similarly be used with other, non-HTML XML vocabularies to generate hyperlinks from other elements or attributes.
XSL-FO assumes that references to the number or title of chapters, sections,
tables, and figures, etc., will be generated by the XSLT that generated the
XSL-FO. The full source document is available to the XSLT processor, and
XSLT includes <xsl:number>
, which can generate multi-level
numbers in a variety of formats. Consequently, XSL-FO does not include a
mechanism to copy text from elsewhere in the FO tree.
The only text that XSL-FO can generate is for values that are not known
before the document is formatted: page numbers and page number references
(and the scaling factor of formatted graphics). <fo:page-number>
generates the page number of the current page.
<fo:page-number-citation>
generates the page number of the page
containing the first normal area from the referenced FO, and
<fo:page-number-citation-last>
generates the page number of the
last page of the referenced FO.
AH Formatter extensions for page numbers in XSL-FO include:
<fo:page-sequence>
CSS can generate text based on the content or position of another element in the
document. The target-text() function retrieves the text value
of a target element or, alternatively, the text value of its
::before
or ::after
pseudo-element or its first
letter. target-counter() (and also
target-counters()) retrieves the value of a named counter as
seen by a target element. To obtain the page number of a target element, use
target-counter() and specify the page counter:
content: target-counter(attr(href url), page);
The AH Formatter extensions for physical and reverse page numbers are available by adding a keyword. For example, to generate the physical page number of a target element:
content: target-counter(attr(href url), page physical);
CSS does not have an equivalent to
<fo:page-number-citation-last>
.
16
16
CSS2 defines the float property, with values left,
right, and none (initial value), as applying to all
elements. left and right float the block to the left
edge and right edge, respectively, of the current block’s containing block. XSL
1.1 limits float to apply to only <fo:float>
. It adds
the before value specifying that the content of the
<fo:float>
is generated in the before-float-reference-area at the top
of a body region. It also adds start, end, inside, and
outside values for specifying the horizontal position of the
<fo:float>
.
AH Formatter extends the float property to be a shorthand for multiple extension properties—available with both XSL-FO and CSS—that provide greater control over the placement of floats. Floats ordinarily float within the current reference area, but they can be specified to float within the page area, multi-column area, or current column. A float can be forced to be placed in the current page or column, moved to the next page or column if there is not enough space in the current page or column, kept in the current page or column while the float’s anchor is moved to the next page or column, or floated to appear on a specific page. There are additional extension properties for how text can flow around a float and for the margins between a float and its surrounding text or its neighboring float. Floats can be made to span a subset of the columns in a multi-column area.
Footnotes and sidenotes in CSS are generated by specifying float: footnote;
and float: sidenote;
, respectively.
17
17
XSL 1.1 does not mention MathML, and it mentions SVG as a common format for
<fo:instream-foreign-object>
content but does not require that SVG is
supported. SVG can be embedded in HTML5, and CSS 3 modules are written with the
assumption that SVG graphics are supported.
AH Formatter provides custom MathML 3 and SVG renderers for including MathML and SVG in PDF output. Output of entire formatted documents in SVG is possible with the SVG Output Option add-on.
AH Formatter natively supports MathML 3, whereas browsers and MathJax implement a subset of MathML 2. Improvements between MathML 3 and MathML 2 include:
<mglyph/>
for displaying images of non-standard symbolshref
added to common attributes to allow elements to link to a URI18
18
XSL 1.1 is designed to generate and format numbers only for page numbers and scaling value citations, because they are the only numbers that cannot be known before the document is formatted. All other numbers are assumed to have been generated by the XSLT stage.
The format property on <fo:page-sequence>
specifies the
format both for the page numbers on pages generated by that
<fo:page-sequence>
and also for <fo:page-number-citation>
that refer to an area on a page generated by that <fo:page-sequence>
.
<fo:scaling-value-citation>
, added in XSL 1.1, is used to obtain the
scale-factor that is applied to a cited <fo:external-graphic>
.
Note that XSL 1.1 does not need to generate numbers for footnotes because it does not define a way for footnote numbers to restart on each new page or new column. Restarting footnote numbers is possible, however, with an AH Formatter extension.
CSS, for possibly every element, can generate a number based on the position of the element. The format of the number is determined by its ‘counter style’. A counter style is a particular algorithm for generating a representation of a number. CSS defines many more counter styles than XSL 1.1 defines number formats. It is also possible to define and use a new counter style within a CSS stylesheet, and any counter style can extend another counter style or fall back to using another counter style for numbers that are outside the range of the current counter style.
AH Formatter implements CSS-style counter styles for both CSS and XSL-FO, in
addition to supporting the XSL 1.1 format property for XSL-FO. For
XSL-FO, AH Formatter uses the counter style to format an existing number,
except for generated page numbers and <fo:scaling-value-citation>
values.
Besides the predefined counter styles, a new counter style is defined in XSL-FO
using the <axf:counter-style>
FO within <fo:declarations>
.
<axf:counter-style>
has identical properties to an
@counter-style rule in CSS. A counter style name, or any XSL 1.1
format string, can be specified on any block-level or inline-level
FO by specifying axf:number-transform. When
axf:number-transform is not none, any positive or
negative integer sequence is transformed using the specified counter style or
number format. Counter styles can also be used as the value of the
format property of <fo:page-sequence>
to specify the
format for page numbers of pages generated by that
<fo:page-sequence>
.
A CSS counter is a special numeric tracker used, among other things, to
automatically number list items in CSS.
Counters are created,
incremented, or set by specifying CSS properties. There are some predefined
counters, such as the page
counter for page numbers, that are
always present and that are automatically incremented. For example, the
page
counter is incremented with each new page. The value of a
predefined counter can also be modified by setting CSS properties.
CSS supports the following properties on an @counter-style rule,
which AH Formatter also supports on <axf:counter-style>
in
XSL-FO:
The following example shows a ‘my-filled-circled-decimal’ counter style that is a based on the ‘filled-circled-decimal’ counter style from CSS Counter Styles Level 3. [CSS3-CounterStyles] As the name suggests, the counter style uses decimal numbers inside filled circles to represent decimal numbers. The generated symbol is followed by a space.
@counter-style my-filled-circled-decimal { system: fixed; /* Using hex escape of Unicode character codes. */ symbols: '\2776' '\2777' '\2778' '\2779' '\277a' '\277b' '\277c' '\277d' '\277e'; /* symbols: '❶' '❷' '❸' '❹' '❺' '❻' '❼' '❽' '❾'; */ suffix: ' '; }
The XSL-FO equivalent using <axf:counter-style>
is:
<axf:counter-style name="my-filled-circled-decimal" symbols="'❶' '❷' '❸' '❹' '❺' '❻' '❼' '❽' '❾'" suffix=" " />
Use axf:number-transform to represent numbers using the counter style:
<fo:list-item-label axf:number-transform="my-filled-circled-decimal"> <fo:block>1</fo:block> </fo:list-item-label>
format and its related properties—grouping-separator, grouping-size, letter-value, country, and language—take their definition from the corresponding XSLT 1.0 number-to-string conversion attributes. XSL is defined as both XSLT and XSL-FO, and XSLT 1.0 was the current XSLT version when XSL 1.0 became a Recommendation.
format in XSLT specifies the format of the numbers generated by
<xsl:number>
. <xsl:number>
can generate a list of
numbers (when level="multiple"), and the XSLT
format attribute contains a sequence of alphanumeric tokens for
the format of the potentially multiple levels of number generated by
<xsl:number>
. These are separated by non-alphanumeric tokens that
are repeated as the punctuation between the generated numbers.
format in XSL-FO is just one alphanumeric token that specifies
the format for the page number or for the scaling value.
<xsl:number>
generates only integers, and page numbers are only
integers and <fo:scaling-value-citation>
generates only an
integer percentage value. Any prefix or suffix on a page number is specified
with <fo:folio-prefix>
or <fo:folio-suffix>
,
respectively. Using separate FOs for the prefix and suffix allows them to be
styled differently from the style for the page number, if desired. Any ‘%’
(or similar) suffix for an <fo:scaling-value-citation>
would have
to be included in the text of the XSL-FO document.
The number formats defined for format in XSLT are aspirational
rather than comprehensive. The format tokens are designed as a superset of
the allowed values of the type attribute for the
<OL>
element in HTML 4.0, but only five token formats are
required:
1 2 ... 10 11 12 ...
(and
01 generates 01 02 ... 09 10 11 12 ... 99 100 101
...
, and so on)A B C ... Z AA AB AC...
a b c ... z aa ab ac...
i ii iii iv v vi vii viii ix x
...
I II III IV V VI VII VIII IX X
...
Any other character can be used to indicate a numbering sequence, provided that the processor supports it. AH Formatter supports an extensive range of format tokens for numbers in multiple scripts, as well as multiple styles of Roman numerals and even Chinese zodiac signs and the ‘*’, ‘†’, ‘‡’ sequence that is traditionally used for footnotes in English. However, the range is not extensible. If something else is required, you can specify one of the predefined CSS counter styles or specify the name of your own counter style as the value of the format property. For more information, see “format” in the AH Formatter manual.
19
19
XSL 1.1 supports only colors specified as RGB or as a color in an ICC (International Color Consortium) color profile using the rgb-icc() function. A color profile defines the conversion between a standard color space and a native or device-dependent color space. An ICC color profile is a cross-platform standard for the color profile format.
In XSL 1.1, in common with CSS2:
#
followed by three or six
hexadecimal digits or using the rgb() function(system-color() is seldom, if ever, used, and CSS deprecated its use in the CSS Color Module Level 3.)
CSS Color Module Level 3 [CSS3-Color]:
AH Formatter implements all of the color representations from CSS Color Module 3 as well as:
AH Formatter implements transparent text by reserving space for the text, but it does not generate any characters in the output. Use rgba(0, 0, 0, 0) to generate invisible text that is included in the output.
More than 1,000 PANTONE® colors can be specified by name and printed as a spot color or be converted into the correct RGB or CMYK for rendering or printing when you have the AH Formatter PANTONE® Option
20
20
Similarly to the character setting properties, the fundamental and most-used properties for borders and backgrounds were defined in CSS1 and CSS2 and, therefore, are also defined identically in XSL-FO. Border and background properties from CSS3 modules that AH Formatter implements are also implemented in XSL-FO as extensions. AH Formatter also implements its own extension properties for both XSL-FO and CSS.
CSS 3 provides properties for specifying rounded corners on any element that can have a border. XSL 1.1 does not define equivalent features, but rounded corners are available as an AH Formatter extension.
XSL 1.1 and CSS 2 support a single background image for a box. CSS 3 allows a box to have multiple background images, which AH Formatter also supports in XSL-FO as an extension.
CSS 2 defines the background-position property for specifying the horizontal and vertical position of a background image, or, with CSS 3, background images. XSL 1.1 treats background-position as a shorthand for the separate background-position-horizontal and background-position-vertical properties.
CSS 2 defines the background-repeat property for specifying whether and how a background image is repeated. CSS 3 defines additional keywords that provide more control over how a repeated image covers the available area.
AH Formatter implements the CSS 3 background-position values for both XSL-FO and CSS and adds a paginate value that is available when embedding a PDF as the background image of a page. Successive pages from the embedded PDF provide the backgrounds of successive pages in the output. The background images can be a subsequence of pages from the embedded PDF. If necessary, extra output pages are generated to match the number of embedded PDF page images.
21
21
AH Formatter supports the same range of PDF versions and the same range of PDF features, such as layers and Tagged PDF, for PDF output from both XSL-FO and CSS.
XSL 1.1 added <fo:bookmark-tree>
and related FOs to hold a list
of access points within the document such as a table of contents, a list of
figures or tables, etc.
The bookmark tree is separate from the visible
content of the document. If present, it is a child of <fo:root>
,
and it appears before the first <fo:page-sequence>
(or
<fo:page-sequence-wrapper>
).
<fo:bookmark-tree>
contains one or more <fo:bookmark>
.
An <fo:bookmark>
contains an <fo:bookmark-title>
and
can also contain any number of subordinate <fo:bookmark>
. An
<fo:bookmark>
can have either an
internal-destination property to refer to the ID of an FO in
the current document or an <fo:external-destination>
to refer to
an external resource. The following figure shows a sample bookmark tree structure, where indentation represents containment:
fo:bookmark-tree fo:bookmark fo:bookmark-title fo:bookmark fo:title fo:bookmark fo:bookmark-title fo:bookmark fo:bookmark-title fo:bookmark fo:bookmark-title
Because the bookmark tree is separate from the visible content and also
because an <fo:bookmark>
can refer to any destination, the
bookmark tree does not have to represent the exact structure of the
document. It is possible, for example, to refer to related documents or web
pages from the bookmark tree or it can present multiple views of the
document, such as listing sections and also tables in the bookmark tree.
An <fo:bookmark>
can be specified as initially showing or hiding
its subordinate <fo:bookmark>
. An <fo:bookmark-title>
can contain text only. Because the bookmark tree is typically generated
using XSLT, the text can match the corresponding section title. In some
cases, it can be necessary to transform superscript or subscript text into
their corresponding plain text form. An <fo:bookmark-title>
can
have a specified color, its font weight can be normal or bold, and its font
style can normal or italic.
Bookmarks in CSS follow the structure of the elements in the document that generate bookmarks. CSS defines an bookmark-level property that applies to all elements. Its value is either none (the default) or an integer, where 1 is the highest level bookmark. The bookmark-label property specifies the text content of the bookmark label. Its initial value is content(text), which generates the text content of the element. The content that can be specified for bookmark-label is the same as for the string-set property: any combination of literal strings, counter values, the content of the current element (or its pseudo-elements), or the value of an attribute of the current element. AH Formatter also allows the -ah-attr-from() and -ah-attr-img() extension functions in bookmark-label.
Bookmarks in CSS automatically link from the bookmark to the element that generated the bookmark. The -ah-outline-internal-destination extension property specifies an ID or a page number (with optional zoom factor) that is used instead of the default link. Alternatively, the -ah-outline-external-destination extension property specifies a URL to use as the link destination.
AH Formatter supports -ah-outline-color, -ah-outline-font-style, and -ah-outline-font-weight extension properties in CSS to provide the same control over the appearance of the bookmark label as is available with XSL-FO.
A block-level element that generates a CSS bookmark label can have a bookmark-state property. When bookmark-state is open, the bookmark label and the bookmark labels of the nearest descendant elements that generate bookmark labels will be shown. Otherwise, the value is closed, and only the bookmark label of the current element is shown.
AH Formatter additionally supports its own extensions for generating bookmarks based on the structure of the document. In general, it is better to use the standard XSL-FO or CSS mechanism instead. The exception is when XSL-FO is formatted to generate multiple PDF volumes. When the AH Formatter extensions are used, a bookmark tree can be generated in the first volume or in each separate volume. The bookmark tree can either cover all the volumes and be the same in each volume or it can cover the current volume only. The AH Formatter extensions include a mechanism for optionally grouping bookmarks. When the bookmark tree is for only the current volume, any bookmark groups in the entire document can appear either in the bookmark tree in the last volume or in the bookmark tree of every volume.
22
22
The key features of a ‘back-of-the-book’ index are:
Some books have multiple indexes
An index is a sorted, and usually also grouped, set of headwords
In paged media, headwords have an associated list of page numbers of the pages that contain content relevant to the headword
The list of page numbers can include either or both of: sequences of consecutive page numbers for multiple separate instances of content that is relevant to the headword; and page ranges for relevant content that spans several pages
Some page numbers can have different styles from others: for example, bold numbers to indicate the most important content, or italic numbers to indicate pages with figures or examples
When starting from XML or HTML, the index terms are usually included in the markup for the body of the document, and these are sorted and collated to generate the markup for the index. Alternatively, the index could be maintained as an external document with cross-references to IDs in the document being indexed.
Sorting and collating the index terms to produce a list with no duplicates can be done without formatting the document, but correct page number references to the original locations of the index terms can only be made once the document is formatted
When an index term appears twice on the one page, the formatter must be able to merge duplicate page numbers
In some cases, when the same index term appears on successive pages, the formatter must merge successive page numbers into a page range
Some typographic traditions have shorthand notations for an index term appearing on two or three consecutive pages: for example, ‘8f.’ for an index term on pages 8 and 9, or ‘8ff.’ for an index term on pages 8, 9, and 10.
XSL 1.1 expects that an XSLT transformation will convert index terms in the
source XML into index-key properties in the XSL-FO and also
sort and collate the index terms to generate the FOs used for formatting the
index (or indexes). The bulk of the FOs for a formatted index will be the
general-purpose <fo:block>
, and so on, for the list of headwords.
The page references for each headword are generated from an
<fo:index-page-citation-list>
. These FOs are also expected to be
generated by the XSLT transformation based on the index terms in the source
XML. In fact, it is an error if a contained
<fo:index-key-reference>
does not match any index term in the
document.
XSL 1.1 defines multiple FOs for the index reference and, optionally, any prefix or suffix to add to each page number reference. For example, the XSL 1.1 Recommendation shows the example of ‘[’ and ‘]’ around index references to figures. The page numbers, and any prefix or suffix, can be styled using inherited properties such as font-style and font-weight.
There are also properties that specify when and how to merge sequential page
numbers and whether to merge page numbers and page ranges across different
<fo:index-key-reference>
. This controls, for example, whether
index references to figures can be merged with ‘ordinary’ index references
to the same or adjacent pages. AH Formatter extends the
merge-sequential-page-numbers property to allow shorthand
notations to be used for two and three successive pages.
All of the page number references in the index must be included in the document being formatted. Unlike with XSL-FO, there is no facility for generating page number references based on an index key.
AH Formatter provides the -ah-merge-sequential-page-numbers extension property for merging sequential page numbers. When specified on a block-level element, adjacent identical page numbers are merged into one number, and sequences of sequential page numbers are merged into ranges. The page references must be to pages earlier in the document. Generating the shorthand notations for two or three consecutive pages is also possible with CSS.
Suppose the following CSS is specified.
p.index-page-citation-list { -ah-merge-sequential-page-numbers: merge; } span.index-item { content: target-counter(attr(href), page); }
Then, suppose the following HTML exists.
<p class="index-page-citation-list"> <span class="index-item" href="#id1"/>, <span class="index-item" href="#id2"/>, <span class="index-item" href="#id3"/>, <span class="index-item" href="#id4"/>, <span class="index-item" href="#id5"/>, <span class="index-item" href="#id6"/>, <span class="index-item" href="#id7"/>, <span class="index-item" href="#id8"/>, <span class="index-item" href="#id9"/> </p>
Suppose the page numbers line up as follows:
1, 3, 4, 4, 5, 6, 8, 8, 9
The result will be:
1, 3–6, 8, 9
If -ah-merge-sequential-page-numbers: merge-f; is specified instead, the result will be:
1, 3–6, 8f.
23
23
This discussion of XSL-FO and CSS has already covered many features and extensions that make AH Formatter uniquely capable of formatting using either XSL-FO or CSS. AH Formatter has yet more features that do not fit neatly into the preceding classifications.
Unless stated otherwise, these features apply to both XSL-FO and CSS formatting.
Two-pass formatting is a feature for formatting large documents that is only available for XSL. This is an AH Formatter feature that is outside the scope of either XSL or CSS.
In single-pass formatting, AH Formatter must keep a page in memory until the page
numbers of all <fo:page-number-citation>
on the page are resolved.
All of the following pages are also kept in memory until the page that is the
target of the last unresolved <fo:page-number-citation>
is
formatted.
In two-pass formatting, the first pass resolves and saves the
<fo:page-number-citation>
values but does not save any formatted
pages. In the second pass, AH Formatter immediately resolves every
<fo:page-number-citation>
using the saved page number information and
flushes each page from memory as soon as it is formatted. This allows extremely
large documents to be formatted.
In XSL formatting but not CSS formatting, a document can be output as multiple PDF files. The bookmarks included in the PDF files can be the same in all volumes or can be different in each volume. The bookmarks in one volume can also refer to IDs in other volumes.
AH Formatter provides extensive control over the fonts that can be used.
The AH Formatter font configuration file specifies:
The Option Setting File specifies:
AH Formatter provides extension properties for the display of line numbers. Line numbers can be counted starting from: the current page sequence or a previous page sequence; current page; current column; previous column in the current table; or the current block. The position and appearance of the line number can be specified. The interval between displayed line numbers can be specified, as can a sequence of line numbers that must always be shown.
AH Formatter provides extension properties for the display of a mark when a line breaks.
You can specify when a color or colors should overprint underlying colors instead of colors that are masked by other colors not printing at all.
In XSL-FO but not CSS, it is possible to define horizontal alignment points—similar to tab stops in a word processor. An <axf:tab>
, and optionally a tab character (U+0009), aligns its following text on the next tab stop. The start, end, or center of the text, or a decimal point within the text, can be aligned on the tab stop.
AH Formatter can analyze the formatted text to identify potential typographic problems such as: lines with excessive white-space; rivers of white-space over successive lines; short lines at the end of paragraphs or at the start of a page; consecutive lines starting or ending with the same word; unbalanced spreads; consecutive lines that end with a hyphen; excessive blank pages at the end of the document; and too few lines before or after a block of text.
Automated analysis is quicker and more reliable than visually inspecting every formatted page. However, AH Formatter cannot fix the problems for you. Solving these problems usually requires editorial or stylistic changes, and sometimes both.
The Barcode Generator Option allows you to embed barcodes, including QR codes, directly in the output as either an SVG or PNG image. Barcode fonts are not required.
<!-- XSL-FO example --> <fo:external-graphic src="data:application/vnd.ah-barcode;type=QR; scale=2,Hello%20World!"/>
<!-- HTML example --> <img src="data:application/vnd.ah-barcode;type=QR;scale=2, Hello%20World!"/>
24
24
XSL-FO and CSS have a lot of similarities because of their commitments to use common properties when XSL 1.0 and CSS2 were developed. More differences developed as XSL and CSS each added new features. AH Formatter smooths out most of the differences by providing many of the properties from one technology as extensions available to the other technology. In addition, AH Formatter provides a large number of original extensions that are, as much as possible, available in both technologies.
Whichever technology you use, or if you use both XSL-FO and CSS, AH Formatter is able to provide more and finer control over the formatted result than any comparable formatter.