tablefunctions.xsl 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!--
  3. This file is part of the DITA Open Toolkit project.
  4. Copyright 2016 Eero Helenius
  5. See the accompanying LICENSE file for applicable license.
  6. Copied from HTML5 plugin to make table and simpletable functions available to XHTML.
  7. -->
  8. <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  9. xmlns:xs="http://www.w3.org/2001/XMLSchema"
  10. xmlns:dita-ot="http://dita-ot.sourceforge.net/ns/201007/dita-ot"
  11. xmlns:table="http://dita-ot.sourceforge.net/ns/201007/dita-ot/table"
  12. xmlns:simpletable="http://dita-ot.sourceforge.net/ns/201007/dita-ot/simpletable"
  13. version="2.0"
  14. exclude-result-prefixes="xs dita-ot table">
  15. <xsl:function name="table:is-tbody-entry" as="xs:boolean">
  16. <xsl:param name="el" as="element()"/>
  17. <xsl:sequence select="
  18. contains($el/@class, ' topic/entry ') and contains($el/../../@class, ' topic/tbody ')
  19. "/>
  20. </xsl:function>
  21. <xsl:function name="table:is-thead-entry" as="xs:boolean">
  22. <xsl:param name="el" as="element()"/>
  23. <xsl:sequence select="
  24. contains($el/@class, ' topic/entry ') and contains($el/../../@class, ' topic/thead ')
  25. "/>
  26. </xsl:function>
  27. <xsl:function name="table:get-current-table" as="element()">
  28. <xsl:param name="node" as="node()"/>
  29. <xsl:sequence select="
  30. $node/ancestor-or-self::*[contains(@class, ' topic/table ')][1]
  31. "/>
  32. </xsl:function>
  33. <xsl:function name="table:get-current-tgroup" as="element()">
  34. <xsl:param name="node" as="node()"/>
  35. <xsl:sequence select="
  36. $node/ancestor-or-self::*[contains(@class, ' topic/tgroup ')][1]
  37. "/>
  38. </xsl:function>
  39. <xsl:function name="table:is-row-header" as="xs:boolean">
  40. <xsl:param name="entry" as="element()"/>
  41. <xsl:sequence select="
  42. table:get-current-table($entry)/@rowheader eq 'firstcol'
  43. and xs:integer($entry/@dita-ot:x) eq 1
  44. "/>
  45. </xsl:function>
  46. <xsl:function name="table:get-entry-colspec" as="element()?">
  47. <xsl:param name="entry" as="element()"/>
  48. <xsl:sequence select="
  49. table:get-current-tgroup($entry)/*[contains(@class, ' topic/colspec ')]
  50. [@colname eq $entry/@colname]
  51. "/>
  52. </xsl:function>
  53. <xsl:function name="table:get-ending-colspec" as="element()?">
  54. <xsl:param name="entry" as="element()"/>
  55. <xsl:sequence select="
  56. table:get-current-tgroup($entry)/*[contains(@class, ' topic/colspec ')]
  57. [@colname eq $entry/@nameend]
  58. "/>
  59. </xsl:function>
  60. <xsl:function name="table:get-entry-align" as="attribute(align)?">
  61. <xsl:param name="el" as="element()"/>
  62. <xsl:sequence select="
  63. ($el/@align,
  64. table:get-current-tgroup($el)/@align,
  65. table:get-entry-colspec($el)/@align)[1]
  66. "/>
  67. </xsl:function>
  68. <xsl:function name="table:get-entry-colsep" as="attribute(colsep)?">
  69. <xsl:param name="el" as="element()"/>
  70. <xsl:sequence select="
  71. ($el/@colsep,
  72. table:get-entry-colspec($el)/@colsep,
  73. table:get-current-table($el)/@colsep,
  74. table:get-current-tgroup($el)/@colsep)[1]
  75. "/>
  76. </xsl:function>
  77. <xsl:function name="table:get-entry-rowsep" as="attribute(rowsep)?">
  78. <xsl:param name="el" as="element()"/>
  79. <xsl:sequence select="
  80. ($el/@rowsep,
  81. table:get-entry-colspec($el)/@rowsep,
  82. table:get-current-table($el)/@rowsep,
  83. table:get-current-tgroup($el)/@rowsep)[1]
  84. "/>
  85. </xsl:function>
  86. <xsl:function name="table:find-entry-end-column" as="xs:integer">
  87. <xsl:param name="ctx" as="element()"/>
  88. <xsl:choose>
  89. <xsl:when test="$ctx/@nameend">
  90. <xsl:value-of select="xs:integer(table:get-ending-colspec($ctx)/@colnum)"/>
  91. </xsl:when>
  92. <xsl:otherwise>
  93. <xsl:value-of select="xs:integer($ctx/@dita-ot:x)"/>
  94. </xsl:otherwise>
  95. </xsl:choose>
  96. </xsl:function>
  97. <!-- Return true if an entry is entirely within the X or Y span of the header.
  98. If entry ends before the header, or starts after the header, no match, otherwise there is overlap. -->
  99. <xsl:function name="table:entry-within-range" as="xs:boolean">
  100. <xsl:param name="entrystart" as="xs:integer"/>
  101. <xsl:param name="entryend" as="xs:integer"/>
  102. <xsl:param name="headerstart" as="xs:integer"/>
  103. <xsl:param name="headerend" as="xs:integer"/>
  104. <xsl:sequence select="not($entryend lt $headerstart or $entrystart gt $headerend)"/>
  105. </xsl:function>
  106. <xsl:function name="table:get-matching-thead-headers" as="xs:string*">
  107. <xsl:param name="ctx" as="element()"/>
  108. <xsl:variable name="startposition" select="xs:integer($ctx/@dita-ot:x)"/>
  109. <xsl:variable name="endposition" select="table:find-entry-end-column($ctx)"/>
  110. <xsl:for-each select="$ctx/../../../*[contains(@class,' topic/thead ')]/*[contains(@class,' topic/row ')]/*[contains(@class,' topic/entry ')]">
  111. <xsl:variable name="headstart" select="xs:integer(@dita-ot:x)"/>
  112. <xsl:variable name="headend" select="table:find-entry-end-column(.)"/>
  113. <xsl:if test="table:entry-within-range($startposition, $endposition, $headstart, $headend)">
  114. <xsl:value-of select="dita-ot:generate-html-id(.)"/>
  115. </xsl:if>
  116. </xsl:for-each>
  117. </xsl:function>
  118. <xsl:function name="table:get-matching-row-headers" as="xs:string*">
  119. <xsl:param name="ctx" as="element()"/>
  120. <xsl:if test="table:get-current-table($ctx)/@rowheader='firstcol' and
  121. $ctx/@dita-ot:x != '1' and
  122. not(table:is-thead-entry($ctx))">
  123. <xsl:variable name="startposition" select="xs:integer($ctx/@dita-ot:y)"/>
  124. <xsl:variable name="endposition" select="if ($ctx/@morerows) then ($startposition + xs:integer($ctx/@morerows)) else $startposition"/>
  125. <xsl:choose>
  126. <xsl:when test="($startposition = $endposition) and $ctx/preceding-sibling::*[contains(@class,' topic/entry ')][@dita-ot:x = '1']">
  127. <!-- Quick result for common simplest case: no spanning and first-col row header is in this row -->
  128. <xsl:value-of select="dita-ot:generate-html-id($ctx/preceding-sibling::*[contains(@class,' topic/entry ')][@dita-ot:x ='1'])"/>
  129. </xsl:when>
  130. <xsl:otherwise>
  131. <xsl:for-each select="$ctx/../../*[contains(@class,' topic/row ')]/*[contains(@class,' topic/entry ')][@dita-ot:x='1']">
  132. <xsl:variable name="headstart" select="xs:integer(@dita-ot:y)"/>
  133. <xsl:variable name="headend" select="if (@morerows) then ($headstart + xs:integer(@morerows)) else $headstart"/>
  134. <xsl:if test="table:entry-within-range($startposition, $endposition, $headstart, $headend)">
  135. <xsl:value-of select="dita-ot:generate-html-id(.)"/>
  136. </xsl:if>
  137. </xsl:for-each>
  138. </xsl:otherwise>
  139. </xsl:choose>
  140. </xsl:if>
  141. </xsl:function>
  142. <xsl:function name="simpletable:is-body-entry" as="xs:boolean">
  143. <xsl:param name="el" as="element()"/>
  144. <xsl:sequence select="
  145. contains($el/@class, ' topic/stentry ') and contains($el/../@class, ' topic/strow ')
  146. "/>
  147. </xsl:function>
  148. <xsl:function name="simpletable:is-head-entry" as="xs:boolean">
  149. <xsl:param name="el" as="element()"/>
  150. <xsl:sequence select="
  151. contains($el/@class, ' topic/stentry ') and contains($el/../@class, ' topic/sthead ')
  152. "/>
  153. </xsl:function>
  154. <xsl:function name="simpletable:get-current-table" as="element()">
  155. <xsl:param name="node" as="node()"/>
  156. <xsl:sequence select="
  157. $node/ancestor-or-self::*[contains(@class, ' topic/simpletable ')][1]
  158. "/>
  159. </xsl:function>
  160. <xsl:function name="simpletable:is-keycol-entry" as="xs:boolean">
  161. <xsl:param name="entry" as="element()"/>
  162. <xsl:variable name="table" as="element()"
  163. select="simpletable:get-current-table($entry)"/>
  164. <xsl:sequence select="
  165. $table/@keycol and xs:integer($table/@keycol) eq count($entry/preceding-sibling::*) + 1
  166. "/>
  167. </xsl:function>
  168. </xsl:stylesheet>