mkfpdoc.pp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. unit mkfpdoc;
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5. Classes, SysUtils, dglobals, fpdocxmlopts, dwriter, pscanner, pparser, fpdocproj;
  6. const
  7. DefOSTarget = {$I %FPCTARGETOS%};
  8. DefCPUTarget = {$I %FPCTARGETCPU%};
  9. DefFPCVersion = {$I %FPCVERSION%};
  10. DefFPCDate = {$I %FPCDATE%};
  11. Type
  12. { TFPDocCreator }
  13. TFPDocCreator = Class(TComponent)
  14. Private
  15. FCurPackage : TFPDocPackage;
  16. FProcessedUnits : TStrings;
  17. FOnLog: TPasParserLogHandler;
  18. FPParserLogEvents: TPParserLogEvents;
  19. FProject : TFPDocProject;
  20. FScannerLogEvents: TPScannerLogEvents;
  21. FVerbose: Boolean;
  22. function GetOptions: TEngineOptions;
  23. function GetPackages: TFPDocPackages;
  24. Protected
  25. procedure HandleOnParseUnit(Sender: TObject; const AUnitName: String; out AInputFile, OSTarget, CPUTarget: String);
  26. procedure SetVerbose(AValue: Boolean); virtual;
  27. Procedure DoLog(Const Msg : String);
  28. procedure DoLog(Const Fmt : String; Args : Array of Const);
  29. procedure CreateOutput(APackage: TFPDocPackage; Engine: TFPDocEngine); virtual;
  30. Public
  31. Constructor Create(AOwner : TComponent); override;
  32. Destructor Destroy; override;
  33. Procedure CreateDocumentation(APackage : TFPDocPackage; ParseOnly : Boolean); virtual;
  34. Procedure CreateProjectFile(Const AFileName : string);
  35. Procedure LoadProjectFile(Const AFileName: string);
  36. Property Project : TFPDocProject Read FProject;
  37. Property ScannerLogEvents : TPScannerLogEvents Read FScannerLogEvents Write FScannerLogEvents;
  38. Property ParserLogEvents : TPParserLogEvents Read FPParserLogEvents Write FPParserLogEvents;
  39. Property Verbose : Boolean Read FVerbose Write SetVerbose;
  40. Property OnLog : TPasParserLogHandler Read FOnLog Write FOnLog;
  41. // Easy access
  42. Property Options : TEngineOptions Read GetOptions;
  43. Property Packages : TFPDocPackages Read GetPackages;
  44. end;
  45. implementation
  46. { TFPDocCreator }
  47. procedure TFPDocCreator.SetVerbose(AValue: Boolean);
  48. begin
  49. if FVerbose=AValue then Exit;
  50. FVerbose:=AValue;
  51. if FVerbose then
  52. begin
  53. ScannerLogEvents:=[sleFile];
  54. ParserLogEvents:=[];
  55. end
  56. else
  57. begin
  58. ScannerLogEvents:=[];
  59. ParserLogEvents:=[];
  60. end;
  61. end;
  62. procedure TFPDocCreator.DoLog(const Msg: String);
  63. begin
  64. If Assigned(OnLog) then
  65. OnLog(Self,Msg);
  66. end;
  67. procedure TFPDocCreator.DoLog(const Fmt: String; Args: array of const);
  68. begin
  69. DoLog(Format(Fmt,Args));
  70. end;
  71. procedure TFPDocCreator.HandleOnParseUnit(Sender: TObject;
  72. const AUnitName: String; out AInputFile, OSTarget, CPUTarget: String);
  73. Var
  74. I : Integer;
  75. S,un,opts : String;
  76. begin
  77. AInputFile:='';
  78. OSTarget:='';
  79. CPUTarget:='';
  80. if Assigned(FCurPackage) then
  81. begin
  82. I:=0;
  83. While (AInputFIle='') and (I<FCurPackage.Inputs.Count) do
  84. begin
  85. S:=FCurPackage.Inputs[i];
  86. SplitInputFIleOption(S,UN,Opts);
  87. if CompareText(ChangeFileExt(ExtractFileName(Un),''),AUnitName)=0 then
  88. begin
  89. AInputFile:=S;
  90. OSTarget:=FProject.Options.OSTarget;
  91. CPUTarget:=FProject.Options.CPUTarget;
  92. FProcessedUnits.Add(UN);
  93. end;
  94. Inc(I);
  95. end;
  96. end;
  97. end;
  98. function TFPDocCreator.GetOptions: TEngineOptions;
  99. begin
  100. Result:=FProject.Options;
  101. end;
  102. function TFPDocCreator.GetPackages: TFPDocPackages;
  103. begin
  104. Result:=FProject.Packages;
  105. end;
  106. constructor TFPDocCreator.Create(AOwner: TComponent);
  107. begin
  108. inherited Create(AOwner);
  109. FProject:=TFPDocProject.Create(Self);
  110. FProject.Options.StopOnParseError:=False;
  111. FProject.Options.CPUTarget:=DefCPUTarget;
  112. FProject.Options.OSTarget:=DefOSTarget;
  113. FProcessedUnits:=TStringList.Create;
  114. end;
  115. destructor TFPDocCreator.Destroy;
  116. begin
  117. FreeAndNil(FProcessedUnits);
  118. FreeAndNil(FProject);
  119. inherited Destroy;
  120. end;
  121. procedure TFPDocCreator.CreateOutput(APackage: TFPDocPackage;Engine : TFPDocEngine);
  122. Var
  123. WriterClass : TFPDocWriterClass;
  124. Writer : TFPDocWriter;
  125. I : Integer;
  126. Cmd,Arg : String;
  127. begin
  128. WriterClass:=GetWriterClass(Options.Backend);
  129. Writer:=WriterClass.Create(Engine.Package,Engine);
  130. With Writer do
  131. Try
  132. If FVerbose then
  133. DoLog('Writing documentation');
  134. OnLog:=Self.OnLog;
  135. EmitNotes:=Options.EmitNotes;
  136. If Options.BackendOptions.Count>0 then
  137. for I:=0 to ((Options.BackendOptions.Count-1) div 2) do
  138. begin
  139. Cmd:=Options.BackendOptions[I*2];
  140. Arg:=Options.BackendOptions[I*2+1];
  141. If not InterPretOption(Cmd,Arg) then
  142. DoLog(SCmdLineInvalidOption,[Cmd+'='+Arg]);
  143. end;
  144. WriteDoc;
  145. Finally
  146. Free;
  147. end;
  148. if Length(APackage.ContentFile) > 0 then
  149. Engine.WriteContentFile(APackage.ContentFile);
  150. end;
  151. procedure TFPDocCreator.CreateDocumentation(APackage: TFPDocPackage; ParseOnly : Boolean);
  152. var
  153. i,j: Integer;
  154. Engine : TFPDocEngine;
  155. Cmd,Arg : String;
  156. begin
  157. FCurPackage:=APackage;
  158. Engine:=TFPDocEngine.Create;
  159. try
  160. For J:=0 to Apackage.Imports.Count-1 do
  161. begin
  162. Arg:=Apackage.Imports[j];
  163. i := Pos(',', Arg);
  164. Engine.ReadContentFile(Copy(Arg,1,i-1),Copy(Arg,i+1,Length(Arg)));
  165. end;
  166. for i := 0 to APackage.Descriptions.Count - 1 do
  167. Engine.AddDocFile(APackage.Descriptions[i],Options.donttrim);
  168. Engine.SetPackageName(APackage.Name);
  169. Engine.Output:=APackage.Output;
  170. Engine.OnLog:=Self.OnLog;
  171. Engine.ScannerLogEvents:=Self.ScannerLogEvents;
  172. Engine.ParserLogEvents:=Self.ParserLogEvents;
  173. Engine.HideProtected:=Options.HideProtected;
  174. Engine.HidePrivate:=Not Options.ShowPrivate;
  175. Engine.OnParseUnit:=@HandleOnParseUnit;
  176. if Length(Options.Language) > 0 then
  177. TranslateDocStrings(Options.Language);
  178. for i := 0 to APackage.Inputs.Count - 1 do
  179. try
  180. SplitInputFileOption(APackage.Inputs[i],Cmd,Arg);
  181. if FProcessedUnits.IndexOf(Cmd)=-1 then
  182. begin
  183. FProcessedUnits.Add(Cmd);
  184. ParseSource(Engine, APackage.Inputs[i], Options.OSTarget, Options.CPUTarget);
  185. end;
  186. except
  187. on e: EParserError do
  188. If Options.StopOnParseError then
  189. Raise
  190. else
  191. DoLog('%s(%d,%d): %s',[e.Filename, e.Row, e.Column, e.Message]);
  192. end;
  193. if Not ParseOnly then
  194. CreateOutput(APackage,Engine);
  195. finally
  196. FreeAndNil(Engine);
  197. FCurPackage:=Nil;
  198. end;
  199. end;
  200. procedure TFPDocCreator.CreateProjectFile(Const AFileName: string);
  201. begin
  202. With TXMLFPDocOptions.Create(Self) do
  203. try
  204. SaveOptionsToFile(FProject,AFileName);
  205. finally
  206. Free;
  207. end;
  208. end;
  209. procedure TFPDocCreator.LoadProjectFile(const AFileName: string);
  210. begin
  211. With TXMLFPDocOptions.Create(self) do
  212. try
  213. LoadOptionsFromFile(FProject,AFileName);
  214. finally
  215. Free;
  216. end;
  217. end;
  218. end.