瀏覽代碼

[template] add new unit for string template replacing

Exilon 5 年之前
父節點
當前提交
08b8c436b2
共有 1 個文件被更改,包括 132 次插入0 次删除
  1. 132 0
      Quick.Template.pas

+ 132 - 0
Quick.Template.pas

@@ -0,0 +1,132 @@
+{ ***************************************************************************
+
+  Copyright (c) 2016-2020 Kike Pérez
+
+  Unit        : Quick.Template
+  Description : String Replace Templates
+  Author      : Kike Pérez
+  Version     : 2.0
+  Created     : 01/04/2020
+  Modified    : 28/06/2020
+
+  This file is part of QuickLib: https://github.com/exilon/QuickLib
+
+ ***************************************************************************
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+ *************************************************************************** }
+ 
+unit Quick.Template;
+
+{$i QuickLib.inc}
+
+interface
+
+uses
+  System.SysUtils,
+  System.Generics.Collections,
+  Quick.Commons;
+
+type
+  TTokenFunc = function(const aToken : string) : string of object;
+  
+  TStringTemplate = class
+  private
+    fVariables : TDictionary<string,string>;
+    fReplaceFunc : TTokenFunc;
+    fQuoteBegin : string;
+    fQuoteEnd : string;
+    fBeginOffSet : Integer;
+    fEndOffSet : Integer;
+  protected
+    constructor Create; overload;
+  public
+    constructor Create(const aQuoteBegin, aQuoteEnd : string; aVariables : TDictionary<string,string>); overload;
+    constructor Create(const aQuoteBegin, aQuoteEnd : string; aReplaceFunc : TTokenFunc); overload;
+    function Replace(const aTemplate : string) : string; virtual;
+  end;
+
+  EStringTemplateError = class(Exception);
+
+implementation
+
+{ TStringTemplate }
+
+constructor TStringTemplate.Create;
+begin
+  
+end;
+
+constructor TStringTemplate.Create(const aQuoteBegin, aQuoteEnd: string; aVariables: TDictionary<string, string>);
+begin
+  inherited Create;
+  if aQuoteBegin.IsEmpty or aQuoteEnd.IsEmpty then raise EStringTemplateError.Create('QuoteBegin and QuoteEnd cannot be null!');
+  if aVariables = nil then raise EStringTemplateError.Create('Dictionary cannot be null!');
+  fQuoteBegin := aQuoteBegin;
+  fQuoteEnd := aQuoteEnd;
+  fBeginOffSet := aQuoteBegin.Length;
+  fEndOffSet := aQuoteEnd.Length;
+  fVariables := aVariables;
+end;
+
+constructor TStringTemplate.Create(const aQuoteBegin, aQuoteEnd: string; aReplaceFunc: TTokenFunc);
+begin
+  inherited Create;
+  if aQuoteBegin.IsEmpty or aQuoteEnd.IsEmpty then raise EStringTemplateError.Create('QuoteBegin and QuoteEnd cannot be null!');
+  if not Assigned(aReplaceFunc) then raise EStringTemplateError.Create('ReplaceFunc cannot be null!');
+  fQuoteBegin := aQuoteBegin;
+  fQuoteEnd := aQuoteEnd;
+  fBeginOffSet := aQuoteBegin.Length;
+  fEndOffSet := aQuoteEnd.Length;
+  fReplaceFunc := aReplaceFunc;
+end;
+
+function TStringTemplate.Replace(const aTemplate : string) : string;
+var
+  idx : Integer;
+  st : Integer;
+  et : Integer;
+  token : string;
+  tokrep : string;
+begin
+  //resolve template
+  Result := '';
+  idx := 1;
+  repeat
+    st := aTemplate.IndexOf(fQuoteBegin,st) + 1;
+    if st > 0 then
+    begin
+      et := aTemplate.IndexOf(fQuoteEnd,st) + 1;
+      if et = 0 then Break;
+      Result := Result + Copy(aTemplate,idx,st-idx);
+      token := Copy(aTemplate,st + fBeginOffSet,et-st-fBeginOffSet);
+      //replace token
+      tokrep := '';
+      if fVariables <> nil then
+      begin
+        fVariables.TryGetValue(token,tokrep)
+      end
+      else
+      begin
+        tokrep := fReplaceFunc(token);
+      end;
+      if tokrep.IsEmpty then tokrep := fQuoteBegin + token + '?' + fQuoteEnd;
+      Result := Result + tokrep;
+      idx := et + fEndOffSet;      
+    end;
+  until st = 0;
+  Result := Result + Copy(aTemplate,idx,aTemplate.Length);
+end;
+
+end.