tables.xsl 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!--
  3. This file is part of the DITA Open Toolkit project.
  4. Copyright 2016 Jarno Elovirta
  5. See the accompanying LICENSE file for applicable license.
  6. -->
  7. <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  8. xmlns:xs="http://www.w3.org/2001/XMLSchema"
  9. xmlns:dita-ot="http://dita-ot.sourceforge.net/ns/201007/dita-ot"
  10. xmlns:dita2html="http://dita-ot.sourceforge.net/ns/200801/dita2html"
  11. xmlns:ditamsg="http://dita-ot.sourceforge.net/ns/200704/ditamsg"
  12. xmlns:table="http://dita-ot.sourceforge.net/ns/201007/dita-ot/table"
  13. version="2.0"
  14. exclude-result-prefixes="xs dita-ot dita2html ditamsg table">
  15. <!-- XML Exchange Table Model Document Type Definition default is all -->
  16. <xsl:variable name="table.frame-default" select="'all'"/>
  17. <!-- XML Exchange Table Model Document Type Definition default is 1 -->
  18. <xsl:variable name="table.rowsep-default" select="'0'"/>
  19. <!-- XML Exchange Table Model Document Type Definition default is 1 -->
  20. <xsl:variable name="table.colsep-default" select="'0'"/>
  21. <xsl:template match="*[contains(@class, ' topic/table ')]" mode="generate-table-summary-attribute">
  22. <!-- Override this to use a local convention for setting table's @summary attribute,
  23. until OASIS provides a standard mechanism for setting. -->
  24. </xsl:template>
  25. <xsl:template match="*[contains(@class, ' topic/tgroup ')]" name="topic.tgroup">
  26. <xsl:variable name="totalwidth" as="xs:double">
  27. <xsl:variable name="relative-widths" as="xs:double*">
  28. <xsl:for-each select="*[contains(@class, ' topic/colspec ')][contains(@colwidth, '*')]">
  29. <xsl:sequence select="xs:double(translate(@colwidth, '*', ''))"/>
  30. </xsl:for-each>
  31. </xsl:variable>
  32. <xsl:sequence select="sum($relative-widths)"/>
  33. </xsl:variable>
  34. <xsl:if test="exists(*[contains(@class, ' topic/colspec ')])">
  35. <colgroup>
  36. <xsl:apply-templates select="*[contains(@class, ' topic/colspec ')]">
  37. <xsl:with-param name="totalwidth" select="$totalwidth"/>
  38. </xsl:apply-templates>
  39. </colgroup>
  40. </xsl:if>
  41. <xsl:apply-templates select="* except *[contains(@class, ' topic/colspec ')]">
  42. <xsl:with-param name="totalwidth" select="$totalwidth"/>
  43. </xsl:apply-templates>
  44. </xsl:template>
  45. <xsl:template match="*[contains(@class, ' topic/colspec ')]">
  46. <xsl:param name="totalwidth" as="xs:double"/>
  47. <xsl:variable name="width" as="xs:string?">
  48. <xsl:choose>
  49. <xsl:when test="empty(@colwidth)"/>
  50. <xsl:when test="contains(@colwidth, '*')">
  51. <xsl:value-of select="concat((xs:double(translate(@colwidth, '*', '')) div $totalwidth) * 100, '%')"/>
  52. </xsl:when>
  53. <xsl:otherwise>
  54. <xsl:value-of select="@colwidth"/>
  55. </xsl:otherwise>
  56. </xsl:choose>
  57. </xsl:variable>
  58. <col>
  59. <xsl:if test="exists($width)">
  60. <xsl:attribute name="style" select="concat('width:', $width)"/>
  61. </xsl:if>
  62. </col>
  63. </xsl:template>
  64. <xsl:template name="doentry">
  65. <xsl:variable name="this-colname" select="@colname"/>
  66. <!-- Rowsep/colsep: Skip if the last row or column. Only check the entry and colsep;
  67. if set higher, will already apply to the whole table. -->
  68. <xsl:variable name="row" select=".." as="element()"/>
  69. <xsl:variable name="body" select="../.." as="element()"/>
  70. <xsl:variable name="group" select="../../.." as="element()"/>
  71. <xsl:variable name="colspec" select="../../../*[contains(@class, ' topic/colspec ')][@colname and @colname = $this-colname]" as="element()"/>
  72. <xsl:variable name="table" select="../../../.." as="element()"/>
  73. <xsl:variable name="framevalue">
  74. <xsl:choose>
  75. <xsl:when test="$table/@frame and $table/@frame != ''">
  76. <xsl:value-of select="$table/@frame"/>
  77. </xsl:when>
  78. <xsl:otherwise>
  79. <xsl:value-of select="$table.frame-default"/>
  80. </xsl:otherwise>
  81. </xsl:choose>
  82. </xsl:variable>
  83. <xsl:variable name="rowsep" as="xs:integer">
  84. <xsl:variable name="last-row" select="(../../../*/*[contains(@class, ' topic/row ')])[last()]" as="element()"/>
  85. <xsl:choose>
  86. <!-- If there are more rows, keep rows on -->
  87. <xsl:when test="not(. &lt;&lt; $last-row)">
  88. <xsl:choose>
  89. <xsl:when test="$framevalue = 'all' or $framevalue = 'bottom' or $framevalue = 'topbot'">1</xsl:when>
  90. <xsl:otherwise>0</xsl:otherwise>
  91. </xsl:choose>
  92. </xsl:when>
  93. <xsl:when test="@rowsep"><xsl:value-of select="@rowsep"/></xsl:when>
  94. <xsl:when test="$row/@rowsep"><xsl:value-of select="$row/@rowsep"/></xsl:when>
  95. <xsl:when test="$colspec/@rowsep"><xsl:value-of select="$colspec/@rowsep"/></xsl:when>
  96. <xsl:when test="$table/@rowsep"><xsl:value-of select="$table/@rowsep"/></xsl:when>
  97. <xsl:otherwise>
  98. <xsl:value-of select="$table.rowsep-default"/>
  99. </xsl:otherwise>
  100. </xsl:choose>
  101. </xsl:variable>
  102. <xsl:variable name="colsep" as="xs:integer">
  103. <xsl:choose>
  104. <!-- If there are more columns, keep rows on -->
  105. <xsl:when test="empty(following-sibling::*)">
  106. <xsl:choose>
  107. <xsl:when test="$framevalue = 'all' or $framevalue = 'sides'">1</xsl:when>
  108. <xsl:otherwise>0</xsl:otherwise>
  109. </xsl:choose>
  110. </xsl:when>
  111. <xsl:when test="@colsep"><xsl:value-of select="@colsep"/></xsl:when>
  112. <xsl:when test="$colspec/@colsep"><xsl:value-of select="$colspec/@colsep"/></xsl:when>
  113. <xsl:when test="$table/@colsep"><xsl:value-of select="$table/@colsep"/></xsl:when>
  114. <xsl:otherwise>
  115. <xsl:value-of select="$table.colsep-default"/>
  116. </xsl:otherwise>
  117. </xsl:choose>
  118. </xsl:variable>
  119. <xsl:variable name="firstcol" as="xs:boolean" select="$table/@rowheader = 'firstcol' and @dita-ot:x = '1'"/>
  120. <xsl:call-template name="commonattributes">
  121. <xsl:with-param name="default-output-class">
  122. <xsl:if test="$firstcol">firstcol </xsl:if>
  123. <xsl:choose>
  124. <xsl:when test="$rowsep = 0 and $colsep = 0">nocellnorowborder</xsl:when>
  125. <xsl:when test="$rowsep = 1 and $colsep = 0">row-nocellborder</xsl:when>
  126. <xsl:when test="$rowsep = 0 and $colsep = 1">cell-norowborder</xsl:when>
  127. <xsl:when test="$rowsep = 1 and $colsep = 1">cellrowborder</xsl:when>
  128. </xsl:choose>
  129. </xsl:with-param>
  130. </xsl:call-template>
  131. <xsl:choose>
  132. <xsl:when test="@id">
  133. <xsl:call-template name="setid"/>
  134. </xsl:when>
  135. <xsl:when test="$firstcol">
  136. <xsl:attribute name="id" select="generate-id(.)"/>
  137. </xsl:when>
  138. </xsl:choose>
  139. <xsl:if test="@morerows">
  140. <xsl:attribute name="rowspan"> <!-- set the number of rows to span -->
  141. <xsl:value-of select="@morerows + 1"/>
  142. </xsl:attribute>
  143. </xsl:if>
  144. <xsl:if test="@dita-ot:morecols"> <!-- get the number of columns to span from the specified named column values -->
  145. <xsl:attribute name="colspan" select="@dita-ot:morecols + 1"/>
  146. </xsl:if>
  147. <!-- If align is specified on a colspec, that takes priority over tgroup -->
  148. <!-- If align is locally specified, that takes priority over all -->
  149. <xsl:call-template name="style">
  150. <xsl:with-param name="contents">
  151. <xsl:variable name="align" as="xs:string?">
  152. <xsl:choose>
  153. <xsl:when test="@align">
  154. <xsl:value-of select="@align"/>
  155. </xsl:when>
  156. <xsl:when test="$group/@align">
  157. <xsl:value-of select="$group/@align"/>
  158. </xsl:when>
  159. <xsl:when test="$colspec/@align">
  160. <xsl:value-of select="$colspec/@align"/>
  161. </xsl:when>
  162. </xsl:choose>
  163. </xsl:variable>
  164. <xsl:if test="exists($align)">
  165. <xsl:text>text-align:</xsl:text>
  166. <xsl:value-of select="$align"/>
  167. <xsl:text>;</xsl:text>
  168. </xsl:if>
  169. <xsl:variable name="valign" as="xs:string?">
  170. <xsl:choose>
  171. <xsl:when test="@valign">
  172. <xsl:value-of select="@valign"/>
  173. </xsl:when>
  174. <xsl:when test="$row/@valign">
  175. <xsl:value-of select="$row/@valign"/>
  176. </xsl:when>
  177. <xsl:when test="$body/@valign">
  178. <xsl:value-of select="$body/@valign"/>
  179. </xsl:when>
  180. <xsl:otherwise>top</xsl:otherwise>
  181. </xsl:choose>
  182. </xsl:variable>
  183. <xsl:if test="exists($valign)">
  184. <xsl:text>vertical-align:</xsl:text>
  185. <xsl:value-of select="$valign"/>
  186. <xsl:text>;</xsl:text>
  187. </xsl:if>
  188. </xsl:with-param>
  189. </xsl:call-template>
  190. <xsl:variable name="char" as="xs:string?">
  191. <xsl:choose>
  192. <xsl:when test="@char">
  193. <xsl:value-of select="@char"/>
  194. </xsl:when>
  195. <xsl:when test="$colspec/@char">
  196. <xsl:value-of select="$colspec/@char"/>
  197. </xsl:when>
  198. </xsl:choose>
  199. </xsl:variable>
  200. <xsl:if test="$char">
  201. <xsl:attribute name="char" select="$char"/>
  202. </xsl:if>
  203. <xsl:variable name="charoff" as="xs:string?">
  204. <xsl:choose>
  205. <xsl:when test="@charoff">
  206. <xsl:value-of select="@charoff"/>
  207. </xsl:when>
  208. <xsl:when test="$colspec/@charoff">
  209. <xsl:value-of select="$colspec/@charoff"/>
  210. </xsl:when>
  211. </xsl:choose>
  212. </xsl:variable>
  213. <xsl:if test="$charoff">
  214. <xsl:attribute name="charoff" select="$charoff"/>
  215. </xsl:if>
  216. <xsl:choose>
  217. <!-- When entry is in a thead, output the ID -->
  218. <xsl:when test="$body/self::*[contains(@class, ' topic/thead ')]">
  219. <xsl:attribute name="id" select="dita-ot:generate-html-id(.)"/>
  220. </xsl:when>
  221. <!-- otherwise, add @headers if needed -->
  222. <xsl:otherwise>
  223. <xsl:call-template name="add-headers-attribute"/>
  224. </xsl:otherwise>
  225. </xsl:choose>
  226. <!-- Add any flags from tgroup, thead or tbody, and row -->
  227. <xsl:apply-templates select="$group/*[contains(@class, ' ditaot-d/ditaval-startprop ')]" mode="out-of-line"/>
  228. <xsl:apply-templates select="$body/*[contains(@class, ' ditaot-d/ditaval-startprop ')]" mode="out-of-line"/>
  229. <xsl:apply-templates select="$row/*[contains(@class, ' ditaot-d/ditaval-startprop ')]" mode="out-of-line"/>
  230. <xsl:choose>
  231. <!-- When entry is empty, output a blank -->
  232. <xsl:when test="not(*|text()|processing-instruction())">
  233. <xsl:text>&#160;</xsl:text> <!-- nbsp -->
  234. </xsl:when>
  235. <xsl:otherwise>
  236. <xsl:apply-templates/>
  237. </xsl:otherwise>
  238. </xsl:choose>
  239. <xsl:apply-templates select="$row/*[contains(@class, ' ditaot-d/ditaval-endprop ')]" mode="out-of-line"/>
  240. <xsl:apply-templates select="$body/*[contains(@class, ' ditaot-d/ditaval-endprop ')]" mode="out-of-line"/>
  241. <xsl:apply-templates select="$group/*[contains(@class, ' ditaot-d/ditaval-endprop ')]" mode="out-of-line"/>
  242. </xsl:template>
  243. <!-- Find the end column of a cell. If the cell does not span any columns,
  244. the end position is the same as the start position. -->
  245. <!-- DEPRECATED since 3.3: use table:find-entry-end-column -->
  246. <xsl:template name="find-entry-end-position">
  247. <xsl:param name="startposition" select="0"/>
  248. <xsl:choose>
  249. <xsl:when test="@nameend">
  250. <xsl:value-of select="number(count(../../../*[contains(@class, ' topic/colspec ')][@colname = current()/@nameend]/preceding-sibling::*[contains(@class, ' topic/colspec ')])+1)"/>
  251. </xsl:when>
  252. <xsl:otherwise>
  253. <xsl:value-of select="$startposition"/>
  254. </xsl:otherwise>
  255. </xsl:choose>
  256. </xsl:template>
  257. <!-- Check <thead> entries, and return IDs for those which match the desired column -->
  258. <!-- DEPRECATED since 3.3: use table:get-matching-thead-headers -->
  259. <xsl:template match="*[contains(@class, ' topic/thead ')]/*[contains(@class, ' topic/row ')]/*[contains(@class, ' topic/entry ')]" mode="findmatch">
  260. <xsl:param name="startmatch" select="1"/> <!-- start column of the tbody cell -->
  261. <xsl:param name="endmatch" select="1"/> <!-- end column of the tbody cell -->
  262. <xsl:variable name="entrystartpos" select="@dita-ot:x"/> <!-- start column of this thead cell -->
  263. <xsl:variable name="entryendpos" select="table:find-entry-end-column(.)"/> <!-- end column of this thead cell -->
  264. <!-- The test cell can be any of the following:
  265. * completely before the header range (ignore id)
  266. * completely after the header range (ignore id)
  267. * completely within the header range (save id)
  268. * partially before, partially within (save id)
  269. * partially within, partially after (save id)
  270. * completely surrounding the header range (save id) -->
  271. <xsl:choose>
  272. <!-- Ignore this header cell if it starts after the tbody cell we are testing -->
  273. <xsl:when test="number($endmatch) &lt; number($entrystartpos)"/>
  274. <!-- Ignore this header cell if it ends before the tbody cell we are testing -->
  275. <xsl:when test="number($startmatch) > number($entryendpos)"/>
  276. <!-- Otherwise, this header lines up with the tbody cell, so use the ID -->
  277. <xsl:otherwise>
  278. <xsl:value-of select="dita-ot:generate-html-id(.)"/>
  279. <xsl:text> </xsl:text>
  280. </xsl:otherwise>
  281. </xsl:choose>
  282. </xsl:template>
  283. <!-- Check the first column for entries that line up with the test row.
  284. Any entries that line up need to have the header saved. This template is first
  285. called with the first entry of the first row in <tbody>. It is called from here
  286. on the next cell in column one. -->
  287. <!-- DEPRECATED since 3.3: use table:get-matching-row-headers -->
  288. <xsl:template match="*[contains(@class, ' topic/entry ')]" mode="check-first-column">
  289. <xsl:param name="startMatchRow" select="1"/> <!-- First row of the tbody cell we are matching -->
  290. <xsl:param name="endMatchRow" select="1"/> <!-- Last row of the tbody cell we are matching -->
  291. <xsl:param name="startCurrentRow" select="1"/> <!-- First row of the column-1 cell we are testing -->
  292. <xsl:variable name="endCurrentRow"> <!-- Last row of the column-1 cell we are testing -->
  293. <xsl:choose>
  294. <!-- If @morerows, the cell ends at startCurrentRow + @morerows. Otherise, start=end. -->
  295. <xsl:when test="@morerows"><xsl:value-of select="number($startCurrentRow)+number(@morerows)"/></xsl:when>
  296. <xsl:otherwise><xsl:value-of select="$startCurrentRow"/></xsl:otherwise>
  297. </xsl:choose>
  298. </xsl:variable>
  299. <xsl:choose>
  300. <!-- When the current column-1 cell ends before the tbody cell we are matching -->
  301. <xsl:when test="number($endCurrentRow) &lt; number($startMatchRow)">
  302. <!-- Call this template again with the next entry in column one -->
  303. <xsl:if test="parent::*/parent::*/*[contains(@class, ' topic/row ')][number($endCurrentRow)+1]">
  304. <xsl:apply-templates select="parent::*/parent::*/*[contains(@class, ' topic/row ')][number($endCurrentRow)+1]/*[contains(@class, ' topic/entry ')][1]" mode="check-first-column">
  305. <xsl:with-param name="startMatchRow" select="$startMatchRow"/>
  306. <xsl:with-param name="endMatchRow" select="$endMatchRow"/>
  307. <xsl:with-param name="startCurrentRow" select="number($endCurrentRow)+1"/>
  308. </xsl:apply-templates>
  309. </xsl:if>
  310. </xsl:when>
  311. <!-- If this column-1 cell starts after the tbody cell we are matching, jump out of recursive loop -->
  312. <xsl:when test="number($startCurrentRow) > number($endMatchRow)"/>
  313. <!-- Otherwise, the column-1 cell is aligned with the tbody cell, so save the ID and continue -->
  314. <xsl:otherwise>
  315. <xsl:value-of select="if(@id) then dita-ot:generate-html-id(.) else generate-id(.)"/>
  316. <xsl:text> </xsl:text>
  317. <!-- If we are not at the end of the tbody cell, and more rows exist, continue testing column 1 -->
  318. <xsl:if test="number($endCurrentRow) &lt; number($endMatchRow) and
  319. parent::*/parent::*/*[contains(@class, ' topic/row ')][number($endCurrentRow)+1]">
  320. <xsl:apply-templates select="parent::*/parent::*/*[contains(@class, ' topic/row ')][number($endCurrentRow)+1]/*[contains(@class, ' topic/entry ')][1]" mode="check-first-column">
  321. <xsl:with-param name="startMatchRow" select="$startMatchRow"/>
  322. <xsl:with-param name="endMatchRow" select="$endMatchRow"/>
  323. <xsl:with-param name="startCurrentRow" select="number($endCurrentRow)+1"/>
  324. </xsl:apply-templates>
  325. </xsl:if>
  326. </xsl:otherwise>
  327. </xsl:choose>
  328. </xsl:template>
  329. <!-- Add @headers to cells in the body of a table. -->
  330. <xsl:template name="add-headers-attribute">
  331. <!-- Find the IDs of all headers that are aligned above this cell. May contain duplicates due to spanning cells. -->
  332. <xsl:variable name="all-thead-headers" select="table:get-matching-thead-headers(.)" as="xs:string*"/>
  333. <!-- Row header should be 0 or 1 today, but future updates may allow multiple -->
  334. <xsl:variable name="all-row-headers" select="table:get-matching-row-headers(.)" as="xs:string*"/>
  335. <xsl:if test="exists($all-row-headers) or exists($all-thead-headers)">
  336. <xsl:attribute name="headers"
  337. select="distinct-values($all-row-headers), distinct-values($all-thead-headers)"
  338. separator=" "/>
  339. </xsl:if>
  340. </xsl:template>
  341. <!-- ========== "FORMAT" MACROS - Table title, figure title, InfoNavGraphic ========== -->
  342. <!--
  343. | These macros support globally-defined formatting constants for
  344. | document content. Some elements have attributes that permit local
  345. | control of formatting; such logic is part of the pertinent template rule.
  346. +-->
  347. <!-- table caption -->
  348. <xsl:template name="place-tbl-lbl">
  349. <xsl:param name="stringName"/>
  350. <!-- Number of table/title's before this one -->
  351. <xsl:variable name="tbl-count-actual" select="count(preceding::*[contains(@class, ' topic/table ')]/*[contains(@class, ' topic/title ')])+1"/>
  352. <!-- normally: "Table 1. " -->
  353. <xsl:variable name="ancestorlang">
  354. <xsl:call-template name="getLowerCaseLang"/>
  355. </xsl:variable>
  356. <xsl:choose>
  357. <!-- title -or- title & desc -->
  358. <xsl:when test="*[contains(@class, ' topic/title ')]">
  359. <caption>
  360. <span class="tablecap">
  361. <span class="table--title-label">
  362. <!-- TODO language specific processing should be done with string variables -->
  363. <xsl:choose> <!-- Hungarian: "1. Table " -->
  364. <xsl:when test="$ancestorlang = ('hu', 'hu-hu')">
  365. <xsl:value-of select="$tbl-count-actual"/>
  366. <xsl:text>. </xsl:text>
  367. <xsl:call-template name="getVariable">
  368. <xsl:with-param name="id" select="'Table'"/>
  369. </xsl:call-template>
  370. <xsl:text> </xsl:text>
  371. </xsl:when>
  372. <xsl:otherwise>
  373. <xsl:call-template name="getVariable">
  374. <xsl:with-param name="id" select="'Table'"/>
  375. </xsl:call-template>
  376. <xsl:text> </xsl:text>
  377. <xsl:value-of select="$tbl-count-actual"/>
  378. <xsl:text>. </xsl:text>
  379. </xsl:otherwise>
  380. </xsl:choose>
  381. </span>
  382. <xsl:apply-templates select="*[contains(@class, ' topic/title ')]" mode="tabletitle"/>
  383. <xsl:if test="*[contains(@class, ' topic/desc ')]">
  384. <xsl:text>. </xsl:text>
  385. </xsl:if>
  386. </span>
  387. <xsl:for-each select="*[contains(@class, ' topic/desc ')]">
  388. <span class="tabledesc">
  389. <xsl:call-template name="commonattributes"/>
  390. <xsl:apply-templates select="." mode="tabledesc"/>
  391. </span>
  392. </xsl:for-each>
  393. </caption>
  394. </xsl:when>
  395. <!-- desc -->
  396. <xsl:when test="*[contains(@class, ' topic/desc ')]">
  397. <xsl:for-each select="*[contains(@class, ' topic/desc ')]">
  398. <span class="tabledesc">
  399. <xsl:call-template name="commonattributes"/>
  400. <xsl:apply-templates select="." mode="tabledesc"/>
  401. </span>
  402. </xsl:for-each>
  403. </xsl:when>
  404. </xsl:choose>
  405. </xsl:template>
  406. <xsl:template match="*[contains(@class, ' topic/table ')]/*[contains(@class, ' topic/title ')]" mode="tabletitle">
  407. <xsl:apply-templates/>
  408. </xsl:template>
  409. <xsl:template match="*[contains(@class, ' topic/table ')]/*[contains(@class, ' topic/desc ')]" mode="tabledesc">
  410. <xsl:apply-templates/>
  411. </xsl:template>
  412. <xsl:template match="*[contains(@class, ' topic/table ')]/*[contains(@class, ' topic/desc ')]" mode="get-output-class">tabledesc</xsl:template>
  413. <xsl:template match="*" mode="table:common">
  414. <xsl:call-template name="commonattributes"/>
  415. <xsl:call-template name="setid"/>
  416. <xsl:apply-templates select="." mode="css-class"/>
  417. </xsl:template>
  418. <xsl:template match="*[contains(@class,' topic/table ')]
  419. [empty(*[contains(@class,' topic/tgroup ')]/*[contains(@class,' topic/tbody ')]/*[contains(@class,' topic/row ')])]" priority="10"/>
  420. <xsl:template match="*[contains(@class,' topic/tgroup ')]
  421. [empty(*[contains(@class,' topic/tbody ')]/*[contains(@class,' topic/row ')])]" priority="10"/>
  422. <xsl:template match="*[contains(@class,' topic/table ')]" name="topic.table">
  423. <xsl:apply-templates select="*[contains(@class, ' ditaot-d/ditaval-startprop ')]" mode="out-of-line"/>
  424. <table>
  425. <xsl:apply-templates select="." mode="table:common"/>
  426. <xsl:apply-templates select="." mode="table:title"/>
  427. <!-- title and desc are processed elsewhere -->
  428. <xsl:apply-templates select="*[contains(@class, ' topic/tgroup ')]"/>
  429. </table>
  430. <xsl:apply-templates select="*[contains(@class, ' ditaot-d/ditaval-endprop ')]" mode="out-of-line"/>
  431. </xsl:template>
  432. <xsl:template match="*[contains(@class, ' topic/thead ')]" name="topic.thead">
  433. <thead>
  434. <xsl:apply-templates select="." mode="table:section"/>
  435. </thead>
  436. </xsl:template>
  437. <xsl:template match="*[contains(@class, ' topic/tbody ')]" name="topic.tbody">
  438. <tbody>
  439. <xsl:apply-templates select="." mode="table:section"/>
  440. </tbody>
  441. </xsl:template>
  442. <xsl:template match="*[contains(@class, ' topic/tgroup ')]/*" mode="table:section">
  443. <xsl:apply-templates select="../*[contains(@class, ' ditaot-d/ditaval-startprop ')]/@outputclass" mode="add-ditaval-style"/>
  444. <xsl:apply-templates select="." mode="table:common"/>
  445. <xsl:apply-templates/>
  446. </xsl:template>
  447. <xsl:template match="*[contains(@class, ' topic/row ')]" name="topic.row">
  448. <tr>
  449. <xsl:apply-templates select="." mode="table:common"/>
  450. <xsl:apply-templates/>
  451. </tr>
  452. </xsl:template>
  453. <xsl:template match="*[table:is-thead-entry(.)]">
  454. <th>
  455. <xsl:apply-templates select="." mode="table:entry"/>
  456. </th>
  457. </xsl:template>
  458. <xsl:template match="*[table:is-tbody-entry(.)][table:is-row-header(.)]">
  459. <th scope="row">
  460. <xsl:apply-templates select="." mode="table:entry"/>
  461. </th>
  462. </xsl:template>
  463. <xsl:template match="*[table:is-tbody-entry(.)][not(table:is-row-header(.))]" name="topic.entry">
  464. <td>
  465. <xsl:apply-templates select="." mode="table:entry"/>
  466. </td>
  467. </xsl:template>
  468. <xsl:template match="*[contains(@class, ' topic/entry ')]" mode="table:entry">
  469. <xsl:apply-templates select="." mode="table:common"/>
  470. <xsl:apply-templates select="." mode="headers"/>
  471. <xsl:apply-templates select="@morerows, @dita-ot:morecols"/>
  472. <xsl:apply-templates/>
  473. </xsl:template>
  474. <xsl:template match="@pgwide" mode="css-class">
  475. <xsl:sequence select="dita-ot:css-class(.)"/>
  476. </xsl:template>
  477. <xsl:template match="*[contains(@class, ' topic/table ')]" mode="css-class">
  478. <xsl:apply-templates select="@frame, @pgwide, @scale" mode="#current"/>
  479. </xsl:template>
  480. <xsl:template match="@align | @valign | @colsep | @rowsep" mode="css-class">
  481. <xsl:sequence select="dita-ot:css-class((), .)"/>
  482. </xsl:template>
  483. <xsl:template match="*[contains(@class, ' topic/tgroup ')]/*" mode="css-class">
  484. <xsl:apply-templates select="@valign" mode="#current"/>
  485. </xsl:template>
  486. <xsl:template match="*[contains(@class, ' topic/row ')]" mode="css-class">
  487. <xsl:apply-templates select="@rowsep, @valign" mode="#current"/>
  488. </xsl:template>
  489. <xsl:template match="*[contains(@class, ' topic/entry ')]" mode="css-class">
  490. <xsl:variable name="colsep" as="attribute(colsep)?" select="table:get-entry-colsep(.)"/>
  491. <xsl:variable name="rowsep" as="attribute(rowsep)?" select="table:get-entry-rowsep(.)"/>
  492. <xsl:apply-templates mode="#current" select="
  493. table:get-entry-align(.), $colsep, $rowsep, @valign
  494. "/>
  495. </xsl:template>
  496. <xsl:template match="*[table:is-thead-entry(.)]" mode="headers">
  497. <xsl:attribute name="id" select="dita-ot:generate-html-id(.)"/>
  498. </xsl:template>
  499. <xsl:template match="*[table:is-tbody-entry(.)]" mode="headers">
  500. <xsl:if test="table:is-row-header(.)">
  501. <xsl:attribute name="id" select="dita-ot:generate-html-id(.)"/>
  502. </xsl:if>
  503. <xsl:call-template name="add-headers-attribute"/>
  504. </xsl:template>
  505. <xsl:template match="@morerows">
  506. <xsl:attribute name="rowspan" select="xs:integer(.) + 1"/>
  507. </xsl:template>
  508. <xsl:template match="@dita-ot:morecols">
  509. <xsl:attribute name="colspan" select="xs:integer(.) + 1"/>
  510. </xsl:template>
  511. <xsl:template match="*[contains(@class, ' topic/table ')]" mode="table:title">
  512. <caption>
  513. <xsl:apply-templates select="*[contains(@class, ' topic/title ')]" mode="label"/>
  514. <xsl:apply-templates select="
  515. *[contains(@class, ' topic/title ')] | *[contains(@class, ' topic/desc ')]
  516. "/>
  517. </caption>
  518. </xsl:template>
  519. <xsl:template match="*[contains(@class, ' topic/table ')]/*[contains(@class, ' topic/title ')]" mode="label">
  520. <span class="table--title-label">
  521. <xsl:apply-templates select="." mode="title-number">
  522. <xsl:with-param name="number" as="xs:integer"
  523. select="count(key('enumerableByClass', 'topic/table')[. &lt;&lt; current()])"/>
  524. </xsl:apply-templates>
  525. </span>
  526. </xsl:template>
  527. <xsl:template match="*[contains(@class, ' topic/table ')]/*[contains(@class, ' topic/title ')]" mode="title-number">
  528. <xsl:param name="number" as="xs:integer"/>
  529. <xsl:sequence select="concat(dita-ot:get-variable(., 'Table'), ' ', $number, '. ')"/>
  530. </xsl:template>
  531. <xsl:template mode="title-number" priority="1" match="
  532. *[contains(@class, ' topic/table ')]
  533. [dita-ot:get-current-language(.) = ('hu', 'hu-hu')]
  534. /*[contains(@class, ' topic/title ')]
  535. ">
  536. <xsl:param name="number" as="xs:integer"/>
  537. <xsl:sequence select="concat($number, '. ', dita-ot:get-variable(., 'Table'), ' ')"/>
  538. </xsl:template>
  539. <xsl:template match="*[contains(@class, ' topic/table ')]/*[contains(@class, ' topic/title ')]" name="topic.table_title">
  540. <span>
  541. <xsl:call-template name="setid"/>
  542. <xsl:call-template name="commonattributes"/>
  543. <xsl:apply-templates/>
  544. </span>
  545. </xsl:template>
  546. <xsl:template match="*[contains(@class, ' topic/table ')]/*[contains(@class, ' topic/desc ')]" name="topic.table_desc">
  547. <span>
  548. <xsl:call-template name="setid"/>
  549. <xsl:call-template name="commonattributes"/>
  550. <xsl:apply-templates/>
  551. </span>
  552. </xsl:template>
  553. </xsl:stylesheet>