Re: [docbook-apps] xrefs to <title> elements don't work

From
Bob Stayton <>
Date
2013-04-09T17:12:02+00:00
ID
09AC8117D2F449A4841579CF06AADFDF@totoro
Thread
Re: [docbook-apps] xrefs to <title> elements don't work
Hi Eric,

The page numbers are not handled by the simple.xlink template, 
but by the template in fo/xref.xsl that matches on xref.  

 

      <xsl:apply-templates 
select="$target" mode="page.citation">

It is trying to process the title element (the value of 
$target) in mode="page.citation".  It generates the correct code, but the 
id for title is not in the fo output, so the xsl-fo processor cannot find the id 
to get the page number.  So you will need to create a template like this 
(untested) to generate the page citation for the parent of title:

 

<xsl:template match="title" 
mode="page.citation">

  <xsl:apply-templates select="parent::*" 
mode="page.citation"/>

</xsl:template>

 

I think that will work.

 

Bob Stayton
Sagehill Enterprises


From: Eric Nordlund 

Sent: Friday, April 05, 2013 11:11 AM

To: Bob 
Stayton ;  

Subject: RE: [docbook-apps] xrefs to <title> elements don't 
work

Thanks Bob. Your suggested style 
sheet customization worked for our documents; the links work and the correct 
text is displayed for the xref.

 

One thing that I noticed is that 
the page.citation dows not work for the titles, however. This isn?t a big deal 
for me because I just turn them off on title xrefs, but is there a way to get 
that template to work with title xrefs the same way that they would for section 
xrefs? Right now they show up as ?<title text> on 
page          
.?

 

Eric

 

From: Bob Stayton 
[mailto:] 
Sent: Friday, April 05, 2013 9:18 
AM
To: Eric Nordlund; 

Subject: Re: [docbook-apps] xrefs to 
<title> elements don't work

 

Hi 
Eric,

Actually, 
creating an xref to a title used to work in the stylesheets.  Currently it 
gets the generated text right, but the link is to the id of the title element, 
and most title elements do not output an @id attribute, so the link 
fails.   It seems this feature was broken some time ago when the xref 
templates were rewritten to support universal linking in DocBook 5.

 

This 
customization of the template named 'simple.xlink' from fo/inline.xsl fixes the 
id problem.  It only corrects the problem for @linkend references, not for 
@xlink:href references used in universal linking, but it should suffice for 
your needs.  Search for 'linkend.candidate' to see where I made the 
changes.

 

 

<xsl:template 
name="simple.xlink">
  <xsl:param name="node" 
select="."/>
  <xsl:param name="content">
    
<xsl:apply-templates/>
  </xsl:param>
  
<xsl:param name="linkend.candidate" select="$node/@linkend"/>
  
<xsl:param name="xhref" select="$node/@xlink:href"/>

 

  
<xsl:choose>
    <xsl:when 
test="$xhref
                    
and (not($node/@xlink:type) or 

                         
$node/@xlink:type='simple')">

 

      
<!-- Is it a local idref? -->
      
<xsl:variable 
name="is.idref">
        
<xsl:choose>
          
<!-- if the href starts with # and does not contain an "(" 
-->
          <!-- or if 
the href starts with #xpointer(id(, it's just an ID 
-->
          <xsl:when 
test="starts-with($xhref,'#')
                          
and 
(not(contains($xhref,'&#40;'))
                          
or 
starts-with($xhref,
                                     
'#xpointer&#40;id&#40;'))">1</xsl:when>
          
<xsl:otherwise>0</xsl:otherwise>
        
</xsl:choose>
      
</xsl:variable>

 

      
<!-- Is it an olink ? -->
      
<xsl:variable 
name="is.olink">
        
<xsl:choose>
          
<!-- If xlink:role="http://docbook.org/xlink/role/olink" 
-->
          <!-- and if 
the href contains # 
-->
          <xsl:when 
test="contains($xhref,'#') 
and
               
@xlink:role = 
$xolink.role">1</xsl:when>
          
<xsl:otherwise>0</xsl:otherwise>
        
</xsl:choose>
      
</xsl:variable>

 

      
<xsl:choose>
        <xsl:when 
test="$is.olink = 
1">
          
<xsl:call-template 
name="olink">
            
<xsl:with-param name="content" 
select="$content"/>
          
</xsl:call-template>
        
</xsl:when>

 

        
<xsl:when test="$is.idref = 1">

 

          
<xsl:variable 
name="idref">
            
<xsl:call-template 
name="xpointer.idref">
              
<xsl:with-param name="xpointer" 
select="$xhref"/>
            
</xsl:call-template>
          
</xsl:variable>

 

          
<xsl:variable name="targets" 
select="key('id',$idref)"/>
          
<xsl:variable name="target" select="$targets[1]"/>

 

          
<xsl:call-template 
name="check.id.unique">
            
<xsl:with-param name="linkend" 
select="$idref"/>
          
</xsl:call-template>

 

          
<xsl:choose>
            
<xsl:when test="count($target) = 
0">
              
<xsl:message>
                
<xsl:text>XLink to nonexistent id: 
</xsl:text>
                
<xsl:value-of 
select="$idref"/>
              
</xsl:message>
              
<xsl:copy-of 
select="$content"/>
            
</xsl:when>

 

            
<xsl:otherwise>
              
<fo:basic-link 
internal-destination="{$idref}">
                
<xsl:apply-templates select="." 
mode="simple.xlink.properties"/>
                
<xsl:copy-of 
select="$content"/>
              
</fo:basic-link>
            
</xsl:otherwise>
          
</xsl:choose>
        
</xsl:when>

 

        
<!-- otherwise it's a URI 
-->
        
<xsl:otherwise>
          
<fo:basic-link 
external-destination="url({$xhref})">
            
<xsl:apply-templates select="." 
mode="simple.xlink.properties"/>
            
<xsl:copy-of 
select="$content"/>
          
</fo:basic-link>
          
<!-- * Call the template for determining whether the URL for this 
-->
          <!-- * 
hyperlink is displayed, and how to display it (either inline or 
-->
          <!-- * as a 
numbered footnote). 
-->
          
<xsl:call-template 
name="hyperlink.url.display">
            
<xsl:with-param name="url" 
select="$xhref"/>
          
</xsl:call-template>
        
</xsl:otherwise>
      
</xsl:choose>
    </xsl:when>

 

    
<xsl:when test="$linkend.candidate">
      
<xsl:variable name="targets.candidate" 
select="key('id',$linkend.candidate)"/>
      
<xsl:variable name="target.candidate" 
select="$targets.candidate[1]"/>

 

      
<xsl:variable 
name="target.id">
        
<xsl:choose>
          
<xsl:when test="$target.candidate/self::title and 

                          
$target.candidate/parent::*/@id">
            
<xsl:value-of 
select="$target.candidate/parent::*/@id"/>
          
</xsl:when>
          
<xsl:otherwise>
            
<xsl:value-of select="$target.candidate/@id"/>
          
</xsl:otherwise>
        
</xsl:choose>
      
</xsl:variable>

 

      
<xsl:variable name="targets" 
select="key('id',$target.id)"/>
      
<xsl:variable name="target" 
select="$targets[1]"/>
      <xsl:variable 
name="linkend" select="$target/@id"/>

 

      
<xsl:call-template 
name="check.id.unique">
        
<xsl:with-param name="linkend" 
select="$linkend"/>
      
</xsl:call-template>

 

      
<xsl:choose>
        <xsl:when 
test="count($target) = 
0">
          
<xsl:message>
            
<xsl:text>XLink to nonexistent id: 
</xsl:text>
            
<xsl:value-of 
select="$linkend"/>
          
</xsl:message>
          
<xsl:copy-of 
select="$content"/>
        
</xsl:when>

 

        
<xsl:otherwise>
          
<fo:basic-link 
internal-destination="{$linkend}">
            
<xsl:apply-templates select="." 
mode="simple.xlink.properties"/>
            
<xsl:copy-of 
select="$content"/>
          
</fo:basic-link>
        
</xsl:otherwise>
      
</xsl:choose>
    </xsl:when>

 

    
<xsl:otherwise>
      <xsl:copy-of 
select="$content"/>
    </xsl:otherwise>
  
</xsl:choose>
</xsl:template>

 

</xsl:stylesheet>

Bob 
Stayton
Sagehill Enterprises


 

From: Eric Nordlund 

Sent: Thursday, April 04, 
2013 6:00 PM

To:  

Subject: [docbook-apps] 
xrefs to <title> elements don't 
work

 

My company has a hundred or so books that were authored with 
Arbortext?s graphic XML editor. I?m having a problem processing these books with 
XSL-FO because so many of the xrefs in these books are to title elements instead 
of the parent procedure, section, example, table, etc., elements.

 

Is there a way to make these work in the XSL-FO output? I was 
thinking I could have a template that could recognize when an xref/@linkend 
pointed to the id of a title and then change the linkend to the id of the 
title?s parent element, but I don?t really know how to do that.

 

Is there another way to do what I need to do?

 

Eric Nordlund

Customer 
Documentation and Training

Cray 
Inc.

901 5th 
Ave

Seattle, WA 
98164

(206)701-2232