SynEdit: Fixed Exporter to work with TSynMultiSyn

git-svn-id: trunk@38554 -
This commit is contained in:
martin 2012-09-07 11:34:35 +00:00
parent 23d713f7b5
commit c391dad785

View File

@ -49,8 +49,8 @@ interface
uses uses
Classes, Classes,
SysUtils, SysUtils,
SynEditHighlighter, SynEditHighlighter, SynEditTextBase, SynEditTextBuffer,
FileUtil, FPCAdds, LCLIntf, LCLType, FileUtil, LazUTF8, FPCAdds, LCLType,
Graphics, Clipbrd; Graphics, Clipbrd;
type type
@ -282,46 +282,73 @@ end;
procedure TSynCustomExporter.ExportRange(ALines: TStrings; Start, Stop: TPoint); procedure TSynCustomExporter.ExportRange(ALines: TStrings; Start, Stop: TPoint);
var var
i: integer; i, X, l: integer;
Line, Token: string; Token: string;
IsSpace: boolean; IsSpace: boolean;
Attri: TSynHighlighterAttributes; Attri: TSynHighlighterAttributes;
TheLines: TSynEditStringsBase;
begin begin
// abort if not all necessary conditions are met // abort if not all necessary conditions are met
if not Assigned(ALines) or not Assigned(Highlighter) or (ALines.Count = 0) if not Assigned(ALines) or not Assigned(Highlighter) or (ALines.Count = 0)
or (Start.Y > ALines.Count) or (Start.Y > Stop.Y) or (Start.Y > ALines.Count) or (Start.Y > Stop.Y)
then then
Abort; Abort;
Stop.Y := Max(1, Min(Stop.Y, ALines.Count)); Stop.Y := Max(1, Min(Stop.Y, ALines.Count));
Stop.X := Max(1, Min(Stop.X, Length(ALines[Stop.Y - 1]) + 1)); Stop.X := Max(1, Min(Stop.X, Length(ALines[Stop.Y - 1]) + 1));
Start.X := Max(1, Min(Start.X, Length(ALines[Start.Y - 1]) + 1)); Start.X := Max(1, Min(Start.X, Length(ALines[Start.Y - 1]) + 1));
if (Start.Y = Stop.Y) and (Start.X >= Stop.X) then if (Start.Y = Stop.Y) and (Start.X >= Stop.X) then
Abort; Abort;
if ALines is TSynEditStringsBase then
TheLines := TSynEditStringsBase(ALines)
else begin
TheLines := TSynEditStringList.Create();
TheLines.Assign(ALines);
end;
Highlighter.AttachToLines(TheLines);
try
Highlighter.CurrentLines := TheLines;
Highlighter.ScanRanges;
// initialization // initialization
fBuffer.Position := 0; fBuffer.Position := 0;
// Size is ReadOnly in Delphi 2
fBuffer.SetSize(Max($1000, (Stop.Y - Start.Y) * 128)); fBuffer.SetSize(Max($1000, (Stop.Y - Start.Y) * 128));
Highlighter.ResetRange;
// export all the lines into fBuffer // export all the lines into fBuffer
fFirstAttribute := TRUE; fFirstAttribute := TRUE;
for i := Start.Y to Stop.Y do begin for i := Start.Y to Stop.Y do begin
Line := ALines[i - 1]; Highlighter.StartAtLineIndex(i - 1);
// order is important, since Start.Y might be equal to Stop.Y X := 1;
if i = Stop.Y then
Delete(Line, Stop.X, MaxInt);
if (i = Start.Y) and (Start.X > 1) then
Delete(Line, 1, Start.X - 1);
// export the line
Highlighter.SetLine(Line, i);
while not Highlighter.GetEOL do begin while not Highlighter.GetEOL do begin
Attri := Highlighter.GetTokenAttribute; Attri := Highlighter.GetTokenAttribute;
Token := ReplaceReservedChars(Highlighter.GetToken, IsSpace); Token := Highlighter.GetToken;
l := UTF8Length(Token);
if (i = Start.Y) and (X < Start.X) then
UTF8Delete(Token, 1, Start.X - X);
X := X + l; // TODO: combound chars
if Token = '' then
continue;
if (i = Stop.Y) and (X >= Stop.X) then begin
UTF8Delete(Token, 1 + X - Stop.X, MaxInt);
if Token = '' then
continue;
end;
Token := ReplaceReservedChars(Token, IsSpace);
SetTokenAttribute(IsSpace, Attri); SetTokenAttribute(IsSpace, Attri);
FormatToken(Token); FormatToken(Token);
Highlighter.Next; Highlighter.Next;
end; end;
FormatNewLine; FormatNewLine;
end; end;
if not fFirstAttribute then if not fFirstAttribute then
FormatAfterLastAttribute; FormatAfterLastAttribute;
// insert header // insert header
@ -331,6 +358,11 @@ begin
AddData(GetFooter); AddData(GetFooter);
// Size is ReadOnly in Delphi 2 // Size is ReadOnly in Delphi 2
fBuffer.SetSize(integer(fBuffer.Position)); fBuffer.SetSize(integer(fBuffer.Position));
finally
Highlighter.DetachFromLines(TheLines);
if TheLines <> ALines then
TheLines.Free;
end;
end; end;
procedure TSynCustomExporter.FormatToken(Token: string); procedure TSynCustomExporter.FormatToken(Token: string);