dw_htmlchm.inc 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632
  1. {%mainunit dw_html}
  2. {$IFDEF chmInterface}
  3. type
  4. { TFpDocChmWriter }
  5. TFpDocChmWriter = class (TChmWriter)
  6. protected
  7. procedure FileAdded(AStream: TStream; const AEntry: TFileEntryRec); override;
  8. end;
  9. { TCHMHTMLWriter }
  10. TCHMHTMLWriter = class(THTMLWriter)
  11. private
  12. FOutChm: TStream;
  13. FChm: TFpDocChmWriter;
  14. FTempUncompressed: TStream;
  15. FTempUncompressedName: String;
  16. FChmTitle: String;
  17. FTOCName,
  18. FIndexName,
  19. FDefaultPage: String;
  20. FMakeSearchable,
  21. FNoBinToc,
  22. FNoBinIndex,
  23. FAutoTOC,
  24. FAutoIndex: Boolean;
  25. FOtherFiles: String;
  26. procedure ProcessOptions;
  27. function ResolveLinkIDAbs(const Name: String; Level : Integer = 0): DOMString;
  28. function RetrieveOtherFiles(const DataName: String; out PathInChm: String; out FileName: String; var Stream: TStream): Boolean;
  29. procedure LastFileAdded(Sender: TObject);
  30. procedure GenerateTOC;
  31. procedure GenerateIndex;
  32. public
  33. procedure WriteHTMLPages; override;
  34. function InterPretOption(const Cmd,Arg : String): boolean; override;
  35. class procedure Usage(List: TStrings); override;
  36. Class Function FileNameExtension : String; override;
  37. Class procedure SplitImport(var AFilename, ALinkPrefix: String); override;
  38. end;
  39. {$ELSE} // implementation
  40. { TFpDocChmWriter }
  41. procedure TFpDocChmWriter.FileAdded ( AStream: TStream;
  42. const AEntry: TFileEntryRec ) ;
  43. begin
  44. // Exclude Full text index for files starting from the dot
  45. if Pos('.', AEntry.Name) <> 1 then
  46. inherited FileAdded(AStream, AEntry);
  47. end;
  48. { TCHMHTMLWriter }
  49. function TCHMHTMLWriter.ResolveLinkIDAbs(const Name: String; Level : Integer = 0): DOMString;
  50. begin
  51. Result:=UTF8Decode(FixHTMLpath(Engine.ResolveLink(Module,Name, True)));
  52. // for global index: don't make it relative to the current document.
  53. end;
  54. procedure TCHMHTMLWriter.ProcessOptions;
  55. var
  56. TempStream: TMemoryStream;
  57. begin
  58. if FDefaultPage = '' then
  59. FDefaultPage := 'index.html'
  60. else
  61. begin
  62. DoLog('Note: --index-page not assigned. Using default "index.html"');
  63. end;
  64. if FCSSFile <> '' then
  65. begin
  66. if not FileExists(FCSSFile) Then
  67. Raise Exception.CreateFmt('Can''t find CSS file "%S"',[FCSSFILE]);
  68. TempStream := TMemoryStream.Create;
  69. TempStream.LoadFromFile(FCSSFile);
  70. TempStream.Position := 0;
  71. FChm.AddStreamToArchive('fpdoc.css', '/', TempStream, True);
  72. TempStream.Free;
  73. end;
  74. FChm.DefaultPage := FDefaultPage;
  75. if FOtherFiles <> '' then
  76. begin
  77. FChm.FilesToCompress.LoadFromFile(FOtherFiles);
  78. end;
  79. FChm.FullTextSearch := FMakeSearchable;
  80. end;
  81. function TCHMHTMLWriter.RetrieveOtherFiles(const DataName: String; out
  82. PathInChm: String; out FileName: String; var Stream: TStream): Boolean;
  83. begin
  84. Result:=True;
  85. if Stream <> nil then
  86. Stream.Free;
  87. Stream := TMemoryStream.Create;
  88. TMemoryStream(Stream).LoadFromFile(DataName);
  89. FileName := ExtractFileName(DataName);
  90. if ExtractFileDir(DataName) <> '' then
  91. PathInChm := ExtractRelativepath(GetCurrentDir, ExtractFileDir(DataName))
  92. else
  93. PathInChm := '/';
  94. FixHTMLpath(PathInChm);
  95. Stream.Position := 0;
  96. end;
  97. procedure TCHMHTMLWriter.LastFileAdded(Sender: TObject);
  98. var
  99. TmpStream: TMemoryStream;
  100. begin
  101. TmpStream := TMemoryStream.Create;
  102. if FAutoTOC then
  103. GenerateTOC
  104. else
  105. if FTOCName <> '' then
  106. begin
  107. TmpStream.LoadFromFile(FTOCName);
  108. TmpStream.Position := 0;
  109. FChm.AppendTOC(TmpStream);
  110. TmpStream.Size := 0;
  111. end;
  112. if FAutoIndex then
  113. GenerateIndex
  114. else
  115. if FIndexName <> '' then
  116. begin
  117. TmpStream.LoadFromFile(FIndexName);
  118. TmpStream.Position := 0;
  119. FChm.AppendIndex(TmpStream);
  120. end;
  121. TmpStream.Free;
  122. DoLog('Finishing compressing...');
  123. end;
  124. function TOCSort(Item1, Item2: TChmSiteMapItem): Integer;
  125. begin
  126. Result := CompareText(LowerCase(Item1.Text), LowerCase(Item2.Text));
  127. end;
  128. function GetAlphaItem(AItems: TChmSiteMapItems; AName: String): TChmSiteMapItem;
  129. var
  130. x: Integer;
  131. begin
  132. Result := nil;
  133. for x := 0 to AItems.Count-1 do
  134. begin
  135. if AItems.Item[x].Text = AName then
  136. Exit(AItems.Item[x]);
  137. end;
  138. Result := AItems.NewItem;
  139. Result.Text := AName;
  140. end;
  141. procedure TCHMHTMLWriter.GenerateTOC;
  142. var
  143. TOC: TChmSiteMap;
  144. Element: TPasElement;
  145. j: Integer;
  146. i: Integer;
  147. AModule: TPasModule;
  148. Stream: TMemoryStream;
  149. TmpItem: TChmSiteMapItem;
  150. ObjByUnitItem,
  151. AlphaObjItem,
  152. ObjUnitItem,
  153. RoutinesByUnitItem,
  154. RoutinesUnitItem,
  155. AlphaRoutinesItem: TChmSiteMapItem;
  156. begin
  157. DoLog('Generating Table of contents...');
  158. if Assigned(Package) then
  159. begin
  160. Toc := TChmSiteMap.Create(stTOC);
  161. Stream := TMemoryStream.Create;
  162. ObjByUnitItem := TOC.Items.NewItem;
  163. ObjByUnitItem.Text := 'Classes and Objects, by Unit';
  164. AlphaObjItem := TOC.Items.NewItem;
  165. AlphaObjItem.Text := 'Alphabetical Classes and Objects List';
  166. RoutinesByUnitItem := TOC.Items.NewItem;
  167. RoutinesByUnitItem.Text := 'Routines, by Unit';
  168. AlphaRoutinesItem := TOC.Items.NewItem;
  169. AlphaRoutinesItem.Text := 'Alphabetical Routines List';
  170. // objects and classes
  171. for i := 0 to Package.Modules.Count - 1 do
  172. begin
  173. AModule := TPasModule(Package.Modules[i]);
  174. If not assigned(AModule.InterfaceSection) Then
  175. Continue;
  176. ObjUnitItem := ObjByUnitItem.Children.NewItem;
  177. ObjUnitItem.Text := AModule.Name;
  178. RoutinesUnitItem := RoutinesByUnitItem.Children.NewItem;
  179. RoutinesUnitItem.Text := AModule.Name;
  180. for j := 0 to AModule.InterfaceSection.Classes.Count-1 do
  181. begin
  182. Element := TPasClassType(AModule.InterfaceSection.Classes[j]);
  183. // by unit
  184. TmpItem := ObjUnitItem.Children.NewItem;
  185. TmpItem.Text := Element.Name;
  186. TmpItem.addLocal(FixHTMLpath(Allocator.GetFilename(Element, 0)));
  187. //alpha
  188. TmpItem := GetAlphaItem(AlphaObjItem.Children, UpperCase(Copy(Element.Name, 1, 2))).Children.NewItem;
  189. TmpItem.Text := Element.Name;
  190. TmpItem.addLocal(FixHTMLpath(Allocator.GetFilename(Element, 0)));
  191. end;
  192. // non object procedures and functions
  193. for j := 0 to AModule.InterfaceSection.Functions.Count-1 do
  194. begin
  195. Element := TPasFunctionType(AModule.InterfaceSection.Functions[j]);
  196. // by unit
  197. TmpItem := RoutinesUnitItem.Children.NewItem;
  198. TmpItem.Text := Element.Name;
  199. TmpItem.addLocal(FixHTMLpath(Allocator.GetFilename(Element, 0)));
  200. // alpha
  201. TmpItem := GetAlphaItem(AlphaRoutinesItem.Children, UpperCase(Element.Name[1])).Children.NewItem;
  202. TmpItem.Text := Element.Name;
  203. TmpItem.addLocal(FixHTMLpath(Allocator.GetFilename(Element, 0)));
  204. end;
  205. end;
  206. end;
  207. // cleanup
  208. for i := ObjByUnitItem.Children.Count-1 downto 0 do
  209. begin
  210. if ObjByUnitItem.Children.Item[i].Children.Count = 0 then
  211. ObjByUnitItem.Children.Delete(i);
  212. end;
  213. for i := RoutinesByUnitItem.Children.Count-1 downto 0 do
  214. begin
  215. if RoutinesByUnitItem.Children.Item[i].Children.Count = 0 then
  216. RoutinesByUnitItem.Children.Delete(i);
  217. end;
  218. for i := TOC.Items.Count-1 downto 0 do
  219. begin
  220. if TOC.Items.Item[i].Children.Count = 0 then
  221. TOC.Items.Delete(i);
  222. end;
  223. // Sort
  224. for i := 0 to TOC.Items.Count-1 do
  225. begin
  226. TOC.Items.Item[i].Children.Sort(TListSortCompare(@TOCSort));
  227. for j := 0 to TOC.Items.Item[i].Children.Count-1 do
  228. begin
  229. TOC.Items.Item[i].Children.Item[j].Children.Sort(TListSortCompare(@TOCSort));
  230. end;
  231. end;
  232. if not fnobintoc then
  233. fchm.AppendBinaryTOCFromSiteMap(Toc);
  234. TOC.SaveToStream(Stream);
  235. TOC.Free;
  236. fchm.AppendTOC(Stream);
  237. Stream.Free;
  238. end;
  239. type
  240. TClassMemberType = (cmtProcedure, cmtFunction, cmtConstructor, cmtDestructor,
  241. cmtInterface, cmtProperty, cmtVariable, cmtUnknown);
  242. function ElementType(Element: TPasElement): TClassMemberType;
  243. var
  244. ETypeName: String;
  245. begin
  246. Result := cmtUnknown;
  247. ETypeName := Element.ElementTypeName;
  248. //overloaded we don't care
  249. if ETypeName[1] = 'o' then ETypeName := Copy(ETypeName, 11, Length(ETypeName));
  250. if ETypeName[1] = 'f' then Exit(cmtFunction);
  251. if ETypeName[1] = 'c' then Exit(cmtConstructor);
  252. if ETypeName[1] = 'v' then Exit(cmtVariable);
  253. if ETypeName[1] = 'i' then Exit(cmtInterface);
  254. // the p's
  255. if ETypeName[4] = 'c' then Exit(cmtProcedure);
  256. if ETypeName[4] = 'p' then Exit(cmtProperty);
  257. end;
  258. procedure TCHMHTMLWriter.GenerateIndex;
  259. var
  260. Index: TChmSiteMap;
  261. i, j, k: Integer;
  262. TmpItem: TChmSiteMapItem;
  263. ParentItem: TChmSiteMapItem;
  264. AModule: TPasModule;
  265. TmpElement: TPasElement;
  266. ParentElement: TPasElement;
  267. MemberItem: TChmSiteMapItem;
  268. Stream: TMemoryStream;
  269. RedirectUrl,Urls: String;
  270. begin
  271. DoLog('Generating Index...');
  272. if Assigned(Package) then
  273. begin
  274. Index := TChmSiteMap.Create(stIndex);
  275. Stream := TMemoryStream.Create;
  276. for i := 0 to Package.Modules.Count - 1 do
  277. begin
  278. AModule := TPasModule(Package.Modules[i]);
  279. if not assigned(AModule.InterfaceSection) then
  280. continue;
  281. ParentItem := Index.Items.NewItem;
  282. ParentItem.Text := AModule.Name;
  283. ParentItem.addLocal(FixHTMLpath(Allocator.GetFilename(AModule, 0)));
  284. // classes
  285. for j := 0 to AModule.InterfaceSection.Classes.Count-1 do
  286. begin
  287. ParentElement := TPasClassType(AModule.InterfaceSection.Classes[j]);
  288. ParentItem := Index.Items.NewItem;
  289. ParentItem.Text := ParentELement.Name;
  290. ParentItem.addLocal(FixHTMLpath(Allocator.GetFilename(ParentElement, 0)));
  291. for k := 0 to TPasClassType(ParentElement).Members.Count-1 do
  292. begin
  293. TmpElement := TPasElement(TPasClassType(ParentElement).Members.Items[k]);
  294. if Engine.HidePrivate and(TmpElement.Visibility = visPrivate) then
  295. continue;
  296. if Engine.HideProtected and(TmpElement.Visibility = visProtected) then
  297. continue;
  298. Urls:=FixHTMLpath(Allocator.GetFilename(TmpElement, 0));
  299. RedirectUrl:='';
  300. if TmpElement is TPasEnumValue then
  301. RedirectUrl := UTF8Encode(ResolveLinkIDAbs(tmpElement.Parent.PathName))
  302. else
  303. RedirectUrl := UTF8Encode(ResolveLinkIDAbs(tmpElement.PathName));
  304. if(trim(RedirectUrl)<>'') and (RedirectUrl<>urls) then
  305. begin
  306. writeln('Hint: Index Resolved:',urls,' to ',RedirectUrl);
  307. urls:=RedirectUrl;
  308. end;
  309. TmpItem := ParentItem.Children.NewItem;
  310. case ElementType(TmpElement) of
  311. cmtProcedure : TmpItem.Text := TmpElement.Name + ' procedure';
  312. cmtFunction : TmpItem.Text := TmpElement.Name + ' function';
  313. cmtConstructor : TmpItem.Text := TmpElement.Name + ' constructor';
  314. cmtDestructor : TmpItem.Text := TmpElement.Name + ' destructor';
  315. cmtProperty : TmpItem.Text := TmpElement.Name + ' property';
  316. cmtVariable : TmpItem.Text := TmpElement.Name + ' variable';
  317. cmtInterface : TmpItem.Text := TmpElement.Name + ' interface';
  318. cmtUnknown : TmpItem.Text := TmpElement.Name;
  319. end;
  320. TmpItem.addLocal(Urls);
  321. {
  322. ParentElement = Class
  323. TmpElement = Member
  324. }
  325. MemberItem := nil;
  326. MemberItem := GetAlphaItem(Index.Items, TmpElement.Name);
  327. // ahh! if MemberItem.Local is empty MemberType is not shown!
  328. MemberItem.addLocal(Urls);
  329. TmpItem := MemberItem.Children.NewItem;
  330. TmpItem.Text := ParentElement.Name;
  331. TmpItem.AddLocal(Urls);
  332. end;
  333. end;
  334. // routines
  335. for j := 0 to AModule.InterfaceSection.Functions.Count-1 do
  336. begin
  337. ParentElement := TPasProcedureType(AModule.InterfaceSection.Functions[j]);
  338. TmpItem := Index.Items.NewItem;
  339. TmpItem.Text := ParentElement.Name + ' ' + ParentElement.ElementTypeName;
  340. TmpItem.addLocal(FixHTMLpath(Allocator.GetFilename(ParentElement, 0)));
  341. end;
  342. // consts
  343. for j := 0 to AModule.InterfaceSection.Consts.Count-1 do
  344. begin
  345. ParentElement := TPasElement(AModule.InterfaceSection.Consts[j]);
  346. TmpItem := Index.Items.NewItem;
  347. TmpItem.Text := ParentElement.Name;
  348. TmpItem.addLocal(FixHTMLpath(Allocator.GetFilename(ParentElement, 0)));
  349. end;
  350. // types
  351. for j := 0 to AModule.InterfaceSection.Types.Count-1 do
  352. begin
  353. ParentElement := TPasType(AModule.InterfaceSection.Types[j]);
  354. TmpItem := Index.Items.NewItem;
  355. TmpItem.Text := ParentElement.Name;
  356. TmpItem.addLocal(FixHTMLpath(Allocator.GetFilename(ParentElement, 0)));
  357. // enums
  358. if ParentELement is TPasEnumType then
  359. begin
  360. ParentItem := TmpItem;
  361. for k := 0 to TPasEnumType(ParentElement).Values.Count-1 do
  362. begin
  363. TmpElement := TPasType(TPasEnumType(ParentElement).Values.Items[k]);
  364. // subitem
  365. TmpItem := ParentItem.Children.NewItem;
  366. TmpItem.Text := TmpElement.Name;
  367. TmpItem.addLocal(ParentItem.Local);
  368. // root level
  369. TmpItem := Index.Items.NewItem;
  370. TmpItem.Text := TmpElement.Name;
  371. TmpItem.addLocal(ParentItem.Local);
  372. end;
  373. end;
  374. end;
  375. // variables
  376. for j := 0 to AModule.InterfaceSection.Variables.Count-1 do
  377. begin
  378. ParentElement := TPasElement(AModule.InterfaceSection.Variables[j]);
  379. TmpItem := Index.Items.NewItem;
  380. TmpItem.Text := ParentElement.Name + ' var';
  381. TmpItem.addLocal(FixHTMLpath(Allocator.GetFilename(ParentElement, 0)));
  382. end;
  383. // declarations
  384. {
  385. for j := 0 to AModule.InterfaceSection.Declarations.Count-1 do
  386. begin
  387. ParentElement := TPasElement(AModule.InterfaceSection.Declarations[j]);
  388. TmpItem := Index.Items.NewItem;
  389. TmpItem.Text := ParentElement.Name;
  390. TmpItem.Local := FixHTMLpath(Allocator.GetFilename(ParentElement, 0));
  391. end;
  392. // resource strings
  393. for j := 0 to AModule.InterfaceSection.ResStrings.Count-1 do
  394. begin
  395. ParentElement := TPasElement(AModule.InterfaceSection.ResStrings[j]);
  396. TmpItem := Index.Items.NewItem;
  397. TmpItem.Text := ParentElement.Name;
  398. TmpItem.Local := FixHTMLpath(Allocator.GetFilename(ParentElement, 0));
  399. end;
  400. }
  401. end;
  402. // Sort
  403. Index.Items.Sort(TListSortCompare(@TOCSort));
  404. for i := 0 to Index.Items.Count-1 do
  405. begin
  406. Index.Items.Item[i].Children.Sort(TListSortCompare(@TOCSort));
  407. end;
  408. // save
  409. Index.SaveToStream(Stream);
  410. if not fnobinindex then
  411. fchm.AppendBinaryindexFromSitemap(index,false);
  412. Index.Free;
  413. Stream.Position :=0 ;
  414. FChm.AppendIndex(Stream);
  415. Stream.Free;
  416. end;
  417. end;
  418. procedure TCHMHTMLWriter.WriteHTMLPages;
  419. var
  420. i: Integer;
  421. PageDoc: TXMLDocument;
  422. FileStream: TMemoryStream;
  423. FileName: String;
  424. FilePath: String;
  425. begin
  426. FileName := Engine.Output;
  427. if FileName = '' then
  428. Raise Exception.Create('Error: no --output option used.');
  429. if ExtractFileExt(FileName) <> FileNameExtension then
  430. FileName := ChangeFileExt(FileName, FileNameExtension);
  431. FOutChm := TFileStream.Create(FileName, fmOpenReadWrite or fmCreate);
  432. FTempUncompressedName := GetTempFileName+IntToStr(GetProcessID) +'.raw';
  433. FTempUncompressed := TFileStream.Create(FTempUncompressedName, fmOpenReadWrite or fmCreate);
  434. FChm := TFpDocChmWriter.Create(FOutChm, False);
  435. FChm.Title := FChmTitle;
  436. FChm.TempRawStream := FTempUncompressed;
  437. FChm.OnGetFileData := @RetrieveOtherFiles;
  438. FChm.OnLastFile := @LastFileAdded;
  439. fchm.hasbinarytoc:=not fnobintoc;;
  440. fchm.hasbinaryindex:=not fnobinindex;
  441. ProcessOptions;
  442. FileStream := TMemoryStream.Create;
  443. for i := 0 to PageInfos.Count - 1 do
  444. with TPageInfo(PageInfos[i]) do
  445. begin
  446. PageDoc := CreateHTMLPage(Element, SubpageIndex);
  447. try
  448. FileName := ExtractFileName(Allocator.GetFilename(Element, SubpageIndex));
  449. FilePath := '/'+FixHTMLpath(ExtractFilePath(Allocator.GetFilename(Element, SubpageIndex)));
  450. try
  451. WriteHTMLFile(PageDoc, FileStream);
  452. FChm.AddStreamToArchive(FileName, FilePath, FileStream, True);
  453. except
  454. on E: Exception do
  455. DoLog(Format(SErrCouldNotCreateFile, [FileName, e.Message]));
  456. end;
  457. finally
  458. PageDoc.Free;
  459. FileStream.Size := 0;
  460. end;
  461. end;
  462. FileStream.Free;
  463. DoLog('HTML Files written. Collecting other files and compressing...this could take some time');
  464. //write any found images to CHM stream
  465. FileStream := TMemoryStream.Create;
  466. for i := 0 to FImageFileList.Count - 1 do
  467. begin
  468. {$ifdef imagetest} DoLog(' adding image: '+FImageFileList[i]); {$endif}
  469. if FileExists(FImageFileList[i]) then
  470. begin
  471. {$ifdef imagetest} DoLog(' - found'); {$endif}
  472. FileName := ExtractFileName(FImageFileList[i]);
  473. FilePath := '/'+FixHTMLpath(ExtractFilePath(FImageFileList[i]));
  474. FileStream.LoadFromFile(FImageFileList[i]);
  475. FChm.AddStreamToArchive(FileName, FilePath, FileStream, True);
  476. FileStream.Size := 0;
  477. end
  478. else
  479. {$ifdef imagetest} DoLog(' - not found'){$endif};
  480. end;
  481. FileStream.Free;
  482. FChm.Execute;
  483. FChm.Free;
  484. // we don't need to free FTempUncompressed
  485. // FTempUncompressed.Free;
  486. FOutChm.Free;
  487. DeleteFile(FTempUncompressedName);
  488. end;
  489. function TCHMHTMLWriter.InterPretOption(const Cmd, Arg: String): boolean;
  490. begin
  491. Result:=True;
  492. FNoBinToc:=False;
  493. FnoBinIndex:=False;
  494. if Cmd = '--toc-file' then
  495. FTOCName := arg
  496. else if Cmd = '--index-file' then
  497. FIndexName := arg
  498. else if Cmd = '--default-page' then
  499. FDefaultPage := arg
  500. else if Cmd = '--other-files' then
  501. FOtherFiles := arg
  502. else if Cmd = '--auto-index' then
  503. FAutoIndex := True
  504. else if Cmd = '--auto-toc' then
  505. FAutoTOC := True
  506. else if Cmd = '--no-bintoc' then
  507. FNoBinToc := True
  508. else if Cmd = '--no-binindex' then
  509. FNoBinIndex := True
  510. else if Cmd = '--make-searchable' then
  511. FMakeSearchable := True
  512. else if Cmd = '--chm-title' then
  513. FChmTitle := arg
  514. else
  515. Result:=inherited InterPretOption(Cmd, Arg);
  516. if Length(FChmTitle) = 0 then
  517. FChmTitle := Copy(Package.Name, 2, Length(Package.Name));
  518. end;
  519. class procedure TCHMHTMLWriter.Usage(List: TStrings);
  520. begin
  521. THTMLWriter.Usage(List);
  522. List.add('--default-page');
  523. List.Add(SCHMUsageDefPage);
  524. List.add('--toc-file');
  525. List.Add(SCHMUsageTOC);
  526. List.add('--index-file');
  527. List.Add(SCHMUsageIndex);
  528. List.add('--other-files');
  529. List.Add(SCHMUsageOtrFiles);
  530. List.add('--css-file');
  531. List.Add(SCHMUsageCSSFile);
  532. List.add('--auto-index');
  533. List.Add(SCHMUsageAutoIDX);
  534. List.add('--auto-toc');
  535. List.Add(SCHMUsageAutoTOC);
  536. List.add('--make-searchable');
  537. List.Add(SCHMUsageMakeSearch);
  538. List.Add('--chm-title');
  539. List.Add(SCHMUsageChmTitle);
  540. end;
  541. Class Function TCHMHTMLWriter.FileNameExtension : String;
  542. begin
  543. result:='.chm';
  544. end;
  545. class procedure TCHMHTMLWriter.SplitImport(var AFilename, ALinkPrefix: String);
  546. var
  547. i: integer;
  548. begin
  549. i := Pos(',', AFilename);
  550. if i > 0 then
  551. begin //split into filename and prefix
  552. ALinkPrefix := Copy(AFilename,i+1,Length(AFilename));
  553. SetLength(AFilename, i-1);
  554. if copy(ALinkPrefix,1,2)='..' then // workaround for project files.
  555. begin
  556. ALinkPrefix := 'ms-its:' + ChangeFileExt(ExtractFileName(AFilename), '.chm') + '::/';
  557. AFilename := ChangeFileExt(AFilename, '.xct');
  558. end;
  559. end
  560. else if ALinkPrefix = '' then
  561. begin //synthesize outdir\pgk.xct, ms-its:pkg.chm::/
  562. ALinkPrefix := 'ms-its:' + ChangeFileExt(ExtractFileName(AFilename), '.chm') + '::/';
  563. AFilename := ChangeFileExt(AFilename, '.xct');
  564. end;
  565. end;
  566. {$ENDIF}