fpcssutils.pp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. {
  2. This file is part of the Free Pascal Run time library.
  3. Copyright (c) 2022 by Michael Van Canneyt ([email protected])
  4. This file contains CSS utility class
  5. See the File COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. {$IFNDEF FPC_DOTTEDUNITS}
  12. unit fpcssutils;
  13. {$ENDIF FPC_DOTTEDUNITS}
  14. {$mode objfpc}{$H+}
  15. interface
  16. {$IFDEF FPC_DOTTEDUNITS}
  17. uses
  18. System.TypInfo, System.Classes, System.SysUtils, System.Types, FPCSS.Tree, FPCSS.Parser, FPCSS.Scanner;
  19. {$ELSE FPC_DOTTEDUNITS}
  20. uses
  21. TypInfo, Classes, SysUtils, types, fpcsstree, fpcssparser, fpcssscanner;
  22. {$ENDIF FPC_DOTTEDUNITS}
  23. Type
  24. { TClassNameVisitor }
  25. TClassNameVisitor = Class(TCSSTreeVisitor)
  26. private
  27. FList: TStrings;
  28. public
  29. Constructor Create(aList: TStrings);
  30. Procedure Visit(obj: TCSSElement); override;
  31. property List : TStrings Read FList;
  32. end;
  33. { TCSSUtils }
  34. TCSSUtils = class(TComponent)
  35. private
  36. FExtraScannerOptions: TCSSScannerOptions;
  37. published
  38. Procedure ExtractClassNames(Const aFileName : String; aList : TStrings);
  39. Procedure ExtractClassNames(Const aStream : TStream; aList : TStrings);
  40. Procedure ExtractClassNames(Const aElement : TCSSElement; aList : TStrings);
  41. Function ExtractClassNames(Const aFileName : String) : TStringDynArray;
  42. Function ExtractClassNames(Const aStream : TStream) : TStringDynArray;
  43. Function ExtractClassNames(Const aElement : TCSSElement) : TStringDynArray;
  44. Procedure Minimize(aInput,aOutput : TStream);
  45. Property ExtraScannerOptions : TCSSScannerOptions Read FExtraScannerOptions Write FExtraScannerOptions;
  46. end;
  47. implementation
  48. { TClassNameVisitor }
  49. constructor TClassNameVisitor.Create(aList: TStrings);
  50. begin
  51. FList:=aList;
  52. end;
  53. procedure TClassNameVisitor.Visit(obj: TCSSElement);
  54. begin
  55. if Obj.CSSType=csstCLASSNAME then
  56. FList.Add(Obj.AsString);
  57. end;
  58. { TCSSUtils }
  59. procedure TCSSUtils.ExtractClassNames(const aFileName: String; aList: TStrings);
  60. Var
  61. S : TStringStream;
  62. begin
  63. S:=TStringStream.Create;
  64. try
  65. S.LoadFromFile(aFileName);
  66. ExtractClassNames(S,aList);
  67. finally
  68. S.Free;
  69. end;
  70. end;
  71. function TCSSUtils.ExtractClassNames(const aFileName: String): TStringDynArray;
  72. Var
  73. L : TStrings;
  74. begin
  75. L:=TStringList.Create;
  76. try
  77. ExtractClassNames(aFileName,L);
  78. Result:=L.ToStringArray;
  79. finally
  80. L.Free;
  81. end;
  82. end;
  83. procedure TCSSUtils.ExtractClassNames(const aStream: TStream; aList: TStrings);
  84. Var
  85. aParser : TCSSParser;
  86. aElement : TCSSElement;
  87. begin
  88. aElement:=Nil;
  89. aParser:=TCSSParser.Create(aStream,ExtraScannerOptions);
  90. try
  91. aElement:=aParser.Parse;
  92. ExtractClassNames(aElement,aList);
  93. finally
  94. aElement.Free;
  95. aParser.Free;
  96. end;
  97. end;
  98. procedure TCSSUtils.ExtractClassNames(const aElement: TCSSElement; aList: TStrings);
  99. Var
  100. aVis : TClassNameVisitor;
  101. begin
  102. aVis:=TClassNameVisitor.Create(aList);
  103. try
  104. aElement.Iterate(aVis);
  105. finally
  106. aVis.Free;
  107. end;
  108. end;
  109. function TCSSUtils.ExtractClassNames(const aStream: TStream): TStringDynArray;
  110. Var
  111. L : TStrings;
  112. begin
  113. L:=TStringList.Create;
  114. try
  115. ExtractClassNames(aStream,L);
  116. Result:=L.ToStringArray;
  117. finally
  118. L.Free;
  119. end;
  120. end;
  121. function TCSSUtils.ExtractClassNames(const aElement: TCSSElement): TStringDynArray;
  122. Var
  123. L : TStrings;
  124. begin
  125. L:=TStringList.Create;
  126. try
  127. ExtractClassNames(aElement,L);
  128. Result:=L.ToStringArray;
  129. finally
  130. L.Free;
  131. end;
  132. end;
  133. procedure TCSSUtils.Minimize(aInput, aOutput: TStream);
  134. Var
  135. aScanner : TCSSScanner;
  136. aToken,aPreviousToken : TCSSToken;
  137. S : UTF8String;
  138. begin
  139. aPrevioustoken:=ctkWHITESPACE;
  140. AScanner:=TCSSScanner.Create(aInput);
  141. try
  142. aScanner.ReturnWhiteSpace:=True;
  143. aToken:=aScanner.FetchToken;
  144. While (aToken<>ctkEOF) do
  145. begin
  146. if aToken=ctkSTRING then
  147. S:=StringToCSSString(aScanner.CurTokenString)
  148. else if aToken<>ctkWHITESPACE then
  149. S:=aScanner.CurTokenString
  150. else if aPreviousToken<>ctkWHITESPACE then
  151. S:=' '
  152. else
  153. S:='';
  154. // writeln(GetEnumName(TypeInfo(TCSSTOKEN),Ord(aToken)),' -> S : >',S,'<');
  155. if S<>'' then
  156. aOutput.WriteBuffer(S[1],length(S));
  157. aPreviousToken:=aToken;
  158. aToken:=aScanner.FetchToken;
  159. end;
  160. finally
  161. aScanner.Free;
  162. end;
  163. end;
  164. end.