whtmlhlp.pas 50 KB

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