fpcssutils.pp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  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. unit fpcssutils;
  12. {$mode objfpc}{$H+}
  13. interface
  14. uses
  15. TypInfo, Classes, SysUtils, types, fpcsstree, fpcssparser, fpcssscanner;
  16. Type
  17. { TClassNameVisitor }
  18. TClassNameVisitor = Class(TCSSTreeVisitor)
  19. private
  20. FList: TStrings;
  21. public
  22. Constructor Create(aList: TStrings);
  23. Procedure Visit(obj: TCSSElement); override;
  24. property List : TStrings Read FList;
  25. end;
  26. { TCSSUtils }
  27. TCSSUtils = class(TComponent)
  28. private
  29. FExtraScannerOptions: TCSSScannerOptions;
  30. published
  31. Procedure ExtractClassNames(Const aFileName : String; aList : TStrings);
  32. Procedure ExtractClassNames(Const aStream : TStream; aList : TStrings);
  33. Procedure ExtractClassNames(Const aElement : TCSSElement; aList : TStrings);
  34. Function ExtractClassNames(Const aFileName : String) : TStringDynArray;
  35. Function ExtractClassNames(Const aStream : TStream) : TStringDynArray;
  36. Function ExtractClassNames(Const aElement : TCSSElement) : TStringDynArray;
  37. Procedure Minimize(aInput,aOutput : TStream);
  38. Property ExtraScannerOptions : TCSSScannerOptions Read FExtraScannerOptions Write FExtraScannerOptions;
  39. end;
  40. implementation
  41. { TClassNameVisitor }
  42. constructor TClassNameVisitor.Create(aList: TStrings);
  43. begin
  44. FList:=aList;
  45. end;
  46. procedure TClassNameVisitor.Visit(obj: TCSSElement);
  47. begin
  48. if Obj.CSSType=csstCLASSNAME then
  49. FList.Add(Obj.AsString);
  50. end;
  51. { TCSSUtils }
  52. procedure TCSSUtils.ExtractClassNames(const aFileName: String; aList: TStrings);
  53. Var
  54. S : TStringStream;
  55. begin
  56. S:=TStringStream.Create;
  57. try
  58. S.LoadFromFile(aFileName);
  59. ExtractClassNames(S,aList);
  60. finally
  61. S.Free;
  62. end;
  63. end;
  64. function TCSSUtils.ExtractClassNames(const aFileName: String): TStringDynArray;
  65. Var
  66. L : TStrings;
  67. begin
  68. L:=TStringList.Create;
  69. try
  70. ExtractClassNames(aFileName,L);
  71. Result:=L.ToStringArray;
  72. finally
  73. L.Free;
  74. end;
  75. end;
  76. procedure TCSSUtils.ExtractClassNames(const aStream: TStream; aList: TStrings);
  77. Var
  78. aParser : TCSSParser;
  79. aElement : TCSSElement;
  80. begin
  81. aElement:=Nil;
  82. aParser:=TCSSParser.Create(aStream,ExtraScannerOptions);
  83. try
  84. aElement:=aParser.Parse;
  85. ExtractClassNames(aElement,aList);
  86. finally
  87. aElement.Free;
  88. aParser.Free;
  89. end;
  90. end;
  91. procedure TCSSUtils.ExtractClassNames(const aElement: TCSSElement; aList: TStrings);
  92. Var
  93. aVis : TClassNameVisitor;
  94. begin
  95. aVis:=TClassNameVisitor.Create(aList);
  96. try
  97. aElement.Iterate(aVis);
  98. finally
  99. aVis.Free;
  100. end;
  101. end;
  102. function TCSSUtils.ExtractClassNames(const aStream: TStream): TStringDynArray;
  103. Var
  104. L : TStrings;
  105. begin
  106. L:=TStringList.Create;
  107. try
  108. ExtractClassNames(aStream,L);
  109. Result:=L.ToStringArray;
  110. finally
  111. L.Free;
  112. end;
  113. end;
  114. function TCSSUtils.ExtractClassNames(const aElement: TCSSElement): TStringDynArray;
  115. Var
  116. L : TStrings;
  117. begin
  118. L:=TStringList.Create;
  119. try
  120. ExtractClassNames(aElement,L);
  121. Result:=L.ToStringArray;
  122. finally
  123. L.Free;
  124. end;
  125. end;
  126. procedure TCSSUtils.Minimize(aInput, aOutput: TStream);
  127. Var
  128. aScanner : TCSSScanner;
  129. aToken,aPreviousToken : TCSSToken;
  130. S : UTF8String;
  131. begin
  132. aPrevioustoken:=ctkWHITESPACE;
  133. AScanner:=TCSSScanner.Create(aInput);
  134. try
  135. aScanner.ReturnWhiteSpace:=True;
  136. aToken:=aScanner.FetchToken;
  137. While (aToken<>ctkEOF) do
  138. begin
  139. if aToken=ctkSTRING then
  140. S:=StringToCSSString(aScanner.CurTokenString)
  141. else if aToken<>ctkWHITESPACE then
  142. S:=aScanner.CurTokenString
  143. else if aPreviousToken<>ctkWHITESPACE then
  144. S:=' '
  145. else
  146. S:='';
  147. // writeln(GetEnumName(TypeInfo(TCSSTOKEN),Ord(aToken)),' -> S : >',S,'<');
  148. if S<>'' then
  149. aOutput.WriteBuffer(S[1],length(S));
  150. aPreviousToken:=aToken;
  151. aToken:=aScanner.FetchToken;
  152. end;
  153. finally
  154. aScanner.Free;
  155. end;
  156. end;
  157. end.