1<?xml version="1.0" encoding="UTF-8"?>
2
3<!--
4### xsl stylesheet used to convert content.xml file from an odtFile to dokuwiki syntax
5@license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6
7@author Greg BELLAMY <garlik.crx@gmail.com> [Gag]
8
9Version 0.2 Alpha 2012-02-15
10  * Adding this comment
11  * Description of parsed markups
12
13Howto :
14  * Support of some dokuwiki plugin will be set by parameters at the begin of this stylesheet
15
16Supported formatting :
17  * headline lvl 1 to 5
18  * paragraph
19  * char :
20    * underline
21    * bold
22    * italic
23  * table (simple one with few fusionned cell, fusion table display the best with an error message)
24  * pictures
25  * list
26
27Supported plugin :
28  * numberedheading : adding numbering to titles
29
30Advice :
31  * The output is directly dependent on the quality of making the input file. The Use of styles is recommanded.
32
33ToDo (next feature):
34  * Add an language support by setting parameters like plugin support
35
36Source :
37  * This stylesheet is an adaptation of the sheet available at http://wiki.lm7.fr/ to translating a odt file format to mediawiki
38
39###
40-->
41
42<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:office="http://openoffice.org/2000/office" xmlns:style="http://openoffice.org/2000/style" xmlns:text="http://openoffice.org/2000/text" xmlns:table="http://openoffice.org/2000/table" xmlns:draw="http://openoffice.org/2000/drawing" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:number="http://openoffice.org/2000/datastyle" xmlns:svg="http://www.w3.org/2000/svg" xmlns:chart="http://openoffice.org/2000/chart" xmlns:dr3d="http://openoffice.org/2000/dr3d" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="http://openoffice.org/2000/form" xmlns:script="http://openoffice.org/2000/script" xmlns:java="http://xml.apache.org/xslt/java">
43  <xsl:output
44    method="text"
45    encoding="utf-8"
46  />
47  <xsl:param
48    name="numberedheadings"
49    value="0"
50  />
51  <xsl:param
52    name="subtable_message">
53    <xsl:text>FIXME : Subtable detected. Formatting must be corrected.</xsl:text>
54  </xsl:param>
55  <!-- Wont work <xsl:param name="cmtopx" value="37.795275591"/>-->
56  <!-- Get toc sources styles to check paragraphe tag with header style in text:p template -->
57  <xsl:variable name="title_style" value="//text:index-source-styles"/>
58  <xsl:strip-space elements="*"/>
59  <!-- Catch the non-content document sections -->
60  <xsl:template match="/XML"/>
61  <xsl:template match="/office:document-content/office:meta"/>
62  <xsl:template match="/office:document-content/office:settings"/>
63  <xsl:template match="/office:document-content/office:script"/>
64  <xsl:template match="/office:document-content/office:font-face-decls"/>
65  <xsl:template match="/office:document-content/office:document-styles"/>
66  <xsl:template match="/office:document-content/office:automatic-styles"/>
67  <xsl:template match="/office:document-content/office:styles"/>
68  <xsl:template match="/office:document-content/office:master-styles"/>
69  <xsl:template match="/office:document-content/office:body/office:text/office:forms"/>
70  <xsl:template match="/office:document-content/office:body/office:text/text:tracked-changes"/>
71  <xsl:template match="/office:document-content/office:body/office:text/sequence-decls"/>
72  <xsl:template match="//text:table-of-content"/>
73
74<!-- Line-break formatting - This is not a paragraph end -->
75  <xsl:template match="//text:line-break">
76    <xsl:text disable-output-escaping="yes">\\ </xsl:text>
77  </xsl:template>
78
79<!-- Headline formatting -->
80  <xsl:template name="titre" match="//text:h">
81    <xsl:param name="level" select="@text:outline-level"/>
82    <xsl:variable name="chaine"><xsl:call-template name="boucle">
83      <xsl:with-param name="debut" select="1" />
84      <xsl:with-param name="fin" select="7 - $level" />
85      <xsl:with-param name="texte" select="'='" />
86    </xsl:call-template></xsl:variable>
87
88    <xsl:value-of select="$chaine"/>
89    <xsl:text disable-output-escaping="yes"> </xsl:text>
90    <xsl:if test="$numberedheadings = '1'"><xsl:text disable-output-escaping="yes">- </xsl:text></xsl:if>
91    <xsl:apply-templates/>
92    <xsl:text disable-output-escaping="yes"> </xsl:text>
93    <xsl:value-of select="$chaine"/>
94    <xsl:text disable-output-escaping="yes">
95
96</xsl:text>
97  </xsl:template>
98
99  <!-- Text blocks
100  Greg - Transcription des paragraphes
101  Déroulé :
102  Mise en variables des éléments (style, contenu)
103  Si le text n'est pas vide
104    Appel de la mise en forme ouvrante
105    Intégration de contenu
106    Appel de la mise en forme sortante
107    Ajout de retour chariot selon les règles de syntaxe Dokuwiki (le première qui match a gagnée)
108    Si cellule d'un tableau avec plusieurs paragraphes : 1 Retour chariot
109    Si cellule d'un tableau : Pas de retour chariot
110    Si élément d'une liste suivi d'un élément : 1 Retour chariot
111    Si dernier élément d'une liste : 2 Retour chariot
112  Si le text est vide
113    On ne fait rien
114  -->
115  <xsl:template match="//text:p">
116    <xsl:if test=".!='' or count(*) &gt; 0">
117      <xsl:variable name="p_style" select="@text:style-name"/>
118      <xsl:variable name="real_style" select="//style:style[@style:name=$p_style]/@style:parent-style-name"/>
119      <xsl:choose>
120        <!-- Check if it is a wrong defined header (with toc attribute compare), then call header template, otherwise it s a paragraphe -->
121        <xsl:when test="not (ancestor::table:table or ancestor::text:list) and $title_style and $title_style/text:index-source-style[@text:style-name = $real_style]">
122          <xsl:call-template name="titre">
123            <xsl:with-param name="level" select="$title_style[@text:style-name = $real_style]/../@text:outline-level"/>
124          </xsl:call-template>
125        </xsl:when>
126        <xsl:when test="1 = 0"></xsl:when>
127        <xsl:otherwise>
128          <!-- Mise en forme -->
129          <xsl:call-template name="p_render"/>
130          <!-- Aplication des retours chariots selon le contexte -->
131          <xsl:choose>
132            <!-- we shouldn't add a newline for elements inside a table -->
133            <xsl:when test="ancestor::table:table-cell and not(following-sibling::text:p)"/>
134            <!-- but we would want a new between two text:p in a cell -->
135            <xsl:when test="ancestor::table:table-cell and following-sibling::text:p">
136              <xsl:text disable-output-escaping="yes">\\ </xsl:text>
137            </xsl:when>
138            <!-- we do want a single newline at the end of a list item
139            fixme : wont work correctly if a list containt §, something like liste & § -->
140            <xsl:when test="ancestor::text:list-item and following-sibling::text:p">
141              <xsl:text disable-output-escaping="yes">\\ </xsl:text>
142            </xsl:when>
143            <xsl:when test="ancestor::text:list-item">
144              <xsl:text disable-output-escaping="yes">
145</xsl:text>
146              </xsl:when>
147            <!-- and double at the end of the list
148            FIXME Trouver la bonne liaison sinon, l'intégrer ailleurs (sortie de liste par exemple)-->
149            <!--<xsl:when test="preceding-sibling::text:list"><xsl:text disable-output-escaping="yes">
150
151    </xsl:text></xsl:when>-->
152            <xsl:when test="ancestor::text:align='center'">
153              <xsl:text disable-output-escaping="yes">
154              </xsl:text>
155            </xsl:when>
156
157            <!-- Si note de bas de page, pas de retour chariot -->
158            <xsl:when test="ancestor::text:note-body"></xsl:when>
159            <xsl:otherwise>
160              <xsl:text disable-output-escaping="yes">
161
162</xsl:text>
163            </xsl:otherwise>
164          </xsl:choose>
165        </xsl:otherwise>
166      </xsl:choose>
167    </xsl:if>
168  </xsl:template>
169
170
171  <!-- Footnote -->
172  <xsl:template match="//text:note-body">
173    <xsl:text disable-output-escaping="yes">(( </xsl:text>
174    <xsl:apply-templates/>
175    <xsl:text disable-output-escaping="yes"> ))</xsl:text>
176  </xsl:template>
177  <xsl:template match="//text:note-citation"/>
178
179  <xsl:template match="//text:a">
180    <xsl:variable name="link">
181      <xsl:value-of select="@xlink:href"/>
182    </xsl:variable>
183    <xsl:variable name="link-text">
184      <xsl:value-of select="."/>
185    </xsl:variable>
186      <xsl:text disable-output-escaping="yes">[[</xsl:text>
187      <xsl:value-of select="$link"/>
188      <xsl:text disable-output-escaping="yes">|</xsl:text>
189      <xsl:value-of select="."/>
190      <xsl:text disable-output-escaping="yes">]]</xsl:text>
191  </xsl:template>
192
193  <xsl:template match="//text:list-item">
194    <xsl:variable name="level">
195      <xsl:value-of select="count(ancestor::text:list)"/>
196    </xsl:variable>
197
198    <xsl:choose>
199      <!-- Si dernier élément et vide, n'affiche rien -->
200      <xsl:when test="not(following-sibling::text:list-item) and not(text:p | text:a)"></xsl:when>
201      <xsl:otherwise>
202      <!-- Sinon, compte le nombre de listes imbriquées et affiche 2 espaces / niveau -->
203
204        <xsl:call-template name="boucle">
205          <xsl:with-param name="debut" select="1" />
206          <xsl:with-param name="fin" select="$level" />
207          <xsl:with-param name="texte" select="'  '" />
208        </xsl:call-template>
209
210        <!-- Puis affiche le symbole de liste adapté (ordonné et non ordonné) -->
211        <xsl:variable name="stylename" select="./*[1]/@text:style-name"/>
212        <xsl:variable name="listename" select="//style:style[@style:name=$stylename]/@style:list-style-name"/>
213
214        <xsl:choose>
215          <xsl:when test="parent::text:list and //text:list-style[@style:name=$listename]/text:list-level-style-bullet[@text:level=$level]"><xsl:text disable-output-escaping="yes">* </xsl:text></xsl:when>
216          <xsl:otherwise><xsl:text disable-output-escaping="yes">- </xsl:text></xsl:otherwise>
217        </xsl:choose>
218
219      </xsl:otherwise>
220    </xsl:choose>
221    <!-- Enfin, affiche le contenu -->
222    <xsl:apply-templates/>
223  </xsl:template>
224
225  <!-- Tables -->
226  <xsl:template match="//table:table">
227    <!-- Greg - Quelle utilitée ?
228    Element mediawiki supprimés
229    -->
230    <xsl:choose>
231      <xsl:when test="@table:is-sub-table='true'"><xsl:call-template name="subtable"/></xsl:when>
232      <xsl:otherwise><xsl:apply-templates/></xsl:otherwise>
233    </xsl:choose>
234    <!-- New line under a table to dissociate following table -->
235    <xsl:text disable-output-escaping="yes">
236</xsl:text>
237  </xsl:template>
238
239  <xsl:template name="subtable" match="//table:sub-table">
240    <!-- Subtable are hard to transform ! help needed ! -->
241    <xsl:if test="descendant::text:p">
242      <xsl:value-of select="$subtable_message"/>
243      <xsl:apply-templates/>
244    </xsl:if>
245  </xsl:template>
246
247  <!-- Table rows
248  Greg - Traitement d'une ligne
249  Une ligne est composée de cellule
250  Déroulé :
251   Traitement des cellules
252   Ajout d'un caractère de fin de ligne '|\n'
253  -->
254  <xsl:template match="//table:table-row">
255    <xsl:if test="descendant::text:*[text() != ''] or descendant::draw:image">
256      <xsl:apply-templates/>
257      <xsl:text disable-output-escaping="yes">|
258</xsl:text>
259    </xsl:if>
260  </xsl:template>
261
262  <!-- Table cells
263  Greg - Traitement d'une cellule
264  Déroulé :
265   Si cellule dans la zone en-tête
266     affichage en mode en-tête
267   sinon
268     affichage en mode normal
269  Traitement des fusions verticales de cellules FIXME
270  Affichage du contenu
271
272  Opérationnel :
273    Export
274    * tableau simple,
275    * tableau contenant des colonnes fusionnées
276    * tableau contenant des fusions de 2 lignes maximum (au delà, OOo créée des sous-tables complexes
277
278  ToDO : Analyser la syntaxe des tableaux ayant plus de 2 lignes fusionnées.
279  -->
280  <xsl:template match="//table:table//table:table-row/table:table-cell">
281    <xsl:choose>
282    <xsl:when test="ancestor::table:table-header-rows">
283    <xsl:text disable-output-escaping="yes">^</xsl:text>
284    </xsl:when>
285    <xsl:otherwise>
286    <xsl:text disable-output-escaping="yes">|</xsl:text>
287    </xsl:otherwise>
288    </xsl:choose>
289    <xsl:if test="not (*[text() != ''] )"><xsl:text disable-output-escaping="yes"> </xsl:text></xsl:if>
290    <xsl:apply-templates/>
291  </xsl:template>
292
293  <!-- Handles horizontally merged cells
294  Traitement des cellules fusionnées
295  -->
296  <xsl:template match="//table:table//table:table-row/table:covered-table-cell">
297    <!-- Récupération de la position du noeud précédent -->
298    <xsl:variable name="mypos" select="position()"/>
299    <xsl:variable name="prevsib" select="../*[position() &lt; $mypos]"/>
300    <xsl:choose>
301      <xsl:when test="not($prevsib[name()= 'table:table-cell'])">
302        <xsl:text disable-output-escaping="yes">| ::: </xsl:text>
303      </xsl:when>
304      <xsl:otherwise>
305        <xsl:for-each select="$prevsib">
306          <xsl:if test="name() = 'table:table-cell' and not(following-sibling::table:table-cell)">
307            <xsl:choose>
308              <xsl:when test="$mypos &gt; 1 and @table:number-columns-spanned and position() + @table:number-columns-spanned &gt; $mypos">
309                <xsl:choose>
310                  <xsl:when test="ancestor::table:table-header-rows">
311                    <xsl:text disable-output-escaping="yes">^</xsl:text>
312                  </xsl:when>
313                  <xsl:otherwise>
314                    <xsl:text disable-output-escaping="yes">|</xsl:text>
315                  </xsl:otherwise>
316                </xsl:choose>
317              </xsl:when>
318              <xsl:otherwise>
319                <xsl:text disable-output-escaping="yes">| ::: </xsl:text>
320              </xsl:otherwise>
321            </xsl:choose>
322          </xsl:if>
323        </xsl:for-each>
324      </xsl:otherwise>
325    </xsl:choose>
326  </xsl:template>
327
328  <xsl:template match="//draw:frame">
329    <xsl:param name="cmtopx" value="37.795275591"/>
330    <xsl:text disable-output-escaping="yes" >{{</xsl:text>
331    <xsl:value-of select="draw:image/@xlink:href"/>
332    <xsl:if test="not (@svg:width = '' or @svg:height = '')">
333      <xsl:choose><!-- check cm, px, in, etc... -->
334        <xsl:when test="contains( @svg:width,'cm' )">?<xsl:value-of select="floor(number(substring-before(@svg:width,'cm')) * 37.795275591)"/><!--x<xsl:value-of select="floor(number(substring-before(@svg:height,'cm')) * 37.795275591)"/>--></xsl:when>
335        <xsl:otherwise/>
336      </xsl:choose>
337    </xsl:if>
338    <xsl:text disable-output-escaping="yes" >}}</xsl:text>
339  </xsl:template>
340
341  <xsl:template match="//draw:image">
342    <!--<xsl:text disable-output-escaping="yes" >{{</xsl:text>
343    <xsl:value-of select="substring-after(@xlink:href,'/')"/>
344    <xsl:text disable-output-escaping="yes" >}}</xsl:text>-->
345  </xsl:template>
346
347  <!-- Mise en forme des balises span et p
348  Greg - Transcription des mise en forme en ligne
349  Déroulé :
350  Mise en variables des éléments (style, contenu)
351  Si le text n'est pas vide
352    Appel de la mise en forme ouvrante
353    Intégration de contenu
354    Appel de la mise en forme sortante
355  Si le text est vide
356    On ne fait rien
357   -->
358  <xsl:template name="p_render" match="//text:span">
359    <xsl:variable name="style">
360      <xsl:value-of select="@text:style-name"/>
361    </xsl:variable>
362    <xsl:variable name="italic"><xsl:if test="//office:automatic-styles/style:style[@style:name=$style]/style:text-properties/@fo:font-style = 'italic'">//</xsl:if></xsl:variable>
363    <xsl:variable name="bold"><xsl:if test="//office:automatic-styles/style:style[@style:name=$style]/style:text-properties/@fo:font-weight = 'bold'">**</xsl:if></xsl:variable>
364    <xsl:variable name="underline"><xsl:if test="//office:automatic-styles/style:style[@style:name=$style]/style:text-properties/@style:text-underline-style = 'solid'">__</xsl:if></xsl:variable>
365    <xsl:variable name="centre"><xsl:if test="//office:automatic-styles/style:style[@style:name=$style]/style:text-properties/@fo:text-align">&lt;WRAP centeralign&gt;</xsl:if></xsl:variable>
366    <xsl:variable name="indice"><xsl:if test="contains(//office:automatic-styles/style:style[@style:name=$style]/style:text-properties/@style:text-position,'sub')">&lt;sub&gt;</xsl:if></xsl:variable>
367    <xsl:variable name="exposant"><xsl:if test="contains(//office:automatic-styles/style:style[@style:name=$style]/style:text-properties/@style:text-position,'sup')">&lt;sup&gt;</xsl:if></xsl:variable>
368    <xsl:variable name="barre"><xsl:if test="contains(//office:automatic-styles/style:style[@style:name=$style]/style:text-properties/@style:text-crossing-out,'line')">&lt;del&gt;</xsl:if></xsl:variable>
369    <xsl:variable name="text" select="."/>
370    <!-- Si le paragraphe contient du texte ou d'autres éléments -->
371    <xsl:if test="$text!='' or count(*) &gt; 0">
372      <!-- Application des mises en formes -->
373      <!-- Ouverture -->
374      <xsl:value-of select="$italic"/><xsl:value-of select="$bold"/><xsl:value-of select="$underline"/><xsl:value-of select="$centre"/><xsl:value-of select="$indice"/><xsl:value-of select="$exposant"/><xsl:value-of select="$barre"/>
375
376      <xsl:apply-templates/>
377
378      <!-- Fermeture -->
379      <xsl:if test="$barre!=''">&lt;/del&gt;</xsl:if><xsl:if test="$exposant!=''">&lt;/sup&gt;</xsl:if><xsl:if test="$indice!=''">&lt;/sub&gt;</xsl:if><xsl:if test="$centre!=''">&lt;/WRAP&gt;</xsl:if><xsl:value-of select="$underline"/><xsl:value-of select="$bold"/><xsl:value-of select="$italic"/>
380      <!-- Fin application des mises en formes -->
381    </xsl:if>
382  </xsl:template>
383
384  <!-- Display spacing #16 -->
385  <xsl:template match="//text:s">
386    <xsl:text disable-output-escaping="yes"> </xsl:text>
387  </xsl:template>
388
389
390  <!-- Boucle affichant une suite de n éléments identiques où n=fin-debut -->
391  <xsl:template name="boucle">
392    <xsl:param name="debut" select="0" />
393    <xsl:param name="fin" select="0" />
394    <xsl:param name="texte" select="'#'" />
395    <xsl:value-of select="$texte"/>
396    <xsl:if test="$debut &lt; $fin">
397    <xsl:call-template name="boucle">
398      <xsl:with-param name="debut" select="($debut)+1" />
399      <xsl:with-param name="fin" select="$fin" />
400      <xsl:with-param name="texte" select="$texte" />
401    </xsl:call-template>
402    </xsl:if></xsl:template>
403
404</xsl:stylesheet>
405