RE: [PDF] Bookmarks - add index groups
Cramer, David W (David <dcramer <at> motive.com>
2010-09-01 18:36:52 GMT
Thanks for posting the details Jan. I've added a feature request linking back to this post. I think it would
be a nice addition to the base xsls:
https://sourceforge.net/tracker/index.php?func=detail&aid=3057673&group_id=21935&atid=373750
David
-----Original Message-----
From: honyk [mailto:j.tosovsky <at> email.cz]
Sent: Wednesday, September 01, 2010 1:10 PM
To: 'Jirka Kosek'; 'Bob Stayton'
Cc: docbook-apps <at> lists.oasis-open.org
Subject: RE: [docbook-apps] [PDF] Bookmarks - add index groups
Hello Guys,
thanks for your useful hints, it is working now!
Some details for future followers...
I've modified templates which match 'indexterm' in modes 'index-div-basic' and 'index-symbol-div'
placing the id attribute on the block element (to create an anchor):
<fo:block id="id{$key}">
Into the bookmark processing code (mode="xep.outline") I've added another branching:
<xsl:when test="self::index">
<rx:bookmark internal-destination="{$id}">
<rx:bookmark-label>
<xsl:value-of select="normalize-space($bookmark-label)"/>
</rx:bookmark-label>
<xsl:apply-templates select="." mode="xep.outline.index"/>
</rx:bookmark>
</xsl:when>
which calls the following template
<xsl:template match="index" mode="xep.outline.index">
<xsl:param name="scope" select="(ancestor::book|/)[last()]"/>
<xsl:variable name="role">
<xsl:if test="$index.on.role != 0">
<xsl:value-of select=" <at> role"/>
</xsl:if>
</xsl:variable>
<xsl:variable name="type">
<xsl:if test="$index.on.type != 0">
<xsl:value-of select=" <at> type"/>
</xsl:if>
</xsl:variable>
<xsl:variable name="terms"
select="//indexterm
[count(.|key('letter',
translate(substring(&primary;, 1, 1),
&lowercase;,
&uppercase;))
[&scope;][1]) = 1
and not( <at> class = 'endofrange')]"/>
<xsl:variable name="alphabetical"
select="$terms[contains(concat(&lowercase;, &uppercase;),
substring(&primary;, 1, 1))]"/>
<xsl:for-each select="$alphabetical">
<xsl:sort select="substring(&primary;, 1, 1)"/>
<xsl:variable name="label">
<xsl:call-template name="string.upper">
<xsl:with-param name="string"
select="substring(&primary;, 1, 1)"/>
</xsl:call-template>
</xsl:variable>
<rx:bookmark internal-destination="id{$label}">
<rx:bookmark-label>
<xsl:value-of select="$label"/>
</rx:bookmark-label>
</rx:bookmark>
</xsl:for-each>
</xsl:template>
The latter code requires placing special entities (/common/entities.ent) into the XSLT file:
<!DOCTYPE xsl:stylesheet [
<!ENTITY % common.entities SYSTEM "path to common entities ">
%common.entities;
]>
That's it.
Thanks once again.
Jan
> Bob Stayton wrote:
>
> > The tricky part is determining which letters actually have entries in
> > the current index, so you don't create bookmark links to non-existant
> > index sections. I don't have a quick solution for that one.
>
> I think that code from autoidx.xsl can be reused, namely from
> generate-basic-template. For example following code will populate
> variable $alphabetical with exactly one indexterm for each letter.
>
> <xsl:variable name="terms"
> select="//indexterm
> [count(.|key('letter',
> translate(substring(&primary;, 1, 1),
> &lowercase;,
> &uppercase;))
> [&scope;][1]) = 1
> and not( <at> class = 'endofrange')]"/>
>
> <xsl:variable name="alphabetical"
> select="$terms[contains(concat(&lowercase;,
> &uppercase;),
> substring(&primary;, 1, 1))]"/>
>
> So in order to get just letters something like the following code could
> be used:
>
> <xsl:for-each select="$alphabetical">
> <rx:bookmark-label>
> <xsl:value-of select="substring(&primary;, 1, 1)"/
> </rx:bookmark-label>
> </xsl:for-each>
>
> Jirka
---------------------------------------------------------------------
To unsubscribe, e-mail: docbook-apps-unsubscribe <at> lists.oasis-open.org
For additional commands, e-mail: docbook-apps-help <at> lists.oasis-open.org