Kit : Améliorations de la gestion du code
Date de publication : 16/11/2006 , Date de mise à jour : 28/01/2006
1. En résumé
2. Nouvelles fonctionnalités
2.1. Numérotation des lignes de code
2.2. Liaison avec un fichier
2.3. Code dissimulable
2.4. Overflow
2.5. Meilleure coloration
2.5.1. Avantages
2.5.2. Inconvénients
3. Nouveau système de coloration
3.1. L'API de coloration
3.2. Créez vos propres modes
3.3. Personnalisez la coloration
1. En résumé
Je vais vous présenter quelques modifications que j'ai apportées au Kit actuel (version 5.9) pour améliorer la gestion des codes.
Pour commencer, on va faire le tour de quelques petites fonctionnalités du style : numérotation des lignes de code, liens avec un fichier ou encore les codes enroulables.
Dans la seconde partie, je vais détailler les modifications faites au système de coloration syntaxique. Différences, avantages et inconvénients par rapport à l'ancien système. Je vais aussi vous montrer comment créer un système de coloration si votre langage favori ne se trouve pas dans la centaine proposée. Par la même occasion, vous verrez comment modifier/étendre un langage, s'il ne vous convient pas dans l'état actuel.
Dans les deux parties suivantes, vous pourrez voir quelques exemples de coloration syntaxique. La première contient les langages déjà présents avec l'ancien système de coloration (ainsi, vous pourrez me dire ce qu'il y a à modifier, puisqu'il y a des différences), et la seconde quelques nouveaux.
Pour finir, vous trouverez en fin d'article les liens vers les sources (l'API Java utilisée) et vers une version du kit utilisant les binaires.
2. Nouvelles fonctionnalités
2.1. Numérotation des lignes de code
Si on met en place ce nouveau système de gestion du code, vous pourrez numéroter les codes que vous proposez en exemple dans vos cours, tutoriels ou FAQs. Cela peut faciliter les explications ultérieures que vous ferrez sur ces mêmes codes. Voici un exemple :
package hello;
public class HelloWorld {
public static void main (String[] args) {
System.out.println (" Hello world !!! " );
}
}
|
Regardez, tout se joue en ligne 7. ;)
Vous pouvez aussi spécifier la "ligne de départ" pour des extraits de fichiers. Par exemple :
public static void main (String[] args) {
System.out.println (" Hello world !!! " );
}
|
Voici le code qui a permis de générer les extraits ci-dessus :
< code langage = " java " showLines = " 1 " > ...< / code >
...
< code langage = " java " showLines = " 1 " startLine = " 5 " > ...< / code >
|
2.2. Liaison avec un fichier
Si vous utilisez la possibilité de numéroter vos codes, il peut être intéressant, nottament dans le cas d'extraits, de fournir le fichier complet à télécharger. Voici un exemple :
package hello;
public class HelloWorld {
public static void main (String[] args) {
System.out.println (" Hello world !!! " );
}
}
|
Et voici le code pour le kit :
< code langage = " java " showLines = " 1 " fichier = " ./fichiers/HelloWorld.java.txt " > ...< / code >
|
Voyons maintenant comment vous pouvez "dissimuler" votre code, si celui-ci est trop long/volumineux/laid ;)
2.3. Code dissimulable
Si certains de vos exemples sont trop "longs", il peut être pas mal de pouvoir les cacher, au moins temporairement, pour pouvoir continuer à lire tranquillement les explications qui tournent autour. Voici un exemple (clickouillez sur les flèches) :
Apache conf |
ServerRoot " /opt/lampp "
Listen 80
|
Le code à utiliser pour l'effet est :
< code langage = " apacheconf " titre = " Apache conf " dissimulable = " 0 " >
|
|
Ceci dit, pour ces effets, il faudra bien veiller à ce qu'ils ne soient pas bloquants pour certains visiteurs, qu'ils ne vont pas casser la validité XHTML du truc et que la fonctionnalité qu'ils proposent est accessible même sans JS. Il faudra aussi penser que ces effets ne seront pas transposables à d'autres formats (au hasard le PDF;).
|
|
Si dissimulable vaut 1 le code est dissimulable et dissimulé, si par contre dissimulable vaut 0 le code est dissimulable et visible par défaut.
|
Apache conf |
ServerRoot " /opt/lampp "
Listen 80
|
2.4. Overflow
En voila une nouveauté qu'elle est bien pour la conduire. En plus ca ne m'a pas pris plus d'une ligne de code et grâce à elle vous allez pouvoir poser de gros paquets de code qui ne vont pas casser la mise en page de votre article. Par exemple :
Code beaucoup trop long |
< paragraph > Ceci dit, pour ces effets, il faudra bien veiller à ce qu'ils ne soient pas bloquants pour certains visiteurs, qu'ils ne vont pas casser la validité XHTML du truc et que la fonctionnalité qu'ils proposent est accessible même sans JS. Il faudra aussi penser que ces effets ne seront pas transposables à d'autres formats (au hasard le PDF;).< / paragraph >
< paragraph > Ceci dit, pour ces effets, il faudra bien veiller à ce qu'ils ne soient pas bloquants pour certains visiteurs, qu'ils ne vont pas casser la validité XHTML du truc et que la fonctionnalité qu'ils proposent est accessible même sans JS. Il faudra aussi penser que ces effets ne seront pas transposables à d'autres formats (au hasard le PDF;).< / paragraph >
|
|
Cette possibilité est seulement là pour veiller à ce que la mise en page n'est pas cassée par vos codes trop longs, même si le visiteur est en 800x600, c'est tout. Ce n'est pas une raison pour écrire des gros pâtés illisibles et qui de toutes facons ne passeront pas en PDF ;)
|
|
Errata : 'En plus ca ne m'a pas pris plus d'une ligne de code'
Précisons que ca ne m'a pas pris plus d'une ligne de code pour que ca fonctionne avec Firefox, la suite Mozilla, Seamonkey, Opera, etc. J'avais oublié de tester avec IE. Du coup c'est à completer... Merci IE ... (¬_¬)
|
Passons maintenant aux améliorations apportées à la coloration syntaxique.
2.5. Meilleure coloration
2.5.1. Avantages
Dans cette partie, je vais juste vous détailler pourquoi c'est une alternative intéressante par rapport au système actuel. Je détaillerais son fonctionnement, le format XML utilisé pour décrire les langages, etc. un peu plus loin.
Pour faire bref, l'ancien système devenait (à mon avis) trop complexe à maintenir et à faire évoluer. Ce nouveau système va permettre d'avoir :
- Une base d'un peu plus d'une centaine de langages (voir ci dessous). Même s'il est peu probable qu'on ai à tous les utiliser, au moins, on sait qu'ils sont disponibles. Et puis, si on retrouve quelqu'un qui fait du cobol, il sera surement ravi de savoir que le kit gère la colloration syntaxique de la chose ;)
- Un traitement plus fin au niveau de chaque langage : une quizaine de marqueurs disponibles (label, litteral, keyword, etc.).
- Une facilité d'évolution : la définition des langages se faisant de manière modulaire, il est facile de faire de l'assemblage. Par exemple à partir de la définition de Ruby et de HTML, ca prends quelques lignes (facilement lisibles) pour définir le RHTML. Je vous montrerais tout à l'heure comment avec du VB et quelques balises ont crée du VB.NET :p
- Une meilleure mise en page des "codes imbriqués". Par codes imbriqués, j'entends par exemple tout ce qui est développement web, ou il n'est pas rare de voir du HTML, cotoyer le langage de script serveur avec éventuellment une pointe de CSS/JS/etc. Voici un exemple, pour vous donner une idée :
JSP, Scriptlet Java, CSS et JS (pour avoir un mélange bien horrible : à ne surtout pas essayer à la maison) |
<%@ page contentType = " text / html " %>
<%@ page pageEncoding = " UTF - 8 " %>
<%@ taglib uri = " http : / / java . sun . com / jsp / jstl / core " prefix = " c " %>
<! DOCTYPE HTML PUBLIC " -//W3C//DTD HTML 4.01 Transitional//EN "
" http://www.w3.org/TR/html4/loose.dtd " >
< html >
< head >
< meta http - equiv = " Content - Type " content = " text / html ; charset = UTF - 8 " >
< title > Hello< / title >
<style type = " text / css " >
body{
font-family : Verdana, sans-serif;
font-size : 14px ;
font-style : italic ;
}
h1.hello{
color : # 0000ff ;
}
</style>
<script type = " text / javascript " >
function sayHello (name){
alert (' Hello ' + name+ ' ' );
}
</script>
< / head >
< body > ééé
<%
boolean needToSayHello = Boolean.valueOf (request.getParameter (" sayHello " )); boolean needToSayHello = Boolean.valueOf (request.getParameter (" sayHello " ));
request.setAttribute (" needToSayHello " , needToSayHello);
%>
< c : if test = " $ { needToSayHello } " >
< h1 class = " hello " >
< a href = " # " onclick = " return sayHello ( ' $ { param . name } ' ) ; " >
Say hello!
< / a >
< / h1 >
< / c : if >
< / body >
< / html >
|
Voici les quelques langages gérés actuellement par cette API :
Fichiers de définition des modes (un mode pouvant regrouper plusieurs langages) |
ioan@ubuntu:~/java/projets/dvp/kit/coloration$ ls *.xml
actionscript.xml icon.xml psp.xml
ada95.xml idl.xml ptl.xml
antlr.xml inform.xml pvwave.xml
apacheconf.xml ini.xml pyrex.xml
apdl.xml inno-setup.xml python.xml
applescript.xml interlis.xml rd.xml
aspect-j.xml io.xml rebol.xml
aspnet.xml javacc.xml redcode.xml
asp.xml javascript.xml relax-ng-compact.xml
assembly-m68k.xml java.xml rest.xml
assembly-macro32.xml jcl.xml rhtml.xml
assembly-mcs51.xml jhtml.xml rib.xml
assembly-parrot.xml jmk.xml rpmspec.xml
assembly-r2000.xml jsp.xml rtf.xml
assembly-x86.xml latex.xml ruby.xml
awk.xml lilypond.xml rview.xml
batch.xml lisp.xml sas.xml
bbj.xml literate-haskell.xml scheme.xml
bcel.xml lotos.xml sdl_pr.xml
bibtex.xml lua.xml sgml.xml
b.xml mail.xml shellscript.xml
chill.xml makefile.xml shtml.xml
cil.xml maple.xml slate.xml
cobol.xml ml.xml smalltalk.xml
coldfusion.xml modula3.xml smi-mib.xml
cplusplus.xml moin.xml splus.xml
csharp.xml mqsc.xml sqr.xml
css.xml myghty.xml squidconf.xml
cvs-commit.xml netrexx.xml ssharp.xml
c.xml nqc.xml svn-commit.xml
doxygen.xml nsis2.xml swig.xml
dsssl.xml objective-c.xml tcl.xml
d.xml objectrexx.xml texinfo.xml
eiffel.xml occam.xml text.xml
embperl.xml omnimark.xml tex.xml
erlang.xml pascal.xml tpl.xml
factor.xml patch.xml tsql.xml
forth.xml perl.xml twiki.xml
fortran.xml php.xml typoscript.xml
foxpro.xml pike.xml uscript.xml
freemarker.xml pl1.xml vbscript.xml
gettext.xml pl-sql.xml velocity.xml
gnuplot.xml pop11.xml verilog.xml
groovy.xml postscript.xml vhdl.xml
haskell.xml povray.xml xml.xml
hex.xml powerdynamo.xml xq.xml
htaccess.xml progress.xml xsl.xml
html.xml prolog.xml zpt.xml
i4gl.xml props.xml
ioan@ubuntu:~/java/projets/dvp/kit/coloration$
|
En plus des langages correspondant aux fichiers xml ci dessus, quelques alias sont disponibles (histoire de garder la compatibilité avec le kit actuel et/ou proposer une alterntive pour les langages non encore définis) :
pascal =delphi, delphinet
actionscript =as
vbscript =asp, vb, vbnet
cplusplus =bcb, cpp
javascript =js
shellscript =linux
pl - sql =oracle,sql, postgresql
text =other, perso
|
2.5.2. Inconvénients
Il y aura quand même du travail pour tout intégrer. Certains langages sont de base mieux définis que dans l'ancien système, pour d'autres, c'est malheureusement le contraire. Donc, il va y avoir un peu de travail à faire la dessus pour que tout le monde puisse s'y retrouver :)
Théoriquement, comme l'ensemble est modulaire et qu'une très grosse partie est faite, ca devrait aller assez vite. J'aurais par contre besoin de votre aide, si naturellement ca vous tente, afin que vous testiez la coloration sur vos nouveaux/anciens articles/FAQs/etc.
Voyons maintenant comment "ca marche" :)
3. Nouveau système de coloration
3.1. L'API de coloration
Cette API joue exactement le même rôle que les fichiers de coloration perl utilisés précedemment : ils vont mettre en page les balises <code> avant que la "moulinette" XSLT prenne le relais pour créer les pagesHTML, XSL-FO, etc. Les prérequis sont Java 5.0 (dispo dans le PATH), dvp-coloration.jar et commons-lang.jar (dispos dans le CLASSPATH) et les fichiers de définition des langages.
Son mode d'emploi se limite à ca :
java -jar /chemin/vers/dvp-coloration.jar /chemin/vers/documents/original.xml /chemin/vers/resultat.xml /chemin/vers/definitions
|
Par exemple, pour les articles (sachant que j'ai placé les définitions des langages dans coloration, les jars dans lib et que je suis au niveau du répertoire script) :
java -jar ./lib/dvp-coloration.jar ../documents/$ 1 /$ 1 .xml ../ArtTmp.xml ./coloration
|
Pour ceux que ca intéresse, les sources sont dispo en bas de l'article.
Passons maintenant à la définition des langages ou modes.
3.2. Créez vos propres modes
Voici à quoi ressemble un fichier de définition de langage :
Bruno, j'espère que tu es rassuré en voyant que Delphi (même .NET) n'a pas été oublié. Il est simplement défini dans le fichier pascal, l'utilisateur n'a pas à se soucier de ce nom, il pourra toujours utiliser <code langage="delphi"> ;)
Ceci dit, on pourra créer un fichier de définition spécial pour Delphi .NET, si celui actuellement disponible n'est pas suffisant :)
C'est justement ce que l'on va voir tout de suite en étendant la définition de VB pour mieux prendre en compte VB.NET. Voici le fichier original de définition de VB :
Langage VB (extrait) |
<? xml version="1.0"? >
<! DOCTYPE MODE SYSTEM " xmode.dtd " >
< MODE >
< PROPS >
< PROPERTY NAME = " lineComment " VALUE = " ' " / >
< / PROPS >
< RULES IGNORE_CASE = " TRUE " HIGHLIGHT_DIGITS = " TRUE " >
< SPAN TYPE = " LITERAL1 " NO_LINE_BREAK = " TRUE " >
< BEGIN > "< / BEGIN >
< END > "< / END >
< / SPAN >
< EOL_SPAN TYPE = " KEYWORD2 " > #if< / EOL_SPAN >
< EOL_SPAN TYPE = " KEYWORD2 " > #else< / EOL_SPAN >
< EOL_SPAN TYPE = " KEYWORD2 " > #end< / EOL_SPAN >
< EOL_SPAN TYPE = " COMMENT1 " > '< / EOL_SPAN >
< EOL_SPAN TYPE = " COMMENT1 " > rem < / EOL_SPAN >
< SEQ TYPE = " OPERATOR " > & lt ; < / SEQ >
< SEQ TYPE = " OPERATOR " > & lt ; =< / SEQ >
< SEQ TYPE = " OPERATOR " > & gt ; =< / SEQ >
< SEQ TYPE = " OPERATOR " > & gt ; < / SEQ >
< SEQ TYPE = " OPERATOR " > =< / SEQ >
< SEQ TYPE = " OPERATOR " > & lt ; & gt ; < / SEQ >
< SEQ TYPE = " OPERATOR " > .< / SEQ >
< MARK_PREVIOUS TYPE = " LABEL " EXCLUDE_MATCH = " TRUE "
AT_LINE_START = " TRUE " > :< / MARK_PREVIOUS >
< KEYWORDS >
< KEYWORD1 > if< / KEYWORD1 >
< KEYWORD1 > then< / KEYWORD1 >
< KEYWORD1 > else< / KEYWORD1 >
< KEYWORD1 > elseif< / KEYWORD1 >
< KEYWORD1 > select< / KEYWORD1 >
< KEYWORD1 > case< / KEYWORD1 >
< OPERATOR > is< / OPERATOR >
< OPERATOR > mod< / OPERATOR >
< OPERATOR > and< / OPERATOR >
< OPERATOR > or< / OPERATOR >
< OPERATOR > not< / OPERATOR >
< OPERATOR > xor< / OPERATOR >
< OPERATOR > imp< / OPERATOR >
< KEYWORD3 > false< / KEYWORD3 >
< KEYWORD3 > true< / KEYWORD3 >
< KEYWORD3 > empty< / KEYWORD3 >
< KEYWORD3 > nothing< / KEYWORD3 >
< KEYWORD3 > null< / KEYWORD3 >
< LITERAL2 > vbblack< / LITERAL2 >
< LITERAL2 > vbred< / LITERAL2 >
< LITERAL2 > vbgreen< / LITERAL2 >
< LITERAL2 > vbyellow< / LITERAL2 >
< LITERAL2 > vbblue< / LITERAL2 >
< LITERAL2 > vbmagenta< / LITERAL2 >
< LITERAL2 > vbcyan< / LITERAL2 >
< LITERAL2 > vbwhite< / LITERAL2 >
< LITERAL2 > vbGeneralDate< / LITERAL2 >
< LITERAL2 > vbLongDate< / LITERAL2 >
< LITERAL2 > vbShortDate< / LITERAL2 >
< LITERAL2 > vbLongTime< / LITERAL2 >
< LITERAL2 > vbShortTime< / LITERAL2 >
< LITERAL2 > vbObjectError< / LITERAL2 >
< KEYWORD2 > Err< / KEYWORD2 >
< / KEYWORDS >
< / RULES >
< / MODE >
|
A priori des mots clefs comme Imports et Namespace sont spécifiques à VB.NET. Créons un fichier pour y définir ce langage (en gros vb.net = vb + qques mots clefs supplémentaires).
vbnet.xml |
<? xml version="1.0"? >
<! DOCTYPE MODE SYSTEM " xmode.dtd " >
< MODE >
< RULES IGNORE_CASE = " TRUE " >
< IMPORT DELEGATE = " vbscript::MAIN " / >
< KEYWORDS >
< KEYWORD4 > imports< / KEYWORD4 >
< KEYWORD4 > namespace< / KEYWORD4 >
< KEYWORD4 > shared< / KEYWORD4 >
< / KEYWORDS >
< / RULES >
< / MODE >
|
Pour information, voici le même code VB.NET colorié une fois avec vb, une fois avec notre nouveau fichier :
code langage='vb' |
sdfs<
Imports System
Imports System. Text . RegularExpressions
Dim s As String = " SELECT * FROM matable WHERE madate='aujourd'hui' AND flag=1 "
Char &
NameSpace ExemplesRegEx &
Public Class Verification
Shared Sub Main ()
Dim verif as Regex = new Regex (" [0-9]{10} " )
Dim numero as String = " 0123456789 "
Dim isNumero As Boolean = verif. IsMatch (numero)
If isNumero Then
Console. WriteLine (" Le numéro de téléphone est valide " )
Else
Console. WriteLine (" Le numéro de téléphone n'est pas valide " )
End If
End Sub
End Class
End NameSpace
|
code langage='vbnet' |
sdfs<
Imports System
Imports System. Text . RegularExpressions
Dim s As String = " SELECT * FROM matable WHERE madate='aujourd'hui' AND flag=1 "
Char &
NameSpace ExemplesRegEx &
Public Class Verification
Shared Sub Main ()
Dim verif as Regex = new Regex (" [0-9]{10} " )
Dim numero as String = " 0123456789 "
Dim isNumero As Boolean = verif. IsMatch (numero)
If isNumero Then
Console. WriteLine (" Le numéro de téléphone est valide " )
Else
Console. WriteLine (" Le numéro de téléphone n'est pas valide " )
End If
End Sub
End Class
End NameSpace
|
"En gros", c'est pas plus compliqué que ca. Il faut relativiser, car il faut se taper la dtd xmode (c'est la seule doc disponible). D'un autre côté, il y a assez d'exemples pour que ce ne soit pas problématique.
Avant de passer aux exemples, voyons quelles possibilités (autres que de rajouter des règles) on a pour personnaliser la coloration d'un code.
3.3. Personnalisez la coloration
En fait, on a deux possibilités :
-
Premièrement, on peut jouer sur les CSS (voir code.css), il y a une quizaine de marqueurs différents. Ce fichier css contient une coloration syntaxique générique et les colorations spécifiques. Voici la coloration générique :
Coloration générique |
.keyword1 {
font-weight : bold ;
color : # 7F0055 ;
}
.keyword2 {
color : # 0033FF ;
}
.keyword3 {
color : # FF8040 ;
}
.keyword4 {
font-weight : bold ;
color : # 3366CC ;
}
.function,.markup {
color : navy ;
}
.operator {
color : # 7F0055 ;
}
.label {
color : olive ;
}
.digit{
color : red ;
}
.comment1 {
color : # 3f7f5f ;
}
.comment2 {
color : # 999999 ;
}
.comment3 {
color : # 3f5fbf ;
}
.comment4 {
font-style : italic ;
color : # 000080 ;
}
.literal1 {
color : # 2a00ff ;
}
.literal2 {
color : teal ;
}
|
Pour rajouter une coloration spécifique à votre langage, trois étapes :
-
Créez votre propre feuille de style et demandez son inclusion dans code.css. Par exemple :
Coloration générique |
.java_keyword1 {
font-weight : bold ;
color : # 7F0055 ;
font-style : italic ;
}
.java_keyword2 {
color : # 0033FF ;
font-style : italic ;
}
.java_keyword3 {
color : # FF8040 ;
font-style : italic ;
}
.java_keyword4 {
font-weight : bold ;
color : # 3366CC ;
font-style : italic ;
}
|
-
Indiquez au kit, qu'il y a une coloration spécifique à mettre en place pour votre langage. Rajoutez le nom de votre langage dans le fichier $KIT_HOME/script/coloration/languages.properties au niveau de colorations.connues. Par exemple :
colorations . connues =java, truc, bidulle
|
-
Prévenez les responsables du kit pour que ces modifications soient intégrées dans les autres formats (par exemple, il n'y a pas moyen d'intégrer une css pour les pdf, il faut donc coder tout ca dans les xsl).
- La seconde facon de chambouler tout ca est de changer le "marquage" des mots clefs (en passer en littéral, d'autres en keyword1,2,3, etc.)
Enfin, voila, voila, je pense qu'entre la centaine de langages déjà dispoibles, la possibilité de rajouter facilement nos règles à des langages existants et les possibilités de changer la mise en page du tout, on est tranquille avec la coloration syntaxique pour quelques années :)
Je vous laisse découvrir les exemples de coloration syntaxique, et j'attends vos remarques, critiques, avis, coups de main, coup de tête, etc. ;)
Ce document ment ment est issu de http://www.developpez.com et reste la propriété exclusive de son auteur.
La copie, modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.