Although the chunk stylesheet provides many parameters that control the chunking of your document into multiple HTML files, you may have a need for further customization. If you need to customize how elements are chunked, as opposed to how they look, then you should use version 1.73 or later of the stylesheets. Those templates are cleanly separated, so customization is easier.
If you examine the
html/chunk.xsl file from version 1.73 or above, you will see that all it does is load other stylesheet modules.
<xsl:import href="docbook.xsl"/> <xsl:import href="chunk-common.xsl"/> <xsl:include href="chunk-code.xsl"/>
The use of both
xsl:include, and the order in which they are used, are important for allowing clean customization. It also allows you to create a customized version of the single-page stylesheet as well as the chunking stylesheet using modular files.
Here are the steps for creating customizations of both chunking and single-page stylesheets.
Create a customization file for single-page output as described in the section “Customization layer”. Let's say you name that file
mydocbook.xsl. It should contain:
xsl:import of the stock
html/docbook.xsl non-chunking stylesheet.
Any parameter settings and customizations of how elements should be styled. You can include any parameters that appear in the
html/param.xsl stylesheet module, even if they control chunking.
html/chunk.xsl file to another customization file, such as
mychunk.xsl. Edit that file as follows:
Import your single-page customization file, which imports docbook.xsl: <xsl:import href="mydocbook.xsl"/> <xsl:import href="chunk-common.xsl"/> <xsl:include href="chunk-code.xsl"/> Add your parameter settings and customizations that affect chunking behavior here.
chunk-code.xsl is included, not imported.
If you customize any chunking templates with a
match attribute (as opposed to a
name attribute), then add a
priority="1" attribute to the
xsl:template element in your customization layer. The next section explains why.
The chunking stylesheet has to process any chunked element in two different ways. A chapter, for example, is always a chunk, and so there must be a template for chapter that generates a new file and adds the correct navigational header and footer. A chapter also has content to be formatted, and so there is another template for chapter that converts its content into HTML elements within the chunk file.
In most situations, processing an element in two different ways is done using a template mode. This does not work for chunking, because of the nature of nested chunks. If you were to create a template for chapter with
mode="chunk", then you could use that to create the chunk file and navigational header/footer. Inside that template you just process the chapter in normal mode to format it for HTML. When that normal processing hits a section, it just processes the section as part of the chapter, and does not chunk the section. Somehow the normal mode has to apply-templates to sections in
mode="chunk", but the normal mode template has no knowledge of chunking.
So the chunking stylesheet takes a different approach. It operates the two different processes at two different import levels. The chunking stylesheet imports the regular stylesheet, and so the chunking templates have a higher import precedence. There is a chunking template with
chunk-code.xsl), but it is in normal mode. It is applied first because it has a higher import precedence than the
match="chapter" template in the non-chunking stylesheet. It opens a new chunk file and writes the navigational header. Then it uses
xsl:apply-imports to format the elements in the chapter. The
xsl:apply-imports element ignores matches in the current import level and reaches back to find a match in lower import levels. It finds the
match="chapter" template in
component.xsl, and uses that to generate HTML for the chapter.
section element within a chapter is encountered, the non-chunking template is using an
xsl:apply-templates instruction. The processor looks for a
match="section" template, and it looks for the match with the highest import precedence. The chunking version of
chunk-code.xsl has the highest import precedence. This is the case even when the chapter is being processed with a template found via
xsl:apply-imports. The import level is not inherited when templates are applied. So the section chunking template starts a new chunk file (while the chapter file is still open for writing), and adds the section navigational header. Then the chunking section template does
xsl:apply-imports, and the section is processed with the non-chunking section template to format it. Repeat as needed. When all the section chunks are completed, the non-chunking chapter template runs out of content and finishes. Control returns to the chunking version of the chapter template, which writes the navigational footer and closes the chapter chunk file.
The advantage of this approach is that there is no mode to keep track of, and the original non-chunking templates can be reused without being duplicated (which is a maintenance headache). This approach does require care when customizing, because customization introduces more import levels. The following list describes how the templates are arranged in import levels in a customization, starting with the lowest import precedence. This description applies to version 1.73 and later of the stylesheets.
The original non-chunking templates are at the bottom of the import ladder. If there is no match on an element in the higher import levels, then these are the templates of last resort. In fact, most elements are handled at this level. Only chunked elements and elements you customize are affected by higher import levels.
The next import level up consists of customizations of templates from the non-chunking stylesheet. These are the templates in a non-chunking customization layer such as
mydocbook.xsl that imports the base stylesheet. You can use
mydocbook.xsl to generate single-file HTML output.
The next import level up consists of the stock chunking templates.
All of the chunking templates with a
name attribute are in
chunk-common.xsl. These are utility templates that are not matched to specific elements.
All of the chunking templates with a
match attribute are in
chunk-code.xsl. These are the templates that initiate chunking for specific elements.
The final import level consists of your customizations of chunking templates. These are in a customization layer such as
mychunk.xsl that looks like the following:
<xsl:import href="mydocbook.xsl"/> <xsl:import href="chunk-common.xsl"/> <xsl:include href="chunk-code.xsl"/> Add your template customizations that affect chunking behavior here.
chunk-common.xsl templates are imported. If you customize a named template from
chunk-common.xsl, then your template will have higher import precedence than the original imported template.
chunk-code.xsl is included, not imported. Because it is included, if you customize a template from
chunk-code.xsl, then your customization has the same import precedence as the original chunking template. That's why you must add a
priority="1" attribute to your customized match template. If you do not, then the XSL processor will complain that there are two templates that match on one element. Adding the
priority attribute resolves the conflict.
xsl:include instead of
chunk-code.xsl? The reason is the use of
xsl:apply-imports in those templates. It must maintain a single level of import level difference in order to reach the non-chunking template when
xsl:apply-imports is used.
If you were to use
chunk-code.xsl, and then customize one of those templates, here is what would happen:
Your customized chunking template initiates a chunk file for an element such as chapter.
Then your customized chunking template uses
xsl:apply-imports to format the content of the chapter.
The processor looks for a template with
match="chapter" below the current import level.
It finds the template with
chunk-code.xsl, which is imported. But that is the original chunking chapter template, not the non-chunking version that you need.
The original chunking chapter template starts a chunk file of the same name, and then it also does
xsl:apply-imports. This time the non-chunking chapter template is found, and it formats the chapter content into the file.
The original chunking chapter template closes the file and returns control to the customized chunking chapter template.
The customized chunking chapter template then writes the footer and then writes the file. Because it is the same filename, it overwrites the previous file. You are left with a chunk that has the correct filename and the correct header and footer, but no content. Its content was separately chunked into a file of the same name that was just overwritten.
xsl:include is used for
chunk-code.xsl, then no new import level is introduced for those templates. When
xsl:apply-imports is used, in either the original or a customized version, then it finds the non-chunking template to fill in the content.
Even with this arrangement, customization of the chunking behavior will require you to understand the templates that perform the chunking process. The behavior is further complicated by options such as fast chunking (when using
chunkfast.xsl instead of
chunk.xsl) and the
variation. The following table summarizes the important chunking
templates (as of version 1.73 and later).
Table 12.3. Chunking templates
|chunk-code.xsl||Matches document root to start processing.|
|chunk-code.xsl||Matches elements that are always chunks and
calls the |
|chunk-code.xsl||Matches section elements, calls the |
|chunk-common.xsl||Determines if the current element is a chunk. It returns 1 if the element is a chunk, or 0 otherwise.|
|chunk-common.xsl||Applies templates to style the element content and saves the styled result in a variable. Routes the content to the appropriate template based on chunking options that are set.|
<xsl:template name="chunk-all-sections">and others
|chunk-common.xsl||Determines the Next and Previous links for the
given chunk element and calls the |
|chunk-common.xsl||Determines the filename of the chunk and calls
|chunker.xsl||Calls the appropriate extension function for the current processor to write the styled content to a chunk file.|
When customizing any of these templates, be sure to set up your chunking customization using the guidelines in the section “Chunking customization”.
|DocBook XSL: The Complete Guide - 4th Edition||PDF version available|
Copyright © 2002-2007 Sagehill Enterprises