Coloration Syntaxique en GWT

Vous connaissez peut-être Rockslide, qui permet de réaliser une présentation (des slides) en GWT.

Qui dit slides techniques dit exemples de code, et donc coloration syntaxique.

J’ai creusé un peu le sujet pour finalement retenir une solution.

Comment faire de la coloration syntaxique côté client, en GWT ?

Solutions disponibles

A ma connaissance, il n’existe pas de solution de coloration syntaxique spécifique à GWT, ce qui nous laisse trois options :

  • Implémenter une solution en GWT (c’est mort, je n’ai pas que ça à faire)

  • Trouver une solution en Java et adapter la partie graphique (fausse bonne idée)

  • Trouver une solution en Javascript et réaliser un binding GWT (ça, c’est dans mes cordes)

Un rapide tour d’horizon fait ressortir deux frameworks Javascript très utilisés pour la coloration syntaxique :

Les deux semblent maintenus, des releases récentes sont disponibles. Mon choix se porte sur SyntaxHighlighter, qui semble plus beau. C’est purement subjectif, mais je trouve que le code mis en couleur par highlight.js a un petit air vieillot.

gwt-syntaxhighlighter

Coup de bol : je tombe sur gwt-syntaxhighlighter, une intégration assez poussée de SyntaxHighlighter dans GWT.

Trop poussée, hélas :

  • gwt-syntaxhighlighter utilise des Generators, ce qui allonge le temps de compilation,

  • gwt-syntaxhighlighter comporte quelques bugs qui ne sont pas corrigés et qui sont difficiles à contourner,

  • la version de SyntaxHighlighter utilisée n’est pas à jour (les versions récentes apportent pourtant des évolutions intéressantes).

De plus, il s’avère que l’intégration de SyntaxHighlighter est relativement aisée, beaucoup plus simple que ce que tente de faire gwt-syntaxhighlighter.

Intégration GWT de SyntaxHighlighter

Charger les scripts et les CSS

Tout d’abord, il faut télécharger SyntaxHighlighter. Les dossiers scripts et styles contiennent tout ce dont vous aurez besoin.

Ces fichiers devront être inclus dans l’application GWT. Il existe différentes méthodes. J’ai choisi de créer un répertoire public au même niveau que le répertoire client, et d’y placer les répertoires scripts et styles.

Ensuite, il suffit de les ajouter au module (fichier .gwt.xml) :

<?xml version="1.0" encoding="UTF-8"?>
<module>

    <!-- La CSS de base pour SyntaxHighlighter -->
    <stylesheet src="styles/shCore.css"/>

    <!-- J'utilise le thème Eclipse (8 thèmes disponibles) -->
    <stylesheet src="styles/shThemeEclipse.css"/>

    <!-- Le javascript de base pour SyntaxHighlighter -->
    <script src="scripts/shCore.js"/>

    <!-- Les extensions pour les différents langages utilisés -->
    <script src="scripts/shBrushJava.js"/>
    <script src="scripts/shBrushXml.js"/>

    <!-- [...] -->
</module>

Go, Go, GO!

A l’origine, SyntaxHighlighter fonctionnait en parsant le DOM et en modifiant les nœuds marqués comme conteneurs de code. La dernière release propose une approche alternative, qui fonctionne indépendamment du DOM.

Le fonctionnement est simple : une fonction Javascript prend en entrée du code sous forme de String, et renvoie une String contenant le HTML pour afficher le code formaté.

Un brush (pinceau) est nécessaire pour colorer du code. Il existe en fait un brush par langage, et celui-ci définit les mots clés, la syntaxe, etc.

Il nous faut donc une fabrique de pinceaux :

public class BrushFactory {
    public native JavaScriptObject newJavaBrush() /*-{
        return new $wnd.SyntaxHighlighter.brushes.Java();
    }-*/;

    public native JavaScriptObject newXmlBrush() /*-{
        return new $wnd.SyntaxHighlighter.brushes.Xml();
    }-*/;
}

Voici le code JSNI utilisant SyntaxHighlighter pour transformer du code en html :

public class SyntaxHighlighter {
    public static native String highlight(String code, JavaScriptObject brush, boolean toolbar) /*-{
        var params = {};
        params['toolbar'] = toolbar;
        brush.init(params);
        return brush.getHtml(code);
    }-*/;
}

Notez le paramètre toolbar qui permet d’afficher ou non la barre d’outil. De nombreux paramètres sont disponibles ; à vous de les intégrer.

Ya plus qu’à utiliser tout ça, par exemple en récupérant le code contenu dans une TextArea et en l’affichant via un HTML.

public void bindTextAreaCodeToHtml(TextArea textArea, HTML html) {
    JavaScriptObject brush = BrushFactory.newJavaBrush();
    String code = textArea.getValue();
    String htmlCode = SyntaxHighlighter.highlight(code, brush, false);
    html.setHTML(htmlCode);
}

Conclusion

Vous avez désormais toutes les clés en main pour faire de la coloration syntaxique côté client en GWT.

Bien entendu, ce code est à adapter suivant vos besoins. Vous n’êtes pas obligés d’utiliser des static partout ;-) .

Comments

Raphaël Brugier (@rbrugier)

Hello,

Intéressant je n’avais pas suivi le développement de SyntaxHighlighter avec la nouvelle méthode sans le parsing du DOM.

J’avais utilisé GWT + le plugin sur mon projet de stage l’an dernier presque de la même façon

En tout cas continue les posts sur gwt, il y a du public

Raphaël.

Piwaï

Cool :) Je vais tâcher de continuer, j’ai quelques idées dans mon sac :)