* Prepared HTML writer
* Separated highlighting from writing
This commit is contained in:
parent
562c64f69a
commit
bd0b6bc3f4
70
UApp.pas
70
UApp.pas
|
@ -25,7 +25,7 @@ unit UApp;
|
||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, CustApp, RegExpr,
|
Classes, SysUtils, CustApp, RegExpr, Math,
|
||||||
UFilter, UWriter;
|
UFilter, UWriter;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
@ -105,6 +105,9 @@ begin
|
||||||
|
|
||||||
FWriter.Add(TConsoleWriter.Create);
|
FWriter.Add(TConsoleWriter.Create);
|
||||||
|
|
||||||
|
if HasOption('html') then
|
||||||
|
FWriter.Add(THTMLWriter.Create(GetOptionValue('html')));
|
||||||
|
|
||||||
AssignFile(logFile, FLogFileName);
|
AssignFile(logFile, FLogFileName);
|
||||||
Reset(logFile);
|
Reset(logFile);
|
||||||
|
|
||||||
|
@ -153,10 +156,73 @@ end;
|
||||||
procedure TLogFilterApplication.WriteContent(AContent: String;
|
procedure TLogFilterApplication.WriteContent(AContent: String;
|
||||||
AFilters: TFilterList; AGroupRanges: TGroupRanges);
|
AFilters: TFilterList; AGroupRanges: TGroupRanges);
|
||||||
var
|
var
|
||||||
|
i: Integer;
|
||||||
|
matchPos, offset: Integer;
|
||||||
|
highlights: THighlights;
|
||||||
|
highlight: THighlight;
|
||||||
|
group: Byte;
|
||||||
writer: TWriter;
|
writer: TWriter;
|
||||||
begin
|
begin
|
||||||
|
|
||||||
|
highlights := THighlights.Create;
|
||||||
|
|
||||||
|
offset := 0;
|
||||||
|
|
||||||
|
for i := 0 to AFilters.Count - 1 do
|
||||||
|
begin
|
||||||
|
if AFilters[i].Expression.Exec(AContent) then
|
||||||
|
begin
|
||||||
|
repeat
|
||||||
|
// We need these values anyway.
|
||||||
|
matchPos := AFilters[i].Expression.MatchPos[0];
|
||||||
|
offset := AFilters[i].Expression.MatchLen[0];
|
||||||
|
|
||||||
|
group := AFilters[i].Group;
|
||||||
|
if group < Length(AGroupRanges) then
|
||||||
|
begin
|
||||||
|
if (matchPos + offset < AGroupRanges[group].StartIdx) or
|
||||||
|
(matchPos > AGroupRanges[group].EndIdx) then
|
||||||
|
continue; //Pointless; nothing we can do here
|
||||||
|
|
||||||
|
highlight.Start := Max(AGroupRanges[group].StartIdx, matchPos);
|
||||||
|
highlight.Length := Min(AGroupRanges[group].EndIdx - highlight.Start,
|
||||||
|
highlight.Start + offset - matchPos);
|
||||||
|
|
||||||
|
{$ifdef debugmatches}
|
||||||
|
writeln(' Highlight: ', highlight.Start, ', ', highlight.Length);
|
||||||
|
writeln(' MatchPos: ', matchPos, ', StartIdx: ', AGroupRanges[group].StartIdx);
|
||||||
|
writeln(' Offset: ', offset, ', EndIdx: ', AGroupRanges[group].EndIdx);
|
||||||
|
{$endif}
|
||||||
|
end else
|
||||||
|
begin
|
||||||
|
highlight.Start := matchPos;
|
||||||
|
highlight.Length := offset;
|
||||||
|
end;
|
||||||
|
|
||||||
|
highlight.FGColor := AFilters[i].FGColor;
|
||||||
|
highlight.BGColor := AFilters[i].BGColor;
|
||||||
|
highlights.Add(highlight);
|
||||||
|
until not AFilters[i].Expression.ExecNext;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
highlights.Sort(@CompareHighlights);
|
||||||
|
|
||||||
|
// Sanitize highlights
|
||||||
|
for i := 0 to highlights.Count - 2 do
|
||||||
|
begin
|
||||||
|
if (highlights[i].Start + highlights[i].Length) > highlights[i+1].Start then
|
||||||
|
begin
|
||||||
|
highlight := highlights[i];
|
||||||
|
highlight.Length := highlights[i+1].Start - highlights[i].Start;
|
||||||
|
highlights[i] := highlight;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
for writer in FWriter do
|
for writer in FWriter do
|
||||||
writer.WriteContent(AContent, AFilters, AGroupRanges);
|
writer.WriteContent(AContent, highlights);
|
||||||
|
|
||||||
|
highlights.Free;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TLogFilterApplication.Create(TheOwner: TComponent);
|
constructor TLogFilterApplication.Create(TheOwner: TComponent);
|
||||||
|
|
116
UWriter.pas
116
UWriter.pas
|
@ -5,13 +5,13 @@ unit UWriter;
|
||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, UFilter, Math, crt, fgl;
|
Classes, SysUtils, UFilter, crt, fgl;
|
||||||
|
|
||||||
type
|
type
|
||||||
TWriter = class
|
TWriter = class
|
||||||
public
|
public
|
||||||
procedure WriteContent(AContent: String; AFilters: TFilterList;
|
procedure WriteContent(AContent: String;
|
||||||
AGroupRanges: TGroupRanges); virtual; abstract;
|
AHighlights: THighlights); virtual; abstract;
|
||||||
end;
|
end;
|
||||||
TWriterList = specialize TFPGObjectList<TWriter>;
|
TWriterList = specialize TFPGObjectList<TWriter>;
|
||||||
|
|
||||||
|
@ -19,80 +19,64 @@ type
|
||||||
|
|
||||||
TConsoleWriter = class(TWriter)
|
TConsoleWriter = class(TWriter)
|
||||||
public
|
public
|
||||||
procedure WriteContent(AContent: String; AFilters: TFilterList;
|
procedure WriteContent(AContent: String;
|
||||||
AGroupRanges: TGroupRanges); override;
|
AHighlights: THighlights); override;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ THTMLWriter }
|
||||||
|
|
||||||
|
THTMLWriter = class(TWriter)
|
||||||
|
protected
|
||||||
|
FFileStream: TFileStream;
|
||||||
|
procedure WriteLine(AContent: String);
|
||||||
|
public
|
||||||
|
constructor Create(AFileName: String);
|
||||||
|
destructor Destroy; override;
|
||||||
|
procedure WriteContent(AContent: String;
|
||||||
|
AHighlights: THighlights); override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
|
{ THTMLWriter }
|
||||||
|
|
||||||
|
procedure THTMLWriter.WriteLine(AContent: String);
|
||||||
|
begin
|
||||||
|
AContent := AContent + LineEnding;
|
||||||
|
FFileStream.Write(AContent[1], Length(AContent));
|
||||||
|
end;
|
||||||
|
|
||||||
|
constructor THTMLWriter.Create(AFileName: String);
|
||||||
|
begin
|
||||||
|
FFileStream := TFileStream.Create(AFileName, fmCreate);
|
||||||
|
WriteLine('<html>');
|
||||||
|
WriteLine('<body>');
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor THTMLWriter.Destroy;
|
||||||
|
begin
|
||||||
|
WriteLine('</body>');
|
||||||
|
WriteLine('</html>');
|
||||||
|
FFileStream.Free;
|
||||||
|
inherited Destroy;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure THTMLWriter.WriteContent(AContent: String; AHighlights: THighlights);
|
||||||
|
begin
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
{ TConsoleWriter }
|
{ TConsoleWriter }
|
||||||
|
|
||||||
procedure TConsoleWriter.WriteContent(AContent: String; AFilters: TFilterList;
|
procedure TConsoleWriter.WriteContent(AContent: String; AHighlights: THighlights
|
||||||
AGroupRanges: TGroupRanges);
|
);
|
||||||
var
|
var
|
||||||
i: Integer;
|
|
||||||
matchPos, offset, lastPos: Integer;
|
matchPos, offset, lastPos: Integer;
|
||||||
highlights: THighlights;
|
|
||||||
highlight: THighlight;
|
highlight: THighlight;
|
||||||
group: Byte;
|
|
||||||
begin
|
begin
|
||||||
highlights := THighlights.Create;
|
|
||||||
|
|
||||||
offset := 0;
|
|
||||||
lastPos := 1;
|
lastPos := 1;
|
||||||
|
|
||||||
for i := 0 to AFilters.Count - 1 do
|
for highlight in AHighlights do
|
||||||
begin
|
|
||||||
if AFilters[i].Expression.Exec(AContent) then
|
|
||||||
begin
|
|
||||||
repeat
|
|
||||||
// We need these values anyway.
|
|
||||||
matchPos := AFilters[i].Expression.MatchPos[0];
|
|
||||||
offset := AFilters[i].Expression.MatchLen[0];
|
|
||||||
|
|
||||||
group := AFilters[i].Group;
|
|
||||||
if group < Length(AGroupRanges) then
|
|
||||||
begin
|
|
||||||
if (matchPos + offset < AGroupRanges[group].StartIdx) or
|
|
||||||
(matchPos > AGroupRanges[group].EndIdx) then
|
|
||||||
continue; //Pointless; nothing we can do here
|
|
||||||
|
|
||||||
highlight.Start := Max(AGroupRanges[group].StartIdx, matchPos);
|
|
||||||
highlight.Length := Min(AGroupRanges[group].EndIdx - highlight.Start,
|
|
||||||
highlight.Start + offset - matchPos);
|
|
||||||
|
|
||||||
{$ifdef debugmatches}
|
|
||||||
writeln(' Highlight: ', highlight.Start, ', ', highlight.Length);
|
|
||||||
writeln(' MatchPos: ', matchPos, ', StartIdx: ', AGroupRanges[group].StartIdx);
|
|
||||||
writeln(' Offset: ', offset, ', EndIdx: ', AGroupRanges[group].EndIdx);
|
|
||||||
{$endif}
|
|
||||||
end else
|
|
||||||
begin
|
|
||||||
highlight.Start := matchPos;
|
|
||||||
highlight.Length := offset;
|
|
||||||
end;
|
|
||||||
|
|
||||||
highlight.FGColor := AFilters[i].FGColor;
|
|
||||||
highlight.BGColor := AFilters[i].BGColor;
|
|
||||||
highlights.Add(highlight);
|
|
||||||
until not AFilters[i].Expression.ExecNext;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
highlights.Sort(@CompareHighlights);
|
|
||||||
|
|
||||||
// Sanitize highlights
|
|
||||||
for i := 0 to highlights.Count - 2 do
|
|
||||||
begin
|
|
||||||
if (highlights[i].Start + highlights[i].Length) > highlights[i+1].Start then
|
|
||||||
begin
|
|
||||||
highlight := highlights[i];
|
|
||||||
highlight.Length := highlights[i+1].Start - highlights[i].Start;
|
|
||||||
highlights[i] := highlight;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
for highlight in highlights do
|
|
||||||
begin
|
begin
|
||||||
matchPos := highlight.Start;
|
matchPos := highlight.Start;
|
||||||
offset := highlight.Length;
|
offset := highlight.Length;
|
||||||
|
@ -107,8 +91,6 @@ begin
|
||||||
end;
|
end;
|
||||||
|
|
||||||
writeln(Copy(AContent, lastPos, Length(AContent)));
|
writeln(Copy(AContent, lastPos, Length(AContent)));
|
||||||
|
|
||||||
highlights.Free;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
Loading…
Reference in New Issue