Syntaxe Highlighter pour Silverlight

Je suis en train de réfléchir à une version full Silverlight 4 de mon blog. Parmi les éléments techniques qu’il me faut pour mener à bien ce projet c’est d’être capable d’afficher des extraits de code en différents langages (C#, C++, XML, ASP…) de manière lisible, donc avec de la couleur, détection de keyword, etc…

Après quelque recherches sur le net il semblerait que je ne suis pas le premier à chercher un parseur de code fait en .Net et à peut près réutilisable. Manifestement il en existe un faisant “autorité” en Windows Form : SyntaxBox de Roger Alsing. J’ai bien aimé ce projet car on retrouve d’une part le parseur à proprement dit et d’autre part l’aspect rendu winform qui en l’occurrence ne m’intéresse pas et sera donc facile à enlever.

Enfin j’ai aussi trouvé ici une personne qui a déjà porté la SyntaxBox pour Silverlight ! Le projet est dispo ici. Ce projet est intéressant car il s’agit ici de profiter pleinement de SyntaxBox qui est prévu pour permettre aux utilisateurs la saisie de code et sa coloration en direct. La technique est simple mais comme toujours il fallait y penser: une textbox transparente est placée devant la zone de rendu du code ce qui permet à l’utilisateur de taper du texte. La syntax box elle se charge du rendu en interceptant les événement de changement de texte sur la texbox.

Pour ma part je ne souhaite que afficher du code avec de la coloration syntaxique, l’utilisateur ne fera donc pas de modification en live. J’ai donc décider de reprendre le portage Silverlight de la SyntaxBox pour proposer un composant réutilisable simple d’emploi. Le fonctionnement interne est simple :
– Le parseur me fourni une collection de Row (lignes de code)
– Chaque Row est composée d’une collection de Word
– Chaque Word est composé d’un texte et d’un type qui permet d’y associer une couleur (commentaire, keyword, string, numeric, etc…)
Donc rien de plus simple que de définir un ItemsControl “bindé" sur ma collection de Row. Cet ItemsControl utilise un DataTemplate pour générer les items qui le compose.

Le control :

<ScrollViewer  Grid.Row="1"  HorizontalAlignment="Stretch" VerticalAlignment="Stretch" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
        <ItemsControl x:Name="itemsBox" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
        ItemsSource="{Binding Rows}" ItemTemplate="{StaticResource RowDataTemplate}">
        </ItemsControl>
        </ScrollViewer>

Le DataTemplate

<DataTemplate x:Key="RowDataTemplate">
        <ItemsControl Grid.Column="1"
        ItemsSource="{Binding Words}"
        ItemTemplate="{StaticResource WordsDataTemplate}"
        ItemsPanel="{StaticResource WordsPanelTemplate}"/>
        </DataTemplate>

Ce DataTemplate lui même va utiliser un second ItemsControl “bindé” sur la collection de Word de la ligne en cours et utiliser un autre DataTemplate afin de faire le rendu des items.

Enfin les word sont rendus en utilisant des TextBlock à l’intérieur d’un StackPanel. De plus j’utilise un Converter pour le ForeGround de TextBlock où je vais utiliser les infos de type de word fourni par le parseur pour décider quelle couleur j’applique.

Le second DataTemplate (pour les Words)

<DataTemplate x:Key="WordsDataTemplate">
        <TextBlock TextWrapping="Wrap"
        Text="{Binding Text}"
        Foreground="{Binding Style, Converter={StaticResource styleForegroundConverter}}" />
        </DataTemplate>
        <ItemsPanelTemplate x:Key="WordsPanelTemplate">
        <StackPanel  Orientation="Horizontal" />
        </ItemsPanelTemplate>

Pour aller plus loin j’ai modifier mon DataTemplate des Rows pour y inclure une coloration alternative ainsi que les numéro de lignes… J’ai aussi mis pour les tests une DropDown qui permet de choisir parmi les différents langages supportés par la SyntaxBox. Enfin le projet de test fourni une TextBox pour saisir en direct le code et voir le rendu. Voilà ce que ça donne :


Get Microsoft Silverlight

L’utilisation est au plus simple, voilà le xaml de ma MainPage :

<codebox:CodeBoxView x:Name="codebox1" Grid.Row="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"  Syntax="CSharp" Text="type code above" />
        

Le code source du projet est ici

Publié dans Silverlight Tagués avec : ,

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

*

Verifions que vous êtes un humain * Time limit is exhausted. Please reload CAPTCHA.

Archives

Social

  • Twitter
  • LinkedIn
  • Flux RSS
  • mvp
  • technet
  • Google+