|
@@ -15,32 +15,41 @@
|
|
|
**********************************************************************}
|
|
|
unit wchmhwrap;
|
|
|
|
|
|
-interface
|
|
|
+interface
|
|
|
{$Mode Delphi}
|
|
|
|
|
|
Uses wutils,whelp,whtml,SysUtils,ChmReader,ChmSiteMap,Classes;
|
|
|
|
|
|
Type
|
|
|
-// TopicLinks: PTopicLinkCollection;IndexEntries : PUnsortedIndexEntryCollection;
|
|
|
+// TopicLinks: PTopicLinkCollection;IndexEntries : PUnsortedIndexEntryCollection;
|
|
|
|
|
|
TChmWrapper = Class
|
|
|
private
|
|
|
- ffs : Classes.TFileStream;
|
|
|
- fchmr : TChmReader;
|
|
|
- findex: TChmSiteMap;
|
|
|
- ftopic: TChmSiteMap;
|
|
|
- floaded : boolean;
|
|
|
- public
|
|
|
- constructor Create(name:String);
|
|
|
+ ffs : Classes.TFileStream;
|
|
|
+ fchmr : TChmReader;
|
|
|
+ findex : TChmSiteMap;
|
|
|
+ ftopic : TChmSiteMap;
|
|
|
+ floaded : boolean;
|
|
|
+ fileid : integer;
|
|
|
+ fshortname : string;
|
|
|
+ flongname : string;
|
|
|
+ fTopicLinks : PTopicLinkCollection;
|
|
|
+ public
|
|
|
+ constructor Create(name:String;aid:integer;TopicLinks:PTopicLinkCollection);
|
|
|
function LoadIndex(id:integer;TopicLinks: PTopicLinkCollection;IndexEntries : PUnsortedIndexEntryCollection;helpfacility:PHelpFacility):boolean;
|
|
|
function GetTopic(name:string):PMemoryTextFile;
|
|
|
destructor Destroy;override;
|
|
|
end;
|
|
|
|
|
|
function combinepaths(relpath,basepath:String):String;
|
|
|
+function CHMResolve( href: ansistring; var AFileId,ALinkId : longint):boolean;
|
|
|
|
|
|
+function stringreplace(const s:ansistring;const oldstr:ansistring; const newstr:ansistring):ansistring;
|
|
|
implementation
|
|
|
|
|
|
+var CHMIndex : TStringList; // list to register open CHMs.
|
|
|
+
|
|
|
+
|
|
|
function combinepaths(relpath,basepath:String):String;
|
|
|
|
|
|
begin
|
|
@@ -56,35 +65,44 @@ begin
|
|
|
basepath:=extractfiledir(basepath);
|
|
|
delete(relpath,1,3);
|
|
|
end;
|
|
|
-
|
|
|
- {$ifdef combinedebug}
|
|
|
+
|
|
|
+ {$ifdef combinedebug}
|
|
|
debugmessageS({$i %file%},'combine out "'+relpath+'" and "'+basepath+'"',{$i %line%},'1',0,0);
|
|
|
{$endif}
|
|
|
-
|
|
|
+ if (length(basepath)>0) and (length(relpath)>0) then
|
|
|
+ begin
|
|
|
+ if (relpath[1]<>'/') and (basepath[length(basepath)]<>'/') then
|
|
|
+ basepath:=basepath+'/';
|
|
|
+ {$ifdef combinedebug}
|
|
|
+ debugmessageS({$i %file%},'combine out2 "'+relpath+'" and "'+basepath+'"',{$i %line%},'1',0,0);
|
|
|
+ {$endif}
|
|
|
+ end;
|
|
|
+
|
|
|
result:=basepath+relpath;
|
|
|
end;
|
|
|
|
|
|
-
|
|
|
-Constructor TChmWrapper.Create(name:string);
|
|
|
+Constructor TChmWrapper.Create(name:string;aid:integer;TopicLinks:PTopicLinkCollection);
|
|
|
|
|
|
begin
|
|
|
- ffs:=Classes.TFileStream.create(name,fmOpenRead);
|
|
|
+ ffs:=Classes.TFileStream.create(name,fmOpenRead or fmsharedenynone);
|
|
|
fchmr:=TChmReader.Create(ffs,True); // owns ffs
|
|
|
findex:=nil;
|
|
|
+ FTopicLinks:=TopicLinks;
|
|
|
if not fchmr.isvalidfile then
|
|
|
begin
|
|
|
freeandnil(fchmr);
|
|
|
freeandnil(ffs);
|
|
|
- exit;
|
|
|
- end;
|
|
|
+ exit;
|
|
|
+ end;
|
|
|
+ fileid:=aid;
|
|
|
+ flongname:=name;
|
|
|
+ fshortname:=lowercase(extractfilename(name)); // We assume ms-its: urls are case insensitive wrt filename.
|
|
|
+ chmindex.addobject(fshortname,self);
|
|
|
{$ifdef wdebug}
|
|
|
- debugmessageS({$i %file%},'TCHMWrapper: before sitemap creation ',{$i %line%},'1',0,0);
|
|
|
+ debugmessageS({$i %file%},'TCHMWrapper.Create: before sitemap creation '+fshortname+' id='+inttostr(aid),{$i %line%},'1',0,0);
|
|
|
{$endif}
|
|
|
findex:=TChmSiteMap.create(stindex);
|
|
|
ftopic:=TChmSiteMap.create(sttoc);
|
|
|
- {$ifdef wdebug}
|
|
|
- debugmessageS({$i %file%},'TCHMWrapper: after sitemap creation ',{$i %line%},'1',0,0);
|
|
|
- {$endif}
|
|
|
floaded:=false;
|
|
|
end;
|
|
|
|
|
@@ -97,7 +115,7 @@ begin
|
|
|
// if (length(alias)>0) and (alias[1]<>'/') then Alias:='/'+alias;
|
|
|
FormatAlias:=Alias;
|
|
|
end;
|
|
|
-
|
|
|
+
|
|
|
var
|
|
|
m : Classes.TMemoryStream;
|
|
|
i,j : integer;
|
|
@@ -105,18 +123,18 @@ var
|
|
|
tli: integer;
|
|
|
begin
|
|
|
result:=false;
|
|
|
- if not assigned (fchmr) then exit;
|
|
|
if floaded then exit;
|
|
|
+ if not assigned (fchmr) then exit;
|
|
|
{$ifdef wdebug}
|
|
|
- debugmessageS({$i %file%},'TCHMWrapper: indexfilename:'+fchmr.indexfile,{$i %line%},'1',0,0);
|
|
|
+ debugmessageS({$i %file%},'TCHMWrapper: indexfilename:'+fchmr.indexfile,{$i %line%},'1',0,0);
|
|
|
{$endif}
|
|
|
-
|
|
|
+
|
|
|
m:=fchmr.getobject(fchmr.indexfile);
|
|
|
try
|
|
|
if assigned(m) then
|
|
|
begin
|
|
|
{$ifdef wdebug}
|
|
|
- debugmessageS({$i %file%},'TCHMWrapper: stream size loaded :'+inttostr(m.size),{$i %line%},'1',0,0);
|
|
|
+ debugmessageS({$i %file%},'TCHMWrapper: stream size loaded :'+inttostr(m.size),{$i %line%},'1',0,0);
|
|
|
{$endif}
|
|
|
findex.loadfromStream(m);
|
|
|
end;
|
|
@@ -124,21 +142,21 @@ begin
|
|
|
freeandnil(m);
|
|
|
end;
|
|
|
{$ifdef wdebug}
|
|
|
- debugmessageS({$i %file%},'TCHMWrapper: loadindex after final ',{$i %line%},'1',0,0);
|
|
|
+ debugmessageS({$i %file%},'TCHMWrapper: loadindex after final ',{$i %line%},'1',0,0);
|
|
|
{$endif}
|
|
|
-
|
|
|
- tli:=TopicLinks^.AddItem(fchmr.defaultpage);
|
|
|
+
|
|
|
+ tli:=TopicLinks^.AddItem(fchmr.defaultpage);
|
|
|
TLI:=EncodeHTMLCtx(ID,TLI+1);
|
|
|
IndexEntries^.Insert(NewIndexEntry( FormatAlias('Table of contents'),ID,TLI));
|
|
|
for i:=0 to findex.items.count-1 do
|
|
|
begin
|
|
|
item:=findex.items.item[i];
|
|
|
- tli:=TopicLinks^.AddItem('/'+item.local);
|
|
|
+ tli:=TopicLinks^.AddItem('/'+item.local);
|
|
|
TLI:=EncodeHTMLCtx(ID,TLI+1);
|
|
|
IndexEntries^.Insert(NewIndexEntry( FormatAlias(item.text),ID,TLI));
|
|
|
end;
|
|
|
{$ifdef wdebug}
|
|
|
- debugmessageS({$i %file%},'TCHMWrapper: endloadindex ',{$i %line%},'1',0,0);
|
|
|
+ debugmessageS({$i %file%},'TCHMWrapper: endloadindex ',{$i %line%},'1',0,0);
|
|
|
{$endif}
|
|
|
floaded:=true;
|
|
|
result:=true;
|
|
@@ -161,7 +179,7 @@ begin
|
|
|
if (s[i]=' ') and not inquote then lastpoint:=i;
|
|
|
if (s[i]='"') then inquote:=not inquote;
|
|
|
inc(i);
|
|
|
- end;
|
|
|
+ end;
|
|
|
scanvalue:=lastpoint;
|
|
|
end;
|
|
|
|
|
@@ -191,19 +209,19 @@ var
|
|
|
begin
|
|
|
result:=nil;
|
|
|
if not assigned(fchmr) or (name='') then exit;
|
|
|
-
|
|
|
+
|
|
|
If (name[1]<>'/') and (copy(name,1,7)<>'ms-its:') Then
|
|
|
name:='/'+name;
|
|
|
linedata:=Classes.TStringList.create;
|
|
|
try
|
|
|
{$ifdef wdebug}
|
|
|
- debugmessageS({$i %file%},'TCHMWrapper: Getting file '+name,{$i %line%},'1',0,0);
|
|
|
+ debugmessageS({$i %file%},'TCHMWrapper: Getting file '+name,{$i %line%},'1',0,0);
|
|
|
{$endif}
|
|
|
// if uppercase(name)='TABLE OF CONTENTS' Then
|
|
|
// m:=fchmr.getobject(fchmr.tocfile)
|
|
|
// else
|
|
|
m:=fchmr.getobject(name);
|
|
|
-
|
|
|
+
|
|
|
if not assigned(m) then exit;
|
|
|
linedata.loadfromstream(m);
|
|
|
result:=new(PMemoryTextFile,Init);
|
|
@@ -220,15 +238,70 @@ begin
|
|
|
end;
|
|
|
end;
|
|
|
|
|
|
-
|
|
|
destructor TChmWrapper.Destroy;
|
|
|
|
|
|
+var i : integer;
|
|
|
begin
|
|
|
+ i:=chmindex.indexof(fshortname);
|
|
|
+ if i<>-1 then
|
|
|
+ begin
|
|
|
+ chmindex.delete(i);
|
|
|
+ {$ifdef wdebug}
|
|
|
+ debugmessageS({$i %file%},'TCHMWrapper: deregistering '+fshortname,{$i %line%},'1',0,0);
|
|
|
+ {$endif}
|
|
|
+ end;
|
|
|
freeandnil(ftopic);
|
|
|
freeandnil(findex);
|
|
|
freeandnil(fchmr);
|
|
|
+ {$ifdef wdebug}
|
|
|
+ debugmessageS({$i %file%},'TCHMWrapper: destroying ',{$i %line%},'1',0,0);
|
|
|
+ {$endif}
|
|
|
+
|
|
|
end;
|
|
|
-// m:=r.getobject(r.indexfile);
|
|
|
-// siteindex.loadfromStream(m);
|
|
|
|
|
|
-end.
|
|
|
+function CHMResolve( href: ansistring; var AFileId,ALinkId : longint):boolean;
|
|
|
+
|
|
|
+var filename, restlink : ansistring;
|
|
|
+ I :integer;
|
|
|
+ chmw: TCHMWrapper;
|
|
|
+begin
|
|
|
+ result:=false;
|
|
|
+ if copy(href,1,7)='ms-its:' then
|
|
|
+ begin
|
|
|
+ {$ifdef wdebug}
|
|
|
+ debugmessageS({$i %file%},'TCHMWrapper: resolving '+href,{$i %line%},'1',0,0);
|
|
|
+ {$endif}
|
|
|
+
|
|
|
+ delete(href,1,7);
|
|
|
+ i:=pos('::',href);
|
|
|
+ if i<>0 then
|
|
|
+ begin
|
|
|
+ filename:=lowercase(copy(href,1,i-1));
|
|
|
+ restlink:=lowercase(copy(href,i+2,length(href)-(I+2)+1));
|
|
|
+ i:=chmindex.indexof(filename);
|
|
|
+ if i<>-1 then
|
|
|
+ begin
|
|
|
+ {$ifdef wdebug}
|
|
|
+ debugmessageS({$i %file%},'TCHMWrapper: resolving '+filename+' '+inttostr(i),{$i %line%},'1',0,0);
|
|
|
+ debugmessageS({$i %file%},'TCHMWrapper: resolving '+restlink+' ',{$i %line%},'1',0,0);
|
|
|
+ {$endif}
|
|
|
+ chmw:=TCHMWrapper(chmindex.objects[i]);
|
|
|
+ Afileid:=chmw.fileid;
|
|
|
+ alinkid:=chmw.fTopicLinks.additem(restlink);
|
|
|
+ result:=true;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ end
|
|
|
+end;
|
|
|
+
|
|
|
+function stringreplace(const s:ansistring;const oldstr:ansistring; const newstr:ansistring):ansistring;
|
|
|
+
|
|
|
+begin
|
|
|
+ result:=sysutils.stringreplace(s,oldstr,newstr,[rfreplaceall]);
|
|
|
+end;
|
|
|
+initialization
|
|
|
+ ChmIndex:=TStringlist.create;
|
|
|
+ ChmIndex.sorted:=true;
|
|
|
+finalization
|
|
|
+ ChmIndex.Free;
|
|
|
+end.
|