1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870 |
- {
- 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;
- {$ifdef cpullvm}
- {$modeswitch nestedprocvars}
- {$endif}
- 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
- setlength(s,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+' Ü'); DocBreak;
- AddText(' '+CharStr('ß',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('þ'+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('Ä',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(TCallbackFunBoolParam(@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(TCallbackFunBoolParam(@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.
|