Added highlighting with regular expressions
This commit is contained in:
parent
86fc1aade0
commit
3852f7546c
|
@ -72,6 +72,11 @@
|
||||||
<OtherUnitFiles Value="jtemplate;synapse"/>
|
<OtherUnitFiles Value="jtemplate;synapse"/>
|
||||||
<UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/>
|
<UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/>
|
||||||
</SearchPaths>
|
</SearchPaths>
|
||||||
|
<Linking>
|
||||||
|
<Debugging>
|
||||||
|
<UseHeaptrc Value="True"/>
|
||||||
|
</Debugging>
|
||||||
|
</Linking>
|
||||||
</CompilerOptions>
|
</CompilerOptions>
|
||||||
<Debugging>
|
<Debugging>
|
||||||
<Exceptions Count="3">
|
<Exceptions Count="3">
|
||||||
|
|
165
restemplate.pas
165
restemplate.pas
|
@ -20,17 +20,47 @@
|
||||||
program restemplate;
|
program restemplate;
|
||||||
|
|
||||||
{$mode objfpc}
|
{$mode objfpc}
|
||||||
|
{$modeswitch advancedrecords}
|
||||||
|
|
||||||
{.$define use_synapse}
|
{.$define use_synapse}
|
||||||
{$define use_fclweb}
|
{$define use_fclweb}
|
||||||
|
|
||||||
uses
|
uses
|
||||||
SysUtils, Classes, strutils, IniFiles,
|
SysUtils, Classes, strutils, IniFiles, fgl,
|
||||||
{$ifdef use_synapse}httpsend, ssl_openssl,{$endif}
|
{$ifdef use_synapse}httpsend, ssl_openssl,{$endif}
|
||||||
{$ifdef use_fclweb}fphttpclient,{$endif}
|
{$ifdef use_fclweb}fphttpclient,{$endif}
|
||||||
JTemplate,
|
JTemplate,
|
||||||
fpjson, jsonparser,
|
fpjson, jsonparser,
|
||||||
DOM, XMLRead, XMLWrite;
|
DOM, XMLRead, XMLWrite,
|
||||||
|
RegExpr, crt;
|
||||||
|
|
||||||
|
type
|
||||||
|
TContentType = (ctOther, ctJSON, ctXML);
|
||||||
|
|
||||||
|
{ THighlightFilter }
|
||||||
|
|
||||||
|
THighlightFilter = class
|
||||||
|
Expression: TRegExpr;
|
||||||
|
FGColor: Byte;
|
||||||
|
BGColor: Byte;
|
||||||
|
constructor Create(AString: String);
|
||||||
|
destructor Destroy; override;
|
||||||
|
class var
|
||||||
|
FilterExpression: TRegExpr;
|
||||||
|
ParamExpression: TRegExpr;
|
||||||
|
end;
|
||||||
|
TFilterList = specialize TFPGObjectList<THighlightFilter>;
|
||||||
|
|
||||||
|
{ THighlight }
|
||||||
|
|
||||||
|
THighlight = record
|
||||||
|
FGColor: Byte;
|
||||||
|
BGColor: Byte;
|
||||||
|
Start: Integer;
|
||||||
|
Length: Integer;
|
||||||
|
class operator =(A, B: THighlight): Boolean;
|
||||||
|
end;
|
||||||
|
THighlights = specialize TFPGList<THighlight>;
|
||||||
|
|
||||||
var
|
var
|
||||||
data: TextFile;
|
data: TextFile;
|
||||||
|
@ -45,9 +75,43 @@ var
|
||||||
templateFile, templateName: String;
|
templateFile, templateName: String;
|
||||||
sessionIni: TIniFile;
|
sessionIni: TIniFile;
|
||||||
beautify: Boolean;
|
beautify: Boolean;
|
||||||
|
filters: TFilterList;
|
||||||
|
|
||||||
type
|
{ THighlight }
|
||||||
TContentType = (ctOther, ctJSON, ctXML);
|
|
||||||
|
class operator THighlight. = (A, B: THighlight): Boolean;
|
||||||
|
begin
|
||||||
|
Result := (A.Start = B.Start) and (A.Length = B.Length);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{ THighlightFilter }
|
||||||
|
|
||||||
|
constructor THighlightFilter.Create(AString: String);
|
||||||
|
begin
|
||||||
|
FGColor := $FF;
|
||||||
|
BGColor := $FF;
|
||||||
|
if FilterExpression.Exec(AString) then
|
||||||
|
begin
|
||||||
|
Expression := TRegExpr.Create(Copy(AString, 1, FilterExpression.MatchPos[0] - 1));
|
||||||
|
if ParamExpression.Exec(FilterExpression.Match[0]) then
|
||||||
|
repeat
|
||||||
|
if ParamExpression.Match[1] = 'FG' then
|
||||||
|
FGColor := StrToInt(ParamExpression.Match[2])
|
||||||
|
else if ParamExpression.Match[1] = 'BG' then
|
||||||
|
BGColor := StrToInt(ParamExpression.Match[2]);
|
||||||
|
until not ParamExpression.ExecNext;
|
||||||
|
end else
|
||||||
|
Expression := TRegExpr.Create(AString);
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor THighlightFilter.Destroy;
|
||||||
|
begin
|
||||||
|
Expression.Free;
|
||||||
|
inherited Destroy;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ Main }
|
||||||
|
|
||||||
procedure CmdAskUser(AName: String);
|
procedure CmdAskUser(AName: String);
|
||||||
var
|
var
|
||||||
|
@ -107,6 +171,75 @@ begin
|
||||||
Result := (ContentType <> ctOther);
|
Result := (ContentType <> ctOther);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function CompareHighlights(const AHL1: THighlight; const AHL2: THighlight): Integer;
|
||||||
|
begin
|
||||||
|
if AHL1.Start = AHL2.Start then
|
||||||
|
begin
|
||||||
|
Result := AHL1.Length - AHL2.Length;
|
||||||
|
end else
|
||||||
|
Result := AHL1.Start - AHL2.Start;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure WriteContent;
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
matchPos, offset, lastPos: Integer;
|
||||||
|
data: String;
|
||||||
|
highlights: THighlights;
|
||||||
|
highlight: THighlight;
|
||||||
|
begin
|
||||||
|
highlights := THighlights.Create;
|
||||||
|
data := content.Text;
|
||||||
|
|
||||||
|
offset := 0;
|
||||||
|
lastPos := 1;
|
||||||
|
|
||||||
|
for i := 0 to filters.Count - 1 do
|
||||||
|
begin
|
||||||
|
if filters[i].Expression.Exec(data) then
|
||||||
|
begin
|
||||||
|
repeat
|
||||||
|
highlight.Start := filters[i].Expression.MatchPos[0];
|
||||||
|
highlight.Length := filters[i].Expression.MatchLen[0];
|
||||||
|
highlight.FGColor := filters[i].FGColor;
|
||||||
|
highlight.BGColor := filters[i].BGColor;
|
||||||
|
highlights.Add(highlight);
|
||||||
|
until not filters[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
|
||||||
|
matchPos := highlight.Start;
|
||||||
|
offset := highlight.Length;
|
||||||
|
write(Copy(data, lastPos, matchPos - lastPos));
|
||||||
|
if highlight.FGColor < $FF then
|
||||||
|
TextColor(highlight.FGColor);
|
||||||
|
if highlight.BGColor < $FF then
|
||||||
|
TextBackground(highlight.BGColor);
|
||||||
|
write(Copy(data, matchPos, offset));
|
||||||
|
NormVideo;
|
||||||
|
lastPos := matchPos + offset;
|
||||||
|
end;
|
||||||
|
|
||||||
|
writeln(Copy(data, lastPos, Length(data)));
|
||||||
|
|
||||||
|
highlights.Free;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure ProcessCall(AURL: String);
|
procedure ProcessCall(AURL: String);
|
||||||
var
|
var
|
||||||
s: String;
|
s: String;
|
||||||
|
@ -199,9 +332,10 @@ begin
|
||||||
begin
|
begin
|
||||||
jsonParser := TJSONParser.Create(response);
|
jsonParser := TJSONParser.Create(response);
|
||||||
jsonData := jsonParser.Parse;
|
jsonData := jsonParser.Parse;
|
||||||
writeln(jsonData.FormatJSON);
|
content.Text := jsonData.FormatJSON;
|
||||||
jsonData.Free;
|
jsonData.Free;
|
||||||
jsonParser.Free;
|
jsonParser.Free;
|
||||||
|
WriteContent;
|
||||||
end;
|
end;
|
||||||
ctXML:
|
ctXML:
|
||||||
begin
|
begin
|
||||||
|
@ -210,13 +344,13 @@ begin
|
||||||
WriteXMLFile(xmlDoc, response);
|
WriteXMLFile(xmlDoc, response);
|
||||||
response.Position := 0;
|
response.Position := 0;
|
||||||
content.LoadFromStream(response);
|
content.LoadFromStream(response);
|
||||||
writeln(content.Text);
|
WriteContent;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end else
|
end else
|
||||||
begin
|
begin
|
||||||
content.LoadFromStream(response);
|
content.LoadFromStream(response);
|
||||||
writeln(content.Text);
|
WriteContent;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
response.Free;
|
response.Free;
|
||||||
|
@ -238,6 +372,12 @@ begin
|
||||||
http.Password := Copy(AData, i + 1, Length(AData));
|
http.Password := Copy(AData, i + 1, Length(AData));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure CmdHighlight(AData: String);
|
||||||
|
begin
|
||||||
|
writeln('Adding expression: ', AData);
|
||||||
|
filters.Add(THighlightFilter.Create(AData));
|
||||||
|
end;
|
||||||
|
|
||||||
function ProcessCommand(ALine: String): Boolean;
|
function ProcessCommand(ALine: String): Boolean;
|
||||||
begin
|
begin
|
||||||
Result := False;
|
Result := False;
|
||||||
|
@ -269,6 +409,11 @@ begin
|
||||||
Result := True;
|
Result := True;
|
||||||
beautify := True;
|
beautify := True;
|
||||||
end else
|
end else
|
||||||
|
if AnsiStartsStr('Highlight ', ALine) then
|
||||||
|
begin
|
||||||
|
Result := True;
|
||||||
|
CmdHighlight(Copy(ALine, 11, Length(ALine)));
|
||||||
|
end else
|
||||||
if AnsiStartsStr('Call ', ALine) then
|
if AnsiStartsStr('Call ', ALine) then
|
||||||
begin
|
begin
|
||||||
Result := True;
|
Result := True;
|
||||||
|
@ -326,6 +471,9 @@ begin
|
||||||
parser := TJTemplateParser.Create;
|
parser := TJTemplateParser.Create;
|
||||||
content := TStringList.Create;
|
content := TStringList.Create;
|
||||||
beautify := False; //By default, we don't want to manipulate output.
|
beautify := False; //By default, we don't want to manipulate output.
|
||||||
|
filters := TFilterList.Create;
|
||||||
|
THighlightFilter.FilterExpression := TRegExpr.Create('( (FG|BG)(\d+))*$');
|
||||||
|
THighlightFilter.ParamExpression := TRegExpr.Create('(FG|BG)(\d+)');
|
||||||
|
|
||||||
{$ifdef use_synapse}
|
{$ifdef use_synapse}
|
||||||
http := THTTPSend.Create;
|
http := THTTPSend.Create;
|
||||||
|
@ -359,6 +507,9 @@ begin
|
||||||
parser.Free;
|
parser.Free;
|
||||||
http.Free;
|
http.Free;
|
||||||
content.Free;
|
content.Free;
|
||||||
|
filters.Free;
|
||||||
|
THighlightFilter.FilterExpression.Free;
|
||||||
|
THighlightFilter.ParamExpression.Free;
|
||||||
|
|
||||||
CloseFile(data);
|
CloseFile(data);
|
||||||
end;
|
end;
|
||||||
|
|
Loading…
Reference in New Issue