So I have been playing with the SourceForge DITA
Toolkit, trying to create better PDF outputs. I have
successfully modified the shell xsl file to include my
overrides, as that file suggests. I thought I would
share my overrides with you all. It is attached to
this note. You need only replace the
xsl/dita2fo-shell.xsl file in the DITA Toolkit package
with this one. Make sure to keep a copy of the
original xsl file from the Toolkit in case you want to
revert back to the original.
My overrides do the following:
- Fix the cover page
- Add a working table of contents, with hyperlinking
to each section
- Fix the display and implementation of internal
links, so that the topic title that is being linked to
is displayed, and the links actually go to their
targets
I have commented out the areas that I replaced in the
attached file, and added comments for all my changes
when possible, so it should be pretty easy to
understand what changes I made.
<?xml version="1.0" encoding="UTF-8" ?>
<!-- (c) Copyright IBM Corp. 2004, 2005 All Rights Reserved. -->
<!--
| Composite DITA topics to FO
*-->
<!DOCTYPE xsl:stylesheet [
<!-- entities for use in the generated output (Unicode typographic glyphs) -->
<!ENTITY gt ">">
<!ENTITY lt "<">
<!ENTITY rbl " ">
<!ENTITY nbsp " ">
<!ENTITY quot """>
<!ENTITY quotedblleft "“">
<!ENTITY quotedblright "”">
<!ENTITY sqbull "[]">
<!ENTITY middot "¥">
<!ENTITY section "§">
<!ENTITY endash "–">
<!ENTITY emdash "—">
<!ENTITY copyr "©">
<!ENTITY trademark "™">
<!ENTITY registered "®">
<!-- create some fixed values for now for customizing later -->
<!ENTITY copyrowner "Sample Company">
<!ENTITY copyrdate "2001">
<!ENTITY headerstub "(stub for header content)">
]>
<xsl:stylesheet version="1.0" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- stylesheet imports -->
<xsl:import href="xslfo/topic2foImpl.xsl"/>
<xsl:import href="xslfo/domains2fo.xsl"/>
<!-- XSL-FO output with XML syntax; no actual doctype for FO -->
<xsl:output method="xml" version="1.0" indent="yes"/>
<!-- CONTROL PARAMETERS: -->
<!-- offset -->
<xsl:param name="basic-start-indent">72pt</xsl:param>
<xsl:param name="basic-end-indent">24pt</xsl:param>
<xsl:param name="output-related-links"/>
<!-- GLOBALS: -->
<xsl:variable name="dflt-ext">.jpg</xsl:variable>
<!-- For Antenna House, set to ".jpg" -->
<!-- Set the prefix for error message numbers -->
<xsl:variable name="msgprefix">IDXS</xsl:variable>
<!-- =============== start of override tweaks ============== -->
<!-- force draft mode on all the time -->
<xsl:param name="DRAFT" select="'no'"/>
<!-- ====================== template rules for merged content ==================== -->
<xsl:template match="dita" mode="toplevel">
<xsl:call-template name="dita-setup"/>
</xsl:template>
<xsl:template match="*[contains(@class,' map/map ')]" mode="toplevel">
<xsl:call-template name="dita-setup"/>
</xsl:template>
<!-- note that bkinfo provides information for a cover in a bookmap application,
hence bkinfo does not need to be instanced. In an application that processes
only maps, bkinfo should process as a topic based on default processing. -->
<xsl:template match="*[contains(@class,' bkinfo/bkinfo ')]" priority="2">
<!-- no operation for bkinfo -->
</xsl:template>
<!-- =========================== overall output organization ========================= -->
<!-- this template rule defines the overall output organization -->
<xsl:template name="dita-setup">
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<!-- get the overall master page defs here -->
<xsl:call-template name="define-page-masters-dita"/>
<!-- place generated content -->
<xsl:call-template name="front-covers"/>
<!--xsl:call-template name="titlepage-ednotice"/-->
<xsl:call-template name="generated-frontmatter"/>
<!-- place main content (fall through occurs here) -->
<xsl:call-template name="main-doc3"/>
<!-- return to place closing generated content -->
<!--xsl:call-template name="index-chapter"/-->
<!--xsl:call-template name="back-covers"/-->
</fo:root>
</xsl:template>
<xsl:template name="define-page-masters-dita">
<fo:layout-master-set>
<!-- master set for chapter pages, first page is the title page -->
<fo:page-sequence-master master-name="chapter-master">
<fo:repeatable-page-master-alternatives>
<fo:conditional-page-master-reference page-position="first"
odd-or-even="odd" master-reference="common-page"/>
<!-- chapter-first-odd -->
<fo:conditional-page-master-reference page-position="first"
odd-or-even="even" master-reference="common-page"/>
<!--chapter-first-even"/-->
<fo:conditional-page-master-reference page-position="rest"
odd-or-even="odd" master-reference="common-page"/>
<!--chapter-rest-odd"/-->
<fo:conditional-page-master-reference page-position="rest"
odd-or-even="even" master-reference="common-page"/>
<!--chapter-rest-even"/-->
</fo:repeatable-page-master-alternatives>
</fo:page-sequence-master>
<fo:simple-page-master master-name="cover" xsl:use-attribute-sets="common-grid">
<fo:region-body margin-top="72pt"/>
</fo:simple-page-master>
<fo:simple-page-master master-name="common-page" xsl:use-attribute-sets="common-grid">
<fo:region-body margin-bottom="36pt" margin-top="12pt"/>
<fo:region-before extent="12pt"/>
<fo:region-after extent="24pt"/>
</fo:simple-page-master>
</fo:layout-master-set>
</xsl:template>
<xsl:template name="front-covers">
<!-- generate an "outside front cover" page (right side) (sheet 1) -->
<fo:page-sequence master-reference="cover">
<!--Jeff added this here -->
<fo:static-content flow-name="xsl-region-after">
<!-- set the brief copyright notice -->
<fo:block margin-top="3pc" text-align="right" font-size="8pt" line-height="normal">
©r; Copyright
<xsl:value-of select="//*[contains(@class,' topic/copyright ')]/copyryear/@year"/>:
<xsl:value-of select="//*[contains(@class,' topic/copyright ')]/*[contains(@class,' topic/copyrholder ')]"/><xsl:text> </xsl:text>
</fo:block>
</fo:static-content>
<!--End of Jeff's addition -->
<!--Jeff is adding this section to replace what was originally there below -->
<fo:flow flow-name="xsl-region-body" >
<!-- Custom cover art/text goes here -->
<xsl:call-template name="place-cover-art"/>
<!-- End of custom art section -->
<fo:block text-align="left" font-family="Helvetica">
<!-- set the brand and title -->
<fo:block font-size="14pt" line-height="540%" margin-bottom="1in" text-align="right">
<xsl:value-of select="//*[contains(@class,' topic/prodinfo ')]/*[contains(@class,' topic/brand ')]"/>
</fo:block>
<fo:block font-size="22pt" font-weight="bold" line-height="140%">
<xsl:value-of select="//*[contains(@class,' topic/prodinfo ')]/*[contains(@class,' topic/prodname ')]"/>
</fo:block>
<!-- set the subtitle -->
<fo:block font-size="8pt" line-height="140%" margin-bottom="1in" font-style="italic">
Version <xsl:value-of select="//*[contains(@class,' topic/prodinfo ')]/vrmlist/vrm/@version"/>
</fo:block>
</fo:block>
</fo:flow>
<!--This is the original piece below, but Jeff is commenting it out to replace with his own above.
<fo:flow flow-name="xsl-region-body">
<fo:block text-align="right" font-family="Helvetica">
<fo:block font-size="30pt" font-weight="bold" line-height="140%">
<xsl:value-of select="//*[contains(@class,' bkinfo/bkinfo ')]/*[contains(@class,' topic/title ')]"/>
</fo:block>
<fo:block font-size="24pt" font-weight="bold" line-height="140%" margin-bottom="1in">
<xsl:value-of select="//*[contains(@class,' bkinfo/bkinfo ')]/*[contains(@class,' bkinfo/bktitlealts ')]/*[contains(@class,' bkinfo/bksubtitle ')]"/>
</fo:block>
<fo:block font-size="11pt" font-weight="bold" line-height="1.5">
<xsl:text>[vertical list of authors]</xsl:text>
</fo:block>
<xsl:for-each select="//author">
<fo:block font-size="11pt" font-weight="bold" line-height="1.5">
[<xsl:value-of select="."/>] </fo:block>
</xsl:for-each>
<fo:block margin-top="3pc" font-size="11pt" font-weight="bold"
line-height="normal"> ©r; Copyright
<xsl:value-of select="//*[contains(@class,' bkinfo/orgname ')]"/>
<xsl:text/>
<xsl:value-of
select="//*[contains(@class,' bkinfo/bkcopyrfirst ')]"/>,<xsl:value-of
select="//*[contains(@class,' bkinfo/bkcopyrlast ')]"/>. </fo:block>
</fo:block>
<xsl:call-template name="place-cover-art"/>
</fo:flow>
-->
</fo:page-sequence>
<!-- generate an "inside front cover" page (left side) (sheet 2) -->
<fo:page-sequence master-reference="cover">
<fo:flow flow-name="xsl-region-body">
<fo:block xsl:use-attribute-sets="p" color="purple" text-align="center"/>
</fo:flow>
</fo:page-sequence>
</xsl:template>
<!--Jeff is adding this to replace the piece below...-->
<xsl:template name="place-cover-art">
<!-- product specific art, etc. -->
<fo:block margin-top="2pc" font-family="Helvetica" border-color="black" border-width="thin" padding="6pt">
<fo:block font-size="12pt" line-height="100%" margin-top="12pc" margin-bottom="12pc" text-align="right">
[We can put a logo or graphic here]
<!-- one might imbed SVG directly here for use with FOP, for instance -->
</fo:block>
</fo:block>
</xsl:template>
<!-- Jeff is commenting this out to replace with piece above.
<xsl:template name="place-cover-art">
<fo:block margin-top="2pc" font-family="Helvetica" border-style="dashed"
border-color="black" border-width="thin" padding="6pt">
<fo:block font-size="12pt" line-height="100%" margin-top="12pc"
margin-bottom="12pc" text-align="center">
<fo:inline color="purple" font-weight="bold">[cover art/text goes here]</fo:inline>
</fo:block>
</fo:block>
</xsl:template>
-->
<!-- internal title page -->
<!-- edition notices -->
<!-- document notice data -->
<!-- grant of usage data -->
<!-- copyright info -->
<!-- disclaimers -->
<!-- redirect to notices page -->
<!-- definitions for placement of Front Matter content -->
<xsl:template name="generated-frontmatter">
<fo:page-sequence master-reference="common-page" format="i" initial-page-number="1">
<!-- Static setup for the generated pages -->
<!-- header -->
<fo:static-content flow-name="xsl-region-before">
<xsl:variable name="booktitle">
<xsl:value-of select="@title"/>
</xsl:variable>
<fo:block font-size="8pt" line-height="8pt">
<xsl:value-of select="$booktitle"/>
</fo:block>
</fo:static-content>
<!-- footer -->
<fo:static-content flow-name="xsl-region-after">
<fo:block text-align="center" font-size="10pt" font-weight="bold" font-family="Helvetica">
<fo:page-number/>
</fo:block>
</fo:static-content>
<!-- Flow setup for the Front Matter "body" (new "chapters" start on odd pages) -->
<fo:flow flow-name="xsl-region-body">
<!-- first, generate a compulsory Table of Contents -->
<fo:block line-height="12pt" font-size="10pt" font-family="Helvetica" id="page1-1">
<fo:block text-align="left" font-family="Helvetica">
<fo:block>
<fo:leader color="black" leader-pattern="rule"
rule-thickness="3pt" leader-length="2in"/>
</fo:block>
<fo:block font-size="20pt" font-weight="bold" line-height="140%">
Contents </fo:block>
<xsl:call-template name="gen-toc"/>
</fo:block>
</fo:block>
</fo:flow>
</fo:page-sequence>
</xsl:template>
<xsl:template name="unused-toc">
<!-- generate the List of Figures -->
<!-- To be done
<fo:block text-align="left" font-family="Helvetica" break-before="page">
<fo:block><fo:leader color="black" leader-pattern="rule" rule-thickness="3pt" leader-length="2in"/></fo:block>
<fo:block font-size="20pt" font-weight="bold" line-height="140%">
Figures
</fo:block>
<xsl:call-template name="gen-figlist"/>
</fo:block>
-->
<!-- generate the List of Tables -->
<!-- To be done
<fo:block text-align="left" font-family="Helvetica" break-before="page">
<fo:block><fo:leader color="black" leader-pattern="rule" rule-thickness="3pt" leader-length="2in"/></fo:block>
<fo:block font-size="20pt" font-weight="bold" line-height="140%">
Tables
</fo:block>
<xsl:call-template name="gen-tlist"/>
</fo:block>
-->
<!-- To be done: while still in Roman numbering, all the bkfrontm content... -->
</xsl:template>
<!-- initiate main content processing within basic page "shell" -->
<xsl:template name="main-doc3">
<fo:page-sequence master-reference="chapter-master">
<!-- header: single page -->
<fo:static-content flow-name="xsl-region-before">
<!-- book title here -->
<xsl:variable name="booktitle">
<!-- <xsl:value-of select="//*/title"/> -->
<xsl:value-of select="@title"/>
</xsl:variable>
<fo:block font-size="8pt" line-height="8pt">
<xsl:value-of select="$booktitle"/>
</fo:block>
</fo:static-content>
<!-- footer static stuff -->
<fo:static-content flow-name="xsl-region-after">
<fo:block text-align="center" font-size="10pt" font-weight="bold" font-family="Helvetica">
<fo:page-number/>
</fo:block>
</fo:static-content>
<!-- special footers for first page of new chapter -->
<!-- Flow setup for the main content (frontm, body, backm) (new "chapters" start on odd pages) -->
<fo:flow flow-name="xsl-region-body">
<!-- chapter body content here -->
<fo:block text-align="left" font-size="10pt" font-family="Helvetica" break-before="page">
<xsl:apply-templates/>
</fo:block>
</fo:flow>
</fo:page-sequence>
</xsl:template>
<!-- set up common attributes for all page definitions -->
<xsl:attribute-set name="common-grid">
<xsl:attribute name="page-width">51pc</xsl:attribute>
<!-- A4: 210mm -->
<xsl:attribute name="page-height">66pc</xsl:attribute>
<!-- A4: 297mm -->
<xsl:attribute name="margin-top">3pc</xsl:attribute>
<xsl:attribute name="margin-bottom">3pc</xsl:attribute>
<xsl:attribute name="margin-left">6pc</xsl:attribute>
<xsl:attribute name="margin-right">6pc</xsl:attribute>
</xsl:attribute-set>
<!-- set up common attributes for all page definitions -->
<xsl:attribute-set name="maptitle">
<xsl:attribute name="font-size">16pt</xsl:attribute>
<xsl:attribute name="font-weight">bold</xsl:attribute>
</xsl:attribute-set>
<!-- set up common attributes for all page definitions -->
<xsl:attribute-set name="mapabstract">
<xsl:attribute name="margin-top">3pc</xsl:attribute>
<xsl:attribute name="margin-bottom">3pc</xsl:attribute>
<xsl:attribute name="margin-left">6pc</xsl:attribute>
<xsl:attribute name="margin-right">6pc</xsl:attribute>
</xsl:attribute-set>
<!-- main toc generator -->
<xsl:template name="gen-toc">
<!-- (Jeff adding this) get by main part: body -->
<xsl:for-each select="//map/*[contains(@class,' topic/topic ')]">
<fo:block margin-top="24pt">
</fo:block>
<fo:block text-align-last="justify" margin-top="6pt" margin-left="4.9pc">
<fo:basic-link
internal-destination="{string(@id)}">
<fo:inline font-weight="bold"><!--Chapter <xsl:number level="any" from="map"/>. -->
<xsl:value-of select="*[contains(@class,' topic/title ')]"/>
</fo:inline>
<fo:leader leader-pattern="dots"/>
<fo:page-number-citation ref-id="{generate-id()}"/>
</fo:basic-link>
</fo:block>
<xsl:call-template name="get-tce2-section"/>
</xsl:for-each>
</xsl:template>
<!-- (Jeff is commenting this out to replace with above section) get by main part: body
<xsl:for-each select="//bookmap/*[contains(@class,' topic/topic ')]">
<fo:block text-align-last="justify" margin-top="6pt" margin-left="4.9pc">
<fo:inline font-weight="bold">
<xsl:value-of select="*[contains(@class,' topic/title ')]"/>
</fo:inline>
<fo:leader leader-pattern="dots"/>
<fo:page-number-citation ref-id="{generate-id()}"/>
</fo:block>
<xsl:call-template name="get-tce2-section"/>
</xsl:for-each>
</xsl:template>
-->
<!-- 2nd level header -->
<xsl:template name="get-tce2-section">
<xsl:for-each select="*[contains(@class,' topic/topic ')]">
<fo:block text-align-last="justify" margin-left="7.5pc">
<fo:basic-link
internal-destination="{string(@id)}">
<fo:inline><xsl:value-of select="*[contains(@class,' topic/title ')]"/></fo:inline>
<fo:leader leader-pattern="dots"/>
<fo:page-number-citation ref-id="{generate-id()}"/>
</fo:basic-link>
</fo:block>
<xsl:call-template name="get-tce3-section"/>
</xsl:for-each>
</xsl:template>
<!-- 3nd level header -->
<xsl:template name="get-tce3-section">
<xsl:for-each select="*[contains(@class,' topic/topic ')]">
<fo:block text-align-last="justify" margin-left="9pc">
<fo:basic-link
internal-destination="{string(@id)}">
<xsl:value-of select="*[contains(@class,' topic/title ')]"/>
<fo:leader leader-pattern="dots"/>
<fo:page-number-citation ref-id="{generate-id()}"/>
</fo:basic-link>
</fo:block>
<xsl:call-template name="get-tce4-section"/>
</xsl:for-each>
</xsl:template>
<!-- 4th level header -->
<xsl:template name="get-tce4-section">
<xsl:for-each select="bksubsect1">
<fo:block text-align-last="justify" margin-left="+5.9pc">
<fo:basic-link
internal-destination="{string(@id)}">
<xsl:value-of select="*/title"/>
<fo:leader leader-pattern="dots"/>
<fo:page-number-citation ref-id="{generate-id()}"/>
</fo:basic-link>
</fo:block>
<xsl:call-template name="get-tce5-section"/>
</xsl:for-each>
</xsl:template>
<!-- 5th level header -->
<xsl:template name="get-tce5-section">
<xsl:for-each select="bksubsect2">
<fo:block text-align-last="justify" margin-left="+5.9pc">
<fo:basic-link
internal-destination="{string(@id)}">
<xsl:value-of select="*/title"/>
<fo:leader leader-pattern="dots"/>
<fo:page-number-citation ref-id="{generate-id()}"/>
</fo:basic-link>
</fo:block>
<!--xsl:call-template name="get-tce6-section"/-->
</xsl:for-each>
</xsl:template>
<xsl:template
match="*[contains(@class,' topic/xref ')[EMAIL PROTECTED] = '']">
<fo:inline color="red">
<fo:inline font-weight="bold">
[xref to:
<xsl:value-of select="@href" />
]
</fo:inline>
<xsl:apply-templates />
</fo:inline>
</xsl:template>
<!-- if there is an href, make it look like a link and remove prompt -->
<xsl:template
match="*[contains(@class,' topic/xref ')][not(@href = '')]">
<fo:inline color="blue" text-decoration="underline">
<xsl:variable name="hrefid">
<xsl:choose>
<xsl:when test="contains(@href, '/')">
<xsl:value-of
select="substring-before(substring-after(@href,'#'), '/')" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of
select="substring-after(@href,'#')" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:choose>
<xsl:when
test="not(contains(@href, '/'))">
<fo:basic-link
internal-destination="{string($hrefid)}">
<!--<xsl:value-of
select="//[EMAIL PROTECTED]/title/child::text()" /> -->
<xsl:apply-templates />
</fo:basic-link>
</xsl:when>
<xsl:otherwise>
<fo:basic-link
internal-destination="{string($hrefid)}">
<xsl:apply-templates />
</fo:basic-link>
</xsl:otherwise>
</xsl:choose>
</fo:inline>
</xsl:template>
<xsl:template
match="*[contains(@class,' topic/xref ')[EMAIL PROTECTED] = 'html']">
<fo:inline color="blue" text-decoration="underline">
<fo:basic-link external-destination="{string(@href)}">
<xsl:apply-templates />
</fo:basic-link>
</fo:inline>
</xsl:template>
</xsl:stylesheet>