Quand on insère du code dans un article avec les balises <code>
, on peut avoir une présentation différente en ajustant le style css. Pourtant, pour des gros morceaux de code, ça fait vite mal aux yeux.
Voici une utilisation des points d’entrée dans inc_texte.php3 pour faire du « syntax highlighting » du code inséré dans les articles. Ainsi, comme dans tout bon éditeur de code, on peut voir les mots clefs, nom de fonctions etc... dans des couleurs différentes. On a ainsi une lecture plus rapide.
- La version « simple » utilise une fonction de php existante pour colorer du code php compris entre des balises <ccode> et </ccode>
.
- La version plus complexe nécessite l’installation d’un module php externe disponible ici ou en version améliorée par mes petites mains ici qui permet de colorer n’importe quel langage [1].
les codes spécifiques se trouvent après l’explication.
Méthode
A partir de la version 1.7.1 de SPIP deux points d’entrée dans inc_texte.php3 sont fournis [2]. Ce fichier est responsable du traitement des raccourcis typographiques que les rédacteurs utilisent quand ils écrivent un article (gras, italique, balises code, etc...) :
- avant_propre permet de traiter le texte avant que SPIP ne le traite lui même et donc d’intercepter des raccourcis qui seraient modifiés par SPIP autrement.
- apres_propre permet de traiter le texte après tous les traitements de SPIP.
Vous pouvez donc implémenter, dans votre propre fichier ecrire/mes_options.php des pré/post-traitements pour des nouveaux raccourcis. Voir par exemple cet article, ou ce wiki et cette explication de Fil.
Bon, je vous ment un tout petit peu. Spip, avant d’appeler avant_propre, va échapper (les enlever du texte) certaines parties du texte qui pourraient être sensibles. par exemple le code entre balises <code>
. Une fois tout le traitement typographique fait (et donc après apres_propre), Spip réinsère le texte échappé au bon endroit. On verra ce que cela implique dans quelques instants.
La méthode que l’on va utilisée est la même : échapper le code entre les balises <ccode> </ccode>
pour le réinsérer tout à la fin avec les informations de couleurs.
Version Simple
Ici, je dit version simple, mais elle implique la même utilisation des points d’entrée dans inc_texte. La seule différence est la technique de coloration du code, qui implique une toute petite différence dans le code de ecrire/mes_options.php3.
Coloration
PHP fournie, avec la fonction highlight_string un moyen de colorer du code. Il y a deux conditions :
- il doit s’agir de code PHP [3],
- le code doit être compris entre les balises php standards : <?php et ?>
.
prétraitement du texte
dans ecrire/mes_options.php3
function avant_colorer_code($texte) {
global $code_a_colorer;
$regexp_echap = "(<ccode>(([^<]|<[^/]|</[^c]|</c[^c]|</cc[^o]|</cco[^d]|</ccod[^e]|</ccode[^>])*)<\/ccode>)";
$colo_code_ech=0;
//on échappe tout ce qui se trouve entre <ccode> et </ccode>
while (preg_match($regexp_echap, $texte, $regs)) {
//on stoque le code à colorer pour plus tard.
$code_a_colorer[$colo_code_ech] = $regs[1];
$pos = strpos($texte, $regs[0]);
//on le remplace par une balise <@@colorercode_X@@>
$texte = substr($texte,0,$pos).
"<@@colorercode_$colo_code_ech@@>".
substr($texte,$pos+strlen($regs[0]));
$colo_code_ech++;
}
return $texte;
}
function avant_propre($texte) {
$new_texte = avant_colorer_code($texte);
return $new_texte;
}
}
Ce code permet d’échapper le code qui se trouve entre nos deux balises. On remplace cette partie du texte par une balise spéciale [4] <@@colorercode_..>
qui comprend un index dans le tableau dans lequel on stoque temporairement le code escamoté.
post traitement
dans ecrire/mes_options.php3
function apres_colorer_code($texte) {
global $code_a_colorer;
//on remplace toutes les balises qu'on a insérées par le code coloré.
while (ereg('<@@colorercode_([0-9]+)@@>', $texte, $regs)) {
//on récupère l'indexe du code dans le tableau.
$lenum = $regs[1];
$lecode = highlight_string("<?php".$code_a_colorer[$lenum]."?>",true);
$pos = strpos($texte, $regs[0]);
//on enlève les balises que highlight a ajouté
$lecode = preg_replace("/(<code>|<\/code>)/","",$lecode);
//on insère une nouvelle balise avec un style css.
$texte = substr($texte, 0, $pos).
"<tt><div class='spip_ccode' dir='ltr'>".
$lecode .
"</div></tt>".
substr($texte, $pos + strlen($regs[0]));
}
//on corrige les balises d'échappement de spip qui ont été transformée par highlight.
$find = "/<@@SPIP_(SOURCEPROPRE|SOURCETYPO)([0-9]+)@@>/";
$replace = "<@@SPIP_\\1\\2@@>";
$texte = preg_replace($find,$replace,$texte);
return $texte;
}
function apres_propre($texte) {
$new_texte = apres_colorer_code($texte);
return $new_texte;
}
Cette fonction est donc appelée à la fin du traitement. On y remplace toutes les balises d’échappement (<@@colorercode_..>
) par le code coloré.
On récupère l’index dans le tableau, puis on appelle la fonction highlight sur le code. Il faut ensuite lui faire un petit traitement :
- on ajoute le code de formatage, qui met le code coloré dans un DIV de classe spip_ccode [5],
- on enléve les balises code (html cette fois, pas spip) ajoutées par la fonction highlight,
La dernière étape nécessite quelques explication. Comme mentionné plus tôt, SPIP échappe un certain nombre de chose avant d’appeler avant_propre, et le remplace par des balises spéciales. Si dans notre code, spip a trouvé quelque chose à échappé (par exemple certain code html au milieu du code php), alors il le fera [6].
Mais les balises spéciales spip sont ensuite traitées par l’highlighter, ainsi les < et > sont remplacés par < et >
. On doit donc les retransformer pour avoir des < et >.
Cela pose un deuxième problème, prenons un exemple : Si votre code php contient une balise d’image
$reg = "/<img src='IMG\/([^']+)'.+alt=(.+) title=([^>]+)>/";
,
alors spip va l’échapper :
$reg = "<@@SPIPSOURCEPROPREX@@>";
et le remettre en place après votre traitement du code php. Ainsi la chaine de caractéres ne sera pas colorée, mais prise comme une vraie balise html [7]. il faut donc mettre tout le code html qui se trouve dans votre code php entre balises spip <code>
, sous peine d’avoir de mauvaises surprises. Ainsi notre exemple devra être écrit :
$reg = "/<code><img src='IMG\/([^']+)'.+alt=(.+) title=([^>]+)>
</code>/";
il faut ensuite faire attention au style. Insérez ce code [8] :
dans habillage.css par exemple
.spip_ccode .spip_code{
border: 0px;
padding: 0px;
margin-left: 0px;
background: transparent;
}
dans votre fichier css [9], pour annuler le style .spip_code à l’intérieur d’un bloc .spip_ccode.
Méthode « complexe »
Ici je décris l’installation du code Beautifier et donne un code adapté d’avant_propre et apres_propre. La technique utilisée dans ces deux méthode n’étant pas différente, je ne la redécris pas.
Beautifier
Je vous conseille d’utiliser l’adaptation du beautifier disponible ici [10].
Le beautifier est simple à installer :
- télécharger les fichiers de base,
- télécharger aussi les fichiers de formatages pour les langages qui vous intéressent.
- décompresser les packages où vous voulez dans votre repertoire spip (par exemple dans ecrire/)
- adapté le chemin dans le fichier Beautifier/Init.php
- adapté le chemin dans la fonction décrite ici.
On va donc appeler depuis spip la fonction du beautifier de cette façon :
dans ecrire/mes_options.php3
function my_highlight_string($texte, $file='php3') {
//ajuster le chemin ici
$m8_path = '/users/mortimer/ecrire/beautifier';
require_once "$m8_path/Beautifier/Init.php";
$class_name = "HFile_$file";
require_once "$m8_path/HFile/$class_name.php";
require_once "$m8_path/Output/Output_css.php";
$highlighter = new Core(new $class_name(), new Output_css());
$lecode = nl2br($highlighter->highlight_text($texte));
$lecode = ereg_replace("\t", " ", $lecode);
$lecode = ereg_replace(" ", " ", $lecode);
return $lecode;
}
elle prend deux paramètre : le code à colorer, et le type du fichier (langage).
il vous faudra aussi ajouter ces styles à votre css [9] [11] :
dans habillage.css par exemple
.beautifier_linecomment {
color: green;
}
.beautifier_blockcomment {
color: green;
}
.beautifier_prepro {
color: lightgreen;
}
.beautifier_select {
color: red;
font-weight: bold;
}
.beautifier_quote {
color: coral;
}
.beautifier_1 {
color: blue;
}
.beautifier_2 {
color: cornflowerblue;
}
.beautifier_3 {
color: #e5b23b;
}
.beautifier_4 {
color: gray;
}
code de traitement du raccourcis
avant_propre et apres_propre ne changent pas beaucoup ici, on les adapte juste pour utiliser des balises au format
<ccode(nom_du_langage)> code à colorer </ccode>
le nom du langage etant le nom dans le fichier HFile, par exemple pour du php3, on a un fichier HFile_php3.php, on donnera donc le nom de langage php3.
dans ecrire/mes_options.php3
function avant_colorer_code($texte) {
global $code_a_colorer;
$regexp_echap = "(<ccode\\(([^\\)]+)\\)>(([^<]|<[^/]|</[^c]|</c[^c]|</cc[^o]|</cco[^d]|</ccod[^e]|</ccode[^>])*)<\/ccode>)";
$colo_code_ech=0;
while (preg_match($regexp_echap, $texte, $regs)) {
$code_a_colorer[$colo_code_ech] = $regs[2];
$langage = $regs[1];
$pos = strpos($texte, $regs[0]);
$texte = substr($texte,0,$pos).
"<@@colorercode_".
$langage.
"_$colo_code_ech@@>"
.substr($texte,$pos+strlen($regs[0]));
$colo_code_ech++;
}
return $texte;
}
function apres_colorer_code($texte) {
global $code_a_colorer;
while (ereg('<@@colorercode_([^_]+)_([0-9]+)@@>', $texte, $regs)) {
$lenum = $regs[2];
$lecode = my_highlight_string($code_a_colorer[$lenum],$regs[1]);
$pos = strpos($texte, $regs[0]);
$texte = substr($texte, 0, $pos).
"<tt><div class='spip_ccode' dir='ltr'>".
$lecode.
"</div></tt>".
substr($texte, $pos + strlen($regs[0]));
}
$find = "/<@@SPIP_(SOURCEPROPRE|SOURCETYPO)([0-9]+)@@>/";
$replace = "<@@SPIP_\\1\\2@@>";
$texte = preg_replace($find,$replace,$texte);
return $texte;
}
Discussions par date d’activité
5 discussions
Pour ceux qui ne l’auraient pas vu, dans la partie « compliquée » il manque les fonctions avant_propre et apres_propre à récupérer de la partie « simple » et à mettre dans ecrire/mes_fonctions.php(3) également.
Belle contribution en tout cas !
et pour les autres, ya le plugin tout clef en main et encore plus plein de bonne chose :
http://files.spip.org/spip-zone/col...
Répondre à ce message
Maintenant on peut utiliser en plus du plugin officiel un autre plugin : SyntaxHighlighter pour SPIP
Répondre à ce message
J’ai modifié ta contrib pour utiliser d’autres langages (colorisés à la sauce PHP). Cà peut être utile pour mettre en valeur du code HTML par exemple sans utiliser de programme externe.
Répondre à ce message
Tout d’abord merci pour cet article très intéressant.
Par gout personnel, j’ai remplacé l’utilisation de beautifier par GeSHI. Pour cela, il suffit de modifier la fonction
apres_colorer_code comme ceci :
Sinon, l’on souhaite une expression régulière plus courte en voici une :
normalement, la fonction my_higlight_string et faite pour être modifiée et brancher un autre systéme. C’est peut être un peu plus simple de proposer une nouvelle fonction :
je ne connaissait pas ce script, il a l’air vraiment interessant, est-ce que c’est facile d’ajouter un langage ?
Répondre à ce message
« screenshot » se dit « copie d’écran » ; « syntaxe highlighting » se dit « surlignement syntaxique » ; etc... si si ! c’est important.
100% d’accord avec toi, Hapax.
Malgré tout je suis surpris que ce soit le seul commentaire pour cet intéressant article, qui une application de avant_propre et apres_propre. J’avais déjà lu les explications indiquées en tête de cet article, auxquelles je n’avais rien compris. Me voilà comblé maintenant. Reste plus qu’à utiliser cette contrib et à l’adapter à mes besoins.
Je veux afficher du code HTML, mais j’ai l’impression que c’est l’expression
$regexp_echap = "(<ccode>(([^<]|<[^/]|</[^c]|</c[^c]|</cc[^o]|</cco[^d]|</ccod[^e]|</ccode[^>])*)<\/ccode>)";
qui ne sait pas délimiter certaines séquences ...</ccode.
Pour moi ce genre de regexp, c’est l’enfer ! Je me demande d’ailleurs pourquoi il n’existe pas quelque chose pour interdire une séquence de caractères. Peut-être avec une référence arrière ? mais je ne vois pas trop comment...
et fin de semaine alors !!
bon je n’ai plus le droit d’ecriture sur l’article, ça tombe mal.
je crois qu’on peut faire cela. J’ai découvert après et jamais essayé :
mais attention, il faut aussi reprendre les index plus loin.
Qu’est ce qui passe pas comme code html en fait ?
Escuses. J’ai testé la regexp toute seule. Elle marche très bien. Donc elle n’est pas en cause...
J’ai des balises HTML entre et le script en masque certaines. Je viens de trouver la raison pour certaines : les balises qui entourent une page HTML sont prises pour des raccourcis du même nom. Mais il y a d’autres choses que je ne comprends pas et SPIP met des
@@SPIP_SOURCEPROPREXX@@
(sans <> autour) dans les $code_a_colorer[$colo_code_ech].Ayant utilisé Beautifier avec le fichier html fourni, comme ça ne fonctionnait pas, je suis passé à la méthode simple et encore sans highlight_text. J’utilise une méthode simple pour passer les balises HTML en < et >.
Ok, le problème est expliqué dans l’article :
SPIP appelle sa fonction d’échappement des blocs « code », « html », « cadre » etc... avant celle fournit ici et je n’y peut rien :(
La méthode, vraiment pas cool quand on doit utiliser
<html>
, c’est d’écrire <code><html></code>.La deuxième méthode, pas très cool non plus, c’est les < ; à la place des <.
Dans les deux cas, beautifier sera perdu et ne pourra pas colorer les parties échappées.
Répondre à ce message
Ajouter un commentaire
Avant de faire part d’un problème sur un plugin X, merci de lire ce qui suit :
Merci d’avance pour les personnes qui vous aideront !
Par ailleurs, n’oubliez pas que les contributeurs et contributrices ont une vie en dehors de SPIP.
Suivre les commentaires : |