<!---->
<
xsl:
stylesheet xmlns:xsl="
http://www.w3.org/1999/XSL/Transform"
xmlns:tps="
http://www.typefi.com/ContentXML"
xmlns:xlink="
http://www.w3.org/1999/xlink"
xmlns:xs="
http://www.w3.org/2001/XMLSchema"
xmlns:xd="
http://www.pnp-software.com/XSLTdoc"
version="
2.0"
exclude-result-prefixes="
xs xlink">
<
xd:
doc type="
stylesheet">
<
xd:
short>
Converts XHTML tables to Cals table
</
xd:
short>
<
xd:
cvsId>
$Revision$</
xd:
cvsId>
</
xd:
doc>
<
xsl:
template match="
table"
mode="
xhtml-to-cals">
<!---->
<
xsl:
variable name="
expanded-spans-table">
<
xsl:
call-template name="
expand-spans" />
</
xsl:
variable>
<
xsl:
apply-templates select="
$expanded-spans-table"
mode="
convert-to-cals" />
</
xsl:
template>
<
xsl:
template name="
expand-spans">
<
xsl:
apply-templates select="
."
mode="
expand-spans" />
</
xsl:
template>
<
xsl:
template match="
table"
mode="
convert-to-cals">
<
table>
<
xsl:
apply-templates select="
(@border, @width)"
mode="
convert-to-cals" />
<!---->
<
tgroup cols="
{count(col | colgroup/col)}">
<
xsl:
call-template name="
create-table-cals-content" />
</
tgroup>
</
table>
</
xsl:
template>
<
xsl:
template match="
table/@*"
mode="
convert-to-cals">
<
xsl:
copy />
</
xsl:
template>
<
xsl:
template name="
create-table-cals-content">
<
xsl:
apply-templates mode="
convert-to-cals" />
</
xsl:
template>
<!---->
<!---->
<!---->
<
xsl:
template match="
col"
mode="
convert-to-cals">
<
xsl:
variable name="
total-width"
select="
sum((., parent::colgroup)/../(., colgroup)/col/@width)"
as="
xs:double" />
<
xsl:
variable name="
percentage"
select="
round(@width div $total-width*100*100) div 100"
as="
xs:double" />
<
xsl:
variable name="
proportional-width"
select="
concat($percentage, '%')"
as="
xs:string" />
<
xsl:
call-template name="
create-colspec">
<
xsl:
with-param name="
colwidth"
select="
if (tps:is-relative-width(@width)) then @width else $proportional-width" />
</
xsl:
call-template>
</
xsl:
template>
<
xsl:
function name="
tps:is-relative-width"
as="
xs:boolean">
<
xsl:
param name="
width"
as="
attribute(width)" />
<
xsl:
sequence select="
matches($width, '[%\*]$')" />
</
xsl:
function>
<
xsl:
template name="
create-colspec">
<
xsl:
param name="
colwidth"
as="
xs:string" />
<
xsl:
variable name="
col-position">
<
xsl:
number count="
col"
level="
any"
from="
table" />
</
xsl:
variable>
<
colspec>
<
xsl:
attribute name="
colnum"
select="
$col-position" />
<
xsl:
attribute name="
colname"
select="
concat('col', $col-position)" />
<
xsl:
attribute name="
colwidth"
select="
$colwidth" />
</
colspec>
</
xsl:
template>
<!---->
<!---->
<!---->
<
xsl:
template match="
thead"
mode="
convert-to-cals">
<
thead>
<
xsl:
apply-templates mode="
convert-to-cals" />
</
thead>
</
xsl:
template>
<
xsl:
template match="
tbody"
mode="
convert-to-cals">
<
tbody>
<
xsl:
apply-templates mode="
convert-to-cals" />
</
tbody>
</
xsl:
template>
<
xsl:
template match="
tfoot"
mode="
convert-to-cals">
<
tfoot>
<
xsl:
apply-templates mode="
convert-to-cals" />
</
tfoot>
</
xsl:
template>
<
xsl:
template match="
tr"
mode="
convert-to-cals">
<
row>
<
xsl:
apply-templates mode="
convert-to-cals" />
</
row>
</
xsl:
template>
<!---->
<!---->
<!---->
<
xsl:
template match="
th[@style] | td[@style]"
mode="
convert-to-cals">
<
xsl:
processing-instruction name="
style"
select="
@style" />
<
xsl:
next-match />
</
xsl:
template>
<
xsl:
template match="
td | th"
mode="
convert-to-cals">
<
xsl:
variable name="
preceding-cells-count"
select="
count(preceding-sibling::*)" />
<
entry>
<
xsl:
apply-templates select="
@valign | @align | @rowspan | @char"
mode="
convert-to-cals" />
<
xsl:
attribute name="
namest"
select="
$preceding-cells-count + 1" />
<
xsl:
attribute name="
nameend"
select="
$preceding-cells-count + (@xcolspan, 1)[1]" />
<
xsl:
apply-templates select="
."
mode="
pre-processing" />
</
entry>
</
xsl:
template>
<
xsl:
template match="
tr/processing-instruction()"
mode="
convert-to-cals">
<
xsl:
copy-of select="
." />
</
xsl:
template>
<
xsl:
template match="
@valign | @align | @char"
mode="
convert-to-cals">
<
xsl:
copy-of select="
." />
</
xsl:
template>
<
xsl:
template match="
@rowspan"
mode="
convert-to-cals">
<
xsl:
attribute name="
morerows"
select="
number(.) - 1" />
</
xsl:
template>
<!---->
<!---->
<!---->
<
xsl:
template match="
td[(@spanCellCol, @spanCellRow) = 'yes']"
mode="
convert-to-cals"
priority="
10" />
<
xsl:
template match="
th[(@spanCellCol, @spanCellRow) = 'yes']"
mode="
convert-to-cals"
priority="
10" />
<!---->
<!---->
<!---->
<
xsl:
template match="
node() | @*"
mode="
expand-spans">
<
xsl:
copy copy-namespaces="
no">
<
xsl:
apply-templates select="
@* | node()"
mode="
#current" />
</
xsl:
copy>
</
xsl:
template>
<!---->
<!---->
<!---->
<
xsl:
template match="
thead|tbody|tfoot"
mode="
expand-spans">
<
xsl:
element name="
{local-name(.)}"
inherit-namespaces="
no">
<
xsl:
copy-of select="
@*"
copy-namespaces="
no" />
<
xsl:
call-template name="
process-block">
<
xsl:
with-param name="
source-rows"
select="
self::*" />
<
xsl:
with-param name="
col-count"
select="
count(../col)"
tunnel="
yes" />
</
xsl:
call-template>
</
xsl:
element>
</
xsl:
template>
<!---->
<!---->
<!---->
<
xsl:
template name="
process-block">
<!---->
<
xsl:
param name="
source-rows"
as="
element()+" />
<!---->
<
xsl:
param name="
processed-row"
as="
document-node()*" />
<!---->
<
xsl:
param name="
row-count"
as="
xs:integer">
1</
xsl:
param>
<
xsl:
param name="
col-count"
as="
xs:integer?"
tunnel="
yes" />
<
xsl:
choose>
<
xsl:
when test="
count($source-rows/tr) < $row-count">
<!---->
</
xsl:
when>
<
xsl:
when test="
count($processed-row/node())=0">
<!---->
<
xsl:
variable name="
expanded"
as="
element()">
<
xsl:
element name="
tr"
inherit-namespaces="
no">
<
xsl:
copy-of select="
tps:expand-col-spans($source-rows/tr[1])" />
</
xsl:
element>
</
xsl:
variable>
<
xsl:
variable name="
first-row"
as="
document-node()">
<
xsl:
copy-of select="
tps:create-supplementary-cells($expanded, $col-count)" />
</
xsl:
variable>
<
xsl:
copy-of select="
$first-row" />
<
xsl:
call-template name="
process-block">
<
xsl:
with-param name="
source-rows"
select="
$source-rows" />
<
xsl:
with-param name="
processed-row"
select="
$first-row" />
<
xsl:
with-param name="
row-count">
2</
xsl:
with-param>
</
xsl:
call-template>
</
xsl:
when>
<
xsl:
otherwise>
<!---->
<
xsl:
variable name="
row">
<
xsl:
copy-of select="
tps:expand-table-row($source-rows, $processed-row, $row-count, $col-count)" />
</
xsl:
variable>
<
xsl:
copy-of select="
$row" />
<
xsl:
call-template name="
process-block">
<
xsl:
with-param name="
source-rows"
select="
$source-rows" />
<
xsl:
with-param name="
processed-row"
select="
$row" />
<
xsl:
with-param name="
row-count"
select="
$row-count+1" />
</
xsl:
call-template>
</
xsl:
otherwise>
</
xsl:
choose>
</
xsl:
template>
<!---->
<!---->
<!---->
<!---->
<
xsl:
function name="
tps:expand-table-row"
as="
item()+">
<!---->
<
xsl:
param name="
table-block"
as="
element()+" />
<!---->
<
xsl:
param name="
expanding-row"
as="
document-node()+" />
<!---->
<
xsl:
param name="
row"
as="
xs:integer" />
<
xsl:
param name="
col-count"
as="
xs:integer?" />
<!---->
<
xsl:
variable name="
expanded"
as="
element()">
<
xsl:
element name="
tr"
inherit-namespaces="
no">
<
xsl:
variable name="
current-row"
select="
$table-block/tr[$row]"
as="
element()" />
<
xsl:
copy-of select="
tps:expand-row-spans($current-row, $expanding-row/node())" />
</
xsl:
element>
</
xsl:
variable>
<
xsl:
variable name="
next-row"
select="
tps:create-supplementary-cells($expanded, $col-count)"
as="
document-node()" />
<!---->
<
xsl:
variable name="
next-row-expanded">
<
xsl:
element name="
tr"
inherit-namespaces="
no">
<
xsl:
copy-of select="
tps:expand-col-spans($next-row/node())" />
</
xsl:
element>
</
xsl:
variable>
<
xsl:
copy-of select="
$next-row-expanded" />
</
xsl:
function>
<!---->
<!---->
<!---->
<!---->
<
xsl:
function name="
tps:expand-col-spans"
as="
item()+">
<!---->
<
xsl:
param name="
source-row"
as="
element()+" />
<
xsl:
variable name="
expand-columns">
<
xsl:
for-each select="
$source-row/*">
<
xsl:
variable name="
element-name"
select="
local-name()" />
<
xsl:
variable name="
current-cell"
select="
self::node()" />
<
xsl:
element name="
{$element-name}"
inherit-namespaces="
no">
<
xsl:
copy-of select="
$current-cell/@*[not(name()='colspan')]"
copy-namespaces="
no" />
<
xsl:
variable name="
colspan"
select="
$current-cell/@colspan" />
<
xsl:
if test="
$colspan">
<
xsl:
attribute name="
xcolspan"
select="
$colspan" />
</
xsl:
if>
<
xsl:
copy-of select="
$current-cell/child::node()"
copy-namespaces="
no" />
</
xsl:
element>
<!---->
<
xsl:
for-each select="
2 to (xs:integer(@colspan))">
<
xsl:
element name="
{$element-name}"
inherit-namespaces="
no">
<
xsl:
attribute name="
spanCellCol">
yes</
xsl:
attribute>
<
xsl:
copy-of select="
$current-cell/@*[not(name()='colspan')]"
copy-namespaces="
no" />
<
xsl:
comment>
<
xsl:
copy-of select="
$current-cell/child::node()"
copy-namespaces="
no" />
</
xsl:
comment>
</
xsl:
element>
</
xsl:
for-each>
</
xsl:
for-each>
</
xsl:
variable>
<
xsl:
copy-of select="
$source-row/processing-instruction()" />
<
xsl:
copy-of select="
$expand-columns" />
</
xsl:
function>
<!---->
<!---->
<!---->
<!---->
<
xsl:
function name="
tps:expand-row-spans"
as="
item()+">
<
xsl:
param name="
source-rows"
as="
element()+" />
<!---->
<
xsl:
param name="
modified-row"
as="
element()+" />
<!---->
<
xsl:
for-each select="
$modified-row/*">
<
xsl:
choose>
<!---->
<
xsl:
when test="
@rowspan > 1">
<
xsl:
element name="
{local-name()}">
<
xsl:
attribute name="
spanCellRow">
yes</
xsl:
attribute>
<
xsl:
copy-of select="
@*[not(name()='rowspan')]"
copy-namespaces="
no" />
<
xsl:
attribute name="
rowspan"
select="
number(@rowspan)-1" />
<
xsl:
comment>
<
xsl:
copy-of select="
child::node()" />
</
xsl:
comment>
</
xsl:
element>
</
xsl:
when>
<!---->
<
xsl:
otherwise>
<
xsl:
variable name="
current-column"
select="
count(preceding-sibling::*)+1" />
<
xsl:
variable name="
spanned-row-cells"
select="
count(preceding-sibling::*[@rowspan > 1])" />
<
xsl:
copy-of select="
$source-rows/processing-instruction()" />
<
xsl:
copy-of select="
tps:select-cell($current-column - $spanned-row-cells,$source-rows,1,0)"
copy-namespaces="
no" />
</
xsl:
otherwise>
</
xsl:
choose>
</
xsl:
for-each>
</
xsl:
function>
<
xsl:
function name="
tps:create-supplementary-cells"
as="
document-node()">
<
xsl:
param name="
row"
as="
element()" />
<
xsl:
param name="
col-count"
as="
xs:integer?" />
<
xsl:
document>
<
xsl:
for-each select="
$row">
<
xsl:
copy>
<
xsl:
copy-of select="
@*, processing-instruction(), *" />
<
xsl:
for-each select="
sum(for $c in * return (xs:integer($c/@colspan), 1)[1]) + 1 to $col-count">
<
td spanCellCol="
supplemented" />
</
xsl:
for-each>
</
xsl:
copy>
</
xsl:
for-each>
</
xsl:
document>
</
xsl:
function>
<
xsl:
function name="
tps:select-cell">
<!---->
<
xsl:
param name="
src-column-no"
as="
xs:integer" />
<!---->
<
xsl:
param name="
row"
as="
element()+" />
<!---->
<
xsl:
param name="
current-column-count"
as="
xs:integer" />
<!---->
<
xsl:
param name="
current-span-col-total"
as="
xs:double" />
<!---->
<
xsl:
variable name="
current-span">
<
xsl:
choose>
<
xsl:
when test="
$row/*[$current-column-count]/@colspan">
<
xsl:
value-of select="
$row/*[$current-column-count]/@colspan" />
</
xsl:
when>
<
xsl:
otherwise>
1</
xsl:
otherwise>
</
xsl:
choose>
</
xsl:
variable>
<
xsl:
choose>
<!---->
<
xsl:
when test="
$src-column-no=$current-span-col-total+$current-span">
<
xsl:
copy-of select="
$row/*[$current-column-count]"
copy-namespaces="
no" />
</
xsl:
when>
<!---->
<
xsl:
when test="
$src-column-no < $current-span-col-total+$current-span">
<!---->
</
xsl:
when>
<!---->
<
xsl:
when test="
$src-column-no > $current-span-col-total+$current-span">
<
xsl:
copy-of select="
tps:select-cell($src-column-no,$row,$current-column-count+1, $current-span+ $current-span-col-total)"
copy-namespaces="
no" />
</
xsl:
when>
<
xsl:
otherwise>
<
xsl:
message terminate="
no">
Error in table conversion. Please contact Typéfi Support</
xsl:
message>
</
xsl:
otherwise>
</
xsl:
choose>
</
xsl:
function>
</
xsl:
stylesheet>
v