dw_htmlchm.inc 18 KB

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