Sizing 'header' to fill available width. Reworked to do area-tree munging in 'ppl' mode. Inserting source code only in final processing.
authorTony Graham
Mon, 28 Jul 2014 20:22:59 +0100
changeset 45 46c7c7f8f793
parent 44 902a8c95ed31
child 46 dc5ee4f88add
Sizing 'header' to fill available width. Reworked to do area-tree munging in 'ppl' mode. Inserting source code only in final processing.
FOPRunXSLTExt/examples/balisage2014.xsl
--- a/FOPRunXSLTExt/examples/balisage2014.xsl	Sun Jul 27 21:35:55 2014 +0100
+++ b/FOPRunXSLTExt/examples/balisage2014.xsl	Mon Jul 28 20:22:59 2014 +0100
@@ -4,7 +4,7 @@
 <!--                                                               -->
 <!-- See http://www.w3.org/community/ppl/wiki/XSLTExtensions       -->
 <!--                                                               -->
-<!-- Requires Saxon 9.5 or later and FOP 1.0 or AHF 6.1            -->
+<!-- Requires Saxon 9.5 or later and AHF 6.1 or later              -->
 <!--                                                               -->
 <!-- Produced by the Print and Page Layout Community Group @ W3C   -->
 <!-- http://www.w3.org/community/ppl/                              -->
@@ -106,6 +106,44 @@
   <xsl:message select="concat('tolerance: ', $tolerance)" />
   <xsl:message select="concat('font-size-tolerance: ', $font-size-tolerance)" />
 
+  <xsl:apply-templates select="/" mode="ppl">
+    <xsl:with-param name="font-size"
+		    select="$font-size" as="xs:double" tunnel="yes" />
+    <xsl:with-param name="source"
+		    as="element()*">
+      <fo:block-container
+	  font-size="9pt"
+	  axf:column-count="4"
+	  column-gap="48pt">
+	<fo:block  xsl:use-attribute-sets="code-title">XML</fo:block>
+	<fo:block xsl:use-attribute-sets="code">
+	  <xsl:sequence
+	      select="if ($pygmentize ne 'no')
+			then doc(concat(tokenize(base-uri(), '/')[last()], '.fo'))
+		      else unparsed-text(base-uri())" />
+	</fo:block>
+	<fo:block xsl:use-attribute-sets="code-title">XSLT</fo:block>
+	<fo:block height="100%"
+		  xsl:use-attribute-sets="code">
+	  <xsl:sequence
+	      select="if ($pygmentize ne 'no')
+			then doc(concat(tokenize(base-uri(doc('')), '/')[last()], '.fo'))
+		      else unparsed-text('')" />
+          </fo:block>
+        </fo:block-container>
+    </xsl:with-param>
+  </xsl:apply-templates>
+</xsl:template>
+
+<xsl:template match="*" mode="ppl">
+  <xsl:apply-templates select="." mode="#default" />
+</xsl:template>
+
+<xsl:template match="/*" mode="ppl">
+  <xsl:apply-templates mode="#current" />
+</xsl:template>
+
+<xsl:template match="box" mode="ppl">
   <!-- 'do-box' templates recursively calls itself until: the
        formatted area fits within the box within $tolerance; the
        change in $font-size between successive runs is less than
@@ -159,9 +197,14 @@
     </overrides>
   </xsl:variable>
 
-  <!-- Save the FO tree in a variable. -->
+  <!-- Get just this box. -->
+  <xsl:variable name="this-box">
+    <xsl:sequence select="." />
+  </xsl:variable>
+
+  <!-- Save the FO tree for this box in a variable. -->
   <xsl:variable name="fo_tree">
-    <xsl:apply-templates select="/">
+    <xsl:apply-templates select="$this-box" mode="#default">
       <xsl:with-param name="overrides"
 		      select="$overrides"
 		      as="document-node()" tunnel="yes" />
@@ -194,7 +237,7 @@
     <xsl:when test="$target-height - $bpd > 0 and
                     $target-height - $bpd &lt; $tolerance">
       <xsl:message>It fits.  Using <xsl:value-of select="$font-size" />.</xsl:message>
-      <xsl:apply-templates select="/">
+      <xsl:apply-templates select="." mode="#default">
         <xsl:with-param
             name="overrides"
             select="$overrides"
@@ -205,7 +248,7 @@
     <xsl:when test="$font-size.maximum - $font-size.minimum &lt; $font-size-tolerance and
 		    $target-height - $bpd > 0">
       <xsl:message>Font size difference less than $font-size-tolerance.  Using <xsl:value-of select="$font-size" />.</xsl:message>
-      <xsl:apply-templates select="/">
+      <xsl:apply-templates select="." mode="#default">
         <xsl:with-param
             name="overrides"
             select="$overrides"
@@ -215,7 +258,7 @@
     </xsl:when>
     <xsl:when test="$iteration eq $iteration-max">
       <xsl:message>Maximum iterations.  Using <xsl:value-of select="$font-size" />.</xsl:message>
-      <xsl:apply-templates select="/">
+      <xsl:apply-templates select="." mode="#default">
         <xsl:with-param
             name="overrides"
             select="$overrides"
@@ -228,8 +271,7 @@
       <xsl:call-template name="do-box">
         <xsl:with-param
             name="font-size"
-            select="min(($font-size * ($bpd div $target-height),
-		         $font-size.minimum))"
+            select="($font-size + $font-size.minimum) div 2"
             as="xs:double"
             tunnel="yes" />
         <xsl:with-param
@@ -262,8 +304,10 @@
 </xsl:template>
 
 
-<xsl:template match="/">
-  <fo:root font-family="'Calluna Sans', verdana, sans-serif" font-size="12pt">
+<xsl:template match="/" mode="#all">
+  <xsl:param name="source" select="()" as="element()*" />
+
+  <fo:root font-family="Calluna Sans, verdana, sans-serif" font-size="18pt">
     <fo:layout-master-set>
       <fo:simple-page-master master-name="test-page">
         <xsl:if test="exists($page-height)">
@@ -281,37 +325,89 @@
 		      axf:line-number-interval="5"
 		      axf:line-number-offset="0.375em + 6pt">
       <fo:flow flow-name="xsl-region-body">
-        <xsl:apply-templates/>
-        <fo:block-container
-            font-size="9pt"
-            axf:column-count="4"
-	    column-gap="48pt">
-	  <fo:block  xsl:use-attribute-sets="code-title">XML</fo:block>
-          <fo:block xsl:use-attribute-sets="code">
-            <xsl:copy-of
-		select="if ($pygmentize ne 'no')
-			then doc(concat(tokenize(base-uri(), '/')[last()], '.fo'))
-			else unparsed-text(base-uri())" />
-          </fo:block>
-	  <fo:block xsl:use-attribute-sets="code-title">XSLT</fo:block>
-          <fo:block height="100%"
-		    xsl:use-attribute-sets="code">
-            <xsl:copy-of
-		select="if ($pygmentize ne 'no')
-			then doc(concat(tokenize(base-uri(doc('')), '/')[last()], '.fo'))
-			else unparsed-text('')" />
-          </fo:block>
-        </fo:block-container>
+        <xsl:apply-templates mode="#current" />
+	<xsl:sequence select="$source" />
       </fo:flow>
     </fo:page-sequence>
   </fo:root>
 </xsl:template>
 
+<xsl:template match="header" mode="ppl">
+  <xsl:variable name="header-font-size" select="20" as="xs:double" />
+
+  <!-- Get a document containing just this element. -->
+  <xsl:variable name="tmp-doc">
+    <xsl:sequence select="." />
+  </xsl:variable>
+
+  <!-- Save the FO tree for this element in a variable. -->
+  <xsl:variable name="fo_tree">
+    <xsl:apply-templates select="$tmp-doc" mode="#default">
+      <xsl:with-param name="overrides" as="document-node()" tunnel="yes">
+	<xsl:document>
+	  <overrides>
+	    <override id="header" font-size="{$header-font-size}pt" />
+	  </overrides>
+	</xsl:document>
+      </xsl:with-param>
+    </xsl:apply-templates>
+  </xsl:variable>
+
+  <xsl:variable
+      name="area-tree"
+      select="ppl:area-tree($fo_tree)"
+      as="document-node()?" />
+
+  <xsl:variable
+      name="block"
+      select="ppl:block-by-id($area-tree, 'header')"
+      as="element()" />
+<xsl:message
+    select="max(for $line-area in $block/ahf:FlowReferenceArea/ahf:BlockArea/ahf:LineArea
+	          return ppl:sum-lengths-to-pt($line-area/*/@width))"
+    xmlns:ahf="http://www.antennahouse.com/names/XSL/AreaTree" />
+<xsl:message select="$block"/>
+  <xsl:variable
+      name="ipd"
+      select="ppl:block-ipd($block)"
+      as="xs:double" />
+
+  <xsl:variable
+      name="available-ipd"
+      select="ppl:block-available-ipd($block)"
+      as="xs:double" />
+
+  <xsl:message select="$ipd"/>
+  <xsl:message select="$available-ipd"/>
+  <xsl:apply-templates select="." mode="#default">
+    <xsl:with-param name="overrides" tunnel="yes">
+      <xsl:document>
+	<overrides>
+	  <override id="header"
+		    font-size="{$header-font-size * $available-ipd div $ipd}pt" />
+	</overrides>
+      </xsl:document>
+    </xsl:with-param>
+  </xsl:apply-templates>
+</xsl:template>
+
 <xsl:template match="header">
-  <fo:block font-size="14pt" color="red"
-	    space-before="5mm" space-after="5mm">
-   <xsl:apply-templates />
-  </fo:block>
+  <xsl:param name="overrides" select="$overrides"
+	     as="document-node()" tunnel="yes"/>
+  <fo:block-container
+      font-size="{(key('overrides', 'header', $overrides)/@font-size, '14pt')[1]}"
+      space-before="5mm" space-after="5mm"
+      font-weight="900" text-align="center" id="header">
+    <fo:block
+	line-height="1.2em"
+	line-height-shift-adjustment="disregard-shifts">
+      <xsl:apply-templates />
+    </fo:block>
+  </fo:block-container>
+</xsl:template>
+
+<xsl:template match="lb">
+  <fo:block />
 </xsl:template>
 
 <xsl:template match="box">
@@ -403,7 +499,9 @@
 </xsl:template>
 
 <xsl:template match="svg">
-  <fo:instream-foreign-object id="{@id}" content-height="1em">
+  <fo:instream-foreign-object
+      id="{@id}" content-height="1.8em"
+      alignment-adjust="-0.25em">
     <xsl:copy-of select="document(@href)"/>
   </fo:instream-foreign-object>
 </xsl:template>