fpc/utils/fpdoc/dw_html.pp
2010-05-30 13:44:20 +00:00

3412 lines
95 KiB
ObjectPascal

{
FPDoc - Free Pascal Documentation Tool
Copyright (C) 2000 - 2005 by
Areca Systems GmbH / Sebastian Guenther, sg@freepascal.org
* HTML/XHTML output generator
See the file COPYING, 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.
}
{$mode objfpc}
{$H+}
unit dw_HTML;
interface
uses Classes, contnrs, DOM, DOM_HTML, dGlobals, PasTree, dWriter, ChmWriter, ChmBase;
const
// Subpage indices for modules
ResstrSubindex = 1;
ConstsSubindex = 2;
TypesSubindex = 3;
ClassesSubindex = 4;
ProcsSubindex = 5;
VarsSubindex = 6;
// Maybe needed later for topic overview ??
TopicsSubIndex = 7;
IndexSubIndex = 8;
// Subpage indices for classes
PropertiesByInheritanceSubindex = 1;
PropertiesByNameSubindex = 2;
MethodsByInheritanceSubindex = 3;
MethodsByNameSubindex = 4;
EventsByInheritanceSubindex = 5;
EventsByNameSubindex = 6;
type
TFileAllocator = class
public
procedure AllocFilename(AElement: TPasElement; ASubindex: Integer); virtual;
function GetFilename(AElement: TPasElement;
ASubindex: Integer): String; virtual; abstract;
function GetRelativePathToTop(AElement: TPasElement): String; virtual;
function GetCSSFilename(ARelativeTo: TPasElement): DOMString; virtual;
end;
TShortNameFileAllocator = class(TFileAllocator)
private
FExtension: String;
public
constructor Create(const AExtension: String);
procedure AllocFilename(AElement: TPasElement; ASubindex: Integer); override;
property Extension: String read FExtension;
end;
TLongNameFileAllocator = class(TFileAllocator)
private
FExtension: String;
public
constructor Create(const AExtension: String);
function GetFilename(AElement: TPasElement;
ASubindex: Integer): String; override;
function GetRelativePathToTop(AElement: TPasElement): String; override;
property Extension: String read FExtension;
end;
TPageInfo = class
Element: TPasElement;
SubpageIndex: Integer;
end;
{ THTMLWriter }
THTMLWriter = class(TFPDocWriter)
private
FOnTest: TNotifyEvent;
FPackage: TPasPackage;
FCharSet : String;
function GetPageCount: Integer;
procedure SetOnTest(const AValue: TNotifyEvent);
protected
FAllocator: TFileAllocator;
CurDirectory: String; // relative to curdir of process
BaseDirectory: String; // relative path to package base directory
PageInfos: TObjectList; // list of TPageInfo objects
Doc: THTMLDocument;
BodyElement, TitleElement: TDOMElement;
Module: TPasModule;
OutputNodeStack: TList;
CurOutputNode: TDOMNode;
InsideHeadRow, DoPasHighlighting: Boolean;
HighlighterFlags: Byte;
FooterFile: string;
FIDF : Boolean;
FDateFormat: String;
FIndexColCount : Integer;
FSearchPage : String;
FBaseImageURL : String;
Procedure CreateAllocator; virtual;
function ResolveLinkID(const Name: String): DOMString;
function ResolveLinkIDInUnit(const Name,AUnitName: String): DOMString;
function ResolveLinkWithinPackage(AElement: TPasElement;
ASubpageIndex: Integer): String;
// Helper functions for creating DOM elements
function CreateEl(Parent: TDOMNode; const AName: DOMString): THTMLElement;
function CreatePara(Parent: TDOMNode): THTMLElement;
function CreateH1(Parent: TDOMNode): THTMLElement;
function CreateH2(Parent: TDOMNode): THTMLElement;
function CreateH3(Parent: TDOMNode): THTMLElement;
function CreateTable(Parent: TDOMNode; const AClass: DOMString = ''): THTMLElement;
function CreateContentTable(Parent: TDOMNode): THTMLElement;
function CreateTR(Parent: TDOMNode): THTMLElement;
function CreateTD(Parent: TDOMNode): THTMLElement;
function CreateTD_vtop(Parent: TDOMNode): THTMLElement;
function CreateLink(Parent: TDOMNode; const AHRef: DOMString): THTMLElement;
function CreateAnchor(Parent: TDOMNode; const AName: DOMString): THTMLElement;
function CreateCode(Parent: TDOMNode): THTMLElement;
function CreateWarning(Parent: TDOMNode): THTMLElement;
// Description node conversion
procedure PushOutputNode(ANode: TDOMNode);
procedure PopOutputNode;
procedure DescrWriteText(const AText: DOMString); override;
procedure DescrBeginBold; override;
procedure DescrEndBold; override;
procedure DescrBeginItalic; override;
procedure DescrEndItalic; override;
procedure DescrBeginEmph; override;
procedure DescrEndEmph; override;
procedure DescrWriteImageEl(const AFileName, ACaption, ALinkName : DOMString); override;
procedure DescrWriteFileEl(const AText: DOMString); override;
procedure DescrWriteKeywordEl(const AText: DOMString); override;
procedure DescrWriteVarEl(const AText: DOMString); override;
procedure DescrBeginLink(const AId: DOMString); override;
procedure DescrEndLink; override;
procedure DescrBeginURL(const AURL: DOMString); override;
procedure DescrEndURL; override;
procedure DescrWriteLinebreak; override;
procedure DescrBeginParagraph; override;
procedure DescrEndParagraph; override;
procedure DescrBeginCode(HasBorder: Boolean; const AHighlighterName: String); override;
procedure DescrWriteCodeLine(const ALine: String); override;
procedure DescrEndCode; override;
procedure DescrBeginOrderedList; override;
procedure DescrEndOrderedList; override;
procedure DescrBeginUnorderedList; override;
procedure DescrEndUnorderedList; override;
procedure DescrBeginDefinitionList; override;
procedure DescrEndDefinitionList; override;
procedure DescrBeginListItem; override;
procedure DescrEndListItem; override;
procedure DescrBeginDefinitionTerm; override;
procedure DescrEndDefinitionTerm; override;
procedure DescrBeginDefinitionEntry; override;
procedure DescrEndDefinitionEntry; override;
procedure DescrBeginSectionTitle; override;
procedure DescrBeginSectionBody; override;
procedure DescrEndSection; override;
procedure DescrBeginRemark; override;
procedure DescrEndRemark; override;
procedure DescrBeginTable(ColCount: Integer; HasBorder: Boolean); override;
procedure DescrEndTable; override;
procedure DescrBeginTableCaption; override;
procedure DescrEndTableCaption; override;
procedure DescrBeginTableHeadRow; override;
procedure DescrEndTableHeadRow; override;
procedure DescrBeginTableRow; override;
procedure DescrEndTableRow; override;
procedure DescrBeginTableCell; override;
procedure DescrEndTableCell; override;
procedure AppendText(Parent: TDOMNode; const AText: DOMString);
procedure AppendNbSp(Parent: TDOMNode; ACount: Integer);
procedure AppendSym(Parent: TDOMNode; const AText: DOMString);
procedure AppendKw(Parent: TDOMNode; const AText: DOMString);
function AppendPasSHFragment(Parent: TDOMNode; const AText: String;
AShFlags: Byte): Byte;
Procedure AppendShortDescr(AContext : TPasElement;Parent: TDOMNode; DocNode : TDocNode);
procedure AppendShortDescr(Parent: TDOMNode; Element: TPasElement);
procedure AppendShortDescrCell(Parent: TDOMNode; Element: TPasElement);
procedure AppendDescr(AContext: TPasElement; Parent: TDOMNode;
DescrNode: TDOMElement; AutoInsertBlock: Boolean);
procedure AppendDescrSection(AContext: TPasElement; Parent: TDOMNode;
DescrNode: TDOMElement; const ATitle: DOMString);
function AppendHyperlink(Parent: TDOMNode; Element: TPasElement): TDOMElement;
function AppendType(CodeEl, TableEl: TDOMElement;
Element: TPasType; Expanded: Boolean;
NestingLevel: Integer = 0): TDOMElement;
function AppendProcType(CodeEl, TableEl: TDOMElement;
Element: TPasProcedureType; Indent: Integer): TDOMElement;
procedure AppendProcExt(CodeEl: TDOMElement; Element: TPasProcedure);
procedure AppendProcDecl(CodeEl, TableEl: TDOMElement;
Element: TPasProcedureBase);
procedure AppendProcArgsSection(Parent: TDOMNode;
Element: TPasProcedureType);
function AppendRecordType(CodeEl, TableEl: TDOMElement;
Element: TPasRecordType; NestingLevel: Integer): TDOMElement;
procedure AppendTitle(const AText: DOMString);
procedure AppendMenuBar(ASubpageIndex: Integer);
procedure AppendTopicMenuBar(Topic : TTopicElement);
procedure AppendSourceRef(AElement: TPasElement);
procedure FinishElementPage(AElement: TPasElement);
Procedure AppendSeeAlsoSection(AElement : TPasElement;DocNode : TDocNode);
Procedure AppendExampleSection(AElement : TPasElement;DocNode : TDocNode);
procedure AppendFooter;
procedure CreateIndexPage(L : TStringList);
procedure CreateModuleIndexPage(AModule: TPasModule);
procedure CreatePageBody(AElement: TPasElement; ASubpageIndex: Integer); virtual;
procedure CreatePackagePageBody;
procedure CreatePackageIndex;
procedure AddModuleIdentifiers(AModule : TPasModule; L : TStrings);
Procedure CreateTopicPageBody(AElement : TTopicElement);
procedure CreateModulePageBody(AModule: TPasModule; ASubpageIndex: Integer);
procedure CreateConstPageBody(AConst: TPasConst);
procedure CreateTypePageBody(AType: TPasType);
procedure CreateClassPageBody(AClass: TPasClassType; ASubpageIndex: Integer);
procedure CreateClassMemberPageBody(AElement: TPasElement);
procedure CreateVarPageBody(AVar: TPasVariable);
procedure CreateProcPageBody(AProc: TPasProcedureBase);
Procedure CreateTopicLinks(Node : TDocNode; PasElement : TPasElement);
public
constructor Create(APackage: TPasPackage; AEngine: TFPDocEngine); override;
destructor Destroy; override;
// Single-page generation
function CreateHTMLPage(AElement: TPasElement;
ASubpageIndex: Integer): TXMLDocument;
function CreateXHTMLPage(AElement: TPasElement;
ASubpageIndex: Integer): TXMLDocument;
// For producing complete package documentation
procedure WriteHTMLPages; virtual;
procedure WriteXHTMLPages;
Function InterPretOption(Const Cmd,Arg : String) : boolean; override;
Procedure WriteDoc; override;
class procedure Usage(List: TStrings); override;
Property SearchPage: String Read FSearchPage Write FSearchPage;
property Allocator: TFileAllocator read FAllocator;
property Package: TPasPackage read FPackage;
property PageCount: Integer read GetPageCount;
Property IncludeDateInFooter : Boolean Read FIDF Write FIDF;
Property DateFormat : String Read FDateFormat Write FDateFormat;
property OnTest: TNotifyEvent read FOnTest write SetOnTest;
Property CharSet : String Read FCharSet Write FCharSet;
Property IndexColCount : Integer Read FIndexColCount write FIndexColCount;
Property BaseImageURL : String Read FBaseImageURL Write FBaseImageURL;
end;
THTMWriter = class(THTMLWriter)
Protected
Procedure CreateAllocator; override;
end;
{$DEFINE chmInterface}
{$I dw_htmlchm.inc}
{$UNDEF chmInterface}
implementation
uses SysUtils, XHTML, XMLRead, XMLWrite, HTMWrite, sh_pas,chmsitemap;
Function FixHTMLpath(S : String) : STring;
begin
Result:=StringReplace(S,'\','/',[rfReplaceAll]);
end;
{$I dw_htmlchm.inc}
procedure TFileAllocator.AllocFilename(AElement: TPasElement;
ASubindex: Integer);
begin
end;
function TFileAllocator.GetRelativePathToTop(AElement: TPasElement): String;
begin
SetLength(Result, 0);
end;
function TFileAllocator.GetCSSFilename(ARelativeTo: TPasElement): DOMString;
begin
Result := GetRelativePathToTop(ARelativeTo) + 'fpdoc.css';
end;
constructor TShortNameFileAllocator.Create(const AExtension: String);
begin
inherited Create;
FExtension := AExtension;
end;
procedure TShortNameFileAllocator.AllocFilename(AElement: TPasElement;
ASubindex: Integer);
begin
// !!!: Add element to file list
end;
constructor TLongNameFileAllocator.Create(const AExtension: String);
begin
inherited Create;
FExtension := AExtension;
end;
function TLongNameFileAllocator.GetFilename(AElement: TPasElement;
ASubindex: Integer): String;
var
s: String;
i: Integer;
begin
if AElement.ClassType = TPasPackage then
Result := 'index'
else if AElement.ClassType = TPasModule then
Result := LowerCase(AElement.Name) + PathDelim + 'index'
else
begin
if AElement is TPasOperator then
begin
Result := LowerCase(AElement.Parent.PathName) + '.op-';
s := Copy(AElement.Name, Pos(' ', AElement.Name) + 1, Length(AElement.Name));
s := Copy(s, 1, Pos('(', s) - 1);
if s = ':=' then
s := 'assign'
else if s = '+' then
s := 'add'
else if s = '-' then
s := 'sub'
else if s = '*' then
s := 'mul'
else if s = '/' then
s := 'div'
else if s = '**' then
s := 'power'
else if s = '=' then
s := 'equal'
else if s = '<>' then
s := 'unequal'
else if s = '<' then
s := 'less'
else if s = '<=' then
s := 'lessequal'
else if s = '>' then
s := 'greater'
else if s = '>=' then
s := 'greaterthan'
else if s = '><' then
s := 'symmetricdifference';
Result := Result + s + '-';
s := '';
i := 1;
while AElement.Name[i] <> '(' do
Inc(i);
Inc(i);
while AElement.Name[i] <> ')' do
begin
if AElement.Name[i] = ',' then
begin
s := s + '-';
Inc(i);
end else
s := s + AElement.Name[i];
Inc(i);
end;
Result := Result + LowerCase(s) + '-' + LowerCase(Copy(AElement.Name,
Pos('):', AElement.Name) + 3, Length(AElement.Name)));
end else
Result := LowerCase(AElement.PathName);
i := 1;
if (Length(Result) > 0) and (Result[1] = '#') then
begin
while Result[i] <> '.' do
Inc(i);
Result := Copy(Result, i + 1, Length(Result));
end;
i := 1;
while (i <= Length(Result)) and (Result[i] <> '.') do
Inc(i);
if (i <= Length(Result)) and (i > 0) then
Result[i] := PathDelim;
end;
if ASubindex > 0 then
Result := Result + '-' + IntToStr(ASubindex);
Result := Result + Extension;
end;
function TLongNameFileAllocator.GetRelativePathToTop(AElement: TPasElement): String;
begin
if (AElement.ClassType=TPasPackage) then
Result := ''
else if (AElement.ClassType=TTopicElement) then
begin
If (AElement.Parent.ClassType=TTopicElement) then
Result:='../'+GetRelativePathToTop(AElement.Parent)
else if (AElement.Parent.ClassType=TPasPackage) then
Result:=''
else if (AElement.Parent.ClassType=TPasModule) then
Result:='../';
end
else
Result := '../';
end;
Type
{ TLinkData }
TLinkData = Class(TObject)
FPathName,
FLink,
FModuleName : String;
Constructor Create(Const APathName,ALink,AModuleName : string);
end;
{ TLinkData }
constructor TLinkData.Create(Const APathName, ALink, AModuleName: string);
begin
FPathName:=APathName;
FLink:=ALink;
FModuleName:=AModuleName;
end;
constructor THTMLWriter.Create(APackage: TPasPackage; AEngine: TFPDocEngine);
procedure AddPage(AElement: TPasElement; ASubpageIndex: Integer);
var
PageInfo: TPageInfo;
begin
PageInfo := TPageInfo.Create;
PageInfo.Element := AElement;
PageInfo.SubpageIndex := ASubpageIndex;
PageInfos.Add(PageInfo);
Allocator.AllocFilename(AElement, ASubpageIndex);
if ASubpageIndex = 0 then
Engine.AddLink(AElement.PathName,
Allocator.GetFilename(AElement, ASubpageIndex));
end;
procedure AddTopicPages(AElement: TPasElement);
var
PreviousTopic,
TopicElement : TTopicElement;
PageInfo : TPageInfo;
DocNode,
TopicNode : TDocNode;
begin
DocNode:=Engine.FindDocNode(AElement);
If not Assigned(DocNode) then
exit;
TopicNode:=DocNode.FirstChild;
PreviousTopic:=Nil;
While Assigned(TopicNode) do
begin
If TopicNode.TopicNode then
begin
TopicElement:=TTopicElement.Create(TopicNode.Name,AElement);
Topics.Add(TopicElement);
TopicElement.TopicNode:=TopicNode;
TopicElement.Previous:=PreviousTopic;
If Assigned(PreviousTopic) then
PreviousTopic.Next:=TopicElement;
PreviousTopic:=TopicElement;
if AElement is TTopicElement then
TTopicElement(AElement).SubTopics.Add(TopicElement);
PageInfo := TPageInfo.Create;
PageInfo.Element := TopicElement;
PageInfo.SubpageIndex := 0;
PageInfos.Add(PageInfo);
Allocator.AllocFilename(TopicElement,0);
Engine.AddLink(TopicElement.PathName, Allocator.GetFilename(TopicElement,0));
if AElement is TTopicElement then
TTopicElement(AElement).SubTopics.Add(TopicElement)
else // Only one level of recursion.
AddTopicPages(TopicElement);
end;
TopicNode:=TopicNode.NextSibling;
end;
end;
procedure AddPages(AElement: TPasElement; ASubpageIndex: Integer;
AList: TList);
var
i: Integer;
begin
if AList.Count > 0 then
begin
AddPage(AElement, ASubpageIndex);
for i := 0 to AList.Count - 1 do
AddPage(TPasElement(AList[i]), 0);
end;
end;
procedure ScanModule(AModule: TPasModule; LinkList : TObjectList);
var
i, j, k: Integer;
s: String;
ClassEl: TPasClassType;
FPEl, AncestorMemberEl: TPasElement;
DocNode: TDocNode;
ALink : DOMString;
DidAutolink: Boolean;
begin
AddPage(AModule, 0);
AddPage(AModule,IndexSubIndex);
AddTopicPages(AModule);
with AModule do
begin
if InterfaceSection.ResStrings.Count > 0 then
begin
AddPage(AModule, ResstrSubindex);
s := Allocator.GetFilename(AModule, ResstrSubindex);
for i := 0 to InterfaceSection.ResStrings.Count - 1 do
with TPasResString(InterfaceSection.ResStrings[i]) do
Engine.AddLink(PathName, s + '#' + LowerCase(Name));
end;
AddPages(AModule, ConstsSubindex, InterfaceSection.Consts);
AddPages(AModule, TypesSubindex, InterfaceSection.Types);
if InterfaceSection.Classes.Count > 0 then
begin
AddPage(AModule, ClassesSubindex);
for i := 0 to InterfaceSection.Classes.Count - 1 do
begin
ClassEl := TPasClassType(InterfaceSection.Classes[i]);
AddPage(ClassEl, 0);
// !!!: Only add when there are items
AddPage(ClassEl, PropertiesByInheritanceSubindex);
AddPage(ClassEl, PropertiesByNameSubindex);
AddPage(ClassEl, MethodsByInheritanceSubindex);
AddPage(ClassEl, MethodsByNameSubindex);
AddPage(ClassEl, EventsByInheritanceSubindex);
AddPage(ClassEl, EventsByNameSubindex);
for j := 0 to ClassEl.Members.Count - 1 do
begin
FPEl := TPasElement(ClassEl.Members[j]);
if ((FPEl.Visibility = visPrivate) and Engine.HidePrivate) or
((FPEl.Visibility = visProtected) and Engine.HideProtected) then
continue;
DocNode := Engine.FindDocNode(FPEl);
if Assigned(DocNode) then
begin
if Assigned(DocNode.Node) then
ALink:=DocNode.Node['link']
else
ALink:='';
If (ALink<>'') then
LinkList.Add(TLinkData.Create(FPEl.PathName,ALink,AModule.name))
else
AddPage(FPEl, 0);
end
else
begin
DidAutolink := False;
if Assigned(ClassEl.AncestorType) and
(ClassEl.AncestorType.ClassType = TPasClassType) then
begin
for k := 0 to TPasClassType(ClassEl.AncestorType).Members.Count - 1 do
begin
AncestorMemberEl :=
TPasElement(TPasClassType(ClassEl.AncestorType).Members[k]);
if AncestorMemberEl.Name = FPEl.Name then
begin
DocNode := Engine.FindDocNode(AncestorMemberEl);
if Assigned(DocNode) then
begin
DidAutolink := True;
Engine.AddLink(FPEl.PathName,
Engine.FindAbsoluteLink(AncestorMemberEl.PathName));
break;
end;
end;
end;
end;
if not DidAutolink then
AddPage(FPEl, 0);
end;
end;
end;
end;
AddPages(AModule, ProcsSubindex, InterfaceSection.Functions);
AddPages(AModule, VarsSubindex, InterfaceSection.Variables);
end;
end;
var
i: Integer;
L : TObjectList;
begin
inherited ;
IndexColCount:=3;
Charset:='iso-8859-1';
CreateAllocator;
FPackage := APackage;
OutputNodeStack := TList.Create;
PageInfos := TObjectList.Create;
// Allocate page for the package itself, if a name is given (i.e. <> '#')
if Length(Package.Name) > 1 then
begin
AddPage(Package, 0);
AddPage(Package,IndexSubIndex);
AddTopicPages(Package);
end;
L:=TObjectList.Create;
try
for i := 0 to Package.Modules.Count - 1 do
ScanModule(TPasModule(Package.Modules[i]),L);
// Resolve links
For I:=0 to L.Count-1 do
With TLinkData(L[i]) do
Engine.AddLink(FPathName,ResolveLinkIDInUnit(FLink,FModuleName));
finally
L.Free;
end;
end;
destructor THTMLWriter.Destroy;
begin
PageInfos.Free;
OutputNodeStack.Free;
FAllocator.Free;
inherited Destroy;
end;
function THTMLWriter.CreateHTMLPage(AElement: TPasElement;
ASubpageIndex: Integer): TXMLDocument;
var
HTMLEl: THTMLHtmlElement;
HeadEl: THTMLHeadElement;
El: TDOMElement;
begin
Doc := THTMLDocument.Create;
Result := Doc;
Doc.AppendChild(Doc.Impl.CreateDocumentType(
'HTML', '-//W3C//DTD HTML 4.01 Transitional//EN',
'http://www.w3.org/TR/html4/loose.dtd'));
HTMLEl := Doc.CreateHtmlElement;
Doc.AppendChild(HTMLEl);
HeadEl := Doc.CreateHeadElement;
HTMLEl.AppendChild(HeadEl);
El := Doc.CreateElement('meta');
HeadEl.AppendChild(El);
El['http-equiv'] := 'Content-Type';
El['content'] := 'text/html; charset=utf-8';
TitleElement := Doc.CreateElement('title');
HeadEl.AppendChild(TitleElement);
El := Doc.CreateElement('link');
BodyElement := Doc.CreateElement('body');
HTMLEl.AppendChild(BodyElement);
CreatePageBody(AElement, ASubpageIndex);
AppendFooter;
HeadEl.AppendChild(El);
El['rel'] := 'stylesheet';
El['type'] := 'text/css';
El['href'] := FixHtmlPath(Allocator.GetCSSFilename(AElement));
end;
function THTMLWriter.CreateXHTMLPage(AElement: TPasElement;
ASubpageIndex: Integer): TXMLDocument;
begin
Result := nil;
end;
procedure CreatePath(const AFilename: String);
var
EndIndex: Integer;
Path: String;
begin
EndIndex := Length(AFilename);
if EndIndex = 0 then
exit;
while not (AFilename[EndIndex] in AllowDirectorySeparators) do
begin
Dec(EndIndex);
if EndIndex = 0 then
exit;
end;
Path := Copy(AFilename, 1, EndIndex - 1);
if not DirectoryExists(Path) then
begin
CreatePath(Path);
MkDir(Path);
end;
end;
procedure THTMLWriter.WriteHTMLPages;
var
i: Integer;
PageDoc: TXMLDocument;
Filename: String;
begin
if Engine.Output <> '' then
Engine.Output := IncludeTrailingBackSlash(Engine.Output);
for i := 0 to PageInfos.Count - 1 do
with TPageInfo(PageInfos[i]) do
begin
PageDoc := CreateHTMLPage(Element, SubpageIndex);
try
Filename := Engine.Output + Allocator.GetFilename(Element, SubpageIndex);
try
CreatePath(Filename);
WriteHTMLFile(PageDoc, Filename);
except
on E: Exception do
WriteLn(Format(SErrCouldNotCreateFile, [FileName, e.Message]));
end;
finally
PageDoc.Free;
end;
end;
end;
procedure THTMLWriter.WriteXHTMLPages;
begin
end;
{procedure THTMLWriter.CreateDoc(const ATitle: DOMString;
AElement: TPasElement; const AFilename: String);
var
El: TDOMElement;
DocInfo: TDocInfo;
CSSName: String;
begin
Doc := TXHTMLDocument.Create;
with TXHTMLDocument(Doc) do
begin
Encoding := 'ISO8859-1';
CSSName := 'fpdoc.css';
if Assigned(Module) then
CSSName := '../' + CSSName;
$IFNDEF ver1_0
StylesheetType := 'text/css';
StylesheetHRef := CSSName;
$ENDIF
CreateRoot(xhtmlStrict);
with RequestHeadElement do
begin
AppendText(RequestTitleElement, ATitle);
El := CreateElement('link');
AppendChild(El);
El['rel'] := 'stylesheet';
El['type'] := 'text/css';
El['href'] := FixHtmlPath(CSSName);
end;
Self.BodyElement := RequestBodyElement('en');
end;
if Length(AFilename) > 0 then
begin
DocInfo := TDocInfo.Create;
DocInfos.Add(DocInfo);
DocInfo.Element := AElement;
DocInfo.Filename := AFilename;
end;
end;
}
{ Used for:
- <link> elements in descriptions
- "see also" entries
- AppendHyperlink (for unresolved parse tree element links)
}
function THTMLWriter.ResolveLinkIDInUnit(const Name,AUnitName: String): DOMString;
begin
Result:=ResolveLinkID(Name);
If (Result='') and (AUnitName<>'') then
Result:=ResolveLinkID(AUnitName+'.'+Name);
end;
function THTMLWriter.ResolveLinkID(const Name: String): DOMString;
var
i: Integer;
ThisPackage: TLinkNode;
begin
if Length(Name) = 0 then
begin
SetLength(Result, 0);
exit;
end;
if Name[1] = '#' then
Result := Engine.FindAbsoluteLink(Name)
else
begin
SetLength(Result, 0);
{ Try all packages }
ThisPackage := Engine.RootLinkNode.FirstChild;
while Assigned(ThisPackage) do
begin
Result := Engine.FindAbsoluteLink(ThisPackage.Name + '.' + Name);
if Length(Result) = 0 then
begin
if Assigned(Module) then
begin
Result := Engine.FindAbsoluteLink(Module.PathName + '.' + Name);
// WriteLn('Searching for ', Module.PathName + '.' + Name, ' => ', Result);
end;
if Length(Result) = 0 then
for i := Length(Name) downto 1 do
if Name[i] = '.' then
begin
Result := ResolveLinkID(Copy(Name, 1, i - 1));
exit;
end;
end;
ThisPackage := ThisPackage.NextSibling;
end;
end;
if Length(Result) > 0 then
if Copy(Result, 1, Length(CurDirectory) + 1) = CurDirectory + '/' then
Result := Copy(Result, Length(CurDirectory) + 2, Length(Result))
else if not IsLinkAbsolute(Result) then
Result := BaseDirectory + Result;
end;
function THTMLWriter.ResolveLinkWithinPackage(AElement: TPasElement;
ASubpageIndex: Integer): String;
var
ParentEl: TPasElement;
begin
ParentEl := AElement;
while Assigned(ParentEl) and not (ParentEl.ClassType = TPasPackage) do
ParentEl := ParentEl.Parent;
if Assigned(ParentEl) and (TPasPackage(ParentEl) = Engine.Package) then
begin
Result := Allocator.GetFilename(AElement, ASubpageIndex);
if Copy(Result, 1, Length(CurDirectory) + 1) = CurDirectory + '/' then
Result := Copy(Result, Length(CurDirectory) + 2, Length(Result))
else
Result := BaseDirectory + Result;
end else
SetLength(Result, 0);
end;
function THTMLWriter.CreateEl(Parent: TDOMNode;
const AName: DOMString): THTMLElement;
begin
Result := Doc.CreateElement(AName);
Parent.AppendChild(Result);
end;
function THTMLWriter.CreatePara(Parent: TDOMNode): THTMLElement;
begin
Result := CreateEl(Parent, 'p');
end;
function THTMLWriter.CreateH1(Parent: TDOMNode): THTMLElement;
begin
Result := CreateEl(Parent, 'h1');
end;
function THTMLWriter.CreateH2(Parent: TDOMNode): THTMLElement;
begin
Result := CreateEl(Parent, 'h2');
end;
function THTMLWriter.CreateH3(Parent: TDOMNode): THTMLElement;
begin
Result := CreateEl(Parent, 'h3');
end;
function THTMLWriter.CreateTable(Parent: TDOMNode; const AClass: DOMString = ''): THTMLElement;
begin
Result := CreateEl(Parent, 'table');
Result['cellspacing'] := '0';
Result['cellpadding'] := '0';
if AClass <> '' then
Result['class'] := AClass;
end;
function THTMLWriter.CreateContentTable(Parent: TDOMNode): THTMLElement;
begin
Result := CreateEl(Parent, 'table');
end;
function THTMLWriter.CreateTR(Parent: TDOMNode): THTMLElement;
begin
Result := CreateEl(Parent, 'tr');
end;
function THTMLWriter.CreateTD(Parent: TDOMNode): THTMLElement;
begin
Result := CreateEl(Parent, 'td');
end;
function THTMLWriter.CreateTD_vtop(Parent: TDOMNode): THTMLElement;
begin
Result := CreateEl(Parent, 'td');
Result['valign'] := 'top';
end;
function THTMLWriter.CreateLink(Parent: TDOMNode;
const AHRef: DOMString): THTMLElement;
begin
Result := CreateEl(Parent, 'a');
Result['href'] := FixHtmlPath(AHRef);
end;
function THTMLWriter.CreateAnchor(Parent: TDOMNode;
const AName: DOMString): THTMLElement;
begin
Result := CreateEl(Parent, 'a');
Result['name'] := AName;
end;
function THTMLWriter.CreateCode(Parent: TDOMNode): THTMLElement;
begin
Result := CreateEl(CreateEl(Parent, 'tt'), 'span');
Result['class'] := 'code';
end;
function THTMLWriter.CreateWarning(Parent: TDOMNode): THTMLElement;
begin
Result := CreateEl(Parent, 'span');
Result['class'] := 'warning';
end;
procedure THTMLWriter.PushOutputNode(ANode: TDOMNode);
begin
OutputNodeStack.Add(CurOutputNode);
CurOutputNode := ANode;
end;
procedure THTMLWriter.PopOutputNode;
begin
CurOutputNode := TDOMNode(OutputNodeStack[OutputNodeStack.Count - 1]);
OutputNodeStack.Delete(OutputNodeStack.Count - 1);
end;
procedure THTMLWriter.DescrWriteText(const AText: DOMString);
begin
AppendText(CurOutputNode, AText);
end;
procedure THTMLWriter.DescrBeginBold;
begin
PushOutputNode(CreateEl(CurOutputNode, 'b'));
end;
procedure THTMLWriter.DescrEndBold;
begin
PopOutputNode;
end;
procedure THTMLWriter.DescrBeginItalic;
begin
PushOutputNode(CreateEl(CurOutputNode, 'i'));
end;
procedure THTMLWriter.DescrEndItalic;
begin
PopOutputNode;
end;
procedure THTMLWriter.DescrBeginEmph;
begin
PushOutputNode(CreateEl(CurOutputNode, 'em'));
end;
procedure THTMLWriter.DescrEndEmph;
begin
PopOutputNode;
end;
procedure THTMLWriter.DescrWriteImageEl(const AFileName, ACaption, ALinkName : DOMString);
Var
Pel,Cel,Lel : TDOMNode;
El :TDomElement;
D : String;
L : Integer;
begin
// Determine parent node.
If (ACaption='') then
Pel:=CurOutputNode
else
begin
Cel:=CreateTable(CurOutputNode, 'imagetable');
Pel:=CreateTD(CreateTR(Cel));
Cel:=CreateTD(CreateTR(Cel));
El := CreateEl(Cel, 'span');
El['class'] := 'imagecaption';
Cel := El;
If (ALinkName<>'') then
Cel:=CreateAnchor(Cel,ALinkName);
AppendText(Cel,ACaption);
end;
// Determine URL for image.
D:=BaseImageURL;
If (D='') then
begin
If (Module=Nil) then
D:=Allocator.GetRelativePathToTop(Package)
else
D:=Allocator.GetRelativePathToTop(Module);
L:=Length(D);
If (L>0) and (D[L]<>'/') then
D:=D+'/';
D:=D+'images/';
end
else
L:=Length(D);
If (L>0) and (D[L]<>'/') then
D:=D+'/';
// Create image node.
El:=CreateEl(Pel,'img');
EL['src']:=D+AFileName;
El['alt']:=ACaption;
end;
procedure THTMLWriter.DescrWriteFileEl(const AText: DOMString);
var
NewEl: TDOMElement;
begin
NewEl := CreateEl(CurOutputNode, 'span');
NewEl['class'] := 'file';
AppendText(NewEl, AText);
end;
procedure THTMLWriter.DescrWriteKeywordEl(const AText: DOMString);
var
NewEl: TDOMElement;
begin
NewEl := CreateEl(CurOutputNode, 'span');
NewEl['class'] := 'kw';
AppendText(NewEl, AText);
end;
procedure THTMLWriter.DescrWriteVarEl(const AText: DOMString);
begin
AppendText(CreateEl(CurOutputNode, 'var'), AText);
end;
procedure THTMLWriter.DescrBeginLink(const AId: DOMString);
var
a,s: String;
begin
a:=AId;
s := ResolveLinkID(a);
if Length(s) = 0 then
begin
WriteLn(Format(SErrUnknownLinkID, [a]));
PushOutputNode(CreateEl(CurOutputNode, 'b'));
end else
PushOutputNode(CreateLink(CurOutputNode, s));
end;
procedure THTMLWriter.DescrEndLink;
begin
PopOutputNode;
end;
procedure THTMLWriter.DescrBeginURL(const AURL: DOMString);
begin
PushOutputNode(CreateLink(CurOutputNode, AURL));
end;
procedure THTMLWriter.DescrEndURL;
begin
PopOutputNode;
end;
procedure THTMLWriter.DescrWriteLinebreak;
begin
CreateEl(CurOutputNode, 'br');
end;
procedure THTMLWriter.DescrBeginParagraph;
begin
PushOutputNode(CreatePara(CurOutputNode));
end;
procedure THTMLWriter.DescrEndParagraph;
begin
PopOutputNode;
end;
procedure THTMLWriter.DescrBeginCode(HasBorder: Boolean; const AHighlighterName: String);
begin
DoPasHighlighting := (AHighlighterName = '') or (AHighlighterName = 'Pascal');
HighlighterFlags := 0;
PushOutputNode(CreateEl(CurOutputNode, 'pre'));
end;
procedure THTMLWriter.DescrWriteCodeLine(const ALine: String);
begin
if DoPasHighlighting then
begin
HighlighterFlags := AppendPasSHFragment(CurOutputNode, ALine,
HighlighterFlags);
AppendText(CurOutputNode, #10);
end else
AppendText(CurOutputNode, ALine + #10);
end;
procedure THTMLWriter.DescrEndCode;
begin
PopOutputNode;
end;
procedure THTMLWriter.DescrBeginOrderedList;
begin
PushOutputNode(CreateEl(CurOutputNode, 'ol'));
end;
procedure THTMLWriter.DescrEndOrderedList;
begin
PopOutputNode;
end;
procedure THTMLWriter.DescrBeginUnorderedList;
begin
PushOutputNode(CreateEl(CurOutputNode, 'ul'));
end;
procedure THTMLWriter.DescrEndUnorderedList;
begin
PopOutputNode;
end;
procedure THTMLWriter.DescrBeginDefinitionList;
begin
PushOutputNode(CreateEl(CurOutputNode, 'dl'));
end;
procedure THTMLWriter.DescrEndDefinitionList;
begin
PopOutputNode;
end;
procedure THTMLWriter.DescrBeginListItem;
begin
PushOutputNode(CreateEl(CurOutputNode, 'li'));
end;
procedure THTMLWriter.DescrEndListItem;
begin
PopOutputNode;
end;
procedure THTMLWriter.DescrBeginDefinitionTerm;
begin
PushOutputNode(CreateEl(CurOutputNode, 'dt'));
end;
procedure THTMLWriter.DescrEndDefinitionTerm;
begin
PopOutputNode;
end;
procedure THTMLWriter.DescrBeginDefinitionEntry;
begin
PushOutputNode(CreateEl(CurOutputNode, 'dd'));
end;
procedure THTMLWriter.DescrEndDefinitionEntry;
begin
PopOutputNode;
end;
procedure THTMLWriter.DescrBeginSectionTitle;
begin
PushOutputNode(CreateEl(CurOutputNode, 'h3'));
end;
procedure THTMLWriter.DescrBeginSectionBody;
begin
PopOutputNode;
end;
procedure THTMLWriter.DescrEndSection;
begin
end;
procedure THTMLWriter.DescrBeginRemark;
var
NewEl, TDEl: TDOMElement;
begin
NewEl := CreateEl(CurOutputNode, 'table');
NewEl['width'] := '100%';
NewEl['border'] := '0';
NewEl['CellSpacing'] := '0';
NewEl['class'] := 'remark';
NewEl := CreateTR(NewEl);
TDEl := CreateTD(NewEl);
TDEl['valign'] := 'top';
TDEl['class'] := 'pre';
AppendText(CreateEl(TDEl, 'b'), SDocRemark);
PushOutputNode(CreateTD(NewEl));
end;
procedure THTMLWriter.DescrEndRemark;
begin
PopOutputNode;
end;
procedure THTMLWriter.DescrBeginTable(ColCount: Integer; HasBorder: Boolean);
var
Table: TDOMElement;
begin
Table := CreateEl(CurOutputNode, 'table');
Table['border'] := IntToStr(Ord(HasBorder));
PushOutputNode(Table);
end;
procedure THTMLWriter.DescrEndTable;
begin
PopOutputNode;
end;
procedure THTMLWriter.DescrBeginTableCaption;
begin
PushOutputNode(CreateEl(CurOutputNode, 'caption'));
end;
procedure THTMLWriter.DescrEndTableCaption;
begin
PopOutputNode;
end;
procedure THTMLWriter.DescrBeginTableHeadRow;
begin
PushOutputNode(CreateTr(CurOutputNode));
InsideHeadRow := True;
end;
procedure THTMLWriter.DescrEndTableHeadRow;
begin
InsideHeadRow := False;
PopOutputNode;
end;
procedure THTMLWriter.DescrBeginTableRow;
begin
PushOutputNode(CreateTR(CurOutputNode));
end;
procedure THTMLWriter.DescrEndTableRow;
begin
PopOutputNode;
end;
procedure THTMLWriter.DescrBeginTableCell;
begin
if InsideHeadRow then
PushOutputNode(CreateEl(CurOutputNode, 'th'))
else
PushOutputNode(CreateTD(CurOutputNode));
end;
procedure THTMLWriter.DescrEndTableCell;
begin
PopOutputNode;
end;
procedure THTMLWriter.AppendText(Parent: TDOMNode; const AText: DOMString);
begin
Parent.AppendChild(Doc.CreateTextNode(AText));
end;
procedure THTMLWriter.AppendNbSp(Parent: TDOMNode; ACount: Integer);
begin
while ACount > 0 do
begin
Parent.AppendChild(Doc.CreateEntityReference('nbsp'));
Dec(ACount);
end;
end;
procedure THTMLWriter.AppendSym(Parent: TDOMNode; const AText: DOMString);
var
El: TDOMElement;
begin
El := CreateEl(Parent, 'span');
El['class'] := 'sym';
AppendText(El, AText);
end;
procedure THTMLWriter.AppendKw(Parent: TDOMNode; const AText: DOMString);
var
El: TDOMElement;
begin
El := CreateEl(Parent, 'span');
El['class'] := 'kw';
AppendText(El, AText);
end;
function THTMLWriter.AppendPasSHFragment(Parent: TDOMNode;
const AText: String; AShFlags: Byte): Byte;
var
Line, Last, p: PChar;
IsInSpecial: Boolean;
lastwasasm : boolean;
El: TDOMElement;
Procedure MaybeOutput;
Var
CurParent: TDomNode;
begin
If (Last<>Nil) then
begin
If (el<>Nil) then
CurParent:=El
else
CurParent:=Parent;
AppendText(CurParent,Last);
El:=Nil;
Last:=Nil;
end;
end;
Function NewEl(Const ElType,Attr,AttrVal : String) : TDomElement;
begin
Result:=CreateEl(Parent,ElType);
Result[Attr]:=AttrVal;
end;
Function NewSpan(Const AttrVal : String) : TDomElement;
begin
Result:=CreateEl(Parent,'span');
Result['class']:=AttrVal;
end;
begin
GetMem(Line, Length(AText) * 3 + 4);
Try
DoPascalHighlighting(AShFlags, PChar(AText), Line);
Result := AShFlags;
IsInSpecial := False;
Last := Nil;
p := Line;
el:=nil;
while p[0] <> #0 do
begin
if p[0] = LF_ESCAPE then
begin
p[0] := #0;
MaybeOutput;
case Ord(p[1]) of
shDefault: El:=Nil;
shInvalid: El:=newel('font','color','red');
shSymbol : El:=newspan('sym');
shKeyword: El:=newspan('kw');
shComment: El:=newspan('cmt');
shDirective: El:=newspan('dir');
shNumbers: El:=newspan('num');
shCharacters: El:=newspan('chr');
shStrings: El:=newspan('str');
shAssembler: El:=newspan('asm');
end;
Inc(P);
end
else If (Last=Nil) then
Last:=P;
Inc(p);
end;
MaybeOutput;
Finally
FreeMem(Line);
end;
end;
Procedure THTMLWriter.AppendShortDescr(AContext: TPasElement; Parent: TDOMNode; DocNode : TDocNode);
Var
N : TDocNode;
begin
if Assigned(DocNode) then
begin
If (DocNode.Link<>'') then
begin
N:=Engine.FindLinkedNode(DocNode);
If (N<>Nil) then
DocNode:=N;
end;
If Assigned(DocNode.ShortDescr) then
begin
PushOutputNode(Parent);
try
if not ConvertShort(AContext,TDomElement(DocNode.ShortDescr)) then
Warning(AContext, SErrInvalidShortDescr)
finally
PopOutputNode;
end;
end;
end;
end;
procedure THTMLWriter.AppendShortDescr(Parent: TDOMNode; Element: TPasElement);
begin
AppendShortDescr(Element,Parent,Engine.FindDocNode(Element));
end;
procedure THTMLWriter.AppendShortDescrCell(Parent: TDOMNode;
Element: TPasElement);
var
ParaEl: TDOMElement;
begin
if Assigned(Engine.FindShortDescr(Element)) then
begin
AppendNbSp(CreatePara(CreateTD(Parent)), 2);
ParaEl := CreatePara(CreateTD(Parent));
ParaEl['class'] := 'cmt';
AppendShortDescr(ParaEl, Element);
end;
end;
procedure THTMLWriter.AppendDescr(AContext: TPasElement; Parent: TDOMNode;
DescrNode: TDOMElement; AutoInsertBlock: Boolean);
begin
if Assigned(DescrNode) then
begin
PushOutputNode(Parent);
try
ConvertDescr(AContext, DescrNode, AutoInsertBlock);
finally
PopOutputNode;
end;
end;
end;
procedure THTMLWriter.AppendDescrSection(AContext: TPasElement;
Parent: TDOMNode; DescrNode: TDOMElement; const ATitle: DOMString);
begin
if not IsDescrNodeEmpty(DescrNode) then
begin
If (ATitle<>'') then // Can be empty for topic.
AppendText(CreateH2(Parent), ATitle);
AppendDescr(AContext, Parent, DescrNode, True);
end;
end;
function THTMLWriter.AppendHyperlink(Parent: TDOMNode;
Element: TPasElement): TDOMElement;
var
s: String;
UnitList: TList;
i: Integer;
ThisPackage: TLinkNode;
begin
if Assigned(Element) then
begin
if Element.InheritsFrom(TPasUnresolvedTypeRef) then
begin
s := ResolveLinkID(Element.Name);
if Length(s) = 0 then
begin
{ Try all packages }
ThisPackage := Engine.RootLinkNode.FirstChild;
while Assigned(ThisPackage) do
begin
s := ResolveLinkID(ThisPackage.Name + '.' + Element.Name);
if Length(s) > 0 then
break;
ThisPackage := ThisPackage.NextSibling;
end;
if Length(s) = 0 then
begin
{ Okay, then we have to try all imported units of the current module }
UnitList := Module.InterfaceSection.UsesList;
for i := UnitList.Count - 1 downto 0 do
begin
{ Try all packages }
ThisPackage := Engine.RootLinkNode.FirstChild;
while Assigned(ThisPackage) do
begin
s := ResolveLinkID(ThisPackage.Name + '.' +
TPasType(UnitList[i]).Name + '.' + Element.Name);
if Length(s) > 0 then
break;
ThisPackage := ThisPackage.NextSibling;
end;
if Length(s) > 0 then
break;
end;
end;
end;
end else if Element is TPasEnumValue then
s := ResolveLinkID(Element.Parent.PathName)
else
s := ResolveLinkID(Element.PathName);
if Length(s) > 0 then
begin
Result := CreateLink(Parent, s);
AppendText(Result, Element.Name);
end else
begin
Result := nil;
AppendText(Parent, Element.Name);
end;
end else
begin
Result := nil;
AppendText(CreateWarning(Parent), '<NIL>');
end;
end;
{ Returns the new CodeEl, which will be the old CodeEl in most cases }
function THTMLWriter.AppendType(CodeEl, TableEl: TDOMElement;
Element: TPasType; Expanded: Boolean; NestingLevel: Integer): TDOMElement;
Var
S : String;
begin
Result := CodeEl;
if not Assigned(Element) then
AppendText(CreateWarning(CodeEl), '<NIL>')
else if (not Expanded) and (Length(Element.Name) > 0) then
AppendHyperlink(CodeEl, Element)
else
// Array
if Element.ClassType = TPasArrayType then
begin
S:='array ';
If (TPasArrayType(Element).IndexRange<>'') then
S:=S+'[' + TPasArrayType(Element).IndexRange + '] ';
S:=S+'of ';
If (TPasArrayType(Element).ElType=Nil) then
S:=S+'Const';
AppendPasSHFragment(CodeEl,S,0);
If (TPasArrayType(Element).ElType<>Nil) then
Result := AppendType(CodeEl, TableEl, TPasArrayType(Element).ElType, False);
end else
// Procedure or funtion type
if Element.InheritsFrom(TPasProcedureType) then
begin
AppendKw(CodeEl, TPasProcedureType(Element).TypeName);
Result := AppendProcType(CodeEl, TableEl, TPasProcedureType(Element), 0)
end else
// Range type
if Element.InheritsFrom(TPasRangeType) then
AppendPasSHFragment(CodeEl, TPasRangeType(Element).RangeStart + '..' +
TPasRangeType(Element).RangeEnd, 0)
// Record type
else if Element.ClassType = TPasRecordType then
Result := AppendRecordType(CodeEl, TableEl, TPasRecordType(Element), NestingLevel)
else if (Element.ClassType = TPasFileType) and (TPasFileType(Element).elType=Nil) then
AppendPasSHFragment(CodeEl,'file',0)
else
// Other types
AppendHyperlink(CodeEl, Element);
end;
function THTMLWriter.AppendProcType(CodeEl, TableEl: TDOMElement;
Element: TPasProcedureType; Indent: Integer): TDOMElement;
function CreateIndentedCodeEl(Indent: Integer): TDOMElement;
begin
Result := CreateCode(CreatePara(CreateTD(CreateTR(TableEl))));
AppendNbSp(Result, Indent);
end;
var
i: Integer;
Arg: TPasArgument;
begin
if Element.Args.Count > 0 then
begin
AppendSym(CodeEl, '(');
for i := 0 to Element.Args.Count - 1 do
begin
Arg := TPasArgument(Element.Args[i]);
CodeEl := CreateIndentedCodeEl(Indent + 2);
case Arg.Access of
argConst: AppendKw(CodeEl, 'const ');
argVar: AppendKw(CodeEl, 'var ');
argOut: AppendKw(CodeEl, 'out ');
end;
AppendText(CodeEl, Arg.Name);
if Assigned(Arg.ArgType) then
begin
AppendSym(CodeEl, ': ');
CodeEl := AppendType(CodeEl, TableEl, Arg.ArgType, False);
end;
if Length(Arg.Value) > 0 then
AppendPasSHFragment(CodeEl, ' = ' + Arg.Value, 0);
if i < Element.Args.Count - 1 then
AppendSym(CodeEl, ';');
end;
if Element.InheritsFrom(TPasFunctionType) or Element.IsOfObject then
begin
CodeEl := CreateIndentedCodeEl(Indent);
if Element.InheritsFrom(TPasFunctionType) then
begin
AppendSym(CodeEl, '):');
AppendHyperlink(CodeEl, TPasFunctionType(Element).ResultEl.ResultType);
end else
AppendSym(CodeEl, ')');
if Element.IsOfObject then
begin
AppendText(CodeEl, ' '); // Don't remove
AppendKw(CodeEl, 'of object');
end;
end else
if Indent > 0 then
AppendSym(CodeEl, ')')
else
begin
CodeEl := CreateCode(CreatePara(CreateTD(CreateTR(TableEl))));
AppendSym(CodeEl, ')');
end;
end else
begin
{ Procedure or function without arguments }
if Element.InheritsFrom(TPasFunctionType) then
begin
AppendSym(CodeEl, ': ');
AppendHyperlink(CodeEl, TPasFunctionType(Element).ResultEl.ResultType);
end;
if Element.IsOfObject then
AppendKw(CodeEl, ' of object');
end;
Result := CodeEl;
end;
procedure THTMLWriter.AppendProcExt(CodeEl: TDOMElement;
Element: TPasProcedure);
procedure AppendExt(const Ext: String);
begin
AppendKw(CodeEl, ' ' + Ext);
AppendSym(CodeEl, ';');
end;
begin
if Element.IsVirtual then
AppendExt('virtual');
if Element.IsDynamic then
AppendExt('dynamic');
if Element.IsAbstract then
AppendExt('abstract');
if Element.IsOverride then
AppendExt('override');
if Element.IsOverload then
AppendExt('overload');
if Element.IsMessage then
AppendExt('message');
end;
{ Used in two places:
- Page for the method of a class
- Page for a tandalone procedure or function. }
procedure THTMLWriter.AppendProcDecl(CodeEl, TableEl: TDOMElement;
Element: TPasProcedureBase);
procedure WriteVariant(AProc: TPasProcedure);
begin
AppendProcArgsSection(TableEl.ParentNode, AProc.ProcType);
AppendKw(CodeEl, AProc.TypeName);
if Element.Parent.ClassType = TPasClassType then
begin
AppendText(CodeEl, ' ');
AppendHyperlink(CodeEl, Element.Parent);
AppendSym(CodeEl, '.');
AppendText(CodeEl, AProc.Name);
end else
AppendText(CodeEl, ' ' + AProc.FullName);
CodeEl := AppendProcType(CodeEl, TableEl, AProc.ProcType, 0);
AppendSym(CodeEl, ';');
AppendProcExt(CodeEl, AProc);
end;
var
i: Integer;
begin
if Element.ClassType = TPasOverloadedProc then
for i := 0 to TPasOverloadedProc(Element).Overloads.Count - 1 do
begin
if i > 0 then
begin
CreateEl(CodeEl, 'br');
CreateEl(CodeEl, 'br');
end;
WriteVariant(TPasProcedure(TPasOverloadedProc(Element).Overloads[i]));
end
else
WriteVariant(TPasProcedure(Element));
end;
procedure THTMLWriter.AppendProcArgsSection(Parent: TDOMNode;
Element: TPasProcedureType);
var
HasFullDescr, IsFirst: Boolean;
ResultEl: TPasResultElement;
ArgTableEl, TREl: TDOMElement;
DocNode: TDocNode;
i: Integer;
Arg: TPasArgument;
begin
IsFirst := True;
for i := 0 to Element.Args.Count - 1 do
begin
Arg := TPasArgument(Element.Args[i]);
if IsDescrNodeEmpty(Engine.FindShortDescr(Arg)) then
continue;
if IsFirst then
begin
IsFirst := False;
AppendText(CreateH2(Parent), SDocArguments);
ArgTableEl := CreateTable(Parent);
end;
TREl := CreateTR(ArgTableEl);
AppendText(CreateCode(CreatePara(CreateTD_vtop(TREl))), Arg.Name);
AppendShortDescrCell(TREl, Arg);
end;
if Element.ClassType = TPasFunctionType then
begin
ResultEl := TPasFunctionType(Element).ResultEl;
DocNode := Engine.FindDocNode(ResultEl);
HasFullDescr := Assigned(DocNode) and not IsDescrNodeEmpty(DocNode.Descr);
if HasFullDescr or
(Assigned(DocNode) and not IsDescrNodeEmpty(DocNode.ShortDescr)) then
begin
AppendText(CreateH2(Parent), SDocFunctionResult);
if HasFullDescr then
AppendDescr(ResultEl, Parent, DocNode.Descr, True)
else
AppendDescr(ResultEl, CreatePara(Parent), DocNode.ShortDescr, False);
end;
end;
end;
function THTMLWriter.AppendRecordType(CodeEl, TableEl: TDOMElement;
Element: TPasRecordType; NestingLevel: Integer): TDOMElement;
var
i, j: Integer;
Variable: TPasVariable;
TREl, TDEl: TDOMElement;
CurVariant: TPasVariant;
begin
if not (Element.Parent is TPasVariant) then
if Element.IsPacked then
If Element.IsBitPacked then
AppendKw(CodeEl, 'bitpacked record')
else
AppendKW(CodeEl, 'packed record')
else
AppendKw(CodeEl, 'record');
for i := 0 to Element.Members.Count - 1 do
begin
Variable := TPasVariable(Element.Members[i]);
TREl := CreateTR(TableEl);
CodeEl := CreateCode(CreatePara(CreateTD_vtop(TREl)));
AppendShortDescrCell(TREl, Variable);
AppendNbSp(CodeEl, NestingLevel * 2 + 2);
AppendText(CodeEl, Variable.Name);
AppendSym(CodeEl, ': ');
CodeEl := AppendType(CodeEl, TableEl, Variable.VarType, False, NestingLevel + 1);
AppendSym(CodeEl, ';');
end;
if Assigned(Element.VariantType) then
begin
TREl := CreateTR(TableEl);
CodeEl := CreateCode(CreatePara(CreateTD_vtop(TREl)));
AppendNbSp(CodeEl, NestingLevel * 2 + 2);
AppendKw(CodeEl, 'case ');
if TPasRecordType(Element).VariantName <> '' then
begin
AppendText(CodeEl, TPasRecordType(Element).VariantName);
AppendSym(CodeEl, ': ');
end;
CodeEl := AppendType(CodeEl, TableEl, TPasRecordType(Element).VariantType, True);
AppendKw(CodeEl, ' of');
for i := 0 to TPasRecordType(Element).Variants.Count - 1 do
begin
CurVariant := TPasVariant(Element.Variants[i]);
TREl := CreateTR(TableEl);
CodeEl := CreateCode(CreatePara(CreateTD_vtop(TREl)));
AppendNbSp(CodeEl, NestingLevel * 2 + 4);
for j := 0 to CurVariant.Values.Count - 1 do
begin
if j > 0 then
AppendSym(CodeEl, ', ');
AppendPasSHFragment(CodeEl, CurVariant.Values[j], 0);
end;
AppendSym(CodeEl, ': (');
AppendType(CodeEl, TableEl, CurVariant.Members, True, NestingLevel + 3);
CodeEl := CreateCode(CreatePara(CreateTD_vtop(CreateTR(TableEl))));
AppendNbSp(CodeEl, NestingLevel * 2 + 6);
AppendSym(CodeEl, ');');
end;
end;
if not (Element.Parent is TPasVariant) then
begin
CodeEl := CreateCode(CreatePara(CreateTD(CreateTR(TableEl))));
AppendText(CodeEl, ' '); // !!!: Dirty trick, necessary for current XML writer
AppendNbSp(CodeEl, NestingLevel * 2);
AppendKw(CodeEl, 'end');
end;
Result := CodeEl;
end;
procedure THTMLWriter.AppendTitle(const AText: DOMString);
begin
AppendText(TitleElement, AText);
AppendText(CreateH1(BodyElement), AText);
end;
procedure THTMLWriter.AppendTopicMenuBar(Topic : TTopicElement);
var
TableEl, TREl, ParaEl, TitleEl: TDOMElement;
procedure AddLink(El : TPasElement; const AName: String);
begin
AppendText(ParaEl, '[');
AppendText(CreateLink(ParaEl, ResolveLinkWithinPackage(El,0)),AName);
AppendText(ParaEl, ']');
end;
begin
TableEl := CreateEl(BodyElement, 'table');
TableEl['cellpadding'] := '4';
TableEl['cellspacing'] := '0';
TableEl['border'] := '0';
TableEl['width'] := '100%';
TableEl['class'] := 'bar';
TREl := CreateTR(TableEl);
ParaEl := CreateEl(CreateTD(TREl), 'b');
If Assigned(Topic.Previous) then
AddLink(Topic.Previous,SDocPrevious);
If Assigned(Topic.Parent) then
AddLink(Topic.Parent,SDocUp);
if Assigned(Topic.Next) then
AddLink(Topic.Next,SDocNext);
if Length(SearchPage) > 0 then
begin
AppendText(ParaEl, '[');
AppendText(CreateLink(ParaEl, SearchPage), SDocSearch);
AppendText(ParaEl, ']');
end;
ParaEl := CreateTD(TREl);
ParaEl['align'] := 'right';
TitleEl := CreateEl(ParaEl, 'span');
TitleEl['class'] := 'bartitle';
if Assigned(Module) then
AppendText(TitleEl, Format(SDocUnitTitle, [Module.Name]));
if Assigned(Package) then
begin
AppendText(TitleEl, ' (');
AppendHyperlink(TitleEl, Package);
AppendText(TitleEl, ')');
end;
end;
procedure THTMLWriter.AppendMenuBar(ASubpageIndex: Integer);
var
TableEl, TREl, ParaEl, TitleEl: TDOMElement;
procedure AddLink(ALinkSubpageIndex: Integer; const AName: String);
begin
AppendText(ParaEl, '[');
if ALinkSubpageIndex = ASubpageIndex then
AppendText(ParaEl, AName)
else
AppendText(
CreateLink(ParaEl, ResolveLinkWithinPackage(Module, ALinkSubpageIndex)),
AName);
AppendText(ParaEl, ']');
end;
begin
TableEl := CreateEl(BodyElement, 'table');
TableEl['cellpadding'] := '4';
TableEl['cellspacing'] := '0';
TableEl['border'] := '0';
TableEl['width'] := '100%';
TableEl['class'] := 'bar';
TREl := CreateTR(TableEl);
ParaEl := CreateEl(CreateTD(TREl), 'b');
if Assigned(Module) then
begin
AddLink(0, SDocOverview);
if Module.InterfaceSection.ResStrings.Count > 0 then
AddLink(ResstrSubindex, SDocResStrings);
if Module.InterfaceSection.Consts.Count > 0 then
AddLink(ConstsSubindex, SDocConstants);
if Module.InterfaceSection.Types.Count > 0 then
AddLink(TypesSubindex, SDocTypes);
if Module.InterfaceSection.Classes.Count > 0 then
AddLink(ClassesSubindex, SDocClasses);
if Module.InterfaceSection.Functions.Count > 0 then
AddLink(ProcsSubindex, SDocProceduresAndFunctions);
if Module.InterfaceSection.Variables.Count > 0 then
AddLink(VarsSubindex, SDocVariables);
AddLink(IndexSubIndex,SDocIdentifierIndex);
end
else
begin
// Manually add link for package page
AppendText(ParaEl, '[');
if (IndexSubIndex = ASubpageIndex) then
AppendText(ParaEl, SDocIdentifierIndex)
else
AppendText(
CreateLink(ParaEl, ResolveLinkWithinPackage(Package, IndexSubIndex)),
SDocIdentifierIndex);
AppendText(ParaEl, ']');
end;
if Length(SearchPage) > 0 then
begin
AppendText(ParaEl, '[');
AppendText(CreateLink(ParaEl, SearchPage), SDocSearch);
AppendText(ParaEl, ']');
end;
ParaEl := CreateTD(TREl);
ParaEl['align'] := 'right';
TitleEl := CreateEl(ParaEl, 'span');
TitleEl['class'] := 'bartitle';
if Assigned(Module) then
AppendText(TitleEl, Format(SDocUnitTitle, [Module.Name]));
if Assigned(Package) then
begin
AppendText(TitleEl, ' (');
AppendHyperlink(TitleEl, Package);
AppendText(TitleEl, ')');
end;
end;
procedure THTMLWriter.AppendSourceRef(AElement: TPasElement);
begin
AppendText(CreatePara(BodyElement), Format(SDocSourcePosition,
[ExtractFileName(AElement.SourceFilename), AElement.SourceLinenumber]));
end;
Procedure THTMLWriter.AppendSeeAlsoSection(AElement : TPasElement;DocNode : TDocNode);
var
Node: TDOMNode;
TableEl, El, TREl, TDEl, ParaEl, NewEl, DescrEl: TDOMElement;
l,s: String;
f: Text;
IsFirstSeeAlso : Boolean;
begin
if Not (Assigned(DocNode) and Assigned(DocNode.SeeAlso)) then
Exit;
IsFirstSeeAlso := True;
Node:=DocNode.SeeAlso.FirstChild;
While Assigned(Node) do
begin
if (Node.NodeType=ELEMENT_NODE) and (Node.NodeName='link') then
begin
if IsFirstSeeAlso then
begin
IsFirstSeeAlso := False;
AppendText(CreateH2(BodyElement), SDocSeeAlso);
TableEl := CreateTable(BodyElement);
end;
El:=TDOMElement(Node);
TREl:=CreateTR(TableEl);
ParaEl:=CreatePara(CreateTD_vtop(TREl));
l:=El['id'];
s:= ResolveLinkID(l);
if Length(s)=0 then
begin
WriteLn(Format(SErrUnknownLinkID, [l]));
NewEl := CreateEl(ParaEl,'b')
end
else
NewEl := CreateLink(ParaEl,s);
if Not IsDescrNodeEmpty(El) then
begin
PushOutputNode(NewEl);
Try
ConvertBaseShortList(AElement, El, True)
Finally
PopOutputNode;
end;
end
else
AppendText(NewEl,El['id']);
l:=El['id'];
DescrEl := Engine.FindShortDescr(AElement.GetModule,L);
if Assigned(DescrEl) then
begin
AppendNbSp(CreatePara(CreateTD(TREl)), 2);
ParaEl := CreatePara(CreateTD(TREl));
ParaEl['class'] := 'cmt';
PushOutputNode(ParaEl);
try
ConvertShort(AElement, DescrEl);
finally
PopOutputNode;
end;
end;
end; // Link node
Node := Node.NextSibling;
end; // While
end;
Procedure THTMLWriter.AppendExampleSection(AElement : TPasElement;DocNode : TDocNode);
var
Node: TDOMNode;
// TableEl, El, TREl, TDEl, ParaEl, NewEl, DescrEl: TDOMElement;
fn,s: String;
f: Text;
begin
if not (Assigned(DocNode) and Assigned(DocNode.FirstExample)) then
Exit;
Node := DocNode.FirstExample;
while Assigned(Node) do
begin
if (Node.NodeType = ELEMENT_NODE) and (Node.NodeName = 'example') then
begin
fn:=Engine.GetExampleFilename(TDOMElement(Node));
If (fn<>'') then
begin
AppendText(CreateH2(BodyElement), SDocExample);
try
Assign(f, FN);
Reset(f);
try
PushOutputNode(BodyElement);
DescrBeginCode(False, TDOMElement(Node)['highlighter']);
while not EOF(f) do
begin
ReadLn(f, s);
DescrWriteCodeLine(s);
end;
DescrEndCode;
PopOutputNode;
finally
Close(f);
end;
except
on e: Exception do
begin
e.Message := '[example] ' + e.Message;
raise;
end;
end;
end;
end;
Node := Node.NextSibling;
end;
end;
procedure THTMLWriter.AppendFooter;
Var
S : String;
F : TDomElement;
begin
if FooterFile<>'' then
ReadXMLFragment(BodyElement, FooterFile)
else if IncludeDateInFooter then
begin
CreateEl(BodyElement, 'hr');
F:=CreateEl(BodyElement,'span');
F['class']:='footer';
If (FDateFormat='') then
S:=DateToStr(Date)
else
S:=FormatDateTime(FDateFormat,Date);
AppendText(F,Format(SDocDateGenerated,[S]));
end;
end;
procedure THTMLWriter.FinishElementPage(AElement: TPasElement);
var
DocNode: TDocNode;
begin
DocNode := Engine.FindDocNode(AElement);
If Assigned(DocNode) then
begin
// Description
if Assigned(DocNode.Descr) then
AppendDescrSection(AElement, BodyElement, DocNode.Descr, SDocDescription);
// Append "Errors" section
if Assigned(DocNode.ErrorsDoc) then
AppendDescrSection(AElement, BodyElement, DocNode.ErrorsDoc, SDocErrors);
// Append Version info
if Assigned(DocNode.Version) then
AppendDescrSection(AElement, BodyElement, DocNode.Version, SDocVersion);
// Append "See also" section
AppendSeeAlsoSection(AElement,DocNode);
// Append examples, if present
AppendExampleSection(AElement,DocNode);
end;
end;
Procedure THTMLWriter.CreateTopicPageBody(AElement : TTopicElement);
var
DocNode: TDocNode;
TableEl, TREl: TDOMElement;
I : Integer;
S : String;
begin
AppendTopicMenuBar(AElement);
DocNode:=AElement.TopicNode;
if Assigned(DocNode) then // should always be true, but we're being careful.
begin
AppendShortDescr(AElement,TitleElement, DocNode);
AppendShortDescr(AElement,CreateH2(BodyElement), DocNode);
if Assigned(DocNode.Descr) then
AppendDescrSection(AElement, BodyElement, DocNode.Descr, '');
AppendSeeAlsoSection(AElement,DocNode);
CreateTopicLinks(DocNode,AElement);
AppendExampleSection(AElement,DocNode);
end;
end;
procedure THTMLWriter.CreatePageBody(AElement: TPasElement;
ASubpageIndex: Integer);
var
i: Integer;
Element: TPasElement;
begin
CurDirectory := Allocator.GetFilename(AElement, ASubpageIndex);
i := Length(CurDirectory);
while (i > 0) and not (CurDirectory[i] in AllowDirectorySeparators) do
Dec(i);
CurDirectory := Copy(CurDirectory, 1, i);
BaseDirectory := Allocator.GetRelativePathToTop(AElement);
if AElement.ClassType = TPasPackage then
begin
Module:=Nil;
If (ASubPageIndex=0) then
CreatePackagePageBody
else if ASubPageIndex=IndexSubIndex then
CreatePackageIndex
end
else
begin
Element := AElement;
while (Element<>Nil) and (Element.ClassType<>TPasModule) do
Element := Element.Parent;
Module := TPasModule(Element);
if AElement.ClassType = TPasModule then
CreateModulePageBody(TPasModule(AElement), ASubpageIndex)
else if AElement.Parent.InheritsFrom(TPasClassType) then
CreateClassMemberPageBody(AElement)
else if AElement.ClassType = TPasConst then
CreateConstPageBody(TPasConst(AElement))
else if AElement.InheritsFrom(TPasClassType) then
CreateClassPageBody(TPasClassType(AElement), ASubpageIndex)
else if AElement.InheritsFrom(TPasType) then
CreateTypePageBody(TPasType(AElement))
else if AElement.ClassType = TPasVariable then
CreateVarPageBody(TPasVariable(AElement))
else if AElement.InheritsFrom(TPasProcedureBase) then
CreateProcPageBody(TPasProcedure(AElement))
else if AElement.ClassType = TTopicELement then
CreateTopicPageBody(TTopicElement(AElement))
end;
end;
procedure THTMLWriter.CreateIndexPage(L : TStringList);
Var
Lists : Array['A'..'Z'] of TStringList;
LOther : TStringList;
CL : TStringList;
TableEl, TREl, EL: TDOMElement;
E : TPasElement;
I,Rows,J,Index : Integer;
S : String;
C : Char;
begin
For C:='A' to 'Z' do
Lists[C]:=Nil;
L.Sort;
Cl:=Nil;
// Divide over alphabet
For I:=0 to L.Count-1 do
begin
S:=L[i];
E:=TPasElement(L.Objects[i]);
If not (E is TPasUnresolvedTypeRef) then
begin
If (S<>'') then
begin
C:=Upcase(S[1]);
If C='_' then
C:='A';
If (C in ['A'..'Z']) and (Lists[C]=Nil) then
begin
CL:=TStringList.Create;
Lists[C]:=CL;
end;
end;
if assigned(cl) then
CL.AddObject(S,E);
end;
end;
Try
// Create a quick jump table to all available letters.
TableEl := CreateTable(BodyElement);
TableEl['border']:='1';
TableEl['width']:='50%';
TREl := CreateTR(TableEl);
for C:='A' to 'Z' do
If (Lists[C]<>Nil) then
begin
El:=CreateTD_vtop(TREl);
AppendText(CreateLink(El,'#SECTION'+C),C);
If C<>'Z' then
AppendNBsp(El,1);
end;
// Now emit all identifiers.
TableEl:=Nil;
For C:='A' to 'Z' do
begin
CL:=Lists[C];
If CL<>Nil then
begin
El:=CreateH2(BodyElement);
AppendText(El,C);
CreateAnchor(El,'SECTION'+C);
TableEl := CreateTable(BodyElement);
TableEl['Width']:='80%';
// Determine number of rows needed
Rows:=(CL.Count div IndexColCount);
If ((CL.Count Mod IndexColCount)<>0) then
Inc(Rows);
// Fill rows
For I:=0 to Rows-1 do
begin
TREl := CreateTR(TableEl);
For J:=0 to IndexColCount-1 do
begin
El:=CreateTD_vtop(TREl);
Index:=(J*Rows)+I;
If (Index<CL.Count) then
begin
S:=CL[Index];
E:=TPasElement(CL.Objects[Index]);
AppendHyperlink(El,E);
end;
end;
end;
end; // have List
end; // For C:=
Finally
for C:='A' to 'Z' do
FreeAndNil(Lists[C]);
end;
end;
procedure THTMLWriter.AddModuleIdentifiers(AModule : TPasModule; L : TStrings);
Procedure AddElementsFromList(L : TStrings; List : TList);
Var
I : Integer;
El : TPasElement;
begin
For I:=0 to List.Count-1 do
begin
El:=TPasElement(List[I]);
L.AddObject(El.Name,El);
If el is TPasEnumType then
AddElementsFromList(L,TPasEnumType(el).Values);
end;
end;
begin
AddElementsFromList(L,AModule.InterfaceSection.Consts);
AddElementsFromList(L,AModule.InterfaceSection.Types);
AddElementsFromList(L,AModule.InterfaceSection.Functions);
AddElementsFromList(L,AModule.InterfaceSection.Classes);
AddElementsFromList(L,AModule.InterfaceSection.Variables);
AddElementsFromList(L,AModule.InterfaceSection.ResStrings);
end;
procedure THTMLWriter.CreatePackageIndex;
Var
L : TStringList;
I : Integer;
M : TPasModule;
E : TPasElement;
S : String;
begin
L:=TStringList.Create;
try
L.Capacity:=PageInfos.Count; // Too much, but that doesn't hurt.
For I:=0 to Package.Modules.Count-1 do
begin
M:=TPasModule(Package.Modules[i]);
L.AddObject(M.Name,M);
AddModuleIdentifiers(M,L);
end;
AppendMenuBar(IndexSubIndex);
S:=Package.Name;
If Length(S)>0 then
Delete(S,1,1);
AppendTitle(Format(SDocPackageIndex, [S]));
CreateIndexPage(L);
Finally
L.Free;
end;
end;
procedure THTMLWriter.CreatePackagePageBody;
var
DocNode: TDocNode;
TableEl, TREl: TDOMElement;
i: Integer;
ThisModule: TPasModule;
L : TStringList;
begin
AppendMenuBar(0);
AppendTitle(Format(SDocPackageTitle, [Copy(Package.Name, 2, 256)]));
AppendShortDescr(CreatePara(BodyElement), Package);
AppendText(CreateH2(BodyElement), SDocUnits);
TableEl := CreateTable(BodyElement);
L:=TStringList.Create;
Try
L.Sorted:=True;
// Sort modules.
For I:=0 to Package.Modules.Count-1 do
L.AddObject(TPasModule(Package.Modules[i]).Name,TPasModule(Package.Modules[i]));
// Now create table.
for i:=0 to L.Count - 1 do
begin
ThisModule := TPasModule(L.Objects[i]);
TREl := CreateTR(TableEl);
AppendHyperlink(CreateCode(CreatePara(CreateTD_vtop(TREl))), ThisModule);
AppendShortDescrCell(TREl, ThisModule);
end;
Finally
L.Free;
end;
DocNode := Engine.FindDocNode(Package);
if Assigned(DocNode) then
begin
if Assigned(DocNode.Descr) then
AppendDescrSection(nil, BodyElement, DocNode.Descr, SDocDescription);
CreateTopicLinks(DocNode,Package);
end;
end;
Procedure THTMLWriter.CreateTopicLinks(Node : TDocNode; PasElement : TPasElement);
var
DocNode: TDocNode;
TableEl, TREl: TDOMElement;
First : Boolean;
ThisTopic: TPasElement;
begin
DocNode:=Node.FirstChild;
First:=True;
While Assigned(DocNode) do
begin
If DocNode.TopicNode then
begin
if first then
begin
First:=False;
AppendText(CreateH2(BodyElement), SDocRelatedTopics);
TableEl := CreateTable(BodyElement);
end;
TREl := CreateTR(TableEl);
ThisTopic:=FindTopicElement(DocNode);
if Assigned(ThisTopic) then
AppendHyperlink(CreateCode(CreatePara(CreateTD_vtop(TREl))), ThisTopic);
AppendShortDescrCell(TREl, ThisTopic);
end;
DocNode:=DocNode.NextSibling;
end;
end;
procedure THTMLWriter.CreateModuleIndexPage(AModule: TPasModule);
Var
L : TStringList;
begin
L:=TStringList.Create;
try
AddModuleIdentifiers(AModule,L);
AppendMenuBar(IndexSubIndex);
AppendTitle(Format(SDocModuleIndex, [AModule.Name]));
CreateIndexPage(L);
Finally
L.Free;
end;
end;
procedure THTMLWriter.CreateModulePageBody(AModule: TPasModule;
ASubpageIndex: Integer);
procedure CreateMainPage;
var
TableEl, TREl, TDEl, CodeEl: TDOMElement;
i: Integer;
UnitRef: TPasType;
DocNode: TDocNode;
begin
AppendMenuBar(0);
AppendTitle(Format(SDocUnitTitle, [AModule.Name]));
AppendShortDescr(CreatePara(BodyElement), AModule);
if AModule.InterfaceSection.UsesList.Count > 0 then
begin
TableEl := CreateTable(BodyElement);
AppendKw(CreateCode(CreatePara(CreateTD(CreateTR(TableEl)))), 'uses');
for i := 0 to AModule.InterfaceSection.UsesList.Count - 1 do
begin
UnitRef := TPasType(AModule.InterfaceSection.UsesList[i]);
DocNode := Engine.FindDocNode(UnitRef);
if Assigned(DocNode) and DocNode.IsSkipped then
continue;
TREl := CreateTR(TableEl);
TDEl := CreateTD_vtop(TREl);
CodeEl := CreateCode(CreatePara(TDEl));
AppendNbSp(CodeEl, 2);
AppendHyperlink(CodeEl, UnitRef);
if i < AModule.InterfaceSection.UsesList.Count - 1 then
AppendSym(CodeEl, ',')
else
AppendSym(CodeEl, ';');
AppendText(CodeEl, ' '); // Space for descriptions
AppendShortDescrCell(TREl, UnitRef);
end;
end;
DocNode := Engine.FindDocNode(AModule);
if Assigned(DocNode) then
begin
if Assigned(DocNode.Descr) then
AppendDescrSection(AModule, BodyElement, DocNode.Descr, SDocOverview);
CreateTopicLinks(DocNode,AModule);
end;
end;
procedure CreateSimpleSubpage(const ATitle: DOMString; AList: TList);
var
TableEl, TREl, TDEl, CodeEl: TDOMElement;
i, j: Integer;
Decl: TPasElement;
SortedList: TList;
DocNode: TDocNode;
S : String;
begin
AppendMenuBar(ASubpageIndex);
S:=ATitle;
AppendTitle(Format(SDocUnitTitle + ': %s', [AModule.Name, S]));
SortedList := TList.Create;
try
for i := 0 to AList.Count - 1 do
begin
Decl := TPasElement(AList[i]);
DocNode := Engine.FindDocNode(Decl);
if (not Assigned(DocNode)) or (not DocNode.IsSkipped) then
begin
j := 0;
while (j < SortedList.Count) and (CompareText(
TPasElement(SortedList[j]).PathName, Decl.PathName) < 0) do
Inc(j);
SortedList.Insert(j, Decl);
end;
end;
TableEl := CreateTable(BodyElement);
for i := 0 to SortedList.Count - 1 do
begin
Decl := TPasElement(SortedList[i]);
TREl := CreateTR(TableEl);
CodeEl := CreateCode(CreatePara(CreateTD_vtop(TREl)));
AppendHyperlink(CodeEl, Decl);
AppendShortDescrCell(TREl, Decl);
end;
finally
SortedList.Free;
end;
end;
procedure CreateResStringsPage;
var
ParaEl: TDOMElement;
i, j: Integer;
Decl: TPasResString;
DocNode: TDocNode;
begin
AppendMenuBar(ResstrSubindex);
AppendTitle(Format(SDocUnitTitle + ': %s', [AModule.Name, SDocResStrings]));
for i := 0 to AModule.InterfaceSection.ResStrings.Count - 1 do
begin
Decl := TPasResString(AModule.InterfaceSection.ResStrings[i]);
CreateEl(BodyElement, 'a')['name'] := LowerCase(Decl.Name);
ParaEl := CreatePara(BodyElement);
AppendText(CreateCode(ParaEl), Decl.Name);
CreateEl(ParaEl, 'br');
AppendText(ParaEl, Decl.Value);
end;
end;
begin
case ASubpageIndex of
0:
CreateMainPage;
ResstrSubindex:
CreateResStringsPage;
ConstsSubindex:
CreateSimpleSubpage(SDocConstants, AModule.InterfaceSection.Consts);
TypesSubindex:
CreateSimpleSubpage(SDocTypes, AModule.InterfaceSection.Types);
ClassesSubindex:
CreateSimpleSubpage(SDocClasses, AModule.InterfaceSection.Classes);
ProcsSubindex:
CreateSimpleSubpage(SDocProceduresAndFunctions, AModule.InterfaceSection.Functions);
VarsSubindex:
CreateSimpleSubpage(SDocVariables, AModule.InterfaceSection.Variables);
IndexSubIndex:
CreateModuleIndexPage(AModule);
end;
end;
procedure THTMLWriter.CreateConstPageBody(AConst: TPasConst);
var
TableEl, CodeEl: TDOMElement;
begin
AppendMenuBar(-1);
AppendTitle(AConst.Name);
AppendShortDescr(CreatePara(BodyElement), AConst);
AppendText(CreateH2(BodyElement), SDocDeclaration);
AppendSourceRef(AConst);
TableEl := CreateTable(BodyElement);
CodeEl := CreateCode(CreatePara(CreateTD(CreateTR(TableEl))));
AppendKw(CodeEl, 'const');
AppendText(CodeEl, ' ' + AConst.Name);
if Assigned(AConst.VarType) then
begin
AppendSym(CodeEl, ': ');
AppendType(CodeEl, TableEl, AConst.VarType, False);
end;
AppendPasSHFragment(CodeEl, ' = ' + AConst.Value + ';', 0);
FinishElementPage(AConst);
end;
procedure THTMLWriter.CreateTypePageBody(AType: TPasType);
var
TableEl, TREl, TDEl, CodeEl: TDOMElement;
DocNode: TDocNode;
i: Integer;
s: String;
EnumType: TPasEnumType;
EnumValue: TPasEnumValue;
Variable: TPasVariable;
begin
AppendMenuBar(-1);
AppendTitle(AType.Name);
AppendShortDescr(CreatePara(BodyElement), AType);
AppendText(CreateH2(BodyElement), SDocDeclaration);
AppendSourceRef(AType);
TableEl := CreateTable(BodyElement);
TREl := CreateTR(TableEl);
TDEl := CreateTD(TREl);
CodeEl := CreateCode(CreatePara(TDEl));
DocNode := Engine.FindDocNode(AType);
AppendKw(CodeEl, 'type ');
AppendText(CodeEl, AType.Name);
AppendSym(CodeEl, ' = ');
If Assigned(DocNode) and
Assigned(DocNode.Node) and
(Docnode.Node['opaque']='1') then
AppendText(CodeEl,SDocOpaque)
else
begin
// Alias
if AType.ClassType = TPasAliasType then
begin
if Assigned(TPasAliasType(AType).DestType) then
AppendHyperlink(CodeEl, TPasAliasType(AType).DestType)
else
AppendText(CreateWarning(CodeEl), '<Destination type is NIL>');
AppendSym(CodeEl, ';');
end else
// Class of
if AType.ClassType = TPasClassOfType then
begin
AppendKw(CodeEl, 'class of ');
AppendHyperlink(CodeEl, TPasClassOfType(AType).DestType);
AppendSym(CodeEl, ';');
end else
// Enumeration
if AType.ClassType = TPasEnumType then
begin
AppendSym(CodeEl, '(');
for i := 0 to TPasEnumType(AType).Values.Count - 1 do
begin
EnumValue := TPasEnumValue(TPasEnumType(AType).Values[i]);
TREl := CreateTR(TableEl);
CodeEl := CreateCode(CreatePara(CreateTD_vtop(TREl)));
AppendShortDescrCell(TREl, EnumValue);
AppendNbSp(CodeEl, 2);
s := EnumValue.Name;
if EnumValue.IsValueUsed then
s := s + ' = ' + IntToStr(EnumValue.Value);
if i < TPasEnumType(AType).Values.Count - 1 then
s := s + ',';
AppendPasSHFragment(CodeEl, s, 0);
end;
AppendSym(CreateCode(CreatePara(CreateTD(CreateTR(TableEl)))), ');');
end else
// Pointer type
if AType.ClassType = TPasPointerType then
begin
AppendSym(CodeEl, '^');
if Assigned(TPasPointerType(AType).DestType) then
AppendHyperlink(CodeEl, TPasPointerType(AType).DestType)
else
AppendText(CreateWarning(CodeEl), '<Destination type is NIL>');
AppendSym(CodeEl, ';');
end else
if AType.InheritsFrom(TPasProcedureType) then
begin
AppendSym(AppendType(CodeEl, TableEl, TPasType(AType), True), ';');
AppendProcArgsSection(BodyElement, TPasProcedureType(AType));
end else
// Record
if AType.ClassType = TPasRecordType then
begin
CodeEl := AppendRecordType(CodeEl, TableEl, TPasRecordType(AType), 0);
AppendSym(CodeEl, ';');
end else
// Set
if AType.ClassType = TPasSetType then
begin
AppendKw(CodeEl, 'set of ');
if TPasSetType(AType).EnumType.ClassType = TPasEnumType then
begin
AppendSym(CodeEl, '(');
EnumType := TPasEnumType(TPasSetType(AType).EnumType);
for i := 0 to EnumType.Values.Count - 1 do
begin
EnumValue := TPasEnumValue(EnumType.Values[i]);
TREl := CreateTR(TableEl);
CodeEl := CreateCode(CreatePara(CreateTD_vtop(TREl)));
AppendShortDescrCell(TREl, EnumValue);
AppendNbSp(CodeEl, 2);
s := EnumValue.Name;
if EnumValue.IsValueUsed then
s := s + ' = ' + IntToStr(EnumValue.Value);
if i < EnumType.Values.Count - 1 then
s := s + ',';
AppendPasSHFragment(CodeEl, s, 0);
end;
AppendSym(CreateCode(CreatePara(CreateTD(CreateTR(TableEl)))), ');');
end else
begin
AppendHyperlink(CodeEl, TPasSetType(AType).EnumType);
AppendSym(CodeEl, ';');
end;
end else
// Type alias
if AType.ClassType = TPasTypeAliasType then
begin
AppendKw(CodeEl, 'type ');
AppendHyperlink(CodeEl, TPasTypeAliasType(AType).DestType);
AppendSym(CodeEl, ';');
end else
// Probably one of the simple types, which allowed in other places as wel...
AppendSym(AppendType(CodeEl, TableEl, TPasType(AType), True), ';');
end;
FinishElementPage(AType);
end;
function PropertyFilter(AMember: TPasElement): Boolean;
begin
Result := (AMember.ClassType = TPasProperty) and
(Copy(AMember.Name, 1, 2) <> 'On');
end;
function MethodFilter(AMember: TPasElement): Boolean;
begin
Result := AMember.InheritsFrom(TPasProcedureBase);
end;
function EventFilter(AMember: TPasElement): Boolean;
begin
Result := (AMember.ClassType = TPasProperty) and
(Copy(AMember.Name, 1, 2) = 'On');
end;
procedure THTMLWriter.CreateClassPageBody(AClass: TPasClassType;
ASubpageIndex: Integer);
type
TMemberFilter = function(AMember: TPasElement): Boolean;
var
ParaEl: TDOMElement;
procedure AppendMemberListLink(AListSubpageIndex: Integer;
const AText: DOMString);
var
LinkEl: TDOMElement;
begin
AppendText(ParaEl, '[');
LinkEl := CreateEl(ParaEl, 'a');
LinkEl['href'] :=
FixHtmlPath(ResolveLinkWithinPackage(AClass, AListSubpageIndex));
LinkEl['onClick'] := 'window.open(''' + LinkEl['href'] + ''', ''list'', ' +
'''dependent=yes,resizable=yes,scrollbars=yes,height=400,width=300''); return false;';
AppendText(LinkEl, AText);
AppendText(ParaEl, ' (');
LinkEl := CreateEl(ParaEl, 'a');
LinkEl['href'] :=
FixHtmlPath(ResolveLinkWithinPackage(AClass, AListSubpageIndex + 1));
LinkEl['onClick'] := 'window.open(''' + LinkEl['href'] + ''', ''list'', ' +
'''dependent=yes,resizable=yes,scrollbars=yes,height=400,width=300''); return false;';
AppendText(LinkEl, SDocByName);
AppendText(ParaEl, ')');
AppendText(ParaEl, '] ');
end;
procedure CreateMainPage;
var
TableEl, TREl, TDEl, CodeEl: TDOMElement;
DocNode: TDocNode;
Member: TPasElement;
CurVisibility: TPasMemberVisibility;
i: Integer;
s: String;
ThisClass: TPasClassType;
HaveSeenTObject: Boolean;
begin
AppendMenuBar(-1);
AppendTitle(AClass.Name);
ParaEl := CreatePara(BodyElement);
AppendMemberListLink(PropertiesByInheritanceSubindex, SDocProperties);
AppendMemberListLink(MethodsByInheritanceSubindex, SDocMethods);
AppendMemberListLink(EventsByInheritanceSubindex, SDocEvents);
AppendShortDescr(CreatePara(BodyElement), AClass);
AppendText(CreateH2(BodyElement), SDocDeclaration);
AppendSourceRef(AClass);
TableEl := CreateTable(BodyElement);
TREl := CreateTR(TableEl);
TDEl := CreateTD(TREl);
CodeEl := CreateCode(CreatePara(TDEl));
AppendKw(CodeEl, 'type');
AppendText(CodeEl, ' ' + AClass.Name + ' ');
AppendSym(CodeEl, '=');
AppendText(CodeEl, ' ');
AppendKw(CodeEl, ObjKindNames[AClass.ObjKind]);
if Assigned(AClass.AncestorType) then
begin
AppendSym(CodeEl, '(');
AppendHyperlink(CodeEl, AClass.AncestorType);
AppendSym(CodeEl, ')');
end;
if AClass.Members.Count > 0 then
begin
CurVisibility := visDefault;
for i := 0 to AClass.Members.Count - 1 do
begin
Member := TPasElement(AClass.Members[i]);
if CurVisibility <> Member.Visibility then
begin
CurVisibility := Member.Visibility;
if ((CurVisibility = visPrivate) and Engine.HidePrivate) or
((CurVisibility = visProtected) and Engine.HideProtected) then
continue;
case CurVisibility of
visPrivate: s := 'private';
visProtected: s := 'protected';
visPublic: s := 'public';
visPublished: s := 'published';
visAutomated: s := 'automated';
end;
AppendKw(CreateCode(CreatePara(CreateTD(CreateTR(TableEl)))), s);
end else
if ((CurVisibility = visPrivate) and Engine.HidePrivate) or
((CurVisibility = visProtected) and Engine.HideProtected) then
continue;
TREl := CreateTR(TableEl);
CodeEl := CreateCode(CreatePara(CreateTD_vtop(TREl)));
AppendNbSp(CodeEl, 2);
AppendShortDescrCell(TREl, Member);
if Member.InheritsFrom(TPasProcedureBase) then
begin
AppendKw(CodeEl, TPasProcedureBase(Member).TypeName + ' ');
AppendHyperlink(CodeEl, Member);
if (Member.ClassType = TPasOverloadedProc) or
(TPasProcedure(Member).ProcType.Args.Count > 0) then
AppendSym(CodeEl, '();')
else
AppendSym(CodeEl, ';');
if Member.ClassType <> TPasOverloadedProc then
AppendProcExt(CodeEl, TPasProcedure(Member));
end else
if Member.ClassType = TPasVariable then
begin
AppendHyperlink(CodeEl, Member);
AppendSym(CodeEl, ': ');
AppendHyperlink(CodeEl, TPasVariable(Member).VarType);
AppendSym(CodeEl, ';');
end else
if Member.ClassType = TPasProperty then
begin
AppendKw(CodeEl, 'property ');
AppendHyperlink(CodeEl, Member);
if Assigned(TPasProperty(Member).VarType) then
begin
AppendSym(CodeEl, ': ');
AppendHyperlink(CodeEl, TPasProperty(Member).VarType);
end;
AppendSym(CodeEl, ';');
if TPasProperty(Member).IsDefault then
begin
AppendKw(CodeEl, ' default');
AppendSym(CodeEl, ';');
end;
if (TPasProperty(Member).ImplementsName<>'') then
begin
AppendKw(CodeEl, ' implements');
AppendText(CodeEl, ' '+TPasProperty(Member).ImplementsName);
AppendSym(CodeEl, ';');
end;
SetLength(s, 0);
if Length(TPasProperty(Member).ReadAccessorName) > 0 then
s := s + 'r';
if Length(TPasProperty(Member).WriteAccessorName) > 0 then
s := s + 'w';
if Length(TPasProperty(Member).StoredAccessorName) > 0 then
s := s + 's';
if Length(s) > 0 then
AppendText(CodeEl, ' [' + s + ']');
end else
AppendText(CreateWarning(CodeEl), '<' + Member.ClassName + '>');
end;
CodeEl := CreateCode(CreatePara(CreateTD(CreateTR(TableEl))));
end;
AppendText(CodeEl, ' '); // !!!: Dirty trick, necessary for current XML writer
AppendKw(CodeEl, 'end');
AppendSym(CodeEl, ';');
AppendText(CreateH2(BodyElement), SDocInheritance);
TableEl := CreateTable(BodyElement);
HaveSeenTObject := AClass.ObjKind <> okClass;
ThisClass := AClass;
while True do
begin
TREl := CreateTR(TableEl);
TDEl := CreateTD_vtop(TREl);
TDEl['align'] := 'center';
CodeEl := CreateCode(CreatePara(TDEl));
AppendHyperlink(CodeEl, ThisClass);
AppendShortDescrCell(TREl, ThisClass);
if HaveSeenTObject or (CompareText(ThisClass.Name, 'TObject') = 0) then
HaveSeenTObject := True
else
begin
TDEl := CreateTD(CreateTR(TableEl));
TDEl['align'] := 'center';
AppendText(TDEl, '|');
end;
if Assigned(ThisClass.AncestorType) then
begin
if ThisClass.AncestorType.InheritsFrom(TPasClassType) then
ThisClass := TPasClassType(ThisClass.AncestorType)
else
begin
TDEl := CreateTD(CreateTR(TableEl));
TDEl['align'] := 'center';
AppendText(CreateCode(CreatePara(TDEl)), ThisClass.AncestorType.Name);
if CompareText(ThisClass.AncestorType.Name, 'TObject') = 0 then
HaveSeenTObject := True
else
begin
TDEl := CreateTD(CreateTR(TableEl));
TDEl['align'] := 'center';
AppendText(TDEl, '?');
end;
break;
end
end else
break;
end;
if not HaveSeenTObject then
begin
TDEl := CreateTD(CreateTR(TableEl));
TDEl['align'] := 'center';
AppendText(CreateCode(CreatePara(TDEl)), 'TObject');
end;
FinishElementPage(AClass);
end;
procedure CreateInheritanceSubpage(AFilter: TMemberFilter);
var
ThisClass: TPasClassType;
i: Integer;
Member: TPasElement;
TableEl, TREl, TDEl, ParaEl, LinkEl: TDOMElement;
begin
TableEl := CreateTable(BodyElement);
ThisClass := AClass;
while True do
begin
TREl := CreateTR(TableEl);
TDEl := CreateTD(TREl);
TDEl['colspan'] := '3';
CreateTD(TREl);
LinkEl := AppendHyperlink(CreateEl(CreateCode(CreatePara(TDEl)), 'b'), ThisClass);
if Assigned(LinkEl) then
LinkEl['onClick'] := 'opener.location.href = ''' + LinkEl['href'] +
'''; return false;';
for i := 0 to ThisClass.Members.Count - 1 do
begin
Member := TPasElement(ThisClass.Members[i]);
if ((Member.Visibility = visPrivate) and Engine.HidePrivate) or
((Member.Visibility = visProtected) and Engine.HideProtected) or
not AFilter(Member) then
continue;
TREl := CreateTR(TableEl);
ParaEl := CreatePara(CreateTD(TREl));
case Member.Visibility of
visPrivate:
AppendText(ParaEl, 'pv');
visProtected:
AppendText(ParaEl, 'pt');
visPublished:
AppendText(ParaEl, 'pl');
end;
AppendNbSp(ParaEl, 1);
ParaEl := CreateTD(TREl);
if (Member.ClassType = TPasProperty) and
(Length(TPasProperty(Member).WriteAccessorName) = 0) then
begin
AppendText(ParaEl, 'ro');
AppendNbSp(ParaEl, 1);
end;
LinkEl := AppendHyperlink(CreatePara(CreateTD(TREl)), Member);
if Assigned(LinkEl) then
LinkEl['onClick'] := 'opener.location.href = ''' + LinkEl['href'] +
'''; return false;';
end;
if (not Assigned(ThisClass.AncestorType)) or
(not (ThisClass.AncestorType.ClassType = TPasClassType)) then
break;
ThisClass := TPasClassType(ThisClass.AncestorType);
AppendNbSp(CreatePara(CreateTD(CreateTR(TableEl))), 1);
end;
end;
procedure CreateSortedSubpage(AFilter: TMemberFilter);
var
List: TList;
ThisClass: TPasClassType;
i, j: Integer;
Member: TPasElement;
TableEl, TREl, TDEl, ParaEl, LinkEl: TDOMElement;
begin
List := TList.Create;
try
ThisClass := AClass;
while True do
begin
for i := 0 to ThisClass.Members.Count - 1 do
begin
Member := TPasElement(ThisClass.Members[i]);
if (not (((Member.Visibility = visPrivate) and Engine.HidePrivate) or
((Member.Visibility = visProtected) and Engine.HideProtected))) and
AFilter(Member) then
begin
j := 0;
while (j < List.Count) and
(CompareText(TPasElement(List[j]).Name, Member.Name) < 0) do
Inc(j);
List.Insert(j, Member);
end;
end;
if (not Assigned(ThisClass.AncestorType)) or
(not (ThisClass.AncestorType.ClassType = TPasClassType)) then
break;
ThisClass := TPasClassType(ThisClass.AncestorType);
end;
TableEl := CreateTable(BodyElement);
for i := 0 to List.Count - 1 do
begin
Member := TPasElement(List[i]);
TREl := CreateTR(TableEl);
ParaEl := CreatePara(CreateTD(TREl));
case Member.Visibility of
visPrivate:
AppendText(ParaEl, 'pv');
visProtected:
AppendText(ParaEl, 'pt');
visPublished:
AppendText(ParaEl, 'pl');
end;
AppendNbSp(ParaEl, 1);
ParaEl := CreatePara(CreateTD(TREl));
if (Member.ClassType = TPasProperty) and
(Length(TPasProperty(Member).WriteAccessorName) = 0) then
begin
AppendText(ParaEl, 'ro');
AppendNbSp(ParaEl, 1);
end;
TDEl := CreateTD(TREl);
TDEl['nowrap'] := 'nowrap';
ParaEl := CreatePara(TDEl);
LinkEl := AppendHyperlink(ParaEl, Member);
if Assigned(LinkEl) then
LinkEl['onClick'] := 'opener.location.href = ''' + LinkEl['href'] +
'''; return false;';
AppendText(ParaEl, ' (');
LinkEl := AppendHyperlink(ParaEl, Member.Parent);
if Assigned(LinkEl) then
LinkEl['onClick'] := 'opener.location.href = ''' + LinkEl['href'] +
'''; return false;';
AppendText(ParaEl, ')');
end;
finally
List.Free;
end;
end;
begin
case ASubpageIndex of
0:
CreateMainPage;
PropertiesByInheritanceSubindex:
CreateInheritanceSubpage(@PropertyFilter);
PropertiesByNameSubindex:
CreateSortedSubpage(@PropertyFilter);
MethodsByInheritanceSubindex:
CreateInheritanceSubpage(@MethodFilter);
MethodsByNameSubindex:
CreateSortedSubpage(@MethodFilter);
EventsByInheritanceSubindex:
CreateInheritanceSubpage(@EventFilter);
EventsByNameSubindex:
CreateSortedSubpage(@EventFilter);
end;
end;
procedure THTMLWriter.CreateClassMemberPageBody(AElement: TPasElement);
var
TableEl, TREl, CodeEl: TDOMElement;
procedure CreateVarPage(Element: TPasVariable);
begin
AppendHyperlink(CodeEl, Element.Parent);
AppendSym(CodeEl, '.');
AppendText(CodeEl, Element.Name);
if Assigned(Element.VarType) then
begin
AppendSym(CodeEl, ': ');
AppendSym(AppendType(CodeEl, TableEl, Element.VarType, False), ';');
end;
end;
procedure CreatePropertyPage(Element: TPasProperty);
var
NeedBreak: Boolean;
begin
AppendKw(CodeEl, 'property ');
AppendHyperlink(CodeEl, Element.Parent);
AppendSym(CodeEl, '.');
AppendText(CodeEl, Element.Name);
if Assigned(Element.VarType) then
begin
AppendSym(CodeEl, ': ');
AppendType(CodeEl, TableEl, Element.VarType, False);
end;
NeedBreak := False;
if Length(TPasProperty(Element).IndexValue) <> 0 then
begin
CreateEl(CodeEl, 'br');
AppendNbsp(CodeEl, 2);
AppendKw(CodeEl, 'index ');
AppendPasSHFragment(CodeEl, TPasProperty(Element).IndexValue, 0);
NeedBreak := True;
end;
if Length(TPasProperty(Element).ReadAccessorName) <> 0 then
begin
CreateEl(CodeEl, 'br');
AppendNbsp(CodeEl, 2);
AppendKw(CodeEl, 'read ');
AppendText(CodeEl, TPasProperty(Element).ReadAccessorName);
NeedBreak := True;
end;
if Length(TPasProperty(Element).WriteAccessorName) <> 0 then
begin
CreateEl(CodeEl, 'br');
AppendNbsp(CodeEl, 2);
AppendKw(CodeEl, 'write ');
AppendText(CodeEl, TPasProperty(Element).WriteAccessorName);
NeedBreak := True;
end;
if Length(TPasProperty(Element).StoredAccessorName) <> 0 then
begin
CreateEl(CodeEl, 'br');
AppendNbsp(CodeEl, 2);
AppendKw(CodeEl, 'stored ');
AppendText(CodeEl, TPasProperty(Element).StoredAccessorName);
NeedBreak := True;
end;
if Length(TPasProperty(Element).DefaultValue) <> 0 then
begin
CreateEl(CodeEl, 'br');
AppendNbsp(CodeEl, 2);
AppendKw(CodeEl, 'default ');
AppendPasSHFragment(CodeEl, TPasProperty(Element).DefaultValue, 0);
NeedBreak := True;
end;
AppendSym(CodeEl, ';');
if TPasProperty(Element).IsDefault or TPasProperty(Element).IsNodefault then
begin
if NeedBreak then
begin
CreateEl(CodeEl, 'br');
AppendNbsp(CodeEl, 2);
end;
if TPasProperty(Element).IsDefault then
AppendKw(CodeEl, 'default')
else
AppendKw(CodeEl, 'nodefault');
AppendSym(CodeEl, ';');
end;
end;
var
s: String;
DocNode: TDocNode;
begin
AppendMenuBar(-1);
AppendTitle(AElement.FullName);
AppendShortDescr(CreatePara(BodyElement), AElement);
AppendText(CreateH2(BodyElement), SDocDeclaration);
AppendSourceRef(AElement);
TableEl := CreateTable(BodyElement);
TREl := CreateTR(TableEl);
CodeEl := CreateCode(CreatePara(CreateTD(TREl)));
AppendText(CodeEl, ' '); // !!!: Workaround for current HTML writer
case AElement.Visibility of
visPrivate: s := 'private';
visProtected: s := 'protected';
visPublic: s := 'public';
visPublished: s := 'published';
visAutomated: s := 'automated';
else s := '';
end;
if Length(s) > 0 then
AppendKw(CodeEl, s);
AppendText(CodeEl, ' ');
if AElement.ClassType = TPasVariable then
CreateVarPage(TPasVariable(AElement))
else if AElement.InheritsFrom(TPasProcedureBase) then
AppendProcDecl(CodeEl, TableEl, TPasProcedureBase(AElement))
else if AElement.ClassType = TPasProperty then
CreatePropertyPage(TPasProperty(AElement))
else
AppendText(CreateWarning(BodyElement), '<' + AElement.ClassName + '>');
FinishElementPage(AElement);
end;
procedure THTMLWriter.CreateVarPageBody(AVar: TPasVariable);
var
TableEl, TREl, TDEl, CodeEl, El: TDOMElement;
DocNode: TDocNode;
begin
AppendMenuBar(-1);
AppendTitle(AVar.FullName);
AppendShortDescr(CreatePara(BodyElement), AVar);
AppendText(CreateH2(BodyElement), SDocDeclaration);
AppendSourceRef(AVar);
TableEl := CreateTable(BodyElement);
TREl := CreateTR(TableEl);
TDEl := CreateTD(TREl);
CodeEl := CreateCode(CreatePara(TDEl));
AppendKw(CodeEl, 'var');
AppendText(CodeEl, ' ' + AVar.Name);
if Assigned(AVar.VarType) then
begin
AppendSym(CodeEl, ': ');
El := AppendType(CodeEl, TableEl, AVar.VarType, False);
end else
El := CodeEl;
if Length(AVar.Value) > 0 then
AppendPasSHFragment(El, ' = ' + AVar.Value + ';', 0)
else
AppendSym(El, ';');
FinishElementPage(AVar);
end;
procedure THTMLWriter.CreateProcPageBody(AProc: TPasProcedureBase);
var
TableEl, TREl, TDEl, CodeEl: TDOMElement;
begin
AppendMenuBar(-1);
AppendTitle(AProc.Name);
AppendShortDescr(CreatePara(BodyElement), AProc);
AppendText(CreateH2(BodyElement), SDocDeclaration);
AppendSourceRef(AProc);
TableEl := CreateTable(BodyElement);
TREl := CreateTR(TableEl);
TDEl := CreateTD(TREl);
CodeEl := CreateCode(CreatePara(TDEl));
AppendProcDecl(CodeEl, TableEl, AProc);
FinishElementPage(AProc);
end;
Function THTMLWriter.InterPretOption(Const Cmd,Arg : String) : boolean;
begin
Result:=True;
if Cmd = '--html-search' then
SearchPage := Arg
else if Cmd = '--footer' then
FooterFile := Arg
else if Cmd = '--charset' then
CharSet := Arg
else if Cmd = '--index-colcount' then
IndexColCount := StrToIntDef(Arg,IndexColCount)
else if Cmd = '--image-url' then
FBaseImageURL := Arg
else if Cmd = '--footer-date' then
begin
FIDF:=True;
FDateFormat:=Arg;
end
else
Result:=False;
end;
procedure THTMLWriter.WriteDoc;
begin
WriteLn(Format(SWritingPages, [PageCount]));
WriteHTMLPages;
end;
class procedure THTMLWriter.Usage(List: TStrings);
begin
List.add('--footer');
List.Add(SHTMLUsageFooter);
List.Add('--footer-date[=Fmt]');
List.Add(SHTMLUsageFooterDate);
List.Add('--charset=set');
List.Add(SHTMLUsageCharset);
List.Add('--html-search=pagename');
List.Add(SHTMLHtmlSearch);
List.Add('--index-colcount=N');
List.Add(SHTMLIndexColcount);
List.Add('--image-url=url');
List.Add(SHTMLImageUrl);
end;
// private methods
function THTMLWriter.GetPageCount: Integer;
begin
Result := PageInfos.Count;
end;
procedure THTMLWriter.SetOnTest(const AValue: TNotifyEvent);
begin
if FOnTest=AValue then exit;
FOnTest:=AValue;
end;
procedure THTMLWriter.CreateAllocator;
begin
FAllocator:=TLongNameFileAllocator.Create('.html');
end;
procedure THTMWriter.CreateAllocator;
begin
FAllocator:=TShortNameFileAllocator.Create('.htm');
end;
initialization
// Do not localize.
RegisterWriter(THTMLWriter,'html','HTML output using fpdoc.css stylesheet.');
RegisterWriter(THTMWriter,'htm','HTM (8.3 filenames) output using fpdoc.css stylesheet.');
RegisterWriter(TCHMHTMLWriter,'chm','Compressed HTML file output using fpdoc.css stylesheet.');
finalization
UnRegisterWriter('html');
UnRegisterWriter('htm');
UnRegisterWriter('chm');
end.