1<?xml version='1.0'?> 2<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 3 xmlns:doc="http://nwalsh.com/xsl/documentation/1.0" 4 xmlns:stbl="http://nwalsh.com/xslt/ext/com.nwalsh.saxon.Table" 5 xmlns:xtbl="com.nwalsh.xalan.Table" 6 xmlns:lxslt="http://xml.apache.org/xslt" 7 exclude-result-prefixes="doc stbl xtbl lxslt" 8 version='1.0'> 9 10<!-- ******************************************************************** 11 $Id$ 12 ******************************************************************** 13 14 This file is part of the XSL DocBook Stylesheet distribution. 15 See /README or http://nwalsh.com/docbook/xsl/ for copyright 16 and other information. 17 18 ******************************************************************** --> 19 20<lxslt:component prefix="xtbl" 21 functions="adjustColumnWidths"/> 22 23<xsl:template match="tgroup"> 24 <table> 25 <xsl:choose> 26 <!-- If there's a <?dbhtml table-summary="foo"?> PI, use it for 27 the HTML table summary attribute --> 28 <xsl:when test="processing-instruction('dbhtml')"> 29 <xsl:variable name="summary"> 30 <xsl:call-template name="dbhtml-attribute"> 31 <xsl:with-param name="pis" 32 select="processing-instruction('dbhtml')[1]"/> 33 <xsl:with-param name="attribute" select="'table-summary'"/> 34 </xsl:call-template> 35 </xsl:variable> 36 <xsl:if test="$summary != ''"> 37 <xsl:attribute name="summary"> 38 <xsl:value-of select="$summary"/> 39 </xsl:attribute> 40 </xsl:if> 41 </xsl:when> 42 <!-- Otherwise, if there's a title, use that --> 43 <xsl:when test="/title"> 44 <xsl:attribute name="summary"> 45 <xsl:value-of select="string(/title)"/> 46 </xsl:attribute> 47 </xsl:when> 48 <!-- Otherwise, forget the whole idea --> 49 <xsl:otherwise><!-- nevermind --></xsl:otherwise> 50 </xsl:choose> 51 52 <xsl:if test="../@pgwide=1"> 53 <xsl:attribute name="width">100%</xsl:attribute> 54 </xsl:if> 55 56<!-- this is wrong, align on tgroup gives the default alignment for table 57 cells, not the alignment for the table itself... 58 <xsl:if test="@align"> 59 <xsl:attribute name="align"> 60 <xsl:value-of select="@align"/> 61 </xsl:attribute> 62 </xsl:if> 63--> 64 65 <xsl:choose> 66 <xsl:when test="../@frame='none'"> 67 <xsl:attribute name="border">0</xsl:attribute> 68 </xsl:when> 69 <xsl:otherwise> 70 <xsl:attribute name="border">1</xsl:attribute> 71 </xsl:otherwise> 72 </xsl:choose> 73 74 <xsl:variable name="vendor" select="system-property('xsl:vendor')"/> 75 76 <xsl:variable name="colgroup"> 77 <colgroup> 78 <xsl:call-template name="generate.colgroup"> 79 <xsl:with-param name="cols" select="@cols"/> 80 </xsl:call-template> 81 </colgroup> 82 </xsl:variable> 83 84 <xsl:variable name="explicit.table.width"> 85 <xsl:call-template name="dbhtml-attribute"> 86 <xsl:with-param name="pis" 87 select="/processing-instruction('dbhtml')[1]"/> 88 <xsl:with-param name="attribute" select="'table-width'"/> 89 </xsl:call-template> 90 </xsl:variable> 91 92 <xsl:variable name="table.width"> 93 <xsl:choose> 94 <xsl:when test="$explicit.table.width != ''"> 95 <xsl:value-of select="$explicit.table.width"/> 96 </xsl:when> 97 <xsl:when test="$default.table.width = ''"> 98 <xsl:text>100%</xsl:text> 99 </xsl:when> 100 <xsl:otherwise> 101 <xsl:value-of select="$default.table.width"/> 102 </xsl:otherwise> 103 </xsl:choose> 104 </xsl:variable> 105 106 <xsl:if test="$default.table.width != '' 107 or $explicit.table.width != ''"> 108 <xsl:attribute name="width"> 109 <xsl:choose> 110 <xsl:when test="contains($table.width, '%')"> 111 <xsl:value-of select="$table.width"/> 112 </xsl:when> 113 <xsl:when test="$use.extensions != 0 114 and $tablecolumns.extension != 0"> 115 <xsl:choose> 116 <xsl:when test="contains($vendor, 'SAXON 6')"> 117 <xsl:value-of select="stbl:convertLength($table.width)"/> 118 </xsl:when> 119 <xsl:when test="contains($vendor, 'SAXON 5')"> 120 <!-- the saxon5 extension doesn't support this (yet) --> 121 <xsl:value-of select="$table.width"/> 122 </xsl:when> 123 <xsl:when test="contains($vendor, 'Apache Software Foundation')"> 124 <xsl:value-of select="xtbl:convertLength($table.width)"/> 125 </xsl:when> 126 <xsl:otherwise> 127 <xsl:message terminate="yes"> 128 <xsl:text>Don't know how to do convert lengths with </xsl:text> 129 <xsl:value-of select="$vendor"/> 130 </xsl:message> 131 </xsl:otherwise> 132 </xsl:choose> 133 </xsl:when> 134 <xsl:otherwise> 135 <xsl:value-of select="$table.width"/> 136 </xsl:otherwise> 137 </xsl:choose> 138 </xsl:attribute> 139 </xsl:if> 140 141 <xsl:choose> 142 <xsl:when test="$use.extensions != 0 143 and $tablecolumns.extension != 0"> 144 <xsl:choose> 145 <xsl:when test="contains($vendor, 'SAXON 6')"> 146 <xsl:copy-of select="stbl:adjustColumnWidths($colgroup)"/> 147 </xsl:when> 148 <xsl:when test="contains($vendor, 'SAXON 5')"> 149 <!-- the saxon5 extension doesn't support this (yet) --> 150 <xsl:copy-of select="$colgroup"/> 151 </xsl:when> 152 <xsl:when test="contains($vendor, 'Apache Software Foundation')"> 153 <xsl:copy-of select="xtbl:adjustColumnWidths($colgroup)"/> 154 </xsl:when> 155 <xsl:otherwise> 156 <xsl:message terminate="yes"> 157 <xsl:text>Don't know how to do adjust column widths with </xsl:text> 158 <xsl:value-of select="$vendor"/> 159 </xsl:message> 160 </xsl:otherwise> 161 </xsl:choose> 162 </xsl:when> 163 <xsl:otherwise> 164 <xsl:copy-of select="$colgroup"/> 165 </xsl:otherwise> 166 </xsl:choose> 167 168 <xsl:apply-templates select="thead"/> 169 <xsl:apply-templates select="tbody"/> 170 <xsl:apply-templates select="tfoot"/> 171 172 <xsl:if test=".//footnote"> 173 <tr> 174 <td colspan="{@cols}"> 175 <xsl:apply-templates select=".//footnote" 176 mode="table.footnote.mode"/> 177 </td> 178 </tr> 179 </xsl:if> 180 </table> 181</xsl:template> 182 183<xsl:template match="tgroup/processing-instruction('dbhtml')"> 184 <xsl:variable name="summary"> 185 <xsl:call-template name="dbhtml-attribute"> 186 <xsl:with-param name="pis" select="."/> 187 <xsl:with-param name="attribute" select="'table-summary'"/> 188 </xsl:call-template> 189 </xsl:variable> 190 191 <!-- Suppress the table-summary PI --> 192 <xsl:if test="$summary = ''"> 193 <xsl:processing-instruction name="dbhtml"> 194 <xsl:value-of select="."/> 195 </xsl:processing-instruction> 196 </xsl:if> 197</xsl:template> 198 199<xsl:template match="colspec"></xsl:template> 200 201<xsl:template match="spanspec"></xsl:template> 202 203<xsl:template match="thead|tfoot"> 204 <xsl:element name="{name(.)}"> 205 <xsl:if test="@align"> 206 <xsl:attribute name="align"> 207 <xsl:value-of select="@align"/> 208 </xsl:attribute> 209 </xsl:if> 210 <xsl:if test="@char"> 211 <xsl:attribute name="char"> 212 <xsl:value-of select="@char"/> 213 </xsl:attribute> 214 </xsl:if> 215 <xsl:if test="@charoff"> 216 <xsl:attribute name="charoff"> 217 <xsl:value-of select="@charoff"/> 218 </xsl:attribute> 219 </xsl:if> 220 <xsl:if test="@valign"> 221 <xsl:attribute name="valign"> 222 <xsl:value-of select="@valign"/> 223 </xsl:attribute> 224 </xsl:if> 225 226 <xsl:apply-templates/> 227 </xsl:element> 228</xsl:template> 229 230<xsl:template match="tbody"> 231 <tbody> 232 <xsl:if test="@align"> 233 <xsl:attribute name="align"> 234 <xsl:value-of select="@align"/> 235 </xsl:attribute> 236 </xsl:if> 237 <xsl:if test="@char"> 238 <xsl:attribute name="char"> 239 <xsl:value-of select="@char"/> 240 </xsl:attribute> 241 </xsl:if> 242 <xsl:if test="@charoff"> 243 <xsl:attribute name="charoff"> 244 <xsl:value-of select="@charoff"/> 245 </xsl:attribute> 246 </xsl:if> 247 <xsl:if test="@valign"> 248 <xsl:attribute name="valign"> 249 <xsl:value-of select="@valign"/> 250 </xsl:attribute> 251 </xsl:if> 252 253 <xsl:apply-templates/> 254 </tbody> 255</xsl:template> 256 257<xsl:template match="row"> 258 <tr> 259 <xsl:if test="@align"> 260 <xsl:attribute name="align"> 261 <xsl:value-of select="@align"/> 262 </xsl:attribute> 263 </xsl:if> 264 <xsl:if test="@char"> 265 <xsl:attribute name="char"> 266 <xsl:value-of select="@char"/> 267 </xsl:attribute> 268 </xsl:if> 269 <xsl:if test="@charoff"> 270 <xsl:attribute name="charoff"> 271 <xsl:value-of select="@charoff"/> 272 </xsl:attribute> 273 </xsl:if> 274 <xsl:if test="@valign"> 275 <xsl:attribute name="valign"> 276 <xsl:value-of select="@valign"/> 277 </xsl:attribute> 278 </xsl:if> 279 280 <xsl:apply-templates/> 281 </tr> 282</xsl:template> 283 284<xsl:template match="thead/row/entry"> 285 <xsl:call-template name="process.cell"> 286 <xsl:with-param name="cellgi">th</xsl:with-param> 287 </xsl:call-template> 288</xsl:template> 289 290<xsl:template match="tbody/row/entry"> 291 <xsl:call-template name="process.cell"> 292 <xsl:with-param name="cellgi">td</xsl:with-param> 293 </xsl:call-template> 294</xsl:template> 295 296<xsl:template match="tfoot/row/entry"> 297 <xsl:call-template name="process.cell"> 298 <xsl:with-param name="cellgi">th</xsl:with-param> 299 </xsl:call-template> 300</xsl:template> 301 302<xsl:template name="process.cell"> 303 <xsl:param name="cellgi">td</xsl:param> 304 <xsl:variable name="empty.cell" select="count(node()) = 0"/> 305 306 <xsl:variable name="entry.colnum"> 307 <xsl:call-template name="entry.colnum"/> 308 </xsl:variable> 309 310 <xsl:if test="$entry.colnum != ''"> 311 <xsl:variable name="prev.entry" select="preceding-sibling::*[1]"/> 312 <xsl:variable name="prev.ending.colnum"> 313 <xsl:choose> 314 <xsl:when test="$prev.entry"> 315 <xsl:call-template name="entry.ending.colnum"> 316 <xsl:with-param name="entry" select="$prev.entry"/> 317 </xsl:call-template> 318 </xsl:when> 319 <xsl:otherwise>0</xsl:otherwise> 320 </xsl:choose> 321 </xsl:variable> 322 323 <!-- 1.31: removed add-empty-entries; there's no practical way for 324 XSLT to keep track of "overhang" from morerows in previous rows. 325 At least none that I can think of. --> 326 </xsl:if> 327 328 <xsl:element name="{$cellgi}"> 329 <xsl:if test="@morerows"> 330 <xsl:attribute name="rowspan"> 331 <xsl:value-of select="@morerows+1"/> 332 </xsl:attribute> 333 </xsl:if> 334 <xsl:if test="@namest"> 335 <xsl:attribute name="colspan"> 336 <xsl:call-template name="calculate.colspan"/> 337 </xsl:attribute> 338 </xsl:if> 339 <xsl:if test="@align"> 340 <xsl:attribute name="align"> 341 <xsl:value-of select="@align"/> 342 </xsl:attribute> 343 </xsl:if> 344 <xsl:if test="@char"> 345 <xsl:attribute name="char"> 346 <xsl:value-of select="@char"/> 347 </xsl:attribute> 348 </xsl:if> 349 <xsl:if test="@charoff"> 350 <xsl:attribute name="charoff"> 351 <xsl:value-of select="@charoff"/> 352 </xsl:attribute> 353 </xsl:if> 354 <xsl:if test="@valign"> 355 <xsl:attribute name="valign"> 356 <xsl:value-of select="@valign"/> 357 </xsl:attribute> 358 </xsl:if> 359 360 <xsl:if test="not(preceding-sibling::*) 361 and ancestor::row/@id"> 362 <a name="{ancestor::row/@id}"/> 363 </xsl:if> 364 365 <xsl:if test="@id"> 366 <a name="{@id}"/> 367 </xsl:if> 368 369 <xsl:choose> 370 <xsl:when test="$empty.cell"> 371 <xsl:text> </xsl:text> 372 </xsl:when> 373 <xsl:otherwise> 374 <xsl:apply-templates/> 375 </xsl:otherwise> 376 </xsl:choose> 377 </xsl:element> 378</xsl:template> 379 380<xsl:template name="entry.colnum"> 381 <xsl:param name="entry" select="."/> 382 383 <xsl:choose> 384 <xsl:when test="$entry/@colname"> 385 <xsl:variable name="colname" select="$entry/@colname"/> 386 <xsl:variable name="colspec" 387 select="$entry/ancestor::tgroup/colspec[@colname=$colname]"/> 388 <xsl:call-template name="colspec.colnum"> 389 <xsl:with-param name="colspec" select="$colspec"/> 390 </xsl:call-template> 391 </xsl:when> 392 <xsl:when test="$entry/@namest"> 393 <xsl:variable name="namest" select="$entry/@namest"/> 394 <xsl:variable name="colspec" 395 select="$entry/ancestor::tgroup/colspec[@colname=$namest]"/> 396 <xsl:call-template name="colspec.colnum"> 397 <xsl:with-param name="colspec" select="$colspec"/> 398 </xsl:call-template> 399 </xsl:when> 400 <xsl:when test="count($entry/preceding-sibling::*) = 0">1</xsl:when> 401 <xsl:otherwise> 402 <xsl:variable name="pcol"> 403 <xsl:call-template name="entry.ending.colnum"> 404 <xsl:with-param name="entry" 405 select="$entry/preceding-sibling::*[1]"/> 406 </xsl:call-template> 407 </xsl:variable> 408 <xsl:value-of select="$pcol + 1"/> 409 </xsl:otherwise> 410 </xsl:choose> 411</xsl:template> 412 413<doc:template name="entry.colnum" xmlns=""> 414<refpurpose>Determine the column number in which a given entry occurs</refpurpose> 415<refdescription> 416<para>If an <sgmltag>entry</sgmltag> has a 417<sgmltag class="attribute">colname</sgmltag> or 418<sgmltag class="attribute">namest</sgmltag> attribute, this template 419will determine the number of the column in which the entry should occur. 420For other <sgmltag>entry</sgmltag>s, nothing is returned.</para> 421</refdescription> 422<refparameter> 423<variablelist> 424<varlistentry><term>entry</term> 425<listitem> 426<para>The <sgmltag>entry</sgmltag>-element which is to be tested.</para> 427</listitem> 428</varlistentry> 429</variablelist> 430</refparameter> 431 432<refreturn> 433<para>This template returns the column number if it can be determined, 434or nothing (the empty string)</para> 435</refreturn> 436</doc:template> 437 438<xsl:template name="entry.ending.colnum"> 439 <xsl:param name="entry" select="."/> 440 441 <xsl:choose> 442 <xsl:when test="$entry/@colname"> 443 <xsl:variable name="colname" select="$entry/@colname"/> 444 <xsl:variable name="colspec" 445 select="$entry/ancestor::tgroup/colspec[@colname=$colname]"/> 446 <xsl:call-template name="colspec.colnum"> 447 <xsl:with-param name="colspec" select="$colspec"/> 448 </xsl:call-template> 449 </xsl:when> 450 <xsl:when test="$entry/@nameend"> 451 <xsl:variable name="nameend" select="$entry/@nameend"/> 452 <xsl:variable name="colspec" 453 select="$entry/ancestor::tgroup/colspec[@colname=$nameend]"/> 454 <xsl:call-template name="colspec.colnum"> 455 <xsl:with-param name="colspec" select="$colspec"/> 456 </xsl:call-template> 457 </xsl:when> 458 <xsl:when test="count($entry/preceding-sibling::*) = 0">1</xsl:when> 459 <xsl:otherwise> 460 <xsl:variable name="pcol"> 461 <xsl:call-template name="entry.ending.colnum"> 462 <xsl:with-param name="entry" 463 select="$entry/preceding-sibling::*[1]"/> 464 </xsl:call-template> 465 </xsl:variable> 466 <xsl:value-of select="$pcol + 1"/> 467 </xsl:otherwise> 468 </xsl:choose> 469</xsl:template> 470 471 472<xsl:template name="colspec.colnum"> 473 <xsl:param name="colspec" select="."/> 474 <xsl:choose> 475 <xsl:when test="$colspec/@colnum"> 476 <xsl:value-of select="$colspec/@colnum"/> 477 </xsl:when> 478 <xsl:when test="$colspec/preceding-sibling::colspec"> 479 <xsl:variable name="prec.colspec.colnum"> 480 <xsl:call-template name="colspec.colnum"> 481 <xsl:with-param name="colspec" 482 select="$colspec/preceding-sibling::colspec[1]"/> 483 </xsl:call-template> 484 </xsl:variable> 485 <xsl:value-of select="$prec.colspec.colnum + 1"/> 486 </xsl:when> 487 <xsl:otherwise>1</xsl:otherwise> 488 </xsl:choose> 489</xsl:template> 490 491<xsl:template name="generate.colgroup"> 492 <xsl:param name="cols" select="1"/> 493 <xsl:param name="count" select="1"/> 494 <xsl:choose> 495 <xsl:when test="$count>$cols"></xsl:when> 496 <xsl:otherwise> 497 <xsl:call-template name="generate.col"> 498 <xsl:with-param name="countcol" select="$count"/> 499 </xsl:call-template> 500 <xsl:call-template name="generate.colgroup"> 501 <xsl:with-param name="cols" select="$cols"/> 502 <xsl:with-param name="count" select="$count+1"/> 503 </xsl:call-template> 504 </xsl:otherwise> 505 </xsl:choose> 506</xsl:template> 507 508<xsl:template name="generate.col"> 509 <xsl:param name="countcol">1</xsl:param> 510 <xsl:param name="colspecs" select="/colspec"/> 511 <xsl:param name="count">1</xsl:param> 512 <xsl:param name="colnum">1</xsl:param> 513 514 <xsl:choose> 515 <xsl:when test="$count>count($colspecs)"> 516 <col/> 517 </xsl:when> 518 <xsl:otherwise> 519 <xsl:variable name="colspec" select="$colspecs[$count=position()]"/> 520 <xsl:variable name="colspec.colnum"> 521 <xsl:choose> 522 <xsl:when test="$colspec/@colnum"> 523 <xsl:value-of select="$colspec/@colnum"/> 524 </xsl:when> 525 <xsl:otherwise> 526 <xsl:value-of select="$colnum"/> 527 </xsl:otherwise> 528 </xsl:choose> 529 </xsl:variable> 530 531 <xsl:choose> 532 <xsl:when test="$colspec.colnum=$countcol"> 533 <col> 534 <xsl:if test="$colspec/@colwidth 535 and $use.extensions != 0 536 and $tablecolumns.extension != 0"> 537 <xsl:attribute name="width"> 538 <xsl:value-of select="$colspec/@colwidth"/> 539 </xsl:attribute> 540 </xsl:if> 541 542 <xsl:choose> 543 <xsl:when test="$colspec/@align"> 544 <xsl:attribute name="align"> 545 <xsl:value-of select="$colspec/@align"/> 546 </xsl:attribute> 547 </xsl:when> 548 <!-- Suggested by Pavel ZAMPACH <zampach@nemcb.cz> --> 549 <xsl:when test="$colspecs/ancestor::tgroup/@align"> 550 <xsl:attribute name="align"> 551 <xsl:value-of select="$colspecs/ancestor::tgroup/@align"/> 552 </xsl:attribute> 553 </xsl:when> 554 </xsl:choose> 555 556 <xsl:if test="$colspec/@char"> 557 <xsl:attribute name="char"> 558 <xsl:value-of select="$colspec/@char"/> 559 </xsl:attribute> 560 </xsl:if> 561 <xsl:if test="$colspec/@charoff"> 562 <xsl:attribute name="charoff"> 563 <xsl:value-of select="$colspec/@charoff"/> 564 </xsl:attribute> 565 </xsl:if> 566 </col> 567 </xsl:when> 568 <xsl:otherwise> 569 <xsl:call-template name="generate.col"> 570 <xsl:with-param name="countcol" select="$countcol"/> 571 <xsl:with-param name="colspecs" select="$colspecs"/> 572 <xsl:with-param name="count" select="$count+1"/> 573 <xsl:with-param name="colnum"> 574 <xsl:choose> 575 <xsl:when test="$colspec/@colnum"> 576 <xsl:value-of select="$colspec/@colnum + 1"/> 577 </xsl:when> 578 <xsl:otherwise> 579 <xsl:value-of select="$colnum + 1"/> 580 </xsl:otherwise> 581 </xsl:choose> 582 </xsl:with-param> 583 </xsl:call-template> 584 </xsl:otherwise> 585 </xsl:choose> 586 </xsl:otherwise> 587 </xsl:choose> 588 589</xsl:template> 590 591<xsl:template name="colspec.colwidth"> 592 <!-- when this macro is called, the current context must be an entry --> 593 <xsl:param name="colname"></xsl:param> 594 <!-- .. = row, ../.. = thead|tbody, ../../.. = tgroup --> 595 <xsl:param name="colspecs" select="/tgroup/colspec"/> 596 <xsl:param name="count">1</xsl:param> 597 <xsl:choose> 598 <xsl:when test="$count>count($colspecs)"></xsl:when> 599 <xsl:otherwise> 600 <xsl:variable name="colspec" select="$colspecs[$count=position()]"/> 601 <xsl:choose> 602 <xsl:when test="$colspec/@colname=$colname"> 603 <xsl:value-of select="$colspec/@colwidth"/> 604 </xsl:when> 605 <xsl:otherwise> 606 <xsl:call-template name="colspec.colwidth"> 607 <xsl:with-param name="colname" select="$colname"/> 608 <xsl:with-param name="colspecs" select="$colspecs"/> 609 <xsl:with-param name="count" select="$count+1"/> 610 </xsl:call-template> 611 </xsl:otherwise> 612 </xsl:choose> 613 </xsl:otherwise> 614 </xsl:choose> 615</xsl:template> 616 617<xsl:template name="calculate.colspan"> 618 <xsl:param name="entry" select="."/> 619 <xsl:variable name="namest" select="$entry/@namest"/> 620 <xsl:variable name="nameend" select="$entry/@nameend"/> 621 622 <xsl:variable name="scol"> 623 <xsl:call-template name="colspec.colnum"> 624 <xsl:with-param name="colspec" 625 select="$entry/ancestor::tgroup/colspec[@colname=$namest]"/> 626 </xsl:call-template> 627 </xsl:variable> 628 <xsl:variable name="ecol"> 629 <xsl:call-template name="colspec.colnum"> 630 <xsl:with-param name="colspec" 631 select="$entry/ancestor::tgroup/colspec[@colname=$nameend]"/> 632 </xsl:call-template> 633 </xsl:variable> 634 <xsl:value-of select="$ecol - $scol + 1"/> 635</xsl:template> 636 637</xsl:stylesheet> 638 639