2
0

whtmlhlp.pas 50 KB

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