[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]
Subject: RE: [docbook-apps] Re: [docbook] Indexterms - see and seealso linked to another indexterm
On 2013-10-08 Bob Stayton wrote: > The basic problem is that the entries in the index are generated from > indexterm elements that reside in the document. You cannot directly use > the id of an indexterm, because that is used to link back into the > text. > So an index entry needs to generate its own unique id. Then the > stylesheet needs to match the text from the <see> to the first > <primary> > element that matches (there may be many). I am attaching my customization I use for some time (for FO/PDF). It generates required IDs [1] and corresponding links to them. I use it rather on simple indexes so it may not work in more complex ones. HTH, Jan __________ [1] IDs are composed from normalized primary/secondary entries (spaces are translated into dashes). Bob's approach to use the generate-id() function seems to be better here.
<?xml version='1.0'?> <!DOCTYPE xsl:stylesheet [ <!ENTITY % common.entities SYSTEM "../../../docbook-stylesheets/1.78.1/common/entities.ent"> %common.entities; ]> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:rx="http://www.renderx.com/XSL/Extensions" exclude-result-prefixes="rx" version="1.0"> <!-- Indices interlinking & tilde --> <!-- added block ID --> <xsl:template match="indexterm" mode="index-div-basic"> <xsl:param name="scope" select="."/> <xsl:param name="role" select="''"/> <xsl:param name="type" select="''"/> <xsl:variable name="key" select="translate(substring(&primary;, 1, 1), &lowercase;,&uppercase;)"/> <xsl:if test="key('letter', $key)[&scope;] [count(.|key('primary', &primary;)[&scope;][1]) = 1]"> <fo:block id="id{$key}"> <xsl:if test="contains(concat(&lowercase;, &uppercase;), $key)"> <xsl:call-template name="indexdiv.title"> <xsl:with-param name="titlecontent"> <xsl:value-of select="translate($key, &lowercase;, &uppercase;)"/> </xsl:with-param> </xsl:call-template> </xsl:if> <fo:block xsl:use-attribute-sets="index.entry.properties"> <xsl:apply-templates select="key('letter', $key)[&scope;] [count(.|key('primary', &primary;) [&scope;][1])=1]" mode="index-primary"> <xsl:sort select="translate(&primary;, &lowercase;, &uppercase;)"/> <xsl:with-param name="scope" select="$scope"/> <xsl:with-param name="role" select="$role"/> <xsl:with-param name="type" select="$type"/> </xsl:apply-templates> </fo:block> </fo:block> </xsl:if> </xsl:template> <!-- added block ID --> <xsl:template match="indexterm" mode="index-symbol-div"> <xsl:param name="scope" select="."/> <xsl:param name="role" select="''"/> <xsl:param name="type" select="''"/> <xsl:variable name="key" select="translate(substring(&primary;, 1, 1),&lowercase;,&uppercase;)"/> <fo:block xsl:use-attribute-sets="index.entry.properties" id="id{$key}"> <xsl:apply-templates select="key('letter', $key)[&scope;][count(.|key('primary', &primary;)[&scope;][1]) = 1]" mode="index-primary"> <xsl:with-param name="scope" select="$scope"/> <xsl:with-param name="role" select="$role"/> <xsl:with-param name="type" select="$type"/> <xsl:sort select="translate(&primary;, &lowercase;, &uppercase;)"/> </xsl:apply-templates> </fo:block> </xsl:template> <xsl:template match="indexterm" mode="index-primary"> <xsl:param name="scope" select="."/> <xsl:param name="role" select="''"/> <xsl:param name="type" select="''"/> <xsl:variable name="key" select="&primary;"/> <xsl:variable name="refs" select="key('primary', $key)[&scope;]"/> <xsl:variable name="term.separator"> <xsl:call-template name="index.separator"> <xsl:with-param name="key" select="'index.term.separator'"/> </xsl:call-template> </xsl:variable> <xsl:variable name="range.separator"> <xsl:call-template name="index.separator"> <xsl:with-param name="key" select="'index.range.separator'"/> </xsl:call-template> </xsl:variable> <xsl:variable name="number.separator"> <xsl:call-template name="index.separator"> <xsl:with-param name="key" select="'index.number.separator'"/> </xsl:call-template> </xsl:variable> <fo:block start-indent="1em" text-indent="-1em"> <xsl:if test="$axf.extensions != 0"> <xsl:attribute name="axf:suppress-duplicate-page-number">true</xsl:attribute> </xsl:if> <xsl:attribute name="id"> <xsl:variable name="primary"> <xsl:call-template name="normalize-id"> <xsl:with-param name="id" select="normalize-space(primary)"/> </xsl:call-template> </xsl:variable> <xsl:value-of select="concat('idx-', $primary)"/> </xsl:attribute> <xsl:value-of select="primary"/> <xsl:choose> <xsl:when test="$xep.extensions != 0"> <xsl:if test="$refs[not(see) and not(secondary)]"> <xsl:copy-of select="$term.separator"/> <xsl:variable name="primary" select="&primary;"/> <xsl:variable name="primary.significant" select="concat(&primary;, $significant.flag)"/> <rx:page-index list-separator="{$number.separator}" range-separator="{$range.separator}"> <xsl:if test="$refs[@significance='preferred'][not(see) and not(secondary)]"> <rx:index-item xsl:use-attribute-sets="index.preferred.page.properties xep.index.item.properties" ref-key="{$primary.significant}"/> </xsl:if> <xsl:if test="$refs[not(@significance) or @significance!='preferred'][not(see) and not(secondary)]"> <rx:index-item xsl:use-attribute-sets="xep.index.item.properties" ref-key="{$primary}"/> </xsl:if> </rx:page-index> </xsl:if> </xsl:when> <xsl:otherwise> <xsl:variable name="page-number-citations"> <xsl:for-each select="$refs[not(see) and not(secondary)]"> <xsl:apply-templates select="." mode="reference"> <xsl:with-param name="scope" select="$scope"/> <xsl:with-param name="role" select="$role"/> <xsl:with-param name="type" select="$type"/> <xsl:with-param name="position" select="position()"/> </xsl:apply-templates> </xsl:for-each> </xsl:variable> <xsl:choose> <xsl:when test="$passivetex.extensions != '0'"> <fotex:sort xmlns:fotex="http://www.tug.org/fotex"> <xsl:copy-of select="$page-number-citations"/> </fotex:sort> </xsl:when> <xsl:otherwise> <xsl:copy-of select="$page-number-citations"/> </xsl:otherwise> </xsl:choose> </xsl:otherwise> </xsl:choose> <xsl:if test="$refs[not(secondary)]/*[self::see]"> <xsl:apply-templates select="$refs[generate-id() = generate-id(key('see', concat(&primary;, &sep;, &sep;, &sep;, see))[&scope;][1])]" mode="index-see"> <xsl:with-param name="scope" select="$scope"/> <xsl:with-param name="role" select="$role"/> <xsl:with-param name="type" select="$type"/> <xsl:sort select="translate(see, &lowercase;, &uppercase;)"/> </xsl:apply-templates> </xsl:if> </fo:block> <xsl:if test="$refs/secondary or $refs[not(secondary)]/*[self::seealso]"> <fo:block start-indent="1em"> <xsl:apply-templates select="$refs[generate-id() = generate-id(key('see-also', concat(&primary;, &sep;, &sep;, &sep;, seealso))[&scope;][1])]" mode="index-seealso"> <xsl:with-param name="scope" select="$scope"/> <xsl:with-param name="role" select="$role"/> <xsl:with-param name="type" select="$type"/> <xsl:sort select="translate(seealso, &lowercase;, &uppercase;)"/> </xsl:apply-templates> <xsl:apply-templates select="$refs[secondary and count(.|key('secondary', concat($key, &sep;, &secondary;))[&scope;][1]) = 1]" mode="index-secondary"> <xsl:with-param name="scope" select="$scope"/> <xsl:with-param name="role" select="$role"/> <xsl:with-param name="type" select="$type"/> <xsl:sort select="translate(&secondary;, &lowercase;, &uppercase;)"/> </xsl:apply-templates> </fo:block> </xsl:if> </xsl:template> <xsl:template match="indexterm" mode="index-secondary"> <xsl:param name="scope" select="."/> <xsl:param name="role" select="''"/> <xsl:param name="type" select="''"/> <xsl:variable name="key" select="concat(&primary;, &sep;, &secondary;)"/> <xsl:variable name="refs" select="key('secondary', $key)[&scope;]"/> <xsl:variable name="term.separator"> <xsl:call-template name="index.separator"> <xsl:with-param name="key" select="'index.term.separator'"/> </xsl:call-template> </xsl:variable> <xsl:variable name="range.separator"> <xsl:call-template name="index.separator"> <xsl:with-param name="key" select="'index.range.separator'"/> </xsl:call-template> </xsl:variable> <xsl:variable name="number.separator"> <xsl:call-template name="index.separator"> <xsl:with-param name="key" select="'index.number.separator'"/> </xsl:call-template> </xsl:variable> <fo:block> <xsl:attribute name="id"> <xsl:variable name="primary"> <xsl:call-template name="normalize-id"> <xsl:with-param name="id" select="normalize-space(primary)"/> </xsl:call-template> </xsl:variable> <xsl:variable name="secondary"> <xsl:call-template name="normalize-id"> <xsl:with-param name="id" select="normalize-space(secondary)"/> </xsl:call-template> </xsl:variable> <xsl:value-of select="concat('idx-', $primary, '--', $secondary)"/> </xsl:attribute> <xsl:if test="$axf.extensions != 0"> <xsl:attribute name="axf:suppress-duplicate-page-number">true</xsl:attribute> </xsl:if> <xsl:text>~ </xsl:text> <xsl:value-of select="secondary"/> <xsl:choose> <xsl:when test="$xep.extensions != 0"> <xsl:if test="$refs[not(see) and not(tertiary)]"> <xsl:copy-of select="$term.separator"/> <xsl:variable name="primary" select="&primary;"/> <xsl:variable name="secondary" select="&secondary;"/> <xsl:variable name="primary.significant" select="concat(&primary;, $significant.flag)"/> <rx:page-index list-separator="{$number.separator}" range-separator="{$range.separator}"> <xsl:if test="$refs[@significance='preferred'][not(see) and not(tertiary)]"> <rx:index-item xsl:use-attribute-sets="index.preferred.page.properties xep.index.item.properties"> <xsl:attribute name="ref-key"> <xsl:value-of select="$primary.significant"/> <xsl:text>, </xsl:text> <xsl:value-of select="$secondary"/> </xsl:attribute> </rx:index-item> </xsl:if> <xsl:if test="$refs[not(@significance) or @significance!='preferred'][not(see) and not(tertiary)]"> <rx:index-item xsl:use-attribute-sets="xep.index.item.properties"> <xsl:attribute name="ref-key"> <xsl:value-of select="$primary"/> <xsl:text>, </xsl:text> <xsl:value-of select="$secondary"/> </xsl:attribute> </rx:index-item> </xsl:if> </rx:page-index> </xsl:if> </xsl:when> <xsl:otherwise> <xsl:variable name="page-number-citations"> <xsl:for-each select="$refs[not(see) and not(tertiary)]"> <xsl:apply-templates select="." mode="reference"> <xsl:with-param name="scope" select="$scope"/> <xsl:with-param name="role" select="$role"/> <xsl:with-param name="type" select="$type"/> <xsl:with-param name="position" select="position()"/> </xsl:apply-templates> </xsl:for-each> </xsl:variable> <xsl:choose> <xsl:when test="$passivetex.extensions != '0'"> <fotex:sort xmlns:fotex="http://www.tug.org/fotex"> <xsl:copy-of select="$page-number-citations"/> </fotex:sort> </xsl:when> <xsl:otherwise> <xsl:copy-of select="$page-number-citations"/> </xsl:otherwise> </xsl:choose> </xsl:otherwise> </xsl:choose> <xsl:if test="$refs[not(tertiary)]/*[self::see]"> <xsl:apply-templates select="$refs[generate-id() = generate-id(key('see', concat(&primary;, &sep;, &secondary;, &sep;, &sep;, see))[&scope;][1])]" mode="index-see"> <xsl:with-param name="scope" select="$scope"/> <xsl:with-param name="role" select="$role"/> <xsl:with-param name="type" select="$type"/> <xsl:sort select="translate(see, &lowercase;, &uppercase;)"/> </xsl:apply-templates> </xsl:if> </fo:block> <xsl:if test="$refs/tertiary or $refs[not(tertiary)]/*[self::seealso]"> <fo:block start-indent="2em"> <xsl:apply-templates select="$refs[generate-id() = generate-id(key('see-also', concat(&primary;, &sep;, &secondary;, &sep;, &sep;, seealso))[&scope;][1])]" mode="index-seealso"> <xsl:with-param name="scope" select="$scope"/> <xsl:with-param name="role" select="$role"/> <xsl:with-param name="type" select="$type"/> <xsl:sort select="translate(seealso, &lowercase;, &uppercase;)"/> </xsl:apply-templates> <xsl:apply-templates select="$refs[tertiary and count(.|key('tertiary', concat($key, &sep;, &tertiary;))[&scope;][1]) = 1]" mode="index-tertiary"> <xsl:with-param name="scope" select="$scope"/> <xsl:with-param name="role" select="$role"/> <xsl:with-param name="type" select="$type"/> <xsl:sort select="translate(&tertiary;, &lowercase;, &uppercase;)"/> </xsl:apply-templates> </fo:block> </xsl:if> </xsl:template> <xsl:template match="indexterm" mode="index-tertiary"> <xsl:param name="scope" select="."/> <xsl:param name="role" select="''"/> <xsl:param name="type" select="''"/> <xsl:variable name="key" select="concat(&primary;, &sep;, &secondary;, &sep;, &tertiary;)"/> <xsl:variable name="refs" select="key('tertiary', $key)[&scope;]"/> <xsl:variable name="term.separator"> <xsl:call-template name="index.separator"> <xsl:with-param name="key" select="'index.term.separator'"/> </xsl:call-template> </xsl:variable> <xsl:variable name="range.separator"> <xsl:call-template name="index.separator"> <xsl:with-param name="key" select="'index.range.separator'"/> </xsl:call-template> </xsl:variable> <xsl:variable name="number.separator"> <xsl:call-template name="index.separator"> <xsl:with-param name="key" select="'index.number.separator'"/> </xsl:call-template> </xsl:variable> <fo:block> <xsl:if test="$axf.extensions != 0"> <xsl:attribute name="axf:suppress-duplicate-page-number">true</xsl:attribute> </xsl:if> <xsl:text>~ ~ </xsl:text> <xsl:value-of select="tertiary"/> <xsl:choose> <xsl:when test="$xep.extensions != 0"> <xsl:if test="$refs[not(see)]"> <xsl:copy-of select="$term.separator"/> <xsl:variable name="primary" select="&primary;"/> <xsl:variable name="secondary" select="&secondary;"/> <xsl:variable name="tertiary" select="&tertiary;"/> <xsl:variable name="primary.significant" select="concat(&primary;, $significant.flag)"/> <rx:page-index list-separator="{$number.separator}" range-separator="{$range.separator}"> <xsl:if test="$refs[@significance='preferred'][not(see)]"> <rx:index-item xsl:use-attribute-sets="index.preferred.page.properties xep.index.item.properties"> <xsl:attribute name="ref-key"> <xsl:value-of select="$primary.significant"/> <xsl:text>, </xsl:text> <xsl:value-of select="$secondary"/> <xsl:text>, </xsl:text> <xsl:value-of select="$tertiary"/> </xsl:attribute> </rx:index-item> </xsl:if> <xsl:if test="$refs[not(@significance) or @significance!='preferred'][not(see)]"> <rx:index-item xsl:use-attribute-sets="xep.index.item.properties"> <xsl:attribute name="ref-key"> <xsl:value-of select="$primary"/> <xsl:text>, </xsl:text> <xsl:value-of select="$secondary"/> <xsl:text>, </xsl:text> <xsl:value-of select="$tertiary"/> </xsl:attribute> </rx:index-item> </xsl:if> </rx:page-index> </xsl:if> </xsl:when> <xsl:otherwise> <xsl:variable name="page-number-citations"> <xsl:for-each select="$refs[not(see)]"> <xsl:apply-templates select="." mode="reference"> <xsl:with-param name="scope" select="$scope"/> <xsl:with-param name="role" select="$role"/> <xsl:with-param name="type" select="$type"/> <xsl:with-param name="position" select="position()"/> </xsl:apply-templates> </xsl:for-each> </xsl:variable> <xsl:choose> <xsl:when test="$passivetex.extensions != '0'"> <fotex:sort xmlns:fotex="http://www.tug.org/fotex"> <xsl:copy-of select="$page-number-citations"/> </fotex:sort> </xsl:when> <xsl:otherwise> <xsl:copy-of select="$page-number-citations"/> </xsl:otherwise> </xsl:choose> </xsl:otherwise> </xsl:choose> <xsl:if test="$refs/see"> <xsl:apply-templates select="$refs[generate-id() = generate-id(key('see', concat(&primary;, &sep;, &secondary;, &sep;, &tertiary;, &sep;, see))[&scope;][1])]" mode="index-see"> <xsl:with-param name="scope" select="$scope"/> <xsl:with-param name="role" select="$role"/> <xsl:with-param name="type" select="$type"/> <xsl:sort select="translate(see, &lowercase;, &uppercase;)"/> </xsl:apply-templates> </xsl:if> </fo:block> </xsl:template> <xsl:template match="indexterm" mode="index-see"> <xsl:param name="scope" select="."/> <xsl:param name="role" select="''"/> <xsl:param name="type" select="''"/> <fo:inline> <xsl:text> (</xsl:text> <xsl:call-template name="gentext"> <xsl:with-param name="key" select="'see'"/> </xsl:call-template> <xsl:text> </xsl:text> <fo:basic-link xsl:use-attribute-sets="index.page.number.properties"> <xsl:attribute name="internal-destination"> <xsl:text>idx-</xsl:text> <xsl:call-template name="normalize-id"> <xsl:with-param name="id" select="normalize-space(see)"/> </xsl:call-template> </xsl:attribute> <xsl:value-of select="see"/> </fo:basic-link> <xsl:text>)</xsl:text> </fo:inline> </xsl:template> <xsl:template match="indexterm" mode="index-seealso"> <xsl:param name="scope" select="."/> <xsl:param name="role" select="''"/> <xsl:param name="type" select="''"/> <xsl:for-each select="seealso"> <xsl:sort select="translate(., &lowercase;, &uppercase;)"/> <fo:block> <xsl:text>(</xsl:text> <xsl:call-template name="gentext"> <xsl:with-param name="key" select="'seealso'"/> </xsl:call-template> <xsl:text> </xsl:text> <fo:basic-link xsl:use-attribute-sets="index.page.number.properties"> <xsl:attribute name="internal-destination"> <xsl:text>idx-</xsl:text> <xsl:call-template name="normalize-id"> <xsl:with-param name="id" select="normalize-space(.)"/> </xsl:call-template> </xsl:attribute> <xsl:value-of select="."/> </fo:basic-link> <xsl:text>)</xsl:text> </fo:block> </xsl:for-each> </xsl:template> </xsl:stylesheet>
[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]