mirror of
https://github.com/doublecmd/doublecmd.git
synced 2026-06-21 09:58:13 +00:00
1858 lines
64 KiB
ObjectPascal
1858 lines
64 KiB
ObjectPascal
{
|
||
The contents of this file are subject to the Mozilla Public License
|
||
Version 1.1 (the "License"); you may not use this file except in compliance
|
||
with the License. You may obtain a copy of the License at
|
||
http://www.mozilla.org/MPL/
|
||
|
||
Software distributed under the License is distributed on an "AS IS" basis,
|
||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
||
the specific language governing rights and limitations under the License.
|
||
|
||
The Original Code is: SynUniHighlighter.pas, released 2003-01
|
||
All Rights Reserved.
|
||
|
||
Alternatively, the contents of this file may be used under the terms of the
|
||
GNU General Public License Version 2 or later (the "GPL"), in which case
|
||
the provisions of the GPL are applicable instead of those above.
|
||
If you wish to allow use of your version of this file only under the terms
|
||
of the GPL and not to allow others to use your version of this file
|
||
under the MPL, indicate your decision by deleting the provisions above and
|
||
replace them with the notice and other provisions required by the GPL.
|
||
If you do not delete the provisions above, a recipient may use your version
|
||
of this file under either the MPL or the GPL.
|
||
|
||
}{
|
||
@abstract(Provides a universal highlighter for SynEdit)
|
||
@authors(Fantasist [walking_in_the_sky@yahoo.com], Vit [nevzorov@yahoo.com],
|
||
Vitalik [vetal-x@mail.ru])
|
||
@created(2003)
|
||
@lastmod(2004-05-12)
|
||
}
|
||
|
||
unit SynUniRules;
|
||
|
||
interface
|
||
|
||
uses
|
||
SysUtils, Graphics,
|
||
Classes, SynEditHighlighter, SynUniClasses, Laz2_DOM;
|
||
|
||
type
|
||
TSynRange = class;
|
||
TSynSet = class; //Vitalik 2004
|
||
|
||
TAbstractSymbol = class
|
||
function GetToken(CurRule: TSynRange; fLine: PChar; var Run: integer; var tkSynSymbol: TSynSymbol): boolean; virtual; abstract;
|
||
end;
|
||
|
||
TSymbols = class(TAbstractSymbol)
|
||
HeadNode: TSymbolNode;
|
||
SynSets: TList; //Vitalik 2004
|
||
function GetToken(CurRule: TSynRange; fLine: PChar; var Run: integer; var tkSynSymbol: TSynSymbol): boolean; override;
|
||
function FindSymbol(st: string): TSymbolNode;
|
||
procedure AddSymbol(st: string; tkSynSymbol: TSynSymbol; ABrakeType: TSymbBrakeType);
|
||
procedure AddSet(SymbolSet: TSynSet); //Vitalik 2004
|
||
constructor Create(ch: char; tkSynSymbol: TSynSymbol; ABrakeType: TSymbBrakeType); reintroduce; overload; virtual;
|
||
constructor Create(SymbolSet: TSynSet); reintroduce; overload; virtual; //Vitalik 2004
|
||
destructor Destroy(); override;
|
||
end;
|
||
|
||
TDefaultSymbols = class(TAbstractSymbol)
|
||
tkSynSymbol: TSynSymbol;
|
||
function GetToken(CurRule: TSynRange; fLine: PChar; var Run: integer; var tkSynSymbol: TSynSymbol): boolean; override;
|
||
constructor Create(SynSymb: TSynSymbol); reintroduce; virtual;
|
||
destructor Destroy(); override;
|
||
end;
|
||
|
||
TDefaultTermSymbols = class(TAbstractSymbol)
|
||
tkSynSymbol: TSynSymbol;
|
||
function GetToken(CurRule: TSynRange; fLine: PChar; var Run: integer; var tkSynSymbol: TSynSymbol): boolean; override;
|
||
constructor Create(SynSymb: TSynSymbol); virtual;
|
||
destructor Destroy(); override;
|
||
end;
|
||
|
||
TSynKeyList = class (TSynRule)
|
||
KeyList: TStringList;
|
||
constructor Create(st: string = '');
|
||
destructor Destroy(); override;
|
||
procedure LoadHglFromXml(xml: TDOMNode; SchCount,SchIndex: integer); //Vitalik 2004
|
||
procedure LoadFromXml(xml: TDOMNode); override; //Vitalik 2004
|
||
procedure SaveToStream(StreamWriter: TStreamWriter; Ind: integer = 0); overload; override; //Vitalik 2004
|
||
end;
|
||
|
||
TSynKeyListLink = class(TAbstractRule) //Vitalik 2004
|
||
KeyList: TSynKeyList;
|
||
end;
|
||
|
||
TSynSet = class (TSynRule) //Vitalik 2004
|
||
SymbSet: TSymbSet;
|
||
StartType: TSymbStartType;
|
||
BrakeType: TSymbBrakeType;
|
||
constructor Create(aSymbSet: TSymbSet = []);
|
||
destructor Destroy(); override;
|
||
procedure LoadHglFromXml(xml: TDOMNode; SchCount,SchIndex: integer);
|
||
procedure LoadFromXml(xml: TDOMNode); override;
|
||
procedure SaveToStream(StreamWriter: TStreamWriter; Ind: integer = 0); overload; override;
|
||
end;
|
||
|
||
TSynSetLink = class(TAbstractRule) //Vitalik 2004
|
||
SynSet: TSynSet;
|
||
end;
|
||
|
||
TSynRangeLink = class(TAbstractRule) //Vitalik 2004
|
||
Range: TSynRange;
|
||
Parent: TSynRange;
|
||
constructor Create(aRange: TSynRange); virtual;
|
||
end;
|
||
|
||
TSynRangeRule = class
|
||
fCloseSymbol: TSynSymbol;
|
||
fOpenSymbol: TSynSymbol;
|
||
fCloseOnTerm: boolean;
|
||
fCloseOnEol: boolean;
|
||
fAllowPredClose: boolean; //Vitalik 2004
|
||
constructor Create(OpenSymbs: string = ''; CloseSymbs: string = '');
|
||
destructor Destroy(); override;
|
||
end;
|
||
|
||
TSynRange = class (TSynRule)
|
||
private
|
||
fCaseSensitive: boolean;
|
||
fOwner: TSynRange;
|
||
|
||
fSynSymbols: TList;
|
||
fSynRanges: TList;
|
||
fSynKeyLists: TList;
|
||
fSynSets: TList; //Vitalik 2004
|
||
|
||
StringCaseFunct: function (const st: string): string;
|
||
fPrepared: boolean;
|
||
|
||
public {temp}
|
||
OpenCount: integer;
|
||
ParentBackup: TSynRange;
|
||
|
||
fRule: TSynRangeRule;
|
||
fClosingSymbol: TSynSymbol;
|
||
|
||
fDefaultSynSymbol: TSynSymbol;
|
||
fDefaultSymbols: TDefaultSymbols;
|
||
fDefaultTermSymbol: TDefaultTermSymbols;
|
||
|
||
fCommonSynRanges: TList;
|
||
fSynRangeLinks: TList;
|
||
|
||
CaseFunct: function (ch: char): char;
|
||
fTermSymbols: TSymbSet;
|
||
HasNodeAnyStart: array[char] of boolean; //Vitalik 2004
|
||
SymbolList: array[char] of TAbstractSymbol;
|
||
private
|
||
function GetSynSymbol(Index: Integer): TSynSymbol;
|
||
function GetCommonSynRange(Index: Integer): TSynRange;
|
||
function GetSynRangeLink(Index: Integer): TSynRangeLink;
|
||
function GetSynRange(Index: Integer): TSynRange;
|
||
function GetSynKeyList(Index: Integer): TSynKeyList;
|
||
function GetSynSet(Index: Integer): TSynSet; //Vitalik 2004
|
||
|
||
function GetSynSymbolCount(): Integer;
|
||
function GetCommonSynRangeCount(): Integer;
|
||
function GetSynRangeLinkCount(): Integer;
|
||
function GetSynRangeCount(): Integer;
|
||
function GetSynKeyListCount(): Integer;
|
||
function GetSynSetCount(): Integer; //Vitalik 2004
|
||
|
||
function GetCaseSensitive: boolean;
|
||
procedure SetCaseSensitive(const Value: boolean);
|
||
|
||
public {temp}
|
||
procedure LoadHglFromXml(xml: TDOMNode; SchCount, SchIndex: integer); //Vitalik 2004
|
||
procedure LoadFromXml(xml: TDOMNode); override; //Vitalik 2004
|
||
procedure SaveToStream(StreamWriter: TStreamWriter; Ind: integer = 0); overload; override; //Vitalik 2004
|
||
public
|
||
constructor Create(OpenSymbs: string = ''; CloseSymbs: string = ''); virtual;
|
||
destructor Destroy(); override;
|
||
|
||
procedure AddSynSymbol(NewSymb: TSynSymbol);
|
||
procedure AddRule(NewRule: TSynRule);
|
||
procedure AddCommonRange(Range: TSynRange);
|
||
procedure AddRangeLink(NewRangeLink: TSynRangeLink); overload;
|
||
function AddRangeLink(aRange: TSynRange; aName: string; aColor: TColor): TSynRangeLink; overload;
|
||
procedure AddRange(NewRange: TSynRange); overload;
|
||
function AddRange(aOpen, aClose, aName: string; aColor: TColor): TSynRange; overload;
|
||
procedure AddKeyList(NewKeyList: TSynKeyList); overload;
|
||
function AddKeyList(aName: string; aColor: TColor): TSynKeyList; overload;
|
||
procedure AddSet(NewSet: TSynSet); overload; //Vitalik 2004
|
||
function AddSet(aName: string; aSymbSet: TSymbSet; aColor: TColor): TSynSet; overload;//Vitalik 2004
|
||
|
||
function FindSymbol(st: string): TSynSymbol;
|
||
function FindSymbolOwner(Symbol: TSynSymbol): TSynKeyList;
|
||
|
||
procedure DeleteCommonRange(index: integer); overload;
|
||
procedure DeleteCommonRange(Range: TSynRange); overload;
|
||
procedure DeleteRangeLink(index: integer); overload;
|
||
procedure DeleteRangeLink(RangeLink: TSynRangeLink); overload;
|
||
procedure DeleteRange(index: integer); overload;
|
||
procedure DeleteRange(Range: TSynRange); overload;
|
||
procedure DeleteKeyList(index: integer); overload;
|
||
procedure DeleteKeyList(KeyList: TSynKeyList); overload;
|
||
procedure DeleteSet(index: integer); overload; //Vitalik 2004
|
||
procedure DeleteSet(SynSet: TSynSet); overload; //Vitalik 2004
|
||
|
||
{ procedure SetParentColor;
|
||
procedure RestoreOldColor; }
|
||
procedure SetDelimiters(Delimiters: TSymbSet);
|
||
// procedure SetStyles(aStyles: TSynUniStyles);
|
||
procedure SetColorForChilds(); //Vitalik 2004
|
||
|
||
procedure ClearParsingFields();
|
||
procedure ResetParents(aParent: TSynRange);
|
||
procedure Prepare(Owner: TSynRange);
|
||
procedure Reset();
|
||
procedure Clear();
|
||
|
||
function FindRange(const Name: string): TSynRange;
|
||
procedure LoadHglFromStream(aSrc: TStream);
|
||
public
|
||
property TermSymbols: TSymbSet read fTermSymbols write fTermSymbols;
|
||
// property OpenSymbol: TSynSymbol read fOpenSymbol;
|
||
// property CloseSymbol: TSynSymbol read fCloseSymbol;
|
||
// property CloseOnTerm: boolean read fCloseOnTerm write fCloseOnTerm;
|
||
// property CloseOnEol: boolean read fCloseOnEol write fCloseOnEol;
|
||
// property AllowPredClose: boolean read fAllowPredClose write fAllowPredClose; //Vitalik 2004
|
||
|
||
property CommonRanges[index: integer]: TSynRange read GetCommonSynRange;
|
||
property CommonRangeCount: integer read GetCommonSynRangeCount;
|
||
property RangeLinks[index: integer]: TSynRangeLink read GetSynRangeLink;
|
||
property RangeLinkCount: integer read GetSynRangeLinkCount;
|
||
property Ranges[index: integer]: TSynRange read GetSynRange;
|
||
property RangeCount: integer read GetSynRangeCount;
|
||
property Symbols[index: integer]: TSynSymbol read GetSynSymbol;
|
||
property SymbolCount: integer read GetSynSymbolCount;
|
||
property KeyLists[index: integer]: TSynKeyList read GetSynKeyList;
|
||
property KeyListCount: Integer read GetSynKeyListCount;
|
||
property Sets[index: integer]: TSynSet read GetSynSet; //Vitalik 2004
|
||
property SetCount: Integer read GetSynSetCount; //Vitalik 2004
|
||
|
||
property CaseSensitive: boolean read GetCaseSensitive write SetCaseSensitive;
|
||
property Prepared: boolean read fPrepared;
|
||
property Parent: TSynRange read fOwner write fOwner;
|
||
end;
|
||
|
||
//function Verify(tag: string; xml: TXMLParser): boolean; overload;
|
||
|
||
const
|
||
DefaultTermSymbols: TSymbSet = ['*','/','+','-','=','\','|','&','(',')',
|
||
'[',']','{','}','`','~','!','@',',','$','%','^','?',':',';','''','"','.',
|
||
'>','<','#'];
|
||
|
||
implementation
|
||
|
||
uses
|
||
Laz2_XMLRead;
|
||
|
||
function CaseNone(ch: char): char; //: Need for CaseSensitive
|
||
begin
|
||
Result := ch;
|
||
end;
|
||
|
||
function StringCaseNone(const st: string): string; //: Need for CaseSensitive
|
||
begin
|
||
Result := st;
|
||
end;
|
||
|
||
//==== TSymbols ==============================================================
|
||
procedure TSymbols.AddSymbol(st: string; tkSynSymbol: TSynSymbol; ABrakeType: TSymbBrakeType);
|
||
//: Add SynSymbol to the tree Symbols
|
||
var
|
||
i: integer;
|
||
l: integer;
|
||
Node: TSymbolNode;
|
||
SList: TSymbolList;
|
||
begin
|
||
SList := HeadNode.NextSymbs; //: All branches of current node (first - root node)
|
||
Node := nil; //: Current Node
|
||
l := Length(st); //: Length of adding string
|
||
for i := 1 to l do //: Check all symbols of adding string
|
||
begin
|
||
Node := SList.FindSymbol(st[i]); //: Try to find current symbol of adding string among branches
|
||
if Node = nil then //: If we can't find current symbol
|
||
begin
|
||
Node := TSymbolNode.Create(st[i]); //: then create node with current symbol
|
||
SList.AddSymbol(Node); //: and add it to current branches
|
||
end;
|
||
SList := Node.NextSymbs; //: Go to finded or added node
|
||
end;
|
||
Node.StartType := tkSynSymbol.StartType;
|
||
Node.BrakeType := ABrakeType; //: Set Break Type and ...
|
||
Node.tkSynSymbol := tkSynSymbol; //: ... SynSymbol of last Node
|
||
end;
|
||
|
||
constructor TSymbols.Create(ch: char; tkSynSymbol: TSynSymbol;
|
||
ABrakeType: TSymbBrakeType);
|
||
begin
|
||
HeadNode := TSymbolNode.Create(ch, tkSynSymbol, ABrakeType);
|
||
SynSets := TList.Create;
|
||
end;
|
||
|
||
constructor TSymbols.Create(SymbolSet: TSynSet);
|
||
begin
|
||
SynSets := TList.Create;
|
||
AddSet(SymbolSet);
|
||
end;
|
||
|
||
destructor TSymbols.Destroy;
|
||
begin
|
||
if Assigned(HeadNode) then
|
||
HeadNode.Free;
|
||
FreeList(SynSets);
|
||
inherited;
|
||
end;
|
||
|
||
function TSymbols.FindSymbol(st: string): TSymbolNode;
|
||
//: Find string st in the tree Symbols
|
||
var
|
||
i: integer;
|
||
l: integer;
|
||
Node, prvNode: TSymbolNode;
|
||
begin
|
||
Node := HeadNode; //: Root of the tree
|
||
l := Length(st); //: Length of string
|
||
for i := 1 to l do
|
||
begin
|
||
prvNode := Node.NextSymbs.FindSymbol(st[i]);
|
||
if prvNode = nil then //: If don't find
|
||
break; //: Exit from cycle
|
||
Node := prvNode; //: Else go to the brench or nil, if don't find
|
||
end;
|
||
Result := Node; //: Return node, if found, and nil, if not found
|
||
end;
|
||
|
||
procedure TSymbols.AddSet(SymbolSet: TSynSet);// ABrakeType: TSymbBrakeType);
|
||
begin
|
||
SynSets.Add(SymbolSet);
|
||
end;
|
||
|
||
function TSymbols.GetToken(CurRule: TSynRange; fLine: PChar; var Run: integer; var tkSynSymbol: TSynSymbol): boolean;
|
||
//: Try to find any token
|
||
var
|
||
curNode, nxtStart, prevFind: TSymbolNode;
|
||
i, posStart, posNext, posPrev: integer;
|
||
AllowedTermSymbols: TSymbSet;
|
||
|
||
function CanBeToken(): boolean;
|
||
var i: integer;
|
||
begin
|
||
CanBeToken := True;
|
||
if curNode.tkSynSymbol = nil then
|
||
CanBeToken := False
|
||
else if (curNode.BrakeType = btTerm) and not (fLine[succ(Run)] in CurRule.fTermSymbols) then
|
||
CanBeToken := False
|
||
else
|
||
case curNode.tkSynSymbol.StartLine of
|
||
slFirstNonSpace:
|
||
for i := 0 to posStart-1 do
|
||
{$IFNDEF FPC}
|
||
if not (fLine[i] in [' ', #32, #9]) then begin
|
||
{$ELSE}
|
||
if not (fLine[i] in [#32, #9]) then begin
|
||
{$ENDIF}
|
||
CanBeToken := False;
|
||
break;
|
||
end;
|
||
slFirst:
|
||
if posStart <> 0 then
|
||
CanBeToken := False;
|
||
end;
|
||
end;
|
||
|
||
begin //Vitalik 2004
|
||
Result := False;
|
||
posStart := Run;
|
||
if Assigned(HeadNode) then begin
|
||
curNode := HeadNode;
|
||
posNext := posStart;
|
||
nxtStart := nil;
|
||
repeat
|
||
if nxtStart <> nil then begin
|
||
curNode := nxtStart;
|
||
Run := posNext;
|
||
nxtStart := nil;
|
||
end;
|
||
if CanBeToken then
|
||
prevFind := curNode
|
||
else
|
||
prevFind := nil;
|
||
posPrev := Run;
|
||
while (curNode.NextSymbs.Count > 0) and (fLine[Run] <> #0) do begin
|
||
inc(Run);
|
||
curNode := curNode.NextSymbs.FindSymbol(CurRule.CaseFunct(fLine[Run]));
|
||
if curNode = nil then begin
|
||
dec(Run);
|
||
break;
|
||
end;
|
||
|
||
if CanBeToken then begin
|
||
prevFind := curNode;
|
||
posPrev := Run;
|
||
end;
|
||
|
||
if nxtStart = nil then
|
||
if (CurRule.HasNodeAnyStart[CurRule.CaseFunct(curNode.ch)] or
|
||
(curNode.ch in CurRule.fTermSymbols) or
|
||
(CurRule.CaseFunct(fLine[Run]) in CurRule.fTermSymbols)) then begin
|
||
nxtStart := curNode;
|
||
posNext := Run;
|
||
end;
|
||
end;
|
||
|
||
Run := posPrev;
|
||
|
||
if prevFind = nil then
|
||
continue;
|
||
if prevFind.tkSynSymbol = nil then
|
||
continue; //Never happened???
|
||
|
||
if fLine[Run] <> #0 then //: Go to next symbol in line if it isn't end of line
|
||
inc(Run);
|
||
|
||
if prevFind.BrakeType = btAny then begin //: If token can end by any symbol
|
||
Result := True; //: We find it!
|
||
tkSynSymbol := prevFind.tkSynSymbol; //: Here it is!
|
||
Exit;
|
||
end;
|
||
|
||
if fLine[Run] in CurRule.fTermSymbols then begin //: If token can end by delimeter and current symbol is delimeter
|
||
Result := True; //: We find it!
|
||
tkSynSymbol := prevFind.tkSynSymbol; //: Here it is!
|
||
Exit;
|
||
end;
|
||
until nxtStart = nil;
|
||
end;
|
||
//l1:
|
||
{begin}
|
||
Run := posStart;
|
||
// Result := False;
|
||
AllowedTermSymbols := CurRule.fTermSymbols;
|
||
for i := 0 to SynSets.Count-1 do begin
|
||
AllowedTermSymbols := AllowedTermSymbols - TSynSet(SynSets[i]).SymbSet;
|
||
end;
|
||
|
||
for i := 0 to SynSets.Count-1 do begin
|
||
Run := posStart;
|
||
repeat
|
||
inc(Run);
|
||
until not (fLine[Run] in TSynSet(SynSets[i]).SymbSet) or (fLine[Run] = #0);
|
||
//: If number ends on some Term-symbol, then
|
||
if TSynSet(SynSets[i]).BrakeType = btAny then begin
|
||
Result := True; //: We find it!
|
||
tkSynSymbol := TSynSymbol.Create('', TSynSet(SynSets[i]).Attribs);
|
||
exit;
|
||
end;
|
||
if (fLine[Run] in AllowedTermSymbols) then begin
|
||
Result := True; //: We find it!
|
||
tkSynSymbol := TSynSymbol.Create('', TSynSet(SynSets[i]).Attribs);
|
||
exit;
|
||
end;
|
||
end;
|
||
Run := succ(posStart);
|
||
{end}
|
||
|
||
{ was:
|
||
Result := false;
|
||
curNode := HeadNode;
|
||
nxtNode := nil;
|
||
while (curNode.NextSymbs.Count > 0) and (parser.fLine[parser.Run] <> #0) do begin
|
||
inc(parser.Run);
|
||
nxtNode := curNode.NextSymbs.FindSymbol(parser.fCurrentRule.CaseFunct(parser.fLine[parser.Run])); //: Ищем этот символ среди текущих веток
|
||
if nxtNode = nil then begin
|
||
dec(parser.Run);
|
||
break;
|
||
end;
|
||
curNode := nxtNode;
|
||
end;
|
||
|
||
if curNode.tkSynSymbol = nil then
|
||
exit;
|
||
|
||
if (nxtNode = nil) and (curNode.NextSymbs.Count > 0) then
|
||
dec(parser.Run);
|
||
|
||
if parser.fLine[parser.Run] <> #0 then
|
||
inc(parser.Run);
|
||
|
||
if curNode.BrakeType = btAny then
|
||
begin
|
||
Result := True;
|
||
tkSynSymbol := curNode.tkSynSymbol;
|
||
exit;
|
||
end;
|
||
|
||
if parser.fLine[parser.Run] in parser.fCurrentRule.fTermSymbols then
|
||
begin
|
||
Result := True;
|
||
tkSynSymbol := curNode.tkSynSymbol;
|
||
end;
|
||
}
|
||
end;
|
||
|
||
//==== TDefaultSymbols =======================================================
|
||
constructor TDefaultSymbols.Create(SynSymb: TSynSymbol);
|
||
begin
|
||
tkSynSymbol := SynSymb;
|
||
end;
|
||
|
||
destructor TDefaultSymbols.Destroy;
|
||
begin
|
||
tkSynSymbol.Free;
|
||
inherited;
|
||
end;
|
||
|
||
function TDefaultSymbols.GetToken(CurRule: TSynRange; fLine: PChar; var Run: integer; var tkSynSymbol: TSynSymbol): boolean;
|
||
//: Read just symbol, nothing to return
|
||
begin
|
||
inc(Run);
|
||
Result := False;
|
||
end;
|
||
|
||
//==== TDefaultTermSymbols ===================================================
|
||
constructor TDefaultTermSymbols.Create(SynSymb: TSynSymbol);
|
||
begin
|
||
tkSynSymbol := SynSymb;
|
||
end;
|
||
|
||
destructor TDefaultTermSymbols.Destroy;
|
||
begin
|
||
tkSynSymbol.Free;
|
||
inherited;
|
||
end;
|
||
|
||
function TDefaultTermSymbols.GetToken(CurRule: TSynRange; fLine: PChar; var Run: integer; var tkSynSymbol: TSynSymbol): boolean;
|
||
begin
|
||
if fLine[Run] <> #0 then //: If is not end of line then
|
||
Inc(Run); //: go to next symbol in fLine
|
||
tkSynSymbol := self.tkSynSymbol; //: And return DefaultTermSymbol
|
||
Result := True; //: We found token
|
||
end;
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
// RRRRRRR UUU UUU LLL EEEEEEE SSSSSS //
|
||
// R R U U L E S //
|
||
// RRRRRR U U L EEEEE SSSSSS //
|
||
// R R U U L L E S //
|
||
// RRR RR UUUUU LLLLLLL EEEEEEE SSSSSS //
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
|
||
//==== TSynKeyList ===========================================================
|
||
constructor TSynKeyList.Create(st: string);
|
||
begin
|
||
inherited Create;
|
||
// AddAttribute();
|
||
KeyList := TStringList.Create;
|
||
KeyList.Text := st;
|
||
end;
|
||
|
||
destructor TSynKeyList.Destroy;
|
||
begin
|
||
KeyList.Free;
|
||
inherited;
|
||
end;
|
||
|
||
//==== TSynSet =========================================================
|
||
constructor TSynSet.Create(aSymbSet: TSymbSet = []); //Vitalik 2004
|
||
begin
|
||
inherited Create;
|
||
// AddAttribute();
|
||
SymbSet := aSymbSet;
|
||
end;
|
||
|
||
destructor TSynSet.Destroy; //Vitalik 2004
|
||
begin
|
||
inherited;
|
||
end;
|
||
|
||
//==== TSynRangeRule =========================================================
|
||
constructor TSynRangeRule.Create(OpenSymbs: string = ''; CloseSymbs: string = '');
|
||
begin
|
||
fOpenSymbol := TSynSymbol.Create(OpenSymbs, nil);
|
||
fCloseSymbol := TSynSymbol.Create(CloseSymbs, nil);
|
||
end;
|
||
|
||
destructor TSynRangeRule.Destroy();
|
||
begin
|
||
fOpenSymbol.Free();
|
||
fCloseSymbol.Free();
|
||
end;
|
||
|
||
//==== TSynRange =============================================================
|
||
constructor TSynRange.Create(OpenSymbs: string; CloseSymbs: string);
|
||
begin
|
||
inherited Create;
|
||
OpenCount := 0;
|
||
|
||
fRule := TSynRangeRule.Create(OpenSymbs, CloseSymbs);
|
||
|
||
fRule.fOpenSymbol.StartType := stAny;
|
||
fRule.fOpenSymbol.BrakeType := btAny;
|
||
fRule.fCloseSymbol.StartType := stAny;
|
||
fRule.fCloseSymbol.BrakeType := btAny;
|
||
|
||
FillChar(SymbolList, sizeof(SymbolList), 0);
|
||
|
||
SetCaseSensitive(False);
|
||
|
||
fPrepared := False;
|
||
fRule.fCloseOnTerm := False;
|
||
fRule.fCloseOnEol := False;
|
||
|
||
fSynKeyLists := TList.Create;
|
||
fSynSets := TList.Create;
|
||
fSynSymbols := TList.Create;
|
||
fSynRanges := TList.Create;
|
||
fSynRangeLinks := TList.Create;
|
||
|
||
fTermSymbols := DefaultTermSymbols;
|
||
// AddAttribute();
|
||
end;
|
||
|
||
destructor TSynRange.Destroy;
|
||
//: Destructor of TSynRange
|
||
begin
|
||
//# Reset; ???
|
||
fRule.Free();
|
||
{ if Assigned(fRule.fOpenSymbol) then
|
||
fRule.fOpenSymbol.Free;
|
||
if Assigned(fRule.fCloseSymbol) then
|
||
fRule.fCloseSymbol.Free;}
|
||
// Attribs.Free;
|
||
FreeList(fSynKeyLists);
|
||
FreeList(fSynSets);
|
||
FreeList(fSynSymbols);
|
||
FreeList(fSynRanges);
|
||
FreeList(fSynRangeLinks);
|
||
inherited;
|
||
end;
|
||
|
||
//=== Work with fSynSymbols ==================================================
|
||
procedure TSynRange.AddSynSymbol(NewSymb: TSynSymbol);
|
||
//: Add SynSymbol to the list fSynSymbols. If SynSymbol already exist in list
|
||
//: then remove it and add to the end of the list
|
||
//: ??? Может надо если существет не добавлять???
|
||
var
|
||
SynSym: TSynSymbol;
|
||
begin
|
||
SynSym := FindSymbol(NewSymb.Symbol);
|
||
if SynSym <> nil then
|
||
begin
|
||
fSynSymbols.Remove(SynSym);
|
||
SynSym.Free;
|
||
end;
|
||
// NewSymb.Order := Order;
|
||
fSynSymbols.Add(NewSymb);
|
||
end;
|
||
|
||
function TSynRange.FindSymbol(st: string): TSynSymbol;
|
||
//: Find SynSymbol (Symbol = st) in the list fSynSymbols
|
||
var
|
||
i: integer;
|
||
begin
|
||
Result := nil;
|
||
for i := 0 to fSynSymbols.Count-1 do
|
||
if TSynSymbol(fSynSymbols.Items[i]).Symbol = st then
|
||
begin
|
||
Result := TSynSymbol(fSynSymbols.Items[i]);
|
||
exit;
|
||
end;
|
||
end;
|
||
|
||
//============================================================================
|
||
function TSynRange.FindSymbolOwner(Symbol: TSynSymbol): TSynKeyList;
|
||
//: Find KeyList that contain SynSymbol
|
||
//> Never used!!!
|
||
var
|
||
i, j: integer;
|
||
begin
|
||
Result := nil;
|
||
for i := 0 to fSynKeyLists.Count-1 do
|
||
if TSynKeyList(fSynKeyLists[i]).KeyList.Find(Symbol.Symbol, j) then
|
||
begin
|
||
Result := TSynKeyList(fSynKeyLists[i]);
|
||
exit;
|
||
end;
|
||
end;
|
||
|
||
//=== Adding rules ===========================================================
|
||
procedure TSynRange.AddRule(NewRule: TSynRule);
|
||
begin
|
||
if NewRule is TSynRange then AddRange(NewRule as TSynRange) else
|
||
if NewRule is TSynKeyList then AddKeyList(NewRule as TSynKeyList) else
|
||
if NewRule is TSynSet then AddSet(NewRule as TSynSet) else
|
||
raise Exception.Create('!!!');
|
||
end;
|
||
|
||
procedure TSynRange.AddCommonRange(Range: TSynRange);
|
||
begin
|
||
fSynRangeLinks.Add(Range);
|
||
end;
|
||
|
||
procedure TSynRange.AddRangeLink(NewRangeLink: TSynRangeLink);
|
||
begin
|
||
fSynRangeLinks.Add(NewRangeLink);
|
||
end;
|
||
|
||
function TSynRange.AddRangeLink(aRange: TSynRange; aName: string; aColor: TColor): TSynRangeLink;
|
||
begin
|
||
Result := TSynRangeLink.Create(aRange);
|
||
with Result do begin
|
||
Name := aName;
|
||
Attribs.Foreground := aColor;
|
||
Attribs.ParentForeground := False;
|
||
end;
|
||
AddRangeLink(Result);
|
||
end;
|
||
|
||
procedure TSynRange.AddRange(NewRange: TSynRange);
|
||
begin
|
||
fSynRanges.Add(NewRange);
|
||
end;
|
||
|
||
function TSynRange.AddRange(aOpen, aClose, aName: string; aColor: TColor): TSynRange;
|
||
begin
|
||
Result := TSynRange.Create(aOpen, aClose);
|
||
with Result do begin
|
||
Name := aName;
|
||
Attribs.Foreground := aColor;
|
||
Attribs.ParentForeground := False;
|
||
end;
|
||
AddRange(Result);
|
||
end;
|
||
|
||
procedure TSynRange.AddKeyList(NewKeyList: TSynKeyList);
|
||
begin
|
||
fSynKeyLists.Add(NewKeyList);
|
||
end;
|
||
|
||
function TSynRange.AddKeyList(aName: string; aColor: TColor): TSynKeyList;
|
||
begin
|
||
Result := TSynKeyList.Create('');
|
||
with Result do begin
|
||
Name := aName;
|
||
Attribs.Foreground := aColor;
|
||
Attribs.ParentForeground := False;
|
||
end;
|
||
AddKeyList(Result);
|
||
end;
|
||
|
||
procedure TSynRange.AddSet(NewSet: TSynSet); //Vitalik 2004
|
||
begin
|
||
fSynSets.Add(NewSet);
|
||
end;
|
||
|
||
function TSynRange.AddSet(aName: string; aSymbSet: TSymbSet; aColor: TColor): TSynSet; //Vitalik 2004
|
||
begin
|
||
Result := TSynSet.Create(aSymbSet);
|
||
with Result do begin
|
||
Name := aName;
|
||
Attribs.Foreground := aColor;
|
||
Attribs.ParentForeground := False;
|
||
end;
|
||
AddSet(Result);
|
||
end;
|
||
|
||
//=== Deleting rules =========================================================
|
||
procedure TSynRange.DeleteCommonRange(index: integer);
|
||
begin
|
||
TSynRangeLink(fCommonSynRanges[index]).Free;
|
||
fCommonSynRanges.Delete(index);
|
||
end;
|
||
|
||
procedure TSynRange.DeleteCommonRange(Range: TSynRange);
|
||
begin
|
||
fCommonSynRanges.Remove(Range);
|
||
end;
|
||
|
||
procedure TSynRange.DeleteRangeLink(index: integer);
|
||
begin
|
||
TSynRangeLink(fSynRangeLinks[index]).Free;
|
||
fSynRangeLinks.Delete(index);
|
||
end;
|
||
|
||
procedure TSynRange.DeleteRangeLink(RangeLink: TSynRangeLink);
|
||
begin
|
||
fSynRangeLinks.Remove(RangeLink);
|
||
RangeLink.Free;
|
||
end;
|
||
|
||
procedure TSynRange.DeleteRange(Range: TSynRange);
|
||
begin
|
||
fSynRanges.Remove(Range);
|
||
Range.Free;
|
||
end;
|
||
|
||
procedure TSynRange.DeleteRange(index: integer);
|
||
begin
|
||
TSynRange(fSynRanges[index]).Free;
|
||
fSynRanges.Delete(index);
|
||
end;
|
||
|
||
procedure TSynRange.DeleteKeyList(KeyList: TSynKeyList);
|
||
begin
|
||
fSynKeyLists.Remove(KeyList);
|
||
KeyList.Free;
|
||
end;
|
||
|
||
procedure TSynRange.DeleteKeyList(index: integer);
|
||
begin
|
||
TSynKeyList(fSynKeyLists[index]).Free;
|
||
fSynKeyLists.Delete(index);
|
||
end;
|
||
|
||
procedure TSynRange.DeleteSet(SynSet: TSynSet); //Vitalik 2004
|
||
begin
|
||
fSynSets.Remove(SynSet);
|
||
SynSet.Free;
|
||
end;
|
||
|
||
procedure TSynRange.DeleteSet(index: integer); //Vitalik 2004
|
||
begin
|
||
TSynSet(fSynSets[index]).Free;
|
||
fSynSets.Delete(index);
|
||
end;
|
||
|
||
//=== GetCount rules =========================================================
|
||
function TSynRange.GetSynSymbolCount: Integer;
|
||
begin
|
||
Result := fSynSymbols.Count;
|
||
end;
|
||
|
||
function TSynRange.GetSynRangeLinkCount: Integer;
|
||
begin
|
||
Result := fSynRangeLinks.Count;
|
||
end;
|
||
|
||
function TSynRange.GetCommonSynRangeCount(): Integer;
|
||
begin
|
||
Result := fCommonSynRanges.Count;
|
||
end;
|
||
|
||
function TSynRange.GetSynRangeCount: Integer;
|
||
begin
|
||
Result := fSynRanges.Count;
|
||
end;
|
||
|
||
function TSynRange.GetSynKeyListCount: Integer;
|
||
begin
|
||
Result := fSynKeyLists.Count;
|
||
end;
|
||
|
||
function TSynRange.GetSynSetCount: Integer; //Vitalik 2004
|
||
begin
|
||
Result := fSynSets.Count;
|
||
end;
|
||
|
||
//=== GetRule from list ======================================================
|
||
function TSynRange.GetSynSymbol(Index: Integer): TSynSymbol;
|
||
begin
|
||
Result := TSynSymbol(fSynSymbols[Index]);
|
||
end;
|
||
|
||
function TSynRange.GetCommonSynRange(Index: Integer): TSynRange;
|
||
begin
|
||
Result := TSynRange(fCommonSynRanges[Index]);
|
||
end;
|
||
|
||
function TSynRange.GetSynRangeLink(Index: Integer): TSynRangeLink;
|
||
begin
|
||
Result := TSynRangeLink(fSynRangeLinks[Index]);
|
||
end;
|
||
|
||
function TSynRange.GetSynRange(Index: Integer): TSynRange;
|
||
begin
|
||
Result := TSynRange(fSynRanges[Index]);
|
||
end;
|
||
|
||
function TSynRange.GetSynKeyList(Index: Integer): TSynKeyList;
|
||
begin
|
||
Result := TSynKeyList(fSynKeyLists[Index]);
|
||
end;
|
||
|
||
function TSynRange.GetSynSet(Index: Integer): TSynSet; //Vitalik 2004
|
||
begin
|
||
Result := TSynSet(fSynSets[Index]);
|
||
end;
|
||
|
||
//=== SetDelimiters ==========================================================
|
||
procedure TSynRange.SetDelimiters(Delimiters: TSymbSet);
|
||
var
|
||
i: integer;
|
||
begin
|
||
TermSymbols := Delimiters;
|
||
for i := 0 to RangeCount-1 do
|
||
Ranges[i].SetDelimiters(Delimiters);
|
||
end;
|
||
|
||
(*
|
||
procedure TSynRange.SetStyles(aStyles: TSynUniStyles);
|
||
//var
|
||
// i: integer;
|
||
begin
|
||
{ Styles := aStyles;
|
||
for i := 0 to RangeCount-1 do
|
||
Ranges[i].SetStyles(aStyles);}
|
||
end;
|
||
*)
|
||
|
||
//=== Case Sensitive =========================================================
|
||
function TSynRange.GetCaseSensitive: boolean;
|
||
//: Return CaseSensitive
|
||
begin
|
||
Result := FCaseSensitive;
|
||
end;
|
||
|
||
procedure TSynRange.SetCaseSensitive(const Value: boolean);
|
||
//: Set CaseSensitive
|
||
begin
|
||
fCaseSensitive := Value;
|
||
if not Value then begin
|
||
CaseFunct := UpCase;
|
||
StringCaseFunct := UpperCase;
|
||
end
|
||
else begin
|
||
CaseFunct := CaseNone;
|
||
StringCaseFunct := StringCaseNone;
|
||
end;
|
||
end;
|
||
|
||
//=== Prepare rules for parsing ==============================================
|
||
procedure QuickSortSymbolList(const List: TList; const lowerPos, upperPos: integer);
|
||
var
|
||
i, middlePos: integer;
|
||
pivotValue: string;
|
||
Begin
|
||
if lowerPos < upperPos then
|
||
begin
|
||
|
||
pivotValue := TSynSymbol(List[lowerPos]).Symbol;
|
||
middlePos := lowerPos;
|
||
|
||
for i := lowerPos + 1 to upperPos do
|
||
begin
|
||
if TSynSymbol(List[i]).Symbol < pivotValue then
|
||
begin
|
||
inc(middlePos);
|
||
List.Exchange(i,middlePos);
|
||
end;
|
||
end;
|
||
List.Exchange(lowerPos,middlePos);
|
||
|
||
QuickSortSymbolList(List, lowerPos, middlePos-1);
|
||
QuickSortSymbolList(List, middlePos+1, upperPos);
|
||
end;
|
||
end;
|
||
|
||
// Used in prepare
|
||
(* replaced by quicksort... arb2004
|
||
procedure SortSymbolList(List: TList);
|
||
//: Sort list fSynSymbols
|
||
var
|
||
i: integer;
|
||
fin: boolean;
|
||
begin
|
||
fin := False;
|
||
while not fin do
|
||
begin
|
||
fin := True;
|
||
for i := 0 to List.Count-2 do
|
||
if TSynSymbol(List[i]).Symbol > TSynSymbol(List[i+1]).Symbol then
|
||
begin
|
||
List.Exchange(i, i+1);
|
||
fin := False;
|
||
end;
|
||
end;
|
||
end;*)
|
||
|
||
procedure TSynRange.ClearParsingFields();
|
||
var
|
||
i: integer;
|
||
begin
|
||
OpenCount := 0;
|
||
for i := 0 to RangeCount-1 do
|
||
Ranges[i].ClearParsingFields();
|
||
end;
|
||
|
||
procedure TSynRange.ResetParents(aParent: TSynRange);
|
||
var
|
||
i: integer;
|
||
begin
|
||
Parent := aParent;
|
||
for i := 0 to RangeCount-1 do
|
||
Ranges[i].ResetParents(Self);
|
||
end;
|
||
|
||
procedure TSynRange.Prepare(Owner: TSynRange);
|
||
//: This procedure prepare Range for parsing
|
||
//: Is called only from SetLine
|
||
var
|
||
i, j, Len: integer;
|
||
SynSymbol: TSynSymbol;
|
||
s: string;
|
||
FirstChar: char;
|
||
BrakeType: TSymbBrakeType;
|
||
|
||
function SafeInsertSymbol(Symb: TSynSymbol; Rules: TSynRange; Attribs: TSynHighlighterAttributes): TSynSymbol;
|
||
//: This function add Symb to SynRange, if and only if there is no it there
|
||
//: Return added or found element
|
||
begin
|
||
Result := Rules.FindSymbol(Symb.Symbol); //: Find Symb in Rules
|
||
if Result = nil then begin //: If Symb not found, then add Symb to Rules
|
||
Result := TSynSymbol.Create(Symb.Symbol, Symb.Attributes);
|
||
Result.StartType := Symb.StartType;
|
||
Result.BrakeType := Symb.BrakeType;
|
||
Result.StartLine := Symb.StartLine;
|
||
Rules.AddSynSymbol(Result);
|
||
end;
|
||
if Result.Attributes = nil then //: If attributes of SynSymbol not setted
|
||
Result.Attributes := Attribs; //: then set them to Attribs
|
||
end;
|
||
|
||
function InsertSymbol(Symb: TSynSymbol; Rules: TSynRange): TSynSymbol;
|
||
begin
|
||
Result := Rules.FindSymbol(Symb.Symbol);
|
||
if Result = nil then begin
|
||
Result := TSynSymbol.Create(Symb.Symbol, Symb.Attributes);
|
||
Result.BrakeType := Symb.BrakeType;
|
||
Rules.AddSynSymbol(Result);
|
||
end;
|
||
Result.Attributes := Symb.Attributes;
|
||
end;
|
||
|
||
var
|
||
Range: TSynRange;
|
||
RangeLink: TSynRangeLink;
|
||
|
||
begin
|
||
Reset; //: If already prepared then reset it!
|
||
fOwner := Owner;
|
||
OpenCount := 0;
|
||
|
||
fDefaultSynSymbol := TSynSymbol.Create('', Attribs);
|
||
fDefaultTermSymbol := TDefaultTermSymbols.Create(TSynSymbol.Create('', Attribs));
|
||
fDefaultSymbols := TDefaultSymbols.Create(TSynSymbol.Create('', Attribs));
|
||
|
||
fTermSymbols := fTermSymbols+AbsoluteTermSymbols;
|
||
|
||
if Enabled then begin
|
||
|
||
//Add all keywords to list fSynSymbols:
|
||
for i := 0 to fSynKeyLists.Count-1 do //: All KeyLists
|
||
if TSynKeyList(fSynKeyLists[i]).Enabled then
|
||
for j := 0 to TSynKeyList(fSynKeyLists[i]).KeyList.Count-1 do begin//: All keywords in KeyLists
|
||
//: Add current keyword to list fSynSymbols:
|
||
InsertSymbol{AddSymbol}(TSynSymbol.Create(TSynKeyList(fSynKeyLists[i]).KeyList[j],
|
||
TSynKeyList(fSynKeyLists[i]).Attribs),
|
||
self);
|
||
end;
|
||
|
||
//Assign range opening and closing symbols and Prepare range rules.
|
||
for i := 0 to fSynRanges.Count-1 do begin
|
||
Range := TSynRange(fSynRanges[i]);
|
||
if Range.Enabled then begin
|
||
//Assign range opening symbol
|
||
SynSymbol := SafeInsertSymbol(Range.fRule.fOpenSymbol, Self, Range.Attribs);
|
||
SynSymbol.fOpenRule := Range;
|
||
|
||
//Assing range closing symbols
|
||
SynSymbol := SafeInsertSymbol(Range.fRule.fCloseSymbol, Range, Range.Attribs);
|
||
Range.fClosingSymbol := SynSymbol;
|
||
Range.Prepare(Self);
|
||
end;
|
||
end;
|
||
|
||
for i := 0 to fSynRangeLinks.Count-1 do begin
|
||
RangeLink := TSynRangeLink(fSynRangeLinks[i]);
|
||
Range := RangeLink.Range;
|
||
if RangeLink.Enabled then begin
|
||
//Assign range opening symbol
|
||
SynSymbol := SafeInsertSymbol(Range.fRule.fOpenSymbol, Self, Range.Attribs);
|
||
SynSymbol.fOpenRule := RangeLink;
|
||
RangeLink.Parent := Self;
|
||
//Assing range closing symbols
|
||
// SynSymbol := SafeInsertSymbol(Range.fRule.fCloseSymbol, Range, Range.Attribs.Std);
|
||
// Range.fClosingSymbol := SynSymbol;
|
||
// Range.Prepare(Self);
|
||
end;
|
||
end;
|
||
|
||
//Build tokens table
|
||
QuickSortSymbolList(fSynSymbols, 0, fSynSymbols.Count-1); //: Sort fSynSymbols
|
||
for i := 0 to fSynSymbols.Count-1 do begin //: run all SynSymbols
|
||
SynSymbol := TSynSymbol(fSynSymbols[i]); //: SynSymbol - next SymSymbol
|
||
Len := Length(SynSymbol.Symbol);
|
||
if Len < 1 then //: If length equal zero
|
||
continue; //: then next SynSymbol
|
||
s := SynSymbol.Symbol; //: String of SynSymbol
|
||
FirstChar := s[1]; //: First symbol of string of SynSymbol
|
||
|
||
if SynSymbol.BrakeType <> btUnspecified then //: If BrakeType defined then
|
||
BrakeType := SynSymbol.BrakeType //: Write this BreakType to local variable
|
||
else //: Else (if BrakeType not defined)
|
||
if s[Len] in fTermSymbols then //: If last symbol is TermSymbol
|
||
BrakeType := btAny //: Write to BreakType: btAny
|
||
else //: Else
|
||
BrakeType := btTerm; //: Write to BreakType: btTerm
|
||
|
||
if SymbolList[CaseFunct(FirstChar)] = nil then //: If in SymbolList on FirstChar there is no nothing
|
||
begin
|
||
if Len = 1 then //: If length of string of SynSymbol equal 1
|
||
//: then write SynSymbol in this element of SimbolList
|
||
SymbolList[CaseFunct(FirstChar)] := TSymbols.Create(FirstChar, SynSymbol, BrakeType)
|
||
else begin //: Else (length of SynSymbol greate then 1)
|
||
//: Write fDefaultSynSymbol (???) to this element | FirstChar
|
||
SymbolList[CaseFunct(FirstChar)] := TSymbols.Create(FirstChar, fDefaultSynSymbol, BrakeType);
|
||
//: and add SynSymbol to this element | All but without FirstChar
|
||
TSymbols(SymbolList[CaseFunct(FirstChar)]).AddSymbol(StringCaseFunct(copy(s, 2, Len-1)), SynSymbol, BrakeType);
|
||
end;
|
||
end
|
||
else begin //: Else (if in SynSymbol exist something)
|
||
if Len = 1 then
|
||
else //: If length of string SynSymbol greate then 1
|
||
//: Add SynSymbol to this element | All but without FirstChar
|
||
TSymbols(SymbolList[CaseFunct(FirstChar)]).AddSymbol(StringCaseFunct(copy(s, 2, Len-1)), SynSymbol, BrakeType);
|
||
end;
|
||
end;
|
||
|
||
{begin} //Vitalik 2004
|
||
if fSynSets.Count > 0 then
|
||
for i := 0 to 255 do
|
||
for j := 0 to fSynSets.Count-1 do begin
|
||
if TSynSet(fSynSets[j]).Enabled and (char(i) in TSynSet(fSynSets[j]).SymbSet) then
|
||
if SymbolList[CaseFunct(char(i))] = nil then
|
||
SymbolList[CaseFunct(char(i))] := TSymbols.Create(TSynSet(fSynSets[j]))
|
||
else
|
||
TSymbols(SymbolList[CaseFunct(char(i))]).AddSet(TSynSet(fSynSets[j]));
|
||
end;
|
||
// SymbolList[char(i)] := fSetSymbols;
|
||
// TSetSymbols(SymbolList[char(i)]).AddSetfSetSymbols;
|
||
{end} //Vitalik 2004
|
||
end;
|
||
//Fill remaining table
|
||
for i := 0 to 255 do
|
||
if SymbolList[char(i)] = nil then
|
||
begin
|
||
if char(i) in fTermSymbols then
|
||
SymbolList[char(i)] := fDefaultTermSymbol
|
||
else
|
||
SymbolList[char(i)] := fDefaultSymbols;
|
||
end;
|
||
|
||
fPrepared := true;
|
||
end;
|
||
|
||
procedure TSynRange.Reset;
|
||
//: Clear some properties of SynRange,
|
||
//: вызывается при очистке Clear, а также при Подготовке SynRang'a (Prepare)
|
||
//: Ресетится только если SynRange был уже подготовлен!
|
||
var
|
||
i: integer;
|
||
begin
|
||
if not fPrepared then
|
||
exit;
|
||
fDefaultSynSymbol.Free;
|
||
fDefaultTermSymbol.Free;
|
||
fDefaultSymbols.Free;
|
||
for i := 0 to 255 do
|
||
SymbolList[char(i)] := nil; //maybe need to free???
|
||
for i := 0 to fSynRanges.Count-1 do
|
||
TSynRange( fSynRanges[i] ).Reset;
|
||
ClearList(fSynSymbols);
|
||
fPrepared := False;
|
||
end;
|
||
|
||
procedure TSynRange.Clear;
|
||
//: Clear primary properties of SynRang, call in creating new rools
|
||
var
|
||
i: integer;
|
||
begin
|
||
//!!!!!!!!!!!!!!!!!!!!!! Нужно еще очищать или удалять OpenSymbol и CloseSymbol !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||
Reset; //: Reser Range (clear some properties)
|
||
for i := 0 to fSynRanges.Count-1 do //: Clear all sub-ranges
|
||
TSynRange(fSynRanges[i]).Clear;
|
||
ClearList(fSynRanges);
|
||
ClearList(fSynSymbols);
|
||
ClearList(fSynKeyLists);
|
||
ClearList(fSynSets);
|
||
end;
|
||
|
||
function TSynRange.FindRange(const Name: string): TSynRange;
|
||
Var
|
||
I: integer;
|
||
begin
|
||
Result := nil;
|
||
if fOwner = nil then Exit;
|
||
|
||
for I := 0 to fOwner.RangeCount - 1 do
|
||
if SameText(Name, fOwner.Ranges[I].Name) then
|
||
begin
|
||
Result := fOwner.Ranges[I];
|
||
Exit;
|
||
end;
|
||
end;
|
||
|
||
procedure TSynRange.SetColorForChilds; //Vitalik 2004
|
||
var
|
||
i: integer;
|
||
begin
|
||
for i := 0 to RangeCount-1 do begin
|
||
if Ranges[i].Attribs.ParentForeground then begin
|
||
Ranges[i].Attribs.Foreground := Attribs.Foreground;
|
||
Ranges[i].Attribs.OldColorForeground := Attribs.Foreground;
|
||
end;
|
||
if Ranges[i].Attribs.ParentBackground then begin
|
||
Ranges[i].Attribs.Background := Attribs.Background;
|
||
Ranges[i].Attribs.OldColorBackground := Attribs.Background;
|
||
end;
|
||
Ranges[i].SetColorForChilds;
|
||
end;
|
||
for i := 0 to KeyListCount-1 do begin
|
||
if KeyLists[i].Attribs.ParentForeground then
|
||
KeyLists[i].Attribs.Foreground := Attribs.Foreground;
|
||
if KeyLists[i].Attribs.ParentBackground then
|
||
KeyLists[i].Attribs.Background := Attribs.Background;
|
||
end;
|
||
for i := 0 to SetCount-1 do begin
|
||
if Sets[i].Attribs.ParentForeground then
|
||
Sets[i].Attribs.Foreground := Attribs.Foreground;
|
||
if Sets[i].Attribs.ParentBackground then
|
||
Sets[i].Attribs.Background := Attribs.Background;
|
||
end;
|
||
end;
|
||
|
||
//==== TSynRangeLink =========================================================
|
||
constructor TSynRangeLink.Create(aRange: TSynRange);
|
||
begin
|
||
inherited Create;
|
||
Range := aRange;
|
||
Parent := nil;
|
||
end;
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
// LLL OOOOO AAAAA DDDDDD IIIII NN N GGGGGG //
|
||
// L O O A A D D I NNN N G //
|
||
// L O O AAAAAAA D D I N NNN N G GGG //
|
||
// L L O O A A D D I N NNN G G //
|
||
// LLLLLLL OOOOO A A DDDDDD IIIII N NN GGGGGG //
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
procedure TSynKeyList.LoadFromXml(xml: TDOMNode);
|
||
var
|
||
I, J: Integer;
|
||
ChildNode: TDOMNode;
|
||
Key, Value, LowValue: string;
|
||
// OldAttribs: {TSynHighlighter}TSynAttributes;
|
||
begin
|
||
if xml = nil then Exit;
|
||
if not SameText(xml.NodeName, 'Keywords') then xml:= xml.FindNode('Keywords');
|
||
if xml = nil then raise Exception.Create(ClassName + '.LoadFromXml - no keywords to load!');
|
||
|
||
for I := 0 to Int32(xml.Attributes.Length) - 1 do
|
||
begin
|
||
Key := xml.Attributes[I].NodeName;
|
||
Value := xml.Attributes[I].NodeValue;
|
||
LowValue := LowerCase(Value);
|
||
if SameText('Name', Key) then Name := Value else
|
||
if SameText('Enabled', Key) then Enabled := (LowValue = 'true') else
|
||
if SameText('Attributes', Key) then
|
||
Attribs.LoadFromString(Value) else
|
||
if SameText('Style', Key) then begin
|
||
Style := Value;
|
||
if Styles <> nil then //begin
|
||
// OldAttribs := Attribs;
|
||
Attribs := Styles.GetStyleDef(Value, Attribs);
|
||
// if OldAttribs <> Attribs then
|
||
// Attribs.UseStyle := True;
|
||
{ if (Attribs = DefaultAttr) or (Attribs = nil) then
|
||
Attribs := DefaultAttri;}
|
||
// end;
|
||
end else
|
||
// Attribs := fStyles.GetStyleDef(getAttrValue('style', xml), defaultattr);
|
||
end;
|
||
|
||
KeyList.BeginUpdate;
|
||
KeyList.Clear;
|
||
try
|
||
for J := 0 to Int32(xml.ChildNodes.Count) - 1 do
|
||
begin
|
||
ChildNode:= xml.ChildNodes.Item[J];
|
||
if SameText('Word', ChildNode.NodeName) then
|
||
if (ChildNode.Attributes.Length > 0) and SameText('Value', ChildNode.Attributes[0].NodeName) then
|
||
KeyList.Add(ChildNode.Attributes[0].NodeValue);
|
||
end;
|
||
finally
|
||
KeyList.EndUpdate;
|
||
end;
|
||
end;
|
||
|
||
procedure TSynSet.LoadFromXml(xml: TDOMNode);
|
||
var
|
||
i: integer;
|
||
Key, Value, LowValue: string;
|
||
// OldAttribs: {TSynHighlighter}TSynAttributes;
|
||
begin
|
||
if xml = nil then Exit;
|
||
if not SameText(xml.NodeName, 'Set') then xml:= xml.FindNode('Set');
|
||
if xml = nil then raise Exception.Create(ClassName + '.LoadFromXml - no set to load!');
|
||
|
||
for i := 0 to Int32(xml.Attributes.Length) - 1 do
|
||
begin
|
||
Key := xml.Attributes[i].NodeName;
|
||
Value := xml.Attributes[i].NodeValue;
|
||
LowValue := LowerCase(Value); {ind := 0;}
|
||
if SameText('Name', Key) then Name := Value else
|
||
if SameText('Enabled', Key) then Enabled := (LowValue = 'true') else
|
||
if SameText('Attributes', Key) then
|
||
Attribs.LoadFromString(Value) else
|
||
if SameText('Style', Key) then begin
|
||
Style := Value;
|
||
if Styles <> nil then //begin
|
||
// OldAttribs := Attribs;
|
||
Attribs := Styles.GetStyleDef(Value, Attribs);
|
||
// if OldAttribs <> Attribs then
|
||
// Attribs.UseStyle := True;
|
||
{ if (Attribs = DefaultAttr) or (Attribs = nil) then
|
||
Attribs := DefaultAttri;}
|
||
// end;
|
||
end else
|
||
if SameText('Symbols', Key) then SymbSet := StrToSet(Value)
|
||
// Attribs := fStyles.GetStyleDef(getAttrValue('style', xml), defaultattr);
|
||
end;
|
||
end;
|
||
|
||
procedure TSynRange.LoadFromXml(xml: TDOMNode);
|
||
var
|
||
I, J: Integer;
|
||
ChildNode: TDOMNode;
|
||
NewSynRange: TSynRange;
|
||
NewSynKeyList: TSynKeyList;
|
||
NewSynSet: TSynSet;
|
||
Key, Value, LowValue: string;
|
||
// OldAttribs: {TSynHighlighter}TSynAttributes;
|
||
begin
|
||
if xml = nil then Exit;
|
||
if not SameText(xml.NodeName, 'Range') then xml:= xml.FindNode('Range');
|
||
if xml = nil then raise Exception.Create(ClassName + '.LoadFromXml - no range to load!');
|
||
|
||
// Clear; //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Вставить нормальный Clear в KeyList и SynSet !!!!!!!!!!!!!!!!!!
|
||
Enabled := True; CaseSensitive := False;
|
||
for i := 0 to Int32(xml.Attributes.Length) - 1 do
|
||
begin
|
||
Key := xml.Attributes[i].NodeName;
|
||
Value := xml.Attributes[i].NodeValue;
|
||
LowValue := LowerCase(Value);
|
||
if SameText('Name', Key) then Name := Value else
|
||
if SameText('Enabled', Key) then Enabled := (LowValue = 'true') else
|
||
if SameText('Attributes', Key) then
|
||
Attribs.LoadFromString(Value) else
|
||
if SameText('Style', Key) then begin
|
||
Style := Value;
|
||
if Styles <> nil then //begin
|
||
// OldAttribs := Attribs;
|
||
Attribs := Styles.GetStyleDef(Value, Attribs);
|
||
// if OldAttribs <> Attribs then
|
||
// Attribs.UseStyle := True;
|
||
{ if (Attribs = DefaultAttr) or (Attribs = nil) then
|
||
Attribs := DefaultAttri;}
|
||
// end;
|
||
end else
|
||
if SameText('CaseSensitive', Key) then CaseSensitive := (LowValue = 'true') else
|
||
if SameText('Delimiters', Key) then
|
||
// if SameText(GetAttrValue('spaces', xml), 'true') then
|
||
// TermSymbols := String2Set(xml.CurContent) + [#32, #9, #13, #10] else
|
||
TermSymbols := StrToSet(Value) // CloseOnTerm := true;
|
||
end;
|
||
|
||
for J := 0 to Int32(xml.ChildNodes.Count) - 1 do
|
||
begin
|
||
ChildNode:= xml.ChildNodes.Item[J];
|
||
if SameText('Rule', ChildNode.NodeName) then
|
||
for i := 0 to Int32(ChildNode.Attributes.Length) - 1 do begin
|
||
Key := ChildNode.Attributes[i].NodeName;
|
||
Value := ChildNode.Attributes[i].NodeValue;
|
||
LowValue := LowerCase(Value);
|
||
if SameText('Enabled', Key) then Enabled := (LowValue = 'true') else
|
||
if SameText('OpenSymbol', Key) then fRule.fOpenSymbol.Symbol := Value else
|
||
if SameText('OpenSymbolFinishOnEol', Key) then
|
||
if LowValue = 'true' then fRule.fOpenSymbol.Symbol := fRule.fOpenSymbol.Symbol + #0 else else
|
||
if SameText('OpenSymbolStartLine', Key) then with fRule.fOpenSymbol do
|
||
if LowValue = 'true' then StartLine := slFirst else
|
||
if LowValue = 'nonspace' then StartLine := slFirstNonSpace else
|
||
StartLine := slNotFirst else
|
||
if SameText('OpenSymbolPartOfTerm', Key) then with fRule.fOpenSymbol do
|
||
if LowValue = 'true' then begin StartType := stAny; BrakeType := btAny; end else
|
||
if LowValue = 'left' then begin StartType := stAny; BrakeType := btTerm; end else
|
||
if LowValue = 'right' then begin StartType := stTerm; BrakeType := btAny; end else
|
||
begin StartType := stTerm; BrakeType := btTerm; end else
|
||
if SameText('CloseSymbol', Key) then fRule.fCloseSymbol.Symbol := Value else
|
||
if SameText('CloseSymbolFinishOnEol', Key) then
|
||
if LowValue = 'true' then fRule.fCloseSymbol.Symbol := fRule.fCloseSymbol.Symbol + #0 else else
|
||
if SameText('CloseSymbolStartLine', Key) then with fRule.fCloseSymbol do
|
||
if LowValue = 'true' then StartLine := slFirst else
|
||
if LowValue = 'nonspace' then StartLine := slFirstNonSpace else
|
||
StartLine := slNotFirst else
|
||
if SameText('CloseSymbolPartOfTerm', Key) then with fRule.fCloseSymbol do
|
||
if LowValue = 'true' then begin StartType := stAny; BrakeType := btAny; end else
|
||
if LowValue = 'left' then begin StartType := stAny; BrakeType := btTerm; end else
|
||
if LowValue = 'right' then begin StartType := stTerm; BrakeType := btAny; end else
|
||
begin StartType := stTerm; BrakeType := btTerm; end else
|
||
if SameText('CloseOnTerm', Key) then fRule.fCloseOnTerm := (LowValue = 'true') else
|
||
if SameText('CloseOnEol', Key) then fRule.fCloseOnEol := (LowValue = 'true') else
|
||
if SameText('AllowPredClose', Key) then fRule.fAllowPredClose := (LowValue = 'true') else
|
||
end else
|
||
if SameText('Range', ChildNode.NodeName) then begin
|
||
NewSynRange := TSynRange.Create;
|
||
NewSynRange.Styles := Styles;
|
||
AddRange(NewSynRange);
|
||
NewSynRange.LoadFromXml(ChildNode);
|
||
end else
|
||
if SameText('Keywords', ChildNode.NodeName) then begin
|
||
NewSynKeyList := TSynKeyList.Create;
|
||
NewSynKeyList.Styles := Styles;
|
||
AddKeyList(NewSynKeyList);
|
||
NewSynKeyList.LoadFromXml(ChildNode);
|
||
end else
|
||
if SameText('Set', ChildNode.NodeName) then begin
|
||
NewSynSet := TSynSet.Create;
|
||
NewSynSet.Styles := Styles;
|
||
AddSet(NewSynSet);
|
||
NewSynSet.LoadFromXml(ChildNode);
|
||
end
|
||
{ else if SameText(xml.CurName, 'TextStyle') then
|
||
begin
|
||
DefaultAttri := fStyles.getStyleDef(xml.CurContent, defaultAttr);
|
||
if (NumberAttri = DefaultAttr) or (NumberAttri = nil) then
|
||
NumberAttri := DefaultAttri;
|
||
end
|
||
else if SameText(xml.CurName, 'NumberStyle') then
|
||
NumberAttri := fStyles.getStyleDef(xml.CurContent, defaultAttr);}
|
||
end;
|
||
end;
|
||
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
// SSSSSS AAAAAA V V IIIII NN N GGGGGGG //
|
||
// S A A V V I NNN N G //
|
||
// SSSSS AAAAAAAA VV VV I N NNN N G GGG //
|
||
// S A A VV VV I N NNN G G //
|
||
// SSSSSS A A V IIIII N NN GGGGGGG //
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
|
||
procedure TSynKeyList.SaveToStream(StreamWriter: TStreamWriter; Ind: integer);
|
||
var
|
||
i: integer;
|
||
begin
|
||
with StreamWriter do begin
|
||
WriteTag(Ind, 'Keywords');
|
||
WriteParam('Name', Name);
|
||
WriteBoolParam('Enabled', Enabled, True);
|
||
Attribs.SaveToStream(StreamWriter);
|
||
WriteParam('Style', Style);
|
||
WriteString(CloseStartTag + EOL);
|
||
for i := 0 to KeyList.Count-1 do begin
|
||
WriteTag(Ind+2, 'Word');
|
||
WriteParam('Value', KeyList[i], CloseEmptyTag);
|
||
end;
|
||
WriteTag(Ind, '/Keywords', True);
|
||
end;
|
||
end;
|
||
|
||
procedure TSynSet.SaveToStream(StreamWriter: TStreamWriter; Ind: integer);
|
||
begin
|
||
with StreamWriter do begin
|
||
WriteTag(Ind, 'Set');
|
||
WriteParam('Name', Name);
|
||
WriteBoolParam('Enabled', Enabled, True);
|
||
Attribs.SaveToStream(StreamWriter);
|
||
WriteParam('Style', Style);
|
||
WriteParam('Symbols', SetToStr(SymbSet), CloseEmptyTag);
|
||
{ if S.StartType = stAny then
|
||
if S.BrakeType = btAny then InsertTag(Ind+1, 'SymbolSetPartOfTerm', 'True')
|
||
else InsertTag(Ind+1, 'SymbolSetPartOfTerm', 'Left')
|
||
else
|
||
if S.BrakeType = btAny then InsertTag(Ind+1, 'SymbolSetPartOfTerm', 'Right')
|
||
else InsertTag(Ind+1, 'SymbolSetPartOfTerm', 'False');}
|
||
end;
|
||
end;
|
||
|
||
procedure TSynRange.SaveToStream(StreamWriter: TStreamWriter; Ind: integer);
|
||
var
|
||
i: integer;
|
||
begin
|
||
with StreamWriter do begin
|
||
WriteTag(Ind, 'Range');
|
||
WriteParam('Name', Name);
|
||
WriteBoolParam('Enabled', Enabled, True);
|
||
Attribs.SaveToStream(StreamWriter);
|
||
WriteParam('Style', Style);
|
||
WriteBoolParam('CaseSensitive', CaseSensitive, False);
|
||
WriteString(EOL + Indent(Ind + Length('<Range')));
|
||
WriteParam('Delimiters', SetToStr(TermSymbols), CloseStartTag);
|
||
for i := 0 to 0 do begin
|
||
WriteTag(Ind+2, 'Rule');
|
||
with fRule.fOpenSymbol do begin
|
||
if Length(Symbol) > 0 then
|
||
if Symbol[Length(Symbol)] = #0 then begin
|
||
WriteParam('OpenSymbol', copy(Symbol, 1, Length(Symbol) - 1));
|
||
WriteParam('OpenSymbolFinishOnEol', 'True');
|
||
end else begin
|
||
WriteParam('OpenSymbol', Symbol);
|
||
{WriteParam('OpenSymbolFinishOnEol', 'False');}
|
||
end;
|
||
if StartLine = slFirst then WriteParam('OpenSymbolStartLine', 'True') else
|
||
if StartLine = slFirstNonSpace then WriteParam('OpenSymbolStartLine', 'NonSpace');
|
||
//else WriteParam('OpenSymbolStartLine', 'False');
|
||
if StartType = stAny then
|
||
if BrakeType = btAny then //WriteParam('OpenSymbolPartOfTerm', 'True')
|
||
else WriteParam('OpenSymbolPartOfTerm', 'Left') else
|
||
if BrakeType = btAny then WriteParam('OpenSymbolPartOfTerm', 'Right')
|
||
else WriteParam('OpenSymbolPartOfTerm', 'False');
|
||
end;
|
||
with fRule.fCloseSymbol do begin
|
||
if Length(Symbol) > 0 then
|
||
if Symbol[Length(Symbol)] = #0 then begin
|
||
WriteParam('CloseSymbol', copy(Symbol, 1, Length(Symbol) - 1));
|
||
WriteParam('CloseSymbolFinishOnEol', 'True');
|
||
end else begin
|
||
WriteParam('CloseSymbol', Symbol);
|
||
{WriteParam('CloseSymbolFinishOnEol', 'False');}
|
||
end;
|
||
if StartLine = slFirst then WriteParam('CloseSymbolStartLine', 'True') else
|
||
if StartLine = slFirstNonSpace then WriteParam('CloseSymbolStartLine', 'NonSpace');
|
||
//else WriteParam('CloseSymbolStartLine', 'False');
|
||
if StartType = stAny then
|
||
if BrakeType = btAny then //WriteParam('CloseSymbolPartOfTerm', 'True')
|
||
else WriteParam('CloseSymbolPartOfTerm', 'Left') else
|
||
if BrakeType = btAny then WriteParam('CloseSymbolPartOfTerm', 'Right')
|
||
else WriteParam('CloseSymbolPartOfTerm', 'False');
|
||
end;
|
||
WriteBoolParam('CloseOnTerm', fRule.fCloseOnTerm, False);
|
||
WriteBoolParam('CloseOnEol', fRule.fCloseOnEol, False);
|
||
WriteBoolParam('AllowPredClose', fRule.fAllowPredClose, False);
|
||
WriteString(CloseEmptyTag + EOL);
|
||
end;
|
||
for i := 0 to KeyListCount-1 do KeyLists[i].SaveToStream(StreamWriter, Ind+2);
|
||
for i := 0 to SetCount-1 do Sets[i].SaveToStream(StreamWriter, Ind+2);
|
||
for i := 0 to RangeCount-1 do Ranges[i].SaveToStream(StreamWriter, Ind+2);
|
||
WriteTag(Ind, '/Range', True);
|
||
end;
|
||
end;
|
||
|
||
function ReadValue(ANode: TDOMNode): String;
|
||
begin
|
||
if Assigned(ANode.FirstChild) then
|
||
Result:= ANode.FirstChild.NodeValue
|
||
else
|
||
Result:= EmptyStr;
|
||
end;
|
||
|
||
function Verify(tag: string; xml: TDOMNode): boolean; overload;
|
||
begin
|
||
Result := SameText(xml.NodeName, tag);
|
||
end;
|
||
|
||
procedure LoadAttri(curRule: TSynRule; xml: TDOMNode);
|
||
var
|
||
J: Integer;
|
||
ChildNode: TDOMNode;
|
||
begin
|
||
// inc(CurRule.ind);
|
||
CurRule.Attribs{ByIndex[0]}.ParentForeground := False;
|
||
CurRule.Attribs{ByIndex[0]}.ParentBackground := False;
|
||
for J := 0 to Int32(xml.ChildNodes.Count) - 1 do
|
||
begin
|
||
ChildNode:= xml.ChildNodes.Item[J];
|
||
if Verify('Back',ChildNode) then begin
|
||
CurRule.Attribs.Background := StrToIntDef(ReadValue(ChildNode), $FFFFFF);
|
||
CurRule.Attribs.OldColorBackground := CurRule.Attribs.Background;
|
||
end else
|
||
if Verify('Fore',ChildNode) then begin
|
||
CurRule.Attribs.Foreground := StrToIntDef(ReadValue(ChildNode), 0);
|
||
CurRule.Attribs.OldColorForeground := CurRule.Attribs.Foreground;
|
||
end else
|
||
if Verify('Style',ChildNode) then
|
||
CurRule.Attribs.Style := StrToFontStyle(ReadValue(ChildNode))
|
||
else if Verify('ParentForeground',ChildNode) then
|
||
CurRule.Attribs.ParentForeground := LowerCase(ReadValue(ChildNode)) = 'true'
|
||
else if Verify('ParentBackground',ChildNode) then
|
||
CurRule.Attribs.ParentBackground := LowerCase(ReadValue(ChildNode)) = 'true';
|
||
end;
|
||
end;
|
||
|
||
procedure TSynKeyList.LoadHglFromXml(xml: TDOMNode; SchCount,SchIndex: integer);
|
||
var
|
||
J: Integer;
|
||
ChildNode: TDOMNode;
|
||
TempSchIndex: integer;
|
||
begin
|
||
// if curKw = nil then Exit;
|
||
if xml = nil then Exit;
|
||
|
||
if ( SameText('KW'{'Keywords'}, xml.NodeName) ) then
|
||
begin
|
||
if xml.Attributes.Length > 0 then Name := xml.Attributes[0].NodeValue
|
||
// Attribs := fStyles.GetStyleDef(getAttrValue('style', xml), defaultattr);
|
||
end
|
||
else
|
||
raise Exception.Create(ClassName + '.LoadFromXml - no keywords to load!');
|
||
|
||
// ClearAttributes();
|
||
// for i := 0 to SchCount-1 do
|
||
// AddAttribute();
|
||
// ind := -1;
|
||
TempSchIndex := SchIndex;
|
||
|
||
KeyList.BeginUpdate;
|
||
KeyList.Clear;
|
||
try
|
||
for J := 0 to Int32(xml.ChildNodes.Count) - 1 do
|
||
begin
|
||
ChildNode:= xml.ChildNodes.Item[J];
|
||
if SameText(ChildNode.NodeName, 'Attri') or SameText(ChildNode.NodeName, 'Def') then begin
|
||
if TempSchIndex >= 0 then LoadAttri(self, ChildNode);
|
||
dec(TempSchIndex);
|
||
end else
|
||
if Verify('Enabled',ChildNode) then
|
||
Enabled := LowerCase(ReadValue(ChildNode)) = 'true'
|
||
else
|
||
if Verify('W',ChildNode) then begin
|
||
KeyList.Add(ReadValue(ChildNode));
|
||
end;
|
||
end;
|
||
finally
|
||
ind := SchIndex;
|
||
KeyList.EndUpdate;
|
||
end;
|
||
end;
|
||
|
||
procedure TSynSet.LoadHglFromXml(xml: TDOMNode; SchCount,SchIndex: integer);
|
||
var
|
||
J: Integer;
|
||
ChildNode: TDOMNode;
|
||
TempSchIndex: integer;
|
||
begin
|
||
// if curSet = nil then Exit;
|
||
if xml = nil then Exit;
|
||
|
||
if ( SameText('Set', xml.NodeName) ) then
|
||
begin
|
||
if xml.Attributes.Length > 0 then Name := xml.Attributes[0].NodeValue
|
||
// Attribs := fStyles.GetStyleDef(getAttrValue('style', xml), defaultattr);
|
||
end
|
||
else
|
||
raise Exception.Create(ClassName + '.LoadFromXml - no set to load!');
|
||
|
||
{ ClearAttributes();
|
||
for i := 0 to SchCount-1 do
|
||
AddAttribute();
|
||
ind := -1;}
|
||
TempSchIndex := SchIndex;
|
||
|
||
for J := 0 to Int32(xml.ChildNodes.Count) - 1 do
|
||
begin
|
||
ChildNode:= xml.ChildNodes.Item[J];
|
||
if SameText(ChildNode.NodeName, 'Attri') or SameText(ChildNode.NodeName, 'Def') then begin
|
||
if TempSchIndex >= 0 then LoadAttri(self, ChildNode);
|
||
dec(TempSchIndex);
|
||
end else
|
||
if Verify('Enabled',ChildNode) then
|
||
Enabled := LowerCase(ReadValue(ChildNode)) = 'true'
|
||
else
|
||
if Verify('S',ChildNode) then
|
||
SymbSet := StrToSet(ReadValue(ChildNode));
|
||
end;
|
||
|
||
ind := SchIndex;
|
||
end;
|
||
|
||
procedure TSynRange.LoadHglFromXml(xml: TDOMNode; SchCount, SchIndex: integer);
|
||
var
|
||
NewSynRange: TSynRange;
|
||
NewSynKeyList: TSynKeyList;
|
||
NewSynSet: TSynSet;
|
||
S: string;
|
||
TempSchIndex: integer;
|
||
J: Integer;
|
||
ChildNode: TDOMNode;
|
||
begin
|
||
fRule.fOpenSymbol.BrakeType := btAny;
|
||
if SameText(xml.NodeName, 'Range') then
|
||
begin
|
||
if xml.Attributes.Length > 0 then
|
||
S:= xml.Attributes[0].NodeValue;
|
||
if S <> '' then
|
||
Name := S;
|
||
end else
|
||
raise Exception.Create(ClassName + '.LoadFromXml - no range to load!');
|
||
|
||
{ ClearAttributes();
|
||
for i := 0 to SchCount-1 do
|
||
AddAttribute();
|
||
ind := -1;}
|
||
TempSchIndex := SchIndex;
|
||
|
||
for J := 0 to Int32(xml.ChildNodes.Count) - 1 do
|
||
begin
|
||
ChildNode:= xml.ChildNodes.Item[J];
|
||
if Verify('Enabled', ChildNode) then
|
||
Enabled := LowerCase(ReadValue(ChildNode)) = 'true'
|
||
else
|
||
if Verify('CaseSensitive', ChildNode) then
|
||
CaseSensitive := LowerCase(ReadValue(ChildNode)) = 'true'
|
||
else
|
||
if Verify('OpenSymbol', ChildNode) then
|
||
fRule.fOpenSymbol.Symbol := ReadValue(ChildNode)
|
||
else
|
||
if Verify('CloseSymbol', ChildNode) then
|
||
fRule.fCloseSymbol.Symbol := ReadValue(ChildNode)
|
||
else
|
||
if Verify('OpenSymbolFinishOnEol', ChildNode) then
|
||
if LowerCase(ReadValue(ChildNode)) = 'true' then
|
||
fRule.fOpenSymbol.Symbol := fRule.fOpenSymbol.Symbol + #0
|
||
else
|
||
else
|
||
if Verify('CloseSymbolFinishOnEol',ChildNode) then
|
||
if LowerCase(ReadValue(ChildNode)) = 'true' then
|
||
fRule.fCloseSymbol.Symbol := fRule.fCloseSymbol.Symbol + #0
|
||
else
|
||
else
|
||
if Verify('CloseOnTerm',ChildNode) then
|
||
fRule.fCloseOnTerm := LowerCase(ReadValue(ChildNode)) = 'true'
|
||
else
|
||
if Verify('CloseOnEol',ChildNode) then
|
||
fRule.fCloseOnEol := LowerCase(ReadValue(ChildNode)) = 'true'
|
||
else
|
||
if Verify('AllowPredClose',ChildNode) then
|
||
fRule.fAllowPredClose := LowerCase(ReadValue(ChildNode)) = 'true'
|
||
else
|
||
if Verify('OpenSymbolStartLine',ChildNode) then
|
||
if LowerCase(ReadValue(ChildNode)) = 'true' then
|
||
fRule.fOpenSymbol.StartLine := slFirst
|
||
else if LowerCase(ReadValue(ChildNode)) = 'nonspace' then
|
||
fRule.fOpenSymbol.StartLine := slFirstNonSpace
|
||
else
|
||
fRule.fOpenSymbol.StartLine := slNotFirst
|
||
else
|
||
if Verify('CloseSymbolStartLine',ChildNode) then
|
||
if LowerCase(ReadValue(ChildNode)) = 'true' then
|
||
fRule.fCloseSymbol.StartLine := slFirst
|
||
else if LowerCase(ReadValue(ChildNode)) = 'nonspace' then
|
||
fRule.fCloseSymbol.StartLine := slFirstNonSpace
|
||
else
|
||
fRule.fCloseSymbol.StartLine := slNotFirst
|
||
else
|
||
if Verify('AnyTerm',ChildNode) then
|
||
if LowerCase(ReadValue(ChildNode)) = 'true' then
|
||
fRule.fOpenSymbol.BrakeType := btAny
|
||
else
|
||
fRule.fOpenSymbol.BrakeType := btTerm
|
||
// if StrToBoolDef(ReadValue(ChildNode), false) then
|
||
// fRule.fOpenSymbol.BrakeType := btTerm;
|
||
else
|
||
if Verify('OpenSymbolPartOfTerm',ChildNode) then
|
||
if LowerCase(ReadValue(ChildNode)) = 'true' then begin
|
||
fRule.fOpenSymbol.StartType := stAny;
|
||
fRule.fOpenSymbol.BrakeType := btAny;
|
||
end else if LowerCase(ReadValue(ChildNode)) = 'left' then begin
|
||
fRule.fOpenSymbol.StartType := stAny;
|
||
fRule.fOpenSymbol.BrakeType := btTerm;
|
||
end else if LowerCase(ReadValue(ChildNode)) = 'right' then begin
|
||
fRule.fOpenSymbol.StartType := stTerm;
|
||
fRule.fOpenSymbol.BrakeType := btAny;
|
||
end else begin
|
||
fRule.fOpenSymbol.StartType := stTerm;
|
||
fRule.fOpenSymbol.BrakeType := btTerm;
|
||
end
|
||
else
|
||
if Verify('CloseSymbolPartOfTerm',ChildNode) then
|
||
if LowerCase(ReadValue(ChildNode)) = 'true' then begin
|
||
fRule.fCloseSymbol.StartType := stAny;
|
||
fRule.fCloseSymbol.BrakeType := btAny;
|
||
end else if LowerCase(ReadValue(ChildNode)) = 'left' then begin
|
||
fRule.fCloseSymbol.StartType := stAny;
|
||
fRule.fCloseSymbol.BrakeType := btTerm;
|
||
end else if LowerCase(ReadValue(ChildNode)) = 'right' then begin
|
||
fRule.fCloseSymbol.StartType := stTerm;
|
||
fRule.fCloseSymbol.BrakeType := btAny;
|
||
end else begin
|
||
fRule.fCloseSymbol.StartType := stTerm;
|
||
fRule.fCloseSymbol.BrakeType := btTerm;
|
||
end
|
||
else
|
||
if Verify('DelimiterChars',ChildNode) then
|
||
// if SameText(GetAttrValue('spaces', xml), 'true') then
|
||
// TermSymbols := String2Set(ReadValue(ChildNode)) + [#32, #9, #13, #10]
|
||
// else
|
||
if Assigned(ChildNode.FirstChild) then
|
||
TermSymbols := StrToSet(ReadValue(ChildNode))
|
||
else
|
||
// CloseOnTerm := true;
|
||
else
|
||
{ else if SameText(xml.CurName, 'TextStyle') then
|
||
begin
|
||
DefaultAttri := fStyles.getStyleDef(ReadValue(ChildNode), defaultAttr);
|
||
if (NumberAttri = DefaultAttr) or (NumberAttri = nil) then
|
||
NumberAttri := DefaultAttri;
|
||
end
|
||
else if SameText(xml.CurName, 'NumberStyle') then
|
||
NumberAttri := fStyles.getStyleDef(ReadValue(ChildNode), defaultAttr);}
|
||
if SameText(ChildNode.NodeName, 'Attri') or SameText(ChildNode.NodeName, 'Def') then begin
|
||
if TempSchIndex >= 0 then LoadAttri(self, ChildNode);
|
||
dec(TempSchIndex);
|
||
end else
|
||
if SameText(ChildNode.NodeName, 'Range') then begin
|
||
NewSynRange := TSynRange.Create;
|
||
AddRange(NewSynRange);
|
||
NewSynRange.LoadHglFromXml(ChildNode, SchCount, SchIndex);
|
||
end else
|
||
if SameText(ChildNode.NodeName, 'KW') then begin
|
||
NewSynKeyList := TSynKeyList.Create;
|
||
AddKeyList(NewSynKeyList);
|
||
NewSynKeyList.LoadHglFromXml(ChildNode, SchCount, SchIndex);
|
||
end else
|
||
if SameText(ChildNode.NodeName, 'Set') then begin
|
||
NewSynSet := TSynSet.Create;
|
||
AddSet(NewSynSet);
|
||
NewSynSet.LoadHglFromXml(ChildNode, SchCount, SchIndex);
|
||
end;
|
||
end;
|
||
ind := SchIndex;
|
||
end;
|
||
|
||
procedure TSynRange.LoadHglFromStream(aSrc: TStream);
|
||
var
|
||
I, J: Integer;
|
||
xml: TXMLDocument = nil;
|
||
SchCount, SchIndex: integer;
|
||
ChildNode, ChildNode2: TDOMNode;
|
||
begin
|
||
try
|
||
SchCount := 0; SchIndex := -1;
|
||
ReadXMLFile(xml, aSrc);
|
||
|
||
for J := 0 to Int32(xml.ChildNodes.Count) - 1 do
|
||
begin
|
||
ChildNode:= xml.ChildNodes.Item[J];
|
||
if Verify('SchemeIndex', ChildNode) then
|
||
SchIndex := StrToInt(ReadValue(ChildNode))
|
||
else if Verify('Schemes', ChildNode) then
|
||
begin
|
||
for I:= 0 to Int32(ChildNode.ChildNodes.Count) - 1 do begin
|
||
ChildNode2:= ChildNode.ChildNodes.Item[I];
|
||
if Verify('S', ChildNode2) then
|
||
inc(SchCount);
|
||
end
|
||
end
|
||
else if SameText(ChildNode.NodeName, 'Range') then
|
||
LoadHglFromXml(ChildNode, SchCount, SchIndex);
|
||
end;
|
||
finally
|
||
xml.Free;
|
||
end;
|
||
end;
|
||
|
||
end.
|