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<!--
25	For further documentation and updates visit http://xml.openoffice.org/odf2xhtml
26-->
27<xsl:stylesheet version="1.0"
28		xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
29		xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0"
30		xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0"
31		xmlns:dc="http://purl.org/dc/elements/1.1/"
32		xmlns:dom="http://www.w3.org/2001/xml-events"
33		xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0"
34		xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0"
35		xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0"
36		xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0"
37		xmlns:math="http://www.w3.org/1998/Math/MathML"
38		xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0"
39		xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0"
40		xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"
41		xmlns:ooo="http://openoffice.org/2004/office"
42		xmlns:oooc="http://openoffice.org/2004/calc"
43		xmlns:ooow="http://openoffice.org/2004/writer"
44		xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0"
45		xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0"
46		xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0"
47		xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0"
48		xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0"
49		xmlns:xforms="http://www.w3.org/2002/xforms"
50		xmlns:xlink="http://www.w3.org/1999/xlink"
51		xmlns:xsd="http://www.w3.org/2001/XMLSchema"
52		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
53		xmlns:xt="http://www.jclark.com/xt"
54		xmlns:common="http://exslt.org/common"
55		xmlns:xalan="http://xml.apache.org/xalan"
56		exclude-result-prefixes="chart config dc dom dr3d draw fo form math meta number office ooo oooc ooow script style svg table text xforms xlink xsd xsi xt common xalan">
57
58
59
60	<!-- ***************************************** -->
61	<!-- *** Gathering office style properties *** -->
62	<!-- ***************************************** -->
63
64	<!-- REASON FOR STYLESHEET:
65			In the OpenOffice documents styles are represented by a hierarchy.
66			(e.g. most styles are inherited from a default style).
67			Many other languages (as XHTML/CSS) do not support inherited styles.
68			The style inheritance have to be made flat/absolute for each style.
69
70			A further reason was, that the earlier style collection mechanism
71			had problems with CSS inline, which do not inherit from XML office defaults
72			nor font:family defaults as the style header does
73			(cp. stylesheet 'style_collector.xsl' and the 'write-default-styles' template)
74
75		 RESULT OF STYLESHEET:
76			All styles will be returned in a variable containing styles with their inherited *:
77
78				<all-styles>
79					<style style:family="foo" style:name="x1">
80						<* fo:padding-left="0cm" fo:margin-right="0cm" />
81					</style>
82					<style style:family="muh" style:name="x2" >
83						<* fo:padding-left="3cm" ...                  />
84					</style>
85					...
86
87				</all-styles>
88	-->
89
90
91	<xsl:template name="collect-global-odf-properties">
92		<!-- to access the variable as a node-set by XPATH expressions, it is necessary to convert it
93			 from a result-tree-fragment (RTF) to a node set by a in a XSLT 1.0 non standarized function -->
94		<xsl:variable name="globalDataRTF">
95			<xsl:call-template name="collect-document-links-RTF" />
96		</xsl:variable>
97
98		<xsl:choose>
99			<xsl:when test="function-available('common:node-set')">
100				<xsl:call-template name="collect-style-properties">
101					<xsl:with-param name="globalData" select="common:node-set($globalDataRTF)" />
102				</xsl:call-template>
103			</xsl:when>
104			<xsl:when test="function-available('xalan:nodeset')">
105				<xsl:call-template name="collect-style-properties">
106					<xsl:with-param name="globalData" select="xalan:nodeset($globalDataRTF)" />
107				</xsl:call-template>
108			</xsl:when>
109			<xsl:when test="function-available('xt:node-set')">
110				<xsl:call-template name="collect-style-properties">
111					<xsl:with-param name="globalData" select="xt:node-set($globalDataRTF)" />
112				</xsl:call-template>
113			</xsl:when>
114			<xsl:otherwise>
115				<xsl:message terminate="yes">The required node-set function was not found!</xsl:message>
116			</xsl:otherwise>
117		</xsl:choose>
118	</xsl:template>
119
120
121
122	<xsl:template name="collect-style-properties">
123		<xsl:param name="globalData" />
124
125		<!-- Add the input file references to the new collected style properties -->
126		<xsl:variable name="globalDataRTF">
127			<xsl:copy-of select="$globalData" />
128			<xsl:call-template name="collect-style-properties-RTF">
129				<xsl:with-param name="globalData" select="$globalData" />
130			</xsl:call-template>
131		</xsl:variable>
132
133		<xsl:choose>
134			<xsl:when test="function-available('common:node-set')">
135				<xsl:call-template name="map-odf-style-properties">
136					<xsl:with-param name="globalData" select="common:node-set($globalDataRTF)" />
137				</xsl:call-template>
138			</xsl:when>
139			<xsl:when test="function-available('xalan:nodeset')">
140				<xsl:call-template name="map-odf-style-properties">
141					<xsl:with-param name="globalData" select="xalan:nodeset($globalDataRTF)" />
142				</xsl:call-template>
143			</xsl:when>
144			<xsl:when test="function-available('xt:node-set')">
145				<xsl:call-template name="map-odf-style-properties">
146					<xsl:with-param name="globalData" select="xt:node-set($globalDataRTF)" />
147				</xsl:call-template>
148			</xsl:when>
149			<xsl:otherwise>
150				<xsl:message terminate="yes">The required node-set function was not found!</xsl:message>
151			</xsl:otherwise>
152		</xsl:choose>
153	</xsl:template>
154
155
156	<xsl:template name="collect-document-links-RTF">
157		<!-- works for zipped office files, unzipped office files as for flat filter single office file format as well -->
158		<xsl:variable name="documentLinksRTF">
159			<xsl:choose>
160				<xsl:when test="office:document-content">
161					<xsl:element name="styles-file" namespace="">
162						<xsl:copy-of select="document(concat($sourceBaseURL, 'styles.xml'), .)" />
163					</xsl:element>
164					<xsl:element name="meta-file" namespace="">
165						<xsl:copy-of select="document(concat($sourceBaseURL, 'meta.xml'), .)" />
166					</xsl:element>
167				</xsl:when>
168				<xsl:otherwise>
169					<xsl:element name="styles-file" namespace="">
170						<xsl:copy-of select="/" />
171					</xsl:element>
172					<xsl:element name="meta-file" namespace="">
173						<xsl:copy-of select="/" />
174					</xsl:element>
175				</xsl:otherwise>
176			</xsl:choose>
177		</xsl:variable>
178
179		<xsl:choose>
180			<xsl:when test="function-available('common:node-set')">
181				<xsl:call-template name="collect-document-links">
182					<xsl:with-param name="documentLinks" select="common:node-set($documentLinksRTF)" />
183				</xsl:call-template>
184			</xsl:when>
185			<xsl:when test="function-available('xalan:nodeset')">
186				<xsl:call-template name="collect-document-links">
187					<xsl:with-param name="documentLinks" select="xalan:nodeset($documentLinksRTF)" />
188				</xsl:call-template>
189			</xsl:when>
190			<xsl:when test="function-available('xt:node-set')">
191				<xsl:call-template name="collect-document-links">
192					<xsl:with-param name="documentLinks" select="xt:node-set($documentLinksRTF)" />
193				</xsl:call-template>
194			</xsl:when>
195			<xsl:otherwise>
196				<xsl:message terminate="yes">The required node-set function was not found!</xsl:message>
197			</xsl:otherwise>
198		</xsl:choose>
199
200	</xsl:template>
201
202
203	<xsl:template name="collect-document-links">
204		<xsl:param name="documentLinks" />
205
206		<xsl:element name="styles-file" namespace="">
207			<xsl:copy-of select="$documentLinks/styles-file/*" />
208		</xsl:element>
209
210		<xsl:element name="meta-file" namespace="">
211			<xsl:copy-of select="$documentLinks/meta-file/*" />
212		</xsl:element>
213
214		<xsl:copy-of select="$documentLinks/styles-file/*/office:styles" />
215		<xsl:copy-of select="$documentLinks/styles-file/*/office:font-face-decls" />
216
217		<!-- office:automatic-styles may be containted in two files (i.e. content.xml and styles.xml).
218			 Wild card necessary as top level element differs from flat office files ("SampleName.fsxw") -->
219		<xsl:copy-of select="/*/office:automatic-styles" />
220
221	</xsl:template>
222
223
224	<xsl:template name="collect-style-properties-RTF">
225		<xsl:param name="globalData" />
226
227	   <!--** DEFAULT STYLES: First adding some office defaults unwritten in XML -->
228		<xsl:variable name="defaultOfficeStyle-RTF">
229			<xsl:element name="style" namespace="">
230				<xsl:element name="style:properties" />
231			</xsl:element>
232		</xsl:variable>
233
234		<xsl:choose>
235			<xsl:when test="function-available('common:node-set')">
236				<xsl:call-template name="collect-properties-defaults">
237					<xsl:with-param name="globalData" select="$globalData" />
238					<xsl:with-param name="defaultOfficeStyle" select="common:node-set($defaultOfficeStyle-RTF)" />
239				</xsl:call-template>
240			</xsl:when>
241			<xsl:when test="function-available('xalan:nodeset')">
242				<xsl:call-template name="collect-properties-defaults">
243					<xsl:with-param name="globalData" select="$globalData" />
244					<xsl:with-param name="defaultOfficeStyle" select="xalan:nodeset($defaultOfficeStyle-RTF)" />
245				</xsl:call-template>
246			</xsl:when>
247			<xsl:when test="function-available('xt:node-set')">
248				<xsl:call-template name="collect-properties-defaults">
249					<xsl:with-param name="globalData" select="$globalData" />
250					<xsl:with-param name="defaultOfficeStyle" select="xt:node-set($defaultOfficeStyle-RTF)" />
251				</xsl:call-template>
252			</xsl:when>
253			<xsl:otherwise>
254				<xsl:message terminate="yes">ERROR: Function not found: 'Nodeset'</xsl:message>
255			</xsl:otherwise>
256		</xsl:choose>
257	</xsl:template>
258
259
260	<xsl:template name="collect-properties-defaults">
261		<xsl:param name="globalData" />
262		<xsl:param name="defaultOfficeStyle" />
263
264		<!--** DEFAULT STYLES: Adding the default styles of a style:family, by adding each office:styles/style:default-style element **-->
265		<xsl:variable name="defaultFamilyStyles-RTF">
266			<xsl:for-each select="$globalData/office:styles/style:default-style">
267				<xsl:element name="style" namespace="">
268					<xsl:copy-of select="@style:family" />
269					<xsl:call-template name="create-inherited-style-properties">
270						<xsl:with-param name="inheritedStyleProperties" select="$defaultOfficeStyle/style/*" />
271					</xsl:call-template>
272				</xsl:element>
273			</xsl:for-each>
274		</xsl:variable>
275
276		<xsl:choose>
277			<xsl:when test="function-available('common:node-set')">
278				<xsl:call-template name="collect-properties">
279					<xsl:with-param name="globalData" select="$globalData" />
280					<xsl:with-param name="defaultOfficeStyle" select="$defaultOfficeStyle" />
281					<xsl:with-param name="defaultFamilyStyles" select="common:node-set($defaultFamilyStyles-RTF)" />
282				</xsl:call-template>
283			</xsl:when>
284			<xsl:when test="function-available('xalan:nodeset')">
285				<xsl:call-template name="collect-properties">
286					<xsl:with-param name="globalData" select="$globalData" />
287					<xsl:with-param name="defaultOfficeStyle" select="$defaultOfficeStyle" />
288					<xsl:with-param name="defaultFamilyStyles" select="xalan:nodeset($defaultFamilyStyles-RTF)" />
289				</xsl:call-template>
290			</xsl:when>
291			<xsl:when test="function-available('xt:node-set')">
292				<xsl:call-template name="collect-properties">
293					<xsl:with-param name="globalData" select="$globalData" />
294					<xsl:with-param name="defaultOfficeStyle" select="$defaultOfficeStyle" />
295					<xsl:with-param name="defaultFamilyStyles" select="xt:node-set($defaultFamilyStyles-RTF)" />
296				</xsl:call-template>
297			</xsl:when>
298			<xsl:otherwise>
299				<xsl:message terminate="yes">ERROR: Function not found: nodeset</xsl:message>
300			</xsl:otherwise>
301		</xsl:choose>
302	</xsl:template>
303
304
305	<xsl:template name="collect-properties">
306		<xsl:param name="globalData" />
307		<xsl:param name="defaultOfficeStyle" />
308		<xsl:param name="defaultFamilyStyles" />
309
310	   <!--** traversee all style trees - branch after branch - collecting style properties **-->
311		<xsl:element name="all-doc-styles" namespace="">
312
313	   <!-- Background Information:
314
315		   There are two different types of styles in the Office:
316			   1) The office:styles from the user pre-defined style templates
317			   2) The automatic:styles, which are created whenever a user uses explicit style formatting.
318
319		   The office:styles only have parent styles in the office:styles,
320		   but automatic:styles may inherit from both office:styles and themself.
321		-->
322
323		   <!--** traversee all office:styles trees beginning with the top-level styles **-->
324			<xsl:for-each select="$globalData/office:styles/style:style[not(@style:parent-style-name)]">
325			   <!-- Looking for parents from style:family
326			   <xsl:for-each select="$globalData/office:styles/style:style[@style:family=current()/@style:family][not(@style:parent-style-name)]"> -->
327				<xsl:choose>
328					<xsl:when test="$defaultFamilyStyles/style[@style:family=current()/@style:family]">
329						<xsl:call-template name="inherit-style-for-self-and-children">
330							<xsl:with-param name="globalData" select="$globalData" />
331							<xsl:with-param name="inheritedStyleProperties" select="$defaultFamilyStyles/style[@style:family=current()/@style:family]/*" />
332							<xsl:with-param name="searchOnlyInAutomaticStyles" select="false()" />
333						</xsl:call-template>
334					</xsl:when>
335					<xsl:otherwise>
336						<xsl:call-template name="inherit-style-for-self-and-children">
337							<xsl:with-param name="globalData" select="$globalData" />
338							<xsl:with-param name="inheritedStyleProperties" select="$defaultOfficeStyle/style/*" />
339							<xsl:with-param name="searchOnlyInAutomaticStyles" select="false()" />
340						</xsl:call-template>
341					</xsl:otherwise>
342				</xsl:choose>
343			   <!--** creates a style element with style:name and style:family attribute and
344					   an element representing the absolute style properties style:property  ** -->
345			</xsl:for-each>
346
347	   <!--** traversee all office:automatic-styles trees beginning with the top-level styles **-->
348			<xsl:for-each select="$globalData/office:automatic-styles/style:style[not(@style:parent-style-name)]">
349			   <!--** creates a style element with style:name and style:family attribute and
350					   an element representing the absolute style properties style:property  ** -->
351				<xsl:choose>
352					<xsl:when test="$defaultFamilyStyles/style[@style:family=current()/@style:family]">
353						<xsl:call-template name="inherit-style-for-self-and-children">
354							<xsl:with-param name="globalData" select="$globalData" />
355							<xsl:with-param name="inheritedStyleProperties" select="$defaultFamilyStyles/style[@style:family=current()/@style:family]/*" />
356							<xsl:with-param name="searchOnlyInAutomaticStyles" select="true()" />
357						</xsl:call-template>
358					</xsl:when>
359					<xsl:otherwise>
360						<xsl:call-template name="inherit-style-for-self-and-children">
361							<xsl:with-param name="globalData" select="$globalData" />
362							<xsl:with-param name="inheritedStyleProperties" select="$defaultOfficeStyle/style/*" />
363							<xsl:with-param name="searchOnlyInAutomaticStyles" select="true()" />
364						</xsl:call-template>
365					</xsl:otherwise>
366				</xsl:choose>
367
368			</xsl:for-each>
369
370		</xsl:element>
371	   <!-- debug output in case only styles should be given out (regression test)  -->
372		<xsl:if test="$onlyStyleOutputEnabled">
373			<xsl:element name="defaultOfficeStyle" namespace="">
374				<xsl:copy-of select="$defaultOfficeStyle" />
375			</xsl:element>
376			<xsl:element name="defaultFamilyStyles" namespace="">
377				<xsl:copy-of select="$defaultFamilyStyles" />
378			</xsl:element>
379		</xsl:if>
380
381	</xsl:template>
382
383
384	<xsl:template name="inherit-style-for-self-and-children">
385		<xsl:param name="globalData" />
386		<xsl:param name="inheritedStyleProperties" />
387		<xsl:param name="searchOnlyInAutomaticStyles" />
388
389		   <!--** create an absolute style by inherting properties from the given parent properties **-->
390		<xsl:variable name="newStyleProperties-RTF">
391			<xsl:call-template name="create-inherited-style-properties">
392				<xsl:with-param name="inheritedStyleProperties" select="$inheritedStyleProperties" />
393			</xsl:call-template>
394		</xsl:variable>
395		<xsl:choose>
396			<xsl:when test="function-available('common:node-set')">
397				<xsl:variable name="newStyleProperties" select="common:node-set($newStyleProperties-RTF)" />
398
399				<xsl:element name="style" namespace="">
400					<xsl:copy-of select="@style:family" />
401					<xsl:copy-of select="@style:name" />
402					<xsl:copy-of select="$newStyleProperties" />
403				</xsl:element>
404
405				<xsl:choose>
406					<xsl:when test="$searchOnlyInAutomaticStyles">
407						<xsl:call-template name="get-children">
408							<xsl:with-param name="globalData" select="$globalData" />
409							<xsl:with-param name="searchOnlyInAutomaticStyles" select="true()" />
410							<xsl:with-param name="inheritedStyleProperties" select="$newStyleProperties/*" />
411						</xsl:call-template>
412					</xsl:when>
413					<xsl:otherwise>
414						   <!--** for all automatic-children of the current office:styles  **-->
415						<xsl:call-template name="get-children">
416							<xsl:with-param name="globalData" select="$globalData" />
417							<xsl:with-param name="searchOnlyInAutomaticStyles" select="false()" />
418							<xsl:with-param name="inheritedStyleProperties" select="$newStyleProperties/*" />
419						</xsl:call-template>
420					</xsl:otherwise>
421				</xsl:choose>
422			</xsl:when>
423			<xsl:when test="function-available('xalan:nodeset')">
424				<xsl:variable name="newStyleProperties" select="xalan:nodeset($newStyleProperties-RTF)" />
425
426				<xsl:element name="style" namespace="">
427					<xsl:copy-of select="@style:family" />
428					<xsl:copy-of select="@style:name" />
429					<xsl:copy-of select="$newStyleProperties" />
430				</xsl:element>
431
432				<xsl:choose>
433					<xsl:when test="$searchOnlyInAutomaticStyles">
434						<xsl:call-template name="get-children">
435							<xsl:with-param name="globalData" select="$globalData" />
436							<xsl:with-param name="searchOnlyInAutomaticStyles" select="true()" />
437							<xsl:with-param name="inheritedStyleProperties" select="$newStyleProperties/*" />
438						</xsl:call-template>
439					</xsl:when>
440					<xsl:otherwise>
441						   <!--** for all automatic-children of the current office:styles  **-->
442						<xsl:call-template name="get-children">
443							<xsl:with-param name="globalData" select="$globalData" />
444							<xsl:with-param name="searchOnlyInAutomaticStyles" select="false()" />
445							<xsl:with-param name="inheritedStyleProperties" select="$newStyleProperties/*" />
446						</xsl:call-template>
447					</xsl:otherwise>
448				</xsl:choose>
449			</xsl:when>
450			<xsl:when test="function-available('xt:node-set')">
451				<xsl:variable name="newStyleProperties" select="xt:node-set($newStyleProperties-RTF)" />
452
453				<xsl:element name="style" namespace="">
454					<xsl:copy-of select="@style:family" />
455					<xsl:copy-of select="@style:name" />
456					<xsl:copy-of select="$newStyleProperties" />
457				</xsl:element>
458
459				<xsl:choose>
460					<xsl:when test="$searchOnlyInAutomaticStyles">
461						<xsl:call-template name="get-children">
462							<xsl:with-param name="globalData" select="$globalData" />
463							<xsl:with-param name="searchOnlyInAutomaticStyles" select="true()" />
464							<xsl:with-param name="inheritedStyleProperties" select="$newStyleProperties/*" />
465						</xsl:call-template>
466					</xsl:when>
467					<xsl:otherwise>
468						   <!--** for all automatic-children of the current office:styles  **-->
469						<xsl:call-template name="get-children">
470							<xsl:with-param name="globalData" select="$globalData" />
471							<xsl:with-param name="searchOnlyInAutomaticStyles" select="false()" />
472							<xsl:with-param name="inheritedStyleProperties" select="$newStyleProperties/*" />
473						</xsl:call-template>
474					</xsl:otherwise>
475				</xsl:choose>
476			</xsl:when>
477			<xsl:otherwise>
478				<xsl:message terminate="yes">ERROR: Function not found: nodeset</xsl:message>
479			</xsl:otherwise>
480		</xsl:choose>
481	</xsl:template>
482
483
484	<xsl:template name="get-children">
485		<xsl:param name="globalData" />
486		<xsl:param name="searchOnlyInAutomaticStyles" />
487		<xsl:param name="inheritedStyleProperties" select="*" />
488
489<!-- QUESTION: Parent style is only unique by name and family, but what about cross family inheritance? -->
490	   <!-- For each child style (that is every style which has the given parentStyleName as style:parent-style-name and the same style:family -->
491		<xsl:variable name="parentStyleFamily" select="@style:family" />
492		<xsl:variable name="parentStyleName" select="@style:name" />
493		<xsl:if test="not($searchOnlyInAutomaticStyles)">
494			<xsl:for-each select="$globalData/office:styles/style:style[@style:family=$parentStyleFamily and @style:parent-style-name=$parentStyleName]">
495				<xsl:call-template name="inherit-style-for-self-and-children">
496					<xsl:with-param name="globalData" select="$globalData" />
497					<xsl:with-param name="inheritedStyleProperties" select="$inheritedStyleProperties" />
498					<xsl:with-param name="searchOnlyInAutomaticStyles" select="$searchOnlyInAutomaticStyles" />
499				</xsl:call-template>
500			</xsl:for-each>
501		</xsl:if>
502		<xsl:for-each select="$globalData/office:automatic-styles/style:style[@style:family=$parentStyleFamily and @style:parent-style-name=$parentStyleName]">
503			<xsl:call-template name="inherit-style-for-self-and-children">
504				<xsl:with-param name="globalData" select="$globalData" />
505				<xsl:with-param name="inheritedStyleProperties" select="$inheritedStyleProperties" />
506				<xsl:with-param name="searchOnlyInAutomaticStyles" select="$searchOnlyInAutomaticStyles" />
507			</xsl:call-template>
508		</xsl:for-each>
509	</xsl:template>
510
511
512	<xsl:template name="create-inherited-style-properties">
513		<xsl:param name="inheritedStyleProperties" />
514
515		<xsl:element name="style:properties">
516		   <!-- Writing all inherited style properties -->
517			<xsl:for-each select="$inheritedStyleProperties/@*">
518				<xsl:sort select="name()" />
519				<xsl:copy-of select="." />
520			</xsl:for-each>
521
522		   <!--All current attributes will override already inserted attributes of the same name
523			   XSLT Spec: "Adding an attribute to an element replaces any existing attribute of that element with the same expanded-name." -->
524			<xsl:for-each select="*/@*[name() != 'style:font-size-rel']">
525				<xsl:copy-of select="." />
526			</xsl:for-each>
527
528			<xsl:if test="*/@style:font-size-rel">
529<!--
530	The intheritedStyleProperties should include a absolute Font Size, but
531	<style:properties
532		xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0"
533		xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0"
534		style:font-name="Courier New"
535		fo:language="en"
536		fo:country="US"
537		style:font-name-asian=Courier New"
538		style:font-name-complex="Courier New"/>
539-->
540				<xsl:variable name="fontSizeAbsolute">
541					<xsl:call-template name="convert2pt">
542						<xsl:with-param name="value" select="$inheritedStyleProperties/@fo:font-size" />
543					</xsl:call-template>
544				</xsl:variable>
545
546				<xsl:variable name="fontSizeRelative">
547					<xsl:call-template name="convert2pt">
548						<xsl:with-param name="value" select="*/@style:font-size-rel" />
549					</xsl:call-template>
550				</xsl:variable>
551
552				<xsl:attribute name="fo:font-size">
553					<xsl:value-of select="$fontSizeAbsolute + $fontSizeRelative"/>
554					<xsl:text>pt</xsl:text>
555				</xsl:attribute>
556			</xsl:if>
557
558			<!-- providing tabulator indentation -->
559			<xsl:copy-of select="$inheritedStyleProperties/style:tab-stops"/>
560			<xsl:copy-of select="*/style:tab-stops"/>
561		</xsl:element>
562	</xsl:template>
563
564   <!-- debugging & testing purpose -->
565	<xsl:template name="write-collected-styles">
566		<xsl:param name="globalData" />
567
568		<xsl:message>&lt;all-doc-styles&gt;</xsl:message>
569		<xsl:for-each select="$globalData/all-doc-styles/style">
570			<xsl:message>&lt;style</xsl:message>
571			<xsl:message>style:family="<xsl:value-of select="current()/@style:family" />"&gt;</xsl:message>
572			<xsl:message>style:name="<xsl:value-of select="current()/@style:name" />" </xsl:message>
573			<xsl:message>   &lt;*</xsl:message>
574			<xsl:for-each select="*/@*">
575				<xsl:message>
576					<xsl:text></xsl:text>
577					<xsl:value-of select="name()" />="<xsl:value-of select="." />"</xsl:message>
578			</xsl:for-each>
579			<xsl:message>/&gt;</xsl:message>
580			<xsl:message>&lt;/style&gt;</xsl:message>
581		</xsl:for-each>
582		<xsl:message>&lt;/all-doc-styles&gt;</xsl:message>
583	</xsl:template>
584
585	<xsl:template name="map-odf-style-properties">
586		<xsl:param name="globalData" />
587
588		<xsl:choose>
589		   <!--+++++ DEBUG STYLE OUTPUT FOR REGRESSION TEST +++++-->
590		   <!-- create styles file from the style variable (testing switch) -->
591			<xsl:when test="$onlyStyleOutputEnabled">
592
593				<xsl:element name="debug-output" namespace="">
594					<xsl:copy-of select="$globalData" />
595					<xsl:call-template name="map-odf-properties">
596						<xsl:with-param name="globalData" select="$globalData" />
597					</xsl:call-template>
598				</xsl:element>
599			</xsl:when>
600
601		   <!-- create XHTML file -->
602			<xsl:otherwise>
603			   <!-- to access the variable like a node-set it is necessary to convert it
604					from a result-tree-fragment (RTF) to a node set using the James Clark extension -->
605				<xsl:variable name="globalDataRTF">
606				   <!-- raw properties still needed for table width attribute creation -->
607					<xsl:copy-of select="$globalData" />
608					<xsl:call-template name="map-odf-properties">
609						<xsl:with-param name="globalData" select="$globalData" />
610					</xsl:call-template>
611				</xsl:variable>
612
613				<xsl:choose>
614					<xsl:when test="function-available('common:node-set')">
615						<xsl:call-template name="start-main">
616							<xsl:with-param name="globalData" select="common:node-set($globalDataRTF)" />
617						</xsl:call-template>
618					</xsl:when>
619					<xsl:when test="function-available('xalan:nodeset')">
620						<xsl:call-template name="start-main">
621							<xsl:with-param name="globalData" select="xalan:nodeset($globalDataRTF)" />
622						</xsl:call-template>
623					</xsl:when>
624					<xsl:when test="function-available('xt:node-set')">
625						<xsl:call-template name="start-main">
626							<xsl:with-param name="globalData" select="xt:node-set($globalDataRTF)" />
627						</xsl:call-template>
628					</xsl:when>
629					<xsl:otherwise>
630						<xsl:message terminate="yes">ERROR: Function not found: nodeset</xsl:message>
631					</xsl:otherwise>
632				</xsl:choose>
633			</xsl:otherwise>
634		</xsl:choose>
635	</xsl:template>
636
637	<!-- REASON FOR TEMPLATE:
638	   The OpenOffice style properities gathered in the variable 'globalData' have to be mapped to the CSS style format
639	-->
640	<xsl:template name="map-odf-properties">
641		<xsl:param name="globalData" />
642		<xsl:element name="all-styles" namespace="">
643			<xsl:for-each select="$globalData/all-doc-styles/style">
644				<xsl:sort select="@style:family" />
645				<xsl:sort select="@style:name" />
646
647				<xsl:call-template name="writeUsedStyles">
648					<xsl:with-param name="globalData" select="$globalData" />
649					<xsl:with-param name="style" select="."/>
650				</xsl:call-template>
651			</xsl:for-each>
652		</xsl:element>
653	</xsl:template>
654
655	<xsl:key name="elementUsingStyle" match="*" use="@text:style-name | @draw:style-name | @draw:text-style-name | @table:style-name | @table:default-cell-style-name"/>
656	<xsl:key name="listLabelStyleInStyles" match="/*/office:styles/text:list-style/*  |
657									  /*/office:styles/style:graphic-properties/text:list-style/*" use="@text:style-name"/>
658
659    <xsl:key name="listLabelStyleInContent" match="/*/office:automatic-styles/text:list-style/* | /*/office:automatic-styles/style:graphic-properties/text:list-style/*" use="@text:style-name"/>
660
661
662	<xsl:variable name="documentRoot" select="/" />
663    <xsl:template name="writeUsedStyles">
664        <xsl:param name="globalData" />
665        <xsl:param name="style"/>
666
667            <!-- for-each changes the key environment from the previously globalData back to the document root  -->
668        <xsl:for-each select="$documentRoot">
669                <!-- only styles, which are used in the content are written as CSS styles -->
670            <xsl:choose>
671                <xsl:when test="key('elementUsingStyle', $style/@style:name)/@* or key('listLabelStyleInContent', $style/@style:name)/@*">
672                    <xsl:call-template name="writeUsedStyles2">
673                        <xsl:with-param name="globalData" select="$globalData" />
674                        <xsl:with-param name="style" select="$style" />
675                    </xsl:call-template>
676                </xsl:when>
677                <xsl:otherwise>
678                    <xsl:choose>
679                        <xsl:when test="not(office:document-content)">
680                            <xsl:if test="key('listLabelStyleInStyles', $style/@style:name)/@* or /*/office:styles/text:notes-configuration[@text:citation-style-name = $style/@style:name or /*/office:styles/@text:citation-body-style-name=$style/@style:name]">
681                                <!-- if there are consecutive paragraphs with borders (OR background AND margin ), only the first and the last have the top/bottom border
682                                unless style:join-border="false" -->
683                                <xsl:call-template name="writeUsedStyles2">
684                                    <xsl:with-param name="globalData" select="$globalData" />
685                                    <xsl:with-param name="style" select="$style" />
686                                </xsl:call-template>
687                            </xsl:if>
688                        </xsl:when>
689                        <xsl:otherwise>
690                            <xsl:for-each select="document($stylesFileURL)">
691                                <xsl:if test="key('listLabelStyleInStyles', $style/@style:name)/@* or /*/office:styles/text:notes-configuration[@text:citation-style-name = $style/@style:name or /*/office:styles/@text:citation-body-style-name=$style/@style:name]">
692                                    <!-- if there are consecutive paragraphs with borders (OR background AND margin ), only the first and the last have the top/bottom border
693                                    unless style:join-border="false" -->
694                                    <xsl:call-template name="writeUsedStyles2">
695                                        <xsl:with-param name="globalData" select="$globalData" />
696                                        <xsl:with-param name="style" select="$style" />
697                                    </xsl:call-template>
698                                </xsl:if>
699                            </xsl:for-each>
700                        </xsl:otherwise>
701                    </xsl:choose>
702                </xsl:otherwise>
703            </xsl:choose>
704        </xsl:for-each>
705    </xsl:template>
706
707	<xsl:template name="writeUsedStyles2">
708		<xsl:param name="globalData" />
709		<xsl:param name="style"/>
710        <xsl:choose>
711            <xsl:when test="
712                $style/@style:family='paragraph'
713            and((
714                  (
715                        $style/*/@fo:border-top
716                     or $style/*/@fo:border-bottom
717                     or $style/*/@fo:border
718                  )
719                   and
720                  (
721                     not($style/*/@style:join-border)
722                     or  $style/*/@style:join-border = 'true'
723                  )
724                )
725               or
726                (
727                  (
728                        $style/*/@fo:margin-top
729                     or $style/*/@fo:margin-bottom
730                     or $style/*/@fo:margin
731                  )
732                    and
733                  (     $style/*/@fo:background-color
734                    and
735                        not($style/*/fo:background-color='transparent')
736                  )
737                )
738               )">
739                <xsl:element name="style" namespace="">
740                    <xsl:copy-of select="$style/@style:family" />
741                    <xsl:attribute name="style:name"><xsl:value-of select="concat($style/@style:name, '_borderStart')" /></xsl:attribute>
742                    <xsl:element name="final-properties" namespace="">
743                        <xsl:apply-templates select="$style/*/@*[not(name() = 'fo:border-bottom')][not(name() = 'fo:padding-bottom')][not(name() = 'fo:margin-bottom')][not(name() = 'fo:margin')]">
744                            <xsl:with-param name="globalData" select="$globalData" />
745                        </xsl:apply-templates>
746                        <xsl:apply-templates mode="paragraphMerge" select="$style/*/@*[name() = 'fo:margin-bottom' or name() = 'fo:margin']">
747                            <xsl:with-param name="globalData" select="$globalData" />
748                        </xsl:apply-templates>
749                        <xsl:text> border-bottom-style:none; </xsl:text>
750                    </xsl:element>
751                </xsl:element>
752                <xsl:element name="style" namespace="">
753                    <xsl:copy-of select="$style/@style:family" />
754                    <xsl:copy-of select="$style/@style:name" />
755                    <xsl:attribute name="mergedBorders"><xsl:value-of select="true()" /></xsl:attribute>
756                    <xsl:element name="final-properties" namespace="">
757                        <xsl:apply-templates select="$style/*/@*[not(name() = 'fo:border-top') and not(name() = 'fo:border-bottom')][not(name() = 'fo:padding-top') and not(name() = 'fo:padding-bottom')][not(name() = 'fo:margin-top') and not(name() = 'fo:margin-bottom')][not(name() = 'fo:margin')]">
758                            <xsl:with-param name="globalData" select="$globalData" />
759                        </xsl:apply-templates>
760                        <xsl:apply-templates mode="paragraphMerge" select="$style/*/@*[name() = 'fo:margin-top' or name() = 'fo:margin-bottom' or name() = 'fo:margin']">
761                            <xsl:with-param name="globalData" select="$globalData" />
762                        </xsl:apply-templates>
763                        <xsl:text> border-top-style:none; border-bottom-style:none; </xsl:text>
764                    </xsl:element>
765                </xsl:element>
766                <xsl:element name="style" namespace="">
767                    <xsl:copy-of select="$style/@style:family" />
768                    <xsl:attribute name="style:name"><xsl:value-of select="concat($style/@style:name, '_borderEnd')" /></xsl:attribute>
769                    <xsl:element name="final-properties" namespace="">
770                        <xsl:apply-templates select="$style/*/@*[not(name() = 'fo:border-top')][not(name() = 'fo:padding-top')][not(name() = 'fo:margin-top')][not(name() = 'fo:margin')]">
771                            <xsl:with-param name="globalData" select="$globalData" />
772                        </xsl:apply-templates>
773                        <xsl:apply-templates mode="paragraphMerge" select="$style/*/@*[name() = 'fo:margin-top' or name() = 'fo:margin']">
774                            <xsl:with-param name="globalData" select="$globalData" />
775                        </xsl:apply-templates>
776                        <xsl:text> border-top-style:none;</xsl:text>
777                    </xsl:element>
778                </xsl:element>
779            </xsl:when>
780            <xsl:otherwise>
781                <xsl:choose>
782                    <xsl:when test="not(key('listLabelStyleInStyles', $style/@style:name)/@*)">
783                        <xsl:element name="style" namespace="">
784                            <xsl:copy-of select="$style/@style:family" />
785                            <xsl:copy-of select="$style/@style:name" />
786                            <xsl:element name="final-properties" namespace="">
787                                <xsl:apply-templates select="$style/*/@*">
788                                    <xsl:with-param name="globalData" select="$globalData" />
789                                </xsl:apply-templates>
790                            </xsl:element>
791                        </xsl:element>
792                    </xsl:when>
793                    <xsl:otherwise>
794                        <xsl:element name="style" namespace="">
795                            <xsl:attribute name="style:family">none</xsl:attribute>
796                            <xsl:attribute name="style:name"><xsl:value-of select="$style/@style:name"/></xsl:attribute>
797                            <xsl:element name="final-properties" namespace="">
798                                <xsl:apply-templates select="$style/*/@*">
799                                    <xsl:with-param name="globalData" select="$globalData" />
800                                </xsl:apply-templates>
801                            </xsl:element>
802                        </xsl:element>
803                    </xsl:otherwise>
804                </xsl:choose>
805            </xsl:otherwise>
806        </xsl:choose>
807	</xsl:template>
808
809	<xsl:template mode="paragraphMerge" match="@fo:margin | @fo:margin-top | @fo:margin-bottom | @fo:margin-left | @fo:margin-right">
810		<xsl:text>padding</xsl:text>
811        <xsl:value-of select="substring-after(name(), 'fo:margin')"/>
812		<xsl:text>:</xsl:text>
813		<!-- Map once erroneusly used inch shortage 'inch' to CSS shortage 'in' -->
814		<xsl:choose>
815			<xsl:when test="contains(., 'inch')">
816				<xsl:value-of select="substring-before(.,'ch')"/>
817			</xsl:when>
818			<xsl:otherwise>
819				<xsl:value-of select="."/>
820			</xsl:otherwise>
821		</xsl:choose>
822		<xsl:text>; </xsl:text>
823	</xsl:template>
824</xsl:stylesheet>
825