10 novembre 2008

Afficher correctement du code dans vos blogs

Dernièrement, j'ai cherché une manière d'afficher correctement du code sur mon blog. En cherchant un petit peu, j'ai trouvé la balise HTML <pre> qui garde l'indentation des lignes. Rien qu'avec cela, le code publié est déjà beaucoup plus lisible. En voici un exemple :

using System.Collections.Generic;

namespace HelloWorld
{
class Program
{
static void Main(string[] args)
{
using(WorkflowRuntime workflowRuntime = new WorkflowRuntime())
{
AutoResetEvent waitHandle = new AutoResetEvent(false);
workflowRuntime.WorkflowCompleted += delegate(object sender, WorkflowCompletedEventArgs e) {waitHandle.Set();};
workflowRuntime.WorkflowTerminated += delegate(object sender, WorkflowTerminatedEventArgs e)
{
Console.WriteLine(e.Exception.Message);
waitHandle.Set();
};


Malheureusement, je n'ai pas trouvé de script ou d'addin fournissant une solution "clé en main" de mise en forme du code, supportant la colorisation de mots clés et l'indentation. Je vous propose donc un petit bout de code Javascript permettant de faire cela.

Voici les objectifs du script de mise en forme:

  • Rechercher toutes les balises ayant l'attribut name comportant la valeur code et appliquer la fonction formatterElement

  • La fonction formatterElement recherche l'ensemble des mots clés fournit par le tableau motCles et rajoute autour la balise <span class="motcle"> mot clé </span>

Pour installer le script sur un blog de type Blogspot, copiez les styles CSS et les fonctions Javascript suivants quelque part dans la balise head de votre modèle.

<style type="text/css">
div.code
{
background : #F0F0F0;
border: 1px solid black;
padding:5px;
margin:5px;
}
span.motcle
{
color:Blue;
}
</style>
<script type="text/javascript">
var regexpEchampement = unescape("([ \(\)\{\},\t\n\r%3C%3E\[;&])");
var motsCles = [
"public",
"private",
"protected",
"sealed",
"partial",
"static",
"class",
"struct",
"interface",
"using",
"namespace",
"object",
"string",
"int",
"bool",
"float",
"double",
"decimal",
"void",
"in",
"out",
"extern",
"true",
"false",
"new",
"if",
"for",
"foreach",
"throw",
"while",
"return",
"case",
"break",
"try",
"catch",
"finally",
"get",
"set",
"typeof",
"delegate"
];

function formatterElements(nameElement) {
var codeElements = document.getElementsByName(nameElement);
eval(unescape("for (var j = 0; j %3C codeElements.length; j++) { formatterElement(codeElements[j]); }"));
}

function formatterElement(element) {
element.className = "code";

var code = null;
if ("outerHTML" in element) {
}
else {
code = element.innerHTML;

var loop = "for ( var i = 0 ; i %3C motsCles.length ; i++) { var reg = new RegExp(regexpEchampement + \"(\" + motsCles[i] + \")\" + regexpEchampement, \"g\"); code = code.replace(reg, unescape(\"%241%3Cspan%20class%3D%27motcle%27%3E%242%3C/span%3E%243\"));}";
eval(unescape(loop));

element.innerHTML = code;
}
}
</script>


Remarquez que le tableau motsCles contient pas mal de mots clés du langage C#. Libre à vous d'ajouter/supprimer des mots clés. De même, vous pouvez aussi modifier les 2 styles CSS.

Ensuite, ajoutez ce petit bout de javascript juste avant la fermeture de la balise body (</body>):
<script type="text/javascript">
formatterElements("code");
</script>

Voila le script est installé.
Pour l'utiliser, il suffit juste d'ajouter une balise pre et une balise div ou autre avec l'attribut name (ainsi que id="code", à cause de la méthode getElementByName d'IE qui regarde uniquement l'id des éléments) contenant la valeur code. Exemple :

<pre><div name="code" id="code" ></pre>
public Impersonation(string pIdentifiant, string pMotDePasse, string pDomaine )
{
_identifiant = pIdentifiant;
_motDePasse = pMotDePasse;
_domaine = pDomaine;
}
</div></pre>

Ce qui donne :

public Impersonation(string pIdentifiant, string pMotDePasse, string pDomaine )
{
_identifiant = pIdentifiant;
_motDePasse = pMotDePasse;
_domaine = pDomaine;
}


EDIT : Pour l'instant, le script fonctionne à merveille sous Firefox, mais ne fonctionne pas vraiment sous IE 7/8. Cela vient du fait que toute affectation de la variable innerHtml d'un élément sous Internet Explorer normalise la chaine de caractères, et enlève l'ensemble tous les retours à la ligne et les espaces de plus de 2 caractères. Pour l'instant, je n'ai pas trouvé de contournement ...

3 commentaires:

tomlev a dit…

Pas mal !

Personnellement je n'utilise pas javascript, mais le formateur de Jean-Claude Manoli.

L'avantage est qu'il n'y a pas de problème de compatibilité Javascript du navigateur, et la feuille de style utilisée est assez simple pour être traitée correctement par tous les navigateurs. Il suffit de l'intégrer dans le template du blog, après l'avoir éventuellement personnalisée.

Aussi, un petit conseil : ajoute "overflow: auto" dans le style de ta balise PRE pour ajouter des scrollbars, sinon les lignes trop longues débordent de la zone visible...

Popul a dit…

Effectivement, le formateur de JC Manoli m'a l'air vraiment bien.

Je pense que je vais l'essayer :) Surtout que ma solution ne fonctionne pas encore correctement sur IE ...

En tout cas merci du tuyau

Christopher MANEU a dit…

En fait ca existe !
http://www.dreamprojections.com/syntaxhighlighter/?ref=about
;)