-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathCodeExtractor.pas
96 lines (82 loc) · 2.14 KB
/
CodeExtractor.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
unit CodeExtractor;
interface
uses
System.SysUtils,
System.Classes,
System.RegularExpressions,
System.Generics.Collections;
type
TCodeBlock = record
Language: string;
Code: string;
FileName: string;
end;
TCodeExtractor = class
private
FOutput: string;
FCodeBlocks: TArray<TCodeBlock>;
function ExtractFileName(const ACode: string): string;
procedure ExtractCodeBlocks;
public
constructor Create(const AOutput: string);
function CodeBlockCount: Integer;
property CodeBlocks: TArray<TCodeBlock> read FCodeBlocks;
end;
implementation
{ TCodeExtractor }
constructor TCodeExtractor.Create(const AOutput: string);
begin
FOutput := AOutput;
ExtractCodeBlocks;
end;
function TCodeExtractor.ExtractFileName(const ACode: string): string;
var
FirstLine: string;
begin
Result := '';
FirstLine := Trim(ACode);
if FirstLine.StartsWith('program', True) then
Result := Copy(FirstLine, Pos(' ', FirstLine) + 1, Length(FirstLine)) + '.dpr'
else if FirstLine.StartsWith('unit', True) then
Result := Copy(FirstLine, Pos(' ', FirstLine) + 1, Length(FirstLine)) + '.pas';
end;
procedure TCodeExtractor.ExtractCodeBlocks;
var
Regex: TRegEx;
Matches: TMatchCollection;
Match: TMatch;
CodeBlock: TCodeBlock;
CodeList: TList<TCodeBlock>;
CodeLines: TStringList;
begin
CodeList := TList<TCodeBlock>.Create;
try
Regex := TRegEx.Create('```(\w+)?\s*([\s\S]*?)```', [roMultiLine]);
Matches := Regex.Matches(FOutput);
for Match in Matches do
begin
CodeBlock.Language := Match.Groups[1].Value;
CodeBlock.Code := Match.Groups[2].Value;
if SameText(CodeBlock.Language, 'delphi') then
begin
CodeLines := TStringList.Create;
try
CodeLines.Text := CodeBlock.Code;
if CodeLines.Count > 0 then
CodeBlock.FileName := ExtractFileName(CodeLines[0]);
finally
CodeLines.Free;
end;
end;
CodeList.Add(CodeBlock);
end;
FCodeBlocks := CodeList.ToArray;
finally
CodeList.Free;
end;
end;
function TCodeExtractor.CodeBlockCount: Integer;
begin
Result := Length(FCodeBlocks);
end;
end.