Ce code est juste un exemple de la façon d'utiliser le package SyntaxHighlight que j'avais déjà posté ici:
http://www.delphifr.com/codes/MATH-FOR-DELPHI-MATH-IN-DELPHI-BIBLIOTHEQUE-EDITEUR_37753.aspx
Un extracteur de lexèmes est défini à partir du fichier Pascal.lexer. Il est référencé dans Pascal.ppas et sert à générer une définition de parser dans Pascal.pas. Cette définition de lexèmes est utilisée dans les événements OnTokenizeLineClass et OnTokenizeLine du TSyntaxHighlighter de la fiche principale pour colorier la syntaxe du code tappé.
Je crois que je n'ai pas oublié d'éléments du langage Delphi, à peu près tout y est:
-Keywords (begin, end, etc.. merci de me dire si vous constatez qu'il en manque)
-Symboles (;,:=<> etc...)
-Parenthèses et crochets
-Nombres (entiers, flottants et hexadécimal)
-Chaînes de caractères et caractères (par exemple #13)
-Les 3 formes de commentaires:
//Commentaire de fin de ligne
{Commentaire multi-ligne}
(* Commentaire multi-ligne *)
-Directives de compilation {$WARNINGS OFF}
-Assembleur
Juste une petite chose qui mériterait d'être approfondie: l'assembleur pour l'instant est colorié uniformément. Je ne connais pas assez la syntaxe de l'assembleur Delphi pour faire quelque chose de plus détaillé. Et le lexème associé à un bloc assembleur commence par asm et finit par end, c'est à dire que si quelqu'un utilise le mot "end" dans l'assembleur (par exemple dans un commentaire) alors la coloration syntaxique buggera dans ce cas-là.
Je n'ai pas eu la prétention de faire un éditeur évolué, simplement d'illustrer l'utilisation de mes composants: en finallement peu de lignes de code, on arrive à faire un éditeur fonctionnel.
Le code-source des événements du TSyntaxHighlighter est à peine compliqué car l'éditeur travaille ligne par ligne pour la syntaxe, et certains éléments syntaxiques du langage (commentaires, directives de compilation et assembleur) peuvent s'étendre sur plusieurs lignes, c'est pour cela que l'événement OnTokenizeLineClass est utilisé.
Je crois que j'ai battu le record du source le plus long, avec un code source de plus de 7000 lignes et qui pèse 790Ko, c'est à dire plus que le programme une fois compilé! ;-)
Source / Exemple :
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, SyntaxHighlighter, VirtualScrollingWinControl,
SyntaxHighlightMemo, Math, Pascal, COW_RunTime, StrUtils, ComCtrls,
TextEditorFooter;
type
TForm1 = class(TForm)
SyntaxHighlightMemo1: TSyntaxHighlightMemo;
SyntaxHighlighter1: TSyntaxHighlighter;
TextEditorFooter1: TTextEditorFooter;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure SyntaxHighlighter1TokenizeLineClass(Sender: TObject;
const LastLineClass: Byte; var NewLineClass: Byte;
const TextBuffer: PAnsiChar; const TextLength: Integer);
procedure SyntaxHighlighter1TokenizeLine(Sender: TObject;
const LineClass: Byte; const TextBuffer: PAnsiChar;
const TextLength: Integer; CharClass: PCharClassArray);
private
FPascalLexer:TDefaultLexer;
public
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
FPascalLexer:=TDefaultLexer.Create(PascalLexerDefinition);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
FPascalLexer.Destroy;
end;
procedure TForm1.SyntaxHighlighter1TokenizeLineClass(Sender: TObject;
const LastLineClass: Byte; var NewLineClass: Byte;
const TextBuffer: PAnsiChar; const TextLength: Integer);
var
i:ICharBuffer;
a:Integer;
begin
NewLineClass:=LastLineClass;
if TextLength=0 then
Exit;
i:=TDefaultCharBuffer.Create(TextBuffer+#13);
FPascalLexer.Init(i);
repeat
case NewLineClass of
0:case FPascalLexer.GetNewLexem of
3:NewLineClass:=1;
11:NewLineClass:=2;
12:NewLineClass:=3;
13:NewLineClass:=4;
end;
1:begin
a:=PosEx('end',TextBuffer,FPascalLexer.GetLastLexerPos);
if a=0 then
Break;
NewLineClass:=0;
FPascalLexer.SetLastLexerPos(a+3);
end;
2,3:begin
a:=PosEx('}',TextBuffer,FPascalLexer.GetLastLexerPos);
if a=0 then
Break;
NewLineClass:=0;
FPascalLexer.SetLastLexerPos(a+1);
end;
4:begin
a:=PosEx('*)',TextBuffer,FPascalLexer.GetLastLexerPos);
if a=0 then
Break;
NewLineClass:=0;
FPascalLexer.SetLastLexerPos(a+2);
end;
end;
until FPascalLexer.GetLexerPos>Cardinal(TextLength);
i:=nil;
end;
procedure TForm1.SyntaxHighlighter1TokenizeLine(Sender: TObject;
const LineClass: Byte; const TextBuffer: PAnsiChar;
const TextLength: Integer; CharClass: PCharClassArray);
var
i:ICharBuffer;
c,l:Byte;
a:Integer;
begin
if TextLength=0 then
Exit;
i:=TDefaultCharBuffer.Create(TextBuffer+#13);
FPascalLexer.Init(i);
l:=LineClass;
repeat
case l of
0:begin
c:=FPascalLexer.GetNewLexem+1;
case c of
4:l:=1;
12:begin
l:=2;
c:=10;
end;
13:begin
l:=3;
c:=11;
end;
14:begin
l:=4;
c:=11;
end;
17:c:=0;
end;
a:=FPascalLexer.GetLexerPos-FPascalLexer.GetLastLexerPos;
FillChar(CharClass[FPascalLexer.GetLastLexerPos-1],Min(a,TextLength-Integer(FPascalLexer.GetLastLexerPos)+1),c);
end;
1:begin
a:=PosEx('end',TextBuffer,FPascalLexer.GetLastLexerPos);
if a=0 then
a:=TextLength;
FillChar(CharClass[FPascalLexer.GetLastLexerPos-1],
Min(a-Integer(FPascalLexer.GetLastLexerPos)+4,TextLength-Integer(FPascalLexer.GetLastLexerPos)+1),4);
FPascalLexer.SetLastLexerPos(a+3);
l:=0;
end;
2:begin
a:=PosEx('}',TextBuffer,FPascalLexer.GetLastLexerPos);
if a=0 then
a:=TextLength;
FillChar(CharClass[FPascalLexer.GetLastLexerPos-1],
Min(a-Integer(FPascalLexer.GetLastLexerPos)+2,TextLength-Integer(FPascalLexer.GetLastLexerPos)+1),10);
FPascalLexer.SetLastLexerPos(a+1);
l:=0;
end;
3:begin
a:=PosEx('}',TextBuffer,FPascalLexer.GetLastLexerPos);
if a=0 then
a:=TextLength;
FillChar(CharClass[FPascalLexer.GetLastLexerPos-1],
Min(a-Integer(FPascalLexer.GetLastLexerPos)+2,TextLength-Integer(FPascalLexer.GetLastLexerPos)+1),11);
FPascalLexer.SetLastLexerPos(a+1);
l:=0;
end;
4:begin
a:=PosEx('*)',TextBuffer,FPascalLexer.GetLastLexerPos);
if a=0 then
a:=TextLength;
FillChar(CharClass[FPascalLexer.GetLastLexerPos-1],
Min(a-Integer(FPascalLexer.GetLastLexerPos)+3,TextLength-Integer(FPascalLexer.GetLastLexerPos)+1),11);
FPascalLexer.SetLastLexerPos(a+2);
l:=0;
end;
end;
until FPascalLexer.GetLexerPos>Cardinal(TextLength);
i:=nil;
end;
end.
Conclusion :
Je ne vois pas trop de catégorie adaptée pour ce code, je le mets donc dans "divers"
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.