unit ce_txtsyn; {$mode objfpc}{$H+} interface uses Classes, SysUtils, SynEditHighlighter, SynEditTypes, ce_dlangutils; type TTokenKind = (tkSym, tkTxt, tkWhi); TSynTxtSyn = class(TSynCustomHighlighter) private fSymAttribs: TSynHighlighterAttributes; fTxtAttribs: TSynHighlighterAttributes; fWhiAttribs: TSynHighlighterAttributes; fTokToAttri: array[TTokenKind] of TSynHighlighterAttributes; fToken: TTokenKind; fTokStart, fTokStop: Integer; fLineBuf: string; procedure setSymAttribs(value: TSynHighlighterAttributes); procedure setTxtAttribs(value: TSynHighlighterAttributes); procedure setWhiAttribs(value: TSynHighlighterAttributes); published property symbols: TSynHighlighterAttributes read fSymAttribs write setSymAttribs; property text: TSynHighlighterAttributes read fTxtAttribs write setTxtAttribs; property whites: TSynHighlighterAttributes read fWhiAttribs write setWhiAttribs; public constructor Create(aOwner: TComponent); override; // procedure setLine(const NewValue: String; LineNumber: Integer); override; procedure Next; override; procedure GetTokenEx(out TokenStart: PChar; out TokenLength: integer); override; function GetTokenAttribute: TSynHighlighterAttributes; override; function GetDefaultAttribute(Index: integer): TSynHighlighterAttributes; override; function GetToken: string; override; function GetTokenKind: integer; override; function GetTokenPos: Integer; override; function GetEol: Boolean; override; end; const txtSym: TCharSet = [ '&', '~', '#', '"', #39, '(', '-', ')', '=', '{', '[', '|', '`', '\', '^', '@', ']', '}', '+', '$', '*', '%', '<', '>', ',', '?', ';', '.', ':', '/', '!']; implementation uses Graphics; constructor TSynTxtSyn.Create(aOwner: TComponent); begin inherited; SetSubComponent(True); // fSymAttribs := TSynHighlighterAttributes.Create('Symbols', 'Symbols'); fTxtAttribs := TSynHighlighterAttributes.Create('Text', 'Text'); fWhiAttribs := TSynHighlighterAttributes.Create('White', 'White'); // fSymAttribs.Foreground := clBlack; fSymAttribs.Style := [fsBold]; fTxtAttribs.Foreground := clNavy; fWhiAttribs.Foreground := clNone; // AddAttribute(fSymAttribs); AddAttribute(fTxtAttribs); AddAttribute(fWhiAttribs); // fTokToAttri[tkSym] := fSymAttribs; fTokToAttri[tkTxt] := fTxtAttribs; fTokToAttri[tkWhi] := fWhiAttribs; // fTokStop := 1; Next; end; procedure TSynTxtSyn.setSymAttribs(value: TSynHighlighterAttributes); begin fSymAttribs.Assign(value); end; procedure TSynTxtSyn.setTxtAttribs(value: TSynHighlighterAttributes); begin fTxtAttribs.Assign(value); end; procedure TSynTxtSyn.setWhiAttribs(value: TSynHighlighterAttributes); begin fWhiAttribs.Assign(value); end; procedure TSynTxtSyn.setLine(const NewValue: String; LineNumber: Integer); begin inherited; fLineBuf := NewValue + #10; fTokStop := 1; Next; end; procedure TSynTxtSyn.Next; begin fTokStart := fTokStop; fTokStop := fTokStart; // EOL if fTokStop > length(fLineBuf) then exit; // spaces if (isWhite(fLineBuf[fTokStop])) then begin fToken := tkWhi; while isWhite(fLineBuf[fTokStop]) do begin Inc(fTokStop); if fTokStop > length(fLineBuf) then exit; end; exit; end; // symbs if (fLineBuf[fTokStop] in txtSym) then begin fToken := tkSym; while (fLineBuf[fTokStop] in txtSym) do begin Inc(fTokStop); if fLineBuf[fTokStop] = #10 then exit; end; exit; end; // text fToken := tkTxt; while not ((fLineBuf[fTokStop] in txtSym) or isWhite(fLineBuf[fTokStop])) do begin Inc(fTokStop); if fLineBuf[fTokStop] = #10 then exit; end; if fLineBuf[fTokStop] = #10 then exit; end; function TSynTxtSyn.GetEol: Boolean; begin Result := fTokStop > length(fLineBuf); end; function TSynTxtSyn.GetTokenAttribute: TSynHighlighterAttributes; begin Result := fTokToAttri[fToken]; Result.FrameEdges := sfeNone; end; function TSynTxtSyn.GetTokenPos: Integer; begin Result := fTokStart - 1; end; function TSynTxtSyn.GetToken: string; begin Result := copy(fLineBuf, FTokStart, fTokStop - FTokStart); end; procedure TSynTxtSyn.GetTokenEx(out TokenStart: PChar; out TokenLength: integer); begin TokenStart := @fLineBuf[FTokStart]; TokenLength := fTokStop - FTokStart; end; function TSynTxtSyn.GetTokenKind: integer; var a: TSynHighlighterAttributes; begin Result := SYN_ATTR_IDENTIFIER; a := GetTokenAttribute; if a = fTxtAttribs then Result := SYN_ATTR_IDENTIFIER else if a = fWhiAttribs then Result := SYN_ATTR_WHITESPACE else if a = fSymAttribs then Result := SYN_ATTR_SYMBOL; end; function TSynTxtSyn.GetDefaultAttribute(Index: integer): TSynHighlighterAttributes; begin case Index of SYN_ATTR_COMMENT: Result := fTxtAttribs; SYN_ATTR_IDENTIFIER: Result := fTxtAttribs; SYN_ATTR_KEYWORD: Result := fTxtAttribs; SYN_ATTR_STRING: Result := fTxtAttribs; SYN_ATTR_WHITESPACE: Result := fWhiAttribs; SYN_ATTR_SYMBOL: Result := fSymAttribs; else Result := fTxtAttribs; end; end; end.