docbook-apps

  • 1.  Selecting text styles for elements within

    Posted 09-01-2012 07:42
    I have a customization for styling <emphasis>, <quote> and <literal>
    elements that are contained in <primary> index elements.

    Typical markup is:

    <indextermclass="startofrange"xml:id="abstract">
    <primary><literal>abstract</literal>element/tag</primary>
    </indexterm>

    In the autoindex, I only want to style the text contained within the
    <literal> tags as font-family "monospace", but all of the text within
    the <primary> element is styled as monospace.

    My customization in
    <xsl:templatematch="d:indexterm"mode="index-primary"> is:

    <xsl:choose>
    <xsl:whentest="d:primary/d:emphasis">
    <fo:inlinefont-style="italic">
    <xsl:value-ofselect="d:primary"/>
    </fo:inline>
    </xsl:when>
    <xsl:whentest="d:primary/d:literal">
    <fo:inlinefont-family="monospace">
    <xsl:value-ofselect="d:primary/d:literal"/>
    </fo:inline>
    <xsl:value-ofselect="d:primary[not(child::d:literal)]"/>
    </xsl:when>
    <xsl:whentest="d:primary/d:quote">
    <xsl:variablename="content">
    <xsl:call-templatename="gentext.startquote"/>
    <xsl:value-ofselect="d:primary"/>
    <xsl:call-templatename="gentext.endquote"/>
    </xsl:variable>
    <fo:inline>
    <xsl:copy-ofselect="$content"/>
    </fo:inline>
    </xsl:when>
    <xsl:otherwise>
    <xsl:value-ofselect="d:primary"/>
    </xsl:otherwise>
    </xsl:choose>

    As you can see, for d:primary/d:literal, I'm attempting to style only
    d:literal as monospace, and for any text following that (within
    d:primary) as normal text. So, I'm trying to separate text in
    d:primary/d:literal from all other text within d:primary so I can apply
    two types of font styles. The expression
    "d:primary[not(child::d:literal)]" doesn't generate the text outside of
    d:literal. Is there an XPath expression to achieve this?

    --
    *Dave Gardiner*




  • 2.  Re: [docbook-apps] Selecting text styles for elements within

    Posted 09-01-2012 09:40
    Hi,

    Am Samstag, 1. September 2012, 17:42:03 schrieb Xmplar:
    > I have a customization for styling <emphasis>, <quote> and <literal>
    > elements that are contained in <primary> index elements.
    >
    > Typical markup is:
    >
    > <indexterm class="startofrange" xml:id="abstract">
    > <primary><literal>abstract</literal>element/tag</primary>
    > </indexterm>
    >
    > In the autoindex, I only want to style the text contained within the
    > <literal> tags as font-family "monospace", but all of the text within
    > the <primary> element is styled as monospace.

    And your primary (except literal) should be styled as serif or sans serif?


    > My customization in
    > <xsl:templatematch="d:indexterm"mode="index-primary"> is:
    >
    > <xsl:choose>
    > [...]
    > </xsl:choose>

    XSLT doesn't work this way. You *could* write something as you did, but it is
    hard to maintain and not very readable. I would recommend to write more
    templates.

    Templates is the way XSLT work. Templates deliver only a small part of the
    output tree. So one template could create a bold text whereas another one
    would creates the monospace text. To distinguish which produces which, use a
    XPath expression.


    > As you can see, for d:primary/d:literal, I'm attempting to style only
    > d:literal as monospace, and for any text following that (within
    > d:primary) as normal text. So, I'm trying to separate text in
    > d:primary/d:literal from all other text within d:primary so I can apply
    > two types of font styles. The expression
    > "d:primary[not(child::d:literal)]" doesn't generate the text outside of
    > d:literal. Is there an XPath expression to achieve this?

    Sorry, but your code is too complicated. :) XSLT is different, it's NOT a
    procedural language (although some elements might think so). In almost all
    cases you write templates and the XSLT processor decides which one should be
    executed.

    Here is a small test case you can use to tweak it to your needs. It just focus
    on the indexterm, its children, but nothing else. Be aware, it doesn't create
    a working FO file. I've integrated only the essential parts, no DocBook
    customization etc. You need to cut the templates and past it to your
    customization layer.

    Let's say, you have the following XML file (taken from your example above,
    added DocBook 5 namespace):

    ------[ index.xml ]------
    <indexterm xmlns="http://docbook.org/ns/docbook"
    class="startofrange" xml:id="abstract">
    <primary><literal>abstract</literal>element/tag</primary>
    </indexterm>
    -------------------------

    Here is the stylesheet:

    ------[ index.xsl ]------

    <xsl:stylesheet version="1.0"
    xmlns:d="http://docbook.org/ns/docbook"
    xmlns:fo="http://www.w3.org/1999/XSL/Format"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    exclude-result-prefixes="d">

    <xsl:template match="/">

    <fo:root>
    <xsl:apply-templates mode="index-primary"/>
    </fo:root>
    </xsl:template>

    <xsl:template match="d:indexterm" mode="index-primary">
    <fo:block>
    <xsl:apply-templates mode="index-primary"/>
    </fo:block>
    </xsl:template>

    <xsl:template match="d:primary" mode="index-primary">
    <fo:inline>
    <xsl:apply-templates mode="index-primary"/>
    </fo:inline>
    </xsl:template>

    <xsl:template match="d:literal" mode="index-primary">
    <fo:inline font-family="monospace">
    <xsl:apply-templates mode="index-primary"/>
    </fo:inline>
    </xsl:template>

    <xsl:template match="d:quote" mode="index-primary">
    <fo:inline>

    <xsl:text>"</xsl:text>
    <xsl:apply-templates mode="index-primary"/>

    <xsl:text>"</xsl:text>
    </fo:inline>
    </xsl:template>

    <xsl:template match="d:emphasis" mode="index-primary">
    <fo:inline font-weight="bold">
    <xsl:apply-templates mode="index-primary"/>
    </fo:inline>
    </xsl:template>
    </xsl:stylesheet>
    -------------------------

    Run xsltproc:

    $ xsltproc index.xsl index.xml

    I get the following output (slightly modified to improve readability):

    <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
    <fo:block>
    <fo:inline><fo:inline
    font-family="monospace">abstract</fo:inline>element/tag</fo:inline>
    </fo:block>
    </fo:root>

    As you can see, only literal is marked up as monospace nothing else.

    I don't know if this is what you wanted. Maybe I've misunderstood your
    intentions. Hope it helps.


    --
    Gruß/Regards
    Thomas Schraitle




  • 3.  Re: [docbook-apps] Selecting text styles for elements within

    Posted 09-02-2012 02:35
      |   view attached
    Thomas,
    Thanks for pointing me in the right direction - with the addition of
    templates I've *almost* got the index looking as I need it. I do have a
    problem with secondary entries and "see" entries being repeated after a
    primary entry. The attached screenshot shows two typical instances where
    a "see" entry, and the last "secondary" entry that follows a primary
    entry, is repeated after the primary entry.

    My customization is:

    <xsl:template match="d:indexterm" mode="index-primary">
    <xsl:param name="scope" select="."></xsl:param>
    <xsl:param name="role" select="''"></xsl:param>
    <xsl:param name="type" select="''"></xsl:param>

    <xsl:variable name="key" select="&primary;"></xsl:variable>
    <xsl:variable name="refs" select="key('primary', $key)[&scope;]"></xsl:variable>

    <xsl:variable name="term.separator">
    <xsl:call-template name="index.separator">
    <xsl:with-param name="key" select="'index.term.separator'"></xsl:with-param>
    </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:with-param>
    </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:with-param>
    </xsl:call-template>
    </xsl:variable>

    <fo:block>
    <xsl:apply-templates mode="index-primary"></xsl:apply-templates>
    <xsl:if test="$axf.extensions != 0">
    <xsl:attribute></xsl:attribute>
    name="axf:suppress-duplicate-page-number">true
    </xsl:if>
    ...

    And new templates for index entries:

    <xsl:template match="d:primary" mode="index-primary">
    <fo:inline>
    <xsl:apply-templates mode="index-primary"></xsl:apply-templates>
    </fo:inline>
    </xsl:template>

    <xsl:template match="d:literal" mode="index-primary">
    <fo:inline font-family="monospace">
    <xsl:apply-templates mode="index-primary"></xsl:apply-templates>
    </fo:inline>
    </xsl:template>

    <xsl:template match="d:quote" mode="index-primary">
    <fo:inline>
    <xsl:call-template name="gentext.startquote"></xsl:call-template>
    <xsl:apply-templates mode="index-primary"></xsl:apply-templates>
    <xsl:call-template name="gentext.endquote"></xsl:call-template>
    </fo:inline>
    </xsl:template>

    <xsl:template match="d:emphasis" mode="index-primary">
    <fo:inline font-style="italic">
    <xsl:apply-templates mode="index-primary"></xsl:apply-templates>
    </fo:inline>
    </xsl:template>

    I'll keep looking to find the logic as to why I'm getting secondary and
    see entries generated twice. I think it's to do with where I put the
    <xsl:apply-templates mode="index-primary"></xsl:apply-templates> in the indexterm template.
    Dave

    On 01-09-12 7:40 PM, Thomas Schraitle wrote:
    > Hi,
    >
    > Am Samstag, 1. September 2012, 17:42:03 schrieb Xmplar:
    >> I have a customization for styling<emphasis>,<quote> and<literal>
    >> elements that are contained in<primary> index elements.
    >>
    >> Typical markup is:
    >>
    >> <indexterm class="startofrange" xml:id="abstract">
    >> <primary><literal>abstract</literal>element/tag</primary>
    >> </indexterm>
    >>
    >> In the autoindex, I only want to style the text contained within the
    >> <literal> tags as font-family "monospace", but all of the text within
    >> the<primary> element is styled as monospace.
    > And your primary (except literal) should be styled as serif or sans serif?
    >
    >
    >> My customization in
    >> <xsl:templatematch="d:indexterm"mode="index-primary"> is:
    >>
    >> <xsl:choose>
    >> [...]
    >> </xsl:choose>
    > XSLT doesn't work this way. You *could* write something as you did, but it is
    > hard to maintain and not very readable. I would recommend to write more
    > templates.
    >
    > Templates is the way XSLT work. Templates deliver only a small part of the
    > output tree. So one template could create a bold text whereas another one
    > would creates the monospace text. To distinguish which produces which, use a
    > XPath expression.
    >
    >
    >> As you can see, for d:primary/d:literal, I'm attempting to style only
    >> d:literal as monospace, and for any text following that (within
    >> d:primary) as normal text. So, I'm trying to separate text in
    >> d:primary/d:literal from all other text within d:primary so I can apply
    >> two types of font styles. The expression
    >> "d:primary[not(child::d:literal)]" doesn't generate the text outside of
    >> d:literal. Is there an XPath expression to achieve this?
    > Sorry, but your code is too complicated. :) XSLT is different, it's NOT a
    > procedural language (although some elements might think so). In almost all
    > cases you write templates and the XSLT processor decides which one should be
    > executed.
    >
    > Here is a small test case you can use to tweak it to your needs. It just focus
    > on the indexterm, its children, but nothing else. Be aware, it doesn't create
    > a working FO file. I've integrated only the essential parts, no DocBook
    > customization etc. You need to cut the templates and past it to your
    > customization layer.
    >
    > Let's say, you have the following XML file (taken from your example above,
    > added DocBook 5 namespace):
    >
    > ------[ index.xml ]------
    > <indexterm xmlns="http://docbook.org/ns/docbook"></indexterm>
    > class="startofrange" xml:id="abstract">
    > <primary><literal>abstract</literal>element/tag</primary>
    >
    > -------------------------
    >
    > Here is the stylesheet:
    >
    > ------[ index.xsl ]------
    >
    > <xsl:stylesheet version="1.0"></xsl:stylesheet>
    > xmlns:d="http://docbook.org/ns/docbook"
    > xmlns:fo="http://www.w3.org/1999/XSL/Format"
    > xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    > exclude-result-prefixes="d">
    >
    > <xsl:template match="/">
    >
    > <fo:root>
    > <xsl:apply-templates mode="index-primary"></xsl:apply-templates>
    > </fo:root>
    > </xsl:template>
    >
    > <xsl:template match="d:indexterm" mode="index-primary">
    > <fo:block>
    > <xsl:apply-templates mode="index-primary"></xsl:apply-templates>
    > </fo:block>
    > </xsl:template>
    >
    > <xsl:template match="d:primary" mode="index-primary">
    > <fo:inline>
    > <xsl:apply-templates mode="index-primary"></xsl:apply-templates>
    > </fo:inline>
    > </xsl:template>
    >
    > <xsl:template match="d:literal" mode="index-primary">
    > <fo:inline font-family="monospace">
    > <xsl:apply-templates mode="index-primary"></xsl:apply-templates>
    > </fo:inline>
    > </xsl:template>
    >
    > <xsl:template match="d:quote" mode="index-primary">
    > <fo:inline>
    >
    > <xsl:text>"</xsl:text>
    > <xsl:apply-templates mode="index-primary"></xsl:apply-templates>
    >
    > <xsl:text>"</xsl:text>
    > </fo:inline>
    > </xsl:template>
    >
    > <xsl:template match="d:emphasis" mode="index-primary">
    > <fo:inline font-weight="bold">
    > <xsl:apply-templates mode="index-primary"></xsl:apply-templates>
    > </fo:inline>
    > </xsl:template>
    >
    > -------------------------
    >
    > Run xsltproc:
    >
    > $ xsltproc index.xsl index.xml
    >
    > I get the following output (slightly modified to improve readability):
    >
    > <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
    > <fo:block>
    > <fo:inline><fo:inline></fo:inline>
    > font-family="monospace">abstract</fo:inline>element/tag
    > </fo:block>
    > </fo:root>
    >
    > As you can see, only literal is marked up as monospace nothing else.
    >
    > I don't know if this is what you wanted. Maybe I've misunderstood your
    > intentions. Hope it helps.
    >
    >

    --
    *Dave Gardiner*
    Xmplar
    info@xmplar.biz
    http://xmplar.biz
    Mob. 0416 833 993

    </xsl:templatematch="d:indexterm"mode="index-primary"></primary></literal></primary></literal></quote></emphasis></fo:block></xsl:template>

    Attachment(s)

    doc
    idx-primary-styles.doc   230 KB 1 version