whtmlhlp.pas 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946
  1. {
  2. $Id$
  3. This file is part of the Free Pascal Integrated Development Environment
  4. Copyright (c) 1999-2000 by Berczi Gabor
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. unit WHTMLHlp;
  12. interface
  13. uses Objects,WHTML,WAnsi,WHelp;
  14. const
  15. extHTML = '.htm';
  16. extHTMLIndex = '.htx';
  17. ListIndent = 2;
  18. DefIndent = 4;
  19. MaxTopicLinks = 4000; { maximum number of links on a single HTML page }
  20. type
  21. THTMLSection = (hsNone,hsHeading1,hsHeading2,hsHeading3,hsHeading4,hsHeading5,hsHeading6);
  22. PTopicLinkCollection = ^TTopicLinkCollection;
  23. TTopicLinkCollection = object(TStringCollection)
  24. procedure Insert(Item: Pointer); virtual;
  25. function At(Index: sw_Integer): PString;
  26. function AddItem(Item: string): integer;
  27. end;
  28. TParagraphAlign = (paLeft,paCenter,paRight);
  29. PHTMLTopicRenderer = ^THTMLTopicRenderer;
  30. THTMLTopicRenderer = object(THTMLParser)
  31. function BuildTopic(P: PTopic; AURL: string; HTMLFile: PTextFile; ATopicLinks: PTopicLinkCollection): boolean;
  32. public
  33. function DocAddTextChar(C: char): boolean; virtual;
  34. procedure DocSoftBreak; virtual;
  35. procedure DocTYPE; virtual;
  36. procedure DocHTML(Entered: boolean); virtual;
  37. procedure DocHEAD(Entered: boolean); virtual;
  38. procedure DocMETA; virtual;
  39. procedure DocTITLE(Entered: boolean); virtual;
  40. procedure DocBODY(Entered: boolean); virtual;
  41. procedure DocAnchor(Entered: boolean); virtual;
  42. procedure DocHeading(Level: integer; Entered: boolean); virtual;
  43. procedure DocParagraph(Entered: boolean); virtual;
  44. procedure DocBreak; virtual;
  45. procedure DocImage; virtual;
  46. procedure DocBold(Entered: boolean); virtual;
  47. procedure DocCite(Entered: boolean); virtual;
  48. procedure DocCode(Entered: boolean); virtual;
  49. procedure DocEmphasized(Entered: boolean); virtual;
  50. procedure DocItalic(Entered: boolean); virtual;
  51. procedure DocKbd(Entered: boolean); virtual;
  52. procedure DocPreformatted(Entered: boolean); virtual;
  53. procedure DocSample(Entered: boolean); virtual;
  54. procedure DocStrong(Entered: boolean); virtual;
  55. procedure DocTeleType(Entered: boolean); virtual;
  56. procedure DocVariable(Entered: boolean); virtual;
  57. procedure DocList(Entered: boolean); virtual;
  58. procedure DocOrderedList(Entered: boolean); virtual;
  59. procedure DocListItem; virtual;
  60. procedure DocDefList(Entered: boolean); virtual;
  61. procedure DocDefTerm; virtual;
  62. procedure DocDefExp; virtual;
  63. procedure DocTable(Entered: boolean); virtual;
  64. procedure DocTableRow(Entered: boolean); virtual;
  65. procedure DocTableItem(Entered: boolean); virtual;
  66. procedure DocHorizontalRuler; virtual;
  67. public
  68. function GetSectionColor(Section: THTMLSection; var Color: byte): boolean; virtual;
  69. private
  70. URL: string;
  71. Topic: PTopic;
  72. TopicLinks: PTopicLinkCollection;
  73. TextPtr: sw_word;
  74. InTitle: boolean;
  75. InBody: boolean;
  76. InAnchor: boolean;
  77. InParagraph: boolean;
  78. InPreformatted: boolean;
  79. TopicTitle: string;
  80. Indent: integer;
  81. AnyCharsInLine: boolean;
  82. CurHeadLevel: integer;
  83. PAlign: TParagraphAlign;
  84. LinkIndexes: array[0..MaxTopicLinks] of sw_integer;
  85. LinkPtr: sw_integer;
  86. LastTextChar: char;
  87. { Anchor: TAnchor;}
  88. procedure AddText(S: string);
  89. procedure AddChar(C: char);
  90. end;
  91. PCustomHTMLHelpFile = ^TCustomHTMLHelpFile;
  92. TCustomHTMLHelpFile = object(THelpFile)
  93. constructor Init(AID: word);
  94. destructor Done; virtual;
  95. public
  96. function SearchTopic(HelpCtx: THelpCtx): PTopic; virtual;
  97. function ReadTopic(T: PTopic): boolean; virtual;
  98. private
  99. Renderer: PHTMLTopicRenderer;
  100. DefaultFileName: string;
  101. CurFileName: string;
  102. TopicLinks: PTopicLinkCollection;
  103. end;
  104. PHTMLHelpFile = ^THTMLHelpFile;
  105. THTMLHelpFile = object(TCustomHTMLHelpFile)
  106. constructor Init(AFileName: string; AID: word; ATOCEntry: string);
  107. public
  108. function LoadIndex: boolean; virtual;
  109. private
  110. TOCEntry: string;
  111. end;
  112. PHTMLIndexHelpFile = ^THTMLIndexHelpFile;
  113. THTMLIndexHelpFile = object(TCustomHTMLHelpFile)
  114. constructor Init(AFileName: string; AID: word);
  115. function LoadIndex: boolean; virtual;
  116. private
  117. IndexFileName: string;
  118. end;
  119. PHTMLAnsiView = ^THTMLAnsiView;
  120. PHTMLAnsiConsole = ^THTMLAnsiConsole;
  121. THTMLAnsiConsole = Object(TAnsiViewConsole)
  122. MaxX,MaxY : integer;
  123. procedure GotoXY(X,Y: integer); virtual;
  124. end;
  125. THTMLAnsiView = Object(TAnsiView)
  126. private
  127. HTMLOwner : PHTMLTopicRenderer;
  128. HTMLConsole : PHTMLAnsiConsole;
  129. public
  130. constructor Init(AOwner: PHTMLTopicRenderer);
  131. procedure CopyToHTML;
  132. end;
  133. THTMLGetSectionColorProc = function(Section: THTMLSection; var Color: byte): boolean;
  134. function DefHTMLGetSectionColor(Section: THTMLSection; var Color: byte): boolean;
  135. const HTMLGetSectionColor : THTMLGetSectionColorProc = {$ifdef fpc}@{$endif}DefHTMLGetSectionColor;
  136. procedure RegisterHelpType;
  137. implementation
  138. uses Views,WConsts,WUtils,WViews,WHTMLScn;
  139. { THTMLAnsiConsole methods }
  140. procedure THTMLAnsiConsole.GotoXY(X,Y : integer);
  141. begin
  142. if X>MaxX then MaxX:=X;
  143. if Y>MaxY then MaxY:=Y;
  144. inherited GotoXY(X,Y);
  145. end;
  146. { THTMLAnsiView methods }
  147. constructor THTMLAnsiView.Init(AOwner : PHTMLTopicRenderer);
  148. var
  149. R : TRect;
  150. begin
  151. if not assigned(AOwner) then
  152. fail;
  153. R.Assign(0,0,80,25);
  154. inherited init(R,nil,nil);
  155. HTMLOwner:=AOwner;
  156. HTMLConsole:=New(PHTMLAnsiConsole,Init(@Self));
  157. Dispose(Console,Done);
  158. Console:=HTMLConsole;
  159. HTMLConsole^.Size.X:=80;
  160. HTMLConsole^.Size.Y:=25;
  161. HTMLConsole^.ClrScr;
  162. HTMLConsole^.MaxX:=-1;
  163. HTMLConsole^.MaxY:=-1;
  164. HTMLConsole^.BoundChecks:=0;
  165. end;
  166. procedure THTMLAnsiView.CopyToHTML;
  167. var
  168. Attr,NewAttr : byte;
  169. X,Y,Pos : longint;
  170. begin
  171. Attr:=(Buffer^[1] shr 8);
  172. HTMLOwner^.AddChar(hscLineBreak);
  173. HTMLOwner^.AddText(hscTextAttr+chr(Attr));
  174. for Y:=0 to HTMLConsole^.MaxY-1 do
  175. begin
  176. for X:=1 to HTMLConsole^.MaxX-1 do
  177. begin
  178. Pos:=(Delta.Y*MaxViewWidth)+X+Y*MaxViewWidth;
  179. NewAttr:=(Buffer^[Pos] shr 8);
  180. if NewAttr <> Attr then
  181. begin
  182. Attr:=NewAttr;
  183. HTMLOwner^.AddText(hscTextAttr+chr(Attr));
  184. end;
  185. HTMLOwner^.AddChar(chr(Buffer^[Pos] and $ff));
  186. end;
  187. HTMLOwner^.AddChar(hscLineBreak);
  188. end;
  189. end;
  190. function DefHTMLGetSectionColor(Section: THTMLSection; var Color: byte): boolean;
  191. begin
  192. Color:=0;
  193. DefHTMLGetSectionColor:=false;
  194. end;
  195. function EncodeHTMLCtx(FileID: integer; LinkNo: word): longint;
  196. var Ctx: longint;
  197. begin
  198. Ctx:=(longint(FileID) shl 16)+LinkNo;
  199. EncodeHTMLCtx:=Ctx;
  200. end;
  201. procedure DecodeHTMLCtx(Ctx: longint; var FileID: word; var LinkNo: word);
  202. begin
  203. if (Ctx shr 16)=0 then
  204. begin
  205. FileID:=$ffff; LinkNo:=0;
  206. end
  207. else
  208. begin
  209. FileID:=Ctx shr 16; LinkNo:=Ctx and $ffff;
  210. end;
  211. end;
  212. function CharStr(C: char; Count: byte): string;
  213. var S: string;
  214. begin
  215. S[0]:=chr(Count);
  216. if Count>0 then FillChar(S[1],Count,C);
  217. CharStr:=S;
  218. end;
  219. procedure TTopicLinkCollection.Insert(Item: Pointer);
  220. begin
  221. AtInsert(Count,Item);
  222. end;
  223. function TTopicLinkCollection.At(Index: sw_Integer): PString;
  224. begin
  225. At:=inherited At(Index);
  226. end;
  227. function TTopicLinkCollection.AddItem(Item: string): integer;
  228. var Idx: sw_integer;
  229. begin
  230. if Item='' then Idx:=-1 else
  231. if Search(@Item,Idx)=false then
  232. begin
  233. AtInsert(Count,NewStr(Item));
  234. Idx:=Count-1;
  235. end;
  236. AddItem:=Idx;
  237. end;
  238. function THTMLTopicRenderer.DocAddTextChar(C: char): boolean;
  239. var Added: boolean;
  240. begin
  241. Added:=false;
  242. if InTitle then
  243. begin
  244. TopicTitle:=TopicTitle+C;
  245. Added:=true;
  246. end
  247. else
  248. if InBody then
  249. begin
  250. if (InPreFormatted) or (C<>#32) or (LastTextChar<>C) then
  251. if (C<>#32) or (AnyCharsInLine=true) or (InPreFormatted=true) then
  252. begin
  253. AddChar(C);
  254. LastTextChar:=C;
  255. Added:=true;
  256. end;
  257. end;
  258. DocAddTextChar:=Added;
  259. end;
  260. procedure THTMLTopicRenderer.DocSoftBreak;
  261. begin
  262. if InPreformatted then DocBreak else
  263. if AnyCharsInLine then
  264. begin
  265. AddChar(' ');
  266. LastTextChar:=' ';
  267. end;
  268. end;
  269. procedure THTMLTopicRenderer.DocTYPE;
  270. begin
  271. end;
  272. procedure THTMLTopicRenderer.DocHTML(Entered: boolean);
  273. begin
  274. end;
  275. procedure THTMLTopicRenderer.DocHEAD(Entered: boolean);
  276. begin
  277. end;
  278. procedure THTMLTopicRenderer.DocMETA;
  279. begin
  280. end;
  281. procedure THTMLTopicRenderer.DocTITLE(Entered: boolean);
  282. begin
  283. if Entered then
  284. begin
  285. TopicTitle:='';
  286. end
  287. else
  288. begin
  289. { render topic title here }
  290. if TopicTitle<>'' then
  291. begin
  292. AddText(' '+TopicTitle+' Ü'); DocBreak;
  293. AddText(' '+CharStr('ß',length(TopicTitle)+3)); DocBreak;
  294. end;
  295. end;
  296. InTitle:=Entered;
  297. end;
  298. procedure THTMLTopicRenderer.DocBODY(Entered: boolean);
  299. begin
  300. InBody:=Entered;
  301. end;
  302. procedure THTMLTopicRenderer.DocAnchor(Entered: boolean);
  303. var HRef,Name: string;
  304. begin
  305. if Entered and InAnchor then DocAnchor(false);
  306. if Entered then
  307. begin
  308. if DocGetTagParam('HREF',HRef)=false then HRef:='';
  309. if DocGetTagParam('NAME',Name)=false then Name:='';
  310. if Name<>'' then
  311. begin
  312. Topic^.NamedMarks^.InsertStr(Name);
  313. AddChar(hscNamedMark);
  314. end;
  315. if (HRef<>'') then
  316. begin
  317. InAnchor:=true;
  318. AddChar(hscLink);
  319. if LinkPtr<MaxTopicLinks then
  320. begin
  321. HRef:=CompleteURL(URL,HRef);
  322. LinkIndexes[LinkPtr]:=TopicLinks^.AddItem(HRef);
  323. Inc(LinkPtr);
  324. end;
  325. end;
  326. end
  327. else
  328. begin
  329. if InAnchor=true then AddChar(hscLink);
  330. InAnchor:=false;
  331. end;
  332. end;
  333. procedure DecodeAlign(Align: string; var PAlign: TParagraphAlign);
  334. begin
  335. Align:=UpcaseStr(Align);
  336. if Align='LEFT' then PAlign:=paLeft else
  337. if Align='CENTER' then PAlign:=paCenter else
  338. if Align='RIGHT' then PAlign:=paRight;
  339. end;
  340. procedure THTMLTopicRenderer.DocHeading(Level: integer; Entered: boolean);
  341. var Align: string;
  342. C: byte;
  343. SC: THTMLSection;
  344. begin
  345. if Entered then
  346. begin
  347. DocBreak;
  348. CurHeadLevel:=Level;
  349. PAlign:=paLeft;
  350. if DocGetTagParam('ALIGN',Align) then
  351. DecodeAlign(Align,PAlign);
  352. SC:=hsNone;
  353. case Level of
  354. 1: SC:=hsHeading1;
  355. 2: SC:=hsHeading2;
  356. 3: SC:=hsHeading3;
  357. 4: SC:=hsHeading4;
  358. 5: SC:=hsHeading5;
  359. 6: SC:=hsHeading6;
  360. end;
  361. if GetSectionColor(SC,C) then
  362. AddText(hscTextAttr+chr(C));
  363. end
  364. else
  365. begin
  366. AddChar(hscNormText);
  367. CurHeadLevel:=0;
  368. DocBreak;
  369. end;
  370. end;
  371. procedure THTMLTopicRenderer.DocParagraph(Entered: boolean);
  372. var Align: string;
  373. begin
  374. if Entered and InParagraph then DocParagraph(false);
  375. if Entered then
  376. begin
  377. if AnyCharsInLine then DocBreak;
  378. if DocGetTagParam('ALIGN',Align) then
  379. DecodeAlign(Align,PAlign);
  380. end
  381. else
  382. begin
  383. { if AnyCharsInLine then }DocBreak;
  384. PAlign:=paLeft;
  385. end;
  386. InParagraph:=Entered;
  387. end;
  388. procedure THTMLTopicRenderer.DocBreak;
  389. begin
  390. if (CurHeadLevel=1) or (PAlign=paCenter) then
  391. AddChar(hscCenter);
  392. if (PAlign=paRight) then
  393. AddChar(hscRight);
  394. AddChar(hscLineBreak);
  395. if Indent>0 then
  396. AddText(CharStr(#255,Indent)+hscLineStart);
  397. AnyCharsInLine:=false;
  398. end;
  399. procedure THTMLTopicRenderer.DocImage;
  400. var Src,Alt,SrcLine: string;
  401. f : text;
  402. attr : byte;
  403. PA : PHTMLAnsiView;
  404. begin
  405. if DocGetTagParam('SRC',src) then
  406. begin
  407. if src<>'' then
  408. begin
  409. src:=CompleteURL(URL,src);
  410. { this should be a image file ending by .gif or .jpg...
  411. Try to see if a file with same name and extension .git
  412. exists PM }
  413. src:=DirAndNameOf(src)+'.ans';
  414. if ExistsFile(src) then
  415. begin
  416. PA:=New(PHTMLAnsiView,init(@self));
  417. PA^.LoadFile(src);
  418. if AnyCharsInLine then DocBreak;
  419. InPreformatted:=true;
  420. {AddText('Image from '+src+hscLineBreak); }
  421. AddChar(hscInImage);
  422. PA^.CopyToHTML;
  423. InPreformatted:=false;
  424. AddChar(hscInImage);
  425. AddChar(hscNormText);
  426. if AnyCharsInLine then DocBreak;
  427. Dispose(PA,Done);
  428. Exit;
  429. end;
  430. { also look for a raw text file without colors }
  431. src:=DirAndNameOf(src)+'.txt';
  432. if ExistsFile(src) then
  433. begin
  434. Assign(f,src);
  435. Reset(f);
  436. DocPreformatted(true);
  437. while not eof(f) do
  438. begin
  439. Readln(f,SrcLine);
  440. AddText(SrcLine+hscLineBreak);
  441. end;
  442. Close(f);
  443. DocPreformatted(false);
  444. Exit;
  445. end;
  446. end;
  447. end;
  448. if DocGetTagParam('ALT',Alt)=false then
  449. begin
  450. DocGetTagParam('SRC',Alt);
  451. if Alt<>'' then
  452. Alt:='Can''t display '+Alt
  453. else
  454. Alt:='IMG';
  455. end;
  456. if Alt<>'' then
  457. begin
  458. AddText('['+Alt+']');
  459. end;
  460. end;
  461. procedure THTMLTopicRenderer.DocBold(Entered: boolean);
  462. begin
  463. end;
  464. procedure THTMLTopicRenderer.DocCite(Entered: boolean);
  465. begin
  466. end;
  467. procedure THTMLTopicRenderer.DocCode(Entered: boolean);
  468. begin
  469. if AnyCharsInLine then DocBreak;
  470. AddText(hscCode);
  471. DocBreak;
  472. end;
  473. procedure THTMLTopicRenderer.DocEmphasized(Entered: boolean);
  474. begin
  475. end;
  476. procedure THTMLTopicRenderer.DocItalic(Entered: boolean);
  477. begin
  478. end;
  479. procedure THTMLTopicRenderer.DocKbd(Entered: boolean);
  480. begin
  481. end;
  482. procedure THTMLTopicRenderer.DocPreformatted(Entered: boolean);
  483. begin
  484. if AnyCharsInLine then DocBreak;
  485. AddText(hscCode);
  486. DocBreak;
  487. InPreformatted:=Entered;
  488. end;
  489. procedure THTMLTopicRenderer.DocSample(Entered: boolean);
  490. begin
  491. end;
  492. procedure THTMLTopicRenderer.DocStrong(Entered: boolean);
  493. begin
  494. end;
  495. procedure THTMLTopicRenderer.DocTeleType(Entered: boolean);
  496. begin
  497. end;
  498. procedure THTMLTopicRenderer.DocVariable(Entered: boolean);
  499. begin
  500. end;
  501. procedure THTMLTopicRenderer.DocList(Entered: boolean);
  502. begin
  503. if Entered then
  504. begin
  505. Inc(Indent,ListIndent);
  506. DocBreak;
  507. end
  508. else
  509. begin
  510. Dec(Indent,ListIndent);
  511. if AnyCharsInLine then DocBreak;
  512. end;
  513. end;
  514. procedure THTMLTopicRenderer.DocOrderedList(Entered: boolean);
  515. begin
  516. DocList(Entered);
  517. end;
  518. procedure THTMLTopicRenderer.DocListItem;
  519. begin
  520. if AnyCharsInLine then
  521. DocBreak;
  522. AddText('þ'+hscLineStart);
  523. end;
  524. procedure THTMLTopicRenderer.DocDefList(Entered: boolean);
  525. begin
  526. if Entered then
  527. begin
  528. { if LastChar<>hscLineBreak then DocBreak;}
  529. end
  530. else
  531. begin
  532. if AnyCharsInLine then DocBreak;
  533. end;
  534. end;
  535. procedure THTMLTopicRenderer.DocDefTerm;
  536. begin
  537. DocBreak;
  538. end;
  539. procedure THTMLTopicRenderer.DocDefExp;
  540. begin
  541. Inc(Indent,DefIndent);
  542. DocBreak;
  543. Dec(Indent,DefIndent);
  544. end;
  545. procedure THTMLTopicRenderer.DocTable(Entered: boolean);
  546. begin
  547. if AnyCharsInLine then
  548. DocBreak;
  549. if Entered then
  550. DocBreak;
  551. end;
  552. procedure THTMLTopicRenderer.DocTableRow(Entered: boolean);
  553. begin
  554. if AnyCharsInLine then
  555. DocBreak;
  556. end;
  557. procedure THTMLTopicRenderer.DocTableItem(Entered: boolean);
  558. begin
  559. if Entered then
  560. AddText(' - ');
  561. end;
  562. procedure THTMLTopicRenderer.DocHorizontalRuler;
  563. var OAlign: TParagraphAlign;
  564. begin
  565. OAlign:=PAlign;
  566. if AnyCharsInLine then DocBreak;
  567. PAlign:=paCenter;
  568. DocAddText(' '+CharStr('Ä',60)+' ');
  569. DocBreak;
  570. PAlign:=OAlign;
  571. end;
  572. procedure THTMLTopicRenderer.AddChar(C: char);
  573. begin
  574. if (Topic=nil) or (TextPtr=MaxBytes) then Exit;
  575. Topic^.Text^[TextPtr]:=ord(C);
  576. Inc(TextPtr);
  577. if (C>#15) and ((C<>' ') or (InPreFormatted=true)) then
  578. AnyCharsInLine:=true;
  579. end;
  580. procedure THTMLTopicRenderer.AddText(S: string);
  581. var I: sw_integer;
  582. begin
  583. for I:=1 to length(S) do
  584. AddChar(S[I]);
  585. end;
  586. function THTMLTopicRenderer.GetSectionColor(Section: THTMLSection; var Color: byte): boolean;
  587. begin
  588. GetSectionColor:=HTMLGetSectionColor(Section,Color);
  589. end;
  590. function THTMLTopicRenderer.BuildTopic(P: PTopic; AURL: string; HTMLFile: PTextFile;
  591. ATopicLinks: PTopicLinkCollection): boolean;
  592. var OK: boolean;
  593. TP: pointer;
  594. I: sw_integer;
  595. begin
  596. URL:=AURL;
  597. Topic:=P; TopicLinks:=ATopicLinks;
  598. OK:=Assigned(Topic) and Assigned(HTMLFile) and Assigned(TopicLinks);
  599. if OK then
  600. begin
  601. if (Topic^.TextSize<>0) and Assigned(Topic^.Text) then
  602. begin
  603. FreeMem(Topic^.Text,Topic^.TextSize);
  604. Topic^.TextSize:=0; Topic^.Text:=nil;
  605. end;
  606. Topic^.TextSize:=MaxHelpTopicSize;
  607. GetMem(Topic^.Text,Topic^.TextSize);
  608. TopicTitle:='';
  609. InTitle:=false; InBody:={false}true; InAnchor:=false;
  610. InParagraph:=false; InPreformatted:=false;
  611. Indent:=0; CurHeadLevel:=0;
  612. PAlign:=paLeft;
  613. TextPtr:=0; LinkPtr:=0;
  614. AnyCharsInLine:=false;
  615. LastTextChar:=#0;
  616. OK:=Process(HTMLFile);
  617. if OK then
  618. begin
  619. { --- topic links --- }
  620. if (Topic^.Links<>nil) and (Topic^.LinkSize>0) then
  621. begin
  622. FreeMem(Topic^.Links,Topic^.LinkSize);
  623. Topic^.Links:=nil; Topic^.LinkCount:=0;
  624. end;
  625. Topic^.LinkCount:=LinkPtr{TopicLinks^.Count}; { <- eeeeeek! }
  626. GetMem(Topic^.Links,Topic^.LinkSize);
  627. if Topic^.LinkCount>0 then { FP causes numeric RTE 215 without this }
  628. for I:=0 to Min(Topic^.LinkCount-1,High(LinkIndexes)-1) do
  629. begin
  630. Topic^.Links^[I].FileID:=Topic^.FileID;
  631. Topic^.Links^[I].Context:=EncodeHTMLCtx(Topic^.FileID,LinkIndexes[I]+1);
  632. end;
  633. { --- topic text --- }
  634. GetMem(TP,TextPtr);
  635. Move(Topic^.Text^,TP^,TextPtr);
  636. FreeMem(Topic^.Text,Topic^.TextSize);
  637. Topic^.Text:=TP; Topic^.TextSize:=TextPtr;
  638. end
  639. else
  640. begin
  641. DisposeTopic(Topic);
  642. Topic:=nil;
  643. end;
  644. end;
  645. BuildTopic:=OK;
  646. end;
  647. constructor TCustomHTMLHelpFile.Init(AID: word);
  648. begin
  649. inherited Init(AID);
  650. New(Renderer, Init);
  651. New(TopicLinks, Init(50,500));
  652. end;
  653. function TCustomHTMLHelpFile.SearchTopic(HelpCtx: THelpCtx): PTopic;
  654. function MatchCtx(P: PTopic): boolean; {$ifndef FPC}far;{$endif}
  655. begin
  656. MatchCtx:=P^.HelpCtx=HelpCtx;
  657. end;
  658. var FileID,LinkNo: word;
  659. P: PTopic;
  660. FName: string;
  661. begin
  662. DecodeHTMLCtx(HelpCtx,FileID,LinkNo);
  663. if (HelpCtx<>0) and (FileID<>ID) then P:=nil else
  664. if (FileID=ID) and (LinkNo>TopicLinks^.Count) then P:=nil else
  665. begin
  666. P:=Topics^.FirstThat(@MatchCtx);
  667. if P=nil then
  668. begin
  669. if LinkNo=0 then
  670. FName:=DefaultFileName
  671. else
  672. FName:=TopicLinks^.At(LinkNo-1)^;
  673. P:=NewTopic(ID,HelpCtx,0,FName,nil,0);
  674. Topics^.Insert(P);
  675. end;
  676. end;
  677. SearchTopic:=P;
  678. end;
  679. function TCustomHTMLHelpFile.ReadTopic(T: PTopic): boolean;
  680. var OK: boolean;
  681. HTMLFile: PMemoryTextFile;
  682. Name: string;
  683. Link,Bookmark: string;
  684. P: sw_integer;
  685. begin
  686. Bookmark:='';
  687. OK:=T<>nil;
  688. if OK then
  689. begin
  690. if T^.HelpCtx=0 then Name:=DefaultFileName else
  691. begin
  692. Link:=TopicLinks^.At((T^.HelpCtx and $ffff)-1)^;
  693. Link:=FormatPath(Link);
  694. P:=Pos('#',Link);
  695. if P>0 then
  696. begin
  697. Bookmark:=copy(Link,P+1,length(Link));
  698. Link:=copy(Link,1,P-1);
  699. end;
  700. { if CurFileName='' then Name:=Link else
  701. Name:=CompletePath(CurFileName,Link);}
  702. Name:=Link;
  703. end;
  704. HTMLFile:=New(PDOSTextFile, Init(Name));
  705. if HTMLFile=nil then
  706. begin
  707. New(HTMLFile, Init);
  708. HTMLFile^.AddLine('<HEAD><TITLE>'+msg_pagenotavailable+'</TITLE></HEAD>');
  709. HTMLFile^.AddLine(
  710. '<BODY>'+
  711. FormatStrStr(msg_cantaccessurl,Name)+'<br><br>'+
  712. '</BODY>');
  713. end;
  714. OK:=Renderer^.BuildTopic(T,Name,HTMLFile,TopicLinks);
  715. if OK then CurFileName:=Name;
  716. if HTMLFile<>nil then Dispose(HTMLFile, Done);
  717. if BookMark='' then
  718. T^.StartNamedMark:=0
  719. else
  720. T^.StartNamedMark:=T^.GetNamedMarkIndex(BookMark)+1;
  721. end;
  722. ReadTopic:=OK;
  723. end;
  724. destructor TCustomHTMLHelpFile.Done;
  725. begin
  726. inherited Done;
  727. if Renderer<>nil then Dispose(Renderer, Done);
  728. if TopicLinks<>nil then Dispose(TopicLinks, Done);
  729. end;
  730. constructor THTMLHelpFile.Init(AFileName: string; AID: word; ATOCEntry: string);
  731. begin
  732. if inherited Init(AID)=false then Fail;
  733. DefaultFileName:=AFileName; TOCEntry:=ATOCEntry;
  734. if DefaultFileName='' then
  735. begin
  736. Done;
  737. Fail;
  738. end;
  739. end;
  740. function THTMLHelpFile.LoadIndex: boolean;
  741. begin
  742. IndexEntries^.Insert(NewIndexEntry(TOCEntry,ID,0));
  743. LoadIndex:=true;
  744. end;
  745. constructor THTMLIndexHelpFile.Init(AFileName: string; AID: word);
  746. begin
  747. inherited Init(AID);
  748. IndexFileName:=AFileName;
  749. end;
  750. function THTMLIndexHelpFile.LoadIndex: boolean;
  751. function FormatAlias(Alias: string): string;
  752. begin
  753. if Assigned(HelpFacility) then
  754. if length(Alias)>HelpFacility^.IndexTabSize-4 then
  755. Alias:=Trim(copy(Alias,1,HelpFacility^.IndexTabSize-4-2))+'..';
  756. FormatAlias:=Alias;
  757. end;
  758. (*procedure AddDoc(P: PHTMLLinkScanDocument); {$ifndef FPC}far;{$endif}
  759. var I: sw_integer;
  760. TLI: THelpCtx;
  761. begin
  762. for I:=1 to P^.GetAliasCount do
  763. begin
  764. TLI:=TopicLinks^.AddItem(P^.GetName);
  765. TLI:=EncodeHTMLCtx(ID,TLI+1);
  766. IndexEntries^.Insert(NewIndexEntry(FormatAlias(P^.GetAlias(I-1)),ID,TLI));
  767. end;
  768. end;*)
  769. var S: PBufStream;
  770. LS: PHTMLLinkScanner;
  771. OK: boolean;
  772. TLI: THelpCtx;
  773. I,J: sw_integer;
  774. begin
  775. New(S, Init(IndexFileName,stOpenRead,4096));
  776. OK:=Assigned(S);
  777. if OK then
  778. begin
  779. New(LS, LoadDocuments(S^));
  780. OK:=Assigned(LS);
  781. if OK then
  782. begin
  783. LS^.SetBaseDir(DirOf(IndexFileName));
  784. for I:=0 to LS^.GetDocumentCount-1 do
  785. for J:=0 to LS^.GetDocumentAliasCount(I)-1 do
  786. begin
  787. TLI:=TopicLinks^.AddItem(LS^.GetDocumentURL(I));
  788. TLI:=EncodeHTMLCtx(ID,TLI+1);
  789. IndexEntries^.Insert(NewIndexEntry(FormatAlias(LS^.GetDocumentAlias(I,J)),ID,TLI));
  790. end;
  791. Dispose(LS, Done);
  792. end;
  793. Dispose(S, Done);
  794. end;
  795. LoadIndex:=OK;
  796. end;
  797. function CreateProcHTML(const FileName,Param: string;Index : longint): PHelpFile; {$ifndef FPC}far;{$endif}
  798. var H: PHelpFile;
  799. begin
  800. H:=nil;
  801. if CompareText(copy(ExtOf(FileName),1,length(extHTML)),extHTML)=0 then
  802. H:=New(PHTMLHelpFile, Init(FileName,Index,Param));
  803. CreateProcHTML:=H;
  804. end;
  805. function CreateProcHTMLIndex(const FileName,Param: string;Index : longint): PHelpFile; {$ifndef FPC}far;{$endif}
  806. var H: PHelpFile;
  807. begin
  808. H:=nil;
  809. if CompareText(ExtOf(FileName),extHTMLIndex)=0 then
  810. H:=New(PHTMLIndexHelpFile, Init(FileName,Index));
  811. CreateProcHTMLIndex:=H;
  812. end;
  813. procedure RegisterHelpType;
  814. begin
  815. RegisterHelpFileType({$ifdef FPC}@{$endif}CreateProcHTML);
  816. RegisterHelpFileType({$ifdef FPC}@{$endif}CreateProcHTMLIndex);
  817. end;
  818. END.
  819. {
  820. $Log$
  821. Revision 1.2 2001-09-18 11:33:53 pierre
  822. * fix Previous Help Topic
  823. Revision 1.1 2001/08/04 11:30:25 peter
  824. * ide works now with both compiler versions
  825. Revision 1.1.2.6 2001/06/07 16:41:14 jonas
  826. * updated for stricter checking of @ for procvars
  827. Revision 1.1.2.5 2001/03/06 22:41:21 pierre
  828. * avoid clipping for ansi file loading
  829. Revision 1.1.2.4 2000/11/27 12:06:52 pierre
  830. New bunch of Gabor fixes
  831. Revision 1.1.2.3 2000/11/16 23:13:06 pierre
  832. + support for ANSI substitutes to HTML images in HTML viewer
  833. Revision 1.1.2.2 2000/10/18 21:53:27 pierre
  834. * several Gabor fixes
  835. Revision 1.1.2.1 2000/09/18 13:20:56 pierre
  836. New bunch of Gabor changes
  837. Revision 1.1 2000/07/13 09:48:37 michael
  838. + Initial import
  839. Revision 1.15 2000/06/22 09:07:15 pierre
  840. * Gabor changes: see fixes.txt
  841. Revision 1.14 2000/06/16 08:50:45 pierre
  842. + new bunch of Gabor's changes
  843. }