whtmlscn.pas 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636
  1. {
  2. $Id$
  3. This file is part of the Free Pascal Integrated Development Environment
  4. Copyright (c) 2000 by Berczi Gabor
  5. HTML scanner objects
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. unit WHTMLScn;
  13. interface
  14. uses Objects,
  15. WHTML;
  16. const
  17. HTMLIndexMagicNo = ord('H')+ord('H') shl 8+ord('I') shl 16+ord('X') shl 24;
  18. HTMLIndexVersion = 2;
  19. type
  20. PHTMLLinkScanner = ^THTMLLinkScanner;
  21. PHTMLLinkScanDocument = ^THTMLLinkScanDocument;
  22. TCustomHTMLLinkScanner = object(THTMLParser)
  23. function DocAddTextChar(C: char): boolean; virtual;
  24. procedure DocAnchor(Entered: boolean); virtual;
  25. public
  26. {a}function CheckURL(const URL: string): boolean; virtual;
  27. {a}function CheckText(const Text: string): boolean; virtual;
  28. {a}procedure AddLink(const LinkText, LinkURL: string); virtual;
  29. {a}function GetDocumentBaseURL: string; virtual;
  30. private
  31. CurLinkText: string;
  32. CurURL: string;
  33. CurDoc: string;
  34. InAnchor,InNameAnchor: boolean;
  35. LastSynonym: PHTMLLinkScanDocument;
  36. end;
  37. THTMLLinkScanDocument = object(TObject)
  38. constructor Init(const ADocName: string);
  39. function GetName: string;
  40. function GetUniqueName: string;
  41. function GetAliasCount: sw_integer;
  42. function GetAlias(Index: sw_integer): string;
  43. procedure AddAlias(const Alias: string);
  44. constructor Load(var S: TStream);
  45. procedure Store(var S: TStream);
  46. destructor Done; virtual;
  47. private
  48. DocName: PString;
  49. Synonym: PHTMLLinkScanDocument;
  50. Aliases: PStringCollection;
  51. end;
  52. PHTMLLinkScanDocumentCollection = ^THTMLLinkScanDocumentCollection;
  53. THTMLLinkScanDocumentCollection = object(TSortedCollection)
  54. constructor Init(AScanner: PHTMLLinkScanner; ALimit, ADelta: Integer);
  55. function Compare(Key1, Key2: Pointer): sw_Integer; virtual;
  56. function At(Index: sw_Integer): PHTMLLinkScanDocument;
  57. function SearchDocument(const DocName: string): PHTMLLinkScanDocument;
  58. procedure MoveAliasesToSynonym;
  59. private
  60. Scanner: PHTMLLinkScanner;
  61. end;
  62. THTMLLinkScanner = object(TCustomHTMLLinkScanner)
  63. constructor Init(const ABaseDir: string);
  64. procedure SetBaseDir(const ABaseDir: string);
  65. function GetDocumentCount: sw_integer;
  66. function GetDocumentURL(DocIndex: sw_integer): string;
  67. function GetUniqueDocumentURL(DocIndex: sw_integer): string;
  68. function GetDocumentAliasCount(DocIndex: sw_integer): sw_integer;
  69. function GetDocumentAlias(DocIndex, AliasIndex: sw_integer): string;
  70. constructor LoadDocuments(var S: TStream);
  71. procedure StoreDocuments(var S: TStream);
  72. destructor Done; virtual;
  73. public
  74. procedure AddLink(const LinkText, LinkURL: string); virtual;
  75. private
  76. Documents: PHTMLLinkScanDocumentCollection;
  77. BaseDir: PString;
  78. function ExpandChildURL(const S: string): string;
  79. function NormalizeChildURL(const S: string): string;
  80. end;
  81. THTMLLinkScanState = (ssScheduled,ssProcessing,ssScanned);
  82. PHTMLLinkScanFile = ^THTMLLinkScanFile;
  83. THTMLLinkScanFile = object(TObject)
  84. constructor Init(const ADocumentURL: string);
  85. function GetDocumentURL: string;
  86. destructor Done; virtual;
  87. private
  88. DocumentURL : PString;
  89. public
  90. State : THTMLLinkScanState;
  91. end;
  92. PHTMLLinkScanFileCollection = ^THTMLLinkScanFileCollection;
  93. THTMLLinkScanFileCollection = object(TSortedCollection)
  94. function At(Index: sw_Integer): PHTMLLinkScanFile;
  95. function Compare(Key1, Key2: Pointer): sw_Integer; virtual;
  96. function SearchFile(const DocURL: string): PHTMLLinkScanFile;
  97. function FindFileWithState(AState: THTMLLinkScanState): PHTMLLinkScanFile;
  98. end;
  99. THTMLLinkScanOption = (soSubDocsOnly);
  100. THTMLLinkScanOptions = set of THTMLLinkScanOption;
  101. THTMLFileLinkScanner = object(THTMLLinkScanner)
  102. constructor Init(const ABaseDir: string);
  103. procedure ProcessDocument(const DocumentURL: string; AOptions: THTMLLinkScanOptions);
  104. destructor Done; virtual;
  105. public
  106. function GetDocumentBaseURL: string; virtual;
  107. procedure AddLink(const LinkText, LinkURL: string); virtual;
  108. function CheckURL(const URL: string): boolean; virtual;
  109. private
  110. Options: THTMLLinkScanOptions;
  111. BaseURL: string;
  112. CurBaseURL: string;
  113. DocumentFiles: PHTMLLinkScanFileCollection;
  114. procedure ScheduleDoc(const DocumentURL: string);
  115. public
  116. procedure ProcessDoc(Doc: PHTMLLinkScanFile); virtual;
  117. end;
  118. procedure RegisterWHTMLScan;
  119. implementation
  120. uses WUtils;
  121. const
  122. RHTMLLinkScanDocument: TStreamRec = (
  123. ObjType: 19500;
  124. VmtLink: Ofs(TypeOf(THTMLLinkScanDocument)^);
  125. Load: @THTMLLinkScanDocument.Load;
  126. Store: @THTMLLinkScanDocument.Store
  127. );
  128. const
  129. CurrentHTMLIndexVersion : sw_integer = HTMLIndexVersion;
  130. function TCustomHTMLLinkScanner.DocAddTextChar(C: char): boolean;
  131. var Added: boolean;
  132. begin
  133. Added:=false;
  134. if InAnchor then
  135. begin
  136. CurLinkText:=CurLinkText+C;
  137. Added:=true;
  138. end;
  139. if ord(c)>32 then
  140. LastSynonym:=nil;
  141. DocAddTextChar:=Added;
  142. end;
  143. procedure TCustomHTMLLinkScanner.DocAnchor(Entered: boolean);
  144. begin
  145. if Entered then
  146. begin
  147. CurLinkText:='';
  148. if DocGetTagParam('HREF',CurURL)=false then
  149. if DocGetTagParam('NAME',CurURL) then
  150. begin
  151. InNameAnchor:=true;
  152. If Pos('#',CurURL)=0 then
  153. CurURL:=CurDoc+'#'+CurURL;
  154. end
  155. else
  156. CurURL:='';
  157. CurURL:=Trim(CurURL);
  158. CurURL:=CompleteURL(GetDocumentBaseURL,CurURL);
  159. end
  160. else
  161. begin
  162. CurLinkText:=Trim(CurLinkText);
  163. if CheckURL(CurURL) and CheckText(CurLinkText) or InNameAnchor then
  164. AddLink(CurLinkText,CurURL);
  165. InNameAnchor:=false;
  166. end;
  167. InAnchor:=Entered;
  168. end;
  169. function TCustomHTMLLinkScanner.GetDocumentBaseURL: string;
  170. begin
  171. { Abstract }
  172. GetDocumentBaseURL:='';
  173. end;
  174. function TCustomHTMLLinkScanner.CheckURL(const URL: string): boolean;
  175. begin
  176. { Abstract }
  177. CheckURL:=true;
  178. end;
  179. function TCustomHTMLLinkScanner.CheckText(const Text: string): boolean;
  180. begin
  181. { Abstract }
  182. CheckText:=true;
  183. end;
  184. procedure TCustomHTMLLinkScanner.AddLink(const LinkText, LinkURL: string);
  185. begin
  186. { Abstract }
  187. end;
  188. constructor THTMLLinkScanDocument.Init(const ADocName: string);
  189. begin
  190. inherited Init;
  191. SetStr(DocName,ADocName);
  192. New(Aliases, Init(10,10));
  193. Synonym:=nil;
  194. end;
  195. function THTMLLinkScanDocument.GetName: string;
  196. begin
  197. GetName:=GetStr(DocName);
  198. end;
  199. function THTMLLinkScanDocument.GetUniqueName: string;
  200. var
  201. PD: PHTMLLinkScanDocument;
  202. begin
  203. PD:=@Self;
  204. while assigned(PD^.synonym) do
  205. PD:=PD^.Synonym;
  206. GetUniqueName:=GetStr(PD^.DocName);
  207. end;
  208. function THTMLLinkScanDocument.GetAliasCount: sw_integer;
  209. begin
  210. GetAliasCount:=Aliases^.Count;
  211. end;
  212. function THTMLLinkScanDocument.GetAlias(Index: sw_integer): string;
  213. begin
  214. GetAlias:=GetStr(Aliases^.At(Index));
  215. end;
  216. procedure THTMLLinkScanDocument.AddAlias(const Alias: string);
  217. begin
  218. Aliases^.Insert(NewStr(Alias));
  219. end;
  220. constructor THTMLLinkScanDocument.Load(var S: TStream);
  221. var
  222. i: sw_integer;
  223. begin
  224. inherited Init;
  225. DocName:=S.ReadStr;
  226. if assigned(DocName) then
  227. for i:=1 to Length(DocName^) do
  228. if (DocName^[i]='\') or (DocName^[i]='/') then
  229. DocName^[i]:=DirSep;
  230. New(Aliases, Load(S));
  231. end;
  232. procedure THTMLLinkScanDocument.Store(var S: TStream);
  233. begin
  234. S.WriteStr(DocName);
  235. Aliases^.Store(S);
  236. end;
  237. destructor THTMLLinkScanDocument.Done;
  238. begin
  239. inherited Done;
  240. if Assigned(Aliases) then Dispose(Aliases, Done); Aliases:=nil;
  241. if Assigned(DocName) then DisposeStr(DocName); DocName:=nil;
  242. end;
  243. constructor THTMLLinkScanDocumentCollection.Init(AScanner: PHTMLLinkScanner; ALimit, ADelta: Integer);
  244. begin
  245. inherited Init(ALimit,ADelta);
  246. Scanner:=AScanner;
  247. end;
  248. function THTMLLinkScanDocumentCollection.Compare(Key1, Key2: Pointer): sw_Integer;
  249. var R: sw_integer;
  250. K1: PHTMLLinkScanDocument absolute Key1;
  251. K2: PHTMLLinkScanDocument absolute Key2;
  252. S1,S2: string;
  253. begin
  254. S1:=K1^.GetName; S2:=K2^.GetName;
  255. if Assigned(Scanner) then
  256. begin S1:=Scanner^.ExpandChildURL(S1); S2:=Scanner^.ExpandChildURL(S2); end;
  257. S1:=UpcaseStr(S1); S2:=UpcaseStr(S2);
  258. if S1<S2 then R:=-1 else
  259. if S1>S2 then R:= 1 else
  260. R:=0;
  261. Compare:=R;
  262. end;
  263. function THTMLLinkScanDocumentCollection.At(Index: sw_Integer): PHTMLLinkScanDocument;
  264. begin
  265. At:=inherited At(Index);
  266. end;
  267. function THTMLLinkScanDocumentCollection.SearchDocument(const DocName: string): PHTMLLinkScanDocument;
  268. var D,P: PHTMLLinkScanDocument;
  269. Index: sw_integer;
  270. begin
  271. New(D, Init(DocName));
  272. if Search(D, Index)=false then P:=nil else
  273. P:=At(Index);
  274. Dispose(D, Done);
  275. SearchDocument:=P;
  276. end;
  277. procedure THTMLLinkScanDocumentCollection.MoveAliasesToSynonym;
  278. procedure MoveAliases(P: PHTMLLinkScanDocument);
  279. var
  280. PD: PHTMLLinkScanDocument;
  281. i: sw_integer;
  282. begin
  283. if not assigned(P^.synonym) then
  284. exit;
  285. PD:=P;
  286. while assigned(PD^.synonym) do
  287. PD:=PD^.Synonym;
  288. For i:=P^.GetAliasCount-1 downto 0 do
  289. begin
  290. PD^.AddAlias(P^.GetAlias(i));
  291. P^.Aliases^.AtFree(i);
  292. end;
  293. end;
  294. begin
  295. ForEach(@MoveAliases);
  296. end;
  297. constructor THTMLLinkScanner.Init(const ABaseDir: string);
  298. begin
  299. inherited Init;
  300. New(Documents, Init(@Self,50,100));
  301. SetBaseDir(ABaseDir);
  302. end;
  303. procedure THTMLLinkScanner.SetBaseDir(const ABaseDir: string);
  304. begin
  305. if Assigned(BaseDir) then DisposeStr(BaseDir);
  306. BaseDir:=NewStr(CompleteDir(ABaseDir));
  307. end;
  308. function THTMLLinkScanner.GetDocumentCount: sw_integer;
  309. begin
  310. GetDocumentCount:=Documents^.Count;
  311. end;
  312. function THTMLLinkScanner.ExpandChildURL(const S: string): string;
  313. begin
  314. ExpandChildURL:=CompleteURL(GetStr(BaseDir),S);
  315. end;
  316. function THTMLLinkScanner.NormalizeChildURL(const S: string): string;
  317. var URL: string;
  318. begin
  319. URL:=S;
  320. if GetStr(BaseDir)<>'' then
  321. if copy(UpcaseStr(S),1,length(GetStr(BaseDir)))=UpcaseStr(GetStr(BaseDir)) then
  322. URL:=copy(S,length(GetStr(BaseDir))+1,length(S));
  323. NormalizeChildURL:=URL;
  324. end;
  325. function THTMLLinkScanner.GetDocumentURL(DocIndex: sw_integer): string;
  326. begin
  327. GetDocumentURL:=ExpandChildURL(Documents^.At(DocIndex)^.GetName);
  328. end;
  329. function THTMLLinkScanner.GetUniqueDocumentURL(DocIndex: sw_integer): string;
  330. begin
  331. GetUniqueDocumentURL:=ExpandChildURL(Documents^.At(DocIndex)^.GetUniqueName);
  332. end;
  333. function THTMLLinkScanner.GetDocumentAliasCount(DocIndex: sw_integer): sw_integer;
  334. begin
  335. GetDocumentAliasCount:=Documents^.At(DocIndex)^.GetAliasCount;
  336. end;
  337. function THTMLLinkScanner.GetDocumentAlias(DocIndex, AliasIndex: sw_integer): string;
  338. begin
  339. GetDocumentAlias:=Documents^.At(DocIndex)^.GetAlias(AliasIndex);
  340. end;
  341. procedure THTMLLinkScanner.AddLink(const LinkText, LinkURL: string);
  342. var D: PHTMLLinkScanDocument;
  343. DoInsert: boolean;
  344. int: sw_integer;
  345. Text: string;
  346. error: word;
  347. begin
  348. D:=Documents^.SearchDocument(LinkURL);
  349. if D=nil then
  350. begin
  351. New(D, Init(NormalizeChildURL(LinkURL)));
  352. Documents^.Insert(D);
  353. end;
  354. If assigned(LastSynonym) then
  355. LastSynonym^.Synonym:=D;
  356. DoInsert:=true;
  357. If (length(LinkText)=0) or (Pos(',',LinkText)=1) then
  358. DoInsert:=false;
  359. Val(LinkText,int,error);
  360. If (Error>1) and (LinkText[Error]=' ') then
  361. Text:=Trim(Copy(LinkText,error+1,length(LinkText)))
  362. else
  363. Text:=LinkText;
  364. IF DoInsert then
  365. D^.AddAlias(Text);
  366. If InNameAnchor then
  367. LastSynonym:=D;
  368. end;
  369. constructor THTMLLinkScanner.LoadDocuments(var S: TStream);
  370. var P,L: longint;
  371. OK: boolean;
  372. PS: PString;
  373. begin
  374. OK:=false;
  375. P:=S.GetPos;
  376. S.Read(L,sizeof(L));
  377. if (S.Status=stOK) and (L=HTMLIndexMagicNo) then
  378. begin
  379. S.Read(L,sizeof(L));
  380. CurrentHTMLIndexVersion:=L;
  381. OK:=(S.Status=stOK);
  382. end;
  383. if not OK then
  384. begin
  385. S.Reset;
  386. S.Seek(P);
  387. end
  388. else
  389. BaseDir:=S.ReadStr;
  390. New(Documents, Load(S));
  391. if not Assigned(Documents) then
  392. Fail;
  393. Documents^.MoveAliasesToSynonym;
  394. CurrentHTMLIndexVersion:=HTMLIndexVersion;
  395. end;
  396. procedure THTMLLinkScanner.StoreDocuments(var S: TStream);
  397. var L: longint;
  398. begin
  399. L:=HTMLIndexMagicNo;
  400. S.Write(L,sizeof(L));
  401. L:=HTMLIndexVersion;
  402. CurrentHTMLIndexVersion:=L;
  403. S.Write(L,sizeof(L));
  404. S.WriteStr(BaseDir);
  405. Documents^.MoveAliasesToSynonym;
  406. Documents^.Store(S);
  407. end;
  408. destructor THTMLLinkScanner.Done;
  409. begin
  410. inherited Done;
  411. if Assigned(Documents) then Dispose(Documents, Done); Documents:=nil;
  412. if Assigned(BaseDir) then DisposeStr(BaseDir); BaseDir:=nil;
  413. end;
  414. constructor THTMLLinkScanFile.Init(const ADocumentURL: string);
  415. begin
  416. inherited Init;
  417. SetStr(DocumentURL,ADocumentURL);
  418. end;
  419. function THTMLLinkScanFile.GetDocumentURL: string;
  420. begin
  421. GetDocumentURL:=GetStr(DocumentURL);
  422. end;
  423. destructor THTMLLinkScanFile.Done;
  424. begin
  425. inherited Done;
  426. if Assigned(DocumentURL) then DisposeStr(DocumentURL); DocumentURL:=nil;
  427. end;
  428. function THTMLLinkScanFileCollection.At(Index: sw_Integer): PHTMLLinkScanFile;
  429. begin
  430. At:=inherited At(Index);
  431. end;
  432. function THTMLLinkScanFileCollection.Compare(Key1, Key2: Pointer): sw_Integer;
  433. var R: integer;
  434. K1: PHTMLLinkScanFile absolute Key1;
  435. K2: PHTMLLinkScanFile absolute Key2;
  436. S1,S2: string;
  437. begin
  438. S1:=UpcaseStr(K1^.GetDocumentURL); S2:=UpcaseStr(K2^.GetDocumentURL);
  439. if S1<S2 then R:=-1 else
  440. if S1>S2 then R:= 1 else
  441. R:=0;
  442. Compare:=R;
  443. end;
  444. function THTMLLinkScanFileCollection.SearchFile(const DocURL: string): PHTMLLinkScanFile;
  445. var P,D: PHTMLLinkScanFile;
  446. Index: sw_integer;
  447. begin
  448. New(D, Init(DocURL));
  449. if Search(D,Index)=false then P:=nil else
  450. P:=At(Index);
  451. Dispose(D, Done);
  452. SearchFile:=P;
  453. end;
  454. function THTMLLinkScanFileCollection.FindFileWithState(AState: THTMLLinkScanState): PHTMLLinkScanFile;
  455. var I: sw_integer;
  456. P,D: PHTMLLinkScanFile;
  457. begin
  458. P:=nil;
  459. for I:=0 to Count-1 do
  460. begin
  461. D:=At(I);
  462. if D^.State=AState then
  463. begin
  464. P:=D;
  465. Break;
  466. end;
  467. end;
  468. FindFileWithState:=P;
  469. end;
  470. constructor THTMLFileLinkScanner.Init(const ABaseDir: string);
  471. begin
  472. inherited Init(ABaseDir);
  473. New(DocumentFiles, Init(50,100));
  474. end;
  475. procedure THTMLFileLinkScanner.ProcessDocument(const DocumentURL: string; AOptions: THTMLLinkScanOptions);
  476. var P: PHTMLLinkScanFile;
  477. begin
  478. CurBaseURL:=''; Options:=AOptions;
  479. ScheduleDoc(DocumentURL);
  480. repeat
  481. P:=DocumentFiles^.FindFileWithState(ssScheduled);
  482. if Assigned(P) then
  483. ProcessDoc(P);
  484. until P=nil;
  485. end;
  486. function THTMLFileLinkScanner.GetDocumentBaseURL: string;
  487. begin
  488. GetDocumentBaseURL:=CurBaseURL;
  489. end;
  490. function THTMLFileLinkScanner.CheckURL(const URL: string): boolean;
  491. var OK: boolean;
  492. begin
  493. if soSubDocsOnly in Options then
  494. OK:=UpcaseStr(copy(URL,1,length(BaseURL)))=UpcaseStr(BaseURL)
  495. else
  496. OK:=true;
  497. CheckURL:=OK;
  498. end;
  499. procedure THTMLFileLinkScanner.AddLink(const LinkText, LinkURL: string);
  500. var D: PHTMLLinkScanFile;
  501. P: sw_integer;
  502. DocURL: string;
  503. begin
  504. P:=Pos('#',LinkURL);
  505. if P=0 then DocURL:=LinkURL else DocURL:=copy(LinkURL,1,P-1);
  506. D:=DocumentFiles^.SearchFile(DocURL);
  507. if Assigned(D)=false then
  508. ScheduleDoc(DocURL);
  509. inherited AddLink(LinkText,LinkURL);
  510. end;
  511. procedure THTMLFileLinkScanner.ProcessDoc(Doc: PHTMLLinkScanFile);
  512. var F: PDOSTextFile;
  513. begin
  514. if Assigned(Doc)=false then Exit;
  515. Doc^.State:=ssProcessing;
  516. CurDoc:=Doc^.GetDocumentURL;
  517. New(F, Init(Doc^.GetDocumentURL));
  518. if Assigned(F) then
  519. begin
  520. CurBaseURL:=CompleteURL(Doc^.GetDocumentURL,'');
  521. Process(F);
  522. Dispose(F, Done);
  523. end;
  524. Doc^.State:=ssScanned;
  525. CurDoc:='';
  526. end;
  527. procedure THTMLFileLinkScanner.ScheduleDoc(const DocumentURL: string);
  528. var D: PHTMLLinkScanFile;
  529. begin
  530. New(D, Init(DocumentURL));
  531. D^.State:=ssScheduled;
  532. DocumentFiles^.Insert(D);
  533. end;
  534. destructor THTMLFileLinkScanner.Done;
  535. begin
  536. inherited Done;
  537. if Assigned(DocumentFiles) then Dispose(DocumentFiles, Done); DocumentFiles:=nil;
  538. end;
  539. procedure RegisterWHTMLScan;
  540. begin
  541. RegisterType(RHTMLLinkScanDocument);
  542. end;
  543. END.
  544. {
  545. $Log$
  546. Revision 1.5 2002-09-07 15:40:49 peter
  547. * old logs removed and tabs fixed
  548. Revision 1.4 2002/04/23 10:11:31 pierre
  549. * try to adapt .htx files to system DirSep
  550. Revision 1.3 2002/04/23 09:55:22 pierre
  551. + added lastsynonym and InNameAnchor fields to TCustomHTMLLinkScanner
  552. these allow to eliminate double index entries pointing to the same
  553. html file location (which had two different names).
  554. Revision 1.2 2002/04/11 07:06:31 pierre
  555. + recreate the full target of an anchor that only has a NAME field
  556. }