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

Last change on this file since 111500 was 109855, checked in by nicolas.dorigny@…, 2 years ago

Passer par le balisage de pre&code s'il est installé

File size: 6.9 KB
Line 
1<?php
2/**
3 * Plugin coloration code
4 * Fonctions spécifiques au plugin
5 *
6 * @package SPIP\Coloration_code\Fonctions
7 */
8
9if (!defined('_ECRIRE_INC_VERSION')) {
10        return;
11}
12
13include_spip('inc/plugin');
14
15// pour interdire globalement et optionnellement le téléchargement associé
16if (!defined('PLUGIN_COLORATION_CODE_TELECHARGE')) {
17        define('PLUGIN_COLORATION_CODE_TELECHARGE', true);
18}
19
20// pour utiliser des styles inline (ou des classes css)
21if (!defined('PLUGIN_COLORATION_CODE_STYLES_INLINE')) {
22        define('PLUGIN_COLORATION_CODE_STYLES_INLINE', true); // false mettra des class et une css associe
23}
24
25// pour mettre des classes css MAIS ne mettre aucun style correspondant
26// cela suppose donc qu'une CSS externe a ce plugin s'occupe de les styler
27if (!defined('PLUGIN_COLORATION_CODE_SANS_STYLES')) {
28        define('PLUGIN_COLORATION_CODE_SANS_STYLES', false); // true mettra des class mais pas de css associe
29}
30
31// pouvoir definir la taille des tablations (defaut de geshi : 8)
32// define('PLUGIN_COLORATION_CODE_TAB_WIDTH', 4);
33
34// Liens externes sur les mots cles de langage (defaut de geshi : true)
35if (!defined('PLUGIN_COLORATION_CODE_LIENS_LANGAGE')) {
36        define('PLUGIN_COLORATION_CODE_LIENS_LANGAGE', true); // false pour les eviter
37}
38
39if (!defined('PLUGIN_COLORATION_CODE_COLORIEUR_SPIP')) {
40        define('PLUGIN_COLORATION_CODE_COLORIEUR_SPIP', 'spip');
41}
42
43function coloration_code_color($code, $language, $cadre = 'cadre', $englobant = 'div') {
44
45        // On ajoute une argument a la fonction pour permettre d'afficher du code dans des <span>
46        // plutot que dans un <div>. Par contre, cette option de span est a utiliser avec la balise <code>
47        // et pas <cadre> pour des raisons de validite et de presentation.
48        // En outre, le bouton telecharger n'est pas affiche.
49        if ($cadre == 'cadre') {
50                $englobant = 'div';
51        }
52        $balise_code = ($englobant == 'div' ? "div" : "code");
53
54        // Supprime le premier et le dernier retour chariot
55        $code = preg_replace("/^(\r\n|\n|\r)*/", "", $code);
56        $code = preg_replace("/(\r\n|\n|\r)*$/", "", $code);
57
58        $params   = explode(' ', $language);
59        $language = array_shift($params);
60
61        if ($language == 'spip') {
62                $language = PLUGIN_COLORATION_CODE_COLORIEUR_SPIP;
63        }
64        if ($language == 'bibtex' and _COLORATION_BIBTEX_COMME_BIBLATEX == 1) {
65                $language = 'biblatex';
66        }
67        include_spip('inc/spip_geshi');
68        //
69        // Create a GeSHi object
70        //
71        $geshi = new SPIP_GeSHi($code, $language);
72        if ($geshi->error()) {
73                return false;
74        }
75        global $spip_lang_right;
76
77        // eviter des ajouts abusifs de CSS par Geshy
78        // qui pose des 'font-family: monospace;' un peu partout
79        // et que FF ne gere pas comme les autres navigateurs (va comprendre).
80        $geshi->set_overall_style('');
81        $geshi->set_code_style('');
82
83        $stylecss = "";
84        if (!PLUGIN_COLORATION_CODE_STYLES_INLINE OR PLUGIN_COLORATION_CODE_SANS_STYLES) {
85                $geshi->enable_classes();
86                if (!PLUGIN_COLORATION_CODE_SANS_STYLES) {
87                        $stylecss = "<style type='text/css'>" . $geshi->get_stylesheet() . "</style>";
88                }
89        }
90
91        if (defined('PLUGIN_COLORATION_CODE_TAB_WIDTH') and PLUGIN_COLORATION_CODE_TAB_WIDTH) {
92                $geshi->set_tab_width(PLUGIN_COLORATION_CODE_TAB_WIDTH);
93        }
94
95        // permettre de supprimer les liens vers les documentations sur les mots cles de langage
96        if (!PLUGIN_COLORATION_CODE_LIENS_LANGAGE) {
97                $geshi->enable_keyword_links(false);
98        }
99
100        include_spip('inc/texte');
101        $code = echappe_retour($code);
102
103        $telecharge = ($englobant == 'div')
104                && (PLUGIN_COLORATION_CODE_TELECHARGE || in_array('telechargement', $params))
105                && (strpos($code, "\n") !== false) && !in_array('sans_telechargement', $params);
106        if ($telecharge) {
107                // Gerer le fichier contenant le code au format texte
108                $nom_fichier = md5($code);
109                $dossier     = sous_repertoire(_DIR_VAR, 'cache-code');
110                $fichier     = "$dossier$nom_fichier.txt";
111
112                if (!file_exists($fichier)) {
113                        ecrire_fichier($fichier, $code);
114                }
115        }
116
117        /**
118         * On insère un attribut data-clipboard-text si on n'a pas le lien de téléchargement car pas de saut de ligne
119         */
120        $datatext         = !$telecharge && PLUGIN_COLORATION_CODE_TELECHARGE;
121        $datatext_content = "";
122        if ($datatext) {
123                $datatext_content = ' data-clipboard-text="' . attribut_html($code) . '"';
124        }
125
126        if ($cadre == 'cadre' OR $englobant == "div") {
127                $geshi->set_header_type(GESHI_HEADER_DIV);
128                $geshi->enable_line_numbers(GESHI_NORMAL_LINE_NUMBERS);
129        } else {
130                $geshi->set_header_type(GESHI_HEADER_NONE);
131                $geshi->enable_line_numbers(GESHI_NO_LINE_NUMBERS);
132        }
133
134        //
135        // And echo the result!
136        //
137        if (defined('_DIR_PLUGIN_PRECODE') && _DIR_PLUGIN_PRECODE) {
138                // si le plugin PRECODE est activé, on utilise son balisage moderne
139                // header <pre> pour ne pas générer de <br>
140                $geshi->set_header_type(GESHI_HEADER_PRE);
141                $geshi->enable_line_numbers(GESHI_NO_LINE_NUMBERS);
142                $code_corps = $geshi->parse_code();
143                // supprimer le <pre> englobant, qui sera ajouté par PRECODE
144                $code_corps = trim(preg_replace('!^<pre[^>]*>|</pre>$!', '', $code_corps), "\n\r");
145                $rempl      = precode_balisage_code('class="' . $language . '"', $code_corps);
146        } else {
147                $rempl = $stylecss . '<' . $englobant . ' class="coloration_code ' . $cadre . '"><' . $balise_code . ' class="spip_' . $language . ' ' . $cadre . '"' . $datatext_content . '>' . $geshi->parse_code() . '</' . $balise_code . '>';
148                if ($telecharge) {
149                        $rempl .= "<p class='download " . $cadre . "_download'><a href='$fichier'>" . _T('bouton_download') . "</a></p>";
150                }
151                $rempl .= '</' . $englobant . '>';
152        }
153
154        return $rempl;
155}
156
157/**
158 * Est-ce à Geshi de traiter les codes et cadres ou on utilise les fonctions natives de SPIP
159 *
160 * @param array $regs
161 *
162 * @return string $ret
163 */
164function cadre_ou_code($regs) {
165
166        // pour l'instant, on oublie $matches[1] et $matches[4] les attributs autour de class="machin"
167        if (preg_match(',^(.*)class=("|\')(.*)\2(.*)$,Uims', $regs[2], $matches)) {
168                $englobant = "div";
169                if ($regs[1] == "code" AND strpos($regs[3], "\n") === false) {
170                        $englobant = "span";
171                }
172                if ($ret = coloration_code_color($regs[3], $matches[3], $regs[1], $englobant)) {
173                        return $ret;
174                }
175        } else {
176                // traiter les <cadre> sans class par precode pour ne pas générer de <textarea>
177                if ($regs[1] == "cadre" && defined('_DIR_PLUGIN_PRECODE') && _DIR_PLUGIN_PRECODE) {
178                        return precode_balisage_code('class=""', trim($regs[3]));
179                }
180        }
181
182        if ($regs[1] == 'code') {
183                return defined('_DIR_PLUGIN_PRECODE') && _DIR_PLUGIN_PRECODE ?
184                        precode_traiter_echap_code($regs) : traiter_echap_code_dist($regs);
185        }
186       
187        return defined('_DIR_PLUGIN_PRECODE') && _DIR_PLUGIN_PRECODE ?
188                precode_traiter_echap_cadre($regs) : traiter_echap_cadre_dist($regs);
189}
190
191/**
192 * Surcharge de la fonction traiter_echap_code_dist native de SPIP
193 * cf : ecrire/inc/texte_mini
194 *
195 * @param array $regs
196 *
197 * @return string
198 */
199function traiter_echap_code($regs) {
200        return cadre_ou_code($regs);
201}
202
203/**
204 * Surcharge de la fonction traiter_echap_cadre_dist native de SPIP
205 * cf : ecrire/inc/texte_mini
206 *
207 * @param array $regs
208 *
209 * @return string
210 */
211function traiter_echap_cadre($regs) {
212        return cadre_ou_code($regs);
213}
Note: See TracBrowser for help on using the repository browser.