chmfilewriter.pas 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. { Copyright (C) <2005> <Andrew Haines> chmfilewriter.pas
  2. This library is free software; you can redistribute it and/or modify it
  3. under the terms of the GNU Library General Public License as published by
  4. the Free Software Foundation; either version 2 of the License, or (at your
  5. option) any later version.
  6. This program is distributed in the hope that it will be useful, but WITHOUT
  7. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  8. FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
  9. for more details.
  10. You should have received a copy of the GNU Library General Public License
  11. along with this library; if not, write to the Free Software Foundation,
  12. Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  13. }
  14. {
  15. See the file COPYING.FPC, included in this distribution,
  16. for details about the copyright.
  17. }
  18. unit chmfilewriter;
  19. {$mode objfpc}{$H+}
  20. interface
  21. uses
  22. Classes, SysUtils, chmwriter;
  23. type
  24. TChmProject = class;
  25. TChmProgressCB = procedure (Project: TChmProject; CurrentFile: String) of object;
  26. { TChmProject }
  27. TChmProject = class
  28. private
  29. FAutoFollowLinks: Boolean;
  30. FDefaultFont: String;
  31. FDefaultPage: String;
  32. FFiles: TStrings;
  33. FIndexFileName: String;
  34. FMakeSearchable: Boolean;
  35. FFileName: String;
  36. FOnProgress: TChmProgressCB;
  37. FOutputFileName: String;
  38. FTableOfContentsFileName: String;
  39. FTitle: String;
  40. protected
  41. function GetData(const DataName: String; out PathInChm: String; out FileName: String; var Stream: TStream): Boolean;
  42. public
  43. constructor Create;
  44. destructor Destroy; override;
  45. procedure LoadFromFile(AFileName: String);
  46. procedure SaveToFile(AFileName: String);
  47. procedure WriteChm(AOutStream: TStream);
  48. function ProjectDir: String;
  49. // though stored in the project file, it is only there for the program that uses the unit
  50. // since we actually write to a stream
  51. property OutputFileName: String read FOutputFileName write FOutputFileName;
  52. property FileName: String read FFileName write FFileName;
  53. property Files: TStrings read FFiles write FFiles;
  54. property AutoFollowLinks: Boolean read FAutoFollowLinks write FAutoFollowLinks;
  55. property TableOfContentsFileName: String read FTableOfContentsFileName write FTableOfContentsFileName;
  56. property Title: String read FTitle write FTitle;
  57. property IndexFileName: String read FIndexFileName write FIndexFileName;
  58. property MakeSearchable: Boolean read FMakeSearchable write FMakeSearchable;
  59. property DefaultPage: String read FDefaultPage write FDefaultPage;
  60. property DefaultFont: String read FDefaultFont write FDefaultFont;
  61. property OnProgress: TChmProgressCB read FOnProgress write FOnProgress;
  62. end;
  63. implementation
  64. uses XmlCfg;
  65. { TChmProject }
  66. function TChmProject.GetData(const DataName: String; out PathInChm: String; out
  67. FileName: String; var Stream: TStream): Boolean;
  68. begin
  69. Result := False; // Return true to abort compressing files
  70. TMemoryStream(Stream).LoadFromFile(ProjectDir+DataName);
  71. WriteLn('Reading: ', DataName);
  72. // clean up the filename
  73. FileName := StringReplace(ExtractFileName(DataName), '\', '/', [rfReplaceAll]);
  74. FileName := StringReplace(FileName, '//', '/', [rfReplaceAll]);
  75. PathInChm := '/'+ExtractFilePath(DataName);
  76. if Assigned(FOnProgress) then FOnProgress(Self, DataName);
  77. end;
  78. constructor TChmProject.Create;
  79. begin
  80. FFiles := TStringList.Create;
  81. end;
  82. destructor TChmProject.Destroy;
  83. begin
  84. FFIles.Free;
  85. inherited Destroy;
  86. end;
  87. procedure TChmProject.LoadFromFile(AFileName: String);
  88. var
  89. Cfg: TXMLConfig;
  90. FileCount: Integer;
  91. I: Integer;
  92. begin
  93. Cfg := TXMLConfig.Create(nil);
  94. Cfg.Filename := AFileName;
  95. FileName := AFileName;
  96. Files.Clear;
  97. FileCount := Cfg.GetValue('Files/Count/Value', 0);
  98. for I := 0 to FileCount-1 do begin
  99. Files.Add(Cfg.GetValue('Files/FileName'+IntToStr(I)+'/Value',''));
  100. end;
  101. IndexFileName := Cfg.GetValue('Files/IndexFile/Value','');
  102. TableOfContentsFileName := Cfg.GetValue('Files/TOCFile/Value','');
  103. AutoFollowLinks := Cfg.GetValue('Settings/AutoFollowLinks/Value', False);
  104. MakeSearchable := Cfg.GetValue('Settings/MakeSearchable/Value', False);
  105. DefaultPage := Cfg.GetValue('Settings/DefaultPage/Value', '');
  106. Title := Cfg.GetValue('Settings/Title/Value', '');
  107. OutputFileName := Cfg.GetValue('Settings/OutputFileName/Value', '');
  108. DefaultFont := Cfg.GetValue('Settings/DefaultFont/Value', '');
  109. Cfg.Free;
  110. end;
  111. procedure TChmProject.SaveToFile(AFileName: String);
  112. var
  113. Cfg: TXMLConfig;
  114. I: Integer;
  115. begin
  116. Cfg := TXMLConfig.Create(nil);
  117. Cfg.StartEmpty := True;
  118. Cfg.Filename := FileName;
  119. Cfg.Clear;
  120. Cfg.SetValue('Files/Count/Value', Files.Count);
  121. for I := 0 to Files.Count-1 do begin
  122. Cfg.SetValue('Files/FileName'+IntToStr(I)+'/Value', Files.Strings[I]);
  123. end;
  124. Cfg.SetValue('Files/IndexFile/Value', IndexFileName);
  125. Cfg.SetValue('Files/TOCFile/Value', TableOfContentsFileName);
  126. Cfg.SetValue('Settings/AutoFollowLinks/Value', AutoFollowLinks);
  127. Cfg.SetValue('Settings/MakeSearchable/Value', MakeSearchable);
  128. Cfg.SetValue('Settings/DefaultPage/Value', DefaultPage);
  129. Cfg.SetValue('Settings/Title/Value', Title);
  130. Cfg.SetValue('Settings/OutputFileName/Value', OutputFileName);
  131. Cfg.SetValue('Settings/DefaultFont/Value', DefaultFont);
  132. Cfg.Free;
  133. end;
  134. function TChmProject.ProjectDir: String;
  135. begin
  136. Result := ExtractFilePath(FileName);
  137. end;
  138. procedure TChmProject.WriteChm(AOutStream: TStream);
  139. var
  140. Writer: TChmWriter;
  141. TOCStream,
  142. IndexStream: TFileStream;
  143. begin
  144. IndexStream := nil;
  145. TOCStream := nil;
  146. Writer := TChmWriter.Create(AOutStream, False);
  147. // our callback to get data
  148. Writer.OnGetFileData := @GetData;
  149. // give it the list of files
  150. Writer.FilesToCompress.AddStrings(Files);
  151. // Assign the TOC and index files
  152. if (IndexFileName <> '') and FileExists(IndexFileName) then begin
  153. IndexStream := TFileStream.Create(IndexFileName, fmOpenRead);
  154. Writer.IndexStream := IndexStream;
  155. end;
  156. if (TableOfContentsFileName <> '') and FileExists(TableOfContentsFileName) then begin
  157. TOCStream := TFileStream.Create(TableOfContentsFileName, fmOpenRead);
  158. Writer.TOCStream := TOCStream;
  159. end;
  160. // now some settings in the chm
  161. Writer.DefaultPage := DefaultPage;
  162. Writer.Title := Title;
  163. Writer.DefaultFont := DefaultFont;
  164. Writer.FullTextSearch := MakeSearchable;
  165. // and write!
  166. Writer.Execute;
  167. if Assigned(TOCStream) then TOCStream.Free;
  168. if Assigned(IndexStream) then IndexStream.Free;
  169. end;
  170. end.