whtmlhlp.pas 50 KB

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