unit uSintax; {$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Graphics, SynEditHighlighter;
type
{Clase para la creación de un resaltador}
//ID para categorizar a los tokens
TtkTokenKind = (tkComment, tkKey, tkNull, tkNumber, tkSpace, tkString, tkUnknown);
TProcTableProc = procedure of object; //Tipo procedimiento para procesar el
//token por el carácter inicial.
{ TSynMiColor }
TSynMiColor = class(TSynCustomHighlighter)
protected
posIni, posFin: Integer;
linAct : PChar;
fProcTable: array[#0..#255] of TProcTableProc; //tabla de procedimientos
fTokenID : TtkTokenKind; //Id del token actual
//define las categorías de los "tokens"
fAtriComent : TSynHighlighterAttributes;
fAtriClave : TSynHighlighterAttributes;
fAtriNumero : TSynHighlighterAttributes;
fAtriEspac : TSynHighlighterAttributes;
fAtriCadena : TSynHighlighterAttributes;
public
procedure SetLine(const NewValue: String; LineNumber: Integer); override;
procedure Next; override;
function GetEol: Boolean; override;
procedure GetTokenEx(out TokenStart: PChar; out TokenLength: integer);
override;
function GetTokenAttribute: TSynHighlighterAttributes; override;
public
function GetToken: String; override;
function GetTokenPos: Integer; override;
function GetTokenKind: integer; override;
constructor Create(AOwner: TComponent); override;
end;
implementation
constructor TSynMiColor.Create(AOwner: TComponent);
//Constructor de la clase. Aquí se deben crear los atributos a usar.
begin
inherited Create(AOwner);
//atributo de comentarios
fAtriComent := TSynHighlighterAttributes.Create('Comment');
fAtriComent.Style := [fsItalic]; //en cursiva
fAtriComent.Foreground := clGray; //color de letra gris
AddAttribute(fAtriComent);
//atribuuto de palabras claves
fAtriClave := TSynHighlighterAttributes.Create('Key');
fAtriClave.Style := [fsBold]; //en negrita
fAtriClave.Foreground:=clGreen; //color de letra verde
AddAttribute(fAtriClave);
//atributo de números
fAtriNumero := TSynHighlighterAttributes.Create('Number');
fAtriNumero.Foreground := clFuchsia;
AddAttribute(fAtriNumero);
//atributo de espacios. Sin atributos
fAtriEspac := TSynHighlighterAttributes.Create('space');
AddAttribute(fAtriEspac);
//atributo de cadenas
fAtriCadena := TSynHighlighterAttributes.Create('String');
fAtriCadena.Foreground := clBlue; //color de letra azul
AddAttribute(fAtriCadena);
end;
procedure TSynMiColor.SetLine(const NewValue: String; LineNumber: Integer);
{Es llamado por el editor, cada vez que necesita actualizar la información de
coloreado sobre una línea. Despues de llamar a esta función, se espera que
GetTokenEx, devuelva el token actual. Y también después de cada llamada a
"Next".}
begin
inherited;
linAct := PChar(NewValue); //copia la línea actual
posFin := 0; //apunta al primer caracter
Next;
end;
procedure TSynMiColor.Next;
//Es llamado por SynEdit, para acceder al siguiente Token.
begin
posIni := posFin; //apunta al siguiente token
///////////////////////////////////////
if linAct[posFin] = #0 then begin
fTokenID := tkNull;
exit;
end;
posFin := posIni + 8;
if posFin > length(linAct) then begin
posFin := length(linAct);
end;
if fTokenID = tkKey then fTokenID := tkUnknown else fTokenID := tkKey;
////////////////////////////////////////
// fProcTable[linAct[posFin]]; //Se ejecuta la función que corresponda.
end;
function TSynMiColor.GetEol: Boolean;
{Indica cuando se ha llegado al final de la línea}
begin
Result := fTokenId = tkNull;
end;
procedure TSynMiColor.GetTokenEx(out TokenStart: PChar; out TokenLength: integer);
{Devuelve información sobre el token actual}
begin
TokenLength := posFin - posIni;
TokenStart := linAct + posIni;
end;
function TSynMiColor.GetTokenAttribute: TSynHighlighterAttributes;
//Devuelve información sobre el token actual
begin
case fTokenID of
tkComment: Result := fAtriComent;
tkKey : Result := fAtriClave;
tkNumber : Result := fAtriNumero;
tkSpace : Result := fAtriEspac;
tkString : Result := fAtriCadena;
else Result := nil; //tkUnknown, tkNull
end;
end;
{Las siguientes funciones, son usadas por SynEdit para el manejo de las
llaves, corchetes, parentesis y comillas. No son cruciales para el coloreado
de tokens, pero deben responder bien.}
function TSynMiColor.GetToken: String;
begin
Result := '';
end;
function TSynMiColor.GetTokenPos: Integer;
begin
Result := posIni - 1;
end;
function TSynMiColor.GetTokenKind: integer;
begin
Result := 0;
end;
end.