whtmlhlp.pas 24 KB

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