mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-08 01:08:07 +02:00
1516 lines
40 KiB
ObjectPascal
1516 lines
40 KiB
ObjectPascal
{$mode objfpc}
|
|
{$H+}
|
|
unit dwlinear;
|
|
{$WARN 5024 off : Parameter "$1" not used}
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, DGlobals, dWriter, pastree, dom;
|
|
|
|
Type
|
|
{ TLinearWriter }
|
|
|
|
TLinearWriter = Class(TFPDocWriter)
|
|
FStream : TStream;
|
|
PackageName: String;
|
|
Module: TPasModule;
|
|
FLastURL : DomString;
|
|
private
|
|
FDupLinkedDoc: Boolean;
|
|
Protected
|
|
ModuleName: String;
|
|
// Writing support.
|
|
procedure Write(const s: String); virtual;
|
|
procedure WriteLn(const s: String); virtual;
|
|
procedure WriteF(const s: String; const Args: array of const); virtual;
|
|
procedure WriteLnF(const s: String; const Args: array of const); virtual;
|
|
Function PushWriteContext(S : TStream) : TStream;
|
|
Procedure PopWriteContext(S : TSTream);
|
|
procedure WriteLabel(El: TPasElement);
|
|
procedure WriteIndex(El: TPasElement);
|
|
procedure WriteTypeDecl(El: TPasElement); virtual;
|
|
procedure WriteVariableDecl(El: TPasElement); virtual;
|
|
procedure WriteConstDecl(El: TPasElement); virtual;
|
|
// Auxiliary routines
|
|
procedure DescrBeginURL(const AURL: DOMString); override; // Provides a default implementation
|
|
procedure DescrEndURL; override;
|
|
procedure SortElementList(List : TFPList);
|
|
procedure StartListing(Frames: Boolean);
|
|
Function ShowMember(M : TPasElement) : boolean;
|
|
procedure StartChapter(ChapterName : String; ChapterLabel : String); virtual;
|
|
procedure StartSection(SectionName : String; SectionLabel : String); virtual;
|
|
procedure StartSubSection(SubSectionName : String; SubSectionLabel : String); virtual;
|
|
procedure StartSubSubSection(SubSubSectionName : String; SubSubSectionLabel : String); virtual;
|
|
Function GetDescrString(AContext: TPasElement; DescrNode: TDOMElement) : String;
|
|
function ConstValue(ConstDecl: TPasConst): String; virtual;
|
|
procedure ProcessSection(ASection: TPasSection); virtual;
|
|
// Procedures which MAY be overridden in descendents
|
|
procedure WriteBeginDocument; virtual;
|
|
procedure WriteEndDocument; virtual;
|
|
Function EscapeText(S : UnicodeString) : AnsiString; overload;
|
|
Function EscapeText(S : AnsiString) : AnsiString; virtual; overload;
|
|
Function StripText(S : String) : String; virtual;
|
|
Procedure StartProcedure; Virtual;
|
|
Procedure EndProcedure; Virtual;
|
|
Procedure StartProperty; Virtual;
|
|
Procedure EndProperty; Virtual;
|
|
Procedure StartSynopsis; Virtual;
|
|
Procedure StartDeclaration; Virtual;
|
|
Procedure StartVisibility; Virtual;
|
|
Procedure StartDescription; Virtual;
|
|
Procedure StartAccess; Virtual;
|
|
Procedure StartErrors; Virtual;
|
|
Procedure StartVersion; Virtual;
|
|
Procedure StartSeealso; Virtual;
|
|
Procedure EndSeealso; Virtual;
|
|
// Procedures which MUST be overridden in descendents;
|
|
procedure WriteCommentLine; virtual; abstract;
|
|
procedure WriteComment(Comment : String); virtual; abstract;
|
|
function GetLabel(AElement: TPasElement): String; virtual; abstract;
|
|
procedure WriteLabel(Const S : String); virtual; abstract;
|
|
procedure WriteIndex(Const S : String); virtual; abstract;
|
|
procedure WriteType(const s: string); virtual;
|
|
procedure WriteVariable(const s: string); virtual;
|
|
procedure WriteConstant(const s: string); virtual;
|
|
procedure StartChapter(ChapterName : String); virtual; abstract;
|
|
procedure StartSection(SectionName : String); virtual; abstract;
|
|
procedure StartSubSection(SubSectionName : String); virtual; abstract;
|
|
procedure StartSubSubSection(SubSubSectionName : String); virtual; abstract;
|
|
procedure StartListing(Frames: Boolean; const name: String); virtual; abstract;
|
|
procedure EndListing; virtual; abstract;
|
|
Procedure WriteExampleFile(FN : String); virtual; abstract;
|
|
procedure StartOverview(Const What : String; WithAccess : Boolean); virtual; Abstract;
|
|
procedure EndOverview; virtual; Abstract;
|
|
procedure WriteOverviewMember(const ALabel,AName,Access,ADescr : String); virtual; Abstract;
|
|
procedure WriteOverviewMember(const ALabel,AName,ADescr : String); virtual; Abstract;
|
|
procedure StartUnitOverview(AModuleName,AModuleLabel : String);virtual; Abstract;
|
|
procedure WriteUnitEntry(UnitRef : TPasType);virtual; Abstract;
|
|
procedure EndUnitOverview; virtual; Abstract;
|
|
Property LastURL : DomString Read FLastURL Write FLastURL;
|
|
// Overriden from fpdocwriter;
|
|
procedure DescrWriteText(const AText: DOMString); override;
|
|
// Actual writing happens here.
|
|
Procedure DoWriteDocumentation; override;
|
|
Public
|
|
Constructor Create(APackage: TPasPackage; AEngine: TFPDocEngine); override;
|
|
function InterpretOption(const Cmd, Arg: String): Boolean; override;
|
|
class procedure Usage(List: TStrings); override;
|
|
// Linear Documentation writing methods.
|
|
Procedure ProcessPackage;
|
|
Procedure ProcessTopics(DocNode : TDocNode; Alevel : Integer);
|
|
procedure WriteResourceStrings(ASection: TPasSection);
|
|
procedure WriteUnitOverview(ASection: TPasSection);
|
|
procedure WriteVarsConstsTypes(ASection: TPasSection);
|
|
procedure WriteConsts(ASection: TPasSection);
|
|
procedure WriteTypes(ASection: TPasSection); virtual;
|
|
procedure WriteEnumElements(TypeDecl : TPasEnumType);
|
|
procedure WriteVars(ASection: TPasSection);
|
|
procedure WriteFunctionsAndProcedures(ASection: TPasSection);
|
|
procedure WriteProcedure(ProcDecl: TPasProcedureBase);
|
|
procedure WriteClasses(ASection: TPasSection);
|
|
Procedure WriteExtendedRecords(Asection : TPasSection);
|
|
procedure WriteClassDecl(ClassDecl: TPasClassType);
|
|
procedure WriteMethodOverview(AParent: TPasType; Members : TFPList);
|
|
procedure WritePropertyOverview(AParent: TPasType; Members : TFPList);
|
|
procedure WriteClassInterfacesOverview(ClassDecl: TPasClassType);
|
|
procedure WriteClassInheritanceOverview(ClassDecl: TPasClassType); virtual;
|
|
procedure WriteProperty(PropDecl: TPasProperty);
|
|
procedure WriteExample(ADocNode: TDocNode);
|
|
procedure WriteSeeAlso(ADocNode: TDocNode);
|
|
Procedure WriteTopicNode(Node : TDocNode; Level : Integer);
|
|
end;
|
|
|
|
implementation
|
|
|
|
uses fpdocstrs;
|
|
|
|
const
|
|
cDupLinkedDocParam = '--duplinkeddoc';
|
|
|
|
{ TLinearWriter }
|
|
|
|
{ ---------------------------------------------------------------------
|
|
Writing support
|
|
---------------------------------------------------------------------}
|
|
|
|
function TLinearWriter.PushWriteContext(S: TStream): TStream;
|
|
|
|
begin
|
|
Result:=FStream;
|
|
FStream:=S;
|
|
end;
|
|
|
|
procedure TLinearWriter.PopWriteContext(S: TSTream);
|
|
|
|
begin
|
|
FStream:=S;
|
|
end;
|
|
|
|
procedure TLinearWriter.Write(const s: String);
|
|
|
|
Var
|
|
L : Integer;
|
|
|
|
begin
|
|
L:=Length(S);
|
|
If (L>0) then
|
|
FStream.Write(PChar(S)^,L);
|
|
end;
|
|
|
|
procedure TLinearWriter.WriteF(const s: String; const Args: array of const);
|
|
begin
|
|
Write(Format(S,Args));
|
|
end;
|
|
|
|
procedure TLinearWriter.WriteLn(const s: String);
|
|
begin
|
|
Write(S);
|
|
Write(LineEnding);
|
|
end;
|
|
|
|
procedure TLinearWriter.WriteLnF(const s: String; const Args: array of const);
|
|
begin
|
|
Write(Format(S,Args));
|
|
Write(LineEnding);
|
|
end;
|
|
|
|
procedure TLinearWriter.DescrWriteText(const AText: DOMString);
|
|
begin
|
|
Write(EscapeText(AText));
|
|
end;
|
|
|
|
function TLinearWriter.GetDescrString(AContext: TPasElement;
|
|
DescrNode: TDOMElement): String;
|
|
|
|
Var
|
|
S : TStringStream;
|
|
F : TStream;
|
|
|
|
begin
|
|
Result:='';
|
|
if Assigned(DescrNode) then
|
|
begin
|
|
S:=TStringStream.Create('');
|
|
Try
|
|
F:=PushWriteContext(S);
|
|
Try
|
|
ConvertDescr(AContext, DescrNode, False);
|
|
Result:=S.DataString;
|
|
FInally
|
|
PopWriteContext(F);
|
|
end;
|
|
finally
|
|
S.FRee;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{ ---------------------------------------------------------------------
|
|
Auxiliary routines
|
|
---------------------------------------------------------------------}
|
|
|
|
procedure TLinearWriter.WriteLabel(El: TPasElement);
|
|
begin
|
|
WriteLabel(GetLabel(El));
|
|
end;
|
|
|
|
procedure TLinearWriter.WriteIndex(El: TPasElement);
|
|
begin
|
|
WriteIndex(EL.Name);
|
|
end;
|
|
|
|
procedure TLinearWriter.WriteTypeDecl(El: TPasElement);
|
|
begin
|
|
WriteType(El.Name);
|
|
end;
|
|
|
|
procedure TLinearWriter.WriteVariableDecl(El: TPasElement);
|
|
begin
|
|
WriteVariable(El.Name);
|
|
end;
|
|
|
|
procedure TLinearWriter.WriteConstDecl(El: TPasElement);
|
|
begin
|
|
WriteConstant(El.Name);
|
|
end;
|
|
|
|
procedure TLinearWriter.DescrBeginURL(const AURL: DOMString);
|
|
begin
|
|
FLastURL:=AURL;
|
|
end;
|
|
|
|
procedure TLinearWriter.DescrEndURL;
|
|
begin
|
|
If (FLastURL<>'') then
|
|
Writeln(Format(SSeeURL,[EscapeText(FLastURL)]));
|
|
FLastURL:='';
|
|
end;
|
|
|
|
procedure TLinearWriter.StartListing(Frames: Boolean);
|
|
begin
|
|
StartListing(Frames,'');
|
|
end;
|
|
|
|
procedure TLinearWriter.StartChapter(ChapterName: String; ChapterLabel: String);
|
|
begin
|
|
StartChapter(ChapterName);
|
|
WriteLabel(ChapterLabel);
|
|
end;
|
|
|
|
procedure TLinearWriter.StartSection(SectionName: String; SectionLabel: String);
|
|
begin
|
|
StartSection(SectionName);
|
|
WriteLabel(SectionLabel);
|
|
end;
|
|
|
|
procedure TLinearWriter.StartSubSection(SubSectionName: String; SubSectionLabel: String);
|
|
begin
|
|
StartSubSection(SubSectionName);
|
|
WriteLabel(SubSectionLabel);
|
|
end;
|
|
|
|
procedure TLinearWriter.StartSubSubSection(SubSubSectionName: String;
|
|
SubSubSectionLabel: String);
|
|
begin
|
|
StartSubSubSection(SubSubSectionName);
|
|
WriteLabel(SubSubSectionLabel);
|
|
end;
|
|
|
|
{ ---------------------------------------------------------------------
|
|
Default implementations, may be overridden in descendents
|
|
---------------------------------------------------------------------}
|
|
|
|
function TLinearWriter.EscapeText(S: AnsiString): AnsiString;
|
|
|
|
begin
|
|
Result:=S;
|
|
end;
|
|
|
|
function TLinearWriter.StripText(S: String): String;
|
|
|
|
begin
|
|
Result:=S;
|
|
end;
|
|
|
|
procedure TLinearWriter.StartProcedure;
|
|
|
|
begin
|
|
Writeln(SDocProcedure+':');
|
|
end;
|
|
|
|
procedure TLinearWriter.StartSynopsis;
|
|
|
|
begin
|
|
Writeln('');
|
|
Writeln(SDocSynopsis+':');
|
|
end;
|
|
|
|
procedure TLinearWriter.StartDeclaration;
|
|
|
|
begin
|
|
Writeln('');
|
|
Writeln(SDocDeclaration+':');
|
|
end;
|
|
|
|
procedure TLinearWriter.StartVisibility;
|
|
|
|
begin
|
|
Writeln('');
|
|
Writeln(SDocVisibility+':');
|
|
end;
|
|
|
|
procedure TLinearWriter.StartDescription;
|
|
|
|
begin
|
|
Writeln('');
|
|
Writeln(SDocDescription+':');
|
|
end;
|
|
|
|
procedure TLinearWriter.StartAccess;
|
|
|
|
begin
|
|
Writeln('');
|
|
Writeln(SDocAccess+':');
|
|
end;
|
|
|
|
procedure TLinearWriter.StartErrors;
|
|
|
|
begin
|
|
Writeln('');
|
|
Writeln(SDocErrors+':');
|
|
end;
|
|
|
|
procedure TLinearWriter.StartVersion;
|
|
|
|
begin
|
|
Writeln('');
|
|
Writeln(SDocVersion+':');
|
|
end;
|
|
|
|
procedure TLinearWriter.StartSeealso;
|
|
|
|
begin
|
|
Writeln('');
|
|
Writeln(SDocSeeAlso+':');
|
|
end;
|
|
|
|
|
|
procedure TLinearWriter.StartProperty;
|
|
|
|
begin
|
|
Writeln('');
|
|
Writeln(SDocProperty+':');
|
|
end;
|
|
|
|
procedure TLinearWriter.EndProcedure;
|
|
|
|
begin
|
|
Writeln('');
|
|
end;
|
|
|
|
procedure TLinearWriter.EndProperty;
|
|
|
|
begin
|
|
Writeln('');
|
|
end;
|
|
|
|
procedure TLinearWriter.EndSeealso;
|
|
begin
|
|
Writeln('');
|
|
end;
|
|
|
|
procedure TLinearWriter.WriteType(const s: string);
|
|
begin
|
|
// do nothing
|
|
end;
|
|
|
|
procedure TLinearWriter.WriteVariable(const s: string);
|
|
begin
|
|
// do nothing
|
|
end;
|
|
|
|
procedure TLinearWriter.WriteConstant(const s: string);
|
|
begin
|
|
// do nothing
|
|
end;
|
|
|
|
procedure TLinearWriter.WriteClassDecl(ClassDecl: TPasClassType);
|
|
var
|
|
DocNode: TDocNode;
|
|
Member: TPasElement;
|
|
i: Integer;
|
|
begin
|
|
DocNode := Engine.FindDocNode(ClassDecl);
|
|
if Assigned(DocNode) and DocNode.IsSkipped then
|
|
Exit;
|
|
StartSection(ClassDecl.Name);
|
|
WriteLabel(ClassDecl);
|
|
WriteIndex(ClassDecl);
|
|
if Assigned(DocNode) and ((not IsDescrNodeEmpty(DocNode.Descr)) or
|
|
(not IsDescrNodeEmpty(DocNode.ShortDescr))) then
|
|
begin
|
|
StartSubSection(SDocDescription);
|
|
WriteDescr(ClassDecl,DocNode);
|
|
If Assigned(DocNode.Version) then
|
|
begin
|
|
StartSubSection(SDocVersion);
|
|
WriteDescr(ClassDecl,DocNode.Version);
|
|
end;
|
|
if Assigned(DocNode.SeeAlso) then
|
|
begin
|
|
WriteSeeAlso(DocNode);
|
|
end;
|
|
ConvertNotes(ClassDecl,DocNode.Notes);
|
|
end;
|
|
|
|
// graemeg: this must move above SeeAlso, Version and Notes written above.
|
|
// Write Class Hierarchy (Inheritance) Overview;
|
|
WriteClassInheritanceOverView(ClassDecl);
|
|
|
|
// Write Interfaces Overview;
|
|
WriteClassInterfacesOverView(ClassDecl);
|
|
// Write method overview
|
|
WriteMethodOverView(ClassDecl,ClassDecl.Members);
|
|
// Write Property Overview;
|
|
WritePropertyOverView(ClassDecl,ClassDecl.Members);
|
|
|
|
// Write method & property descriptions
|
|
|
|
// Determine visibilities
|
|
|
|
for i := 0 to ClassDecl.Members.Count - 1 do
|
|
begin
|
|
Member := TPasElement(ClassDecl.Members[i]);
|
|
if Member.InheritsFrom(TPasProcedureBase) and Engine.ShowElement(Member) then
|
|
WriteProcedure(TPasProcedureBase(Member));
|
|
end;
|
|
|
|
// properties.
|
|
|
|
for i := 0 to ClassDecl.Members.Count - 1 do
|
|
begin
|
|
Member := TPasElement(ClassDecl.Members[i]);
|
|
if Member.InheritsFrom(TPasProperty) and Engine.ShowElement(Member) then
|
|
WriteProperty(TPasProperty(Member));
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TLinearWriter.WritePropertyOverview(AParent: TPasType; Members : TFPList);
|
|
|
|
var
|
|
Member: TPasElement;
|
|
i: Integer;
|
|
L,N,S,A: String;
|
|
DocNode: TDocNode;
|
|
List : TStringList;
|
|
lNode: TDocNode;
|
|
begin
|
|
// Write property overview
|
|
List:=TStringList.Create;
|
|
Try
|
|
List.Sorted:=True;
|
|
for i := 0 to Members.Count - 1 do
|
|
begin
|
|
Member := TPasElement(Members[i]);
|
|
With Member do
|
|
if InheritsFrom(TPasProperty) and SHowMember(Member) then
|
|
List.AddObject(Member.Name,Member)
|
|
end;
|
|
If (List.Count>0) then
|
|
begin
|
|
StartSubSection(SDocPropertyOverview);
|
|
WriteLabel(GetLabel(AParent) + ':Properties');
|
|
StartOverView(SDocProperties,True);
|
|
For I:=0 to List.Count-1 do
|
|
begin
|
|
Member:=TPasElement(List.objects[i]);
|
|
L:=StripText(GetLabel(Member));
|
|
N:=EscapeText(Member.Name);
|
|
DocNode := Engine.FindDocNode(Member);
|
|
if Assigned(DocNode) and DocNode.IsSkipped then
|
|
Continue;
|
|
if Assigned(DocNode) then
|
|
begin
|
|
if FDupLinkedDoc and (DocNode.Link <> '') then
|
|
begin
|
|
lNode := Engine.FindLinkedNode(DocNode);
|
|
if not Assigned(lNode) then
|
|
lNode := DocNode;
|
|
end
|
|
else
|
|
lNode := DocNode;
|
|
S := GetDescrString(Member, lNode.ShortDescr);
|
|
end
|
|
else
|
|
S := '';
|
|
|
|
A:='';
|
|
if Length(TPasProperty(Member).ReadAccessorName) > 0 then
|
|
a := a + 'r';
|
|
if Length(TPasProperty(Member).WriteAccessorName) > 0 then
|
|
a := a + 'w';
|
|
if Length(TPasProperty(Member).StoredAccessorName) > 0 then
|
|
a := a + 's';
|
|
WriteOverviewMember(L,N,A,S);
|
|
S := '';
|
|
end;
|
|
EndOverview;
|
|
end;
|
|
Finally
|
|
List.Free;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TLinearWriter.WriteClassInterfacesOverview(ClassDecl: TPasClassType);
|
|
var
|
|
lInterface: TPasElement;
|
|
i: Integer;
|
|
L,N,S: String;
|
|
DocNode: TDocNode;
|
|
List : TStringList;
|
|
lNode: TDocNode;
|
|
begin
|
|
// Write Interfaces overview
|
|
List:=TStringList.Create;
|
|
try
|
|
List.Sorted:=True;
|
|
for i := 0 to ClassDecl.Interfaces.Count-1 do
|
|
begin
|
|
lInterface := TPasElement(ClassDecl.Interfaces[i]);
|
|
List.AddObject(lInterface.Name,lInterface);
|
|
end;
|
|
if (List.Count>0) then
|
|
begin
|
|
StartSubSection(SDocInterfacesOverview);
|
|
WriteLabel(GetLabel(ClassDecl) + ':Interfaces');
|
|
StartOverView(SDocInterface,False);
|
|
for i := 0 to List.Count-1 do
|
|
begin
|
|
lInterface := TPasElement(List.Objects[i]);
|
|
L := StripText(GetLabel(lInterface));
|
|
N := EscapeText(lInterface.Name);
|
|
DocNode := Engine.FindDocNode(lInterface);
|
|
if Assigned(DocNode) and DocNode.IsSkipped then
|
|
Continue;
|
|
if Assigned(DocNode) then
|
|
begin
|
|
if FDupLinkedDoc and (DocNode.Link <> '') then
|
|
begin
|
|
lNode := Engine.FindLinkedNode(DocNode);
|
|
if not Assigned(lNode) then
|
|
lNode := DocNode;
|
|
end
|
|
else
|
|
lNode := DocNode;
|
|
S := GetDescrString(lInterface, lNode.ShortDescr);
|
|
end
|
|
else
|
|
S := '';
|
|
|
|
WriteOverviewMember(L,N,S);
|
|
S := '';
|
|
end;
|
|
EndOverview;
|
|
end;
|
|
finally
|
|
List.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TLinearWriter.WriteClassInheritanceOverview(ClassDecl: TPasClassType);
|
|
begin
|
|
{ Do nothing by default. This will be implemented by descendant writers. See
|
|
the IPF Writer for an example. }
|
|
end;
|
|
|
|
|
|
function TLinearWriter.ConstValue(ConstDecl: TPasConst): String;
|
|
begin
|
|
if Assigned(ConstDecl) then
|
|
Result := ConstDecl.ClassName
|
|
else
|
|
Result := '<nil>';
|
|
end;
|
|
|
|
procedure TLinearWriter.DoWriteDocumentation;
|
|
|
|
var
|
|
i : Integer;
|
|
L : TstringList;
|
|
|
|
begin
|
|
PackageName := LowerCase(Copy(Package.Name, 2, 255));
|
|
If (Engine.OutPut='') then
|
|
Engine.Output:=PackageName+FileNameExtension
|
|
else if (ExtractFileExt(Engine.output)='') and (FileNameExtension<>'') then
|
|
Engine.Output:=ChangeFileExt(Engine.output,FileNameExtension);
|
|
FStream:=TFileStream.Create(Engine.Output,fmCreate);
|
|
try
|
|
WriteBeginDocument;
|
|
ProcessPackage;
|
|
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
|
|
Module := TPasModule(L.Objects[i]);
|
|
ModuleName := LowerCase(Module.Name);
|
|
WriteCommentLine;
|
|
StartChapter(Format(SDocUnitTitle, [Module.Name]));
|
|
WriteLabel(Module);
|
|
// extra Topics now get processed in ProcessSection()
|
|
ProcessSection(Module.InterfaceSection);
|
|
end;
|
|
Finally
|
|
L.Free;
|
|
end;
|
|
WriteEndDocument;
|
|
finally
|
|
FSTream.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TLinearWriter.ProcessSection(ASection: TPasSection);
|
|
var
|
|
DocNode: TDocNode;
|
|
begin
|
|
With ASection do
|
|
begin
|
|
SortElementList(UsesList);
|
|
SortElementList(Declarations);
|
|
SortElementList(ResStrings);
|
|
SortElementList(Types);
|
|
SortElementList(Consts);
|
|
SortElementList(Classes);
|
|
SortElementList(Functions);
|
|
SortElementList(Variables);
|
|
end;
|
|
WriteUnitOverView(ASection);
|
|
|
|
// Now process unit (extra) Topics
|
|
DocNode:=Engine.FindDocNode(Module);
|
|
If Assigned(DocNode) then
|
|
ProcessTopics(DocNode,1);
|
|
|
|
WriteVarsConstsTypes(ASection);
|
|
WriteFunctionsAndProcedures(ASection);
|
|
WriteExtendedRecords(ASection);
|
|
WriteClasses(ASection);
|
|
end;
|
|
|
|
procedure TLinearWriter.WriteVarsConstsTypes(ASection: TPasSection);
|
|
|
|
begin
|
|
With Asection do
|
|
if (Consts.Count>0) or (Types.Count>0) or
|
|
(Variables.Count>0) or (ResStrings.Count>0) then
|
|
begin
|
|
StartSection(SDocConstsTypesVars, ModuleName+'ConstsTypesVars');
|
|
WriteResourceStrings(ASection);
|
|
WriteConsts(ASection);
|
|
WriteTypes(ASection);
|
|
WriteVars(ASection);
|
|
end;
|
|
end;
|
|
|
|
procedure TLinearWriter.WriteResourceStrings(ASection: TPasSection);
|
|
var
|
|
ResStrDecl: TPasResString;
|
|
i: Integer;
|
|
DocNode : TDocNode;
|
|
begin
|
|
if ASection.ResStrings.Count > 0 then
|
|
begin
|
|
StartSubSection(SDocResStrings,ModuleName+'ResStrings');
|
|
for i := 0 to ASection.ResStrings.Count - 1 do
|
|
begin
|
|
ResStrDecl := TPasResString(ASection.ResStrings[i]);
|
|
StartListing(false, '');
|
|
DescrWriteText(UTF8Decode(ResStrDecl.GetDeclaration(True))); // instead of WriteLn() so we can do further processing like manual line wrapping in descendants
|
|
EndListing;
|
|
WriteLabel(ResStrDecl);
|
|
WriteIndex(ResStrDecl);
|
|
DocNode:=WriteDescr(ResStrDecl);
|
|
If Assigned(DocNode) and Assigned(DocNode.Version) then
|
|
begin
|
|
Writeln(Format('%s : ',[SDocVersion]));
|
|
WriteDescr(ResStrDecl, DocNode.Version);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TLinearWriter.WriteUnitOverview(ASection: TPasSection);
|
|
|
|
var
|
|
i: Integer;
|
|
UnitRef: TPasType;
|
|
DocNode: TDocNode;
|
|
begin
|
|
if ASection.UsesList.Count > 0 then
|
|
begin
|
|
StartSection(SDocUsedUnits);
|
|
StartUnitOverview(Module.Name,ModuleName);
|
|
for i := 0 to ASection.UsesList.Count - 1 do
|
|
begin
|
|
UnitRef := TPasType(ASection.UsesList[i]);
|
|
WriteUnitEntry(UnitRef);
|
|
end;
|
|
EndUnitOverview;
|
|
end;
|
|
DocNode := Engine.FindDocNode(ASection.Parent);
|
|
if Assigned(DocNode) and not IsDescrNodeEmpty(DocNode.Descr) then
|
|
begin
|
|
StartSection(SDocOverview);
|
|
WriteDescr(ASection.Parent, DocNode.Descr);
|
|
ConvertNotes(ASection.Parent,DocNode.Notes);
|
|
end;
|
|
end;
|
|
|
|
procedure TLinearWriter.ProcessPackage;
|
|
|
|
var
|
|
DocNode: TDocNode;
|
|
|
|
begin
|
|
DocNode:=Engine.FindDocNode(Package);
|
|
if not Assigned(DocNode) then
|
|
exit;
|
|
if Assigned(DocNode) and not IsDescrNodeEmpty(DocNode.Descr) then
|
|
begin
|
|
StartSection(SDocOverview);
|
|
WriteDescr(Package, DocNode.Descr);
|
|
end;
|
|
WriteSeeAlso(DocNode);
|
|
ConvertNotes(Nil,DocNode.Notes);
|
|
ProcessTopics(DocNode,1);
|
|
end;
|
|
|
|
procedure TLinearWriter.ProcessTopics(DocNode: TDocNode; Alevel: Integer);
|
|
|
|
Var
|
|
Node : TDocNode;
|
|
|
|
begin
|
|
If Not Assigned(DocNode) then
|
|
Exit;
|
|
Node:=DocNode.FirstChild;
|
|
While Assigned(Node) do
|
|
begin
|
|
If Node.TopicNode then
|
|
WriteTopicNode(Node,ALevel);
|
|
Node:=Node.NextSibling;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TLinearWriter.WriteTopicNode(Node: TDocNode; Level: Integer);
|
|
|
|
Var
|
|
Element : TTopicElement;
|
|
SubNode : TDocNode;
|
|
S : String;
|
|
|
|
begin
|
|
Element:=FindTopicElement(Node);
|
|
If Not Assigned(Element) then
|
|
Exit;
|
|
S:=GetDescrString(Element,Node.ShortDescr);
|
|
Case Level of
|
|
1 : StartSection(S);
|
|
2 : StartSubSection(S);
|
|
3 : StartSubSubSection(S);
|
|
end;
|
|
WriteLabel(Element);
|
|
If Assigned(Node.Descr) then
|
|
WriteDescr(Element,Node.Descr);
|
|
WriteSeeAlso(Node);
|
|
ConvertNotes(Element,Node.Notes);
|
|
If Level<3 then
|
|
begin
|
|
SubNode:=Node.FirstChild;
|
|
While Assigned(SubNode) do
|
|
begin
|
|
If SubNode.TopicNode then
|
|
WriteTopicNode(SubNode,Level+1);
|
|
SubNode:=SubNode.NextSibling;
|
|
end;
|
|
end;
|
|
WriteExample(Node);
|
|
end;
|
|
|
|
procedure TLinearWriter.WriteConsts(ASection: TPasSection);
|
|
var
|
|
i: Integer;
|
|
ConstDecl: TPasConst;
|
|
begin
|
|
if ASection.Consts.Count > 0 then
|
|
begin
|
|
StartSubSection(SDocConstants,EscapeText(ModuleName));
|
|
for i := 0 to ASection.Consts.Count - 1 do
|
|
begin
|
|
DescrBeginParaGraph;
|
|
ConstDecl := TPasConst(ASection.Consts[i]);
|
|
WriteConstDecl(ConstDecl);
|
|
StartListing(False,'');
|
|
WriteLn(EscapeText(ConstDecl.GetDeclaration(True)));
|
|
EndListing;
|
|
WriteLabel(ConstDecl);
|
|
WriteIndex(ConstDecl);
|
|
WriteDescr(ConstDecl);
|
|
DescrEndParaGraph;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TLinearWriter.WriteEnumElements(TypeDecl : TPasEnumType);
|
|
|
|
Var
|
|
EV : TPasEnumValue;
|
|
I : Integer;
|
|
DocNode : TDocNode;
|
|
|
|
begin
|
|
With TypeDecl do
|
|
begin
|
|
SortElementList(Values);
|
|
DescrBeginTable(2,True);
|
|
DescrBeginTableCaption;
|
|
Writeln(EscapeText(Format(SDocValuesForEnum,[TypeDecl.Name])));
|
|
DescrEndTableCaption;
|
|
DescrBeginTableHeadRow;
|
|
DescrBeginTableCell;
|
|
Writeln(EscapeText(SDocValue));
|
|
DescrEndTableCell;
|
|
DescrBeginTableCell;
|
|
Writeln(EscapeText(SDocExplanation));
|
|
DescrEndTableCell;
|
|
DescrEndTableHeadRow;
|
|
For I:=0 to Values.Count-1 do
|
|
begin
|
|
EV:=TPasEnumValue(Values[i]);
|
|
DescrBeginTableRow;
|
|
DescrBeginTableCell;
|
|
Writeln(EscapeText(EV.Name));
|
|
DescrEndTableCell;
|
|
DescrBeginTableCell;
|
|
DocNode := Engine.FindDocNode(EV);
|
|
if Assigned(DocNode) and (not IsDescrNodeEmpty(DocNode.ShortDescr)) then
|
|
WriteDescr(EV,DocNode.ShortDescr);
|
|
DescrEndTableCell;
|
|
DescrEndTableRow;
|
|
end;
|
|
DescrEndTable;
|
|
end;
|
|
end;
|
|
|
|
procedure TLinearWriter.WriteTypes(ASection: TPasSection);
|
|
var
|
|
i: Integer;
|
|
TypeDecl: TPasType;
|
|
DocNode : TDocNode;
|
|
begin
|
|
if ASection.Types.Count > 0 then
|
|
begin
|
|
StartSubSection(SDocTypes,ModuleName+'Types');
|
|
for i := 0 to ASection.Types.Count - 1 do
|
|
begin
|
|
TypeDecl := TPasType(ASection.Types[i]);
|
|
DocNode := Engine.FindDocNode(TypeDecl);
|
|
if Assigned(DocNode) and DocNode.IsSkipped then
|
|
Continue;
|
|
if not ((TypeDecl is TPasRecordType) and TPasRecordType(TypeDecl).IsAdvancedRecord) then
|
|
begin
|
|
DescrBeginParagraph;
|
|
WriteTypeDecl(TypeDecl);
|
|
StartListing(False,'');
|
|
If Assigned(DocNode) and
|
|
Assigned(DocNode.Node) and
|
|
(Docnode.Node['opaque']='1') then
|
|
Writeln(TypeDecl.Name+' = '+SDocOpaque)
|
|
else
|
|
begin
|
|
Writeln(EscapeText(TypeDecl.GetDeclaration(True)));
|
|
end;
|
|
EndListing;
|
|
WriteLabel(TypeDecl);
|
|
WriteIndex(TypeDecl);
|
|
If TypeDecl is TPasEnumType then
|
|
WriteENumElements(TypeDecl as TPasEnumType)
|
|
else If (TypeDecl is TPasSetType)
|
|
and (TPasSetType(TypeDecl).EnumType is TPasEnumType)
|
|
and (TPasSetType(TypeDecl).EnumType.Name='') then
|
|
WriteENumElements(TPasSetType(TypeDecl).EnumType as TPasEnumType);
|
|
WriteDescr(TypeDecl,DocNode);
|
|
If Assigned(DocNode) and Assigned(DocNode.Version) then
|
|
begin
|
|
Writeln(Format('%s : ',[SDocVersion]));
|
|
WriteDescr(TypeDecl, DocNode.Version);
|
|
end;
|
|
if Assigned(DocNode) and assigned(DocNode.Notes) then
|
|
ConvertNotes(TypeDecl,DocNode.Notes);
|
|
DescrEndParagraph;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TLinearWriter.WriteVars(ASection: TPasSection);
|
|
var
|
|
VarDecl: TPasVariable;
|
|
i: Integer;
|
|
DocNode : TDocNode;
|
|
|
|
begin
|
|
if ASection.Variables.Count > 0 then
|
|
begin
|
|
StartSubsection(SDocVariables,ModuleName+'Variables');
|
|
for i := 0 to ASection.Variables.Count - 1 do
|
|
begin
|
|
DescrBeginParaGraph;
|
|
VarDecl := TPasVariable(ASection.Variables[i]);
|
|
WriteVariableDecl(VarDecl);
|
|
StartListing(False,'');
|
|
WriteLn(EscapeText(VarDecl.GetDeclaration(True)));
|
|
EndListing;
|
|
WriteLabel(VarDecl);
|
|
WriteIndex(VarDecl);
|
|
DocNode:=WriteDescr(VarDecl);
|
|
If Assigned(DocNode) and Assigned(DocNode.Version) then
|
|
begin
|
|
Writeln(Format('%s : ',[SDocVersion]));
|
|
WriteDescr(VarDecl, DocNode.Version);
|
|
ConvertNotes(VarDecl,DocNode.Notes);
|
|
end;
|
|
DescrEndParaGraph;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TLinearWriter.WriteProcedure(ProcDecl : TPasProcedureBase);
|
|
var
|
|
DocNode: TDocNode;
|
|
OP : TPasOverloadedProc;
|
|
i : integer;
|
|
begin
|
|
With ProcDecl do
|
|
begin
|
|
DocNode := Engine.FindDocNode(ProcDecl);
|
|
if Assigned(DocNode) and DocNode.IsSkipped then
|
|
Exit;
|
|
if Not (Assigned(Parent) and ((Parent.InheritsFrom(TPasClassType)) or Parent.InheritsFrom(TPasRecordType))) then
|
|
begin
|
|
StartSubSection(Name);
|
|
WriteLabel(ProcDecl);
|
|
WriteIndex(ProcDecl);
|
|
end
|
|
else
|
|
begin // Parent assigned and hence method.
|
|
StartSubSection(Parent.Name+'.'+Name);
|
|
WriteLabel(ProcDecl);
|
|
WriteIndex(Parent.Name+'.'+Name);
|
|
end;
|
|
StartProcedure;
|
|
if Assigned(DocNode) and Assigned(DocNode.ShortDescr) then
|
|
begin
|
|
StartSynopsis;
|
|
WriteDescr(ProcDecl, DocNode.ShortDescr);
|
|
end;
|
|
StartDeclaration;
|
|
StartListing(False);
|
|
if ClassType = TPasOverloadedProc then
|
|
begin
|
|
OP:=TPasOverloadedProc(ProcDecl);
|
|
for i := 0 to OP.Overloads.Count - 1 do
|
|
begin
|
|
WriteLn(TPasProcedure(OP.Overloads[i]).GetDeclaration(True));
|
|
end;
|
|
end
|
|
else
|
|
WriteLn(GetDeclaration(True));
|
|
EndListing;
|
|
If Assigned(Parent) then
|
|
begin
|
|
StartVisibility;
|
|
Writeln(VisibilityNames[Visibility])
|
|
end;
|
|
if Assigned(DocNode) then
|
|
begin
|
|
If Assigned(DocNode.Descr) then
|
|
begin
|
|
StartDescription;
|
|
WriteDescr(ProcDecl);
|
|
end;
|
|
if Assigned(DocNode.ErrorsDoc) and (DocNode.ErrorsDoc.HasChildNodes) then
|
|
begin
|
|
StartErrors;
|
|
WriteDescr(ProcDecl, DocNode.ErrorsDoc);
|
|
end;
|
|
if Assigned(DocNode.Version) then
|
|
begin
|
|
StartVersion;
|
|
WriteDescr(ProcDecl, DocNode.Version);
|
|
end;
|
|
WriteSeeAlso(DocNode);
|
|
EndProcedure;
|
|
WriteExample(DocNode);
|
|
ConvertNotes(ProcDecl,DocNode.Notes);
|
|
end
|
|
else
|
|
EndProcedure;
|
|
end;
|
|
end;
|
|
|
|
procedure TLinearWriter.WriteFunctionsAndProcedures(ASection: TPasSection);
|
|
var
|
|
i: Integer;
|
|
begin
|
|
if ASection.Functions.Count > 0 then
|
|
begin
|
|
StartSection(SDocProceduresAndFunctions,ModuleName+'Functions');
|
|
for i := 0 to ASection.Functions.Count - 1 do
|
|
WriteProcedure(TPasProcedureBase(ASection.Functions[i]));
|
|
end;
|
|
end;
|
|
|
|
procedure TLinearWriter.WriteExample(ADocNode: TDocNode);
|
|
|
|
var
|
|
Example: TDOMElement;
|
|
S : string;
|
|
|
|
begin
|
|
S:='';
|
|
if Assigned(ADocNode) then
|
|
begin
|
|
Example := ADocNode.FirstExample;
|
|
while Assigned(Example) do
|
|
begin
|
|
if IsExampleNode(Example) then
|
|
begin
|
|
if (S<>'') then // not first example, start new paragraph
|
|
DescrBeginParagraph;
|
|
s:=Engine.GetExampleFileName(Example);
|
|
if (S<>'') then
|
|
WriteExampleFile(S);
|
|
if Assigned(Example.NextSibling) then
|
|
DescrEndParaGraph;
|
|
end;
|
|
Example := TDomElement(Example.NextSibling);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TLinearWriter.WriteProperty(PropDecl : TPasProperty);
|
|
var
|
|
DocNode: TDocNode;
|
|
S: String;
|
|
lNode: TDocNode;
|
|
begin
|
|
With PropDecl do
|
|
begin
|
|
DocNode := Engine.FindDocNode(PropDecl);
|
|
if Assigned(DocNode) and DocNode.IsSkipped then
|
|
Exit;
|
|
StartSubSection(Parent.Name+'.'+Name);
|
|
WriteLabel(PropDecl);
|
|
WriteIndex(Parent.Name+'.'+Name);
|
|
StartProperty;
|
|
if Assigned(DocNode) then
|
|
begin
|
|
if FDupLinkedDoc and (DocNode.Link <> '') then
|
|
begin
|
|
lNode := Engine.FindLinkedNode(DocNode);
|
|
if not Assigned(lNode) then
|
|
lNode := DocNode;
|
|
end
|
|
else
|
|
lNode := DocNode;
|
|
|
|
if Assigned(lNode.ShortDescr) then
|
|
begin
|
|
StartSynopsis;
|
|
WriteDescr(PropDecl, lNode.ShortDescr);
|
|
end;
|
|
end;
|
|
StartDeclaration;
|
|
StartListing(False);
|
|
WriteLn('Property '+GetDeclaration(True));
|
|
EndListing;
|
|
If Assigned(Parent) then
|
|
begin
|
|
StartVisibility;
|
|
Writeln(VisibilityNames[Visibility])
|
|
end;
|
|
StartAccess;
|
|
S:='';
|
|
If Length(ReadAccessorName) > 0 then
|
|
S:='Read';
|
|
if Length(WriteAccessorName) > 0 then
|
|
begin
|
|
If S<>'' then
|
|
S:=S+',';
|
|
S:=S+'Write';
|
|
end;
|
|
Writeln(S);
|
|
if Assigned(DocNode) then
|
|
begin
|
|
if Assigned(lNode.Descr) then // lNode will be assigned if DocNode exists
|
|
begin
|
|
StartDescription;
|
|
WriteDescr(PropDecl, lNode);
|
|
end;
|
|
if Assigned(lNode.ErrorsDoc) and (lNode.ErrorsDoc.HasChildNodes) then
|
|
begin
|
|
StartErrors;
|
|
WriteDescr(PropDecl, DocNode.ErrorsDoc);
|
|
end;
|
|
if Assigned(lNode.Version) then
|
|
begin
|
|
StartVersion;
|
|
WriteDescr(PropDecl, lNode.Version);
|
|
end;
|
|
WriteSeeAlso(lNode);
|
|
ConvertNotes(PropDecl,lNode.Notes);
|
|
EndProperty;
|
|
WriteExample(lNode);
|
|
end
|
|
else
|
|
EndProperty;
|
|
end;
|
|
end;
|
|
|
|
procedure TLinearWriter.WriteSeeAlso(ADocNode: TDocNode);
|
|
|
|
var
|
|
Node: TDOMNode;
|
|
s: DOMString;
|
|
First : Boolean;
|
|
|
|
begin
|
|
if Not (Assigned(ADocNode) and Assigned(ADocNode.SeeAlso)) then
|
|
Exit;
|
|
Node := ADocNode.SeeAlso.FirstChild;
|
|
First:=True;
|
|
while Assigned(Node) do
|
|
begin
|
|
if IsLinkNode(Node) then
|
|
begin
|
|
If First then
|
|
begin
|
|
StartSeealso;
|
|
First:=False;
|
|
end
|
|
else
|
|
Writeln(',');
|
|
S:=TDomElement(Node)['id'];
|
|
DescrBeginLink(S);
|
|
if Node.FirstChild <> nil then
|
|
s := Node.FirstChild.NodeValue;
|
|
Write(EscapeText(S));
|
|
DescrEndLink();
|
|
end;
|
|
Node:=Node.NextSibling;
|
|
end;
|
|
If Not First then
|
|
EndSeeAlso
|
|
end;
|
|
|
|
Function CompareElements(P1,P2 : Pointer) : Integer;
|
|
|
|
begin
|
|
Result:=CompareText(TPasElement(P1).Name,TPasElement(P2).Name);
|
|
end;
|
|
|
|
procedure TLinearWriter.SortElementList(List : TFPList);
|
|
|
|
begin
|
|
List.Sort(@CompareElements);
|
|
end;
|
|
|
|
function TLinearWriter.ShowMember(M: TPasElement): boolean;
|
|
|
|
begin
|
|
Result:=Engine.ShowElement(M);
|
|
end;
|
|
|
|
procedure TLinearWriter.WriteClasses(ASection: TPasSection);
|
|
var
|
|
i: Integer;
|
|
begin
|
|
if (ASection.Classes.Count > 0) then
|
|
for i := 0 to ASection.Classes.Count - 1 do
|
|
WriteClassDecl(TPasClassType(ASection.Classes[i]));
|
|
end;
|
|
|
|
procedure TLinearWriter.WriteExtendedRecords(Asection: TPasSection);
|
|
|
|
var
|
|
i,j : Integer;
|
|
Recdecl : TPasRecordType;
|
|
DocNode : TDocNode;
|
|
Member : TPasElement;
|
|
begin
|
|
if (ASection.Types.Count > 0) then
|
|
for i := 0 to ASection.Types.Count - 1 do
|
|
begin
|
|
If TPasElement(ASection.Types[i]) is TPasRecordType then
|
|
begin
|
|
Recdecl:=TPasRecordType(ASection.Types[i]);
|
|
if RecDecl.IsAdvancedRecord then
|
|
begin
|
|
StartSection(RecDecl.Name);
|
|
DescrBeginParagraph;
|
|
WriteTypeDecl(RecDecl);
|
|
StartListing(False,'');
|
|
DocNode := Engine.FindDocNode(RecDecl);
|
|
If Assigned(DocNode) and
|
|
Assigned(DocNode.Node) and
|
|
(Docnode.Node['opaque']='1') then
|
|
Writeln(RecDecl.Name+' = '+SDocOpaque)
|
|
else
|
|
begin
|
|
Writeln(EscapeText(RecDecl.GetDeclaration(True)));
|
|
end;
|
|
EndListing;
|
|
WriteLabel(RecDecl);
|
|
WriteIndex(RecDecl);
|
|
WriteDescr(RecDecl,DocNode);
|
|
If Assigned(DocNode) and Assigned(DocNode.Version) then
|
|
begin
|
|
Writeln(Format('%s : ',[SDocVersion]));
|
|
WriteDescr(RecDecl, DocNode.Version);
|
|
end;
|
|
if Assigned(DocNode) and assigned(DocNode.Notes) then
|
|
ConvertNotes(RecDecl,DocNode.Notes);
|
|
DescrEndParagraph;
|
|
WriteMethodOverView(Recdecl,Recdecl.Members);
|
|
WritePropertyOverView(Recdecl,Recdecl.Members);
|
|
for J := 0 to Recdecl.Members.Count - 1 do
|
|
begin
|
|
Member := TPasElement(Recdecl.Members[j]);
|
|
if Member.InheritsFrom(TPasProcedureBase) and Engine.ShowElement(Member) then
|
|
WriteProcedure(TPasProcedureBase(Member));
|
|
end;
|
|
for j := 0 to Recdecl.Members.Count - 1 do
|
|
begin
|
|
Member := TPasElement(Recdecl.Members[j]);
|
|
if Member.InheritsFrom(TPasProperty) and Engine.ShowElement(Member) then
|
|
WriteProperty(TPasProperty(Member));
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TLinearWriter.WriteMethodOverview(AParent: TPasType; Members : TFPList);
|
|
|
|
var
|
|
Member : TPasElement;
|
|
i : Integer;
|
|
L,N,S : String;
|
|
DocNode : TDocNode;
|
|
List : TStringList;
|
|
|
|
begin
|
|
List:=TStringList.Create;
|
|
Try
|
|
List.Sorted:=True;
|
|
for i := 0 to Members.Count - 1 do
|
|
begin
|
|
Member := TPasElement(Members[i]);
|
|
With Member do
|
|
if InheritsFrom(TPasProcedureBase) and ShowMember(Member) then
|
|
List.AddObject(Member.Name,Member);
|
|
end;
|
|
If List.Count>0 then
|
|
begin
|
|
StartSubSection(SDocMethodOverview);
|
|
WriteLabel(GetLabel(AParent) + ':Methods');
|
|
StartOverview(SDocMethod,False);
|
|
For I:=0 to List.Count-1 do
|
|
begin
|
|
Member:=TPasElement(List.Objects[i]);
|
|
L:=StripText(GetLabel(Member));
|
|
N:=EscapeText(Member.Name);
|
|
DocNode := Engine.FindDocNode(Member);
|
|
if Assigned(DocNode) and DocNode.IsSkipped then
|
|
Continue;
|
|
If Assigned(DocNode) then
|
|
S:=GetDescrString(Member, DocNode.ShortDescr)
|
|
else
|
|
S:='';
|
|
WriteOverviewMember(L,N,S);
|
|
end;
|
|
EndOverview;
|
|
end;
|
|
Finally
|
|
List.Free;
|
|
end;
|
|
end;
|
|
|
|
|
|
constructor TLinearWriter.Create(APackage: TPasPackage; AEngine: TFPDocEngine);
|
|
|
|
procedure AddLabel(AElement: TPasElement);
|
|
begin
|
|
Engine.AddLink(AElement.PathName, GetLabel(AElement));
|
|
end;
|
|
|
|
procedure AddList(AElement: TPasElement; AList: TFPList);
|
|
var
|
|
i,j: Integer;
|
|
R : TPasRecordType;
|
|
FPEl : TPaselement;
|
|
DocNode: TDocNode;
|
|
|
|
begin
|
|
for i := 0 to AList.Count - 1 do
|
|
begin
|
|
AddLabel(TPasElement(AList[i]));
|
|
if (TObject(AList[i]) is TPasRecordType) then
|
|
begin
|
|
R:=TObject(AList[I]) as TPasRecordType;
|
|
For J:=0 to R.Members.Count-1 do
|
|
begin
|
|
FPEl:=TPasElement(R.Members[J]);
|
|
if ((FPEL is TPasProperty) or (FPEL is TPasProcedureBase))
|
|
and Engine.ShowElement(FPEl) then
|
|
begin
|
|
DocNode := Engine.FindDocNode(FPEl);
|
|
if Assigned(DocNode) then
|
|
AddLabel(FPEl);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure AddTopicPages(AElement: TPasElement);
|
|
|
|
var
|
|
PreviousTopic,
|
|
TopicElement : TTopicElement;
|
|
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);
|
|
Engine.AddLink(TopicElement.PathName, GetLabel(TopicElement));
|
|
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 ScanModule(AModule: TPasModule);
|
|
var
|
|
i, j, k: Integer;
|
|
ClassEl: TPasClassType;
|
|
FPEl, AncestorMemberEl: TPasElement;
|
|
DocNode: TDocNode;
|
|
DidAutolink: Boolean;
|
|
begin
|
|
AddLabel(AModule);
|
|
AddTopicPages(AModule);
|
|
with AModule do
|
|
begin
|
|
AddList(AModule, InterfaceSection.ResStrings);
|
|
AddList(AModule, InterfaceSection.Consts);
|
|
AddList(AModule, InterfaceSection.Types);
|
|
if InterfaceSection.Classes.Count > 0 then
|
|
begin
|
|
for i := 0 to InterfaceSection.Classes.Count - 1 do
|
|
begin
|
|
ClassEl := TPasClassType(InterfaceSection.Classes[i]);
|
|
AddLabel(ClassEl);
|
|
|
|
for j := 0 to ClassEl.Members.Count - 1 do
|
|
begin
|
|
FPEl := TPasElement(ClassEl.Members[j]);
|
|
if Not Engine.ShowElement(FPEl) then
|
|
continue;
|
|
|
|
DocNode := Engine.FindDocNode(FPEl);
|
|
if not Assigned(DocNode) then
|
|
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
|
|
AddLabel(FPEl);
|
|
end else
|
|
AddLabel(FPEl);
|
|
end;
|
|
end;
|
|
end;
|
|
AddList(AModule, InterfaceSection.Functions);
|
|
AddList(AModule, InterfaceSection.Variables);
|
|
end;
|
|
end;
|
|
|
|
var
|
|
i: Integer;
|
|
begin
|
|
inherited ;
|
|
FDupLinkedDoc := False; // by default we don't duplicate linked element documentation
|
|
|
|
{ Allocate labels for all elements for which we are going to create
|
|
documentation. This is needed for links to work correctly. }
|
|
|
|
// Allocate label for the package itself, if a name is given (i.e. <> '#')
|
|
if Length(Package.Name) > 1 then
|
|
begin
|
|
AddLabel(Package);
|
|
AddTopicPages(Package);
|
|
end;
|
|
for i := 0 to Package.Modules.Count - 1 do
|
|
ScanModule(TPasModule(Package.Modules[i]));
|
|
end;
|
|
|
|
procedure TLinearWriter.WriteBeginDocument;
|
|
|
|
begin
|
|
WriteComment('This file has been created automatically by FPDoc.');
|
|
WriteComment('Linear output (c) 2005 Michael Van Canneyt');
|
|
end;
|
|
|
|
procedure TLinearWriter.WriteEndDocument;
|
|
begin
|
|
// do nothing
|
|
end;
|
|
|
|
function TLinearWriter.EscapeText(S: UnicodeString): AnsiString;
|
|
begin
|
|
Result:=EscapeText(UTF8Encode(S));
|
|
end;
|
|
|
|
function TLinearWriter.InterpretOption(const Cmd, Arg: String): Boolean;
|
|
begin
|
|
Result := True;
|
|
if Cmd = cDupLinkedDocParam then
|
|
begin
|
|
FDupLinkedDoc := True;
|
|
end
|
|
else
|
|
Result := False;
|
|
end;
|
|
|
|
class procedure TLinearWriter.Usage(List: TStrings);
|
|
begin
|
|
List.Add(cDupLinkedDocParam);
|
|
List.Add(SLinearUsageDupLinkedDocsP1);
|
|
List.Add('');
|
|
List.Add(SLinearUsageDupLinkedDocsP2);
|
|
end;
|
|
|
|
|
|
end.
|
|
|