Reworked ppl:block-ipd() for AHF. Added ppl:sum-lengths-to-inches(), ppl:sum-lengths-to-pt(), ppl:length-to-inches(), ppl:length-to-pt(), and ppli:fop-length-to-pt().
authorTony Graham
Mon, 28 Jul 2014 20:25:57 +0100
changeset 47 b4865f38b290
parent 46 dc5ee4f88add
child 48 98b6ced65630
Reworked ppl:block-ipd() for AHF. Added ppl:sum-lengths-to-inches(), ppl:sum-lengths-to-pt(), ppl:length-to-inches(), ppl:length-to-pt(), and ppli:fop-length-to-pt().
FOPRunXSLTExt/examples/ppl-extensions.xsl
--- a/FOPRunXSLTExt/examples/ppl-extensions.xsl	Mon Jul 28 20:23:15 2014 +0100
+++ b/FOPRunXSLTExt/examples/ppl-extensions.xsl	Mon Jul 28 20:25:57 2014 +0100
@@ -15,16 +15,17 @@
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     version="2.0"
     xmlns:ppl="http://www.w3.org/community/ppl/ns/"
+    xmlns:ppli="http://www.w3.org/community/ppl/ns/internal"
     xmlns:fo="http://www.w3.org/1999/XSL/Format"
     xmlns:xalan="http://xml.apache.org/xalan"
     xmlns:se="http://org.w3c.ppl.xslt/saxon-extension"
     xmlns:runfop="runfop"
     xmlns:runahf="runahf"
-	xmlns:runahfdotnet="pi.ep.ppl.xslt.ext.ahf.dotnet"
-	xmlns:runfopdotnet="pi.ep.ppl.xslt.ext.fop.dotnet"
+    xmlns:runahfdotnet="pi.ep.ppl.xslt.ext.ahf.dotnet"
+    xmlns:runfopdotnet="pi.ep.ppl.xslt.ext.fop.dotnet"
     xmlns:ahf="http://www.antennahouse.com/names/XSL/AreaTree"
     xmlns:xs="http://www.w3.org/2001/XMLSchema"
-    exclude-result-prefixes="ppl se ahf xalan runahf runfop runahfdotnet runfopdotnet xs">
+    exclude-result-prefixes="ppl ppli se ahf xalan runahf runfop runahfdotnet runfopdotnet xs">
 
 <!-- ============================================================= -->
 <!-- KEYS                                                          -->
@@ -114,7 +115,7 @@
 <!-- XSLT 2.0-COMPATIBLE FUNCTIONS                                 -->
 <!-- ============================================================= -->
 <!-- Functions for use with XSLT 2.0 processors such as
-     Saxon. -->
+     Saxon 9. -->
 
 <xsl:function name="ppl:area-tree" as="document-node()">
   <xsl:param name="fo-tree" as="node()" />
@@ -133,24 +134,107 @@
   <xsl:param name="block" as="element()" />
 
   <xsl:sequence
-      select="(xs:double($block/block/@bpd) div 1000,
-	       xs:double(substring-before($block/*/ahf:BlockArea/@height, 'pt')))[1]" />
+      select="(ppli:fop-length-to-pt($block/block/@bpd),
+	       ppl:length-to-pt($block/*/ahf:BlockArea/@height))[1]" />
 </xsl:function>
 
 <xsl:function name="ppl:block-ipd" as="xs:double">
   <xsl:param name="block" as="element()" />
 
   <xsl:sequence
-      select="(xs:double($block/block/@ipd) div 1000,
-	       xs:double(substring-before($block/*/ahf:BlockArea/@width, 'pt')))[1]" />
+      select="(ppli:fop-length-to-pt($block/block/@ipd),
+	       max(for $line-area in $block/ahf:FlowReferenceArea/ahf:BlockArea/ahf:LineArea
+	          return ppl:sum-lengths-to-pt($line-area/*/@width)))[1]" />
 </xsl:function>
 
 <xsl:function name="ppl:block-available-ipd" as="xs:double">
   <xsl:param name="block" as="element()" />
 
   <xsl:sequence
-      select="(xs:double($block/ancestor::flow/@ipd) div 1000,
-	       xs:double(substring-before($block/ancestor::ahf:NormalFlowReferenceArea/@width, 'pt')))[1]" />
+      select="(ppli:fop-length-to-pt($block/ancestor::flow/@ipd),
+	       ppl:length-to-pt($block/ancestor::ahf:NormalFlowReferenceArea/@width))[1]" />
+</xsl:function>
+
+<xsl:variable name="ppl:units" as="element(unit)+">
+  <unit name="in" per-inch="1"    per-pt="72" />
+  <unit name="pt" per-inch="72"   per-pt="1" />
+  <unit name="pc" per-inch="6"    per-pt="{1 div 12}" />
+  <unit name="cm" per-inch="2.54" per-pt="{2.54 div 72}" />
+  <unit name="mm" per-inch="25.4" per-pt="{25.4 div 72}" />
+  <unit name="px" per-inch="96"   per-pt="{96 div 72}" />
+</xsl:variable>
+
+<xsl:variable
+    name="ppl:units-pattern"
+    select="concat('(',
+                   string-join($ppl:units/@name, '|'),
+                   ')')"
+    as="xs:string" />
+
+<xsl:function name="ppl:sum-lengths-to-inches" as="xs:double">
+  <xsl:param name="lengths" as="xs:string*" />
+
+  <xsl:sequence select="sum(for $length in $lengths
+                              return ppl:length-to-inches($length))" />
+</xsl:function>
+
+<xsl:function name="ppl:sum-lengths-to-pt" as="xs:double">
+  <xsl:param name="lengths" as="xs:string*" />
+
+  <xsl:sequence select="sum(for $length in $lengths
+                              return ppl:length-to-pt($length))" />
+</xsl:function>
+
+<xsl:function name="ppl:length-to-inches" as="xs:double">
+  <xsl:param name="length" as="xs:string" />
+
+  <xsl:choose>
+    <xsl:when test="matches($length, concat('^-?\d+(\.\d*)?', $ppl:units-pattern, '$'))">
+      <!--<xsl:message select="$length" />-->
+      <xsl:analyze-string
+          select="$length"
+          regex="{concat('^(-?\d+(\.\d*)?)', $ppl:units-pattern, '$')}">
+        <xsl:matching-substring>
+          <xsl:sequence select="xs:double(regex-group(1)) div
+                                xs:double($ppl:units[@name eq regex-group(3)]/@per-inch)" />
+        </xsl:matching-substring>
+      </xsl:analyze-string>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:message select="concat('Unrecognized length: ', $length)" />
+      <xsl:sequence select="0" />
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:function>
+
+<xsl:function name="ppl:length-to-pt" as="xs:double">
+  <xsl:param name="length" as="xs:string" />
+
+  <xsl:choose>
+    <xsl:when test="matches($length, concat('^-?\d+(\.\d*)?', $ppl:units-pattern, '$'))">
+      <!--<xsl:message select="$length" />-->
+      <xsl:analyze-string
+          select="$length"
+          regex="{concat('^(-?\d+(\.\d*)?)', $ppl:units-pattern, '$')}">
+        <xsl:matching-substring>
+          <xsl:sequence
+              select="xs:double(regex-group(1)) div
+                      xs:double($ppl:units[@name eq regex-group(3)]/@per-pt)" />
+        </xsl:matching-substring>
+      </xsl:analyze-string>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:message select="concat('Unrecognized length: ', $length)" />
+      <xsl:sequence select="0" />
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:function>
+
+<!-- FOP area tree dimensions are in 'millipoints'. -->
+<xsl:function name="ppli:fop-length-to-pt" as="xs:double?">
+  <xsl:param name="length" as="xs:string?" />
+
+  <xsl:sequence select="xs:double($length) div 1000" />
 </xsl:function>
 
 </xsl:stylesheet>
\ No newline at end of file