whtmlhlp.pas 48 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823
  1. {
  2. This file is part of the Free Pascal Integrated Development Environment
  3. Copyright (c) 1999-2000 by Berczi Gabor
  4. See the file COPYING.FPC, included in this distribution,
  5. for details about the copyright.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  9. **********************************************************************}
  10. unit WHTMLHlp;
  11. interface
  12. uses Objects,WHTML,WAnsi,WHelp,WChmHWrap;
  13. const
  14. extHTML = '.htm';
  15. extHTMLIndex = '.htx';
  16. extCHM = '.chm';
  17. ListIndent = 2;
  18. DefIndent = 4;
  19. MaxTopicLinks = 24000; { maximum number of links on a single HTML page }
  20. type
  21. THTMLSection = (hsNone,hsHeading1,hsHeading2,hsHeading3,hsHeading4,hsHeading5,hsHeading6);
  22. TParagraphAlign = (paLeft,paCenter,paRight);
  23. PTableElement = ^TTableElement;
  24. TTableElement = object(Tobject)
  25. TextBegin,TextEnd, TextLength, NumNL : sw_word;
  26. Alignment : TParagraphAlign;
  27. NextEl : PTableElement;
  28. constructor init(AAlignment : TParagraphAlign);
  29. end;
  30. PTableLine = ^TTableLine;
  31. TTableLine = object(Tobject)
  32. NumElements : sw_word;
  33. Nextline : PTableLine;
  34. FirstEl,LastEl : PTableElement;
  35. constructor Init;
  36. procedure AddElement(PTE : PTableElement);
  37. destructor Done; virtual;
  38. end;
  39. PHTMLTopicRenderer = ^THTMLTopicRenderer;
  40. PTable = ^TTable;
  41. TTable = object(Tobject)
  42. NumLines,NumCols : sw_word;
  43. GlobalOffset,
  44. GlobalTextBegin : sw_word;
  45. WithBorder : boolean;
  46. IsBar : boolean;
  47. FirstLine : PTableLine;
  48. LastLine : PTableLine;
  49. PreviousTable : PTable;
  50. Renderer : PHTMLTopicRenderer;
  51. constructor Init(Previous : PTable);
  52. procedure AddLine(PL : PTableLine);
  53. procedure AddElement(PTE : PTableElement);
  54. procedure TextInsert(Pos : sw_word;const S : string);
  55. procedure FormatTable;
  56. destructor Done; virtual;
  57. end;
  58. THTMLTopicRenderer = object(THTMLParser)
  59. function BuildTopic(P: PTopic; AURL: string; HTMLFile: PTextFile; ATopicLinks: PTopicLinkCollection): boolean;
  60. public
  61. function DocAddTextChar(C: char): boolean; virtual;
  62. procedure DocSoftBreak; virtual;
  63. procedure DocTYPE; virtual;
  64. procedure DocHTML(Entered: boolean); virtual;
  65. procedure DocHEAD(Entered: boolean); virtual;
  66. procedure DocMETA; virtual;
  67. procedure DocTITLE(Entered: boolean); virtual;
  68. procedure DocBODY(Entered: boolean); virtual;
  69. procedure DocAnchor(Entered: boolean); virtual;
  70. procedure DocUnknownTag; virtual;
  71. procedure DocHeading(Level: integer; Entered: boolean); virtual;
  72. procedure DocParagraph(Entered: boolean); virtual;
  73. procedure DocBreak; virtual;
  74. procedure DocImage; virtual;
  75. procedure DocProcessComment(Comment: string); virtual;
  76. procedure DocBold(Entered: boolean); virtual;
  77. procedure DocCite(Entered: boolean); virtual;
  78. procedure DocCode(Entered: boolean); virtual;
  79. procedure DocEmphasized(Entered: boolean); virtual;
  80. procedure DocItalic(Entered: boolean); virtual;
  81. procedure DocKbd(Entered: boolean); virtual;
  82. procedure DocPreformatted(Entered: boolean); virtual;
  83. procedure DocSample(Entered: boolean); virtual;
  84. procedure DocStrong(Entered: boolean); virtual;
  85. procedure DocTeleType(Entered: boolean); virtual;
  86. procedure DocVariable(Entered: boolean); virtual;
  87. procedure DocSpan(Entered: boolean); virtual;
  88. procedure DocList(Entered: boolean); virtual;
  89. procedure DocOrderedList(Entered: boolean); virtual;
  90. procedure DocListItem(Entered: boolean); virtual;
  91. procedure DocDefList(Entered: boolean); virtual;
  92. procedure DocDefTerm(Entered: boolean); virtual;
  93. procedure DocDefExp(Entered: boolean); virtual;
  94. procedure DocTable(Entered: boolean); virtual;
  95. procedure DocTableRow(Entered: boolean); virtual;
  96. procedure DocTableHeaderItem(Entered: boolean); virtual;
  97. procedure DocTableItem(Entered: boolean); virtual;
  98. procedure DocHorizontalRuler; virtual;
  99. function CanonicalizeURL(const Base,Relative:String):string; virtual;
  100. public
  101. function GetSectionColor(Section: THTMLSection; var Color: byte): boolean; virtual;
  102. private
  103. URL: string;
  104. Topic: PTopic;
  105. TopicLinks: PTopicLinkCollection;
  106. TextPtr: sw_word;
  107. InTitle: boolean;
  108. InBody: boolean;
  109. InAnchor: boolean;
  110. InParagraph: boolean;
  111. InPreformatted: boolean;
  112. SuppressOutput: boolean;
  113. SuppressUntil : string;
  114. InDefExp: boolean;
  115. TopicTitle: string;
  116. Indent: integer;
  117. AnyCharsInLine,
  118. LastAnsiLoadFailed: boolean;
  119. CurHeadLevel: integer;
  120. PAlign: TParagraphAlign;
  121. LinkIndexes: array[0..MaxTopicLinks] of sw_integer;
  122. LinkPtr: sw_integer;
  123. LastTextChar: char;
  124. { Anchor: TAnchor;}
  125. { Table stuff }
  126. CurrentTable : PTable;
  127. procedure AddText(const S: string);
  128. procedure AddChar(C: char);
  129. procedure AddCharAt(C: char;AtPtr : sw_word);
  130. function AddTextAt(const S: string;AtPtr : sw_word) : sw_word;
  131. function ComputeTextLength(TStart,TEnd : sw_word) : sw_word;
  132. end;
  133. PCHMTopicRenderer = ^TCHMTopicRenderer;
  134. TCHMTopicRenderer = object(THTMLTopicRenderer)
  135. function CanonicalizeURL(const Base,Relative:String):string; virtual;
  136. end;
  137. PCustomHTMLHelpFile = ^TCustomHTMLHelpFile;
  138. TCustomHTMLHelpFile = object(THelpFile)
  139. constructor Init(AID: word);
  140. destructor Done; virtual;
  141. public
  142. Renderer: PHTMLTopicRenderer;
  143. function GetTopicInfo(T: PTopic) : string; virtual;
  144. function SearchTopic(HelpCtx: THelpCtx): PTopic; virtual;
  145. function ReadTopic(T: PTopic): boolean; virtual;
  146. function FormatLink(const s:String):string; virtual;
  147. private
  148. DefaultFileName: string;
  149. CurFileName: string;
  150. TopicLinks: PTopicLinkCollection;
  151. end;
  152. PHTMLHelpFile = ^THTMLHelpFile;
  153. THTMLHelpFile = object(TCustomHTMLHelpFile)
  154. constructor Init(AFileName: string; AID: word; ATOCEntry: string);
  155. public
  156. function LoadIndex: boolean; virtual;
  157. private
  158. TOCEntry: string;
  159. end;
  160. PCHMHelpFile = ^TCHMHelpFile;
  161. TCHMHelpFile = object(TCustomHTMLHelpFile)
  162. constructor Init(AFileName: string; AID: word);
  163. destructor Done; virtual;
  164. public
  165. function LoadIndex: boolean; virtual;
  166. function ReadTopic(T: PTopic): boolean; virtual;
  167. function GetTopicInfo(T: PTopic) : string; virtual;
  168. function SearchTopic(HelpCtx: THelpCtx): PTopic; virtual;
  169. function FormatLink(const s:String):string; virtual;
  170. private
  171. Chmw: TCHMWrapper;
  172. end;
  173. PHTMLIndexHelpFile = ^THTMLIndexHelpFile;
  174. THTMLIndexHelpFile = object(TCustomHTMLHelpFile)
  175. constructor Init(AFileName: string; AID: word);
  176. function LoadIndex: boolean; virtual;
  177. private
  178. IndexFileName: string;
  179. end;
  180. PHTMLAnsiView = ^THTMLAnsiView;
  181. PHTMLAnsiConsole = ^THTMLAnsiConsole;
  182. THTMLAnsiConsole = Object(TAnsiViewConsole)
  183. MaxX,MaxY : integer;
  184. procedure GotoXY(X,Y: integer); virtual;
  185. end;
  186. THTMLAnsiView = Object(TAnsiView)
  187. private
  188. HTMLOwner : PHTMLTopicRenderer;
  189. HTMLConsole : PHTMLAnsiConsole;
  190. public
  191. constructor Init(AOwner: PHTMLTopicRenderer);
  192. procedure CopyToHTML;
  193. end;
  194. THTMLGetSectionColorProc = function(Section: THTMLSection; var Color: byte): boolean;
  195. function DefHTMLGetSectionColor(Section: THTMLSection; var Color: byte): boolean;
  196. const HTMLGetSectionColor : THTMLGetSectionColorProc = {$ifdef fpc}@{$endif}DefHTMLGetSectionColor;
  197. procedure RegisterHelpType;
  198. implementation
  199. uses
  200. Views,WConsts,WUtils,WViews,WHTMLScn;
  201. constructor TTableElement.init(AAlignment : TParagraphAlign);
  202. begin
  203. Alignment:=AAlignment;
  204. NextEl:=nil;
  205. TextBegin:=0;
  206. TextEnd:=0;
  207. end;
  208. { TTableLine methods }
  209. constructor TTableLine.Init;
  210. begin
  211. NumElements:=0;
  212. NextLine:=nil;
  213. Firstel:=nil;
  214. LastEl:=nil;
  215. end;
  216. procedure TTableLine.AddElement(PTE : PTableElement);
  217. begin
  218. if not assigned(FirstEl) then
  219. FirstEl:=PTE;
  220. if assigned(LastEl) then
  221. LastEl^.NextEl:=PTE;
  222. LastEl:=PTE;
  223. Inc(NumElements);
  224. end;
  225. destructor TTableLine.Done;
  226. begin
  227. LastEl:=FirstEl;
  228. while assigned(LastEl) do
  229. begin
  230. LastEl:=FirstEl^.NextEl;
  231. Dispose(FirstEl,Done);
  232. FirstEl:=LastEl;
  233. end;
  234. inherited Done;
  235. end;
  236. { TTable methods }
  237. constructor TTable.Init(Previous : PTable);
  238. begin
  239. PreviousTable:=Previous;
  240. NumLines:=0;
  241. NumCols:=0;
  242. GlobalOffset:=0;
  243. GlobalTextBegin:=0;
  244. FirstLine:=nil;
  245. LastLine:=nil;
  246. WithBorder:=false;
  247. IsBar:=false;
  248. end;
  249. procedure TTable.AddLine(PL : PTableLine);
  250. begin
  251. If not assigned(FirstLine) then
  252. FirstLine:=PL;
  253. if Assigned(LastLine) then
  254. LastLine^.NextLine:=PL;
  255. LastLine:=PL;
  256. Inc(NumLines);
  257. end;
  258. procedure TTable.AddElement(PTE : PTableElement);
  259. begin
  260. if assigned(LastLine) then
  261. begin
  262. LastLine^.AddElement(PTE);
  263. If LastLine^.NumElements>NumCols then
  264. NumCols:=LastLine^.NumElements;
  265. end;
  266. end;
  267. procedure TTable.TextInsert(Pos : sw_word;const S : string);
  268. var
  269. i : sw_word;
  270. begin
  271. if S='' then
  272. exit;
  273. i:=Renderer^.AddTextAt(S,Pos+GlobalOffset);
  274. GlobalOffset:=GlobalOffset+i;
  275. end;
  276. procedure TTable.FormatTable;
  277. const
  278. MaxCols = 200;
  279. type
  280. TLengthArray = Array [ 1 .. MaxCols] of sw_word;
  281. PLengthArray = ^TLengthArray;
  282. var
  283. ColLengthArray : PLengthArray;
  284. RowSizeArray : PLengthArray;
  285. CurLine : PTableLine;
  286. CurEl : PTableElement;
  287. Align : TParagraphAlign;
  288. TextBegin,TextEnd : sw_word;
  289. i,j,k,Length : sw_word;
  290. begin
  291. { do nothing for single cell tables }
  292. if (NumCols=1) and (NumLines=1) then
  293. exit;
  294. GetMem(ColLengthArray,Sizeof(sw_word)*NumCols);
  295. FillChar(ColLengthArray^,Sizeof(sw_word)*NumCols,#0);
  296. GetMem(RowSizeArray,Sizeof(sw_word)*NumLines);
  297. FillChar(RowSizeArray^,Sizeof(sw_word)*NumLines,#0);
  298. { Compute the largest cell }
  299. CurLine:=FirstLine;
  300. For i:=1 to NumLines do
  301. begin
  302. CurEl:=CurLine^.FirstEl;
  303. RowSizeArray^[i]:=1;
  304. For j:=1 to NumCols do
  305. begin
  306. if not assigned(CurEl) then
  307. break;
  308. Length:=CurEl^.TextLength;
  309. if assigned(CurEl^.NextEl) and
  310. (CurEl^.NextEl^.TextBegin>CurEl^.TextEnd) then
  311. Inc(Length,Renderer^.ComputeTextLength(
  312. CurEl^.NextEl^.TextBegin+GlobalOffset,
  313. CurEl^.TextBegin+GlobalOffset));
  314. if Length>ColLengthArray^[j] then
  315. ColLengthArray^[j]:=Length;
  316. { We need to handle multiline cells... }
  317. if CurEl^.NumNL>=RowSizeArray^[i] then
  318. RowSizeArray^[i]:=CurEl^.NumNL;
  319. { We don't handle multiline cells yet... }
  320. if CurEl^.NumNL>=1 then
  321. begin
  322. for k:=CurEl^.TextBegin+GlobalOffset to
  323. CurEl^.TextEnd+GlobalOffset do
  324. if Renderer^.Topic^.Text^[k]=ord(hscLineBreak) then
  325. Renderer^.Topic^.Text^[k]:=ord(' ');
  326. end;
  327. CurEl:=CurEl^.NextEl;
  328. end;
  329. CurLine:=CurLine^.NextLine;
  330. end;
  331. { Adjust to largest cell }
  332. CurLine:=FirstLine;
  333. TextBegin:=GlobalTextBegin;
  334. If (NumLines>0) and WithBorder then
  335. Begin
  336. TextInsert(TextBegin,#218);
  337. For j:=1 to NumCols do
  338. begin
  339. TextInsert(TextBegin,CharStr(#196,ColLengthArray^[j]));
  340. if j<NumCols then
  341. TextInsert(TextBegin,#194);
  342. end;
  343. TextInsert(TextBegin,#191);
  344. TextInsert(TextBegin,hscLineBreak);
  345. End;
  346. For i:=1 to NumLines do
  347. begin
  348. CurEl:=CurLine^.FirstEl;
  349. For j:=1 to NumCols do
  350. begin
  351. if not assigned(CurEl) then
  352. begin
  353. Length:=0;
  354. Align:=paLeft;
  355. end
  356. else
  357. begin
  358. TextBegin:=CurEl^.TextBegin;
  359. TextEnd:=CurEl^.TextEnd;
  360. {While (TextEnd>TextBegin) and
  361. (Renderer^.Topic^.Text^[TextEnd+GlobalOffset]=ord(hscLineBreak)) do
  362. dec(TextEnd); }
  363. Length:=CurEl^.TextLength;
  364. Align:=CurEl^.Alignment;
  365. end;
  366. if WithBorder then
  367. TextInsert(TextBegin,#179)
  368. else
  369. TextInsert(TextBegin,' ');
  370. if Length<ColLengthArray^[j] then
  371. begin
  372. case Align of
  373. paLeft:
  374. TextInsert(TextEnd,CharStr(' ',ColLengthArray^[j]-Length));
  375. paRight:
  376. TextInsert(TextBegin,CharStr(' ',ColLengthArray^[j]-Length));
  377. paCenter:
  378. begin
  379. TextInsert(TextBegin,CharStr(' ',(ColLengthArray^[j]-Length) div 2));
  380. TextInsert(TextEnd,CharStr(' ',(ColLengthArray^[j]-Length)- ((ColLengthArray^[j]-Length) div 2)));
  381. end;
  382. end;
  383. end;
  384. if Assigned(CurEl) then
  385. CurEl:=CurEl^.NextEl;
  386. end;
  387. if WithBorder then
  388. TextInsert(TextEnd,#179);
  389. //TextInsert(TextEnd,hscLineBreak);
  390. CurLine:=CurLine^.NextLine;
  391. end;
  392. If (NumLines>0) and WithBorder then
  393. Begin
  394. TextInsert(TextEnd,hscLineBreak);
  395. TextInsert(TextEnd,#192);
  396. For j:=1 to NumCols do
  397. begin
  398. TextInsert(TextEnd,CharStr(#196,ColLengthArray^[j]));
  399. if j<NumCols then
  400. TextInsert(TextEnd,#193);
  401. end;
  402. TextInsert(TextEnd,#217);
  403. TextInsert(TextEnd,hscLineBreak);
  404. End;
  405. FreeMem(ColLengthArray,Sizeof(sw_word)*NumCols);
  406. FreeMem(RowSizeArray,Sizeof(sw_word)*NumLines);
  407. end;
  408. destructor TTable.Done;
  409. begin
  410. LastLine:=FirstLine;
  411. while assigned(LastLine) do
  412. begin
  413. LastLine:=FirstLine^.NextLine;
  414. Dispose(FirstLine,Done);
  415. FirstLine:=LastLine;
  416. end;
  417. if Assigned(PreviousTable) then
  418. Inc(PreviousTable^.GlobalOffset,GlobalOffset);
  419. inherited Done;
  420. end;
  421. { THTMLAnsiConsole methods }
  422. procedure THTMLAnsiConsole.GotoXY(X,Y : integer);
  423. begin
  424. if X>MaxX then MaxX:=X-1;
  425. if Y>MaxY then MaxY:=Y-1;
  426. inherited GotoXY(X,Y);
  427. end;
  428. { THTMLAnsiView methods }
  429. constructor THTMLAnsiView.Init(AOwner : PHTMLTopicRenderer);
  430. var
  431. R : TRect;
  432. begin
  433. if not assigned(AOwner) then
  434. fail;
  435. R.Assign(0,0,80,25);
  436. inherited init(R,nil,nil);
  437. HTMLOwner:=AOwner;
  438. HTMLConsole:=New(PHTMLAnsiConsole,Init(@Self));
  439. HTMLConsole^.HighVideo;
  440. Dispose(Console,Done);
  441. Console:=HTMLConsole;
  442. HTMLConsole^.Size.X:=80;
  443. HTMLConsole^.Size.Y:=25;
  444. HTMLConsole^.ClrScr;
  445. HTMLConsole^.MaxX:=-1;
  446. HTMLConsole^.MaxY:=-1;
  447. HTMLConsole^.BoundChecks:=0;
  448. end;
  449. procedure THTMLAnsiView.CopyToHTML;
  450. var
  451. Attr,NewAttr : byte;
  452. c : char;
  453. X,Y,Pos : longint;
  454. begin
  455. Attr:=(Buffer^[1] shr 8);
  456. HTMLOwner^.AddChar(hscLineBreak);
  457. HTMLOwner^.AddText(hscTextAttr+chr(Attr));
  458. for Y:=0 to HTMLConsole^.MaxY-1 do
  459. begin
  460. for X:=0 to HTMLConsole^.MaxX-1 do
  461. begin
  462. Pos:=(Delta.Y*MaxViewWidth)+X+Y*MaxViewWidth;
  463. NewAttr:=(Buffer^[Pos] shr 8);
  464. if NewAttr <> Attr then
  465. begin
  466. Attr:=NewAttr;
  467. HTMLOwner^.AddText(hscTextAttr+chr(Attr));
  468. end;
  469. c:= chr(Buffer^[Pos] and $ff);
  470. if ord(c)>16 then
  471. HTMLOwner^.AddChar(c)
  472. else
  473. begin
  474. HTMLOwner^.AddChar(hscDirect);
  475. HTMLOwner^.AddChar(c);
  476. end;
  477. end;
  478. { Write start of next line in normal color, for correct alignment }
  479. HTMLOwner^.AddChar(hscNormText);
  480. { Force to set attr again at start of next line }
  481. Attr:=0;
  482. HTMLOwner^.AddChar(hscLineBreak);
  483. end;
  484. end;
  485. function DefHTMLGetSectionColor(Section: THTMLSection; var Color: byte): boolean;
  486. begin
  487. Color:=0;
  488. DefHTMLGetSectionColor:=false;
  489. end;
  490. function CharStr(C: char; Count: byte): string;
  491. var S: string;
  492. begin
  493. S[0]:=chr(Count);
  494. if Count>0 then FillChar(S[1],Count,C);
  495. CharStr:=S;
  496. end;
  497. function THTMLTopicRenderer.DocAddTextChar(C: char): boolean;
  498. var Added: boolean;
  499. begin
  500. Added:=false;
  501. if InTitle then
  502. begin
  503. TopicTitle:=TopicTitle+C;
  504. Added:=true;
  505. end
  506. else
  507. if InBody then
  508. begin
  509. if (InPreFormatted) or (C<>#32) or (LastTextChar<>C) then
  510. if (C<>#32) or (AnyCharsInLine=true) or (InPreFormatted=true) then
  511. begin
  512. AddChar(C);
  513. LastTextChar:=C;
  514. Added:=true;
  515. end;
  516. end;
  517. DocAddTextChar:=Added;
  518. end;
  519. procedure THTMLTopicRenderer.DocSoftBreak;
  520. begin
  521. if InPreformatted then DocBreak else
  522. if AnyCharsInLine and not assigned(CurrentTable) then
  523. begin
  524. AddChar(' ');
  525. LastTextChar:=' ';
  526. end;
  527. end;
  528. procedure THTMLTopicRenderer.DocTYPE;
  529. begin
  530. end;
  531. procedure THTMLTopicRenderer.DocHTML(Entered: boolean);
  532. begin
  533. end;
  534. procedure THTMLTopicRenderer.DocHEAD(Entered: boolean);
  535. begin
  536. end;
  537. procedure THTMLTopicRenderer.DocMETA;
  538. begin
  539. end;
  540. procedure THTMLTopicRenderer.DocTITLE(Entered: boolean);
  541. begin
  542. if Entered then
  543. begin
  544. TopicTitle:='';
  545. end
  546. else
  547. begin
  548. { render topic title here }
  549. if TopicTitle<>'' then
  550. begin
  551. AddText(' '+TopicTitle+' Ü'); DocBreak;
  552. AddText(' '+CharStr('ß',length(TopicTitle)+3)); DocBreak;
  553. end;
  554. end;
  555. InTitle:=Entered;
  556. end;
  557. procedure THTMLTopicRenderer.DocBODY(Entered: boolean);
  558. begin
  559. InBody:=Entered;
  560. end;
  561. procedure THTMLTopicRenderer.DocAnchor(Entered: boolean);
  562. var HRef,Name: string;
  563. begin
  564. if Entered and InAnchor then DocAnchor(false);
  565. if Entered then
  566. begin
  567. if DocGetTagParam('HREF',HRef)=false then HRef:='';
  568. if DocGetTagParam('NAME',Name)=false then Name:='';
  569. if {(HRef='') and} (Name='') then
  570. if DocGetTagParam('ID',Name)=false then
  571. Name:='';
  572. if Name<>'' then
  573. begin
  574. Topic^.NamedMarks^.InsertStr(Name);
  575. {$IFDEF WDEBUG}
  576. DebugMessageS({$i %file%},' Adding Name "'+Name+'"',{$i %line%},'1',0,0);
  577. {$endif WDEBUG}
  578. AddChar(hscNamedMark);
  579. end;
  580. if (HRef<>'')then
  581. begin
  582. if (LinkPtr<MaxTopicLinks){ and
  583. not DisableCrossIndexing} then
  584. begin
  585. InAnchor:=true;
  586. AddChar(hscLink);
  587. {$IFDEF WDEBUG}
  588. DebugMessageS({$i %file%},' Adding Link1 "'+HRef+'"'+' "'+url+'"',{$i %line%},'1',0,0);
  589. {$ENDIF WDEBUG}
  590. if pos('#',HRef)=1 then
  591. Href:=NameAndExtOf(GetFilename)+Href;
  592. HRef:=canonicalizeURL(URL,HRef);
  593. LinkIndexes[LinkPtr]:=TopicLinks^.AddItem(HRef);
  594. {$IFDEF WDEBUG}
  595. DebugMessageS({$i %file%},' Adding Link2 "'+HRef+'"',{$i %line%},'1',0,0);
  596. {$ENDIF WDEBUG}
  597. Inc(LinkPtr);
  598. end;
  599. end;
  600. end
  601. else
  602. begin
  603. if InAnchor=true then AddChar(hscLink);
  604. InAnchor:=false;
  605. end;
  606. end;
  607. procedure THTMLTopicRenderer.DocUnknownTag;
  608. begin
  609. {$IFDEF WDEBUG}
  610. DebugMessageS({$i %file%},' Unknown tag "'+TagName+'" params "'+TagParams+'"' ,{$i %line%},'1',0,0);
  611. {$endif WDEBUG}
  612. end;
  613. procedure DecodeAlign(Align: string; var PAlign: TParagraphAlign);
  614. begin
  615. Align:=UpcaseStr(Align);
  616. if Align='LEFT' then PAlign:=paLeft else
  617. if Align='CENTER' then PAlign:=paCenter else
  618. if Align='RIGHT' then PAlign:=paRight;
  619. end;
  620. procedure THTMLTopicRenderer.DocHeading(Level: integer; Entered: boolean);
  621. var Align: string;
  622. C: byte;
  623. SC: THTMLSection;
  624. begin
  625. if Entered then
  626. begin
  627. DocBreak;
  628. CurHeadLevel:=Level;
  629. PAlign:=paLeft;
  630. if DocGetTagParam('ALIGN',Align) then
  631. DecodeAlign(Align,PAlign);
  632. SC:=hsNone;
  633. case Level of
  634. 1: SC:=hsHeading1;
  635. 2: SC:=hsHeading2;
  636. 3: SC:=hsHeading3;
  637. 4: SC:=hsHeading4;
  638. 5: SC:=hsHeading5;
  639. 6: SC:=hsHeading6;
  640. end;
  641. if GetSectionColor(SC,C) then
  642. AddText(hscTextAttr+chr(C));
  643. end
  644. else
  645. begin
  646. AddChar(hscNormText);
  647. CurHeadLevel:=0;
  648. DocBreak;
  649. end;
  650. end;
  651. Function THTMLTopicRenderer.CanonicalizeURL(const Base,Relative:String):string;
  652. // uses info from filesystem (curdir) -> overriden for CHM.
  653. begin
  654. CanonicalizeURL:=CompleteURL(Base,relative);
  655. end;
  656. procedure THTMLTopicRenderer.DocParagraph(Entered: boolean);
  657. var Align: string;
  658. begin
  659. if Entered and InParagraph then DocParagraph(false);
  660. if Entered then
  661. begin
  662. if AnyCharsInLine then DocBreak;
  663. if DocGetTagParam('ALIGN',Align) then
  664. DecodeAlign(Align,PAlign);
  665. end
  666. else
  667. begin
  668. { if AnyCharsInLine then }DocBreak;
  669. PAlign:=paLeft;
  670. end;
  671. InParagraph:=Entered;
  672. end;
  673. procedure THTMLTopicRenderer.DocBreak;
  674. begin
  675. if (CurHeadLevel=1) or (PAlign=paCenter) then
  676. AddChar(hscCenter);
  677. if (PAlign=paRight) then
  678. AddChar(hscRight);
  679. AddChar(hscLineBreak);
  680. if Indent>0 then
  681. AddText(CharStr(#255,Indent)+hscLineStart);
  682. AnyCharsInLine:=false;
  683. end;
  684. procedure THTMLTopicRenderer.DocProcessComment(Comment: string);
  685. var
  686. src,index : string;
  687. begin
  688. if pos('tex4ht:',Comment)=0 then
  689. exit;
  690. {$IFDEF WDEBUG}
  691. DebugMessage(GetFileName,'tex4ht comment "'
  692. +Comment+'"',Line,1);
  693. {$endif WDEBUG}
  694. if SuppressOutput then
  695. begin
  696. if (pos(SuppressUntil,Comment)=0) then
  697. exit
  698. else
  699. begin
  700. {$IFDEF WDEBUG}
  701. DebugMessage(GetFileName,' Found '+SuppressUntil+'comment "'
  702. +Comment+'" SuppressOuput reset to false',Line,1);
  703. {$endif WDEBUG}
  704. SuppressOutput:=false;
  705. SuppressUntil:='';
  706. end;
  707. end;
  708. if (pos('tex4ht:graphics ',Comment)>0) and
  709. LastAnsiLoadFailed then
  710. begin
  711. {$IFDEF WDEBUG}
  712. DebugMessage(GetFileName,' Using tex4ht comment "'
  713. +Comment+'"',Line,1);
  714. {$endif WDEBUG}
  715. { Try again with this info }
  716. TagParams:=Comment;
  717. DocImage;
  718. end;
  719. if (pos('tex4ht:syntaxdiagram ',Comment)>0) then
  720. begin
  721. {$IFDEF WDEBUG}
  722. DebugMessage(GetFileName,' Using tex4ht:syntaxdiagram comment "'
  723. +Comment+'"',Line,1);
  724. {$endif WDEBUG}
  725. { Try again with this info }
  726. TagParams:=Comment;
  727. DocImage;
  728. if not LastAnsiLoadFailed then
  729. begin
  730. SuppressOutput:=true;
  731. SuppressUntil:='tex4ht:endsyntaxdiagram ';
  732. end
  733. end;
  734. if (pos('tex4ht:mysyntdiag ',Comment)>0) then
  735. begin
  736. {$IFDEF WDEBUG}
  737. DebugMessage(GetFileName,' Using tex4ht:mysyntdiag comment "'
  738. +Comment+'"',Line,1);
  739. {$endif WDEBUG}
  740. { Try again with this info }
  741. TagParams:=Comment;
  742. DocGetTagParam('SRC',src);
  743. DocGetTagParam('INDEX',index);
  744. TagParams:='src="../syntax/'+src+'-'+index+'.png"';
  745. DocImage;
  746. if not LastAnsiLoadFailed then
  747. begin
  748. SuppressOutput:=true;
  749. SuppressUntil:='tex4ht:endmysyntdiag ';
  750. end
  751. end;
  752. end;
  753. procedure THTMLTopicRenderer.DocImage;
  754. var Name,Src,Alt,SrcLine: string;
  755. f : text;
  756. attr : byte;
  757. PA : PHTMLAnsiView;
  758. StorePreformatted : boolean;
  759. begin
  760. if SuppressOutput then
  761. exit;
  762. {$IFDEF WDEBUG}
  763. if not DocGetTagParam('NAME',Name) then
  764. Name:='<No name>';
  765. DebugMessage(GetFileName,' Image "'+Name+'"',Line,1);
  766. {$endif WDEBUG}
  767. if DocGetTagParam('SRC',src) then
  768. begin
  769. {$IFDEF WDEBUG}
  770. DebugMessage(GetFileName,' Image source tag "'+Src+'"',Line,1);
  771. {$endif WDEBUG}
  772. if src<>'' then
  773. begin
  774. src:=CompleteURL(URL,src);
  775. { this should be a image file ending by .gif or .jpg...
  776. Try to see if a file with same name and extension .git
  777. exists PM }
  778. src:=DirAndNameOf(src)+'.ans';
  779. {$IFDEF WDEBUG}
  780. DebugMessage(GetFileName,' Trying "'+Src+'"',Line,1);
  781. {$endif WDEBUG}
  782. if not ExistsFile(src) then
  783. begin
  784. DocGetTagParam('SRC',src);
  785. src:=DirAndNameOf(src)+'.ans';
  786. src:=CompleteURL(DirOf(URL)+'../',src);
  787. {$IFDEF WDEBUG}
  788. DebugMessage(GetFileName,' Trying "'+Src+'"',Line,1);
  789. {$endif wDEBUG}
  790. end;
  791. if not ExistsFile(src) then
  792. begin
  793. LastAnsiLoadFailed:=true;
  794. {$IFDEF WDEBUG}
  795. DebugMessage(GetFileName,' "'+Src+'" not found',Line,1);
  796. {$endif WDEBUG}
  797. end
  798. else
  799. begin
  800. PA:=New(PHTMLAnsiView,init(@self));
  801. PA^.LoadFile(src);
  802. LastAnsiLoadFailed:=false;
  803. if AnyCharsInLine then DocBreak;
  804. StorePreformatted:=InPreformatted;
  805. InPreformatted:=true;
  806. {AddText('Image from '+src+hscLineBreak); }
  807. AddChar(hscInImage);
  808. PA^.CopyToHTML;
  809. InPreformatted:=StorePreformatted;
  810. AddChar(hscInImage);
  811. AddChar(hscNormText);
  812. if AnyCharsInLine then DocBreak;
  813. Dispose(PA,Done);
  814. Exit;
  815. end;
  816. { also look for a raw text file without colors }
  817. src:=DirAndNameOf(src)+'.txt';
  818. if not ExistsFile(src) then
  819. begin
  820. LastAnsiLoadFailed:=true;
  821. {$IFDEF WDEBUG}
  822. DebugMessage(GetFileName,' "'+Src+'" not found',Line,1);
  823. {$endif WDEBUG}
  824. end
  825. else
  826. begin
  827. Assign(f,src);
  828. Reset(f);
  829. DocPreformatted(true);
  830. while not eof(f) do
  831. begin
  832. Readln(f,SrcLine);
  833. AddText(SrcLine+hscLineBreak);
  834. end;
  835. Close(f);
  836. LastAnsiLoadFailed:=false;
  837. DocPreformatted(false);
  838. LastAnsiLoadFailed:=false;
  839. Exit;
  840. end;
  841. end;
  842. end;
  843. if DocGetTagParam('ALT',Alt)=false then
  844. begin
  845. DocGetTagParam('SRC',Alt);
  846. if Alt<>'' then
  847. Alt:='Can''t display '+Alt
  848. else
  849. Alt:='IMG';
  850. end;
  851. if Alt<>'' then
  852. begin
  853. StorePreformatted:=InPreformatted;
  854. InPreformatted:=true;
  855. DocGetTagParam('SRC',src);
  856. AddChar(hscInImage);
  857. AddText('[--'+Src+'--'+hscLineBreak);
  858. AddText(Alt+hscLineBreak+'--]');
  859. AddChar(hscInImage);
  860. AddChar(hscNormText);
  861. InPreformatted:=StorePreformatted;
  862. end;
  863. end;
  864. procedure THTMLTopicRenderer.DocBold(Entered: boolean);
  865. begin
  866. end;
  867. procedure THTMLTopicRenderer.DocCite(Entered: boolean);
  868. begin
  869. end;
  870. procedure THTMLTopicRenderer.DocCode(Entered: boolean);
  871. begin
  872. if AnyCharsInLine then DocBreak;
  873. AddText(hscCode);
  874. DocBreak;
  875. end;
  876. procedure THTMLTopicRenderer.DocEmphasized(Entered: boolean);
  877. begin
  878. end;
  879. procedure THTMLTopicRenderer.DocItalic(Entered: boolean);
  880. begin
  881. end;
  882. procedure THTMLTopicRenderer.DocKbd(Entered: boolean);
  883. begin
  884. end;
  885. procedure THTMLTopicRenderer.DocPreformatted(Entered: boolean);
  886. begin
  887. if AnyCharsInLine then DocBreak;
  888. AddText(hscCode);
  889. DocBreak;
  890. InPreformatted:=Entered;
  891. end;
  892. procedure THTMLTopicRenderer.DocSample(Entered: boolean);
  893. begin
  894. end;
  895. procedure THTMLTopicRenderer.DocStrong(Entered: boolean);
  896. begin
  897. end;
  898. procedure THTMLTopicRenderer.DocTeleType(Entered: boolean);
  899. begin
  900. end;
  901. procedure THTMLTopicRenderer.DocVariable(Entered: boolean);
  902. begin
  903. end;
  904. procedure THTMLTopicRenderer.DocSpan(Entered: boolean);
  905. begin
  906. end;
  907. procedure THTMLTopicRenderer.DocList(Entered: boolean);
  908. begin
  909. if Entered then
  910. begin
  911. Inc(Indent,ListIndent);
  912. DocBreak;
  913. end
  914. else
  915. begin
  916. Dec(Indent,ListIndent);
  917. if AnyCharsInLine then DocBreak;
  918. end;
  919. end;
  920. procedure THTMLTopicRenderer.DocOrderedList(Entered: boolean);
  921. begin
  922. DocList(Entered);
  923. end;
  924. procedure THTMLTopicRenderer.DocListItem(Entered: boolean);
  925. begin
  926. if not Entered then
  927. exit;
  928. if AnyCharsInLine then
  929. DocBreak;
  930. AddText('þ'+hscLineStart);
  931. end;
  932. procedure THTMLTopicRenderer.DocDefList(Entered: boolean);
  933. begin
  934. if Entered then
  935. begin
  936. { if LastChar<>hscLineBreak then DocBreak;}
  937. end
  938. else
  939. begin
  940. if AnyCharsInLine then DocBreak;
  941. InDefExp:=false;
  942. end;
  943. end;
  944. procedure THTMLTopicRenderer.DocDefTerm(Entered: boolean);
  945. begin
  946. if not Entered then
  947. exit;
  948. DocBreak;
  949. end;
  950. procedure THTMLTopicRenderer.DocDefExp(Entered: boolean);
  951. begin
  952. if not Entered then
  953. begin
  954. if InDefExp then
  955. Dec(Indent,DefIndent);
  956. InDefExp:=false;
  957. end
  958. else
  959. begin
  960. if not InDefExp then
  961. Inc(Indent,DefIndent);
  962. InDefExp:=true;
  963. DocBreak;
  964. end;
  965. end;
  966. procedure THTMLTopicRenderer.DocTable(Entered: boolean);
  967. var
  968. ATable : PTable;
  969. Param : String;
  970. begin
  971. if AnyCharsInLine then
  972. begin
  973. AddChar(hscLineBreak);
  974. AnyCharsInLine:=false;
  975. end;
  976. if Entered then
  977. begin
  978. DocBreak;
  979. New(ATable,Init(CurrentTable));
  980. CurrentTable:=ATable;
  981. CurrentTable^.Renderer:=@Self;
  982. if DocGetTagParam('BORDER',Param) then
  983. if Param<>'0' then
  984. CurrentTable^.WithBorder:=true;
  985. if DocGetTagParam('CLASS',Param) then
  986. if Param='bar' then
  987. CurrentTable^.IsBar:=true;
  988. end
  989. else
  990. begin
  991. CurrentTable^.FormatTable;
  992. ATable:=CurrentTable;
  993. CurrentTable:=ATable^.PreviousTable;
  994. Dispose(ATable,Done);
  995. end;
  996. end;
  997. procedure THTMLTopicRenderer.DocTableRow(Entered: boolean);
  998. var
  999. ATableLine : PTableLine;
  1000. begin
  1001. if AnyCharsInLine or
  1002. (assigned(CurrentTable) and
  1003. assigned(CurrentTable^.FirstLine)) then
  1004. begin
  1005. AddChar(hscLineBreak);
  1006. AnyCharsInLine:=false;
  1007. end;
  1008. if Entered then
  1009. begin
  1010. New(ATableLine,Init);
  1011. if CurrentTable^.GlobalTextBegin=0 then
  1012. CurrentTable^.GlobalTextBegin:=TextPtr;
  1013. CurrentTable^.AddLine(ATableLine);
  1014. end;
  1015. end;
  1016. procedure THTMLTopicRenderer.DocTableItem(Entered: boolean);
  1017. var
  1018. Align : String;
  1019. i : sw_word;
  1020. NewEl : PTableElement;
  1021. PAlignEl : TParagraphAlign;
  1022. begin
  1023. if Entered then
  1024. begin
  1025. if assigned(CurrentTable^.LastLine) and Assigned(CurrentTable^.LastLine^.LastEl) and
  1026. (CurrentTable^.LastLine^.LastEl^.TextEnd=sw_word(-1)) then
  1027. begin
  1028. NewEl:=CurrentTable^.LastLine^.LastEl;
  1029. NewEl^.TextEnd:=TextPtr;
  1030. NewEl^.TextLength:=ComputeTextLength(
  1031. NewEl^.TextBegin+CurrentTable^.GlobalOffset,
  1032. TextPtr+CurrentTable^.GlobalOffset);
  1033. end;
  1034. PAlignEl:=paLeft;
  1035. if DocGetTagParam('ALIGN',Align) then
  1036. DecodeAlign(Align,PAlignEl);
  1037. New(NewEl,Init(PAlignEl));
  1038. CurrentTable^.AddElement(NewEl);
  1039. NewEl^.TextBegin:=TextPtr;
  1040. NewEl^.TextEnd:=sw_word(-1);
  1041. { AddText(' - ');}
  1042. end
  1043. else
  1044. begin
  1045. NewEl:=CurrentTable^.LastLine^.LastEl;
  1046. NewEl^.TextEnd:=TextPtr;
  1047. NewEl^.TextLength:=ComputeTextLength(
  1048. NewEl^.TextBegin+CurrentTable^.GlobalOffset,
  1049. TextPtr+CurrentTable^.GlobalOffset);
  1050. NewEl^.NumNL:=0;
  1051. for i:=NewEl^.TextBegin to TextPtr do
  1052. begin
  1053. if Topic^.Text^[i]=ord(hscLineBreak) then
  1054. inc(NewEl^.NumNL);
  1055. end;
  1056. end;
  1057. end;
  1058. procedure THTMLTopicRenderer.DocTableHeaderItem(Entered: boolean);
  1059. begin
  1060. { Treat as a normal item }
  1061. DocTableItem(Entered);
  1062. end;
  1063. procedure THTMLTopicRenderer.DocHorizontalRuler;
  1064. var OAlign: TParagraphAlign;
  1065. begin
  1066. OAlign:=PAlign;
  1067. if AnyCharsInLine then DocBreak;
  1068. PAlign:=paCenter;
  1069. DocAddText(' '+CharStr('Ä',60)+' ');
  1070. DocBreak;
  1071. PAlign:=OAlign;
  1072. end;
  1073. procedure THTMLTopicRenderer.AddChar(C: char);
  1074. begin
  1075. if (Topic=nil) or (TextPtr=MaxBytes) or SuppressOutput then Exit;
  1076. Topic^.Text^[TextPtr]:=ord(C);
  1077. Inc(TextPtr);
  1078. if (C>#15) and ((C<>' ') or (InPreFormatted=true)) then
  1079. AnyCharsInLine:=true;
  1080. end;
  1081. procedure THTMLTopicRenderer.AddCharAt(C: char;AtPtr : sw_word);
  1082. begin
  1083. if (Topic=nil) or (TextPtr=MaxBytes) or SuppressOutput then Exit;
  1084. if AtPtr>TextPtr then
  1085. AtPtr:=TextPtr
  1086. else
  1087. begin
  1088. Move(Topic^.Text^[AtPtr],Topic^.Text^[AtPtr+1],TextPtr-AtPtr);
  1089. end;
  1090. Topic^.Text^[AtPtr]:=ord(C);
  1091. Inc(TextPtr);
  1092. end;
  1093. procedure THTMLTopicRenderer.AddText(const S: string);
  1094. var I: sw_integer;
  1095. begin
  1096. for I:=1 to length(S) do
  1097. AddChar(S[I]);
  1098. end;
  1099. function THTMLTopicRenderer.ComputeTextLength(TStart,TEnd : sw_word) : sw_word;
  1100. var I,tot: sw_integer;
  1101. begin
  1102. tot:=0;
  1103. i:=TStart;
  1104. while i<= TEnd-1 do
  1105. begin
  1106. inc(tot);
  1107. case chr(Topic^.Text^[i]) of
  1108. hscLink,hscCode,
  1109. hscCenter,hscRight,
  1110. hscNamedMark,hscNormText :
  1111. Dec(tot);{ Do not increase tot }
  1112. hscDirect:
  1113. begin
  1114. Inc(i); { Skip next }
  1115. //Inc(tot);
  1116. end;
  1117. hscTextAttr,
  1118. hscTextColor:
  1119. begin
  1120. Inc(i);
  1121. Dec(tot);
  1122. end;
  1123. end;
  1124. inc(i);
  1125. end;
  1126. ComputeTextLength:=tot;
  1127. end;
  1128. function THTMLTopicRenderer.AddTextAt(const S: String;AtPtr : sw_word) : sw_word;
  1129. var
  1130. i,slen,len : sw_word;
  1131. begin
  1132. if (Topic=nil) or (TextPtr>=MaxBytes) or SuppressOutput then Exit;
  1133. slen:=length(s);
  1134. if TextPtr+slen>=MaxBytes then
  1135. slen:=MaxBytes-TextPtr;
  1136. if AtPtr>TextPtr then
  1137. AtPtr:=TextPtr
  1138. else
  1139. begin
  1140. len:=TextPtr-AtPtr;
  1141. Move(Topic^.Text^[AtPtr],Topic^.Text^[AtPtr+slen],len);
  1142. end;
  1143. for i:=1 to slen do
  1144. begin
  1145. Topic^.Text^[AtPtr]:=ord(S[i]);
  1146. Inc(TextPtr);
  1147. inc(AtPtr);
  1148. if (TextPtr=MaxBytes) then Exit;
  1149. end;
  1150. AddTextAt:=slen;
  1151. end;
  1152. function THTMLTopicRenderer.GetSectionColor(Section: THTMLSection; var Color: byte): boolean;
  1153. begin
  1154. GetSectionColor:=HTMLGetSectionColor(Section,Color);
  1155. end;
  1156. function THTMLTopicRenderer.BuildTopic(P: PTopic; AURL: string; HTMLFile: PTextFile;
  1157. ATopicLinks: PTopicLinkCollection): boolean;
  1158. var OK: boolean;
  1159. TP: pointer;
  1160. I: sw_integer;
  1161. begin
  1162. URL:=AURL;
  1163. Topic:=P; TopicLinks:=ATopicLinks;
  1164. OK:=Assigned(Topic) and Assigned(HTMLFile) and Assigned(TopicLinks);
  1165. if OK then
  1166. begin
  1167. if (Topic^.TextSize<>0) and Assigned(Topic^.Text) then
  1168. begin
  1169. FreeMem(Topic^.Text,Topic^.TextSize);
  1170. Topic^.TextSize:=0; Topic^.Text:=nil;
  1171. end;
  1172. Topic^.TextSize:=MaxHelpTopicSize;
  1173. GetMem(Topic^.Text,Topic^.TextSize);
  1174. TopicTitle:='';
  1175. InTitle:=false; InBody:={false}true; InAnchor:=false;
  1176. InParagraph:=false; InPreformatted:=false;
  1177. Indent:=0; CurHeadLevel:=0;
  1178. PAlign:=paLeft;
  1179. TextPtr:=0; LinkPtr:=0;
  1180. AnyCharsInLine:=false;
  1181. LastTextChar:=#0;
  1182. SuppressUntil:='';
  1183. SuppressOutput:=false;
  1184. OK:=Process(HTMLFile);
  1185. if OK then
  1186. begin
  1187. { --- topic links --- }
  1188. if (Topic^.Links<>nil) and (Topic^.LinkSize>0) then
  1189. begin
  1190. FreeMem(Topic^.Links,Topic^.LinkSize);
  1191. Topic^.Links:=nil; Topic^.LinkCount:=0;
  1192. end;
  1193. Topic^.LinkCount:=LinkPtr{TopicLinks^.Count}; { <- eeeeeek! }
  1194. GetMem(Topic^.Links,Topic^.LinkSize);
  1195. if Topic^.LinkCount>0 then { FP causes numeric RTE 215 without this }
  1196. for I:=0 to Min(Topic^.LinkCount-1,High(LinkIndexes)-1) do
  1197. begin
  1198. {$IFDEF WDEBUG}
  1199. DebugMessageS({$i %file%},' Indexing links ('+inttostr(i)+')'+topiclinks^.at(linkindexes[i])^,{$i %line%},'1',0,0);
  1200. {$endif WDEBUG}
  1201. Topic^.Links^[I].FileID:=Topic^.FileID;
  1202. Topic^.Links^[I].Context:=EncodeHTMLCtx(Topic^.FileID,LinkIndexes[I]+1);
  1203. end;
  1204. {$IFDEF WDEBUG}
  1205. if Topic^.Linkcount>High(linkindexes) then
  1206. DebugMessageS({$i %file%},' Maximum links exceeded ('+inttostr(Topic^.LinkCount)+') '+URL,{$i %line%},'1',0,0);
  1207. {$endif WDEBUG}
  1208. { --- topic text --- }
  1209. GetMem(TP,TextPtr);
  1210. Move(Topic^.Text^,TP^,TextPtr);
  1211. FreeMem(Topic^.Text,Topic^.TextSize);
  1212. Topic^.Text:=TP; Topic^.TextSize:=TextPtr;
  1213. end
  1214. else
  1215. begin
  1216. DisposeTopic(Topic);
  1217. Topic:=nil;
  1218. end;
  1219. end;
  1220. BuildTopic:=OK;
  1221. end;
  1222. Function TCHMTopicRenderer.CanonicalizeURL(const Base,Relative:String):string;
  1223. begin
  1224. if copy(relative,1,7)<>'ms-its:' then
  1225. CanonicalizeUrl:=combinepaths(relative,base)
  1226. else
  1227. CanonicalizeUrl:=relative;
  1228. end;
  1229. constructor TCustomHTMLHelpFile.Init(AID: word);
  1230. begin
  1231. inherited Init(AID);
  1232. New(Renderer, Init);
  1233. New(TopicLinks, Init(50,500));
  1234. end;
  1235. function TCustomHTMLHelpFile.SearchTopic(HelpCtx: THelpCtx): PTopic;
  1236. function MatchCtx(P: PTopic): boolean;
  1237. begin
  1238. MatchCtx:=P^.HelpCtx=HelpCtx;
  1239. end;
  1240. var FileID,LinkNo: word;
  1241. P: PTopic;
  1242. FName: string;
  1243. begin
  1244. DecodeHTMLCtx(HelpCtx,FileID,LinkNo);
  1245. if (HelpCtx<>0) and (FileID<>ID) then P:=nil else
  1246. if (FileID=ID) and (LinkNo>TopicLinks^.Count) then P:=nil else
  1247. begin
  1248. P:=Topics^.FirstThat(@MatchCtx);
  1249. if P=nil then
  1250. begin
  1251. if LinkNo=0 then
  1252. FName:=DefaultFileName
  1253. else
  1254. FName:=TopicLinks^.At(LinkNo-1)^;
  1255. P:=NewTopic(ID,HelpCtx,0,FName,nil,0);
  1256. Topics^.Insert(P);
  1257. end;
  1258. end;
  1259. SearchTopic:=P;
  1260. end;
  1261. function TCustomHTMLHelpFile.FormatLink(const s:String):string;
  1262. begin
  1263. formatlink:=formatpath(s);
  1264. end;
  1265. function TCustomHTMLHelpFile.GetTopicInfo(T: PTopic) : string;
  1266. var OK: boolean;
  1267. Name: string;
  1268. Link,Bookmark: string;
  1269. P: sw_integer;
  1270. begin
  1271. Bookmark:='';
  1272. OK:=T<>nil;
  1273. if OK then
  1274. begin
  1275. if T^.HelpCtx=0 then
  1276. begin
  1277. Name:=DefaultFileName;
  1278. P:=0;
  1279. end
  1280. else
  1281. begin
  1282. Link:=TopicLinks^.At((T^.HelpCtx and $ffff)-1)^;
  1283. {$IFDEF WDEBUG}
  1284. DebugMessageS({$i %file%},'(Topicinfo) Link before formatpath "'+link+'"',{$i %line%},'1',0,0);
  1285. {$ENDIF WDEBUG}
  1286. Link:=FormatLink(Link);
  1287. {$IFDEF WDEBUG}
  1288. DebugMessageS({$i %file%},'(Topicinfo) Link after formatpath "'+link+'"',{$i %line%},'1',0,0);
  1289. {$ENDIF WDEBUG}
  1290. P:=Pos('#',Link);
  1291. if P>0 then
  1292. begin
  1293. Bookmark:=copy(Link,P+1,length(Link));
  1294. Link:=copy(Link,1,P-1);
  1295. end;
  1296. { if CurFileName='' then Name:=Link else
  1297. Name:=CompletePath(CurFileName,Link);}
  1298. Name:=Link;
  1299. end;
  1300. end;
  1301. GetTopicInfo:=Name+'#'+BookMark;
  1302. end;
  1303. function TCustomHTMLHelpFile.ReadTopic(T: PTopic): boolean;
  1304. var OK: boolean;
  1305. HTMLFile: PMemoryTextFile;
  1306. Name: string;
  1307. Link,Bookmark: string;
  1308. P: sw_integer;
  1309. begin
  1310. Bookmark:='';
  1311. OK:=T<>nil;
  1312. if OK then
  1313. begin
  1314. if T^.HelpCtx=0 then
  1315. begin
  1316. Name:=DefaultFileName;
  1317. P:=0;
  1318. end
  1319. else
  1320. begin
  1321. Link:=TopicLinks^.At((T^.HelpCtx and $ffff)-1)^;
  1322. {$IFDEF WDEBUG}
  1323. DebugMessageS({$i %file%},'(ReadTopic) Link before formatpath "'+link+'"',{$i %line%},'1',0,0);
  1324. {$ENDIF WDEBUG}
  1325. Link:=FormatPath(Link);
  1326. {$IFDEF WDEBUG}
  1327. DebugMessageS({$i %file%},'(ReadTopic) Link before formatpath "'+link+'"',{$i %line%},'1',0,0);
  1328. {$ENDIF WDEBUG}
  1329. P:=Pos('#',Link);
  1330. if P>0 then
  1331. begin
  1332. Bookmark:=copy(Link,P+1,length(Link));
  1333. Link:=copy(Link,1,P-1);
  1334. end;
  1335. { if CurFileName='' then Name:=Link else
  1336. Name:=CompletePath(CurFileName,Link);}
  1337. Name:=Link;
  1338. end;
  1339. HTMLFile:=nil;
  1340. if Name<>'' then
  1341. HTMLFile:=New(PDOSTextFile, Init(Name));
  1342. if (HTMLFile=nil) and (CurFileName<>'') then
  1343. begin
  1344. Name:=CurFileName;
  1345. HTMLFile:=New(PDOSTextFile, Init(Name));
  1346. end;
  1347. if (HTMLFile=nil) then
  1348. begin
  1349. {$IFDEF WDEBUG}
  1350. DebugMessageS({$i %file%},'(ReadTopic) Filename not known: "'+link+'"',{$i %line%},'1',0,0);
  1351. {$ENDIF WDEBUG}
  1352. end;
  1353. if (p>1) and (HTMLFile=nil) then
  1354. begin
  1355. {$IFDEF WDEBUG}
  1356. if p>0 then
  1357. DebugMessage(Name,Link+'#'+Bookmark+' not found',1,1)
  1358. else
  1359. DebugMessage(Name,Link+' not found',1,1);
  1360. {$endif WDEBUG}
  1361. New(HTMLFile, Init);
  1362. HTMLFile^.AddLine('<HEAD><TITLE>'+msg_pagenotavailable+'</TITLE></HEAD>');
  1363. HTMLFile^.AddLine(
  1364. '<BODY>'+
  1365. FormatStrStr(msg_cantaccessurl,Name)+'<br><br>'+
  1366. '</BODY>');
  1367. end;
  1368. OK:=Renderer^.BuildTopic(T,Name,HTMLFile,TopicLinks);
  1369. if OK then
  1370. CurFileName:=Name
  1371. else
  1372. begin
  1373. {$IFDEF WDEBUG}
  1374. if p>0 then
  1375. DebugMessage(Name,Link+'#'+Bookmark+' not found',1,1)
  1376. else
  1377. DebugMessage(Name,Link+' not found',1,1);
  1378. {$endif WDEBUG}
  1379. end;
  1380. if HTMLFile<>nil then Dispose(HTMLFile, Done);
  1381. if BookMark='' then
  1382. T^.StartNamedMark:=0
  1383. else
  1384. begin
  1385. P:=T^.GetNamedMarkIndex(BookMark);
  1386. {$IFDEF WDEBUG}
  1387. if p=-1 then
  1388. DebugMessage(Name,Link+'#'+Bookmark+' bookmark not found',1,1);
  1389. {$endif WDEBUG}
  1390. T^.StartNamedMark:=P+1;
  1391. end;
  1392. end;
  1393. ReadTopic:=OK;
  1394. end;
  1395. destructor TCustomHTMLHelpFile.Done;
  1396. begin
  1397. inherited Done;
  1398. if Renderer<>nil then Dispose(Renderer, Done);
  1399. if TopicLinks<>nil then Dispose(TopicLinks, Done);
  1400. end;
  1401. constructor THTMLHelpFile.Init(AFileName: string; AID: word; ATOCEntry: string);
  1402. begin
  1403. if inherited Init(AID)=false then Fail;
  1404. DefaultFileName:=AFileName; TOCEntry:=ATOCEntry;
  1405. if DefaultFileName='' then
  1406. begin
  1407. Done;
  1408. Fail;
  1409. end;
  1410. end;
  1411. function THTMLHelpFile.LoadIndex: boolean;
  1412. begin
  1413. IndexEntries^.Insert(NewIndexEntry(TOCEntry,ID,0));
  1414. LoadIndex:=true;
  1415. end;
  1416. constructor THTMLIndexHelpFile.Init(AFileName: string; AID: word);
  1417. begin
  1418. inherited Init(AID);
  1419. IndexFileName:=AFileName;
  1420. end;
  1421. function THTMLIndexHelpFile.LoadIndex: boolean;
  1422. function FormatAlias(Alias: string): string;
  1423. begin
  1424. if Assigned(HelpFacility) then
  1425. if length(Alias)>HelpFacility^.IndexTabSize-4 then
  1426. Alias:=Trim(copy(Alias,1,HelpFacility^.IndexTabSize-4-2))+'..';
  1427. FormatAlias:=Alias;
  1428. end;
  1429. (*procedure AddDoc(P: PHTMLLinkScanDocument);
  1430. var I: sw_integer;
  1431. TLI: THelpCtx;
  1432. begin
  1433. for I:=1 to P^.GetAliasCount do
  1434. begin
  1435. TLI:=TopicLinks^.AddItem(P^.GetName);
  1436. TLI:=EncodeHTMLCtx(ID,TLI+1);
  1437. IndexEntries^.Insert(NewIndexEntry(FormatAlias(P^.GetAlias(I-1)),ID,TLI));
  1438. end;
  1439. end;*)
  1440. var S: PBufStream;
  1441. LS: PHTMLLinkScanner;
  1442. OK: boolean;
  1443. TLI: THelpCtx;
  1444. I,J: sw_integer;
  1445. begin
  1446. New(S, Init(IndexFileName,stOpenRead,4096));
  1447. OK:=Assigned(S);
  1448. if OK then
  1449. begin
  1450. New(LS, LoadDocuments(S^));
  1451. OK:=Assigned(LS);
  1452. if OK then
  1453. begin
  1454. LS^.SetBaseDir(DirOf(IndexFileName));
  1455. for I:=0 to LS^.GetDocumentCount-1 do
  1456. begin
  1457. TLI:=TopicLinks^.AddItem(LS^.GetDocumentURL(I));
  1458. TLI:=EncodeHTMLCtx(ID,TLI+1);
  1459. for J:=0 to LS^.GetDocumentAliasCount(I)-1 do
  1460. IndexEntries^.Insert(NewIndexEntry(
  1461. FormatAlias(LS^.GetDocumentAlias(I,J)),ID,TLI));
  1462. end;
  1463. Dispose(LS, Done);
  1464. end;
  1465. Dispose(S, Done);
  1466. end;
  1467. LoadIndex:=OK;
  1468. end;
  1469. constructor TChmHelpFile.Init(AFileName: string; AID: word);
  1470. begin
  1471. if inherited Init(AID)=false then
  1472. Fail;
  1473. Dispose(renderer,done);
  1474. renderer:=New(PCHMTopicRenderer, Init);
  1475. DefaultFileName:=AFileName;
  1476. if (DefaultFileName='') or not ExistsFile(DefaultFilename) then
  1477. begin
  1478. Done;
  1479. Fail;
  1480. end
  1481. else
  1482. chmw:=TCHMWrapper.Create(DefaultFileName);
  1483. end;
  1484. function TChmHelpFile.LoadIndex: boolean;
  1485. begin
  1486. loadindex:=false;
  1487. if assigned(chmw) then
  1488. loadindex:=chmw.loadindex(id,TopicLinks,IndexEntries,helpfacility);
  1489. end;
  1490. function TCHMHelpFile.FormatLink(const s:String):string;
  1491. // do not reformat for chms, we assume them internally consistent.
  1492. begin
  1493. formatlink:=s;
  1494. end;
  1495. function TChmHelpFile.SearchTopic(HelpCtx: THelpCtx): PTopic;
  1496. function MatchCtx(P: PTopic): boolean;
  1497. begin
  1498. MatchCtx:=P^.HelpCtx=HelpCtx;
  1499. end;
  1500. var FileID,LinkNo: word;
  1501. P: PTopic;
  1502. FName: string;
  1503. begin
  1504. DecodeHTMLCtx(HelpCtx,FileID,LinkNo);
  1505. if (HelpCtx<>0) and (FileID<>ID) then P:=nil else
  1506. if (FileID=ID) and (LinkNo>TopicLinks^.Count) then P:=nil else
  1507. begin
  1508. P:=Topics^.FirstThat(@MatchCtx);
  1509. if P=nil then
  1510. begin
  1511. if LinkNo=0 then
  1512. FName:=DefaultFileName
  1513. else
  1514. FName:=TopicLinks^.At(LinkNo-1)^;
  1515. P:=NewTopic(ID,HelpCtx,0,FName,nil,0);
  1516. Topics^.Insert(P);
  1517. end;
  1518. end;
  1519. SearchTopic:=P;
  1520. end;
  1521. function TChmHelpFile.GetTopicInfo(T: PTopic) : string;
  1522. var OK: boolean;
  1523. Name: string;
  1524. Link,Bookmark: string;
  1525. P: sw_integer;
  1526. begin
  1527. Bookmark:='';
  1528. OK:=T<>nil;
  1529. if OK then
  1530. begin
  1531. if T^.HelpCtx=0 then
  1532. begin
  1533. Name:=DefaultFileName;
  1534. P:=0;
  1535. end
  1536. else
  1537. begin
  1538. Link:=TopicLinks^.At((T^.HelpCtx and $ffff)-1)^;
  1539. Link:=FormatPath(Link);
  1540. {$IFDEF WDEBUG}
  1541. DebugMessageS({$i %file%},' Looking for "'+Link+'"',{$i %line%},'1',0,0);
  1542. {$endif WDEBUG}
  1543. P:=Pos('#',Link);
  1544. if P>0 then
  1545. begin
  1546. Bookmark:=copy(Link,P+1,length(Link));
  1547. Link:=copy(Link,1,P-1);
  1548. end;
  1549. { if CurFileName='' then Name:=Link else
  1550. Name:=CompletePath(CurFileName,Link);}
  1551. Name:=Link;
  1552. end;
  1553. end;
  1554. GetTopicInfo:=Name+'#'+BookMark;
  1555. end;
  1556. function TChmHelpFile.ReadTopic(T: PTopic): boolean;
  1557. var OK: boolean;
  1558. HTMLFile: PMemoryTextFile;
  1559. Name: string;
  1560. Link,Bookmark: string;
  1561. P: sw_integer;
  1562. begin
  1563. Bookmark:='';
  1564. OK:=T<>nil;
  1565. if OK then
  1566. begin
  1567. if T^.HelpCtx=0 then
  1568. begin
  1569. Name:=DefaultFileName;
  1570. P:=0;
  1571. end
  1572. else
  1573. begin
  1574. Link:=TopicLinks^.At((T^.HelpCtx and $ffff)-1)^;
  1575. {$IFDEF WDEBUG}
  1576. DebugMessageS({$i %file%},' Looking for "'+Link+'"',{$i %line%},'1',0,0);
  1577. {$endif WDEBUG}
  1578. Link:=FormatLink(Link);
  1579. {$IFDEF WDEBUG}
  1580. DebugMessageS({$i %file%},' Looking for (after formatlink) "'+Link+'"',{$i %line%},'1',0,0);
  1581. {$endif WDEBUG}
  1582. P:=Pos('#',Link);
  1583. if P>0 then
  1584. begin
  1585. Bookmark:=copy(Link,P+1,length(Link));
  1586. Link:=copy(Link,1,P-1);
  1587. {$IFDEF WDEBUG}
  1588. debugMessageS({$i %file%},' Removed label: "'+Link+'"',{$i %line%},'1',0,0);
  1589. {$endif WDEBUG}
  1590. end;
  1591. { if CurFileName='' then Name:=Link else
  1592. Name:=CompletePath(CurFileName,Link);}
  1593. Name:=Link;
  1594. end;
  1595. HTMLFile:=nil;
  1596. if Name<>'' then
  1597. HTMLFile:=chmw.gettopic(name);
  1598. if (HTMLFile=nil) and (CurFileName<>'') then
  1599. begin
  1600. Name:=CurFileName;
  1601. HTMLFile:=chmw.gettopic(name);
  1602. end;
  1603. if (HTMLFile=nil) then
  1604. begin
  1605. {$IFDEF WDEBUG}
  1606. DebugMessage(Link,' filename not known :(',1,1);
  1607. {$endif WDEBUG}
  1608. end;
  1609. if (p>1) and (HTMLFile=nil) then
  1610. begin
  1611. {$IFDEF WDEBUG}
  1612. if p>0 then
  1613. DebugMessage(Name,Link+'#'+Bookmark+' not found',1,1)
  1614. else
  1615. DebugMessage(Name,Link+' not found',1,1);
  1616. {$endif WDEBUG}
  1617. New(HTMLFile, Init);
  1618. HTMLFile^.AddLine('<HEAD><TITLE>'+msg_pagenotavailable+'</TITLE></HEAD>');
  1619. HTMLFile^.AddLine(
  1620. '<BODY>'+
  1621. FormatStrStr(msg_cantaccessurl,Name)+'<br><br>'+
  1622. '</BODY>');
  1623. end;
  1624. OK:=Renderer^.BuildTopic(T,Name,HTMLFile,TopicLinks);
  1625. if OK then
  1626. CurFileName:=Name
  1627. else
  1628. begin
  1629. {$IFDEF WDEBUG}
  1630. if p>0 then
  1631. DebugMessage(Name,Link+'#'+Bookmark+' not found',1,1)
  1632. else
  1633. DebugMessage(Name,Link+' not found',1,1);
  1634. {$endif WDEBUG}
  1635. end;
  1636. if HTMLFile<>nil then Dispose(HTMLFile, Done);
  1637. if BookMark='' then
  1638. T^.StartNamedMark:=0
  1639. else
  1640. begin
  1641. P:=T^.GetNamedMarkIndex(BookMark);
  1642. {$IFDEF WDEBUG}
  1643. if p=-1 then
  1644. DebugMessage(Name,Link+'#'+Bookmark+' bookmark not found',1,1);
  1645. {$endif WDEBUG}
  1646. T^.StartNamedMark:=P+1;
  1647. end;
  1648. end;
  1649. ReadTopic:=OK;
  1650. end;
  1651. destructor TChmHelpFile.done;
  1652. begin
  1653. if assigned(chmw) then
  1654. chmw.free;
  1655. inherited Done;
  1656. end;
  1657. function CreateProcHTML(const FileName,Param: string;Index : longint): PHelpFile;
  1658. var H: PHelpFile;
  1659. begin
  1660. H:=nil;
  1661. if CompareText(copy(ExtOf(FileName),1,length(extHTML)),extHTML)=0 then
  1662. H:=New(PHTMLHelpFile, Init(FileName,Index,Param));
  1663. CreateProcHTML:=H;
  1664. end;
  1665. function CreateProcCHM(const FileName,Param: string;Index : longint): PHelpFile;
  1666. var H: PHelpFile;
  1667. begin
  1668. H:=nil;
  1669. if CompareText(copy(ExtOf(FileName),1,length(extCHM)),extCHM)=0 then
  1670. H:=New(PCHMHelpFile, Init(FileName,Index));
  1671. CreateProcCHM:=H;
  1672. end;
  1673. function CreateProcHTMLIndex(const FileName,Param: string;Index : longint): PHelpFile;
  1674. var H: PHelpFile;
  1675. begin
  1676. H:=nil;
  1677. if CompareText(ExtOf(FileName),extHTMLIndex)=0 then
  1678. H:=New(PHTMLIndexHelpFile, Init(FileName,Index));
  1679. CreateProcHTMLIndex:=H;
  1680. end;
  1681. procedure RegisterHelpType;
  1682. begin
  1683. RegisterHelpFileType({$ifdef FPC}@{$endif}CreateProcHTML);
  1684. RegisterHelpFileType({$ifdef FPC}@{$endif}CreateProcHTMLIndex);
  1685. RegisterHelpFileType({$ifdef FPC}@{$endif}CreateProcCHM);
  1686. end;
  1687. END.