📄 skymanager.pas
字号:
{*******************************************************************************
* TSkyManager -- 管理多个TSkyParser的支持类 *
* *
* 功能:管理多个TSkyParser,由文件扩展名得到相应的SkyParser来支持对应的 *
* SkyEdit,从而实现多种语言的支持 *
* 版本:0.98 beta *
* 作者:顾中军 *
* 实现: *
* 直到2004年11月中下旬,为实现Demo中那个编辑器的多语言,才着手编写了 *
* TSkyManager类,其实它就是通过一个简单规则的语法定义源文件来解析出相应 *
* 语言的语法定义,并创建相应的TSkyParser类供SkyEdit使用。 *
* *
* 说明: *
* TSkyManager实现了SkyEdit多语言的自动管理,它的思想来源于UltraEdit, *
* 实际上它并不是SkyEdit所必须的,它只是为了实现编辑器而做的一个简单扩展; *
* 其实,你完全可以使用其他方法来完成TSkyManager所实现的功能,只不过 *
* 我觉得它的实现虽然简单,但的确做到了多语言的支持,而且很容易通过编辑它 *
* 的语法定义文件来实现编辑器的自动扩展,你认为呢? *
* *
* 版权声明: *
* SkyEdit源码公开,你可以在它的基础上进行任何改进,并且你可以将它用 *
* 于任何场合; *
* 如果你有更好的改进,别忘了给我发一份啊; *
* 此外,如果你是在它的基础上改进,请保留我写的文本及说明,毕竟我花 *
* 了不少精力和时间,请尊重我的劳动成果;另外我希望你能将改进的代码公布 *
* 出来,多交流才能更快地进步嘛; *
* 因为SkyEdit的编写过程中,我从mwCustomEdit 0.62 版的源码中学到了不 *
* 少东西,在此向它的作者们表示最衷心的感谢(以下TCustomSkyEdit的实现处 *
* 有进一步的说明);当然,由于Borland提供了几乎所有的VCL源码,使得我从 *
* 中学到了很多,故而在此对Borland及为Borland作出贡献的人们表示最诚挚的 *
* 祝福,祝Borland开发工具之树常青; *
* *
* *
* 虽然SkyEdit与一些更专业的编辑控件相比显得苗条了些,不过它还是实现 *
* 一个编辑器所应有的基本功能;因此作者在这里希望它能给想要学习和正在学 *
* 习编写控件的朋友一点帮助。 *
* 最后,愿与所有喜爱软件开发的朋友们共勉:让世界因软件而变得更美好! *
* *
* 网站:不好意思,还没建立自己的网站呢 *
* 妹儿:iamdream@citiz.net *
*******************************************************************************}
unit SkyManager;
interface
uses
Windows, Classes, SysUtils, SkyEdit, SkyParser, Graphics;
type
TSkyManager = Class
private
FDelimiterChar: Char;
FParserList: TList;
FOwner: TComponent;
procedure FreeSkyParserOfList;
function GetParserCount: Integer;
function GetParserItem(index: Integer): TSkyParser;
protected
procedure ParserSyntax(slParser: TStrings);
procedure SetSkyParserDefaultAttr(sprTarget: TSkyParser);
public
constructor Create(AOwner: TComponent); overload;
constructor Create(AOwner: TComponent; const sFileName: String); overload;
destructor Destroy; override;
procedure LoadParserFile(const sFileName: String);
function GetParserByFileExt(const sFileExt: String): TSkyParser; overload;
function GetParserByFileExt(const sFileExt: String;
var iParserIdx: Integer): TSkyParser; overload;
property DelimiterChar: Char read FDelimiterChar write FDelimiterChar;
property ParserCount: Integer read GetParserCount;
property ParserList[index: Integer]: TSkyParser read GetParserItem;
end;
implementation
constructor TSkyManager.Create(AOwner: TComponent);
begin
inherited Create;
FParserList := TList.Create;
FOwner := AOwner;
FDelimiterChar := ' '; //默认为空格
end;
constructor TSkyManager.Create(AOwner: TComponent; const sFileName: String);
begin
Create(AOwner);
LoadParserFile(sFileName);
end;
destructor TSkyManager.Destroy;
begin
FreeSkyParserOfList();
FParserList.Free;
inherited Destroy;
end;
procedure TSkyManager.FreeSkyParserOfList;
var //释放列表中的所有 SkyParser 语法解析器
i: Integer;
begin
for i := 0 to FParserList.Count - 1 do
TSkyParser(FParserList.Items[i]).Free;
FParserList.Clear;
end;
function TSkyManager.GetParserCount: Integer;
begin //取当前语法解析器个数
Result := FParserList.Count;
end;
function TSkyManager.GetParserItem(index: Integer): TSkyParser;
begin //取语法解析器,注意:这里未检测是否越界!!! 2004.11.14
Result := TSkyParser(FParserList.Items[index]);
end;
procedure TSkyManager.SetSkyParserDefaultAttr(sprTarget: TSkyParser);
begin //设置 SkyParser 之默认属性(主要是显示属性)
sprTarget.CharAttr.BkgColor := clNavy;
sprTarget.CharAttr.FrgColor := clAqua;
sprTarget.CharAttr.Style := [fsItalic];
sprTarget.CommentsAttr.BkgColor := clNavy;
sprTarget.CommentsAttr.FrgColor := clSilver;
sprTarget.CommentsAttr.Style := [fsItalic];
sprTarget.DelimitersAttr.BkgColor := clNavy;
sprTarget.DelimitersAttr.FrgColor := clRed;
sprTarget.Int_1_Attr.BkgColor := clNavy;
sprTarget.Int_1_Attr.FrgColor := clFuchsia;
sprTarget.Int_2_Attr.BkgColor := clNavy;
sprTarget.Int_2_Attr.FrgColor := clAqua;
sprTarget.Int_3_Attr.BkgColor := clNavy;
sprTarget.Int_3_Attr.FrgColor := clAqua;
sprTarget.Int_4_Attr.BkgColor := clNavy;
sprTarget.Int_4_Attr.FrgColor := clAqua;
sprTarget.MacrosAttr.BkgColor := clNavy;
sprTarget.MacrosAttr.FrgColor := clLime;
sprTarget.NormalTextAttr.BkgColor := clNavy;
sprTarget.NormalTextAttr.FrgColor := clYellow;
sprTarget.StringsAttr.BkgColor := clNavy;
sprTarget.StringsAttr.FrgColor := clFuchsia;
sprTarget.Words_1_Attr.BkgColor := clNavy;
sprTarget.Words_1_Attr.FrgColor := clBtnHighlight;
sprTarget.Words_1_Attr.Style := [fsBold];
sprTarget.Words_2_Attr.BkgColor := clNavy;
sprTarget.Words_2_Attr.FrgColor := clSkyBlue;
sprTarget.Words_3_Attr.BkgColor := clNavy;
sprTarget.Words_3_Attr.FrgColor := TColor($00FFB3B3);
sprTarget.Words_4_Attr.BkgColor := clNavy;
sprTarget.Words_4_Attr.FrgColor := clCream;
sprTarget.Words_5_Attr.BkgColor := clNavy;
sprTarget.Words_5_Attr.FrgColor := clLime;
sprTarget.Words_6_Attr.BkgColor := clNavy;
sprTarget.Words_6_Attr.FrgColor := clRed;
sprTarget.Words_7_Attr.BkgColor := clNavy;
sprTarget.Words_7_Attr.FrgColor := clFuchsia;
sprTarget.Words_8_Attr.BkgColor := clNavy;
sprTarget.Words_8_Attr.FrgColor := clAqua;
end;
procedure TSkyManager.ParserSyntax(slParser: TStrings);
var //分析语法文件并生成相应 SkyParser 语法解析器
i, iPos, iLen{, k}: Integer;
iParserIdx: Integer;//当前 SkyParser 索引
slTemp: TStrings;
sprTemp: TSkyParser;
sTmpStr: String;
iWordsIdx: Integer; //当前正在分析的单词组序号
function GetIndicator(const sTmpStr: String): Char;
begin //取指示符
if (sTmpStr = '') or (sTmpStr = '#0') then
Result := #0
else
Result := sTmpStr[1];
end;
procedure AppendWords(iWordsIdx: Integer; const sWordsText: String);
var //将单词组添加到相应的单词列表中
k: Integer;
begin
slTemp.DelimitedText := sWordsText;
for k:=0 to slTemp.Count - 1 do
begin
with TSkyParser(FParserList.Items[iParserIdx]) do
begin
case iWordsIdx of
1: Words_1.Append(slTemp[k]);
2: Words_2.Append(slTemp[k]);
3: Words_3.Append(slTemp[k]);
4: Words_4.Append(slTemp[k]);
5: Words_5.Append(slTemp[k]);
6: Words_6.Append(slTemp[k]);
7: Words_7.Append(slTemp[k]);
8: Words_8.Append(slTemp[k]);
end;
end;
end;
end;
procedure SetWordsName(iWordsIdx: Integer; const sName: String);
begin //设置单词之名称
with TSkyParser(FParserList.Items[iParserIdx]) do
begin
case iWordsIdx of
1: Words_1_Attr.Name := sName;
2: Words_2_Attr.Name := sName;
3: Words_3_Attr.Name := sName;
4: Words_4_Attr.Name := sName;
5: Words_5_Attr.Name := sName;
6: Words_6_Attr.Name := sName;
7: Words_7_Attr.Name := sName;
8: Words_8_Attr.Name := sName;
end;
end;
end;
begin
iParserIdx := -1;
iWordsIdx := 0; //初始化单词序号为0(即什么都不是)
slTemp := TStringList.Create;
slTemp.Delimiter := FDelimiterChar;
try
for i:=0 to slParser.Count - 1 do
begin
if Pos('/Language', slParser[i]) = 1 then
begin //遇到一种新语言
iPos := Pos('=', slParser[i]);
if iPos > 9 then
begin
sprTemp := TSkyParser.Create(FOwner);
sprTemp.LanguageName := Copy(slParser[i],
iPos + 1,
Length(slParser[i]) - iPos);
SetSkyParserDefaultAttr(sprTemp);
FParserList.Add(Pointer(sprTemp));
Inc(iParserIdx);
end;
end
else if Pos('/LineComments=', slParser[i]) = 1 then
begin //单行注释符
if FParserList.Count > 0 then
begin
sTmpStr := Copy(slParser[i], 15, Length(slParser[i]) - (15 - 1));
TSkyParser(FParserList.Items[iParserIdx]).LineComments.Text :=
StringReplace(sTmpStr, FDelimiterChar, #13#10, [rfReplaceAll]);
end;
end
else if Pos('/BlockCommentOns=', slParser[i]) = 1 then
begin //多行注释开始符
if FParserList.Count > 0 then
begin
sTmpStr := Copy(slParser[i], 18, Length(slParser[i]) - (18 - 1));
TSkyParser(FParserList.Items[iParserIdx]).BlockCommentOns.Text :=
StringReplace(sTmpStr, FDelimiterChar, #13#10, [rfReplaceAll]);
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -