mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-10 02:09:19 +02:00
1867 lines
50 KiB
ObjectPascal
1867 lines
50 KiB
ObjectPascal
{
|
||
This file is part of the Free Pascal Integrated Development Environment
|
||
Copyright (c) 1999-2000 by Berczi Gabor
|
||
|
||
See the file COPYING.FPC, included in this distribution,
|
||
for details about the copyright.
|
||
|
||
This program is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||
|
||
**********************************************************************}
|
||
unit WHTMLHlp;
|
||
|
||
interface
|
||
|
||
uses Objects,WHTML,WAnsi,WHelp,WChmHWrap;
|
||
|
||
const
|
||
extHTML = '.htm';
|
||
extHTMLIndex = '.htx';
|
||
extCHM = '.chm';
|
||
|
||
ListIndent = 2;
|
||
DefIndent = 4;
|
||
|
||
MaxTopicLinks = 24000; { maximum number of links on a single HTML page }
|
||
|
||
type
|
||
THTMLSection = (hsNone,hsHeading1,hsHeading2,hsHeading3,hsHeading4,hsHeading5,hsHeading6);
|
||
|
||
TParagraphAlign = (paLeft,paCenter,paRight);
|
||
|
||
PTableElement = ^TTableElement;
|
||
TTableElement = object(Tobject)
|
||
TextBegin,TextEnd, TextLength, NumNL : sw_word;
|
||
Alignment : TParagraphAlign;
|
||
NextEl : PTableElement;
|
||
constructor init(AAlignment : TParagraphAlign);
|
||
end;
|
||
|
||
PTableLine = ^TTableLine;
|
||
TTableLine = object(Tobject)
|
||
NumElements : sw_word;
|
||
Nextline : PTableLine;
|
||
FirstEl,LastEl : PTableElement;
|
||
constructor Init;
|
||
procedure AddElement(PTE : PTableElement);
|
||
destructor Done; virtual;
|
||
end;
|
||
|
||
PHTMLTopicRenderer = ^THTMLTopicRenderer;
|
||
PTable = ^TTable;
|
||
TTable = object(Tobject)
|
||
NumLines,NumCols : sw_word;
|
||
GlobalOffset,
|
||
GlobalTextBegin : sw_word;
|
||
WithBorder : boolean;
|
||
IsBar : boolean;
|
||
FirstLine : PTableLine;
|
||
LastLine : PTableLine;
|
||
PreviousTable : PTable;
|
||
Renderer : PHTMLTopicRenderer;
|
||
constructor Init(Previous : PTable);
|
||
procedure AddLine(PL : PTableLine);
|
||
procedure AddElement(PTE : PTableElement);
|
||
procedure TextInsert(Pos : sw_word;const S : string);
|
||
procedure FormatTable;
|
||
destructor Done; virtual;
|
||
end;
|
||
|
||
THTMLTopicRenderer = object(THTMLParser)
|
||
function BuildTopic(P: PTopic; AURL: string; HTMLFile: PTextFile; ATopicLinks: PTopicLinkCollection): boolean;
|
||
public
|
||
function DocAddTextChar(C: char): boolean; virtual;
|
||
procedure DocSoftBreak; virtual;
|
||
procedure DocTYPE; virtual;
|
||
procedure DocHTML(Entered: boolean); virtual;
|
||
procedure DocHEAD(Entered: boolean); virtual;
|
||
procedure DocMETA; virtual;
|
||
procedure DocTITLE(Entered: boolean); virtual;
|
||
procedure DocBODY(Entered: boolean); virtual;
|
||
procedure DocAnchor(Entered: boolean); virtual;
|
||
procedure DocUnknownTag; virtual;
|
||
procedure DocHeading(Level: integer; Entered: boolean); virtual;
|
||
procedure DocParagraph(Entered: boolean); virtual;
|
||
procedure DocBreak; virtual;
|
||
procedure DocImage; virtual;
|
||
procedure DocProcessComment(Comment: string); virtual;
|
||
procedure DocBold(Entered: boolean); virtual;
|
||
procedure DocCite(Entered: boolean); virtual;
|
||
procedure DocCode(Entered: boolean); virtual;
|
||
procedure DocEmphasized(Entered: boolean); virtual;
|
||
procedure DocItalic(Entered: boolean); virtual;
|
||
procedure DocKbd(Entered: boolean); virtual;
|
||
procedure DocPreformatted(Entered: boolean); virtual;
|
||
procedure DocSample(Entered: boolean); virtual;
|
||
procedure DocStrong(Entered: boolean); virtual;
|
||
procedure DocTeleType(Entered: boolean); virtual;
|
||
procedure DocVariable(Entered: boolean); virtual;
|
||
procedure DocSpan(Entered: boolean); virtual;
|
||
procedure DocList(Entered: boolean); virtual;
|
||
procedure DocOrderedList(Entered: boolean); virtual;
|
||
procedure DocListItem(Entered: boolean); virtual;
|
||
procedure DocDefList(Entered: boolean); virtual;
|
||
procedure DocDefTerm(Entered: boolean); virtual;
|
||
procedure DocDefExp(Entered: boolean); virtual;
|
||
procedure DocTable(Entered: boolean); virtual;
|
||
procedure DocTableRow(Entered: boolean); virtual;
|
||
procedure DocTableHeaderItem(Entered: boolean); virtual;
|
||
procedure DocTableItem(Entered: boolean); virtual;
|
||
procedure DocHorizontalRuler; virtual;
|
||
function CanonicalizeURL(const Base,Relative:String):string; virtual;
|
||
procedure Resolve( href: ansistring; var AFileId,ALinkId : sw_integer); virtual;
|
||
public
|
||
function GetSectionColor(Section: THTMLSection; var Color: byte): boolean; virtual;
|
||
private
|
||
URL: string;
|
||
Topic: PTopic;
|
||
TopicLinks: PTopicLinkCollection;
|
||
TextPtr: sw_word;
|
||
InTitle: boolean;
|
||
InBody: boolean;
|
||
InAnchor: boolean;
|
||
InParagraph: boolean;
|
||
InPreformatted: boolean;
|
||
SuppressOutput: boolean;
|
||
SuppressUntil : string;
|
||
InDefExp: boolean;
|
||
TopicTitle: string;
|
||
Indent: integer;
|
||
AnyCharsInLine,
|
||
LastAnsiLoadFailed: boolean;
|
||
CurHeadLevel: integer;
|
||
PAlign: TParagraphAlign;
|
||
LinkIndexes: array[0..MaxTopicLinks] of sw_integer;
|
||
FileIDLinkIndexes: array[0..MaxTopicLinks] of sw_integer;
|
||
LinkPtr: sw_integer;
|
||
LastTextChar: char;
|
||
{ Anchor: TAnchor;}
|
||
{ Table stuff }
|
||
CurrentTable : PTable;
|
||
procedure AddText(const S: string);
|
||
procedure AddChar(C: char);
|
||
procedure AddCharAt(C: char;AtPtr : sw_word);
|
||
function AddTextAt(const S: string;AtPtr : sw_word) : sw_word;
|
||
function ComputeTextLength(TStart,TEnd : sw_word) : sw_word;
|
||
end;
|
||
|
||
PCHMTopicRenderer = ^TCHMTopicRenderer;
|
||
TCHMTopicRenderer = object(THTMLTopicRenderer)
|
||
function CanonicalizeURL(const Base,Relative:String):string; virtual;
|
||
procedure Resolve( href: ansistring; var AFileId,ALinkId : sw_integer); virtual;
|
||
end;
|
||
|
||
PCustomHTMLHelpFile = ^TCustomHTMLHelpFile;
|
||
TCustomHTMLHelpFile = object(THelpFile)
|
||
constructor Init(AID: word);
|
||
destructor Done; virtual;
|
||
public
|
||
Renderer: PHTMLTopicRenderer;
|
||
function GetTopicInfo(T: PTopic) : string; virtual;
|
||
function SearchTopic(HelpCtx: THelpCtx): PTopic; virtual;
|
||
function ReadTopic(T: PTopic): boolean; virtual;
|
||
function FormatLink(const s:String):string; virtual;
|
||
private
|
||
DefaultFileName: string;
|
||
CurFileName: string;
|
||
TopicLinks: PTopicLinkCollection;
|
||
end;
|
||
|
||
PHTMLHelpFile = ^THTMLHelpFile;
|
||
THTMLHelpFile = object(TCustomHTMLHelpFile)
|
||
constructor Init(AFileName: string; AID: word; ATOCEntry: string);
|
||
public
|
||
function LoadIndex: boolean; virtual;
|
||
private
|
||
TOCEntry: string;
|
||
end;
|
||
|
||
PCHMHelpFile = ^TCHMHelpFile;
|
||
TCHMHelpFile = object(TCustomHTMLHelpFile)
|
||
constructor Init(AFileName: string; AID: word);
|
||
destructor Done; virtual;
|
||
public
|
||
function LoadIndex: boolean; virtual;
|
||
function ReadTopic(T: PTopic): boolean; virtual;
|
||
function GetTopicInfo(T: PTopic) : string; virtual;
|
||
function SearchTopic(HelpCtx: THelpCtx): PTopic; virtual;
|
||
function FormatLink(const s:String):string; virtual;
|
||
private
|
||
Chmw: TCHMWrapper;
|
||
end;
|
||
|
||
PHTMLIndexHelpFile = ^THTMLIndexHelpFile;
|
||
THTMLIndexHelpFile = object(TCustomHTMLHelpFile)
|
||
constructor Init(AFileName: string; AID: word);
|
||
function LoadIndex: boolean; virtual;
|
||
private
|
||
IndexFileName: string;
|
||
end;
|
||
|
||
PHTMLAnsiView = ^THTMLAnsiView;
|
||
PHTMLAnsiConsole = ^THTMLAnsiConsole;
|
||
|
||
THTMLAnsiConsole = Object(TAnsiViewConsole)
|
||
MaxX,MaxY : integer;
|
||
procedure GotoXY(X,Y: integer); virtual;
|
||
end;
|
||
|
||
THTMLAnsiView = Object(TAnsiView)
|
||
private
|
||
HTMLOwner : PHTMLTopicRenderer;
|
||
HTMLConsole : PHTMLAnsiConsole;
|
||
public
|
||
constructor Init(AOwner: PHTMLTopicRenderer);
|
||
procedure CopyToHTML;
|
||
end;
|
||
|
||
THTMLGetSectionColorProc = function(Section: THTMLSection; var Color: byte): boolean;
|
||
|
||
function DefHTMLGetSectionColor(Section: THTMLSection; var Color: byte): boolean;
|
||
|
||
const HTMLGetSectionColor : THTMLGetSectionColorProc = {$ifdef fpc}@{$endif}DefHTMLGetSectionColor;
|
||
|
||
procedure RegisterHelpType;
|
||
|
||
implementation
|
||
|
||
uses
|
||
Views,WConsts,WUtils,WViews,WHTMLScn;
|
||
|
||
|
||
|
||
constructor TTableElement.init(AAlignment : TParagraphAlign);
|
||
begin
|
||
Alignment:=AAlignment;
|
||
NextEl:=nil;
|
||
TextBegin:=0;
|
||
TextEnd:=0;
|
||
end;
|
||
|
||
|
||
{ TTableLine methods }
|
||
|
||
constructor TTableLine.Init;
|
||
begin
|
||
NumElements:=0;
|
||
NextLine:=nil;
|
||
Firstel:=nil;
|
||
LastEl:=nil;
|
||
end;
|
||
|
||
procedure TTableLine.AddElement(PTE : PTableElement);
|
||
begin
|
||
if not assigned(FirstEl) then
|
||
FirstEl:=PTE;
|
||
if assigned(LastEl) then
|
||
LastEl^.NextEl:=PTE;
|
||
LastEl:=PTE;
|
||
Inc(NumElements);
|
||
end;
|
||
|
||
destructor TTableLine.Done;
|
||
begin
|
||
LastEl:=FirstEl;
|
||
while assigned(LastEl) do
|
||
begin
|
||
LastEl:=FirstEl^.NextEl;
|
||
Dispose(FirstEl,Done);
|
||
FirstEl:=LastEl;
|
||
end;
|
||
inherited Done;
|
||
end;
|
||
|
||
{ TTable methods }
|
||
constructor TTable.Init(Previous : PTable);
|
||
begin
|
||
PreviousTable:=Previous;
|
||
NumLines:=0;
|
||
NumCols:=0;
|
||
GlobalOffset:=0;
|
||
GlobalTextBegin:=0;
|
||
FirstLine:=nil;
|
||
LastLine:=nil;
|
||
|
||
WithBorder:=false;
|
||
IsBar:=false;
|
||
end;
|
||
|
||
procedure TTable.AddLine(PL : PTableLine);
|
||
begin
|
||
If not assigned(FirstLine) then
|
||
FirstLine:=PL;
|
||
if Assigned(LastLine) then
|
||
LastLine^.NextLine:=PL;
|
||
LastLine:=PL;
|
||
Inc(NumLines);
|
||
end;
|
||
|
||
procedure TTable.AddElement(PTE : PTableElement);
|
||
begin
|
||
if assigned(LastLine) then
|
||
begin
|
||
LastLine^.AddElement(PTE);
|
||
If LastLine^.NumElements>NumCols then
|
||
NumCols:=LastLine^.NumElements;
|
||
end;
|
||
end;
|
||
|
||
procedure TTable.TextInsert(Pos : sw_word;const S : string);
|
||
var
|
||
i : sw_word;
|
||
begin
|
||
if S='' then
|
||
exit;
|
||
i:=Renderer^.AddTextAt(S,Pos+GlobalOffset);
|
||
GlobalOffset:=GlobalOffset+i;
|
||
end;
|
||
|
||
procedure TTable.FormatTable;
|
||
const
|
||
MaxCols = 200;
|
||
type
|
||
TLengthArray = Array [ 1 .. MaxCols] of sw_word;
|
||
PLengthArray = ^TLengthArray;
|
||
var
|
||
ColLengthArray : PLengthArray;
|
||
RowSizeArray : PLengthArray;
|
||
CurLine : PTableLine;
|
||
CurEl : PTableElement;
|
||
Align : TParagraphAlign;
|
||
TextBegin,TextEnd : sw_word;
|
||
i,j,k,Length : sw_word;
|
||
begin
|
||
{ do nothing for single cell tables }
|
||
if (NumCols=1) and (NumLines=1) then
|
||
exit;
|
||
GetMem(ColLengthArray,Sizeof(sw_word)*NumCols);
|
||
FillChar(ColLengthArray^,Sizeof(sw_word)*NumCols,#0);
|
||
GetMem(RowSizeArray,Sizeof(sw_word)*NumLines);
|
||
FillChar(RowSizeArray^,Sizeof(sw_word)*NumLines,#0);
|
||
{ Compute the largest cell }
|
||
CurLine:=FirstLine;
|
||
For i:=1 to NumLines do
|
||
begin
|
||
CurEl:=CurLine^.FirstEl;
|
||
RowSizeArray^[i]:=1;
|
||
For j:=1 to NumCols do
|
||
begin
|
||
if not assigned(CurEl) then
|
||
break;
|
||
Length:=CurEl^.TextLength;
|
||
if assigned(CurEl^.NextEl) and
|
||
(CurEl^.NextEl^.TextBegin>CurEl^.TextEnd) then
|
||
Inc(Length,Renderer^.ComputeTextLength(
|
||
CurEl^.NextEl^.TextBegin+GlobalOffset,
|
||
CurEl^.TextBegin+GlobalOffset));
|
||
|
||
if Length>ColLengthArray^[j] then
|
||
ColLengthArray^[j]:=Length;
|
||
{ We need to handle multiline cells... }
|
||
if CurEl^.NumNL>=RowSizeArray^[i] then
|
||
RowSizeArray^[i]:=CurEl^.NumNL;
|
||
{ We don't handle multiline cells yet... }
|
||
if CurEl^.NumNL>=1 then
|
||
begin
|
||
for k:=CurEl^.TextBegin+GlobalOffset to
|
||
CurEl^.TextEnd+GlobalOffset do
|
||
if Renderer^.Topic^.Text^[k]=ord(hscLineBreak) then
|
||
Renderer^.Topic^.Text^[k]:=ord(' ');
|
||
end;
|
||
|
||
CurEl:=CurEl^.NextEl;
|
||
end;
|
||
CurLine:=CurLine^.NextLine;
|
||
end;
|
||
{ Adjust to largest cell }
|
||
CurLine:=FirstLine;
|
||
TextBegin:=GlobalTextBegin;
|
||
If (NumLines>0) and WithBorder then
|
||
Begin
|
||
TextInsert(TextBegin,#218);
|
||
For j:=1 to NumCols do
|
||
begin
|
||
TextInsert(TextBegin,CharStr(#196,ColLengthArray^[j]));
|
||
if j<NumCols then
|
||
TextInsert(TextBegin,#194);
|
||
end;
|
||
TextInsert(TextBegin,#191);
|
||
TextInsert(TextBegin,hscLineBreak);
|
||
End;
|
||
For i:=1 to NumLines do
|
||
begin
|
||
CurEl:=CurLine^.FirstEl;
|
||
For j:=1 to NumCols do
|
||
begin
|
||
if not assigned(CurEl) then
|
||
begin
|
||
Length:=0;
|
||
Align:=paLeft;
|
||
end
|
||
else
|
||
begin
|
||
TextBegin:=CurEl^.TextBegin;
|
||
TextEnd:=CurEl^.TextEnd;
|
||
{While (TextEnd>TextBegin) and
|
||
(Renderer^.Topic^.Text^[TextEnd+GlobalOffset]=ord(hscLineBreak)) do
|
||
dec(TextEnd); }
|
||
Length:=CurEl^.TextLength;
|
||
Align:=CurEl^.Alignment;
|
||
end;
|
||
if WithBorder then
|
||
TextInsert(TextBegin,#179)
|
||
else
|
||
TextInsert(TextBegin,' ');
|
||
if Length<ColLengthArray^[j] then
|
||
begin
|
||
case Align of
|
||
paLeft:
|
||
TextInsert(TextEnd,CharStr(' ',ColLengthArray^[j]-Length));
|
||
paRight:
|
||
TextInsert(TextBegin,CharStr(' ',ColLengthArray^[j]-Length));
|
||
paCenter:
|
||
begin
|
||
TextInsert(TextBegin,CharStr(' ',(ColLengthArray^[j]-Length) div 2));
|
||
TextInsert(TextEnd,CharStr(' ',(ColLengthArray^[j]-Length)- ((ColLengthArray^[j]-Length) div 2)));
|
||
end;
|
||
end;
|
||
end;
|
||
if Assigned(CurEl) then
|
||
CurEl:=CurEl^.NextEl;
|
||
end;
|
||
if WithBorder then
|
||
TextInsert(TextEnd,#179);
|
||
//TextInsert(TextEnd,hscLineBreak);
|
||
CurLine:=CurLine^.NextLine;
|
||
end;
|
||
If (NumLines>0) and WithBorder then
|
||
Begin
|
||
TextInsert(TextEnd,hscLineBreak);
|
||
TextInsert(TextEnd,#192);
|
||
For j:=1 to NumCols do
|
||
begin
|
||
TextInsert(TextEnd,CharStr(#196,ColLengthArray^[j]));
|
||
if j<NumCols then
|
||
TextInsert(TextEnd,#193);
|
||
end;
|
||
TextInsert(TextEnd,#217);
|
||
TextInsert(TextEnd,hscLineBreak);
|
||
End;
|
||
|
||
FreeMem(ColLengthArray,Sizeof(sw_word)*NumCols);
|
||
FreeMem(RowSizeArray,Sizeof(sw_word)*NumLines);
|
||
end;
|
||
|
||
destructor TTable.Done;
|
||
begin
|
||
LastLine:=FirstLine;
|
||
while assigned(LastLine) do
|
||
begin
|
||
LastLine:=FirstLine^.NextLine;
|
||
Dispose(FirstLine,Done);
|
||
FirstLine:=LastLine;
|
||
end;
|
||
if Assigned(PreviousTable) then
|
||
Inc(PreviousTable^.GlobalOffset,GlobalOffset);
|
||
inherited Done;
|
||
end;
|
||
|
||
|
||
{ THTMLAnsiConsole methods }
|
||
|
||
procedure THTMLAnsiConsole.GotoXY(X,Y : integer);
|
||
begin
|
||
if X>MaxX then MaxX:=X-1;
|
||
if Y>MaxY then MaxY:=Y-1;
|
||
inherited GotoXY(X,Y);
|
||
end;
|
||
|
||
{ THTMLAnsiView methods }
|
||
|
||
constructor THTMLAnsiView.Init(AOwner : PHTMLTopicRenderer);
|
||
var
|
||
R : TRect;
|
||
begin
|
||
if not assigned(AOwner) then
|
||
fail;
|
||
R.Assign(0,0,80,25);
|
||
inherited init(R,nil,nil);
|
||
HTMLOwner:=AOwner;
|
||
HTMLConsole:=New(PHTMLAnsiConsole,Init(@Self));
|
||
HTMLConsole^.HighVideo;
|
||
Dispose(Console,Done);
|
||
Console:=HTMLConsole;
|
||
HTMLConsole^.Size.X:=80;
|
||
HTMLConsole^.Size.Y:=25;
|
||
HTMLConsole^.ClrScr;
|
||
HTMLConsole^.MaxX:=-1;
|
||
HTMLConsole^.MaxY:=-1;
|
||
HTMLConsole^.BoundChecks:=0;
|
||
end;
|
||
|
||
procedure THTMLAnsiView.CopyToHTML;
|
||
var
|
||
Attr,NewAttr : byte;
|
||
c : char;
|
||
X,Y,Pos : longint;
|
||
begin
|
||
Attr:=(Buffer^[1] shr 8);
|
||
HTMLOwner^.AddChar(hscLineBreak);
|
||
HTMLOwner^.AddText(hscTextAttr+chr(Attr));
|
||
for Y:=0 to HTMLConsole^.MaxY-1 do
|
||
begin
|
||
for X:=0 to HTMLConsole^.MaxX-1 do
|
||
begin
|
||
Pos:=(Delta.Y*MaxViewWidth)+X+Y*MaxViewWidth;
|
||
NewAttr:=(Buffer^[Pos] shr 8);
|
||
if NewAttr <> Attr then
|
||
begin
|
||
Attr:=NewAttr;
|
||
HTMLOwner^.AddText(hscTextAttr+chr(Attr));
|
||
end;
|
||
c:= chr(Buffer^[Pos] and $ff);
|
||
if ord(c)>16 then
|
||
HTMLOwner^.AddChar(c)
|
||
else
|
||
begin
|
||
HTMLOwner^.AddChar(hscDirect);
|
||
HTMLOwner^.AddChar(c);
|
||
end;
|
||
end;
|
||
{ Write start of next line in normal color, for correct alignment }
|
||
HTMLOwner^.AddChar(hscNormText);
|
||
{ Force to set attr again at start of next line }
|
||
Attr:=0;
|
||
HTMLOwner^.AddChar(hscLineBreak);
|
||
end;
|
||
end;
|
||
|
||
function DefHTMLGetSectionColor(Section: THTMLSection; var Color: byte): boolean;
|
||
begin
|
||
Color:=0;
|
||
DefHTMLGetSectionColor:=false;
|
||
end;
|
||
|
||
function CharStr(C: char; Count: byte): string;
|
||
var S: string;
|
||
begin
|
||
S[0]:=chr(Count);
|
||
if Count>0 then FillChar(S[1],Count,C);
|
||
CharStr:=S;
|
||
end;
|
||
|
||
|
||
function THTMLTopicRenderer.DocAddTextChar(C: char): boolean;
|
||
var Added: boolean;
|
||
begin
|
||
Added:=false;
|
||
if InTitle then
|
||
begin
|
||
TopicTitle:=TopicTitle+C;
|
||
Added:=true;
|
||
end
|
||
else
|
||
if InBody then
|
||
begin
|
||
if (InPreFormatted) or (C<>#32) or (LastTextChar<>C) then
|
||
if (C<>#32) or (AnyCharsInLine=true) or (InPreFormatted=true) then
|
||
begin
|
||
AddChar(C);
|
||
LastTextChar:=C;
|
||
Added:=true;
|
||
end;
|
||
end;
|
||
DocAddTextChar:=Added;
|
||
end;
|
||
|
||
procedure THTMLTopicRenderer.DocSoftBreak;
|
||
begin
|
||
if InPreformatted then DocBreak else
|
||
if AnyCharsInLine and not assigned(CurrentTable) then
|
||
begin
|
||
AddChar(' ');
|
||
LastTextChar:=' ';
|
||
end;
|
||
end;
|
||
|
||
procedure THTMLTopicRenderer.DocTYPE;
|
||
begin
|
||
end;
|
||
|
||
procedure THTMLTopicRenderer.DocHTML(Entered: boolean);
|
||
begin
|
||
end;
|
||
|
||
procedure THTMLTopicRenderer.DocHEAD(Entered: boolean);
|
||
begin
|
||
end;
|
||
|
||
procedure THTMLTopicRenderer.DocMETA;
|
||
begin
|
||
end;
|
||
|
||
procedure THTMLTopicRenderer.DocTITLE(Entered: boolean);
|
||
begin
|
||
if Entered then
|
||
begin
|
||
TopicTitle:='';
|
||
end
|
||
else
|
||
begin
|
||
{ render topic title here }
|
||
if TopicTitle<>'' then
|
||
begin
|
||
AddText(' '+TopicTitle+' <20>'); DocBreak;
|
||
AddText(' '+CharStr('<27>',length(TopicTitle)+3)); DocBreak;
|
||
end;
|
||
end;
|
||
InTitle:=Entered;
|
||
end;
|
||
|
||
procedure THTMLTopicRenderer.DocBODY(Entered: boolean);
|
||
begin
|
||
InBody:=Entered;
|
||
end;
|
||
|
||
procedure THTMLTopicRenderer.DocAnchor(Entered: boolean);
|
||
var HRef,Name: string;
|
||
lfileid,llinkid : sw_integer;
|
||
begin
|
||
if Entered and InAnchor then DocAnchor(false);
|
||
if Entered then
|
||
begin
|
||
if DocGetTagParam('HREF',HRef)=false then HRef:='';
|
||
if DocGetTagParam('NAME',Name)=false then Name:='';
|
||
if {(HRef='') and} (Name='') then
|
||
if DocGetTagParam('ID',Name)=false then
|
||
Name:='';
|
||
if Name<>'' then
|
||
begin
|
||
Topic^.NamedMarks^.InsertStr(Name);
|
||
{$IFDEF WDEBUG}
|
||
DebugMessageS({$i %file%},' Adding Name "'+Name+'"',{$i %line%},'1',0,0);
|
||
{$endif WDEBUG}
|
||
AddChar(hscNamedMark);
|
||
end;
|
||
if (HRef<>'')then
|
||
begin
|
||
if (LinkPtr<MaxTopicLinks){ and
|
||
not DisableCrossIndexing} then
|
||
begin
|
||
InAnchor:=true;
|
||
AddChar(hscLink);
|
||
{$IFDEF WDEBUG}
|
||
DebugMessageS({$i %file%},' Adding Link1 "'+HRef+'"'+' "'+url+'"',{$i %line%},'1',0,0);
|
||
{$ENDIF WDEBUG}
|
||
|
||
if pos('#',HRef)=1 then
|
||
Href:=NameAndExtOf(GetFilename)+Href;
|
||
HRef:=canonicalizeURL(URL,HRef);
|
||
Resolve(Href,lfileid,llinkid);
|
||
LinkIndexes[LinkPtr]:=llinkid;
|
||
FileIDLinkIndexes[LinkPtr]:=lfileid;
|
||
{$IFDEF WDEBUG}
|
||
DebugMessageS({$i %file%},' Adding Link2 "'+HRef+'"',{$i %line%},'1',0,0);
|
||
{$ENDIF WDEBUG}
|
||
Inc(LinkPtr);
|
||
end;
|
||
end;
|
||
end
|
||
else
|
||
begin
|
||
if InAnchor=true then AddChar(hscLink);
|
||
InAnchor:=false;
|
||
end;
|
||
end;
|
||
|
||
procedure THTMLTopicRenderer.DocUnknownTag;
|
||
begin
|
||
{$IFDEF WDEBUG}
|
||
DebugMessageS({$i %file%},' Unknown tag "'+TagName+'" params "'+TagParams+'"' ,{$i %line%},'1',0,0);
|
||
{$endif WDEBUG}
|
||
end;
|
||
|
||
procedure DecodeAlign(Align: string; var PAlign: TParagraphAlign);
|
||
begin
|
||
Align:=UpcaseStr(Align);
|
||
if Align='LEFT' then PAlign:=paLeft else
|
||
if Align='CENTER' then PAlign:=paCenter else
|
||
if Align='RIGHT' then PAlign:=paRight;
|
||
end;
|
||
|
||
procedure THTMLTopicRenderer.DocHeading(Level: integer; Entered: boolean);
|
||
var Align: string;
|
||
C: byte;
|
||
SC: THTMLSection;
|
||
begin
|
||
if Entered then
|
||
begin
|
||
DocBreak;
|
||
CurHeadLevel:=Level;
|
||
PAlign:=paLeft;
|
||
if DocGetTagParam('ALIGN',Align) then
|
||
DecodeAlign(Align,PAlign);
|
||
SC:=hsNone;
|
||
case Level of
|
||
1: SC:=hsHeading1;
|
||
2: SC:=hsHeading2;
|
||
3: SC:=hsHeading3;
|
||
4: SC:=hsHeading4;
|
||
5: SC:=hsHeading5;
|
||
6: SC:=hsHeading6;
|
||
end;
|
||
if GetSectionColor(SC,C) then
|
||
AddText(hscTextAttr+chr(C));
|
||
end
|
||
else
|
||
begin
|
||
AddChar(hscNormText);
|
||
CurHeadLevel:=0;
|
||
DocBreak;
|
||
end;
|
||
end;
|
||
|
||
Function THTMLTopicRenderer.CanonicalizeURL(const Base,Relative:String):string;
|
||
// uses info from filesystem (curdir) -> overridden for CHM.
|
||
begin
|
||
CanonicalizeURL:=CompleteURL(Base,relative);
|
||
end;
|
||
|
||
procedure THTMLTopicRenderer.Resolve( href: ansistring; var AFileId,ALinkId : sw_integer);
|
||
begin
|
||
{$IFDEF WDEBUG}
|
||
DebugMessageS({$i %file%},' htmlresolve "'+HRef+'"',{$i %line%},'1',0,0);
|
||
{$ENDIF WDEBUG}
|
||
|
||
Afileid:=Topic^.FileId;
|
||
ALinkId:=TopicLinks^.AddItem(HRef);
|
||
end;
|
||
|
||
procedure THTMLTopicRenderer.DocParagraph(Entered: boolean);
|
||
var Align: string;
|
||
begin
|
||
if Entered and InParagraph then DocParagraph(false);
|
||
if Entered then
|
||
begin
|
||
if AnyCharsInLine then DocBreak;
|
||
if DocGetTagParam('ALIGN',Align) then
|
||
DecodeAlign(Align,PAlign);
|
||
end
|
||
else
|
||
begin
|
||
{ if AnyCharsInLine then }DocBreak;
|
||
PAlign:=paLeft;
|
||
end;
|
||
InParagraph:=Entered;
|
||
end;
|
||
|
||
procedure THTMLTopicRenderer.DocBreak;
|
||
begin
|
||
if (CurHeadLevel=1) or (PAlign=paCenter) then
|
||
AddChar(hscCenter);
|
||
if (PAlign=paRight) then
|
||
AddChar(hscRight);
|
||
AddChar(hscLineBreak);
|
||
if Indent>0 then
|
||
AddText(CharStr(#255,Indent)+hscLineStart);
|
||
AnyCharsInLine:=false;
|
||
end;
|
||
|
||
procedure THTMLTopicRenderer.DocProcessComment(Comment: string);
|
||
var
|
||
src,index : string;
|
||
begin
|
||
if pos('tex4ht:',Comment)=0 then
|
||
exit;
|
||
{$IFDEF WDEBUG}
|
||
DebugMessage(GetFileName,'tex4ht comment "'
|
||
+Comment+'"',Line,1);
|
||
{$endif WDEBUG}
|
||
if SuppressOutput then
|
||
begin
|
||
if (pos(SuppressUntil,Comment)=0) then
|
||
exit
|
||
else
|
||
begin
|
||
{$IFDEF WDEBUG}
|
||
DebugMessage(GetFileName,' Found '+SuppressUntil+'comment "'
|
||
+Comment+'" SuppressOuput reset to false',Line,1);
|
||
{$endif WDEBUG}
|
||
SuppressOutput:=false;
|
||
SuppressUntil:='';
|
||
end;
|
||
end;
|
||
if (pos('tex4ht:graphics ',Comment)>0) and
|
||
LastAnsiLoadFailed then
|
||
begin
|
||
{$IFDEF WDEBUG}
|
||
DebugMessage(GetFileName,' Using tex4ht comment "'
|
||
+Comment+'"',Line,1);
|
||
{$endif WDEBUG}
|
||
{ Try again with this info }
|
||
TagParams:=Comment;
|
||
DocImage;
|
||
end;
|
||
if (pos('tex4ht:syntaxdiagram ',Comment)>0) then
|
||
begin
|
||
{$IFDEF WDEBUG}
|
||
DebugMessage(GetFileName,' Using tex4ht:syntaxdiagram comment "'
|
||
+Comment+'"',Line,1);
|
||
{$endif WDEBUG}
|
||
{ Try again with this info }
|
||
TagParams:=Comment;
|
||
DocImage;
|
||
if not LastAnsiLoadFailed then
|
||
begin
|
||
SuppressOutput:=true;
|
||
SuppressUntil:='tex4ht:endsyntaxdiagram ';
|
||
end
|
||
end;
|
||
if (pos('tex4ht:mysyntdiag ',Comment)>0) then
|
||
begin
|
||
{$IFDEF WDEBUG}
|
||
DebugMessage(GetFileName,' Using tex4ht:mysyntdiag comment "'
|
||
+Comment+'"',Line,1);
|
||
{$endif WDEBUG}
|
||
{ Try again with this info }
|
||
TagParams:=Comment;
|
||
DocGetTagParam('SRC',src);
|
||
DocGetTagParam('INDEX',index);
|
||
TagParams:='src="../syntax/'+src+'-'+index+'.png"';
|
||
DocImage;
|
||
if not LastAnsiLoadFailed then
|
||
begin
|
||
SuppressOutput:=true;
|
||
SuppressUntil:='tex4ht:endmysyntdiag ';
|
||
end
|
||
end;
|
||
end;
|
||
|
||
procedure THTMLTopicRenderer.DocImage;
|
||
var Name,Src,Alt,SrcLine: string;
|
||
f : text;
|
||
attr : byte;
|
||
PA : PHTMLAnsiView;
|
||
StorePreformatted : boolean;
|
||
begin
|
||
if SuppressOutput then
|
||
exit;
|
||
{$IFDEF WDEBUG}
|
||
if not DocGetTagParam('NAME',Name) then
|
||
Name:='<No name>';
|
||
DebugMessage(GetFileName,' Image "'+Name+'"',Line,1);
|
||
{$endif WDEBUG}
|
||
if DocGetTagParam('SRC',src) then
|
||
begin
|
||
{$IFDEF WDEBUG}
|
||
DebugMessage(GetFileName,' Image source tag "'+Src+'"',Line,1);
|
||
{$endif WDEBUG}
|
||
if src<>'' then
|
||
begin
|
||
src:=CompleteURL(URL,src);
|
||
{ this should be a image file ending by .gif or .jpg...
|
||
Try to see if a file with same name and extension .git
|
||
exists PM }
|
||
src:=DirAndNameOf(src)+'.ans';
|
||
{$IFDEF WDEBUG}
|
||
DebugMessage(GetFileName,' Trying "'+Src+'"',Line,1);
|
||
{$endif WDEBUG}
|
||
if not ExistsFile(src) then
|
||
begin
|
||
DocGetTagParam('SRC',src);
|
||
src:=DirAndNameOf(src)+'.ans';
|
||
src:=CompleteURL(DirOf(URL)+'../',src);
|
||
{$IFDEF WDEBUG}
|
||
DebugMessage(GetFileName,' Trying "'+Src+'"',Line,1);
|
||
{$endif wDEBUG}
|
||
end;
|
||
if not ExistsFile(src) then
|
||
begin
|
||
LastAnsiLoadFailed:=true;
|
||
{$IFDEF WDEBUG}
|
||
DebugMessage(GetFileName,' "'+Src+'" not found',Line,1);
|
||
{$endif WDEBUG}
|
||
end
|
||
else
|
||
begin
|
||
PA:=New(PHTMLAnsiView,init(@self));
|
||
PA^.LoadFile(src);
|
||
LastAnsiLoadFailed:=false;
|
||
if AnyCharsInLine then DocBreak;
|
||
StorePreformatted:=InPreformatted;
|
||
InPreformatted:=true;
|
||
{AddText('Image from '+src+hscLineBreak); }
|
||
AddChar(hscInImage);
|
||
PA^.CopyToHTML;
|
||
InPreformatted:=StorePreformatted;
|
||
AddChar(hscInImage);
|
||
AddChar(hscNormText);
|
||
if AnyCharsInLine then DocBreak;
|
||
Dispose(PA,Done);
|
||
Exit;
|
||
end;
|
||
{ also look for a raw text file without colors }
|
||
src:=DirAndNameOf(src)+'.txt';
|
||
if not ExistsFile(src) then
|
||
begin
|
||
LastAnsiLoadFailed:=true;
|
||
{$IFDEF WDEBUG}
|
||
DebugMessage(GetFileName,' "'+Src+'" not found',Line,1);
|
||
{$endif WDEBUG}
|
||
end
|
||
else
|
||
begin
|
||
Assign(f,src);
|
||
Reset(f);
|
||
DocPreformatted(true);
|
||
while not eof(f) do
|
||
begin
|
||
Readln(f,SrcLine);
|
||
AddText(SrcLine+hscLineBreak);
|
||
end;
|
||
Close(f);
|
||
LastAnsiLoadFailed:=false;
|
||
DocPreformatted(false);
|
||
LastAnsiLoadFailed:=false;
|
||
Exit;
|
||
end;
|
||
end;
|
||
end;
|
||
if DocGetTagParam('ALT',Alt)=false then
|
||
begin
|
||
DocGetTagParam('SRC',Alt);
|
||
if Alt<>'' then
|
||
Alt:='Can''t display '+Alt
|
||
else
|
||
Alt:='IMG';
|
||
end;
|
||
if Alt<>'' then
|
||
begin
|
||
StorePreformatted:=InPreformatted;
|
||
InPreformatted:=true;
|
||
DocGetTagParam('SRC',src);
|
||
AddChar(hscInImage);
|
||
AddText('[--'+Src+'--'+hscLineBreak);
|
||
AddText(Alt+hscLineBreak+'--]');
|
||
AddChar(hscInImage);
|
||
AddChar(hscNormText);
|
||
InPreformatted:=StorePreformatted;
|
||
end;
|
||
end;
|
||
|
||
procedure THTMLTopicRenderer.DocBold(Entered: boolean);
|
||
begin
|
||
end;
|
||
|
||
procedure THTMLTopicRenderer.DocCite(Entered: boolean);
|
||
begin
|
||
end;
|
||
|
||
procedure THTMLTopicRenderer.DocCode(Entered: boolean);
|
||
begin
|
||
if AnyCharsInLine then DocBreak;
|
||
AddText(hscCode);
|
||
DocBreak;
|
||
end;
|
||
|
||
procedure THTMLTopicRenderer.DocEmphasized(Entered: boolean);
|
||
begin
|
||
end;
|
||
|
||
procedure THTMLTopicRenderer.DocItalic(Entered: boolean);
|
||
begin
|
||
end;
|
||
|
||
procedure THTMLTopicRenderer.DocKbd(Entered: boolean);
|
||
begin
|
||
end;
|
||
|
||
procedure THTMLTopicRenderer.DocPreformatted(Entered: boolean);
|
||
begin
|
||
if AnyCharsInLine then DocBreak;
|
||
AddText(hscCode);
|
||
DocBreak;
|
||
InPreformatted:=Entered;
|
||
end;
|
||
|
||
procedure THTMLTopicRenderer.DocSample(Entered: boolean);
|
||
begin
|
||
end;
|
||
|
||
procedure THTMLTopicRenderer.DocStrong(Entered: boolean);
|
||
begin
|
||
end;
|
||
|
||
procedure THTMLTopicRenderer.DocTeleType(Entered: boolean);
|
||
begin
|
||
end;
|
||
|
||
procedure THTMLTopicRenderer.DocVariable(Entered: boolean);
|
||
begin
|
||
end;
|
||
|
||
procedure THTMLTopicRenderer.DocSpan(Entered: boolean);
|
||
begin
|
||
end;
|
||
|
||
procedure THTMLTopicRenderer.DocList(Entered: boolean);
|
||
begin
|
||
if Entered then
|
||
begin
|
||
Inc(Indent,ListIndent);
|
||
DocBreak;
|
||
end
|
||
else
|
||
begin
|
||
Dec(Indent,ListIndent);
|
||
if AnyCharsInLine then DocBreak;
|
||
end;
|
||
end;
|
||
|
||
procedure THTMLTopicRenderer.DocOrderedList(Entered: boolean);
|
||
begin
|
||
DocList(Entered);
|
||
end;
|
||
|
||
procedure THTMLTopicRenderer.DocListItem(Entered: boolean);
|
||
begin
|
||
if not Entered then
|
||
exit;
|
||
if AnyCharsInLine then
|
||
DocBreak;
|
||
AddText('<27>'+hscLineStart);
|
||
end;
|
||
|
||
procedure THTMLTopicRenderer.DocDefList(Entered: boolean);
|
||
begin
|
||
if Entered then
|
||
begin
|
||
{ if LastChar<>hscLineBreak then DocBreak;}
|
||
end
|
||
else
|
||
begin
|
||
if AnyCharsInLine then DocBreak;
|
||
InDefExp:=false;
|
||
end;
|
||
end;
|
||
|
||
procedure THTMLTopicRenderer.DocDefTerm(Entered: boolean);
|
||
begin
|
||
if not Entered then
|
||
exit;
|
||
DocBreak;
|
||
end;
|
||
|
||
procedure THTMLTopicRenderer.DocDefExp(Entered: boolean);
|
||
begin
|
||
if not Entered then
|
||
begin
|
||
if InDefExp then
|
||
Dec(Indent,DefIndent);
|
||
InDefExp:=false;
|
||
end
|
||
else
|
||
begin
|
||
if not InDefExp then
|
||
Inc(Indent,DefIndent);
|
||
InDefExp:=true;
|
||
DocBreak;
|
||
end;
|
||
end;
|
||
|
||
procedure THTMLTopicRenderer.DocTable(Entered: boolean);
|
||
var
|
||
ATable : PTable;
|
||
Param : String;
|
||
begin
|
||
if AnyCharsInLine then
|
||
begin
|
||
AddChar(hscLineBreak);
|
||
AnyCharsInLine:=false;
|
||
end;
|
||
if Entered then
|
||
begin
|
||
DocBreak;
|
||
New(ATable,Init(CurrentTable));
|
||
CurrentTable:=ATable;
|
||
CurrentTable^.Renderer:=@Self;
|
||
if DocGetTagParam('BORDER',Param) then
|
||
if Param<>'0' then
|
||
CurrentTable^.WithBorder:=true;
|
||
if DocGetTagParam('CLASS',Param) then
|
||
if Param='bar' then
|
||
CurrentTable^.IsBar:=true;
|
||
end
|
||
else
|
||
begin
|
||
CurrentTable^.FormatTable;
|
||
ATable:=CurrentTable;
|
||
CurrentTable:=ATable^.PreviousTable;
|
||
Dispose(ATable,Done);
|
||
end;
|
||
end;
|
||
|
||
procedure THTMLTopicRenderer.DocTableRow(Entered: boolean);
|
||
var
|
||
ATableLine : PTableLine;
|
||
begin
|
||
if AnyCharsInLine or
|
||
(assigned(CurrentTable) and
|
||
assigned(CurrentTable^.FirstLine)) then
|
||
begin
|
||
AddChar(hscLineBreak);
|
||
AnyCharsInLine:=false;
|
||
end;
|
||
if Entered then
|
||
begin
|
||
New(ATableLine,Init);
|
||
if CurrentTable^.GlobalTextBegin=0 then
|
||
CurrentTable^.GlobalTextBegin:=TextPtr;
|
||
CurrentTable^.AddLine(ATableLine);
|
||
end;
|
||
end;
|
||
|
||
procedure THTMLTopicRenderer.DocTableItem(Entered: boolean);
|
||
var
|
||
Align : String;
|
||
i : sw_word;
|
||
NewEl : PTableElement;
|
||
PAlignEl : TParagraphAlign;
|
||
begin
|
||
if Entered then
|
||
begin
|
||
if assigned(CurrentTable^.LastLine) and Assigned(CurrentTable^.LastLine^.LastEl) and
|
||
(CurrentTable^.LastLine^.LastEl^.TextEnd=sw_word(-1)) then
|
||
begin
|
||
NewEl:=CurrentTable^.LastLine^.LastEl;
|
||
NewEl^.TextEnd:=TextPtr;
|
||
NewEl^.TextLength:=ComputeTextLength(
|
||
NewEl^.TextBegin+CurrentTable^.GlobalOffset,
|
||
TextPtr+CurrentTable^.GlobalOffset);
|
||
end;
|
||
PAlignEl:=paLeft;
|
||
if DocGetTagParam('ALIGN',Align) then
|
||
DecodeAlign(Align,PAlignEl);
|
||
New(NewEl,Init(PAlignEl));
|
||
CurrentTable^.AddElement(NewEl);
|
||
NewEl^.TextBegin:=TextPtr;
|
||
NewEl^.TextEnd:=sw_word(-1);
|
||
{ AddText(' - ');}
|
||
end
|
||
else
|
||
begin
|
||
NewEl:=CurrentTable^.LastLine^.LastEl;
|
||
NewEl^.TextEnd:=TextPtr;
|
||
NewEl^.TextLength:=ComputeTextLength(
|
||
NewEl^.TextBegin+CurrentTable^.GlobalOffset,
|
||
TextPtr+CurrentTable^.GlobalOffset);
|
||
NewEl^.NumNL:=0;
|
||
for i:=NewEl^.TextBegin to TextPtr do
|
||
begin
|
||
if Topic^.Text^[i]=ord(hscLineBreak) then
|
||
inc(NewEl^.NumNL);
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
procedure THTMLTopicRenderer.DocTableHeaderItem(Entered: boolean);
|
||
begin
|
||
{ Treat as a normal item }
|
||
DocTableItem(Entered);
|
||
end;
|
||
|
||
|
||
procedure THTMLTopicRenderer.DocHorizontalRuler;
|
||
var OAlign: TParagraphAlign;
|
||
begin
|
||
OAlign:=PAlign;
|
||
if AnyCharsInLine then DocBreak;
|
||
PAlign:=paCenter;
|
||
DocAddText(' '+CharStr('<27>',60)+' ');
|
||
DocBreak;
|
||
PAlign:=OAlign;
|
||
end;
|
||
|
||
procedure THTMLTopicRenderer.AddChar(C: char);
|
||
begin
|
||
if (Topic=nil) or (TextPtr=MaxBytes) or SuppressOutput then Exit;
|
||
Topic^.Text^[TextPtr]:=ord(C);
|
||
Inc(TextPtr);
|
||
if (C>#15) and ((C<>' ') or (InPreFormatted=true)) then
|
||
AnyCharsInLine:=true;
|
||
end;
|
||
|
||
procedure THTMLTopicRenderer.AddCharAt(C: char;AtPtr : sw_word);
|
||
begin
|
||
if (Topic=nil) or (TextPtr=MaxBytes) or SuppressOutput then Exit;
|
||
if AtPtr>TextPtr then
|
||
AtPtr:=TextPtr
|
||
else
|
||
begin
|
||
Move(Topic^.Text^[AtPtr],Topic^.Text^[AtPtr+1],TextPtr-AtPtr);
|
||
end;
|
||
Topic^.Text^[AtPtr]:=ord(C);
|
||
Inc(TextPtr);
|
||
end;
|
||
|
||
procedure THTMLTopicRenderer.AddText(const S: string);
|
||
var I: sw_integer;
|
||
begin
|
||
for I:=1 to length(S) do
|
||
AddChar(S[I]);
|
||
end;
|
||
|
||
function THTMLTopicRenderer.ComputeTextLength(TStart,TEnd : sw_word) : sw_word;
|
||
var I,tot: sw_integer;
|
||
begin
|
||
tot:=0;
|
||
i:=TStart;
|
||
while i<= TEnd-1 do
|
||
begin
|
||
inc(tot);
|
||
case chr(Topic^.Text^[i]) of
|
||
hscLink,hscCode,
|
||
hscCenter,hscRight,
|
||
hscNamedMark,hscNormText :
|
||
Dec(tot);{ Do not increase tot }
|
||
hscDirect:
|
||
begin
|
||
Inc(i); { Skip next }
|
||
//Inc(tot);
|
||
end;
|
||
hscTextAttr,
|
||
hscTextColor:
|
||
begin
|
||
Inc(i);
|
||
Dec(tot);
|
||
end;
|
||
end;
|
||
inc(i);
|
||
end;
|
||
ComputeTextLength:=tot;
|
||
|
||
end;
|
||
function THTMLTopicRenderer.AddTextAt(const S: String;AtPtr : sw_word) : sw_word;
|
||
var
|
||
i,slen,len : sw_word;
|
||
begin
|
||
if (Topic=nil) or (TextPtr>=MaxBytes) or SuppressOutput then Exit;
|
||
slen:=length(s);
|
||
if TextPtr+slen>=MaxBytes then
|
||
slen:=MaxBytes-TextPtr;
|
||
if AtPtr>TextPtr then
|
||
AtPtr:=TextPtr
|
||
else
|
||
begin
|
||
len:=TextPtr-AtPtr;
|
||
Move(Topic^.Text^[AtPtr],Topic^.Text^[AtPtr+slen],len);
|
||
end;
|
||
for i:=1 to slen do
|
||
begin
|
||
Topic^.Text^[AtPtr]:=ord(S[i]);
|
||
Inc(TextPtr);
|
||
inc(AtPtr);
|
||
if (TextPtr=MaxBytes) then Exit;
|
||
end;
|
||
AddTextAt:=slen;
|
||
end;
|
||
|
||
function THTMLTopicRenderer.GetSectionColor(Section: THTMLSection; var Color: byte): boolean;
|
||
begin
|
||
GetSectionColor:=HTMLGetSectionColor(Section,Color);
|
||
end;
|
||
|
||
function THTMLTopicRenderer.BuildTopic(P: PTopic; AURL: string; HTMLFile: PTextFile;
|
||
ATopicLinks: PTopicLinkCollection): boolean;
|
||
var OK: boolean;
|
||
TP: pointer;
|
||
I: sw_integer;
|
||
begin
|
||
URL:=AURL;
|
||
Topic:=P; TopicLinks:=ATopicLinks;
|
||
OK:=Assigned(Topic) and Assigned(HTMLFile) and Assigned(TopicLinks);
|
||
if OK then
|
||
begin
|
||
if (Topic^.TextSize<>0) and Assigned(Topic^.Text) then
|
||
begin
|
||
FreeMem(Topic^.Text,Topic^.TextSize);
|
||
Topic^.TextSize:=0; Topic^.Text:=nil;
|
||
end;
|
||
Topic^.TextSize:=MaxHelpTopicSize;
|
||
GetMem(Topic^.Text,Topic^.TextSize);
|
||
|
||
TopicTitle:='';
|
||
InTitle:=false; InBody:={false}true; InAnchor:=false;
|
||
InParagraph:=false; InPreformatted:=false;
|
||
Indent:=0; CurHeadLevel:=0;
|
||
PAlign:=paLeft;
|
||
TextPtr:=0; LinkPtr:=0;
|
||
AnyCharsInLine:=false;
|
||
LastTextChar:=#0;
|
||
SuppressUntil:='';
|
||
SuppressOutput:=false;
|
||
OK:=Process(HTMLFile);
|
||
|
||
if OK then
|
||
begin
|
||
{ --- topic links --- }
|
||
if (Topic^.Links<>nil) and (Topic^.LinkSize>0) then
|
||
begin
|
||
FreeMem(Topic^.Links,Topic^.LinkSize);
|
||
Topic^.Links:=nil; Topic^.LinkCount:=0;
|
||
end;
|
||
Topic^.LinkCount:=LinkPtr{TopicLinks^.Count}; { <- eeeeeek! }
|
||
GetMem(Topic^.Links,Topic^.LinkSize);
|
||
if Topic^.LinkCount>0 then { FP causes numeric RTE 215 without this }
|
||
for I:=0 to Min(Topic^.LinkCount-1,High(LinkIndexes)-1) do
|
||
begin
|
||
{$IFDEF WDEBUG}
|
||
DebugMessageS({$i %file%},' Indexing links ('+inttostr(i)+')'+topiclinks^.at(linkindexes[i])^+' '+inttostr(i)+' '+inttostr(linkindexes[i]),{$i %line%},'1',0,0);
|
||
{$endif WDEBUG}
|
||
Topic^.Links^[I].FileID:=FileIDLinkIndexes[i];
|
||
Topic^.Links^[I].Context:=EncodeHTMLCtx(FileIDLinkIndexes[i],LinkIndexes[I]+1);
|
||
end;
|
||
{$IFDEF WDEBUG}
|
||
if Topic^.Linkcount>High(linkindexes) then
|
||
DebugMessageS({$i %file%},' Maximum links exceeded ('+inttostr(Topic^.LinkCount)+') '+URL,{$i %line%},'1',0,0);
|
||
{$endif WDEBUG}
|
||
|
||
|
||
{ --- topic text --- }
|
||
GetMem(TP,TextPtr);
|
||
Move(Topic^.Text^,TP^,TextPtr);
|
||
FreeMem(Topic^.Text,Topic^.TextSize);
|
||
Topic^.Text:=TP; Topic^.TextSize:=TextPtr;
|
||
end
|
||
else
|
||
begin
|
||
DisposeTopic(Topic);
|
||
Topic:=nil;
|
||
end;
|
||
end;
|
||
BuildTopic:=OK;
|
||
end;
|
||
|
||
Function TCHMTopicRenderer.CanonicalizeURL(const Base,Relative:String):string;
|
||
begin
|
||
if copy(relative,1,6)='http:/' then // external links don't need to be fixed since we can't load them.
|
||
begin
|
||
CanonicalizeUrl:=relative;
|
||
exit;
|
||
end;
|
||
if copy(relative,1,7)<>'ms-its:' then
|
||
CanonicalizeUrl:=combinepaths(relative,base)
|
||
else
|
||
CanonicalizeUrl:=relative;
|
||
end;
|
||
|
||
procedure TCHMTopicRenderer.Resolve( href: ansistring; var AFileId,ALinkId : sw_integer);
|
||
var resolved:boolean;
|
||
begin
|
||
{$IFDEF WDEBUG}
|
||
DebugMessageS({$i %file%},' chmresolve "'+HRef+'"',{$i %line%},'1',0,0);
|
||
{$ENDIF WDEBUG}
|
||
resolved:=false; AFileID:=0; ALinkID:=0;
|
||
href:=stringreplace(href,'%20',' ');
|
||
if copy(href,1,7)='ms-its:' then
|
||
resolved:=CHMResolve(Href,AFileId,ALinkID);
|
||
if not resolved then
|
||
begin
|
||
{$IFDEF WDEBUG}
|
||
DebugMessageS({$i %file%},' chmresolve not resolved "'+HRef+'"',{$i %line%},'1',0,0);
|
||
{$ENDIF WDEBUG}
|
||
|
||
Afileid:=Topic^.FileId;
|
||
ALinkId:=TopicLinks^.AddItem(HRef);
|
||
end;
|
||
end;
|
||
|
||
|
||
constructor TCustomHTMLHelpFile.Init(AID: word);
|
||
begin
|
||
inherited Init(AID);
|
||
New(Renderer, Init);
|
||
New(TopicLinks, Init(50,500));
|
||
end;
|
||
|
||
function TCustomHTMLHelpFile.SearchTopic(HelpCtx: THelpCtx): PTopic;
|
||
function MatchCtx(P: PTopic): boolean;
|
||
begin
|
||
MatchCtx:=P^.HelpCtx=HelpCtx;
|
||
end;
|
||
var FileID,LinkNo: word;
|
||
P: PTopic;
|
||
FName: string;
|
||
begin
|
||
DecodeHTMLCtx(HelpCtx,FileID,LinkNo);
|
||
if (HelpCtx<>0) and (FileID<>ID) then P:=nil else
|
||
if (FileID=ID) and (LinkNo>TopicLinks^.Count) then P:=nil else
|
||
begin
|
||
P:=Topics^.FirstThat(@MatchCtx);
|
||
if P=nil then
|
||
begin
|
||
if LinkNo=0 then
|
||
FName:=DefaultFileName
|
||
else
|
||
FName:=TopicLinks^.At(LinkNo-1)^;
|
||
P:=NewTopic(ID,HelpCtx,0,FName,nil,0);
|
||
Topics^.Insert(P);
|
||
end;
|
||
end;
|
||
SearchTopic:=P;
|
||
end;
|
||
|
||
function TCustomHTMLHelpFile.FormatLink(const s:String):string;
|
||
begin
|
||
formatlink:=formatpath(s);
|
||
end;
|
||
|
||
function TCustomHTMLHelpFile.GetTopicInfo(T: PTopic) : string;
|
||
var OK: boolean;
|
||
Name: string;
|
||
Link,Bookmark: string;
|
||
P: sw_integer;
|
||
begin
|
||
Bookmark:='';
|
||
OK:=T<>nil;
|
||
if OK then
|
||
begin
|
||
if T^.HelpCtx=0 then
|
||
begin
|
||
Name:=DefaultFileName;
|
||
P:=0;
|
||
end
|
||
else
|
||
begin
|
||
Link:=TopicLinks^.At((T^.HelpCtx and $ffff)-1)^;
|
||
{$IFDEF WDEBUG}
|
||
DebugMessageS({$i %file%},'(Topicinfo) Link before formatpath "'+link+'"',{$i %line%},'1',0,0);
|
||
{$ENDIF WDEBUG}
|
||
|
||
Link:=FormatLink(Link);
|
||
{$IFDEF WDEBUG}
|
||
DebugMessageS({$i %file%},'(Topicinfo) Link after formatpath "'+link+'"',{$i %line%},'1',0,0);
|
||
{$ENDIF WDEBUG}
|
||
P:=Pos('#',Link);
|
||
if P>0 then
|
||
begin
|
||
Bookmark:=copy(Link,P+1,length(Link));
|
||
Link:=copy(Link,1,P-1);
|
||
end;
|
||
{ if CurFileName='' then Name:=Link else
|
||
Name:=CompletePath(CurFileName,Link);}
|
||
Name:=Link;
|
||
end;
|
||
end;
|
||
GetTopicInfo:=Name+'#'+BookMark;
|
||
end;
|
||
|
||
function TCustomHTMLHelpFile.ReadTopic(T: PTopic): boolean;
|
||
var OK: boolean;
|
||
HTMLFile: PMemoryTextFile;
|
||
Name: string;
|
||
Link,Bookmark: string;
|
||
P: sw_integer;
|
||
begin
|
||
Bookmark:='';
|
||
OK:=T<>nil;
|
||
if OK then
|
||
begin
|
||
if T^.HelpCtx=0 then
|
||
begin
|
||
Name:=DefaultFileName;
|
||
P:=0;
|
||
end
|
||
else
|
||
begin
|
||
Link:=TopicLinks^.At((T^.HelpCtx and $ffff)-1)^;
|
||
{$IFDEF WDEBUG}
|
||
DebugMessageS({$i %file%},'(ReadTopic) Link before formatpath "'+link+'"',{$i %line%},'1',0,0);
|
||
{$ENDIF WDEBUG}
|
||
Link:=FormatPath(Link);
|
||
{$IFDEF WDEBUG}
|
||
DebugMessageS({$i %file%},'(ReadTopic) Link before formatpath "'+link+'"',{$i %line%},'1',0,0);
|
||
{$ENDIF WDEBUG}
|
||
P:=Pos('#',Link);
|
||
if P>0 then
|
||
begin
|
||
Bookmark:=copy(Link,P+1,length(Link));
|
||
Link:=copy(Link,1,P-1);
|
||
end;
|
||
{ if CurFileName='' then Name:=Link else
|
||
Name:=CompletePath(CurFileName,Link);}
|
||
Name:=Link;
|
||
end;
|
||
HTMLFile:=nil;
|
||
if Name<>'' then
|
||
HTMLFile:=New(PDOSTextFile, Init(Name));
|
||
|
||
if (HTMLFile=nil) and (CurFileName<>'') then
|
||
begin
|
||
Name:=CurFileName;
|
||
HTMLFile:=New(PDOSTextFile, Init(Name));
|
||
end;
|
||
if (HTMLFile=nil) then
|
||
begin
|
||
{$IFDEF WDEBUG}
|
||
DebugMessageS({$i %file%},'(ReadTopic) Filename not known: "'+link+'"',{$i %line%},'1',0,0);
|
||
{$ENDIF WDEBUG}
|
||
end;
|
||
if (p>1) and (HTMLFile=nil) then
|
||
begin
|
||
{$IFDEF WDEBUG}
|
||
if p>0 then
|
||
DebugMessage(Name,Link+'#'+Bookmark+' not found',1,1)
|
||
else
|
||
DebugMessage(Name,Link+' not found',1,1);
|
||
{$endif WDEBUG}
|
||
New(HTMLFile, Init);
|
||
HTMLFile^.AddLine('<HEAD><TITLE>'+msg_pagenotavailable+'</TITLE></HEAD>');
|
||
HTMLFile^.AddLine(
|
||
'<BODY>'+
|
||
FormatStrStr(msg_cantaccessurl,Name)+'<br><br>'+
|
||
'</BODY>');
|
||
end;
|
||
OK:=Renderer^.BuildTopic(T,Name,HTMLFile,TopicLinks);
|
||
if OK then
|
||
CurFileName:=Name
|
||
else
|
||
begin
|
||
{$IFDEF WDEBUG}
|
||
if p>0 then
|
||
DebugMessage(Name,Link+'#'+Bookmark+' not found',1,1)
|
||
else
|
||
DebugMessage(Name,Link+' not found',1,1);
|
||
{$endif WDEBUG}
|
||
end;
|
||
if HTMLFile<>nil then Dispose(HTMLFile, Done);
|
||
if BookMark='' then
|
||
T^.StartNamedMark:=0
|
||
else
|
||
begin
|
||
P:=T^.GetNamedMarkIndex(BookMark);
|
||
{$IFDEF WDEBUG}
|
||
if p=-1 then
|
||
DebugMessage(Name,Link+'#'+Bookmark+' bookmark not found',1,1);
|
||
{$endif WDEBUG}
|
||
T^.StartNamedMark:=P+1;
|
||
end;
|
||
end;
|
||
ReadTopic:=OK;
|
||
end;
|
||
|
||
destructor TCustomHTMLHelpFile.Done;
|
||
begin
|
||
inherited Done;
|
||
if Renderer<>nil then Dispose(Renderer, Done);
|
||
if TopicLinks<>nil then Dispose(TopicLinks, Done);
|
||
end;
|
||
|
||
constructor THTMLHelpFile.Init(AFileName: string; AID: word; ATOCEntry: string);
|
||
begin
|
||
if inherited Init(AID)=false then Fail;
|
||
DefaultFileName:=AFileName; TOCEntry:=ATOCEntry;
|
||
if DefaultFileName='' then
|
||
begin
|
||
Done;
|
||
Fail;
|
||
end;
|
||
end;
|
||
|
||
function THTMLHelpFile.LoadIndex: boolean;
|
||
begin
|
||
IndexEntries^.Insert(NewIndexEntry(TOCEntry,ID,0));
|
||
LoadIndex:=true;
|
||
end;
|
||
|
||
constructor THTMLIndexHelpFile.Init(AFileName: string; AID: word);
|
||
begin
|
||
inherited Init(AID);
|
||
IndexFileName:=AFileName;
|
||
end;
|
||
|
||
function THTMLIndexHelpFile.LoadIndex: boolean;
|
||
function FormatAlias(Alias: string): string;
|
||
begin
|
||
if Assigned(HelpFacility) then
|
||
if length(Alias)>HelpFacility^.IndexTabSize-4 then
|
||
Alias:=Trim(copy(Alias,1,HelpFacility^.IndexTabSize-4-2))+'..';
|
||
FormatAlias:=Alias;
|
||
end;
|
||
(*procedure AddDoc(P: PHTMLLinkScanDocument);
|
||
var I: sw_integer;
|
||
TLI: THelpCtx;
|
||
begin
|
||
for I:=1 to P^.GetAliasCount do
|
||
begin
|
||
TLI:=TopicLinks^.AddItem(P^.GetName);
|
||
TLI:=EncodeHTMLCtx(ID,TLI+1);
|
||
IndexEntries^.Insert(NewIndexEntry(FormatAlias(P^.GetAlias(I-1)),ID,TLI));
|
||
end;
|
||
end;*)
|
||
var S: PBufStream;
|
||
LS: PHTMLLinkScanner;
|
||
OK: boolean;
|
||
TLI: THelpCtx;
|
||
I,J: sw_integer;
|
||
begin
|
||
New(S, Init(IndexFileName,stOpenRead,4096));
|
||
OK:=Assigned(S);
|
||
if OK then
|
||
begin
|
||
New(LS, LoadDocuments(S^));
|
||
OK:=Assigned(LS);
|
||
if OK then
|
||
begin
|
||
{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.}
|
||
for I:=0 to LS^.GetDocumentCount-1 do
|
||
begin
|
||
TLI:=TopicLinks^.AddItem(LS^.GetDocumentURL(I));
|
||
TLI:=EncodeHTMLCtx(ID,TLI+1);
|
||
for J:=0 to LS^.GetDocumentAliasCount(I)-1 do
|
||
IndexEntries^.Insert(NewIndexEntry(
|
||
FormatAlias(LS^.GetDocumentAlias(I,J)),ID,TLI));
|
||
end;
|
||
Dispose(LS, Done);
|
||
end;
|
||
Dispose(S, Done);
|
||
end;
|
||
LoadIndex:=OK;
|
||
end;
|
||
|
||
constructor TChmHelpFile.Init(AFileName: string; AID: word);
|
||
begin
|
||
if inherited Init(AID)=false then
|
||
Fail;
|
||
Dispose(renderer,done);
|
||
renderer:=New(PCHMTopicRenderer, Init);
|
||
DefaultFileName:=AFileName;
|
||
if (DefaultFileName='') or not ExistsFile(DefaultFilename) then
|
||
begin
|
||
Done;
|
||
Fail;
|
||
end
|
||
else
|
||
chmw:=TCHMWrapper.Create(DefaultFileName,AID,TopicLinks);
|
||
end;
|
||
|
||
function TChmHelpFile.LoadIndex: boolean;
|
||
begin
|
||
loadindex:=false;
|
||
if assigned(chmw) then
|
||
loadindex:=chmw.loadindex(id,TopicLinks,IndexEntries,helpfacility);
|
||
end;
|
||
|
||
function TCHMHelpFile.FormatLink(const s:String):string;
|
||
// do not reformat for chms, we assume them internally consistent.
|
||
begin
|
||
formatlink:=s;
|
||
end;
|
||
|
||
function TChmHelpFile.SearchTopic(HelpCtx: THelpCtx): PTopic;
|
||
function MatchCtx(P: PTopic): boolean;
|
||
begin
|
||
MatchCtx:=P^.HelpCtx=HelpCtx;
|
||
end;
|
||
var FileID,LinkNo: word;
|
||
P: PTopic;
|
||
FName: string;
|
||
begin
|
||
DecodeHTMLCtx(HelpCtx,FileID,LinkNo);
|
||
if (HelpCtx<>0) and (FileID<>ID) then P:=nil else
|
||
if (FileID=ID) and (LinkNo>TopicLinks^.Count) then P:=nil else
|
||
begin
|
||
P:=Topics^.FirstThat(@MatchCtx);
|
||
if P=nil then
|
||
begin
|
||
if LinkNo=0 then
|
||
FName:=DefaultFileName
|
||
else
|
||
FName:=TopicLinks^.At(LinkNo-1)^;
|
||
P:=NewTopic(ID,HelpCtx,0,FName,nil,0);
|
||
Topics^.Insert(P);
|
||
end;
|
||
end;
|
||
SearchTopic:=P;
|
||
end;
|
||
|
||
function TChmHelpFile.GetTopicInfo(T: PTopic) : string;
|
||
var OK: boolean;
|
||
Name: string;
|
||
Link,Bookmark: string;
|
||
P: sw_integer;
|
||
begin
|
||
Bookmark:='';
|
||
OK:=T<>nil;
|
||
if OK then
|
||
begin
|
||
if T^.HelpCtx=0 then
|
||
begin
|
||
Name:=DefaultFileName;
|
||
P:=0;
|
||
end
|
||
else
|
||
begin
|
||
Link:=TopicLinks^.At((T^.HelpCtx and $ffff)-1)^;
|
||
Link:=FormatPath(Link);
|
||
{$IFDEF WDEBUG}
|
||
DebugMessageS({$i %file%},' Looking for "'+Link+'"',{$i %line%},'1',0,0);
|
||
{$endif WDEBUG}
|
||
P:=Pos('#',Link);
|
||
if P>0 then
|
||
begin
|
||
Bookmark:=copy(Link,P+1,length(Link));
|
||
Link:=copy(Link,1,P-1);
|
||
end;
|
||
{ if CurFileName='' then Name:=Link else
|
||
Name:=CompletePath(CurFileName,Link);}
|
||
Name:=Link;
|
||
end;
|
||
end;
|
||
GetTopicInfo:=Name+'#'+BookMark;
|
||
end;
|
||
|
||
function TChmHelpFile.ReadTopic(T: PTopic): boolean;
|
||
var OK: boolean;
|
||
HTMLFile: PMemoryTextFile;
|
||
Name: string;
|
||
Link,Bookmark: string;
|
||
P: sw_integer;
|
||
begin
|
||
Bookmark:='';
|
||
OK:=T<>nil;
|
||
if OK then
|
||
begin
|
||
if T^.HelpCtx=0 then
|
||
begin
|
||
Name:=DefaultFileName;
|
||
P:=0;
|
||
end
|
||
else
|
||
begin
|
||
Link:=TopicLinks^.At((T^.HelpCtx and $ffff)-1)^;
|
||
{$IFDEF WDEBUG}
|
||
DebugMessageS({$i %file%},' Looking for "'+Link+'"',{$i %line%},'1',0,0);
|
||
{$endif WDEBUG}
|
||
Link:=FormatLink(Link);
|
||
{$IFDEF WDEBUG}
|
||
DebugMessageS({$i %file%},' Looking for (after formatlink) "'+Link+'"',{$i %line%},'1',0,0);
|
||
{$endif WDEBUG}
|
||
P:=Pos('#',Link);
|
||
if P>0 then
|
||
begin
|
||
Bookmark:=copy(Link,P+1,length(Link));
|
||
Link:=copy(Link,1,P-1);
|
||
{$IFDEF WDEBUG}
|
||
debugMessageS({$i %file%},' Removed label: "'+Link+'"',{$i %line%},'1',0,0);
|
||
{$endif WDEBUG}
|
||
end;
|
||
{ if CurFileName='' then Name:=Link else
|
||
Name:=CompletePath(CurFileName,Link);}
|
||
Name:=Link;
|
||
end;
|
||
HTMLFile:=nil;
|
||
if Name<>'' then
|
||
HTMLFile:=chmw.gettopic(name);
|
||
|
||
if (HTMLFile=nil) and (CurFileName<>'') then
|
||
begin
|
||
Name:=CurFileName;
|
||
HTMLFile:=chmw.gettopic(name);
|
||
end;
|
||
if (HTMLFile=nil) then
|
||
begin
|
||
{$IFDEF WDEBUG}
|
||
DebugMessage(Link,' filename not known :(',1,1);
|
||
{$endif WDEBUG}
|
||
end;
|
||
if (p>1) and (HTMLFile=nil) then
|
||
begin
|
||
{$IFDEF WDEBUG}
|
||
if p>0 then
|
||
DebugMessage(Name,Link+'#'+Bookmark+' not found',1,1)
|
||
else
|
||
DebugMessage(Name,Link+' not found',1,1);
|
||
{$endif WDEBUG}
|
||
New(HTMLFile, Init);
|
||
HTMLFile^.AddLine('<HEAD><TITLE>'+msg_pagenotavailable+'</TITLE></HEAD>');
|
||
HTMLFile^.AddLine(
|
||
'<BODY>'+
|
||
FormatStrStr(msg_cantaccessurl,Name)+'<br><br>'+
|
||
'</BODY>');
|
||
end;
|
||
OK:=Renderer^.BuildTopic(T,Name,HTMLFile,TopicLinks);
|
||
if OK then
|
||
CurFileName:=Name
|
||
else
|
||
begin
|
||
{$IFDEF WDEBUG}
|
||
if p>0 then
|
||
DebugMessage(Name,Link+'#'+Bookmark+' not found',1,1)
|
||
else
|
||
DebugMessage(Name,Link+' not found',1,1);
|
||
{$endif WDEBUG}
|
||
end;
|
||
if HTMLFile<>nil then Dispose(HTMLFile, Done);
|
||
if BookMark='' then
|
||
T^.StartNamedMark:=0
|
||
else
|
||
begin
|
||
P:=T^.GetNamedMarkIndex(BookMark);
|
||
{$IFDEF WDEBUG}
|
||
if p=-1 then
|
||
DebugMessage(Name,Link+'#'+Bookmark+' bookmark not found',1,1);
|
||
{$endif WDEBUG}
|
||
T^.StartNamedMark:=P+1;
|
||
end;
|
||
end;
|
||
ReadTopic:=OK;
|
||
end;
|
||
|
||
destructor TChmHelpFile.done;
|
||
|
||
begin
|
||
if assigned(chmw) then
|
||
chmw.free;
|
||
inherited Done;
|
||
end;
|
||
|
||
function CreateProcHTML(const FileName,Param: string;Index : longint): PHelpFile;
|
||
var H: PHelpFile;
|
||
begin
|
||
H:=nil;
|
||
if CompareText(copy(ExtOf(FileName),1,length(extHTML)),extHTML)=0 then
|
||
H:=New(PHTMLHelpFile, Init(FileName,Index,Param));
|
||
CreateProcHTML:=H;
|
||
end;
|
||
|
||
function CreateProcCHM(const FileName,Param: string;Index : longint): PHelpFile;
|
||
var H: PHelpFile;
|
||
begin
|
||
H:=nil;
|
||
if CompareText(copy(ExtOf(FileName),1,length(extCHM)),extCHM)=0 then
|
||
H:=New(PCHMHelpFile, Init(FileName,Index));
|
||
CreateProcCHM:=H;
|
||
end;
|
||
|
||
function CreateProcHTMLIndex(const FileName,Param: string;Index : longint): PHelpFile;
|
||
var H: PHelpFile;
|
||
begin
|
||
H:=nil;
|
||
if CompareText(ExtOf(FileName),extHTMLIndex)=0 then
|
||
H:=New(PHTMLIndexHelpFile, Init(FileName,Index));
|
||
CreateProcHTMLIndex:=H;
|
||
end;
|
||
|
||
procedure RegisterHelpType;
|
||
begin
|
||
RegisterHelpFileType({$ifdef FPC}@{$endif}CreateProcHTML);
|
||
RegisterHelpFileType({$ifdef FPC}@{$endif}CreateProcHTMLIndex);
|
||
RegisterHelpFileType({$ifdef FPC}@{$endif}CreateProcCHM);
|
||
end;
|
||
|
||
|
||
END.
|