1<?xml version="1.0" encoding="UTF-8"?>
2<!--***********************************************************
3 *
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements.  See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership.  The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License.  You may obtain a copy of the License at
11 *
12 *   http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied.  See the License for the
18 * specific language governing permissions and limitations
19 * under the License.
20 *
21 ***********************************************************-->
22
23
24<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:w="http://schemas.microsoft.com/office/word/2003/wordml" xmlns:wx="http://schemas.microsoft.com/office/word/2003/auxHint" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:aml="http://schemas.microsoft.com/aml/2001/core" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dom="http://www.w3.org/2001/xml-events" exclude-result-prefixes="office table style text draw svg   dc config xlink meta oooc dom ooo chart math dr3d form script ooow draw">
25    <xsl:key name="table-style" match="style:style[@style:family='table']" use="@style:name"/>
26    <xsl:key name="table-column-style" match="style:style[@style:family='table-column']" use="@style:name"/>
27    <xsl:key name="table-row-style" match="style:style[@style:family='table-row']" use="@style:name"/>
28    <xsl:key name="table-cell-style" match="style:style[@style:family='table-cell']" use="@style:name"/>
29    <xsl:template match="style:table-properties" mode="table">
30        <xsl:param name="within-body"/>
31        <xsl:if test="$within-body = 'yes'">
32            <w:tblW>
33                <xsl:choose>
34                    <xsl:when test="@style:rel-width">
35                        <xsl:attribute name="w:w"><xsl:value-of select="substring-before(@style:rel-width, '%') * 50"/></xsl:attribute>
36                        <xsl:attribute name="w:type">pct</xsl:attribute>
37                    </xsl:when>
38                    <xsl:when test="@style:width">
39                        <xsl:attribute name="w:w"><xsl:call-template name="convert2twip"><xsl:with-param name="value" select="@style:width"/></xsl:call-template></xsl:attribute>
40                        <xsl:attribute name="w:type">dxa</xsl:attribute>
41                    </xsl:when>
42                    <xsl:otherwise>
43                        <xsl:attribute name="w:w">0</xsl:attribute>
44                        <xsl:attribute name="w:type">auto</xsl:attribute>
45                    </xsl:otherwise>
46                </xsl:choose>
47            </w:tblW>
48        </xsl:if>
49        <w:tblInd>
50            <xsl:choose>
51                <xsl:when test="@fo:margin-left">
52                    <xsl:attribute name="w:w"><xsl:call-template name="convert2twip"><xsl:with-param name="value" select="@fo:margin-left"/></xsl:call-template></xsl:attribute>
53                    <xsl:attribute name="w:type">dxa</xsl:attribute>
54                </xsl:when>
55                <xsl:otherwise>
56                    <xsl:attribute name="w:w">0</xsl:attribute>
57                    <xsl:attribute name="w:type">auto</xsl:attribute>
58                </xsl:otherwise>
59            </xsl:choose>
60        </w:tblInd>
61        <xsl:if test="@table:align">
62            <w:jc>
63                <xsl:choose>
64                    <xsl:when test="@table:align = 'left' or @table:align= 'center' or @table:align = 'right'">
65                        <xsl:attribute name="w:val"><xsl:value-of select="@table:align"/></xsl:attribute>
66                    </xsl:when>
67                    <xsl:otherwise>
68                        <xsl:attribute name="w:val">left</xsl:attribute>
69                    </xsl:otherwise>
70                </xsl:choose>
71            </w:jc>
72        </xsl:if>
73    </xsl:template>
74    <xsl:template match="table:table">
75        <!--fix for issue i32030 pagebreak before-->
76        <xsl:if test="key('table-style', @table:style-name)/style:table-properties/@fo:break-before">
77            <xsl:variable name="table-break-before" select="key('table-style', @table:style-name)/style:table-properties/@fo:break-before"/>
78            <xsl:choose>
79                <xsl:when test="$table-break-before = 'page' ">
80                    <w:p>
81                        <w:r>
82                            <w:br w:type="page"/>
83                        </w:r>
84                    </w:p>
85                </xsl:when>
86                <xsl:when test="$table-break-before = 'column' ">
87                    <w:p>
88                        <w:r>
89                            <w:br w:type="column"/>
90                        </w:r>
91                    </w:p>
92                </xsl:when>
93            </xsl:choose>
94        </xsl:if>
95        <w:tbl>
96            <w:tblPr>
97                <xsl:if test="not (@table:is-sub-table) or (@table:is-sub-table = 'false' )">
98                    <w:tblStyle w:val="{@table:style-name}"/>
99                    <xsl:apply-templates select="key('table-style', @table:style-name)/style:table-properties" mode="table">
100                        <xsl:with-param name="within-body" select="'yes'"/>
101                    </xsl:apply-templates>
102                </xsl:if>
103                <xsl:if test="@table:is-sub-table ='true' ">
104                    <w:tblW w:type="dxa">
105                        <xsl:variable name="sub-table-width">
106                            <xsl:call-template name="caculate-sub-table-width">
107                                <xsl:with-param name="sub-table-column-node" select="table:table-column[1]"/>
108                                <xsl:with-param name="total-sub-table-width" select="0"/>
109                            </xsl:call-template>
110                        </xsl:variable>
111                        <xsl:attribute name="w:w"><xsl:value-of select="$sub-table-width"/></xsl:attribute>
112                    </w:tblW>
113                    <!--w:tblLayout w:type="Fixed"/-->
114                </xsl:if>
115            </w:tblPr>
116            <w:tblGrid>
117                <xsl:apply-templates select="table:table-column"/>
118            </w:tblGrid>
119            <xsl:apply-templates select="table:table-header-rows/table:table-row | table:table-row"/>
120        </w:tbl>
121        <!--fix for issue i32030 pagebreak after-->
122        <xsl:if test="key('table-style', @table:style-name)/style:table-properties/@fo:break-after">
123            <xsl:variable name="table-break-after" select="   key('table-style', @table:style-name)/style:table-properties/@fo:break-after"/>
124            <xsl:choose>
125                <xsl:when test="$table-break-after = 'page' ">
126                    <w:p>
127                        <w:r>
128                            <w:br w:type="page"/>
129                        </w:r>
130                    </w:p>
131                </xsl:when>
132                <xsl:when test="$table-break-after = 'column' ">
133                    <w:p>
134                        <w:r>
135                            <w:br w:type="column"/>
136                        </w:r>
137                    </w:p>
138                </xsl:when>
139            </xsl:choose>
140        </xsl:if>
141        <xsl:if test="name(..)= 'table:table-cell' ">
142            <w:p/>
143        </xsl:if>
144    </xsl:template>
145    <xsl:template name="caculate-sub-table-width">
146        <xsl:param name="sub-table-column-node"/>
147        <xsl:param name="total-sub-table-width"/>
148        <xsl:variable name="column-width" select="key('table-column-style', $sub-table-column-node/@table:style-name)/style:table-column-properties/@style:column-width"/>
149        <xsl:variable name="column-width-in-twip">
150            <xsl:call-template name="convert2twip">
151                <xsl:with-param name="value" select="$column-width"/>
152            </xsl:call-template>
153        </xsl:variable>
154        <xsl:choose>
155            <xsl:when test="$sub-table-column-node/following-sibling::table:table-column">
156                <xsl:choose>
157                    <xsl:when test="$sub-table-column-node/@table:number-columns-repeated">
158                        <xsl:call-template name="caculate-sub-table-width">
159                            <xsl:with-param name="sub-table-column-node" select="$sub-table-column-node/following-sibling::table:table-column[ 1]"/>
160                            <xsl:with-param name="total-sub-table-width" select="$total-sub-table-width + $column-width-in-twip *  $sub-table-column-node/@table:number-columns-repeated"/>
161                        </xsl:call-template>
162                    </xsl:when>
163                    <xsl:otherwise>
164                        <xsl:call-template name="caculate-sub-table-width">
165                            <xsl:with-param name="sub-table-column-node" select="$sub-table-column-node/following-sibling::table:table-column[1]"/>
166                            <xsl:with-param name="total-sub-table-width" select="$total-sub-table-width + $column-width-in-twip "/>
167                        </xsl:call-template>
168                    </xsl:otherwise>
169                </xsl:choose>
170            </xsl:when>
171            <xsl:otherwise>
172                <xsl:choose>
173                    <xsl:when test="$sub-table-column-node/@table:number-columns-repeated">
174                        <xsl:value-of select="$total-sub-table-width + $column-width-in-twip *  $sub-table-column-node/@table:number-columns-repeated"/>
175                    </xsl:when>
176                    <xsl:otherwise>
177                        <xsl:value-of select="$total-sub-table-width + $column-width-in-twip "/>
178                    </xsl:otherwise>
179                </xsl:choose>
180            </xsl:otherwise>
181        </xsl:choose>
182    </xsl:template>
183    <xsl:template match="table:table-column">
184        <xsl:variable name="column-width" select="key('table-column-style', @table:style-name)/style:table-column-properties/@style:column-width"/>
185        <xsl:variable name="column-width-in-twip">
186            <xsl:call-template name="convert2twip">
187                <xsl:with-param name="value" select="$column-width"/>
188            </xsl:call-template>
189        </xsl:variable>
190        <xsl:choose>
191            <!-- if table:table-column has attribute table:number-columns-repeated, then call the recursion
192			temple repeat-gridcol to produce multiple w:gridCol in MS word. Gary.Yang   -->
193            <xsl:when test="@table:number-columns-repeated">
194                <xsl:call-template name="repeat-gridcol">
195                    <xsl:with-param name="grid-repeat-count" select="@table:number-columns-repeated"/>
196                    <xsl:with-param name="column-width" select="$column-width-in-twip"/>
197                </xsl:call-template>
198            </xsl:when>
199            <xsl:otherwise>
200                <w:gridCol w:w="{$column-width-in-twip}"/>
201            </xsl:otherwise>
202        </xsl:choose>
203    </xsl:template>
204    <!--recursion template for produce multiple w:gridCol  Gary.Yang-->
205    <xsl:template name="repeat-gridcol">
206        <xsl:param name="grid-repeat-count"/>
207        <xsl:param name="column-width"/>
208        <xsl:if test="$grid-repeat-count &gt; 0">
209            <w:gridCol w:w="{$column-width}"/>
210            <xsl:call-template name="repeat-gridcol">
211                <xsl:with-param name="grid-repeat-count" select="$grid-repeat-count - 1"/>
212                <xsl:with-param name="column-width" select="$column-width"/>
213            </xsl:call-template>
214        </xsl:if>
215    </xsl:template>
216    <xsl:template match="table:table-row">
217        <xsl:element name="w:tr">
218            <xsl:element name="w:trPr">
219                <xsl:if test="parent::table:table-header-rows">
220                    <!-- fix for  Issue 32034-->
221                    <w:tblHeader>on</w:tblHeader>
222                </xsl:if>
223                <xsl:variable name="row-height" select="key('table-row-style', @table:style-name)/style:table-row-properties/@style:row-height"/>
224                <xsl:if test="$row-height">
225                    <w:trHeight>
226                        <xsl:attribute name="w:val"><xsl:call-template name="convert2twip"><xsl:with-param name="value" select="$row-height"/></xsl:call-template></xsl:attribute>
227                    </w:trHeight>
228                </xsl:if>
229            </xsl:element>
230            <!--end of w:trPr-->
231            <xsl:apply-templates select="table:table-cell "/>
232        </xsl:element>
233    </xsl:template>
234    <xsl:template match="table:table-cell ">
235        <xsl:element name="w:tc">
236            <xsl:element name="w:tcPr">
237                <!-- to caclate the table-cell width Gary.Yang -->
238                <xsl:choose>
239                    <!--when the table-cell  contains the sub-table -->
240                    <xsl:when test="table:table/@table:is-sub-table= 'true' ">
241                        <xsl:variable name="table-cell-width">
242                            <xsl:call-template name="caculate-sub-table-width">
243                                <xsl:with-param name="sub-table-column-node" select="table:table/table:table-column[1]"/>
244                                <xsl:with-param name="total-sub-table-width" select="0"/>
245                            </xsl:call-template>
246                        </xsl:variable>
247                        <w:tcW w:type="dxa">
248                            <xsl:attribute name="w:w"><xsl:value-of select="$table-cell-width"/></xsl:attribute>
249                        </w:tcW>
250                    </xsl:when>
251                    <xsl:otherwise>
252                        <!-- when the table-cell doesn't contain the sub-table -->
253                        <xsl:variable name="table-cell-width">
254                            <xsl:call-template name="caculate-table-cell-width">
255                                <xsl:with-param name="table-cell-position" select="position()"/>
256                                <xsl:with-param name="table-column" select="ancestor::table:table[1]/table:table-column[1]"/>
257                            </xsl:call-template>
258                        </xsl:variable>
259                        <w:tcW w:type="dxa">
260                            <xsl:attribute name="w:w"><xsl:value-of select="$table-cell-width"/></xsl:attribute>
261                        </w:tcW>
262                        <!-- for performance issue, we can set w:type to auto that makes the cell width auto fit the content. -->
263                        <!--w:tcW w:w="0" w:type="auto"/-->
264                    </xsl:otherwise>
265                </xsl:choose>
266                <xsl:if test="@table:number-columns-spanned">
267                    <w:gridSpan w:val="{@table:number-columns-spanned}"/>
268                </xsl:if>
269                <xsl:variable name="cell-style-properties" select="key('table-cell-style', @table:style-name)/style:table-cell-properties"/>
270                <xsl:if test="$cell-style-properties/@fo:background-color">
271                    <w:shd w:val="solid" w:color="{substring-after($cell-style-properties/@fo:background-color,'#')}"/>
272                </xsl:if>
273                <xsl:if test="$cell-style-properties/@fo:vertical-align">
274                    <xsl:choose>
275                        <xsl:when test="$cell-style-properties/@fo:vertical-align = 'middle'">
276                            <w:vAlign w:val="center"/>
277                        </xsl:when>
278                        <xsl:when test="$cell-style-properties/@fo:vertical-align = 'Automatic'">
279                            <w:vAlign w:val="both"/>
280                        </xsl:when>
281                        <xsl:otherwise>
282                            <w:vAlign w:val="{$cell-style-properties/@fo:vertical-align}"/>
283                        </xsl:otherwise>
284                    </xsl:choose>
285                </xsl:if>
286                <w:tcMar>
287                    <xsl:if test="$cell-style-properties/@fo:padding-top">
288                        <w:top w:type="dxa">
289                            <xsl:attribute name="w:w"><xsl:call-template name="convert2twip"><xsl:with-param name="value" select="$cell-style-properties/@fo:padding-top"/></xsl:call-template></xsl:attribute>
290                        </w:top>
291                    </xsl:if>
292                    <xsl:if test="$cell-style-properties/@fo:padding-bottom">
293                        <w:bottom w:type="dxa">
294                            <xsl:attribute name="w:w"><xsl:call-template name="convert2twip"><xsl:with-param name="value" select="$cell-style-properties/@fo:padding-bottom"/></xsl:call-template></xsl:attribute>
295                        </w:bottom>
296                    </xsl:if>
297                    <xsl:if test="$cell-style-properties/@fo:padding-left">
298                        <w:left w:type="dxa">
299                            <xsl:attribute name="w:w"><xsl:call-template name="convert2twip"><xsl:with-param name="value" select="$cell-style-properties/@fo:padding-left"/></xsl:call-template></xsl:attribute>
300                        </w:left>
301                    </xsl:if>
302                    <xsl:if test="$cell-style-properties/@fo:padding-right">
303                        <w:right w:type="dxa">
304                            <xsl:attribute name="w:w"><xsl:call-template name="convert2twip"><xsl:with-param name="value" select="$cell-style-properties/@fo:padding-right"/></xsl:call-template></xsl:attribute>
305                        </w:right>
306                    </xsl:if>
307                </w:tcMar>
308                <!-- the following code is to get the cell borders if they exsits Gary.Yang-->
309                <xsl:variable name="border-top" select="$cell-style-properties/@fo:border-top | $cell-style-properties/@fo:border"/>
310                <xsl:variable name="border-bottom" select="$cell-style-properties/@fo:border-bottom | $cell-style-properties/@fo:border"/>
311                <xsl:variable name="border-left" select="$cell-style-properties/@fo:border-left | $cell-style-properties/@fo:border"/>
312                <xsl:variable name="border-right" select="$cell-style-properties/@fo:border-right | $cell-style-properties/@fo:border"/>
313                <xsl:variable name="border-line-width-top" select="$cell-style-properties/@style:border-line-width-top | $cell-style-properties/@style:border-line-width "/>
314                <xsl:variable name="border-line-width-bottom" select="$cell-style-properties/@style:border-line-width-bottom | $cell-style-properties/@style:border-line-width"/>
315                <xsl:variable name="border-line-width-left" select="$cell-style-properties/@style:border-line-width-left | $cell-style-properties/@style:border-line-width"/>
316                <xsl:variable name="border-line-width-right" select="$cell-style-properties/@style:border-line-width-right | $cell-style-properties/@style:border-line-width"/>
317                <xsl:element name="w:tcBorders">
318                    <xsl:if test="$border-top">
319                        <xsl:element name="w:top">
320                            <xsl:call-template name="get-border">
321                                <xsl:with-param name="so-border" select="$border-top"/>
322                                <xsl:with-param name="so-border-line-width" select="$border-line-width-top"/>
323                                <xsl:with-param name="so-border-position" select=" 'top' "/>
324                            </xsl:call-template>
325                        </xsl:element>
326                    </xsl:if>
327                    <xsl:if test="$border-bottom">
328                        <xsl:element name="w:bottom">
329                            <xsl:call-template name="get-border">
330                                <xsl:with-param name="so-border" select="$border-bottom"/>
331                                <xsl:with-param name="so-border-line-width" select="$border-line-width-bottom"/>
332                                <xsl:with-param name="so-border-position" select=" 'bottom' "/>
333                            </xsl:call-template>
334                        </xsl:element>
335                    </xsl:if>
336                    <xsl:if test="$border-left">
337                        <xsl:element name="w:left">
338                            <xsl:call-template name="get-border">
339                                <xsl:with-param name="so-border" select="$border-left"/>
340                                <xsl:with-param name="so-border-line-width" select="$border-line-width-left"/>
341                                <xsl:with-param name="so-border-position" select=" 'left' "/>
342                            </xsl:call-template>
343                        </xsl:element>
344                    </xsl:if>
345                    <xsl:if test="$border-right">
346                        <xsl:element name="w:right">
347                            <xsl:call-template name="get-border">
348                                <xsl:with-param name="so-border" select="$border-right"/>
349                                <xsl:with-param name="so-border-line-width" select="$border-line-width-right"/>
350                                <xsl:with-param name="so-border-position" select=" 'right' "/>
351                            </xsl:call-template>
352                        </xsl:element>
353                    </xsl:if>
354                </xsl:element>
355            </xsl:element>
356            <xsl:if test="not (*) ">
357                <w:p/>
358            </xsl:if>
359            <xsl:apply-templates select=" text:p | table:table | text:h | office:annotation"/>
360        </xsl:element>
361    </xsl:template>
362    <xsl:template name="caculate-table-cell-width">
363        <xsl:param name="table-cell-position"/>
364        <xsl:param name="table-column"/>
365        <xsl:choose>
366            <xsl:when test="$table-column/@table:number-columns-repeated">
367                <xsl:choose>
368                    <xsl:when test="($table-cell-position - $table-column/@table:number-columns-repeated) &lt;= 0">
369                        <xsl:variable name="table-cell-width" select="key('table-column-style', $table-column/@table:style-name)/style:table-column-properties/@style:column-width"/>
370                        <xsl:variable name="table-cell-width-in-twip">
371                            <xsl:call-template name="convert2twip">
372                                <xsl:with-param name="value" select="$table-cell-width"/>
373                            </xsl:call-template>
374                        </xsl:variable>
375                        <xsl:value-of select="$table-cell-width-in-twip"/>
376                    </xsl:when>
377                    <xsl:otherwise>
378                        <xsl:call-template name="caculate-table-cell-width">
379                            <xsl:with-param name="table-cell-position" select="$table-cell-position - $table-column/@table:number-columns-repeated"/>
380                            <xsl:with-param name="table-column" select="$table-column/following-sibling::table:table-column[1]"/>
381                        </xsl:call-template>
382                    </xsl:otherwise>
383                </xsl:choose>
384            </xsl:when>
385            <xsl:otherwise>
386                <!-- if the $table-column doesn't contain the table:number-columns-repeated attribute -->
387                <xsl:choose>
388                    <xsl:when test="($table-cell-position - 1) = 0">
389                        <xsl:variable name="table-cell-width" select="key('table-column-style', $table-column/@table:style-name)/style:table-column-properties/@style:column-width"/>
390                        <xsl:variable name="table-cell-width-in-twip">
391                            <xsl:call-template name="convert2twip">
392                                <xsl:with-param name="value" select="$table-cell-width"/>
393                            </xsl:call-template>
394                        </xsl:variable>
395                        <xsl:value-of select="$table-cell-width-in-twip"/>
396                    </xsl:when>
397                    <xsl:when test="($table-cell-position - 1) &gt; 0">
398                        <xsl:call-template name="caculate-table-cell-width">
399                            <xsl:with-param name="table-cell-position" select=" $table-cell-position - 1 "/>
400                            <xsl:with-param name="table-column" select="$table-column/following-sibling::table:table-column[1]"/>
401                        </xsl:call-template>
402                    </xsl:when>
403                    <xsl:otherwise>
404                        <xsl:message>
405                            <xsl:value-of select=" 'caculate table cell width wrong ' "/>
406                        </xsl:message>
407                    </xsl:otherwise>
408                </xsl:choose>
409            </xsl:otherwise>
410        </xsl:choose>
411    </xsl:template>
412</xsl:stylesheet>
413