1 <?xml version="1.0" encoding="utf-8"?>
4 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
5 xmlns:fo="http://www.w3.org/1999/XSL/Format"
6 xmlns:office="http://openoffice.org/2000/office"
7 xmlns:style="http://openoffice.org/2000/style"
8 xmlns:text="http://openoffice.org/2000/text"
9 xmlns:table="http://openoffice.org/2000/table"
10 xmlns:draw="http://openoffice.org/2000/drawing"
11 xmlns:xlink="http://www.w3.org/1999/xlink"
12 xmlns:number="http://openoffice.org/2000/datastyle"
13 xmlns:svg="http://www.w3.org/2000/svg"
14 xmlns:chart="http://openoffice.org/2000/chart"
15 xmlns:dr3d="http://openoffice.org/2000/dr3d"
16 xmlns:math="http://www.w3.org/1998/Math/MathML"
17 xmlns:form="http://openoffice.org/2000/form"
18 xmlns:script="http://openoffice.org/2000/script"
19 office:class="text" office:version="1.0"
20 exclude-result-prefixes = "xsl fo office style text table draw xlink number svg chart dr3d math form script">
22 <!--TODO's: indent, picture cache (trml2pdf) -->
24 <xsl:output method="xml" indent="yes" />
25 <xsl:strip-space elements="*"/>
27 <xsl:key name="text_style" match="style:style[@style:family='text']" use="@style:name" />
28 <xsl:key name="page_break_before" match="style:style[@style:family='paragraph' and ./style:properties/@fo:break-before='page']" use="@style:name" />
29 <xsl:key name="page_break_after" match="style:style[@style:family='paragraph' and ./style:properties/@fo:break-after='page']" use="@style:name" />
30 <xsl:key name="table_column_style" match="style:style[@style:family='table-column']" use="@style:name" />
31 <xsl:key name="table_cell_style" match="style:style[@style:family='table-cell']" use="@style:name" />
32 <xsl:key name="paragraph_style" match="style:style[@style:family='paragraph']" use="@style:name" />
34 <xsl:template match="office:document-content">
35 <document filename="test.pdf">
36 <xsl:apply-templates select="office:automatic-styles" />
37 <xsl:apply-templates select="office:body" />
41 <xsl:template name="page_size">
42 <xsl:attribute name="pageSize">
43 <xsl:text>(</xsl:text>
44 <xsl:value-of select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:page-width" />
45 <xsl:text>,</xsl:text>
46 <xsl:value-of select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:page-height" />
47 <xsl:text>)</xsl:text>
51 <xsl:template name="fixed_frame">
52 <xsl:for-each select="//draw:text-box">
54 <xsl:attribute name="id"><xsl:value-of select="./@draw:name" /></xsl:attribute>
55 <xsl:attribute name="x1"><xsl:value-of select="./@svg:x" /></xsl:attribute>
56 <xsl:attribute name="y1">
58 select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:page-height - ./@svg:y - ./@fo:min-height" />
60 <xsl:attribute name="width">
61 <xsl:value-of select="./@svg:width" />
63 <xsl:attribute name="height">
64 <xsl:value-of select="./@fo:min-height" />
70 <xsl:template name="margin_sizes">
71 <xsl:variable name="margin_left" select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:margin-left" />
72 <xsl:variable name="margin_right" select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:margin-right" />
73 <xsl:variable name="margin_top" select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:margin-top" />
74 <xsl:variable name="margin_bottom" select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:margin-bottom" />
75 <xsl:variable name="page_width" select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:page-width" />
76 <xsl:variable name="page_height" select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:page-height" />
77 <xsl:attribute name="x1"><xsl:value-of select="$margin_left" /></xsl:attribute>
78 <xsl:attribute name="y1"><xsl:value-of select="$margin_bottom" /></xsl:attribute>
79 <xsl:attribute name="width"><xsl:value-of select="$page_width - $margin_left - $margin_right"/></xsl:attribute>
80 <xsl:attribute name="height"><xsl:value-of select="$page_height - $margin_bottom - $margin_top"/></xsl:attribute>
83 <xsl:template name="text_width">
84 <!-- You need this for the workaround to make primitive outlines-->
85 <xsl:variable name="margin_left" select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:margin-left" />
86 <xsl:variable name="margin_right" select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:margin-right" />
87 <xsl:variable name="page_width" select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:page-width" />
88 <xsl:value-of select="$page_width - $margin_left - $margin_right - 18"/>
93 <xsl:template match="office:automatic-styles">
94 <!--<template pageSize="(21cm, 29.7cm)" leftMargin="1.0cm" rightMargin="2.0cm" topMargin="1.0cm" bottomMargin="1.0cm" title="Test" author="Martin Simon" allowSplitting="20">-->
95 <template pageSize="(21cm, 29.7cm)" title="Test" author="Martin Simon" allowSplitting="20">
96 <xsl:call-template name="page_size" />
97 <pageTemplate id="first">
98 <xsl:call-template name="fixed_frame" />
99 <frame id="first" x1="2cm" y1="2cm" width="17cm" height="26cm">
100 <xsl:call-template name="margin_sizes" />
105 <!--A table style to simulate primitive outlines -till the <addOutline> tag is implemented in trml2pdf -->
106 <blockTableStyle id="Standard_Outline">
107 <blockAlignment value="LEFT"/>
108 <blockValign value="TOP"/>
110 <!--use two standard table grid styles like PyOpenOffice "Old Way": with and without a grid-->
111 <!--TODO insert table cell colors here, not within the <td> tag - otherwise
112 it will not work with flowables as cell content-->
113 <xsl:call-template name="make_blocktablestyle" />
115 <paraStyle name="all" alignment="justify" />
117 <xsl:apply-templates select="style:style" />
121 <xsl:template name="make_blocktablestyle">
122 <xsl:for-each select="//table:table">
123 <xsl:variable name="test">
124 <xsl:value-of select="./@table:name" />
126 <xsl:if test="not(boolean(count(preceding-sibling::table:table[@table:name=$test])))">
127 <!--Test if this is the first table with this style, nested tables not counted-->
128 <blockTableStyle id="{@table:name}">
129 <xsl:if test=".//draw:image">
130 <blockTopPadding value="0"/>
131 <blockBottomPadding value="0"/>
133 <blockAlignment value="LEFT" />
134 <blockValign value="TOP" />
135 <xsl:call-template name="make_tablegrid" />
136 <xsl:call-template name="make_tablebackground" />
142 <xsl:template name="make_tablegrid">
143 <xsl:variable name="test_grid">
144 <xsl:call-template name="test_grid" />
146 <xsl:if test="contains($test_grid,'has_grid')">
147 <lineStyle kind="GRID" colorName="black" />
152 <!-- Was needed to simulate bulleted lists:
153 <xsl:template match="text:ordered-list|text:unordered-list">
154 <xsl:variable name = "text_width">
155 <xsl:call-template name="text_width" />
157 <blockTable style="Standard_Outline" colWidths="18,{$text_width}">
158 <xsl:apply-templates match="text:list-item" />
162 <xsl:template match="text:list-item">
164 <td><para><font face="Helvetica-Bold" size="10">*</font></para></td>
166 <xsl:apply-templates />
174 <xsl:template match="office:body">
176 <xsl:apply-templates />
177 <xsl:for-each select="//draw:text-box">
179 <xsl:attribute name="name">
180 <xsl:value-of select="./@draw:name" />
183 <xsl:apply-templates>
184 <xsl:with-param name="skip_draw" select="0" />
185 </xsl:apply-templates>
191 <xsl:template match="table:table">
193 <xsl:attribute name="colWidths">
194 <xsl:call-template name="make_columns" />
196 <xsl:call-template name="make_tableheaders" />
197 <xsl:attribute name="style">
198 <xsl:value-of select="@table:name" />
200 <xsl:apply-templates />
204 <xsl:template name="make_tableheaders">
205 <xsl:if test="boolean(count(table:table-header-rows))">
206 <xsl:attribute name="repeatRows">1</xsl:attribute>
210 <xsl:template name="make_tablebackground">
211 <xsl:for-each select=".//table:table-row">
212 <!--Be careful when there are table:table-header-rows as
213 parent node of table:table-row -->
214 <xsl:variable name="row" select="position() - 1" />
215 <xsl:for-each select="./table:table-cell">
216 <xsl:variable name="col" select="position() - 1" />
217 <xsl:variable name="background">
218 <xsl:value-of select="key('table_cell_style',@table:style-name)/style:properties/@fo:background-color" />
220 <xsl:if test="not($background='') and boolean(key('table_cell_style',@table:style-name)/style:properties/@fo:background-color) and starts-with($background,'#')">
221 <!--only RGB hexcolors are accepted -->
222 <blockBackground colorName="{$background}" start="{$col},{$row}" stop="{$col},{$row}" />
228 <xsl:template name="test_grid">
229 <!--very primitive: if at last one cell has a border,
230 the whole table style is set to GRID.-->
231 <xsl:for-each select=".//table:table-cell">
232 <xsl:for-each select="key('table_cell_style',@table:style-name)/style:properties" >
233 <!--Test all table cell styles if there is at least one border line -->
234 <xsl:variable name="border">
235 <xsl:value-of select="@fo:border" />
237 <xsl:if test="not($border='none') and not($border='') and boolean(@fo:border)">
238 <xsl:text>has_grid</xsl:text>
244 <xsl:template name="make_columns">
245 <xsl:variable name="columns" >
246 <xsl:for-each select="table:table-column">
247 <xsl:value-of select="key('table_column_style',@table:style-name)/style:properties/@style:column-width" />
248 <xsl:text>,</xsl:text>
251 <xsl:value-of select="substring($columns,1,string-length($columns) - 1)" />
252 <!--strip the last comma-->
255 <xsl:template match="table:table-row">
257 <xsl:apply-templates />
261 <xsl:template match="table:table-cell">
263 <xsl:apply-templates />
267 <xsl:template match="text:section">
269 <xsl:apply-templates />
274 <xsl:template match="text:span">
276 <xsl:call-template name="make_fontnames_span" />
277 <xsl:call-template name="make_fontsize_span" />
278 <xsl:apply-templates />
282 <xsl:template name="make_fontsize_span">
283 <xsl:variable name ="fontsize">
284 <xsl:value-of select="key('text_style',@text:style-name)/style:properties/@fo:font-size" />
286 <xsl:if test="not($fontsize='') and boolean(key('text_style',@text:style-name)/style:properties/@fo:font-size)" >
287 <xsl:attribute name="size">
288 <xsl:value-of select="$fontsize" />
293 <xsl:template name="make_fontnames_span">
294 <xsl:attribute name="face">
295 <xsl:call-template name="make_fontnames">
296 <xsl:with-param name="fontName" select="key('text_style',@text:style-name)/style:properties/@style:font-name" />
297 <xsl:with-param name="fontWeight" select="key('text_style',@text:style-name)/style:properties/@fo:font-weight" />
298 <xsl:with-param name="fontStyle" select="key('text_style',@text:style-name)/style:properties/@fo:font-style" />
303 <xsl:template name="make_image">
304 <illustration height="{.//draw:image/@svg:height}" width="{.//draw:image/@svg:width}">
305 <image x="0" y="0" file="{substring-after(.//draw:image/@xlink:href,'#Pictures/')}" height="{.//draw:image/@svg:height}" width="{.//draw:image/@svg:width}" />
309 <xsl:template name="empty_paragraph">
310 <xsl:if test="not(boolean(count(descendant::node())))">
311 <xsl:call-template name="distance_point">
312 <xsl:with-param name="background" select="key('paragraph_style',@text:style-name)/style:properties/@fo:background-color" />
317 <xsl:template name="distance_point">
318 <xsl:param name="background" />
319 <xsl:param name="tab_stop"></xsl:param>
320 <xsl:variable name="local_back">
322 <xsl:when test="not(boolean($background)) or not(contains($background,'#'))">
323 <!-- Do not accept OO colors like "transparent", only hex-colors -->
324 <xsl:text>white</xsl:text>
327 <xsl:value-of select="$background" />
331 <font color="{$local_back}">
332 <xsl:text> </xsl:text>
333 <xsl:if test="boolean($tab_stop)">
334 <!-- simulate a tabstop with white/background-color points -->
335 <xsl:text>.........</xsl:text>
340 <xsl:template match="text:ordered-list">
341 <xsl:apply-templates />
342 <para><seqreset id="ordered_list" /></para>
343 <!-- Reset the counter. seqreset is not a trml2pdf tag, but a Platypus Intra Paragraph Markup,
344 so it needs a dummy paragraph to enclose it -->
347 <xsl:template name="make_listitem">
348 <xsl:if test="(name(..)='text:list-item')">
349 <xsl:attribute name="leftIndent">15</xsl:attribute>
350 <xsl:attribute name="bulletIndent">0</xsl:attribute>
352 <xsl:when test="(name(../..)='text:unordered-list')">
353 <xsl:variable name="fontsize">
354 <xsl:value-of select="number(key('paragraph_style',@text:style-name)/style:properties/@fo:font-size)" />
357 <xsl:when test="$fontsize='NaN'">
358 <!-- you should exclude non-numerical values for bulletFontSize. <== Sometimes the preprocessing went wrong.-->
359 <!--use a default bullet font size-->
360 <xsl:attribute name="bulletFontSize">6</xsl:attribute>
363 <xsl:attribute name="bulletFontSize"><xsl:value-of select="floor(($fontsize div 2) + 1)" /></xsl:attribute>
366 <xsl:attribute name="bulletFontName">ZapfDingbats</xsl:attribute>
367 <xsl:attribute name="bulletText">l</xsl:attribute>
370 <!-- Generate the numbers for an ordered list -->
371 <xsl:variable name="size">
372 <xsl:value-of select="key('paragraph_style',@text:style-name)/style:properties/@fo:font-size" />
374 <!-- For ordered lists we use the bullet tag from Platypus Intra Paragraph Markup -->
376 <xsl:if test="not($size='') and boolean(key('paragraph_style',@text:style-name)/style:properties/@fo:font-size)">
377 <xsl:attribute name="size">
378 <!-- adapt the fontsize to the fontsize of the current paragraph -->
379 <xsl:value-of select="$size" />
382 <seq id="ordered_list" />.</bullet>
388 <xsl:template match="text:drop-down">
389 <xsl:value-of select="text:label[2]/@text:value" />
393 <xsl:template match="text:p|text:h">
394 <xsl:param name="skip_draw" select="1" />
395 <xsl:if test="boolean(key('page_break_before',@text:style-name))" >
399 <xsl:when test="boolean(.//draw:image)">
400 <xsl:call-template name="make_image" />
402 <xsl:when test="boolean(name(..) = 'draw:text-box') and boolean($skip_draw)">
406 <xsl:attribute name="style">
407 <xsl:value-of select="@text:style-name" />
409 <xsl:call-template name="make_listitem" />
410 <xsl:apply-templates />
411 <xsl:call-template name="empty_paragraph" />
415 <xsl:if test="boolean(key('page_break_after',@text:style-name))" >
420 <xsl:template match="text:p/text:tab-stop">
421 <!-- simulate a tabstop -->
422 <xsl:call-template name="distance_point">
423 <xsl:with-param name="background" select="key('paragraph_style',@text:style-name)/style:properties/@fo:background-color" />
424 <xsl:with-param name="tab_stop">yes</xsl:with-param>
428 <!-- experimental - switched off
429 <xsl:template match="text:h">
431 <xsl:attribute name="style">
432 <xsl:value-of select="@text:style-name" />
434 <xsl:call-template name="make_number" />
435 <xsl:apply-templates />
436 <xsl:call-template name="empty_paragraph" />
440 <xsl:template name="make_number">
442 <xsl:when test="@text:level='1'">
443 <xsl:number format="1. " />
445 <xsl:when test="@text:level='2'">
446 <xsl:number count="text:h[@text:level='1']|text:h[text:level='2']" level="any" format="1.1." />
453 <xsl:template match="style:style[@style:family='paragraph']">
455 <xsl:attribute name="name">
456 <xsl:value-of select="@style:name" />
458 <xsl:call-template name="make_indent_paragraph" />
459 <xsl:call-template name="make_fontnames_paragraph" />
460 <xsl:call-template name="make_fontsize" />
461 <!--<xsl:call-template name="make_parent" /> not necessary -
462 parent styles processed by PyOpenOffice -->
463 <xsl:call-template name="make_alignment" />
464 <xsl:call-template name="make_background" />
465 <xsl:call-template name="make_space_beforeafter" />
469 <xsl:template name="make_indent_paragraph">
470 <xsl:variable name="right_indent"><xsl:value-of select="style:properties/@fo:margin-right" /></xsl:variable>
471 <xsl:variable name="left_indent"><xsl:value-of select="style:properties/@fo:margin-left" /></xsl:variable>
472 <xsl:if test="not($right_indent='') and boolean(style:properties/@fo:margin-right)">
473 <xsl:attribute name="rightIndent">
474 <xsl:value-of select="$right_indent" />
477 <xsl:if test="not($left_indent='') and boolean(style:properties/@fo:margin-left)">
478 <xsl:attribute name="leftIndent">
479 <xsl:value-of select="$left_indent" />
484 <xsl:template name="make_background">
485 <xsl:variable name="background">
486 <xsl:value-of select="style:properties/@fo:background-color" />
488 <xsl:if test="not($background='') and boolean(style:properties/@fo:background-color) and starts-with($background,'#')" >
489 <xsl:attribute name="backColor">
490 <xsl:value-of select="$background" />
495 <xsl:template name="make_space_beforeafter">
496 <xsl:variable name="before">
497 <xsl:value-of select="style:properties/@fo:margin-top" />
499 <xsl:variable name="after">
500 <xsl:value-of select="style:properties/@fo:margin-bottom" />
502 <xsl:if test="not($before='') and boolean(style:properties/@fo:margin-top)" >
503 <xsl:attribute name="spaceBefore">
504 <xsl:value-of select="$before" />
507 <xsl:if test="not($after='') and boolean(style:properties/@fo:margin-bottom)" >
508 <xsl:attribute name="spaceAfter">
509 <xsl:value-of select="$after" />
514 <xsl:template name="make_fontsize">
515 <xsl:variable name="fontSize">
516 <xsl:value-of select="style:properties/@fo:font-size" />
518 <xsl:if test="not($fontSize='') and boolean(style:properties/@fo:font-size)">
519 <xsl:attribute name="fontSize">
520 <xsl:value-of select="$fontSize" />
522 <xsl:attribute name="leading">
523 <xsl:value-of select="$fontSize + floor($fontSize div 5) + 1" />
524 <!--use a standard leading related to the font size -->
529 <!--this template is not needed anymore for "normalized" sxw files -->
530 <xsl:template name="make_parent">
531 <xsl:variable name="parent">
532 <xsl:value-of select="@style:parent-style-name" />
534 <xsl:if test="not($parent='') and boolean(@style:parent-style-name)">
535 <xsl:attribute name="parent">
536 <xsl:value-of select="$parent" />
541 <xsl:template name="make_alignment">
542 <xsl:variable name="alignment">
543 <xsl:value-of select="style:properties/@fo:text-align" />
545 <xsl:if test="not($alignment='') and boolean(style:properties/@fo:text-align)">
547 <xsl:when test="$alignment='start'">
548 <xsl:attribute name="alignment">LEFT</xsl:attribute>
550 <xsl:when test="$alignment='center'">
551 <xsl:attribute name="alignment">CENTER</xsl:attribute>
553 <xsl:when test="$alignment='end'">
554 <xsl:attribute name="alignment">RIGHT</xsl:attribute>
556 <xsl:when test="$alignment='justify'">
557 <xsl:attribute name="alignment">JUSTIFY</xsl:attribute>
563 <xsl:template name="make_fontnames_paragraph">
564 <xsl:attribute name="fontName">
565 <xsl:call-template name="make_fontnames">
566 <xsl:with-param name="fontName" select="style:properties/@style:font-name" />
567 <xsl:with-param name="fontWeight" select="style:properties/@fo:font-weight" />
568 <xsl:with-param name="fontStyle" select="style:properties/@fo:font-style" />
573 <xsl:template name="make_fontnames">
574 <!--much too verbose, needs improvement-->
575 <xsl:param name="fontName" />
576 <xsl:param name="fontWeight" />
577 <xsl:param name="fontStyle" />
579 <xsl:when test="not($fontName='') and boolean($fontName)">
581 <xsl:when test="contains($fontName,'Courier')">
583 <xsl:when test="($fontWeight='bold') and ($fontStyle='italic')">
584 <xsl:text>Courier-BoldOblique</xsl:text>
586 <xsl:when test="($fontWeight='bold') and not ($fontStyle='italic')">
587 <xsl:text>Courier-Bold</xsl:text>
589 <xsl:when test="not($fontWeight='bold') and ($fontStyle='italic')">
590 <xsl:text>Courier-Oblique</xsl:text>
593 <xsl:text>Courier</xsl:text>
597 <xsl:when test="contains($fontName,'Helvetica') or contains($fontName,'Arial') or contains($fontName,'Sans')">
599 <xsl:when test="($fontWeight='bold') and ($fontStyle='italic')">
600 <xsl:text>Helvetica-BoldOblique</xsl:text>
602 <xsl:when test="($fontWeight='bold') and not ($fontStyle='italic')">
603 <xsl:text>Helvetica-Bold</xsl:text>
605 <xsl:when test="not($fontWeight='bold') and ($fontStyle='italic')">
606 <xsl:text>Helvetica-Oblique</xsl:text>
609 <xsl:text>Helvetica</xsl:text>
615 <xsl:when test="($fontWeight='bold') and ($fontStyle='italic')">
616 <xsl:text>Times-BoldItalic</xsl:text>
618 <xsl:when test="($fontWeight='bold') and not ($fontStyle='italic')">
619 <xsl:text>Times-Bold</xsl:text>
621 <xsl:when test="not($fontWeight='bold') and ($fontStyle='italic')">
622 <xsl:text>Times-Italic</xsl:text>
625 <xsl:text>Times-Roman</xsl:text>
632 <!--Use this as default -->
633 <xsl:text>Times-Roman</xsl:text>
639 This stylesheet is part of:
640 PyOpenOffice Version 0.4
641 Copyright (C) 2005: Martin Simon
642 Homepage: www.bezirksreiter.de
644 GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999