1<?xml version="1.0" encoding="UTF-8"?> 2 3<!-- 4### xsl stylesheet used to convert content.xml file from an odt file 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(*) > 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:when test="text:p/@text:style-name = 'Table_20_Heading'"> 286 <xsl:text disable-output-escaping="yes">^</xsl:text> 287 </xsl:when> 288 <xsl:otherwise> 289 <xsl:text disable-output-escaping="yes">|</xsl:text> 290 </xsl:otherwise> 291 </xsl:choose> 292 <xsl:if test="not (*[text() != ''] )"><xsl:text disable-output-escaping="yes"> </xsl:text></xsl:if> 293 <xsl:apply-templates/> 294 </xsl:template> 295 296 <!-- Handles horizontally merged cells 297 Traitement des cellules fusionnées 298 --> 299 <xsl:template match="//table:table//table:table-row/table:covered-table-cell"> 300 <!-- Récupération de la position du noeud précédent --> 301 <xsl:variable name="mypos" select="position()"/> 302 <xsl:variable name="prevsib" select="../*[position() < $mypos]"/> 303 <xsl:choose> 304 <xsl:when test="not($prevsib[name()= 'table:table-cell'])"> 305 <xsl:text disable-output-escaping="yes">| ::: </xsl:text> 306 </xsl:when> 307 <xsl:otherwise> 308 <xsl:for-each select="$prevsib"> 309 <xsl:if test="name() = 'table:table-cell' and not(following-sibling::table:table-cell)"> 310 <xsl:choose> 311 <xsl:when test="$mypos > 1 and @table:number-columns-spanned and position() + @table:number-columns-spanned > $mypos"> 312 <xsl:choose> 313 <xsl:when test="ancestor::table:table-header-rows"> 314 <xsl:text disable-output-escaping="yes">^</xsl:text> 315 </xsl:when> 316 <xsl:when test="text:p/@text:style-name = 'Table_20_Heading'"> 317 <xsl:text disable-output-escaping="yes">^</xsl:text> 318 </xsl:when> 319 <xsl:otherwise> 320 <xsl:text disable-output-escaping="yes">|</xsl:text> 321 </xsl:otherwise> 322 </xsl:choose> 323 </xsl:when> 324 <xsl:otherwise> 325 <xsl:text disable-output-escaping="yes">| ::: </xsl:text> 326 </xsl:otherwise> 327 </xsl:choose> 328 </xsl:if> 329 </xsl:for-each> 330 </xsl:otherwise> 331 </xsl:choose> 332 </xsl:template> 333 334 <xsl:template match="//draw:frame"> 335 <xsl:param name="cmtopx" value="37.795275591"/> 336 <xsl:text disable-output-escaping="yes" >{{</xsl:text> 337 <xsl:value-of select="draw:image/@xlink:href"/> 338 <xsl:if test="not (@svg:width = '' or @svg:height = '')"> 339 <xsl:choose><!-- check cm, px, in, etc... --> 340 <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> 341 <xsl:otherwise/> 342 </xsl:choose> 343 </xsl:if> 344 <xsl:text disable-output-escaping="yes" >}}</xsl:text> 345 </xsl:template> 346 347 <xsl:template match="//draw:image"> 348 <!--<xsl:text disable-output-escaping="yes" >{{</xsl:text> 349 <xsl:value-of select="substring-after(@xlink:href,'/')"/> 350 <xsl:text disable-output-escaping="yes" >}}</xsl:text>--> 351 </xsl:template> 352 353 <!-- Mise en forme des balises span et p 354 Greg - Transcription des mise en forme en ligne 355 Déroulé : 356 Mise en variables des éléments (style, contenu) 357 Si le text n'est pas vide 358 Appel de la mise en forme ouvrante 359 Intégration de contenu 360 Appel de la mise en forme sortante 361 Si le text est vide 362 On ne fait rien 363 --> 364 <xsl:template name="p_render" match="//text:span"> 365 <xsl:variable name="style"> 366 <xsl:value-of select="@text:style-name"/> 367 </xsl:variable> 368 <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> 369 <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> 370 <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> 371 <xsl:variable name="centre"><xsl:if test="//office:automatic-styles/style:style[@style:name=$style]/style:text-properties/@fo:text-align"><WRAP centeralign></xsl:if></xsl:variable> 372 <xsl:variable name="indice"><xsl:if test="contains(//office:automatic-styles/style:style[@style:name=$style]/style:text-properties/@style:text-position,'sub')"><sub></xsl:if></xsl:variable> 373 <xsl:variable name="exposant"><xsl:if test="contains(//office:automatic-styles/style:style[@style:name=$style]/style:text-properties/@style:text-position,'sup')"><sup></xsl:if></xsl:variable> 374 <xsl:variable name="barre"><xsl:if test="contains(//office:automatic-styles/style:style[@style:name=$style]/style:text-properties/@style:text-crossing-out,'line')"><del></xsl:if></xsl:variable> 375 <xsl:variable name="text" select="."/> 376 <!-- Si le paragraphe contient du texte ou d'autres éléments --> 377 <xsl:if test="$text!='' or count(*) > 0"> 378 <!-- Application des mises en formes --> 379 <!-- Ouverture --> 380 <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"/> 381 382 <xsl:apply-templates/> 383 384 <!-- Fermeture --> 385 <xsl:if test="$barre!=''"></del></xsl:if><xsl:if test="$exposant!=''"></sup></xsl:if><xsl:if test="$indice!=''"></sub></xsl:if><xsl:if test="$centre!=''"></WRAP></xsl:if><xsl:value-of select="$underline"/><xsl:value-of select="$bold"/><xsl:value-of select="$italic"/> 386 <!-- Fin application des mises en formes --> 387 </xsl:if> 388 </xsl:template> 389 390 <!-- Display spacing #16 --> 391 <xsl:template match="//text:s"> 392 <xsl:text disable-output-escaping="yes"> </xsl:text> 393 </xsl:template> 394 395 396 <!-- Boucle affichant une suite de n éléments identiques où n=fin-debut --> 397 <xsl:template name="boucle"> 398 <xsl:param name="debut" select="0" /> 399 <xsl:param name="fin" select="0" /> 400 <xsl:param name="texte" select="'#'" /> 401 <xsl:value-of select="$texte"/> 402 <xsl:if test="$debut < $fin"> 403 <xsl:call-template name="boucle"> 404 <xsl:with-param name="debut" select="($debut)+1" /> 405 <xsl:with-param name="fin" select="$fin" /> 406 <xsl:with-param name="texte" select="$texte" /> 407 </xsl:call-template> 408 </xsl:if></xsl:template> 409 410</xsl:stylesheet> 411