source: spip-zone/_plugins_/coloration_code/trunk/public/format_html_geshi.php @ 111500

Last change on this file since 111500 was 107904, checked in by marcimat@…, 3 years ago

Revert partiel de r107599 et r107601 : Inclure peut accepter un appel avec parenthèse (un fichier .php) (oui… longue histoire tout ça).
On restreint drastiquement cependant l’utilisation de parenthèse dans cette coloration au seul cas que ça devrait concerner.
De plus on évite de faire afficher le texte des styles sur une inclusion {fond=#TOTO} (toujours avec le colorieur spip3).

File size: 11.7 KB
Line 
1<?php
2
3/*****************************************************************************\
4 *  Decompilateur créant une syntaxe avec des <| class='' > pour GESHI 1.0.8 *
5\*****************************************************************************/
6
7if (!defined('_ECRIRE_INC_VERSION')) {
8        return;
9}
10
11
12/**
13 * Encadre un texte donne par un code <| style='x'|code|> ou <| class='x'|code|>
14 * que GESHI remplacera ensuite par des spans
15 *
16 * L'encadrement tient compte du fait que l'on veut des styles inline
17 * ou des classes CSS dans le code genere par GESHI
18 *
19 * On indique le type de style que l'on veut (KEYWORDS) et son numero (30)
20 * Il faut se referer a geshi/geshi/spip3.php pour avoir les correspondances.
21 *
22 * @param string $code
23 *              Le code a encadrer
24 * @param string $styles_geshi_name
25 *              Un des types de styles dans Geshi ( KEYWORDS uniquement utilise pour l'instant )
26 * @param int $styles_geshi_key
27 *              Le numero de style dans le groupe precedent.
28 * @return string
29 *              Le code encadre.
30**/
31function format_to_geshi_spip($code, $styles_geshi_name, $styles_geshi_key) {
32        static $use_style = null;
33        static $styles = array();
34        static $classes = array();
35
36        // utiliser des styles ou des classes
37        if (is_null($use_style)) {
38                // geshi/spip3.php doit forcement etre deja charge !
39                include_spip('geshi/geshi/spip3');
40                $styles = geshi_language_data_spip3_styles();
41                $use_style = (!defined('PLUGIN_COLORATION_CODE_STYLES_INLINE') OR PLUGIN_COLORATION_CODE_STYLES_INLINE);
42                $classes = array(
43                        'KEYWORDS' => 'kw'
44                );
45        }
46
47        $style  = $styles[ $styles_geshi_name ][ $styles_geshi_key ];
48        $classe = $classes[ $styles_geshi_name ] . $styles_geshi_key;
49        $in = $use_style ? "style=\"$style\"" : "class=\"$classe\"";
50        $code = "<| $in>$code|>";
51        return $code;
52}
53
54
55
56
57/**
58 * Demande d'encadrer un texte pour geshi selon un code de couleur demande.
59 *
60 *
61 * @param string $code
62 *              Le code a encadrer
63 * @param string $quoi
64 *              Un type de couleur plus lisible que les mots cles de GESHI
65 *              La correspondance est fait avec les tags GESHI dans cette fonction.
66 * @param bool $echapper
67 *              Echappe le texte au passage selon la methode de GESHI
68 *              Evidemment, il ne faut pas le faire 2 fois pour un meme texte !
69 * @return string
70 *              Le code encadre.
71**/
72function format_geshi_spip($code, $quoi, $echapper=true) {
73        // echapper le code en mode geshi
74        if ($echapper) {
75                $code = geshi_hsc($code);
76        }
77
78        // ajouter l'encadrement geshi
79        switch($quoi) {
80                case 'boucle':
81                        $code = format_to_geshi_spip($code, 'KEYWORDS', 10);
82                        break;
83                case 'boucle_table':
84                        $code = format_to_geshi_spip($code, 'KEYWORDS', 11);
85                        break;
86                case 'boucle_critere':
87                        $code = format_to_geshi_spip($code, 'KEYWORDS', 12);
88                        break;
89
90                case 'balise':
91                        $code = format_to_geshi_spip($code, 'KEYWORDS', 20);
92                        break;
93                case 'balise_boucle':
94                        $code = format_to_geshi_spip($code, 'KEYWORDS', 21);
95                        break;
96                case 'balise_etoile':
97                        $code = format_to_geshi_spip($code, 'KEYWORDS', 22);
98                        break;
99                       
100                case 'balise_crochet':
101                        $code = format_to_geshi_spip($code, 'KEYWORDS', 25);
102                        break;
103                case 'balise_parenthese':
104                        $code = format_to_geshi_spip($code, 'KEYWORDS', 26);
105                        break;
106
107                case 'filtre':
108                        $code = format_to_geshi_spip($code, 'KEYWORDS', 30);
109                        break;
110                case 'parametre':
111                        $code = format_to_geshi_spip($code, 'KEYWORDS', 31);
112                        break;
113                case 'parametre_contenu':
114                        $code = format_to_geshi_spip($code, 'KEYWORDS', 32);
115                        break;
116
117                case 'inclure':
118                        $code = format_to_geshi_spip($code, 'KEYWORDS', 40);
119                        break;
120                case 'inclure_fichier':
121                        $code = format_to_geshi_spip($code, 'KEYWORDS', 41);
122                        break;
123
124                case 'polyglotte':
125                        $code = format_to_geshi_spip($code, 'KEYWORDS', 50);
126                        break;
127                case 'polyglotte_langue':
128                        $code = format_to_geshi_spip($code, 'KEYWORDS', 51);
129                        break;
130                case 'polyglotte_contenu':
131                        $code = format_to_geshi_spip($code, 'KEYWORDS', 52);
132                        break;
133
134                case 'idiome':
135                        $code = format_to_geshi_spip($code, 'KEYWORDS', 60);
136                        break;
137                case 'idiome_module':
138                        $code = format_to_geshi_spip($code, 'KEYWORDS', 61);
139                        break;
140                case 'idiome_chaine':
141                        $code = format_to_geshi_spip($code, 'KEYWORDS', 62);
142                        break;
143
144                case 'operateur':
145                        $code = format_to_geshi_spip($code, 'KEYWORDS', 70);
146                        break;
147
148                case 'nombre':
149                        $code = format_to_geshi_spip($code, 'KEYWORDS', 80);
150                        break;
151        }
152        return $code;
153}
154
155
156/**
157 * Copie de la methode GESHI->hsc() (geshi/geshi.php)
158 * servant a echapper les textes.
159**/
160function geshi_hsc($string, $quote_style = ENT_COMPAT) {
161        // init
162        static $aTransSpecchar = array(
163                '&' => '&amp;',
164                '"' => '&quot;',
165                '<' => '&lt;',
166                '>' => '&gt;',
167
168                //This fix is related to SF#1923020, but has to be applied
169                //regardless of actually highlighting symbols.
170
171                //Circumvent a bug with symbol highlighting
172                //This is required as ; would produce undesirable side-effects if it
173                //was not to be processed as an entity.
174                ';' => '<SEMI>', // Force ; to be processed as entity
175                '|' => '<PIPE>' // Force | to be processed as entity
176                );                      // ENT_COMPAT set
177
178        switch ($quote_style) {
179                case ENT_NOQUOTES: // don't convert double quotes
180                        unset($aTransSpecchar['"']);
181                        break;
182                case ENT_QUOTES: // convert single quotes as well
183                        $aTransSpecchar["'"] = '&#39;'; // (apos) htmlspecialchars() uses '&#039;'
184                        break;
185        }
186
187        // return translated string
188        return strtr($string, $aTransSpecchar);
189}
190
191
192
193
194/**
195 * <BOUCLES>
196 * Fonction automatiquement appelee par le decompilateur
197 * pour recreer le code d'une boucle.
198 *
199**/
200function format_boucle_html_geshi ($avant, $nom, $type, $crit, $corps, $apres, $altern, $prof)
201{
202        $avant = $avant ? format_geshi_spip("<B$nom>", "boucle") . "$avant" : "";
203        $apres = $apres ? "$apres" . format_geshi_spip("</B$nom>", "boucle") : "";
204        $altern = $altern ? "$altern" . format_geshi_spip("<//B$nom>", "boucle") : "";
205        if (!$corps) {
206                $corps = format_geshi_spip(" />", "boucle");
207        } else {
208                $corps = format_geshi_spip(">", "boucle") . $corps . format_geshi_spip("</BOUCLE$nom>", "boucle");
209        }
210        return "$avant"
211                . format_geshi_spip("<BOUCLE$nom", "boucle")
212                . format_geshi_spip("($type)", "boucle_table")
213                . "$crit$corps$apres$altern";
214}
215
216
217
218
219// raccourcis pour {parametre}
220function _format_parametre_html_geshi($param, $echapper=true) {
221        if (!$param) return '';
222
223        if (is_array($param)) {
224                $param = join(format_geshi_spip(", ", 'parametre'), $param);
225        }
226
227        return   format_geshi_spip("{", 'parametre')
228                   . format_geshi_spip($param, 'parametre_contenu', $echapper)
229                   . format_geshi_spip("}", 'parametre');
230}
231
232
233
234
235/**
236 * <INCLURE>
237 * Fonction automatiquement appelee par le decompilateur
238 * pour recreer le code d'une inclusion.
239 *
240 **/
241function format_inclure_html_geshi ($file, $args, $prof)
242{
243        if (
244                strpos($file, '#') === false
245                and substr($file,-4) === '.php'
246        ) {
247                $t =  format_geshi_spip("(", 'inclure')
248                        . format_geshi_spip($file, 'inclure_fichier')
249                        . format_geshi_spip(")", 'inclure');
250        } else {
251                $t = _format_parametre_html_geshi("fond=" . $file, false);
252        }
253        $args = _format_parametre_html_geshi($args, false);
254
255        return (
256                format_geshi_spip("<INCLURE", 'inclure')
257                . $t . $args
258                . format_geshi_spip(" />", 'inclure'));
259}
260
261
262/**
263 * <multi>[fr]texte</multi>
264 *
265 * Fonction automatiquement appelee par le decompilateur
266 * pour recreer le code d'un polyglotte.
267 *
268**/
269function format_polyglotte_html_geshi ($args, $prof)
270{
271        $contenu = array(); 
272        foreach($args as $l=>$t)
273                $contenu[]= ($l ? format_geshi_spip("[$l]", 'polyglotte_langue') : '') . $t;
274
275        return (
276                  format_geshi_spip("<multi>", 'polyglotte')
277                . format_geshi_spip(join(" ", $contenu), 'polyglotte_contenu', false)
278                . format_geshi_spip("</multi>", 'polyglotte')
279        );
280}
281
282
283
284/**
285 * <:chaine_de_langue:>
286 *
287 * Fonction automatiquement appelee par le decompilateur
288 * pour recreer le code d'un idiome.
289 *
290**/
291function format_idiome_html_geshi ($nom, $module, $args, $filtres, $prof)
292{
293        foreach ($args as $k => $v) {
294                $args[$k] = "$k" . format_geshi_spip("=", 'operateur') . "$v";
295        }
296        $args = _format_parametre_html_geshi($args, false);
297        return (
298                  format_geshi_spip("<:", 'idiome')
299                . ($module ? format_geshi_spip($module, 'idiome_module') . format_geshi_spip(":", 'idiome') : "")
300                . format_geshi_spip($nom, 'idiome_chaine')
301                . $args
302                . $filtres
303                . format_geshi_spip(":>", 'idiome')
304        );
305}
306
307
308
309/**
310 * #BALISE
311 * [(#BALISE)]
312 *
313 * Fonction automatiquement appelee par le decompilateur
314 * pour recreer le code d'une balise.
315 *
316**/
317function format_champ_html_geshi ($nom, $boucle, $etoile, $avant, $apres, $args, $filtres, $prof)
318{
319        $nom = format_geshi_spip("#", 'balise')
320        . ($boucle ? format_geshi_spip($boucle . ":", 'balise_boucle') : "")
321        . format_geshi_spip($nom, 'balise')
322        . format_geshi_spip($etoile, 'balise_etoile')
323        . $args
324        . $filtres;
325
326        // Determiner si c'est un champ etendu,
327        $s = ($avant OR $apres OR $filtres
328              OR (strpos($args, '(#') !==false)); // ## A VERIFIER !!
329
330        // champ simple
331        if (!$s) {
332                return $nom;
333        }
334
335        return format_geshi_spip("[", 'balise_crochet')
336                        . $avant
337                        . format_geshi_spip("(", 'balise_parenthese')
338                        . $nom
339                        . format_geshi_spip(")", 'balise_parenthese')
340                        . $apres
341                        . format_geshi_spip("]", 'balise_crochet');
342}
343
344
345
346/**
347 * {criteres de boucles}
348 *
349 * Fonction automatiquement appelee par le decompilateur
350 * pour recreer les criteres d'une boucle.
351 *
352**/
353function format_critere_html_geshi ($critere)
354{
355        foreach ($critere as $k => $crit) {
356                $crit_s = '';
357                foreach ($crit as $operande) {
358                        list($type, $valeur) = $operande;
359                        if ($type == 'champ' AND $valeur[0]=='[') {
360                          $valeur = substr($valeur,1,-1);
361                          if (preg_match(',^[(](#[^|]*)[)]$,sS', $valeur))
362                                $valeur = substr($valeur,1,-1);
363                        }
364                        $crit_s .= $valeur;
365                }
366                $critere[$k] = $crit_s;
367        }
368        return (!$critere ? "" : format_geshi_spip(
369                geshi_hsc("{") . join(", ", $critere). geshi_hsc("}"),
370                "boucle_critere", false));
371}
372
373
374/**
375 * {parametres de balises}
376 * |filtre{parametres de filtres}
377 *
378 * Fonction automatiquement appelee par le decompilateur
379 * pour recreer les parametres d'une balise,
380 * les filtres et leurs parametres.
381 *
382**/
383function format_liste_html_geshi ($fonc, $args, $prof)
384{
385        return ((($fonc!=='')
386                ? format_geshi_spip("|$fonc", 'filtre')
387                : $fonc)
388        . _format_parametre_html_geshi($args, false));
389}
390
391
392/**
393 *
394 * Fonction automatiquement appelee par le decompilateur
395 * pour concatener les morceaux tel que "#TITRE #TITRE"
396 * = "#TITRE" + " " + "#TITRE" (3 morceaux)
397 *
398 * Concatenation sans separateur: verifier qu'on ne cree pas de faux lexemes
399 *
400**/ 
401function format_suite_html_geshi ($args)
402{
403        for($i=0; $i < count($args)-1; $i++) {
404                list($texte, $type) = $args[$i];
405                list($texte2, $type2) = $args[$i+1];
406                if (!$texte OR !$texte2) continue; 
407                $c1 = substr($texte,-1);
408                if ($type2 !== 'texte') {
409                  // si un texte se termine par ( et est suivi d'un champ
410                  // ou assimiles, forcer la notation pleine
411                        if ($c1 == '(' AND substr($texte2,0,1) == '#')
412                                $args[$i+1][0] = _format_suite_html_geshi_notation_balise_pleine($texte2);
413                } else {
414                        if ($type == 'texte') continue;
415                        // si un champ ou assimiles est suivi d'un texte
416                        // et si celui-ci commence par un caractere de champ
417                        // forcer la notation pleine
418                        if (($c1 == '}' AND substr(ltrim($texte2),0,1) == '|')
419                        OR (preg_match('/[\w\d_*]/', $c1) AND preg_match('/^[\w\d_*{|]/', $texte2)))
420                                $args[$i][0] = _format_suite_html_geshi_notation_balise_pleine($texte);
421                }
422        }
423        return join("", array_map('array_shift', $args));
424}
425
426
427// Raccourci pour ajouter [( et )] sur une balise
428function _format_suite_html_geshi_notation_balise_pleine($balise) {
429        return
430                  format_geshi_spip("[", 'balise_crochet')
431                . format_geshi_spip("(", 'balise_parenthese')
432                . $balise
433                . format_geshi_spip(")", 'balise_parenthese')
434                . format_geshi_spip("]", 'balise_crochet');
435}
436
437
438/**
439 * Du texte
440 *
441**/
442function format_texte_html_geshi ($texte)
443{
444        if (is_numeric($texte)) {
445                return format_geshi_spip($texte, 'nombre');
446        } else {
447                return geshi_hsc($texte);
448        }
449}
450
Note: See TracBrowser for help on using the repository browser.