Markus Gamperl wrote:
Hello Eliot!
I'm also evaluating your suggestion (saxon extension) - but i'm having
problems in including the extensions in my stylesheet! What do i have to do
to get it working in my Stylesheet (perhaps include .jar file in
CLASSPATH,...)
Because in the .zip file there are NO example files as mentioned on the
website... (rendered_text_width_test.xml and
rendered_text_width_test_fo.xsl)
Doh! Totally my mistake--I failed to include those in the package I gave
to our Web dude. I'll try to get that corrected today.
So how i have to use it???
Here's the sample XSLT script that should have been in the package. You
do need the jar file in your classpath but the real key is the
"xmlns:inno_iso=" attribute below: this binds the namespace prefix for
the extension functions to the Java class that implements the functions
according to the Saxon 6.x extension API.
---- cut here ----
<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:inno_iso="java:com.innodata_isogen.saxon.InnodataSaxonExtensions"
>
<!--======================================
Copyright (c) 2004 Innodata Isogen, All Rights Reserved
This XSLT transform demonstrates teh use of the
InnodataSaxonExtensions
Java library. It may be used, copied, or modified without restriction.
Run this style sheet using Saxon from the xslt directory like so:
java com.icl.saxon.StyleSheet -cp
../build/inno_iso_saxon_extensions.jar;../lib/saxon.jar
rendered_text_width_test.xml rendered_text_width_test_fo.xsl > test.fo
$Revision: 1.4 $
======================================-->
<xsl:param name="base-font-size" select="'12pt'"/>
<xsl:param name="base-font-family" select="'Times New Roman'"/>
<xsl:template match="/">
<fo:root
font-size="{$base-font-size}"
font-family="{$base-font-family}"
line-height="120%"
>
<xsl:call-template name="generate-layout-master-set"/>
<xsl:apply-templates/>
</fo:root>
</xsl:template>
<xsl:template match="/*">
<fo:page-sequence master-reference="basepage">
<fo:static-content flow-name="xsl-region-after">
<fo:block
text-align="center"
>
<xsl:text>-</xsl:text>
<fo:page-number/>
<xsl:text>-</xsl:text>
</fo:block>
</fo:static-content>
<fo:flow flow-name="xsl-region-body"
>
<xsl:apply-templates/>
</fo:flow>
</fo:page-sequence>
</xsl:template>
<xsl:template match="section">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="/*/title">
<fo:block
font-size="16pt"
font-weight="bold"
font-family="sans-serif"
space-after="1.5em"
><xsl:apply-templates/>
</fo:block>
</xsl:template>
<xsl:template match="section/title">
<fo:block
font-size="14pt"
font-weight="bold"
space-before="12pt"
space-after="1em"
><xsl:apply-templates/>
</fo:block>
</xsl:template>
<xsl:template match="deflist">
<xsl:variable name="label_width">
<xsl:call-template name="get-longest-item-length">
<xsl:with-param name="items" select="dlitem/term"/>
<xsl:with-param name="curr_width" select="0"/>
<xsl:with-param name="font-family" select="'Times New Roman'"/>
<xsl:with-param name="font-weight" select="'bold'"/>
<xsl:with-param name="font-size" select="12"/>
</xsl:call-template>
</xsl:variable>
<xsl:apply-templates select="title"/>
<fo:list-block
provisional-distance-between-starts="{$label_width}"
provisional-label-separation="1pt"
>
<xsl:apply-templates select="dlitem"/>
</fo:list-block>
</xsl:template>
<xsl:template match="dlitem">
<fo:list-item
space-before="6pt"
>
<xsl:apply-templates/>
</fo:list-item>
</xsl:template>
<xsl:template match="dlitem/term">
<fo:list-item-label end-indent="label-end()">
<fo:block
font-weight="bold"
><xsl:apply-templates/>
</fo:block>
</fo:list-item-label>
</xsl:template>
<xsl:template match="dlitem/definition">
<fo:list-item-body start-indent="body-start()">
<xsl:apply-templates/>
</fo:list-item-body>
</xsl:template>
<xsl:template match="deflist/title">
<fo:block
space-before="6pt"
font-weight="bold"
keep-with-next="always"
><xsl:apply-templates/>
</fo:block>
</xsl:template>
<xsl:template match="para">
<fo:block
space-before="6pt"
><xsl:apply-templates/>
</fo:block>
</xsl:template>
<xsl:template match="font_list">
<fo:block
space-before="6pt"
linefeed-treatment="preserve"
>
<xsl:value-of select="inno_iso:listJavaSystemFonts()"/>
</fo:block>
</xsl:template>
<xsl:template match="show_text_length">
<xsl:variable name="font-family">
<xsl:choose>
<xsl:when test="string(@font-family) != ''">
<xsl:value-of select="@font-family"/>
</xsl:when>
<xsl:otherwise><xsl:value-of
select="$base-font-family"/></xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="font-weight">
<xsl:choose>
<xsl:when test="string(@font-weight) != ''">
<xsl:value-of select="@font-weight"/>
</xsl:when>
<xsl:otherwise>normal</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="font-size">
<xsl:choose>
<xsl:when test="string(@font-size) != ''">
<xsl:value-of select="@font-size"/>
</xsl:when>
<xsl:otherwise><xsl:value-of
select="$base-font-size"/></xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="text">
<xsl:apply-templates mode="text-only"/>
</xsl:variable>
<fo:inline
border-style="solid"
border-color="blue"
border-width="0.5pt"
font-size="{$font-size}"
font-family="{$font-family}"
font-weight="{$font-weight}"
><xsl:apply-templates
/></fo:inline>
<xsl:text> rendered length=</xsl:text
><xsl:value-of
select="inno_iso:renderedTextLength($text, $font-family,
$font-weight, $font-size)"
/><xsl:text>pt, font used: </xsl:text>
<xsl:value-of select="inno_iso:renderedTextFontName($font-family,
$font-weight, $font-size)"/>
</xsl:template>
<xsl:template match="point_scale">
<xsl:call-template name="pica-ruler">
<xsl:with-param name="picas" select="18"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="get-longest-item-length">
<!-- Given a list of nodes, process each one in text-only mode and
return the width of the
longest as determined by the renderedTextLength() extension
function.
When calling for the first time, specify a non-zero value for
the curr_width
parameter to establish a minimum length to be returned.
-->
<xsl:param name="items"/><!-- List of elements to process, e.g.
option_item/option -->
<xsl:param name="curr_width"/><!-- Longest width we have so far -->
<xsl:param name="font-family"/>
<xsl:param name="font-weight"/>
<xsl:param name="font-size"/>
<xsl:variable name="text">
<xsl:apply-templates select="$items[1]" mode="text-only"/>
</xsl:variable>
<xsl:variable name="cand_width"
select="inno_iso:renderedTextLength(string($text),
'NokiaSans',
'bold',
$font-size)"
/>
<xsl:choose>
<xsl:when test="count($items) = 0">
<xsl:value-of select="concat($curr_width, 'pt')"/>
</xsl:when>
<xsl:when test="$curr_width > $cand_width">
<xsl:call-template name="get-longest-item-length">
<xsl:with-param name="items" select="$items[position() > 1]"/>
<xsl:with-param name="curr_width" select="$curr_width"/>
<xsl:with-param name="font-family" select="$font-family"/>
<xsl:with-param name="font-weight" select="$font-weight"/>
<xsl:with-param name="font-size" select="$font-size"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="get-longest-item-length">
<xsl:with-param name="items" select="$items[position() > 1]"/>
<xsl:with-param name="curr_width" select="$cand_width"/>
<xsl:with-param name="font-family" select="$font-family"/>
<xsl:with-param name="font-weight" select="$font-weight"/>
<xsl:with-param name="font-size" select="$font-size"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="generate-layout-master-set">
<fo:layout-master-set>
<fo:simple-page-master master-name="basepage"
page-height="11in"
page-width="8.5in">
<fo:region-body
margin-left="1in"
margin-right="1in"
margin-top="1in"
margin-bottom="1in"
/>
<fo:region-after
extent="0.75in"
/>
</fo:simple-page-master>
</fo:layout-master-set>
</xsl:template>
<xsl:template name="pica-ruler">
<xsl:param name="picas" select="6"/>
<fo:table
table-layout="fixed"
>
<xsl:call-template name="pr-generate-table-columns">
<xsl:with-param name="picas" select="$picas"/>
</xsl:call-template>
<fo:table-body
margin-left="0pt"
start-indent="0pt"
font-size="6pt"
line-height="100%"
>
<fo:table-row>
<xsl:call-template name="pr-generate-top-row-cells">
<xsl:with-param name="max-value" select="$picas * 12"/>
</xsl:call-template>
</fo:table-row>
<fo:table-row height="0.5em">
<xsl:call-template name="pr-generate-mid-row-cells">
<xsl:with-param name="picas" select="$picas"/>
</xsl:call-template>
</fo:table-row>
<fo:table-row height="0.5em">
<xsl:call-template name="pr-generate-bottom-row-cells">
<xsl:with-param name="picas" select="$picas"/>
</xsl:call-template>
</fo:table-row>
</fo:table-body>
</fo:table>
</xsl:template>
<xsl:template name="pr-generate-table-columns">
<!-- Generate one pica's worth of table column specs -->
<xsl:param name="picas" select="0"/>
<xsl:choose>
<xsl:when test="$picas <= 0 or $picas = 'NaN'"/>
<xsl:otherwise>
<fo:table-column
column-width="4pt"/>
<fo:table-column
column-width="4pt"/>
<fo:table-column
column-width="4pt"/>
<xsl:call-template name="pr-generate-table-columns">
<xsl:with-param name="picas" select="$picas - 1"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="pr-generate-top-row-cells">
<!-- Generate one pica's worth of table cells for the first row -->
<xsl:param name="max-value" select="0"/>
<xsl:param name="picas-rendered" select="0"/>
<xsl:choose>
<xsl:when test="$picas-rendered >= $max-value"/><!-- Need to handle
case where picas is not a multiple of 3 -->
<xsl:otherwise>
<fo:table-cell
number-columns-spanned="3"
>
<fo:block><xsl:value-of
select="$picas-rendered"/></fo:block><!-- 3 divisions of 4 points each -->
</fo:table-cell>
<fo:table-cell
number-columns-spanned="3"
>
<fo:block><xsl:value-of select="$picas-rendered + (4 *
3)"/></fo:block><!-- 3 divisions of 4 points each -->
</fo:table-cell>
<fo:table-cell
number-columns-spanned="3"
>
<fo:block><xsl:value-of select="$picas-rendered + ((4 * 3) *
2)"/></fo:block><!-- 3 divisions of 4 points each -->
</fo:table-cell>
<xsl:call-template name="pr-generate-top-row-cells">
<xsl:with-param name="picas-rendered" select="$picas-rendered +
(4 * 3) * 3"/>
<xsl:with-param name="max-value" select="$max-value"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="pr-generate-mid-row-cells">
<!-- Generate one pica's worth of table cells for the middle row -->
<xsl:param name="picas" select="0"/>
<xsl:choose>
<xsl:when test="$picas <= 0 or string($picas) = 'NaN'"/><!--
Need to handle case where picas is not a multiple of 3 -->
<xsl:otherwise>
<fo:table-cell
number-columns-spanned="3"
border-start-style="solid"
border-start-width="0.5pt"
border-start-color="blue">
<fo:block>​</fo:block>
</fo:table-cell>
<fo:table-cell
number-columns-spanned="3"
border-start-style="solid"
border-start-width="0.5pt"
border-start-color="blue">
<fo:block>​</fo:block>
</fo:table-cell>
<fo:table-cell
number-columns-spanned="3"
border-start-style="solid"
border-start-width="0.5pt"
border-start-color="blue">
<fo:block>​</fo:block>
</fo:table-cell>
<xsl:call-template name="pr-generate-mid-row-cells">
<xsl:with-param name="picas" select="$picas - 3"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="pr-generate-bottom-row-cells">
<!-- Generate one pica's worth of table cells for the middle row -->
<xsl:param name="picas" select="0"/>
<xsl:choose>
<xsl:when test="$picas <= 0 or string($picas) = 'NaN'"/><!--
Need to handle case where picas is not a multiple of 3 -->
<xsl:otherwise>
<fo:table-cell
border-start-style="solid"
border-start-width="0.5pt"
border-start-color="blue">
<fo:block>​</fo:block>
</fo:table-cell>
<fo:table-cell
border-start-style="solid"
border-start-width="0.5pt"
border-start-color="blue">
<fo:block>​</fo:block>
</fo:table-cell>
<fo:table-cell
border-start-style="solid"
border-start-width="0.5pt"
border-start-color="blue">
<fo:block>​</fo:block>
</fo:table-cell>
<fo:table-cell
border-start-style="solid"
border-start-width="0.5pt"
border-start-color="blue">
<fo:block>​</fo:block>
</fo:table-cell>
<fo:table-cell
border-start-style="solid"
border-start-width="0.5pt"
border-start-color="blue">
<fo:block>​</fo:block>
</fo:table-cell>
<fo:table-cell
border-start-style="solid"
border-start-width="0.5pt"
border-start-color="blue">
<fo:block>​</fo:block>
</fo:table-cell>
<fo:table-cell
border-start-style="solid"
border-start-width="0.5pt"
border-start-color="blue">
<fo:block>​</fo:block>
</fo:table-cell>
<fo:table-cell
border-start-style="solid"
border-start-width="0.5pt"
border-start-color="blue">
<fo:block>​</fo:block>
</fo:table-cell>
<fo:table-cell
border-start-style="solid"
border-start-width="0.5pt"
border-start-color="blue"
>
<fo:block>​</fo:block>
</fo:table-cell>
<xsl:call-template name="pr-generate-bottom-row-cells">
<xsl:with-param name="picas" select="$picas - 3"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
--
W. Eliot Kimber
Professional Services
Innodata Isogen
9030 Research Blvd, #410
Austin, TX 78758
(512) 372-8122
eliot(_at_)innodata-isogen(_dot_)com
www.innodata-isogen.com