]> granicus.if.org Git - docbook-dsssl/commitdiff
Fix issue #27 to allow merge from resource of titles not inside info because they...
authorbobstayton <bobs@sagehill.net>
Sun, 10 Jun 2018 20:44:22 +0000 (13:44 -0700)
committerbobstayton <bobs@sagehill.net>
Mon, 11 Jun 2018 05:55:34 +0000 (22:55 -0700)
xsl/assembly/assemble.xsl

index 22e4db75af7202592546f2a36185e3bb11b3156b..a244520f9cd2be3aa2368da4dd789130170537f7 100644 (file)
     </xsl:attribute>
     <xsl:copy-of select="@xml:id"/>
 
+    <!-- get any merge resource element before changing context -->
+    <xsl:variable name="merge.resourceref" select="d:merge[1]/@resourceref"/>
+    <xsl:variable name="merge.resource" select="key('id', $merge.resourceref)"/>
+    
     <!-- use the merge element if present -->
     <xsl:call-template name="merge.info">
       <xsl:with-param name="merge.element" select="d:merge"/>
+      <xsl:with-param name="resource" select="$merge.resource"/>
     </xsl:call-template>
 
     <xsl:apply-templates> 
       </xsl:when>
     </xsl:choose>
 
+    <!-- get any merge resource element before changing context -->
+    <xsl:variable name="merge.resourceref" select="d:merge[1]/@resourceref"/>
+    <xsl:variable name="merge.resource" select="key('id', $merge.resourceref)"/>
+    
+    <!-- use the merge element if present -->
     <xsl:call-template name="merge.info">
-      <xsl:with-param name="merge.element" select="$module/d:merge"/>
+      <xsl:with-param name="merge.element" select="d:merge"/>
+      <xsl:with-param name="resource" select="$merge.resource"/>
     </xsl:call-template>
-      
+          
     <xsl:apply-templates>
       <xsl:with-param name="parent" select="$element.name"/>
     </xsl:apply-templates>
     </xsl:when>
   </xsl:choose>
 
-  <xsl:variable name="href.att" select="$resource/@fileref | $resource/@href"/>
+  <xsl:variable name="href.att" select="$resource/@href"/>
 
   <xsl:variable name="fragment.id">
     <xsl:if test="contains($href.att, '#')">
 
   <xsl:choose>
     <xsl:when test="string-length($fileref) = 0">
-      <!-- A resource without @fileref gets its content copied -->
-      <xsl:apply-templates select="$resource/node()" mode="copycontent"/>
+      <!-- A resource without an @href value is an error -->
+      <xsl:message terminate="yes">
+        <xsl:text>ERROR: resource with @xml:id='</xsl:text>
+        <xsl:value-of select="$resourceref"/>
+        <xsl:text>' does not resolve to a filename.</xsl:text>
+      </xsl:message>
     </xsl:when>
+    
     <xsl:otherwise>
-
       <xsl:variable name="ref.file.content" select="document($fileref,/)"/>
     
-      <!-- selects root or fragmeht depending on if $fragment is blank -->
+      <!-- selects root or fragment depending on if $fragment is blank -->
       <xsl:variable name="ref.content"
         select="$ref.file.content/*[1][$fragment.id = ''] |
                 $ref.file.content/*[1][$fragment.id != '']/
         
       <xsl:if test="count($ref.content) = 0">
         <xsl:message terminate="yes">
-          <xsl:text>ERROR: @fileref = '</xsl:text>
+          <xsl:text>ERROR: @href = '</xsl:text>
           <xsl:value-of select="$fileref"/>
           <xsl:text>' has no content or is unresolved.</xsl:text>
         </xsl:message>
         </xsl:call-template>
       </xsl:variable>
     
+      <!-- get any merge resource element before changing context -->
+      <xsl:variable name="merge.resourceref" select="$module/d:merge[1]/@resourceref"/>
+      <xsl:variable name="merge.resource" select="key('id', $merge.resourceref)"/>
+
       <xsl:choose>
         <xsl:when test="$contentonly.property = 'true' or 
                         $contentonly.property = 'yes' or
                 <xsl:with-param name="merge.element" select="$module/d:merge"/>
                 <xsl:with-param name="ref.content" select="$ref.content"/>
                 <xsl:with-param name="omittitles" select="$omittitles.property"/>
+                <xsl:with-param name="resource" select="$merge.resource"/>
               </xsl:call-template>
       
               <!-- copy through all but titles, which moved to info -->
               <xsl:with-param name="merge.element" select="d:merge"/>
               <xsl:with-param name="ref.content" select="$ref.content"/>
               <xsl:with-param name="omittitles" select="$omittitles.property"/>
+              <xsl:with-param name="resource" select="$merge.resource"/>
             </xsl:call-template>
     
             <!-- copy through all but titles, which moved to info -->
   <xsl:param name="merge.element" select="NOTANODE"/>
   <xsl:param name="ref.content" select="NOTANODE"/>
   <xsl:param name="omittitles"/> 
+  <xsl:param name="resource"/> 
 
   <!-- a merge element may use resourceref as well as literal content -->
   <!-- any literal content overrides the merge resourceref content -->
   <xsl:variable name="merge.ref.content">
     <xsl:if test="$merge.element/@resourceref">
-      <xsl:variable name="resourceref" select="$merge.element/@resourceref"/>
-      <xsl:variable name="resource" select="key('id', $resourceref)"/>
 
       <xsl:choose>
         <xsl:when test="not($resource)">
           <xsl:message terminate="yes">
             <xsl:text>ERROR: no xml:id matches @resourceref = '</xsl:text>
-            <xsl:value-of select="$resourceref"/>
+            <xsl:value-of select="$merge.element/@resourceref"/>
             <xsl:text>'.</xsl:text>
           </xsl:message>
         </xsl:when>
         <xsl:when test="not($resource/self::d:resource)">
           <xsl:message terminate="yes">
             <xsl:text>ERROR: xml:id matching @resourceref = '</xsl:text>
-            <xsl:value-of select="$resourceref"/>
+            <xsl:value-of select="$merge.element/@resourceref"/>
             <xsl:text> is not a resource element'.</xsl:text>
           </xsl:message>
         </xsl:when>
       </xsl:choose>
 
-      <xsl:variable name="href.att" select="$resource/@fileref | $resource/@href"/>
+      <xsl:variable name="href.att" select="$resource/@href"/>
 
       <xsl:variable name="fileref">
         <xsl:choose>
     </xsl:if>
   </xsl:variable>
 
-  <xsl:variable name="merge.ref.info" 
-                select="exsl:node-set($merge.ref.content)//d:info[1]"/>
-
-  <xsl:if test="$merge.element/@resourceref and not($merge.ref.info)">
-    <xsl:message terminate="yes">
-      <xsl:text>ERROR: merge element with resourceref '</xsl:text>
-      <xsl:value-of select="$merge.element/@resourceref"/>
-      <xsl:text>' must point to something with an info element.'</xsl:text>
-    </xsl:message>
-  </xsl:if>
+  <!-- Copy all metadata from merge.ref.content to a single node-set -->
+  <xsl:variable name="merge.ref.nodes">
+    <xsl:copy-of select="exsl:node-set($merge.ref.content)/*/d:title[1]"/>
+    <xsl:copy-of select="exsl:node-set($merge.ref.content)/*/d:titleabbrev[1]"/>
+    <xsl:copy-of select="exsl:node-set($merge.ref.content)/*/d:subtitle[1]"/>
+    <xsl:copy-of select="exsl:node-set($merge.ref.content)/*/d:info[1]/node()"/>
+  </xsl:variable>
+  <xsl:variable name="merge.ref.nodeset" select="exsl:node-set($merge.ref.nodes)"/>
+  <!-- copy attributes separately so they can be applied in the right place -->
+  <xsl:variable name="merge.ref.attributes" select="exsl:node-set($merge.ref.content)/*/d:info[1]/@*"/>
 
   <xsl:variable name="omittitles.boolean">
     <xsl:choose>
   </xsl:variable>
   <!-- output info if there is any -->
   <xsl:if test="$merge.element/node() or 
-                $merge.ref.info/node() or
+                $merge.ref.nodeset or
+                $merge.ref.attributes or 
                 $ref.content/d:info/node() or
                 $ref.content/d:title[$omittitles.boolean = 0] or
                 $ref.content/d:subtitle[$omittitles.boolean = 0] or
     <info>
       <!-- First copy through any merge attributes and elements and comments -->
       <xsl:copy-of select="$merge.element/@*[not(local-name(.) = 'resourceref')]"/>
+      
+      <!-- add any attributes from the merge resource -->
+      <xsl:copy-of select="$merge.ref.attributes"/>
 
       <!-- And copy any resource info attributes not in merge-->
       <xsl:for-each select="$ref.info/@*">
           <xsl:when test="$merge.element/@*[local-name(.) = $resource.att]">
             <!-- do nothing because overridden -->
           </xsl:when>
+          <xsl:when test="$merge.ref.attributes[local-name(.) = $resource.att]">
+            <!-- do nothing because overridden -->
+          </xsl:when>
           <xsl:otherwise>
             <!-- copy through if not overridden -->
             <xsl:copy-of select="."/>
       <xsl:copy-of select="$merge.element/node()"/>
 
       <!-- and copy through those merge resource elements not in merge element -->
-      <xsl:for-each select="$merge.ref.info/node()">
+      <xsl:for-each select="$merge.ref.nodeset/node()">
         <xsl:variable name="resource.node" select="local-name(.)"/>
         <xsl:choose>
+          <xsl:when test="self::processing-instruction()">
+            <xsl:copy-of select="."/>
+          </xsl:when>
+          <xsl:when test="self::comment()">
+            <xsl:copy-of select="."/>
+          </xsl:when>
           <xsl:when test="$merge.element/node()[local-name(.) = $resource.node]">
             <!-- do nothing because overridden -->
           </xsl:when>
           <xsl:when test="$merge.element/node()[local-name(.) = $resource.node]">
             <!-- do nothing because overridden -->
           </xsl:when>
-          <xsl:when test="$merge.ref.info/node()[local-name(.) = $resource.node]">
+          <xsl:when test="$merge.ref.nodeset/*[local-name(.) = $resource.node]">
             <!-- do nothing because overridden -->
           </xsl:when>
           <xsl:otherwise>