mkfpdoc.pp 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. unit mkfpdoc;
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5. Classes, SysUtils, dglobals, DOM, 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. FBaseDescrDir: String;
  16. FBaseInputDir: String;
  17. FCurPackage : TFPDocPackage;
  18. FProcessedUnits : TStrings;
  19. FOnLog: TPasParserLogHandler;
  20. FPParserLogEvents: TPParserLogEvents;
  21. FProject : TFPDocProject;
  22. FScannerLogEvents: TPScannerLogEvents;
  23. FVerbose: Boolean;
  24. function GetOptions: TEngineOptions;
  25. function GetPackages: TFPDocPackages;
  26. procedure SetBaseDescrDir(AValue: String);
  27. procedure SetBaseInputDir(AValue: String);
  28. Protected
  29. Function FixInputFile(Const AFileName : String) : String;
  30. Function FixDescrFile(Const AFileName : String) : String;
  31. Procedure DoBeforeEmitNote(Sender : TObject; Note : TDomElement; Var EmitNote : Boolean); virtual;
  32. procedure HandleOnParseUnit(Sender: TObject; const AUnitName: String; out AInputFile, OSTarget, CPUTarget: String);
  33. procedure SetVerbose(AValue: Boolean); virtual;
  34. Procedure DoLog(Const Msg : String);
  35. procedure DoLog(Const Fmt : String; Args : Array of Const);
  36. procedure CreateOutput(APackage: TFPDocPackage; Engine: TFPDocEngine); virtual;
  37. Public
  38. Constructor Create(AOwner : TComponent); override;
  39. Destructor Destroy; override;
  40. Procedure CreateDocumentation(APackage : TFPDocPackage; ParseOnly : Boolean); virtual; //Writes out documentation in selected format
  41. Procedure CreateProjectFile(Const AFileName : string); //Writes out project file with the chosen options
  42. Procedure LoadProjectFile(Const AFileName: string);
  43. Property Project : TFPDocProject Read FProject;
  44. Property ScannerLogEvents : TPScannerLogEvents Read FScannerLogEvents Write FScannerLogEvents;
  45. Property ParserLogEvents : TPParserLogEvents Read FPParserLogEvents Write FPParserLogEvents;
  46. Property Verbose : Boolean Read FVerbose Write SetVerbose;
  47. Property OnLog : TPasParserLogHandler Read FOnLog Write FOnLog;
  48. // Easy access
  49. Property Options : TEngineOptions Read GetOptions;
  50. Property Packages : TFPDocPackages Read GetPackages;
  51. // When set, they will be prepended to non-absolute filenames.
  52. Property BaseInputDir : String Read FBaseInputDir Write SetBaseInputDir;
  53. Property BaseDescrDir : String Read FBaseDescrDir Write SetBaseDescrDir;
  54. end;
  55. implementation
  56. { TFPDocCreator }
  57. procedure TFPDocCreator.SetVerbose(AValue: Boolean);
  58. begin
  59. if FVerbose=AValue then Exit;
  60. FVerbose:=AValue;
  61. if FVerbose then
  62. begin
  63. ScannerLogEvents:=[sleFile];
  64. ParserLogEvents:=[];
  65. end
  66. else
  67. begin
  68. ScannerLogEvents:=[];
  69. ParserLogEvents:=[];
  70. end;
  71. end;
  72. Procedure TFPDocCreator.DoLog(Const Msg: String);
  73. begin
  74. If Assigned(OnLog) then
  75. OnLog(Self,Msg);
  76. end;
  77. procedure TFPDocCreator.DoLog(Const Fmt: String; Args: Array of Const);
  78. begin
  79. DoLog(Format(Fmt,Args));
  80. end;
  81. procedure TFPDocCreator.HandleOnParseUnit(Sender: TObject;
  82. const AUnitName: String; out AInputFile, OSTarget, CPUTarget: String);
  83. Var
  84. I : Integer;
  85. S,un,opts : String;
  86. begin
  87. AInputFile:='';
  88. OSTarget:='';
  89. CPUTarget:='';
  90. if Assigned(FCurPackage) then
  91. begin
  92. I:=0;
  93. While (AInputFIle='') and (I<FCurPackage.Inputs.Count) do
  94. begin
  95. S:=FCurPackage.Inputs[i];
  96. SplitInputFIleOption(S,UN,Opts);
  97. if CompareText(ChangeFileExt(ExtractFileName(Un),''),AUnitName)=0 then
  98. begin
  99. AInputFile:=FixInputFile(UN)+' '+Opts;
  100. OSTarget:=FProject.Options.OSTarget;
  101. CPUTarget:=FProject.Options.CPUTarget;
  102. FProcessedUnits.Add(UN);
  103. end;
  104. Inc(I);
  105. end;
  106. end;
  107. end;
  108. function TFPDocCreator.GetOptions: TEngineOptions;
  109. begin
  110. Result:=FProject.Options;
  111. end;
  112. function TFPDocCreator.GetPackages: TFPDocPackages;
  113. begin
  114. Result:=FProject.Packages;
  115. end;
  116. Function TFPDocCreator.FixInputFile(Const AFileName: String): String;
  117. begin
  118. Result:=AFileName;
  119. If Result='' then exit;
  120. if (ExtractFileDrive(Result)='') and (Result[1]<>PathDelim) then
  121. Result:=BaseInputDir+Result;
  122. end;
  123. Function TFPDocCreator.FixDescrFile(Const AFileName: String): String;
  124. begin
  125. Result:=AFileName;
  126. If Result='' then exit;
  127. if (ExtractFileDrive(Result)='') and (Result[1]<>PathDelim) then
  128. Result:=BaseDescrDir+Result;
  129. end;
  130. procedure TFPDocCreator.SetBaseDescrDir(AValue: String);
  131. begin
  132. if FBaseDescrDir=AValue then Exit;
  133. FBaseDescrDir:=AValue;
  134. If FBaseDescrDir<>'' then
  135. FBaseDescrDir:=IncludeTrailingPathDelimiter(FBaseDescrDir);
  136. end;
  137. procedure TFPDocCreator.SetBaseInputDir(AValue: String);
  138. begin
  139. if FBaseInputDir=AValue then Exit;
  140. FBaseInputDir:=AValue;
  141. If FBaseInputDir<>'' then
  142. FBaseInputDir:=IncludeTrailingPathDelimiter(FBaseInputDir);
  143. end;
  144. Procedure TFPDocCreator.DoBeforeEmitNote(Sender: TObject; Note: TDomElement;
  145. Var EmitNote: Boolean);
  146. begin
  147. EmitNote:=True;
  148. end;
  149. Constructor TFPDocCreator.Create(AOwner: TComponent);
  150. begin
  151. inherited Create(AOwner);
  152. FProject:=TFPDocProject.Create(Self);
  153. FProject.Options.StopOnParseError:=False;
  154. FProject.Options.CPUTarget:=DefCPUTarget;
  155. FProject.Options.OSTarget:=DefOSTarget;
  156. FProcessedUnits:=TStringList.Create;
  157. end;
  158. Destructor TFPDocCreator.Destroy;
  159. begin
  160. FreeAndNil(FProcessedUnits);
  161. FreeAndNil(FProject);
  162. inherited Destroy;
  163. end;
  164. procedure TFPDocCreator.CreateOutput(APackage: TFPDocPackage;Engine : TFPDocEngine);
  165. Var
  166. WriterClass : TFPDocWriterClass;
  167. Writer : TFPDocWriter;
  168. I : Integer;
  169. Cmd,Arg : String;
  170. begin
  171. WriterClass:=GetWriterClass(Options.Backend);
  172. Writer:=WriterClass.Create(Engine.Package,Engine);
  173. With Writer do
  174. Try
  175. If FVerbose then
  176. DoLog('Writing documentation');
  177. OnLog:=Self.OnLog;
  178. BeforeEmitNote:[email protected];
  179. EmitNotes:=Options.EmitNotes;
  180. If Options.BackendOptions.Count>0 then
  181. for I:=0 to ((Options.BackendOptions.Count-1) div 2) do
  182. begin
  183. Cmd:=Options.BackendOptions[I*2];
  184. Arg:=Options.BackendOptions[I*2+1];
  185. If not InterPretOption(Cmd,Arg) then
  186. DoLog(SCmdLineInvalidOption,[Cmd+'='+Arg]);
  187. end;
  188. WriteDoc;
  189. Finally
  190. Free;
  191. end;
  192. if Length(APackage.ContentFile) > 0 then
  193. Engine.WriteContentFile(APackage.ContentFile);
  194. end;
  195. Procedure TFPDocCreator.CreateDocumentation(APackage: TFPDocPackage;
  196. ParseOnly: Boolean);
  197. var
  198. i,j: Integer;
  199. Engine : TFPDocEngine;
  200. Cmd,Arg : String;
  201. WriterClass: TFPDocWriterClass;
  202. begin
  203. Cmd:='';
  204. FCurPackage:=APackage;
  205. Engine:=TFPDocEngine.Create;
  206. try
  207. WriterClass:=GetWriterClass(Options.Backend);
  208. For J:=0 to Apackage.Imports.Count-1 do
  209. begin
  210. Arg:=Apackage.Imports[j];
  211. WriterClass.SplitImport(Arg,Cmd);
  212. Engine.ReadContentFile(Arg, Cmd);
  213. end;
  214. for i := 0 to APackage.Descriptions.Count - 1 do
  215. Engine.AddDocFile(FixDescrFile(APackage.Descriptions[i]),Options.donttrim);
  216. Engine.SetPackageName(APackage.Name);
  217. Engine.Output:=APackage.Output;
  218. Engine.OnLog:=Self.OnLog;
  219. Engine.ScannerLogEvents:=Self.ScannerLogEvents;
  220. Engine.ParserLogEvents:=Self.ParserLogEvents;
  221. Engine.HideProtected:=Options.HideProtected;
  222. Engine.HidePrivate:=Not Options.ShowPrivate;
  223. Engine.OnParseUnit:=@HandleOnParseUnit;
  224. Engine.WarnNoNode:=Options.WarnNoNode;
  225. if Length(Options.Language) > 0 then
  226. TranslateDocStrings(Options.Language);
  227. for i := 0 to APackage.Inputs.Count - 1 do
  228. try
  229. SplitInputFileOption(APackage.Inputs[i],Cmd,Arg);
  230. Cmd:=FixInputFIle(Cmd);
  231. if FProcessedUnits.IndexOf(Cmd)=-1 then
  232. begin
  233. FProcessedUnits.Add(Cmd);
  234. ParseSource(Engine,Cmd+' '+Arg, Options.OSTarget, Options.CPUTarget);
  235. end;
  236. except
  237. on e: EParserError do
  238. If Options.StopOnParseError then
  239. Raise
  240. else
  241. DoLog('%s(%d,%d): %s',[e.Filename, e.Row, e.Column, e.Message]);
  242. end;
  243. if Not ParseOnly then
  244. begin
  245. Engine.StartDocumenting;
  246. CreateOutput(APackage,Engine);
  247. end;
  248. finally
  249. FreeAndNil(Engine);
  250. FCurPackage:=Nil;
  251. end;
  252. end;
  253. Procedure TFPDocCreator.CreateProjectFile(Const AFileName: string);
  254. begin
  255. With TXMLFPDocOptions.Create(Self) do
  256. try
  257. SaveOptionsToFile(FProject,AFileName);
  258. finally
  259. Free;
  260. end;
  261. end;
  262. Procedure TFPDocCreator.LoadProjectFile(Const AFileName: string);
  263. begin
  264. With TXMLFPDocOptions.Create(self) do
  265. try
  266. LoadOptionsFromFile(FProject,AFileName);
  267. finally
  268. Free;
  269. end;
  270. end;
  271. end.