source: spip-zone/_plugins_/convertisseur/inc/convertisseur.php @ 57284

Last change on this file since 57284 was 57284, checked in by erational@…, 8 years ago

un peu de nettoyage en même temps que le rafraichissement de la doc.
faut il conserver tous les formats (moinmoin ? phpBB ?). prochain chantier virer les eregs + passage à spip3

File size: 17.2 KB
Line 
1<?php
2
3/*
4 * Fonctions de conversion de format
5 */
6
7
8
9function nettoyer_format($t) {
10
11        // resserrer les {}
12        $t = preg_replace('/{([.,]+)/', '\1{', $t);
13        $t = preg_replace('/}([.,]+)/', '\1}', $t);
14        $t = preg_replace(',([^{]){ ,', '\1 {', $t);
15        $t = preg_replace(', }([^}]),', '} \1', $t);
16        $t = preg_replace(',} {,', ' ', $t);
17
18        $t = preg_replace(", +~,", '~', $t);
19        $t = preg_replace(",~ +,", '~', $t);
20        $t = preg_replace("/{([?!., ]?)}/", '\1', $t);
21
22#$a = '«';
23#for($i=0;$i<strlen($a); $i++)
24#       echo ord($a[$i]).'-';exit;
25
26        ## attention ici c'est de l'utf8
27        $t = str_replace("~\xc2\xbb", "\xc2\xbb", $t);  # guillemet >>
28        $t = str_replace("\xc2\xab~", "\xc2\xab", $t);  # <<
29        $t = str_replace ("\xe2\x80\x93", '--', $t); # tiret long
30
31        // supprimer les insecables sauf dans les nombres,
32        // parce que ca prend le chou (?)
33        $t = preg_replace(",(\D)~(\D),", '\1 \2', $t);
34
35        return $t;
36}
37
38
39        // -----------------------------------------------------------------------
40        // Definition des regex pour les Conversions
41        // -----------------------------------------------------------------------
42        global $conv_formats;       // les regex à appliquer
43        global $conv_functions_pre; // les functions à appliquer avant les regex
44
45        $conv_formats = $conv_functions_pre = array();
46
47        // syntaxe SPIP
48        // http://www.spip-contrib.net/IMG/html/antiseche_spip-3.html
49       
50        // Conversion MediaWiki -> SPIP
51  // ref. syntaxe: http://www.mediawiki.org/wiki/Help:Formatting
52  $conv_functions_pre['MediaWiki_SPIP'] = array("convertisseur_add_ln","mediawiki_doQuotes");
53  $conv_formats['MediaWiki_SPIP'] = array(
54      "pattern" => array( 
55        'model'  => "\{\{([^\}\}]*)\}\}",   // FIXME si template ds template       
56         // applies anywhere       
57        'ib' => "<i><b>([^<]*)</b></i>",           
58        'b' => "<b>([^<]*)</b>", 
59        'i'   => "<i>([^<]*)</i>", 
60        'ib_post' => "<ib>([^<]*)</ib>",       
61        // only at the beginning of the line         
62        'h4'     => "\n=====([^=====]*)=====",
63        'h3'     => "\n====([^====]*)====",
64        'h2'     => "\n===([^=====]*)===",
65        'h1'     => "\n==([^==]*)==",
66        'ul_3'     => "\n\*\*\*", 
67        'ul_2'     => "\n\*\*", 
68        'ul_1'     => "\n\*", 
69        'ol_3'     => "\n\#\#\#", 
70        'ol_2'     => "\n\#\#", 
71        'ol_1'     => "\n\#", 
72        'dt'     => "\n\;([^\r]*)", 
73        'dd'     => "\n\:([^\r]*)", 
74        // TODO: Preformatted text
75       
76        // links - http://www.mediawiki.org/wiki/Help:Links
77        'comment' => "<!--([^\-]*)-->",
78        'link_img'  => "\[\[(Image|Media):([^\[\[]*)\]\]", 
79        'link_cat'  => "\[\[(Category|Catégorie|:Category):([^\[\[]*)\]\]",
80        'link_user'  => "\[\[(Utilisateur|User):([^|\[]*)\|([^\[]*)\]\]",  // avec pipe
81        'link_user2'  => "\[\[(Utilisateur|User):([^\[]*)\]\]", 
82        'link_lang'  => "\[\[([^\:\[]*):([^\[]*)\]\]", 
83        'link_int'  => "\[\[([^|\[]*)\|([^\[]*)\]\]",                     // avec pipe
84        'link_int2'  => "\[\[([^\[\[]*)\]\]", 
85        'link_ext0'  => "\nhttp([^ \r]*)", 
86        'link_ext1'  => " http([^ \r]*)", 
87        'link_ext2'  => "\\[([^\\[ ]*) ([^(\\[|)]*)\\]",                  // support ext., supporte plusieurs blancs
88        'ref' => "<ref>", 
89        'ref2' => "</ref>",
90       
91        // TODO: Table (http://www.mediawiki.org/wiki/Help:Tables)
92        ),
93      "replacement" => array(
94        'model'  => "<MODELE_WIKI:\\1>",
95        'ib' => "<ib>\\1</ib>", 
96        'b' => "{{\\1}}",   
97        'i' => "{\\1}", 
98        'ib_post' => "{{<i>\\1</i>}}",
99        'h4'     => "{{{\\1}}}", 
100        'h3'     => "{{{\\1}}}", 
101        'h2'     => "{{{\\1}}}", 
102        'h1'     => "{{{\\1}}}", 
103        'ul_3'     => "-*** ", 
104        'ul_2'     => "-** ", 
105        'ul_1'     => "-* ", 
106        'ol_3'     => "-### ", 
107        'ol_2'     => "-## ", 
108        'ol_1'     => "-# ",
109        'dt'     => "<dt>\\1</dt>", 
110        'dd'     => "<dd>\\1</dd>",
111        'comment' => "",
112        'link_img' => "",
113        'link_cat' => "",
114        'link_user' => "\\3",
115        'link_user2' => "\\2",
116        'link_lang' => "",
117        'link_int'  => "\\2", 
118        'link_int2'  => "\\1", 
119        'link_ext0'  => "[->http\\1]", 
120        'link_ext1'  => " [->http\\1]",   
121        'link_ext2'  => "[\\2->\\1]",
122        'ref'  => "[[ ",
123        'ref2'  => " ]]",
124       
125        )
126  );
127       
128 
129  // Conversion MoinWiki -> SPIP
130  // ref. syntaxe: http://trac.edgewall.org/wiki/WikiFormatting
131  // ref. syntaxe: http://moinmo.in/HelpOnFormatting?highlight=%28formatting%29
132  $conv_formats['MoinWiki_SPIP'] = array(
133      "pattern" => array(
134        'code'   => "{{{([^}}}]*)}}}", // FIXME si } dans {{{ }}}               
135        'bold3'  => "'''''([^''''']*)'''''",
136        'bold2'  => "''''([^'''']*)''''",
137        'bold'   => "'''([^''']*)'''", 
138        'i'      => "''([^'']*)''",     
139        'under'  => "__([^\_]*)__", 
140        'del'    => "~~([^\~]*)~~",
141        'h4'     => "==== ([^ ====]*) ====",
142        'h3'     => "=== ([^ ===]*) ===",
143        'h2'     => "== ([^ ==]*) ==",
144        'h'      => "= ([^ =]*) =", 
145        'link2'  => "\\[([^\\[]*) ([^(\\[| )]*)\\]", // FIXME si plusieurs espaces blanc
146        'cell'   => "\|\|([^\|]*)\|\|",
147        'ul'     => "([^ ]*)\*([^ \*]*)", 
148        'ul_pas2'=> " -\*", 
149        'ul2'    => "  -\*", 
150        'ul3'    => "  -\**",       
151        'ol2'    => "   ([^ ]*)1.([^ 1.]*)",
152        'ol'     => " 1\.([^ 1\.]*)",
153       
154        ),
155      "replacement" => array(
156        'code'   => "<code>\\1</code>",             
157        'bold3'   => "{{\\1}}",
158        'bold2'   => "{{\\1}}", 
159        'bold'   => "{{\\1}}", 
160        'i'      => "{\\1}",       
161        'under'  => "<span class='underline'>\\1</span",
162        'del'    => '<del>\\1</del>',
163        'h4'     => "{{{\\1}}}", 
164        'h3'     => "{{{\\1}}}", 
165        'h2'     => "{{{\\1}}}", 
166        'h'      => "{{{\\1}}}",               
167        'link2'  => "[\\2->\\1]",
168        'cell'   => "|\\1|",       
169        'ul'     => "-*\\2", 
170        'ul_pas2'=> "-*", 
171        'ul2'    => "-**",
172        'ul3'    => "-***",             
173        'ol2'    => "1.#\\2",
174        'ol'     => "-#\\1", 
175        )
176  );
177 
178  // Conversion BBcode -> SPIP
179  // ref. syntaxe: http://en.wikipedia.org/wiki/BBCode
180  // voir aussi la version filtre: http://www.spip-contrib.net/Du-BBcode-dans-SPIP 
181  // question: detecter si barre enrichie pour adopter la syntaxte etendue ?
182  $conv_formats['BBcode_SPIP'] = array(
183      "pattern" => array(
184        'url'   => "\\[url]([^\\[]*)\\[/url\\]",
185        'url2'  => "\\[url=([^\\[]*)\\]([^\\[]*)\\[/url\\]",
186        'email' => "\\[email\\]([^\\[]*)\\[/email\\]",
187        'email2'=> "\\[email=([^\\[]*)\\]([^\\[]*)\\[/email\\]",
188        'color' => "\\[color=([^\\[]*)\\]([^\\[]*)\\[/color\\]",
189        'size'  => "\\[size=([^\\[]*)\\]([^\\[]*)\\[/size\\]",
190        //'list'  => "!\[list\](.+)\[/list\]!Umi",
191        //'list2' => "!\[\*\](.+)(?=(\[\*\]|</ul>))!Umi",
192        'code'  => "\\[code]([^\\[]*)\\[/code\\]",
193        'quote' => "\\[quote]([^\\[]*)\\[/quote\\]",
194        'b'     => "\\[b]([^\\[]*)\\[/b\\]",
195        'i'     => "\\[i]([^\\[]*)\\[/i\\]",
196        'center'=> "\\[center]([^\\[]*)\\[/center\\]",
197        'img'   => "\\[img]([^\\[]*)\\[/img\\]",
198      ),
199      "replacement" => array(
200        'url'   => "[\\1->\\1]",
201        'url2'  => "[\\2->\\1]",
202        'email' => "[\\1->mailto:\\1]",
203        'email2'=> "[\\2->mailto:\\1]",
204        'color' => "<span style=\"color:\\1\">\\2</span>",
205        'size'  => "<span style=\"font-size:\\1px\">\\2</span>",
206        //'list'  => "<ul> $1 </ul>",
207        //'list2' => "<li>$1</li>",
208        'code'   => "<code>\\1</code>",
209        'quote'  => "<quote>\\1</quote>",
210        'b'      => "{{\\1}}",
211        'i'      => "{\\1}",
212        'center' => "<div style=\"text-align:center:\\1\">\\2</div>",
213        'img'    => "<img src=\"\\1\" alt='' />",
214      )     
215  );
216 
217  // Conversion SPIP -> txt
218  $conv_formats['SPIP_txt'] = array(
219      "pattern" => array(
220        'h'     => "{{{([^}}}]*)}}}",
221        'b'     => "{{([^}}]*)}}",
222        'i'     => "{([^}]*)}",
223        'url'   => "\\[([^\\[]*)->([^(\\[| )]*)\\]",         
224      ),
225      "replacement" => array(
226        'h'   => "\\1\n",
227        'b'   => "* \\1 *",
228        'i'   => "\\1",
229        'url' => "\\1 (\\2)",       
230      )     
231  );
232 
233  // Conversion DotClear -> SPIP
234  // http://doc.dotclear.net/1.2/usage/syntaxes
235  $conv_formats['DotClear_SPIP'] = array(
236      "pattern" => array(
237        // faux amis
238        'q3' => '{{([^{]*)\|([^\{]*)\|([^\{]*)}}',       
239        'q2' => '{{([^{]*)\|([^\{]*)}}',
240        'q' => '{{([^{]*)}}',
241       
242        // type bloc
243        'h3'  => "\n\!\!\!([^\r]*)",
244        'h4'  => "\n\!\!([^\r]*)",
245        'h5'   => "\n\!([^\r]*)", 
246        'ul'   => "\n\* ([^\r]*)",
247        'ol'   => "\n# ([^\r]*)",     // FIXME gerer les ss listes
248       
249        // en ligne
250        'br'   => "%%%", 
251        'em' => '\'\'([^\']*)\'\'',
252        'strong' => '__([^\_]*)__',
253        'ins' => '\+\+([^\+]*)\+\+',
254        'del' => '--([^\+]*)--',
255        'code'=> '@@([^\@]*)@@',
256        'img' => '\(\(([^\)]*)\)\)',
257        'href_0' => '\[([^\|[]*)\]',                                  // 0 pipe
258        'href_3' => '\[([^\[]*)\|([^\[]*)\|([^\[]*)\|([^\[\|]*)\]',   // 3 pipes
259        'href_2' => '\[([^\[]*)\|([^\[]*)\|([^\[\|]*)\]',             // 2 pipes
260        'href_1' => '\[([^\[]*)\|([^\[\|]*)\]',                       // 1 pipe
261        'a' => '~([^~]*)~',
262        'acronym' => '\?\?([^\?]*)\|([^\?]*)\?\?',
263        'note' => '\$\$([^\$]*)\$\$',
264       
265       
266      ),
267      "replacement" => array(
268        // faux amis
269        'q3' => '<quote>\\1</quote>',       
270        'q2' => '<quote>\\1</quote>',
271        'q' => '<quote>\\1</quote>',
272       
273        // type bloc
274        'h3'   => "{{{\\1}}}",
275        'h4'   => "{{{\\1}}}", 
276        'h5'   => "{{{\\1}}}", 
277        'ul'   => "\n-* \\1",
278        'ol'   => "\n-# \\1",       
279       
280        // en ligne
281        'br'   => "\n_ ",
282        'em'   => "{{\\1}}",
283        'strong'   => "{{\\1}}",
284        'ins'   => "<ins>\\1</ins>",
285        'del'   => "<del>\\1</del>",
286        'code'   => "<code>\\1</code>",
287        'img'   => "",
288        'href_0'   => "[->\\1]",
289        'href_3' => '[\\2->\\1]',
290        'href_2' => '[\\2->\\1]',
291        'href_1' => '[\\2->\\1]',
292        'a' => '[\\1<-]',
293        'acronym'   => "<acronym  title=\"\\2\">>\\1</acronym>",
294        'note' => '[[\\1]]',
295      )     
296  );
297 
298  // Conversion XTG -> SPIP
299  // format demandé par Jean Luc Girard
300  // http://195.13.83.33/twiki/bin/view/FipDoc/QuarkTagsList
301  // http://www.macworld.com/downloads/magazine/XPressTagsList.pdf   
302  // cf. extract/quark.php
303  $conv_formats['XTG_SPIP'] = 'quark';
304
305  // conversion DOCX
306  $conv_formats['DOCX_SPIP'] = 'docx';
307
308
309  // Conversion SLA (Scribus) -> SPIP
310  // SLA 1.2 http://docs.scribus.net/index.php?lang=en&sm=scribusfileformat&page=scribusfileformat
311  // SLA 1.3 http://wiki.scribus.net/index.php/File_Format_for_Scribus_1.3.x
312  $conv_formats['SLA_SPIP'] = array(
313      "pattern" => array(
314        'ch'    => " CH=\"([^\"]*)\" ",  // "CH=\"<([^>]*)\""
315        'br'    => "&#x5;",
316        'sp'    => "&#x1d;",       
317        'tag'   => "<([^\>]*)>", 
318
319      ),
320      "replacement" => array(
321        'ch'   => ">\\1<",
322        'br'   => "\n\n\n",
323        'sp'   => " ",
324        'tag'   => "",
325      )     
326  );
327
328
329  $conv_formats['XPressTags'] = 'quark'; // function extract/
330  $conv_formats['Word'] = 'doc'; // function extract/
331  $conv_formats['RTF'] = 'rtf'; // function extract/
332  $conv_formats['PDF'] = 'pdf'; // function extract/
333  $conv_formats['html_SPIP'] = 'html'; // function HTML2SPIP
334
335
336        // FIN INITIALISATION
337
338
339
340
341
342function conversion_format($conv_in, $format) {
343        global $log;
344
345        global $conv_formats;
346        global $conv_functions_pre;
347
348        $conv_out = $conv_in;
349
350        // S'agit-il d'un tableau de conversion ?
351        // si non, ca peut etre une fonction, par exemple un extracteur
352        if (is_array($conv_formats[$format])) {
353
354                // fonctions pre traitement ?
355                if (is_array($conv_functions_pre[$format])) {
356                        include_spip("inc/fonction_convertisseur");
357                        foreach($conv_functions_pre[$format] as $key=>$pattern)
358                                $conv_out = $pattern($conv_out);
359                }
360
361
362                // on convertit (en avant les regex!)
363                foreach($conv_formats[$format]['pattern'] as $key=>$pattern) {
364                        $replacement = $conv_formats[$format]['replacement'][$key];
365                        $conv_out = eregi_replace($pattern, $replacement, $conv_out);
366                }
367        }
368
369        // fonction HTML2SPIP - http://ftp.espci.fr/pub/html2spip/
370        else if ($format=="html_SPIP") {       
371          if (file_exists(find_in_path('lib/html2spip-0.6/misc_tools.php'))) {                 
372                require_once(find_in_path('lib/html2spip-0.6/misc_tools.php'));
373                require_once(find_in_path('lib/html2spip-0.6/HTMLEngine.class'));
374                require_once(find_in_path('lib/html2spip-0.6/HTML2SPIPEngine.class'));
375                //define('_HTML2SPIP_PRESERVE_DISTANT',false);
376                $parser = new HTML2SPIPEngine('', _DIR_IMG);    // Quels sont les bons parametres ?
377                $parser->loggingEnable();
378                $output = $parser->translate($conv_out);
379                $conv_out = $output['default']; 
380           } else {
381                  // utilisation de sale
382                  // limitation: echoue sur les pages completes ou trop complexes
383                  include_spip("inc/sale");
384                  $conv_out = sale($conv_out); 
385           }
386               
387  }
388
389        // c'est un nom de fonction : 'quark' par exemple
390        else {
391                if (is_string($conv_formats[$format])) {
392                        $cv = $conv_formats[$format];
393                        include_spip("extract/$cv");
394                        if ($cv = $GLOBALS['extracteur'][$cv]) {
395                                ecrire_fichier(_DIR_TMP.'convertisseur.tmp', $conv_in);
396                                $conv_out = $cv(_DIR_TMP.'convertisseur.tmp', $charset);
397                                supprimer_fichier(_DIR_TMP.'convertisseur.tmp');
398                                include_spip('inc/charsets');
399                                $conv_out = importer_charset($conv_out, $charset);
400                        }
401
402                        if ($cv AND !$conv_out)
403                                $log = "<span style='color:red'>"
404                                        ._T("convertisseur:erreur_extracteur")
405                                        ." $cv</span>";
406                        }
407                        if (!$cv)
408                                $log = "<span style='color:red'>"
409                                        ._T("convertisseur:unknown_format")
410                                        ."</span>";
411                }
412
413        return $conv_out;
414}
415
416# callback pour le deballage d'un zip telecharge
417# http://www.phpconcept.net/pclzip/man/en/?options-pclzip_cb_pre_extractfunction
418// cf. http://doc.spip.org/@callback_deballe_fichier
419function callback_admissibles($p_event, &$p_header) {
420        if (accepte_fichier_upload2($p_header['filename'])) {
421                $p_header['filename'] = _tmp_dir
422                        . preg_replace(',\W,', '-', basename($p_header['filename']));
423                return 1;
424        } else {
425                return 0;
426        }
427}
428
429function accepte_fichier_upload2($f) {
430        if (!preg_match(",.*__MACOSX/,", $f)
431        AND !preg_match(",^\.,", basename($f)))
432                return true;
433}
434
435function inserer_conversion($texte, $id_rubrique, $f=null) {
436        global $log;
437
438        $id_rubrique = intval($id_rubrique);
439        $id_auteur = $GLOBALS['auteur_session']['id_auteur'];
440
441        // Verifier que la rubrique existe et qu'on a le droit d'y ecrire
442        if (!$t = sql_fetsel('id_rubrique', 'spip_rubriques', 'id_rubrique='.$id_rubrique)) {
443                $log = "erreur la rubrique n'existe pas";
444                return false;
445        }
446
447        // Si $f (chargement zip), on cherche un article du meme $f
448        // (valeur stockée dans le PS)
449        // dans la meme rubrique,
450        // avec le statut prepa, qui nous appartient, et... on l'ecrase
451        $ps = 'Conversion depuis '.basename($f);
452        $s = spip_query("SELECT a.id_article
453                FROM spip_articles AS a,
454                spip_auteurs_articles AS aut
455                WHERE id_rubrique=$id_rubrique
456                AND ps=".sql_quote($ps)."
457                AND aut.id_article=a.id_article
458                AND aut.id_auteur=".$id_auteur
459                );
460        if ($t = spip_fetch_array($s)) {
461                $id_article = $t['id_article'];
462        } else {
463                // regler lang + id_secteur
464                $q = sql_fetsel('id_secteur,lang', 'spip_rubriques',
465                        'id_rubrique='.intval($id_rubrique)
466                );
467
468                $champs = array(
469                        'titre' => $ps,
470                        'statut' => 'prepa',
471                        'id_rubrique' => $id_rubrique,
472                        'id_secteur' => $q['id_secteur'],
473                        'lang' => $q['lang'],
474                        'ps' => $ps
475                        );
476
477                // Envoyer aux plugins
478                $champs = pipeline('pre_insertion',
479                        array(
480                                'args' => array(
481                                        'table' => 'spip_articles',
482                                ),
483                                'data' => $champs
484                        )
485                );
486
487                $id_article = sql_insertq('spip_articles', $champs);
488
489                pipeline('post_insertion',
490                        array(
491                                'args' => array(
492                                        'table' => 'spip_articles',
493                                        'id_objet' => $id_article
494                                ),
495                                'data' => $champs
496                        )
497                );
498
499                if ($id_article>0
500                AND $id_auteur>0) {
501                        sql_insertq('spip_auteurs_articles',
502                                array(
503                                'id_article' => $id_article,
504                                'id_auteur' => $id_auteur
505                                )
506                        );
507                }
508        }
509
510        // en cas d'echec de l'insertion
511        if (!$id_article) {
512                $log = "erreur insertion d'article";
513                return;
514        }
515
516        // Si on a repere des <ins class='titre'> etc, les inserer
517        // dans les bons champs ; note : on choisi <ins> pour eviter les erreurs
518        // avec <div> qui est plus courant
519        $c = array('texte' => $texte);
520        foreach (array('surtitre', 'titre', 'soustitre', 'chapo') as $champ) {
521                if (preg_match(",<ins class='$champ'>(.*?)</ins>\n*,ims", $texte, $r)
522                AND strlen($x = trim($r[1]))) {
523                        $c[$champ] = $x;
524                        $c['texte'] = substr_replace($c['texte'], '', strpos($c['texte'], $r[0]), strlen($r[0]));
525                }
526        }
527
528        $r = '';
529        foreach ($c as $var => $val)
530                $r .= "$var="._q(trim($val)).', ';
531
532        spip_query("UPDATE spip_articles
533                SET $r
534                date=NOW(),
535                date_modif=NOW()
536                WHERE id_article=$id_article"
537        );
538
539        return $id_article;
540}
541
542
543?>
Note: See TracBrowser for help on using the repository browser.