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" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:java="http://xml.apache.org/xslt/java" xmlns:urlencoder="http://www.jclark.com/xt/java/java.net.URLEncoder" 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 java urlencoder">
28
29
30	<xsl:include href="table_of_content.xsl"/>
31
32
33	<!-- ****************** -->
34	<!-- *** Whitespace *** -->
35	<!-- ****************** -->
36
37	<xsl:template match="text:s">
38		<xsl:call-template name="write-breakable-whitespace">
39			<xsl:with-param name="whitespaces" select="@text:c"/>
40		</xsl:call-template>
41	</xsl:template>
42
43
44	<!--write the number of 'whitespaces' -->
45	<xsl:template name="write-breakable-whitespace">
46		<xsl:param name="whitespaces"/>
47
48		<!--write two space chars as the normal white space character will be stripped
49			and the other is able to break -->
50		<xsl:text>&#160;</xsl:text>
51		<xsl:if test="$whitespaces >= 2">
52			<xsl:call-template name="write-breakable-whitespace-2">
53				<xsl:with-param name="whitespaces" select="$whitespaces - 1"/>
54			</xsl:call-template>
55		</xsl:if>
56	</xsl:template>
57
58
59	<!--write the number of 'whitespaces' -->
60	<xsl:template name="write-breakable-whitespace-2">
61		<xsl:param name="whitespaces"/>
62		<!--write two space chars as the normal white space character will be stripped
63			and the other is able to break -->
64		<xsl:text> </xsl:text>
65		<xsl:if test="$whitespaces >= 2">
66			<xsl:call-template name="write-breakable-whitespace">
67				<xsl:with-param name="whitespaces" select="$whitespaces - 1"/>
68			</xsl:call-template>
69		</xsl:if>
70	</xsl:template>
71
72	<!-- currentSolution: 8 non-breakable-spaces instead of a TAB is an approximation.
73		 Sometimes less spaces than 8 might be needed and the output might be more difficult to read-->
74	<xsl:template match="text:tab">
75		<xsl:param name="globalData"/>
76
77		<xsl:call-template name="write-breakable-whitespace">
78			<xsl:with-param name="whitespaces" select="8"/>
79		</xsl:call-template>
80	</xsl:template>
81
82
83
84	<!-- *************** -->
85	<!-- *** Textbox *** -->
86	<!-- *************** -->
87
88	<!-- ID / NAME of text-box -->
89	<xsl:template match="@draw:name">
90		<xsl:attribute name="id">
91			<xsl:choose>
92				<xsl:when test="number(substring(.,1,1))">
93				<!-- Heuristic: If the first character is a number a 'a_' will be set
94					as prefix, as id have to be of type NMTOKEN -->
95					<xsl:value-of select="concat('a_',translate(., '&#xA;&amp;&lt;&gt;.,;: %()[]/\+', '___________________________'))"/>
96				</xsl:when>
97				<xsl:otherwise>
98					<xsl:value-of select="translate(., '&#xA;&amp;&lt;&gt;.,;: %()[]/\+', '___________________________')"/>
99				</xsl:otherwise>
100			</xsl:choose>
101		</xsl:attribute>
102	</xsl:template>
103
104
105	<xsl:template match="text:line-break">
106		<xsl:param name="listIndent"/>
107
108		<xsl:element namespace="{$namespace}" name="br"/>
109
110		<!-- line breaks in lists need an indent similar to the list label -->
111		<xsl:if test="$listIndent">
112			<xsl:element namespace="{$namespace}" name="span">
113				<xsl:attribute name="style">margin-left:<xsl:value-of select="$listIndent"/>cm</xsl:attribute>
114			</xsl:element>
115		</xsl:if>
116	</xsl:template>
117
118
119	<!-- currently there have to be an explicit call of the style attribute nodes, maybe the attributes nodes have no priority only order relevant-->
120	<xsl:template name="apply-styles-and-content">
121		<xsl:param name="globalData"/>
122		<xsl:param name="footnotePrefix" />
123		<xsl:apply-templates select="@*">
124			<xsl:with-param name="globalData" select="$globalData"/>
125		</xsl:apply-templates>
126		<!-- the footnote symbol is the prefix for a footnote in the footer -->
127		<xsl:copy-of select="$footnotePrefix"/>
128		<xsl:apply-templates select="node()">
129			<xsl:with-param name="globalData" select="$globalData"/>
130		</xsl:apply-templates>
131	</xsl:template>
132
133
134	<!-- ******************* -->
135	<!-- *** References  *** -->
136	<!-- ******************* -->
137
138	<xsl:template match="text:reference-ref | text:sequence-ref">
139		<xsl:param name="globalData"/>
140		<xsl:element namespace="{$namespace}" name="a">
141			<xsl:attribute name="href">
142				<xsl:text>#</xsl:text>
143				<xsl:choose>
144					<xsl:when test="number(substring(@text:ref-name,1,1))">
145					<!-- Heuristic: If the first character is a number a 'a_' will be set
146						as prefix, as id have to be of type NMTOKEN -->
147						<xsl:value-of select="concat('a_',translate(@text:ref-name, '&#xA;&amp;&lt;&gt;.,;: %()[]/\+', '___________________________'))"/>
148					</xsl:when>
149					<xsl:otherwise>
150						<xsl:value-of select="translate(@text:ref-name, '&#xA;&amp;&lt;&gt;.,;: %()[]/\+', '___________________________')"/>
151					</xsl:otherwise>
152				</xsl:choose>
153			</xsl:attribute>
154
155			<xsl:apply-templates select="@* | node()">
156				<xsl:with-param name="globalData" select="$globalData"/>
157			</xsl:apply-templates>
158		</xsl:element>
159	</xsl:template>
160
161    <xsl:template match="@text:name">
162		<xsl:attribute name="id">
163			<xsl:choose>
164				<xsl:when test="number(substring(.,1,1))">
165				<!-- Heuristic: If the first character is a number a 'a_' will be set
166					as prefix, as id have to be of type NMTOKEN -->
167					<xsl:value-of select="concat('a_',translate(., '&#xA;&amp;&lt;&gt;.,;: %()[]/\+', '___________________________'))"/>
168				</xsl:when>
169				<xsl:otherwise>
170					<xsl:value-of select="translate(., '&#xA;&amp;&lt;&gt;.,;: %()[]/\+', '___________________________')"/>
171				</xsl:otherwise>
172			</xsl:choose>
173        </xsl:attribute>
174    </xsl:template>
175
176	<xsl:template match="text:sequence">
177		<xsl:param name="globalData"/>
178
179		<xsl:element namespace="{$namespace}" name="a">
180			<xsl:apply-templates select="@*" />
181			<xsl:attribute name="id">
182				<xsl:choose>
183					<xsl:when test="number(substring(@text:ref-name,1,1))">
184					<!-- Heuristic: If the first character is a number a 'a_' will be set
185						as prefix, as id have to be of type NMTOKEN -->
186						<xsl:value-of select="concat('a_',translate(@text:ref-name, '&#xA;&amp;&lt;&gt;.,;: %()[]/\+', '___________________________'))"/>
187					</xsl:when>
188					<xsl:otherwise>
189						<xsl:value-of select="translate(@text:ref-name, '&#xA;&amp;&lt;&gt;.,;: %()[]/\+', '___________________________')"/>
190					</xsl:otherwise>
191				</xsl:choose>
192			</xsl:attribute>
193		</xsl:element>
194
195		<xsl:apply-templates>
196			<xsl:with-param name="globalData" select="$globalData"/>
197		</xsl:apply-templates>
198	</xsl:template>
199
200	<xsl:template match="text:reference-mark">
201		<xsl:param name="globalData"/>
202
203		<xsl:element namespace="{$namespace}" name="a">
204			<xsl:apply-templates select="@*" />
205			<xsl:attribute name="id">
206				<xsl:choose>
207					<xsl:when test="number(substring(@text:name,1,1))">
208					<!-- Heuristic: If the first character is a number a 'a_' will be set
209						as prefix, as id have to be of type NMTOKEN -->
210						<xsl:value-of select="concat('a_',translate(@text:name, '&#xA;&amp;&lt;&gt;.,;: %()[]/\+', '___________________________'))"/>
211					</xsl:when>
212					<xsl:otherwise>
213						<xsl:value-of select="translate(@text:name, '&#xA;&amp;&lt;&gt;.,;: %()[]/\+', '___________________________')"/>
214					</xsl:otherwise>
215				</xsl:choose>
216			</xsl:attribute>
217		</xsl:element>
218
219		<xsl:apply-templates>
220			<xsl:with-param name="globalData" select="$globalData"/>
221		</xsl:apply-templates>
222	</xsl:template>
223
224
225	<xsl:template match="text:reference-mark-start">
226		<xsl:param name="globalData"/>
227
228		<xsl:element namespace="{$namespace}" name="a">
229			<xsl:apply-templates select="@*" />
230		</xsl:element>
231	</xsl:template>
232
233	<xsl:template match="text:bibliography-mark">
234		<xsl:param name="globalData"/>
235
236		<xsl:element namespace="{$namespace}" name="a">
237			<xsl:apply-templates select="@* | node()">
238				<xsl:with-param name="globalData" select="$globalData"/>
239			</xsl:apply-templates>
240		</xsl:element>
241	</xsl:template>
242
243	<!-- @text:title exist only in text:bibliography-mark -->
244	<xsl:template match="@text:title">
245		<xsl:attribute name="title">
246			<xsl:value-of select="."/>
247		</xsl:attribute>
248	</xsl:template>
249
250	<!-- @text:url exist only in text:bibliography-mark -->
251	<xsl:template match="@text:url">
252		<xsl:attribute name="href">
253			<xsl:value-of select="."/>
254		</xsl:attribute>
255	</xsl:template>
256
257	<xsl:template match="text:user-defined">
258		<xsl:apply-templates/>
259	</xsl:template>
260
261
262    <xsl:template match="office:annotation">
263        <xsl:element name="span">
264            <xsl:attribute name="title">annotation</xsl:attribute>
265            <xsl:attribute name="class">annotation_style_by_filter</xsl:attribute>
266            <xsl:apply-templates select="@*" />
267            <br/>
268            <xsl:text>[ANNOTATION:</xsl:text>
269            <br/>
270            <xsl:apply-templates select="*" mode="annotation"/>
271            <xsl:text>]</xsl:text>
272        </xsl:element>
273    </xsl:template>
274
275    <xsl:template match="text:p" mode="annotation">
276        <br/>
277        <xsl:element name="span">
278            <xsl:text>NOTE: '</xsl:text>
279            <xsl:apply-templates />
280            <xsl:text>'</xsl:text>
281        </xsl:element>
282    </xsl:template>
283
284    <xsl:template match="dc:creator" mode="annotation">
285        <br/>
286        <xsl:element name="span">
287            <xsl:attribute name="title">dc:creator</xsl:attribute>
288            <xsl:text>BY '</xsl:text>
289            <xsl:apply-templates />
290            <xsl:text>'</xsl:text>
291        </xsl:element>
292    </xsl:template>
293
294    <xsl:template match="dc:date" mode="annotation">
295        <br/>
296        <xsl:element name="span">
297            <xsl:attribute name="title">dc:date</xsl:attribute>
298            <xsl:text>ON '</xsl:text>
299            <xsl:apply-templates />
300            <xsl:text>'</xsl:text>
301        </xsl:element>
302    </xsl:template>
303
304    <xsl:template match="meta:date-string" mode="annotation">
305        <br/>
306        <xsl:element name="span">
307            <xsl:attribute name="title">meta-date-string</xsl:attribute>
308            <xsl:text>META DATE '</xsl:text>
309            <xsl:apply-templates />
310            <xsl:text>'</xsl:text>
311        </xsl:element>
312    </xsl:template>
313
314
315	<!-- *************** -->
316	<!-- *** HELPER  *** -->
317	<!-- *************** -->
318
319
320	<xsl:template name="create-href">
321		<xsl:param name="href"/>
322
323		<xsl:choose>
324			<!-- internal OOo URL used in content tables -->
325			<xsl:when test="contains($href, '%7Coutline')">
326				<!-- the simple workaround for content tables in a single document is to create create an anchor from every heading element
327					 work-around downside: Multiple identical headings won't refer always to the first.
328				-->
329				<xsl:text>#</xsl:text>
330				<xsl:variable name="title">
331					<xsl:apply-templates mode="concatenate"/>
332				</xsl:variable>
333
334				<xsl:value-of select="concat('a_', translate(normalize-space($title), '.,;: %()[]/\+', '_____________'))"/>
335			</xsl:when>
336			<xsl:when test="self::draw:image[office:binary-data]">
337				<xsl:text>data:image/*;base64,</xsl:text><xsl:value-of select="office:binary-data"/>
338			</xsl:when>
339			<xsl:otherwise>
340				<xsl:choose>
341					 <!-- in case of packed open office document -->
342					<xsl:when test="starts-with($sourceBaseURL, 'jar:') or $isPackageFormat">
343						<xsl:choose>
344							 <!-- for images relative to open office document -->
345							<xsl:when test="starts-with($href, '../')">
346								<!-- creating an absolute http URL to the packed image file (removing the '.')-->
347								<xsl:value-of select="concat(substring-after(substring-before($sourceBaseURL, '!'), 'jar:'), '/', $href, $optionalURLSuffix)"/>
348							</xsl:when>
349							 <!-- for absolute URLs & absolute paths -->
350							<xsl:when test="contains($href, ':') or starts-with($href, '/')">
351								<xsl:value-of select="concat($href, $optionalURLSuffix)"/>
352							</xsl:when>
353							<!-- for images jared in open office document -->
354							<xsl:otherwise>
355								<xsl:value-of select="concat($sourceBaseURL, $href, $optionalURLSuffix)"/>
356							</xsl:otherwise>
357						</xsl:choose>
358					</xsl:when>
359					<xsl:otherwise>
360						<xsl:choose>
361							 <!-- for absolute URLs & Paths -->
362							<xsl:when test="contains($href, ':') or starts-with($href, '/')">
363								<xsl:value-of select="concat($href, $optionalURLSuffix)"/>
364							</xsl:when>
365							 <!-- for relative URLs -->
366							<xsl:otherwise>
367								<xsl:value-of select="concat($sourceBaseURL, $href, $optionalURLSuffix)"/>
368							</xsl:otherwise>
369						</xsl:choose>
370					</xsl:otherwise>
371				</xsl:choose>
372			</xsl:otherwise>
373		</xsl:choose>
374
375	</xsl:template>
376
377	<xsl:template match="text()" mode="concatenate">
378		<xsl:value-of select="."/>
379	</xsl:template>
380	<xsl:template match="*" mode="concatenate">
381		<xsl:apply-templates mode="concatenate"/>
382	</xsl:template>
383
384
385	<!-- ******************** -->
386	<!-- *** Common Rules *** -->
387	<!-- ******************** -->
388
389	<!-- ignore / neglect the following elements -->
390	<xsl:template match="draw:custom-shape | draw:g | office:forms | text:alphabetical-index-mark | text:alphabetical-index-mark-end | text:alphabetical-index-mark-start | text:bibliography-source | text:number | text:reference-mark-end | text:sequence-decls | text:soft-page-break | text:table-of-content-source | text:tracked-changes | text:user-field-decls"/>
391
392	<!-- default template used by purpose-->
393	<xsl:template match="text:bibliography | text:change-end | text:change-start">
394		<xsl:param name="globalData"/>
395
396		<xsl:apply-templates>
397			<xsl:with-param name="globalData" select="$globalData"/>
398		</xsl:apply-templates>
399	</xsl:template>
400
401	<!-- default template for not recognized elements -->
402	<xsl:template match="*">
403		<xsl:param name="globalData"/>
404		<xsl:message>Using default element rule for ODF element '<xsl:value-of select="name()"/>'.</xsl:message>
405
406		<xsl:apply-templates>
407			<xsl:with-param name="globalData" select="$globalData"/>
408		</xsl:apply-templates>
409	</xsl:template>
410
411	<xsl:template match="@*"/>
412
413	<!-- allowing all matched text nodes -->
414	<xsl:template match="text()">
415		<xsl:value-of select="."/>
416	</xsl:template>
417
418</xsl:stylesheet>
419