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