Docbook HTML Stylesheets

1. HTML cross references to chunked output.
2. How do I add something to the HTML navigational header or footer?
3. Images for next and previous pages in chunked output
4. Address Layout in HTML
5. Changing Fonts - HTML output
6. Creating an index
7. Labels in QandADivs
8. Automatic generation of map and alias files
9. Using Microsoft XML parser with docbook
10. Ordered lists have extra spaces between lines
11. Controlling the table of contents in XSL stylesheets
12. table of contents labels
13. Table Column widths
14. Output div as top level element, html mode
15. Shading programlisting
16. Numbering sections,
17. Pop up sidebars in HTML?
18. meta tags
19. Using CSS
20. Using an external CSS stylesheet
21. Output the doctype
22. Empty Table Cells
23. Creating Index terms from Glossary entries
24. Xref within index
25. Missing cross-references
26. Index and indexterm in website
27. Right to Left in markup
28. Right to left and left to right directional tags
29. Stylesheet support for revisionflag element
30. Indexterms in FAQ Questions result in duplicate text?
31. Variant toc depths, set and book
32. Processing large Cals tables
33. Chunks for abstract and toc
34. Add document title to each chunk
1.

HTML cross references to chunked output.

Bob Stayton





> I was wondering if there is a way to create links from HTML files to
> docbook generated HTML.
> I experimented with the DSSL style sheet, if I give an "id" to a section
> or chapter,
> most of the time I get file named like that.
> Which makes it easy to links to them from the outside, and even internal
> anchors do work.

> But in case of the first section within a chapter, the first section is
> placed on the same page as the chapter and
> its table of contents, so no seperate file.
> How can I control styling so that (certain)
> sections are placed on seperate pages.
> I tried <beginpage>, but that does not make a difference.

> For the XML style sheets the behaviour is different, I get files like
> ch01.html , sect01.html etc.


Don't give up. There is a definite logic to the XSL stylesheet output that lets you cross reference to the HTML. It works best when each element in the target document has an id attribute.

If you are seeing ch01.html, etc., then the document you are cross referencing to was chunked, meaning it was split into many HTML files. The breakpoints for chunking are at the elements named

<set>, 
 <book>, 
  <part>, 
   <chapter>, 
    <appendix>,
       and sect1 (or first-level <section> equivalent).

And a few others like <index>. There is an XSL parameter 'chunk.sections' which if set to true will further break up sect1 into more files.

If the element that starts a new chunk has an id attribute, then that is used as the filename, plus ".html". If you are seeing "ch01.html", then that chapter element did not have an id value to make into a filename, so the XSL stylesheet had to generate a name. It does so by counting chapters in the document. The naming scheme makes sure each output filename is unique. If your document is a set of books that each have a chapter 1, then the chunked filenames use bk01ch01.html (book 1, chapter 1) and bk02ch01.html (book2, chapter 1), etc.

So the filenames depend on how deeply the original XML document was structured, and whether it used id attributes in its chunking elements.

Every element that doesn't start a new chunk can still be referenced if it has an id attribute, because the stylesheet inserts <a name="id"> in the HTML output at that point. So if you know the ids of the chunk and of your final destination, you can form an href like HREF="myfile.html#finalstop". If the target element does not have an id, then there won't be an <a name="*" > tag in the HTML output, so you can't reference it directly.

Working with filenames that are generated is risky, because if the document is rearranged the numbering will change. That's why I said it works best if all the elements you want have ids.

2.

How do I add something to the HTML navigational header or footer?

Bob Stayton

Applicable to 1.48 and after stylesheets.

When you process your document in chunk mode, each HTML output file includes a header and footer that provide navigational links. The stylesheets provide a couple of empty templates that allow you to add to the header or footer.

To add to something above the navigational header, like a company logo, you define the content in a template named user.header.content in your stylesheet customization layer. For example:

<xsl:template name="user.header.content">
  <IMG>
    <xsl:attribute name="src">graphics/companylogo.png</xsl:attribute>
  </IMG>
</xsl:template>

The content of this template always appears first on each HTML page.

Likewise, to add something below the navigational footer, such as copyright information, you define content in a template named user.footer.content. This content always appears last on each HTML page.

If you want to rearrange the headers and footers beyond these additions, you'll need to redefine the templates that the stylesheet uses to generate the standard header and footer content. Those templates are named header.navigation and footer.navigation.

3.

Images for next and previous pages in chunked output

You can replace the text for Next and Previous with graphics in the navigational headers and footers of HTML output that is chunked into separate files. This feature is controlled by a set of stylesheet parameters, starting with version 1.48 of the DocBook stylesheets. Add these parameter settings to your HTML stylesheet customization layer.

<xsl:param name="navig.graphics" select="1"/>
<xsl:param name="navig.graphics.extension" select="'.gif'"/>
<xsl:param name="navig.graphics.path">images/</xsl:param>
<xsl:param name="navig.showtitles" select="1"/>
  • Setting navig.graphics parameter to anything but zero turns on the feature to replace the words Next, Previous, Up, and Home with graphics files. A default set of graphics files with names next.gif, previous.gif, up.gif, and home.gif are included in the images directory of the stylesheet distribution. It is your job to copy them to the output directory. You can also supply your own graphics files, but be sure to name them the same (except maybe for the extension; see the next parameter).

  • The navig.graphics.extension parameter sets the filename extension to something other than .gif if you are supplying your own graphics files.

  • The navig.graphics.path is the path relative to the output HTML files of the directory where the graphics files will be located. This path is used to form the SRC attribute of the IMG element in the output. By default, the graphics are in an images subdirectory below the HTML files.

  • The navig.showtitles parameter displays the titles of the Next and Previous files along with the graphical icons. If this parameter is set to zero, then only the graphical icons will appear in the header and footer, making for a very clean display.

4.

Address Layout in HTML

Norm Walsh




| I am trying to write a customization layer using the XSL stylesheets for 
| DocBook XML 4.1.2.  It is importing Norm's stylesheets as a basis.  I am 
| trying to alter how the address tag is displayed for HTML.  Currently it is 
| outputing: <div class="address">Free Software Foundation,Inc. <br>
|     59 Temple Place - Suite 330<br>
|     Boston MA 02111-1307<br>
|     USA<br>
|  </div>

| I want to have the output look like: 
| <div class="address">
|  Free Software Foundation,Inc., 59 Temple Place
|  - Suite 330, Boston, MA 02111-1307, USA
</div>

You could just write the address that way:

<address>Free Software Foundation,Inc., 59 Temple Place
- Suite 330, Boston, MA 02111-1307, USA</address>

The problem you're running into is that <address> has "verbatim" semantics. So that you can write

<address>Some Street
Some City, Some Province
Postal Code
Country</address>

and have it display that way (rather than getting all run together).

But if you don't want a <pre> (which implies a fixed-width font), the only way to do this (reliably, CSS notwithstanding) is to replace spaces with non-breaking spaces and linefeeds with <br/>.

| This leads to the make-verbatim template which is almost a complete mystery.
| I start losing it at the definition of the variable starts-with-nl.  What is 
| the string '&#xA;' supposed to be?

Yeah, it's a pretty hairy template. Basically it recurses to walk over the content of the address so that it can replace the characters it needs to. &#xA; is a linefeed.

| Below is the start of the customization of address.

| <xsl:template match="legalnotice/address//text()">
|   <xsl:call-template name="make-verbatim-inline">
|     <xsl:with-param name="text" select="."/>
|   </xsl:call-template>
| </xsl:template>

| <xsl:template name="make-verbatim-inline">

| At this point I'm at a loss of where to continue.  Basically I only want 
| to alter a portion of the template "make-verbatim" so instead of inserting 
| <br/> I insert "," except for the child state.  How do you this?

What does your source markup look like? Let's assume it's:

<address><street>Free Software Foundation,Inc.<street>
<street>59 Temple Place - Suite 330</street>
<city>Boston</city> <state>MA</state> <postcode>02110-1307</postcode>
<country>USA</country></address>

Try:

<xsl:template match="legalnotice/address">
  <xsl:apply-templates mode="inline-address">
</xsl:template>

<xsl:template match="street|city|postcode" mode="inline-address">
  <xsl:apply-templates/>
  <xsl:text>, </xsl:text>
</xsl:template>

<xsl:template match="state|country" mode="inline-address">
  <xsl:apply-templates/>
</xsl:template>

Untested.

5.

Changing Fonts - HTML output

Bob Stayton

This is most easily done by associating a CSS stylesheet with the HTML output. You can do that with the 'html.stylesheet' parameter. If you look in the generated HTML output, you'll see each element is in a <div> with its name, which makes writing css stylesheets that style specific elements easy.

6.

Creating an index

Peter Ring

"IndexTerms mark either a single point in the document or a range. A single point is marked with an IndexTerm placed in the text at the point of reference. There are two ways to identify a range of text:

* Place an IndexTerm at the beginning of the range with Class set to StartOfRange and give this term an ID. Place another IndexTerm at the end of the range with StartRef pointing to the ID of the starting IndexTerm. This second IndexTerm must be empty.

The advantage of this method is that the range can span unbalanced element boundries.

* Place the IndexTerm anywhere you like and point to the element that contains the range of text you wish to index with the Zone attribute on the IndexTerm. Note that Zone is defined as IDREFS so a single IndexTerm can point to multiple ranges.

The advantage of this method is that IndexTerms can be collected together or even stored totally outside the flow of the document (in the meta for example)."

I.e., you can build an external list of elements, provided they have IDs, and then associate IndexTerm elements with those elements using IDREFs. It is of course not feasible to put an ID on every word in the body text; you'll have to find an enclosing element and ensure it has the ID attribute. You can populate elements with unique IDs at document creation time or as a separate processing step. Theoretically, even without IDs it might be feasible to point to anywhere in the document with a XPath expression (or similar HyTime construct); in practice, it won't be stable without dependable IDs. If you manage to get something XPath-aware working, you can point to a range of #PCDATA inside an element, but it might not be needed. For online presentation, page numbers does not make much sense anyway, and for typeset paginated presentation, you can usually get away with refering to an eclosing element.

7.

Labels in QandADivs

Bob Stayton



> Given the following DocBook XML:

> <qandaset defaultlabel="none">
> <qandadiv id="s1"><title>Essentials</title>

> <qandaentry><question id="q1.1"><para>1.1 What is the purpose of this
> newsgroup?</para></question>

> <answer><para><ulink
> url="news:alt.comp.lang.learn.c-c++">alt.comp.lang.learn.c-c++</ulink>
> is a self-moderated newsgroup for the discussion of issues that concern
> novice to intermediate C and C++ programmers.  We ask and answer
> questions about those languages as defined by their respective standard
> documents.</para>


> The DocBook stylesheets generate this HTML output:

> <div class="qandaset">

> [ snip TOC ]

> <div class="qandadiv">
> <h3 class="title">
> <a name="s1"></a>1 Essentials</h3>
> <div class="qandaentry">
> <div class="question"><p>
> <a name="q1.1"></a><b>1.1 What is the purpose of this?</b>
> </p></div>
> <div class="answer">
> <p>
> <b></b><a href="news:alt.comp.lang.learn.c-c++"
> target="_top">alt.comp.lang.learn.c-c++</a> is a self-moderated
> newsgroup for the discussion of issues that concern novice to
> intermediate C and C++ programmers.  We ask and answer questions about
> those languages as defined by their respective standard documents.</p>


> Curiously, an empty <b></b> tag par is generated 
> at the beginning of the
> first paragraph of each answer. It's relatively harmless, but what
> causes it?

Reading the html/qandaset.xsl stylesheet module, the bold is for the label. If you had not set <qandaset defaultlabel="none">, then your answer would start with "<b>A:</b>", or whatever the translation of that label would be in another language. The "A:" comes from common/en.xml as the generated text for the label of an <answer> element.

8.

Automatic generation of map and alias files

Jirka Kosek

I have just added some new functionality to HTML Help stylesheet related to automatic generation of map and alias files. These files are used to glue application and context sensitive help made in HTML Help.

From now, you can use special PI in documents:

<chapter>
<title>Some title</title>
<?dbhh topicname="some_title" topicid="42"?>
...

This will automatically create corresponding entries in map and alias files:

context.h:
#define some_title 42 

alias.h:
some_title=name_of_chunk_for_chapter.html

If you want different names for context.h and alias.h, you can use parameters htmlhelp.map.file and htmlhelp.alias.file to change it.

If you want create context.h and alias.h manually, stylesheet can automatically include reference to them in project file if you set parameter htmlhelp.force.map.and.alias to 1.

I will appreciate your feedback about this extension as I personally don't use it in any real application. The idea comes from my correspondence with Denis Bradford.

9.

Using Microsoft XML parser with docbook

David Cramer

I've had good luck with it. There's a situation where msxml gets confused resolving entities. I can't remember what it is, but it seems like it is not the same 'relative to the place it was used rather than declared' problem that Saxon used to have.

Can I display the 'styled' docbook from the XML source using Microsoft kit?

Yes! You need only to add the following line to your xml file directly after the xml-prolog (<?xml version="1.0"...?>):

<?xml-stylesheet type="text/xsl" href="uri/or/location/of/xsl/stylesheet" ?>

I've tried this with a quite large document and some older version of the DocBook-XSL-Stylesheet. It worked pretty fine. But take care of the different versions of the MSXML-Parser (IE build-in parser). If your are using IE 5.x you might have MSXML 2.5 installed on your system. I've tried it with MSXML 3.0 wich works much better.

(DaveP. and version 4 even better)

You can download the new releases of the MSXML-Parser from http://msdn.microsoft.com. Note that the parser installs itself in a so called side-by-side mode. This mode doesn't replace the parser within IE. You have to download and install another small programm wich replaces the parser (I think ist called xmlinst). There is a good description about how to install the parser on the MSDN.

Be sure that you take the single-output-file-stylesheet. It doesn't supports chunking the way Saxon or Xalan do. So use the docbook.xsl-Stylesheet in the HTML directory of the XSL-Stylesheet to ge a nice HTML-Output ;-)

Microsoft unofficial help page for further MS help.

10.

Ordered lists have extra spaces between lines

Norm Walsh


> My ordered lists have extra space between lines.

This is, IMHO, a browser issue. The content model of LI clearly allows P and there's no reason why the browsers should do what they do.

That said, lots of people would like it to work differently. It would be fairly easy to suppress the P on listitems containing a single paragraph, so I suppose that's what I should do. I hesitate because it would create some inconsistencies if some listitems in the list contained more than one paragraph.

Actually, this is already supported! If a listitem contains only a single 'simpara', the P wrapper is suppressed.

11.

Controlling the table of contents in XSL stylesheets

Bob Stayton


> Can someone please point me to the file(s) and templates where I can
> customize the display of Tables of Contents inserted at the top of page in
> both single and chunked HTML output?
>
> I'd like to experiment with a horizontal link list and, to improve
> accessibility, I'd like to insert a TITLE attribute in the link that
> contains the same text as the section title.

The TOC processing machinery for a chapter starts in the "component.toc" template, which is in the autotoc.xsl file. That template outputs the localizes "Table of Contents" title, and then does apply-templates in mode="toc". The templates in that file that use that mode call the "subtoc" template recursively to build the TOC from the element and its children. It is "subtoc" that actually outputs the <dl> elements, so that is where you would want to concentrate your efforts on customizing the format of a TOC, probably by providing a replacement subtoc template.

12.

table of contents labels

Jirka Kosek


> 2) The labels in the map file that is generated seems random alphanumeric 
> text. I need to reference these labels in java code in order to get context 
> sensitive help. a) Is there a tag in the docbook xml that I can use to set 
> these "labels"? 

I think that setting id attribute on component container (chapter, section, ...) will help. Content of ID should be used then instead of autogenerated value.

> b) Will these "labels" stay constant accross each iteration 
> of an XLS transform?

Usually yes, but XSLT specifications says that they can be different in each transformation.

13.

Table Column widths

Norm Walsh


| about tables: if i know well, colwidth attribute has measure only like
| inch or cm and not %.

That's why CALS allows relative units.

If you set pagewide=1, you're asking for the table to be coerced to the page width. If you don't, you're giving the renderer a free hand to build a table that may be narrower than the available page width. (Note that in a multi-column environment, there's no equivalent colwide=1; if you set pagewide=1, you're implicitly asking for the table to span all the columns.)

For example

Here's a table that will be formatted such that the first column is always three units wide and the second column is always two units wide, where "units" is a relative measure left up to the formatter.

<informaltable>
<tgroup cols="2">
<colspec colwidth="3*"/>
<colspec colwidth="2*"/>
...
14.

Output div as top level element, html mode

Bob Stayton


> The HTML stream generated from the docbook source should for instance 
> start with

> <div class="article"> instead of <html><head>

> and end up with

> </div> instead of </body></html>.

No parameter, but an easy customization. Currently the HTML head stuff is output by this template in html/docbook.xsl:


  <xsl:template match="*" mode="process.root">

If you only want to modify this for articles, you could add a template in mode "process.root" to your html customization layer:

  <xsl:template match="article" mode="process.root">
     <xsl:apply-templates select="."/>
  </xsl:template>

Then it will not output the <head><body> stuff, but it will process everything in the document as html.

15.

Shading programlisting

Robert Day



> I am a DocBook newbie.  My programlisting output for html is not shaded 
> and I   would like them to be shaded.  

> I searched the web on "docbook shading" and found some references to 
> %verbatim-shading%.  The Definitive Guide did not have this parameter.

Shading has nothing to do with the content of your docbook document. It's a property of the presentation and has to be applied when you generate the HTML -- that's why you won't find it in TDG.

sourceforge.net is the HTML parameter reference, and under "miscellaneous", you'll find the entries for shade.verbatim and shade.verbatim.style that you can use when you transform docbook to html. i just tried it -- works fine.

If you check the description of, say, <programlisting>, you'll notice that it describes itself as "verbatim", so it should have shading applied to it via that parameter.

16.

Numbering sections,

Bob Stayton


> What is the cleanest way to get numbers in sections?

> Example:

> 1 Some section

>   1.1 Some sub section

>   1.1.2 Some sub-sub section

> .....

Setting the stylesheet parameter 'section.autolabel' to 1 turns on section numbering. If you also want the section numbers to include the chapter number as the first part of the number, then also set the 'section.label.includes.component.label' parameter to 1.

17.

Pop up sidebars in HTML?

Bob Stayton



> I'd like to display the <sidebar> element content in a pop up window.

> Any suggestions on how I can accomplish that with DocBook stylesheets.

That's not a a built-in feature, so you would have to write a customization to do that. You need to write a replacement XSL template for <xsl:template match="sidebar"> (the original is in html/block.xsl in the DocBook XSL distribution, but it doesn't do much).

The things it would need to do include:

1. Figure out a unique filename for each popup.

2. Call the 'write.chunk' template with the correct set of parameters, including the content.

3. Generate an anchor of some sort so the user knows there is a sidebar and can click to reach it. The anchor might look like this:


<a href="sidebar.filename.html" target="sidebar">Sidebar title</a>

18.

meta tags

Bob Stayton


> How do one set meta tags with docbook ?
> I want the html file to contain : 
> <meta name="description" content="blablablabla">
> <meta name="keywords" content="bla,bla,bla,bla,etc">

For these two meta names, there is some direct support in Docbook XSL.

For "description", if you put your description in the document's <abstract> element, and set the stylesheet parameter 'generate.meta.abstract' to 1, then the text of the abstract will appear as the 'content' value of the meta.

For keywords, if you put a <keywordset> element with keywords in your document's *info element (bookinfo, chapterinfo, etc), then it will be output in a meta name="keywords" element in the HTML HEAD.

If you want other meta elements, or you want to customize how the description meta is handled (passed as a parameter, for example), then you can customize the built-in placeholder template named 'user.head.content'. It is automatically called during the output of the HTML HEAD.

19.

Using CSS

Bob Stayton


> Is it also possible to attach a
> .css to override some of the formatting? For example, the spacing after
> each bullet seems too large and I also don't want the bullets indented that
> much.

Yes, see: sagehill

20.

Using an external CSS stylesheet

David Cramer

I would like to embed the contents of an external css stylesheet at user.head.content. That is, instead of a link to the stylesheet (a la html.stylesheet), I would like a document-level <style> block in the head of the document. I want to pull the css rules in from an external, shared file, rather than hardwiring them in the stylesheet.

Try this (where html.css is your css):

<?xml version="1.0" encoding="US-ASCII"?>
<!DOCTYPE stylesheet [
<!ENTITY css SYSTEM "html.css">
]>

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:doc="http://nwalsh.com/xsl/documentation/1.0"
  exclude-result-prefixes="doc" version="1.0">

<xsl:template name="user.head.content">
<style type="text/css">
&css;
</style>
</xsl:template>

</xsl:stylesheet>

21.

Output the doctype

Bob Stayton



 I think, that the only way to ensure that documents
> created with docbook.xsl have a DOCTYPE declaration, is to add
> xsl:output to the used customisation layer?

If you are referring to HTML output, using xsl:output is not the only way. The chunking stylesheet accepts the 'chunker.output.doctype-public' and chunker.output.doctype-system' parameters to specify a DOCTYPE for the output. If you need it for single file output, you can use the onechunk stylesheet, which also accepts those parameters.

See this reference for an example: on my site

22.

Empty Table Cells

Bob Stayton



> I've got a document with an informaltable with empty entries and
> the 1.61.2 xhtml stylesheets produce odd results. When I look at the
> resultant html in a browser I see a '^A' in the empty cells.
> The stylesheet seems to output a &#160; for an empty cell.
>
> Any ideas on how to avoid this?

Those aren't Control-A's you are seeing, they are the UTF-8 encoding of the non-breaking space character (00A0 in Unicode). The two-character sequence in UTF-8 encoding is C2 and A0. Most browsers support UTF-8, and the XHTML output should indicate the encoding with:

<meta http-equiv="Content-Type"
 content="text/html; charset=UTF-8" />

That should be enough for the browser to recognize the character as a space character, not as an unknown character. What browser are you using?

The reason the nonbreaking spaces are output to empty cells is because some browsers don't properly handle cell border display for truly empty cells.

23.

Creating Index terms from Glossary entries

Tom Peters and David Cramer.

To answer my own question: I had the same problem a year ago, and I believe it was David Cramer who sent me a stylesheet that appends an <indexterm> stanza after each relevant <glossterm> entry. At the time I was still using DSSSL so I didn't know what to do with it. Now I tried it, and it gives a very good first impression.

I attach David's stylesheet. It works as a first run of xsltproc, producing an intermediate DocBook text that can be further processed by xsltprocw ith another stylesheet, and fop . I did not get it to work when included into a stylesheet that aims to produce the .fo file in one run.

<?xml version="1.0"?>

<!-- I made the default namespace null to avoid having 
Saxon put a saxon name space on the indexterm elements we're writing out -->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns=""
  version="1.0">

  <xsl:output
	method="xml"
	indent="yes"/>

  <!-- By default, copy everything -->
  <xsl:template match="@*|node()">
	<xsl:copy>
	  <xsl:apply-templates select="@*|node()"/>
	</xsl:copy>
  </xsl:template>


  <!-- For glossterms outside of the glossary, copy the element,
  but add an index marker immediately after it. UNLESS it's
  <glossterm role="no indexterm">; this gives the writer the
  ability to put in a glossterm and avoid having it create an
  indexterm marker.  -->

  <xsl:template match="glossterm[not(ancestor::glossary) and 
 not(@role = 'no indexterm')]">
	<xsl:copy-of 
  select="."/><indexterm><primary><xsl:value-of
 select="."/><
      /primary></indexterm>
  </xsl:template>

  <!-- This handles glossterms in the glossary as a special case -->
  <xsl:template match="glossentry">
	<glossentry>
	  <xsl:copy-of select="@*"/>
	  <xsl:copy-of select="glossterm"/>
	  <xsl:copy-of select="acronym"/>
	  <xsl:copy-of select="abbrev"/>
	  <indexterm><primary><xsl:value-of 
	  select="glossterm"/></primary></indexterm>
	  <xsl:copy-of select="revhistory"/>
	  <xsl:copy-of select="glosssee"/>
	  <xsl:copy-of select="glossdef"/>
	</glossentry>
  </xsl:template>

</xsl:stylesheet>
24.

Xref within index

Bob Stayton



>
> I'm trying to use xref within an index so that the xref points to another
> entry within the index. The problem is the anchor tag never gets created
> in the xhtml. I'm using docbook-xsl-1.65.1.
>
> Here's example code:
>
> <index>
> <title>Index Title</title>
> <indexdiv><title>A</title>
>   <indexentry><primaryie>APR</primaryie>
>               <seeie><emphasis role="italic">See</emphasis>
>               <xref linkend="a1001"/></seeie>
>   </indexentry>
>   <indexentry id="a1001" xreflabel="Alaska &#x26; Polar Regions">
>            <primaryie>Alaska &amp; Polar Regions</primaryie>
>    </indexentry>
> </indexdiv>
> </index>
>

The template you want to customize is this one in xhtml/index.xsl:

<xsl:template match="indexentry">
  <xsl:apply-templates select="primaryie"/>
</xsl:template>

Change it to this in your customization layer:

<xsl:template match="indexentry">
  <xsl:call-template name="anchor"/>
  <xsl:apply-templates select="primaryie"/>
</xsl:template>

I guess no one ever asked to cross reference between index entries before.

It's a bit unusual to write the index by hand using <indexentry> elements, when the stylesheet can generate the index from <indexterm> elements embedded in your document. Are you doing it this way so you can hot link between index entries? I don't see how your entries link into the body of the text, though.

Hot linking see and seealso entries is not currently a stylesheet feature, but it seems like it would be a good one.

25.

Missing cross-references

David Cramer


>I want to cross reference a figure in a docbook document 
>that is going to be converted to HTML. 
>I tried using the Xref element, but I don't know how to 
>implement it correctly.
>After the conversion to HTML, the Xref element has been replaced by 
>a triple question mark: "???", so something has gone wrong.

>This is what I did:

> The Xref element has an attribute "Linkend". 
> I assigned it a value "SomeTitle".
> The figure that I intend to reference has a caption element, 
> which has an attribute "ID". I assigned it the value "SomeTitle"
> I converted the docbook XML document to HTML, using Saxon .

Put the id on the <figure> rather than the <caption>. You can xref to most elements that have <title>s, but you have to xref to the element itself. See Bob's book for all the details and options: http://www.sagehill.net/docbookxsl/CrossRefs.html

26.

Index and indexterm in website

Bob Stayton


> I'm interesting in adding index entries to my WebSite sources and
> generating an index page. website-full.dtd appears to include docbook
> index elements in webpage.mix, but they don't validate, so I must be
> misunderstanding the dtd.
>
> If there's no way to use docbook indexterms and index in WebSite, is
> there perhaps another way to do something similar?

Well, there's good news and there's bad news.

The good news is that index and indexterm are permitted inside a webpage element whose DOCTYPE is website-full.dtd, and they do validate. I just tested it. I'm not sure what's going wrong when you try it.

The bad news is that they don't do what you want them to do, which is create an index for your website. You have to keep in mind that each webpage document is a separate XML document, and it is processed as a separate document. That means the scope of an index can be no larger than one webpage document. In order for the index to cover all your webpages, they would have to be included as children of a larger container document that is processed all at once. But that isn't how Website works.

As it currently ships, Website can't collect index entries from the set of webpage documents and generate a sorted index.

27.

Right to Left in markup

Markus Schuetz



>I am trying (helplessly) to figure out how to use DocBook/XML to produce
>Arabic documentation. This is probably not the first time I approach
>this issue, but I am going at it again.
>
>At Arabeyes [1], we use DocBook/XML for all our documentation.
>Unfortunately, for the Arabic documents we have two problems:
>
>1. The HTML output is in LTR mode (should be in RTL)
>2. None of the XSL-Fo's I know of (we use Apache's FOP [2]) can handle
>   Arabic text (not the UTF-8 nor the bidi mode).
>
>Currently, what we have been doing is adding a CSS that sets the
>direction to rtl. This is not a good enough solution, since browsers are
>instructed that they can happily ignore those in CSS [3]. It is noted
>that this should be in the mark-up. 
>
>So, where in all of this do we go from here? I am completely lost!
>
>References:
>[1] http://www.arabeyes.org/
>[2] http://xml.apache.org/fop/index.html
>[3] http://www.w3.org/TR/i18n-html-tech-bidi/#IDAMJFO

there are several ways to turn your flow of text into the "right direction".

(1) With HTML, the most effective one seems to use the BDO element (an inliner) and the DIR attribute to specifiy the text direction. For example, use:

<p>Some left to right text <bdo 
       dir="rtl">Some right to left text</bdo> 
Some more ltr...<p>

The DIR attribute is also available for several other elements in HTML 4.01, most notably P and BODY. This will also right-align your text in the browser.

Just have a look at the HTML spec for more information. (e.g.http://www.w3.org/TR/html401/struct/dirlang.html#h-8.2) I don't know how the different browsers support this, but I'm confident that at least the most prominent will do.

(2) It is true that the current FOP release (0.20.5) does not support BIDI. But there are some hacks to serve that purpose. Maybe you will find some more information on the FOP mailing list at http://xml.apache.org/fop/maillist.html. The forthcomimg release of FOP (1.0) is said to support BIDI. As far as I know, the remaining suspects (namely XEP by RenderX and XSL Formatter by Antenna House) support BIDI. But these are commercial tools.

28.

Right to left and left to right directional tags

David Tolpin



> I don't have one handy (could get one by tomorrow -- work is getting
> busy).. but you may grab this:
>
> http://www.arabeyes.org/download/documents/guide/translator-guide-ar/
>

OK, I understand now what you mean by saying it is LTR. Not the phrases in Arabic in the table, but the layout of the table itself.

Then what you want is not Unicode BIDI marks, but

<body style="direction: rtl">

that is, the default mode is right to left. I've just checked it with your file, it worked.

Forget about Unicode BIDI marks; use CSS instead. A description of the property is at zvon

Additionally, zvon is a very good resource for references and tutorials on many things including CSS.

Again, you don't need to set the order of characters in words or of words in phrases, just the layout of the page. It does not know otherwise that you want rtl by default (and it is written by people who think that default is ltr, sigh).

29.

Stylesheet support for revisionflag element

Jirka Kosek



> is there support for DocBook's "revisionflag" attribute in the HTML
> output of the current DocBook XSLTs?

Yes, use changebars.xsl stylesheet instead of docbook.xsl.

30.

Indexterms in FAQ Questions result in duplicate text?

Bob Stayton


  

> If I put an <indexentry> into an FAQ <question>,  the index term gets
> duplicated in the list of questions in the HTML output.
>

>
> Example:
>
> <question>
> <para>
> Can I use
> <indexterm><primary>OOPS</primary></indexterm> docbook as my
> documentation standard?
>    </para>
> </question>
>
> gives the following output in the list of questions
>
> Q:
> Q: Can I use OOPS docbook as my documentation standard?
> Q:
>
> but
> Q: Can I use docbook as my documentation standard?
> A: ...
>
> in the full sequence.

You have run into one of the compromises that the stylesheet has to make for HTML. In the case of the QandA table of contents, it processes the question element by using <xsl:value-of> on the first child element of <question>. That gets just its string value, and so the indexterm text is included. It gets the string value because it puts it inside an HTML <a> element. Since a question element can contain arbitrary content, including other cross references, that would lead to bad HTML because you can't nest links within links in HTML.

You can work around the problem by putting the <indexterm> after the closing </para> tag within the <question>. That way it will not be included in the first child of question, and it should still work.

31.

Variant toc depths, set and book

Bob Stayton



> I'm trying to find a way, to alter the creating of the ToC in
> index.html.
>
> I have a single <set>, with 10 <book>s under it.
> I'm trying to get the ToC that the html stylesheets produce, to only
> list the books, not the titles of the chapters under them. I want to
> save those titles for once the user is looking at the book itself.

If you want to retain the depth of the book tables of contents while reducing the depth of the set table of contents, you will have to do a little customization.

The template named 'make.toc' in autotoc.xsl is called at the beginning of a table of contents, and then it applies templates in mode="toc" for each nested level. As it applies templates in that mode, it supplies the 'toc-context' parameter whose value is the top element containing the TOC. You want to change how a book is processed when the toc-context is set. So copy the match="book" mode="toc" template from autotoc.xsl to your customization layer and add an xsl:choose to modify the behavior:

<xsl:template match="book" mode="toc">
  <xsl:param name="toc-context" select="."/>

  <xsl:choose>
    <xsl:when test="local-name($toc-context) = 'set'">
      <xsl:call-template name="subtoc">
        <xsl:with-param name="toc-context" select="$toc-context"/>
        <xsl:with-param name="nodes" select="foo"/>
      </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
      <xsl:call-template name="subtoc">
        <xsl:with-param name="toc-context" select="$toc-context"/>
        <xsl:with-param name="nodes" select="part|reference
                                         |preface|chapter|appendix
                                         |article
                                         |bibliography|glossary|index
                                         |refentry
                                    |bridgehead[$bridgehead.in.toc !=0]"/>
      </xsl:call-template>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

In the xsl:when statement, if the toc-context is 'set', then call subtoc with no nodes selected (I entered a fake element name because it won't accept an empty select statement). The subtoc template will format the book title, and then won't have any subnodes to process.

32.

Processing large Cals tables

Jakob ??



THE PROBLEM

big oasis-open/cals tables, i.e. tables with more than ca. 500 rows cause Saxon 6.5.3 and Xalan 2.5.2 to throw an StackOverflowError, no matter how much stack size is allocated. i am not sure whether the problem is with the processors, or Java.

note that MSXML3 (not sure about the version) does handle the conversion.

note as well that oXygen's xslt debugger is also able to convert the table using Saxon 6.5.3, after warning you that a possible infinite loop has been detected (you have to say yes, you want to continue anyway).

THE CAUSE

apparently, the cause for this is in the recursiveness of the stylesheets used. I used the Docbook xsl stylesheets 1.65.1 which include oasis-open/cals table transformation stylesheets.

THE SOLUTION

i've been given a stylesheet which conforms to xslt2, and can be run with Saxon 7 which does the transformation. it is "tail-recursive" which means less stack is used. i have successfully used it for a table of 1753 rows. it is still long, i.e. ca. 12 minutes on a P4 2.4GHz with 512MB.

obviously, it would have been nice to stay with xslt1, and to do it quicker, but hey, it works!

CREDITS

John Mullee wrote and has me provided with the stylesheet, thanks a lot! All the other people on docbook-apps and saxon-help who took the time to respond, thank you!

Norman Walsh and team for their xslt docbook stylesheets (i'm still using the table stylesheets for all "normal" tables).

SEE ALSO

[1] on the saxon-help mailing list, search for this title "OASIS-Open/CALS *big* table conversion problems", for posts related to this issue.

[2] with John's permission: his stylesheet, the table in question, the output etc. are available on his site (via tinyurl): http://tinyurl.com/25mkc

Ednote: Inserted here, unsure of the longevity of those links

<!-- (c) john mullee 2004 - copyright placed in the public domain -->
<!DOCTYPE xsl:stylesheet [
   <!ENTITY nbsp "&#160;">
]>
<xsl:stylesheet version="2.0"
   xmlns:xsl=     "http://www.w3.org/1999/XSL/Transform"
   xmlns:xs=      "http://www.w3.org/2001/XMLSchema"
   xmlns:local   ="http://127.0.0.1/cals_to_html.xslt"
   exclude-result-prefixes="#all"
   >

   <xsl:output
     method                  = "html"
     doctype-public          = "-//W3C//DTD HTML 4.01 Transitional//EN"
     encoding                = "UTF-8"
     escape-uri-attributes   = "yes"
     include-content-type    = "yes"
     indent                  = "yes"
     />
<!--
   CALS Table Model
      http://www.oasis-open.org/specs/a502.htm
      http://www.oasis-open.org/cover/tr9502.html
   OASIS XML Exchange Table Model
      http://www.oasis-open.org/specs/a503.htm
      http://www.oasis-open.org/specs/tm9901.htm
   Some test cases:
      http://sources.redhat.com/ml/xsl-list/2001-07/msg00835.html
       * Subject: Re: [xsl] Table formatting challenge
       * From: Norman Walsh <ndw at nwalsh dot com>
      ".. Here are a few more examples (that thwart the code you presented)" 
-->

   <xsl:template match="node()|@*" mode="html-only" 
	  xpath-default-namespace="http://www.w3.org/1999/xhtml">
      <xsl:choose>
         <xsl:when test="compare(local-name(), name())=0">
            <xsl:copy copy-namespaces="no">
               <xsl:apply-templates select="@*|node()" mode="html-only"/>
            </xsl:copy>
         </xsl:when>
         <xsl:otherwise>
            <xsl:apply-templates select="node()" mode="html-only"/>
         </xsl:otherwise>
      </xsl:choose>
   </xsl:template>

   <xsl:template match="/">
      <html>
         <head>
            <style type="text/css">
               td.generated { background-color: green; }
            </style>
         </head>
         <body>
            <xsl:apply-templates/>
         </body>
      </html>
   </xsl:template>

   <!-- ===================== -->
   <!-- dummy for Jakob's xml -->
      <xsl:template match="para">
         <xsl:choose>
            <xsl:when test="count(node()) > 0">
               <p>
                  <xsl:apply-templates/>
               </p>
            </xsl:when>
            <xsl:otherwise>&nbsp;</xsl:otherwise>
         </xsl:choose>
      </xsl:template>
      <xsl:template match="anote"><a 
	  href="#{@refid}">(LINK <xsl:apply-templates/>)</a>
	  </xsl:template>
      <xsl:template match="note"><a 
	  name="{@id}"/><xsl:apply-templates/></xsl:template>
   <!-- ===================== -->

   <!-- CHANGE xsl:template match="informaltable"-->
   <xsl:template match="table">
      <xsl:apply-templates select="tgroup" mode="XML_ExTabModel"/>
   </xsl:template>

   <!-- XML_ExTabModel mode -->

   <xsl:template match="tgroup" mode="XML_ExTabModel">
      <table border="1" summary="">
         <caption>
            <!-- not part of XML_ExTabModel -->
         </caption>
         <colgroup span="{@cols}">
            <xsl:for-each select="colspec">
               <col span="1" width="{@colwidth}">
                  <xsl:call-template name="general_cell_alignment">
                     <xsl:with-param name="element" select="."/>
                  </xsl:call-template>
               </col>
            </xsl:for-each>
         </colgroup>
         <xsl:apply-templates select="thead"   mode="XML_ExTabModel"/>
         <tfoot>
            <!-- not part of XML_ExTabModel -->
         </tfoot>
         <xsl:apply-templates select="tbody"   mode="XML_ExTabModel"/>
      </table>

   </xsl:template>

   <xsl:template match="thead" mode="XML_ExTabModel">
      <thead>
         <xsl:call-template name="general_cell_alignment">
            <xsl:with-param name="element" select="."/>
         </xsl:call-template>
         <xsl:call-template name="recursive_row_processor"/>
      </thead>
   </xsl:template>

   <xsl:template match="tbody" mode="XML_ExTabModel">
      <tbody>
         <xsl:call-template name="general_cell_alignment">
            <xsl:with-param name="element" select="."/>
         </xsl:call-template>
         <xsl:call-template name="recursive_row_processor"/>
      </tbody>
   </xsl:template>

   <!-- ===== recursive row processing ======= -->

   <xsl:template name="recursive_row_processor">
      <xsl:param name="curr_row"    as="xs:integer" select="1"/>
      <xsl:param name="set_of_rows" as="element()*" />

<xsl:message>recursive_row_processor <xsl:value-of 
	  select="$curr_row"/></xsl:message>

      <xsl:variable name="num_rows" select="count(./row)"/>

      <!-- add a new row to set -->
      <xsl:variable name="new_set_of_rows" as="element()*">
         <xsl:copy-of select="$set_of_rows"/>
         <xsl:apply-templates select="./row[$curr_row]" 
	  mode="XML_ExTabModel">
            <!-- generated rows are forwarded to cell generator 
	  for rowspan lookup -->
            <xsl:with-param name="set_of_rows" select="$set_of_rows"/>
         </xsl:apply-templates>
      </xsl:variable>

      <xsl:choose>
         <xsl:when test="$curr_row = $num_rows">
            <!-- terminate recursion, output rows -->
            <!-- copy without local-namespace stuff -->
            <xsl:apply-templates select="$new_set_of_rows" 
	  mode="html-only"/>
         </xsl:when>
         <xsl:otherwise>
            <!-- tail-recurse for more rows -->
            <xsl:call-template name="recursive_row_processor">
               <xsl:with-param name="curr_row" 
	  select="xs:integer($curr_row + 1)"/>
               <xsl:with-param name="set_of_rows" 
	  select="$new_set_of_rows"/>
            </xsl:call-template>
         </xsl:otherwise>
      </xsl:choose>

   </xsl:template>

   <xsl:template match="row" mode="XML_ExTabModel">
      <xsl:param name="set_of_rows" as="element()*" />
      <tr>
         <xsl:if test="ancestor::thead">
            <xsl:attribute name="bgcolor" select="'#999999'"/>
         </xsl:if>
         <xsl:call-template name="general_cell_alignment">
            <xsl:with-param name="element" select="."/>
         </xsl:call-template>
         <xsl:call-template name="recursive_cell_processor">
            <xsl:with-param name="set_of_rows" select="$set_of_rows" />
         </xsl:call-template>
      </tr>
   </xsl:template>

   <!-- ===== recursive cell processing ======= -->
   <xsl:template name="recursive_cell_processor">
      <xsl:param name="curr_entry"   as="xs:integer" select="1"/>
      <xsl:param name="curr_column"  as="xs:integer" select="1"/>
      <xsl:param name="set_of_cells" as="element()*"/>
      <xsl:param name="last_cell"    as="document-node()?"/>
      <xsl:param name="set_of_rows"  as="element()*"/>

      <xsl:variable name="num_columns" select="../../@cols"/>
      <xsl:variable name="num_entries" select="count(entry)"/>
      <xsl:variable name="current_row" select="count($set_of_rows) + 1"/>

      <xsl:variable name="cells_spanning_rows">
         <!-- build a list of row-spanning cells which will affect 
	  this row -->
         <xsl:for-each 
	  select="$set_of_rows[ td/@rowspan >= ($current_row - position()) ]">
            <!-- context = TR containing a cell which rowspans 
	  across current row -->
            <xsl:variable name="row_id" select="generate-id(.)"/>
            <!-- BUG this relies on id-strings Collating in
         document-order 
	  : saxon 7 works -->
            <xsl:variable name="rowndx" 
	  select="count($set_of_rows[$row_id > generate-id(.)])" 
	  as="xs:integer"/>
            <xsl:for-each select="td[@rowspan]">
               <!-- context = TD's containing rowspan -->
               <xsl:if test="(@rowspan + $rowndx) >= $current_row">
                  <!-- TD's which spans across current row -->
                  <xsl:for-each select="@local:beg to @local:end">
                     <span col="{.}"/>
                  </xsl:for-each>
               </xsl:if>
            </xsl:for-each>
         </xsl:for-each>
      </xsl:variable>

      <!-- adjust for the special case of the first column being 
	  overlapped -->
      <xsl:variable name="adjusted_curr_column_list" as="xs:integer+">
         <xsl:choose>
            <xsl:when test="count($cells_spanning_rows/span[@col = 
	  $curr_column]) > 0">
               <!-- build a list of col numbers which follow 
	  contiguous series' of col numbers -->
               <xsl:for-each 
	  select="$cells_spanning_rows/span">
	  <xsl:sort 
	  select="number(@col)"/>
                  <xsl:choose>
                     <xsl:when test="following-sibling::node()[1]/@col">
                        <xsl:if test="not(xs:integer(@col) = 
	  xs:integer(following-sibling::node()[1]/@col - 1))">
                           <xsl:value-of select="@col + 1"/>
                        </xsl:if>
                        <!-- otherwise, context is within 
	  contiguous series -->
                     </xsl:when>
                     <xsl:otherwise><xsl:value-of 
	  select="@col + 1"/></xsl:otherwise>
                  </xsl:choose>
               </xsl:for-each>
            </xsl:when>
            <xsl:otherwise><xsl:value-of
	  select="$curr_column"/></xsl:otherwise>
         </xsl:choose>
      </xsl:variable>
      <xsl:variable name="adjusted_curr_column" 
	  as="xs:integer" select="$adjusted_curr_column_list[1]"/>

      <!-- build another table cell -->
      <xsl:variable name="built_cell">
         <xsl:call-template name="build_table_cell">
            <xsl:with-param name="entry"       select="entry[$curr_entry]"/>
            <xsl:with-param name="curr_column" 
	  select="$adjusted_curr_column"/>
         </xsl:call-template>
      </xsl:variable>

      <xsl:variable name="next_cell_start"
	  select="$built_cell/td/@local:beg"/>
      <xsl:variable name="next_cell_end"   
	  select="$built_cell/td/@local:end"/>
      <xsl:variable name="last_cell_end"   
	  select="$last_cell/td/@local:end"/>
      <xsl:variable name="num_prev_cells" 
	  select="count($set_of_cells[name()='td'])"/>

      <!-- add new cell to existing set of cells -->
      <xsl:variable name="new_set_of_cells" as="element()*">
         <!-- insert any cells needed at beginning of row -->
            <xsl:if test="($curr_entry = 1) and ($next_cell_end > 1)">
               <xsl:call-template name="add_empty_cells">
                  <xsl:with-param name="count" 
	  select="xs:integer($built_cell/td/@local:beg - 1)"/>
                  <xsl:with-param name="start" select="xs:integer(1)"/>
                  <xsl:with-param name="cells_spanning_rows" 
	  select="$cells_spanning_rows"/>
               </xsl:call-template>
            </xsl:if>
         <!-- emit the previously-generated cells -->
            <xsl:copy-of select="$set_of_cells"/>
         <!-- fill in any gap between prev cell and this -->
            <xsl:if test="($num_prev_cells > 0) and 
	  ($next_cell_start > ($last_cell_end + 1))">
               <xsl:call-template name="add_empty_cells">
                  <xsl:with-param name="count" 
	  select="xs:integer($next_cell_start - ($last_cell_end + 1) )"/>
                  <xsl:with-param name="cells_spanning_rows" 
	  select="$cells_spanning_rows"/>
                  <xsl:with-param name="start" 
	  select="xs:integer($last_cell_end + 1)"/>
               </xsl:call-template>
            </xsl:if>
         <!-- emit the cell we just generated -->
            <xsl:copy-of select="$built_cell"/>
         <!-- last entry: insert any cells needed at end of row -->
            <xsl:if test="($curr_entry = $num_entries) and 
	  ($next_cell_end &lt; $num_columns)">
               <xsl:call-template name="add_empty_cells">
                  <xsl:with-param name="count" 
	  select="xs:integer($num_columns - $next_cell_end)"/>
                  <xsl:with-param name="cells_spanning_rows" 
	  select="$cells_spanning_rows"/>
                  <xsl:with-param name="start" 
	  select="xs:integer($built_cell/td/@local:end + 1)"/>
               </xsl:call-template>
            </xsl:if>
      </xsl:variable>

      <xsl:choose>
         <xsl:when test="not($curr_entry = $num_entries)">
            <!-- tail-recurse for more cells -->
            <xsl:call-template name="recursive_cell_processor">
               <xsl:with-param name="curr_entry"   
	  select="$curr_entry + 1"/>
               <xsl:with-param name="curr_column"  
	  select="xs:integer($next_cell_end + 1)"/>
               <xsl:with-param name="set_of_cells" 
	  select="$new_set_of_cells"/>
               <xsl:with-param name="last_cell"    
	  select="$built_cell"/>
               <xsl:with-param name="set_of_rows"  select="$set_of_rows"/>
            </xsl:call-template>
         </xsl:when>
         <xsl:otherwise>
            <!-- terminate recusion, output cells -->
            <xsl:copy-of select="$new_set_of_cells"/>
         </xsl:otherwise>
      </xsl:choose>

   </xsl:template>

   <!-- ===== column numbering ======= -->
   <xsl:function name="local:fn_get_col_number" as="xs:integer">
      <xsl:param name="context_tgroup"/>
      <xsl:param name="colname"/>
      <xsl:param name="default" as="xs:integer"/>
      <xsl:choose>
         <xsl:when test="$colname">
            <xsl:choose>
               <xsl:when 
	  test="$context_tgroup/colspec[@colname=$colname]/@colnum">
                  <xsl:value-of 
select="xs:integer($context_tgroup/colspec[@colname=$colname]/@colnum)"/>
               </xsl:when>
               <xsl:otherwise>
                  <!-- BUG there might be no preceding colspec -->
                  <xsl:value-of 
select="count($context_tgroup/colspec[
@colname=$colname]/preceding-sibling::*[name()='colspec'])+1"/>
               </xsl:otherwise>
            </xsl:choose>
         </xsl:when>
         <xsl:otherwise><xsl:value-of 
	  select="$default"/></xsl:otherwise>
      </xsl:choose>
   </xsl:function>

   <!-- ===== adding empty cells ======= -->
   <xsl:template name="add_empty_cells">
      <xsl:param name="count" as="xs:integer" select="0"/>
      <xsl:param name="start" as="xs:integer" select="0"/>
      <xsl:param name="cells_spanning_rows"/>
      <xsl:for-each select="$start to ($start + $count - 1)">
         <xsl:variable name="col_index" select="." as="xs:integer"/>
         <xsl:if test="count($cells_spanning_rows/span[@col = 
	  $col_index]) = 0">
            <td class="generated" local:beg="{$start + position()}" 
	  local:end="{$start + position()}">&nbsp;</td>
         </xsl:if>
      </xsl:for-each>
   </xsl:template>

   <!-- ===== table cell ======= -->
   <xsl:template name="build_table_cell">
      <xsl:param name="entry"/>
      <xsl:param name="curr_column"/>

      <xsl:variable name="start_col_pos" 
	  select="local:fn_get_col_number($entry/ancestor::tgroup, 
	  $entry/@namest,  $curr_column)"/>
      <xsl:variable name="end_col_pos"   
	  select="local:fn_get_col_number($entry/ancestor::tgroup, 
	  $entry/@nameend, $start_col_pos)"/>

      <xsl:variable name="computed_col_span" 
	  select="xs:integer(($end_col_pos - $start_col_pos) + 1)"/>

      <!-- output results element and TD -->
      <td local:beg="{$start_col_pos}" local:end="{$end_col_pos}">
         <xsl:call-template name="general_cell_alignment">
            <xsl:with-param name="element" select="$entry"/>
         </xsl:call-template>
         <!-- colspan -->
         <xsl:if test="$computed_col_span > 1">
            <xsl:attribute name="colspan">
               <xsl:value-of select="$computed_col_span"/>
            </xsl:attribute>
         </xsl:if>
         <!-- rowspan -->
         <xsl:if test="$entry/@morerows">
            <xsl:if test="number($entry/@morerows)>0">
               <xsl:attribute name="rowspan">
                  <xsl:value-of select="number($entry/@morerows)+1"/>
               </xsl:attribute>
            </xsl:if>
         </xsl:if>
         <!-- nbsp for empty cells -->
         <xsl:if test="count($entry/node()) = 0">&nbsp;</xsl:if>
         <!-- proceed in Non-XML_ExTabModel mode -->
         <xsl:apply-templates select="$entry"/>
      </td>

   </xsl:template>

   <!-- ===== alignment attributes ======= -->
   <xsl:template name="general_cell_alignment">
      <xsl:param name="element"/>

      <xsl:if test="$element/@align">
         <xsl:attribute name="align">
            <xsl:choose>
               <xsl:when test="string-length(string($element/@align))>0">
                  <xsl:value-of 
	  select="replace($element/@align,'justify','left')"/>
               </xsl:when>
               <xsl:otherwise>center</xsl:otherwise>
            </xsl:choose>
         </xsl:attribute>
      </xsl:if>
      <xsl:if test="$element/@valign">
         <xsl:attribute name="valign">
            <xsl:choose>
               <xsl:when
         test="string-length(string($element/@valign))>0">
	  <xsl:value-of select="$element/@valign"/></xsl:when>
               <xsl:otherwise>top</xsl:otherwise>
            </xsl:choose>
         </xsl:attribute>
      </xsl:if>
      <xsl:if test="$element/@char">
         <xsl:attribute name="char">
            <xsl:choose>
               <xsl:when
         test="string-length(string($element/@char))>0">
	  <xsl:value-of select="$element/@char"/></xsl:when>
               <xsl:otherwise>%</xsl:otherwise>
            </xsl:choose>
         </xsl:attribute>
      </xsl:if>
      <xsl:if test="$element/@charoff">
         <xsl:attribute name="charoff">
            <xsl:choose>
               <xsl:when
         test="string-length(string($element/@charoff))>0">
	  <xsl:value-of select="$element/@charoff"/></xsl:when>
               <xsl:otherwise>3</xsl:otherwise>
            </xsl:choose>
         </xsl:attribute>
      </xsl:if>
      <xsl:if test="$element/@width">
         <xsl:attribute name="width">
            <xsl:choose>
               <xsl:when
         test="string-length(string($element/@width))>0">
	  <xsl:value-of select="$element/@width"/></xsl:when>
               <xsl:otherwise></xsl:otherwise>
            </xsl:choose>
         </xsl:attribute>
      </xsl:if>
   </xsl:template>

</xsl:stylesheet>
33.

Chunks for abstract and toc

Bob Stayton



> I wrote a long abstract part in my diploma thesis and want to split
> the abstract and toc on the HTML output to seperate pages.
>
> Is there an easy way to do this ?

The toc is easy. Just set the parameter 'chunk.toc.and.lots' to 1 and you will get a separate chunk.

The abstract is not so easy because there is no parameter to do it. It will require a customization. But you can basically copy what is done for legalnotice when the 'generate.legalnotice.link' parameter is set to 1. That code is in html/titlepage.xsl in the template that starts with:

<xsl:template match="legalnotice" mode="titlepage.mode">
34.

Add document title to each chunk

Bob Stayton


>
> In chunked HTML files, the title of a DocBook document is only displayed
> in the <title> section and as <h1> header of/in the first (the
> index.html) file.

>     * How to place the document title as <h1> header in every chunked
file?
>     * How to place the document title in the <title> section of every
>       chunked file, in the following format: "document_title -
>       section_title_of_chunk_file"?

You could use the 'user.header.content' template to add an H1 heading to every chunked file.

To merge the document title with each section title, you could customize the template named 'section.heading' from html/sections.xsl to output the document title before the section title. For chapters and other component-level elements, you would also need to customize the template named 'component.title' in html/component.xsl in a similar manner.