Browse Source

--- Merging r15345 into '.':
U utils/fpdoc/fpdoc.css
U utils/fpdoc/dw_html.pp
--- Merging r15794 into '.':
G utils/fpdoc/dw_html.pp
U packages/fcl-passrc/src/pastree.pp
U packages/fcl-passrc/src/pparser.pp
--- Merging r15796 into '.':
G utils/fpdoc/dw_html.pp
--- Merging r15797 into '.':
U utils/fpdoc/dglobals.pp
U utils/fpdoc/fpdoc.pp
--- Merging r15803 into '.':
G utils/fpdoc/dw_html.pp
--- Merging r15809 into '.':
G packages/fcl-passrc/src/pastree.pp
G packages/fcl-passrc/src/pparser.pp
--- Merging r15825 into '.':
G utils/fpdoc/dglobals.pp
--- Merging r15849 into '.':
U utils/fpdoc/dwlinear.pp
U utils/fpdoc/dw_latex.pp
U utils/fpdoc/dw_txt.pp
A utils/fpdoc/dw_ipflin.pas
G utils/fpdoc/dglobals.pp
U utils/fpdoc/dw_linrtf.pp
G utils/fpdoc/fpdoc.pp
D utils/fpdoc/dw_ipf.pp
--- Merging r15866 into '.':
G utils/fpdoc/dglobals.pp
--- Merging r15867 into '.':
G utils/fpdoc/dglobals.pp
--- Merging r15868 into '.':
G utils/fpdoc/dglobals.pp
G packages/fcl-passrc/src/pparser.pp
--- Merging r15875 into '.':
G utils/fpdoc/dw_html.pp
--- Merging r15877 into '.':
U packages/fcl-passrc/src/pscanner.pp
G packages/fcl-passrc/src/pparser.pp
--- Merging r15897 into '.':
U packages/chm/src/chmls.lpr
U packages/chm/src/chmsitemap.pas
--- Merging r15902 into '.':
G packages/fcl-passrc/src/pastree.pp
G packages/fcl-passrc/src/pparser.pp
--- Merging r15903 into '.':
G packages/fcl-passrc/src/pastree.pp
G packages/fcl-passrc/src/pparser.pp
--- Merging r15909 into '.':
G packages/fcl-passrc/src/pastree.pp
G packages/fcl-passrc/src/pparser.pp
--- Merging r15910 into '.':
G utils/fpdoc/dglobals.pp
U utils/fpdoc/fpdoc.lpi
--- Merging r15981 into '.':
G packages/fcl-passrc/src/pastree.pp
G packages/fcl-passrc/src/pparser.pp

# revisions: 15345,15794,15796,15797,15803,15809,15825,15849,15866,15867,15868,15875,15877,15897,15902,15903,15909,15910,15981,
------------------------------------------------------------------------
r15345 | michael | 2010-05-30 15:44:20 +0200 (Sun, 30 May 2010) | 1 line
Changed paths:
M /trunk/utils/fpdoc/dw_html.pp
M /trunk/utils/fpdoc/fpdoc.css

* Patch from Nikolay Nikolov to fix compliance mode rendering
------------------------------------------------------------------------
------------------------------------------------------------------------
r15794 | marco | 2010-08-13 12:19:54 +0200 (Fri, 13 Aug 2010) | 2 lines
Changed paths:
M /trunk/packages/fcl-passrc/src/pastree.pp
M /trunk/packages/fcl-passrc/src/pparser.pp
M /trunk/utils/fpdoc/dw_html.pp

* list interfaces in html declaration

------------------------------------------------------------------------
------------------------------------------------------------------------
r15796 | marco | 2010-08-13 14:29:27 +0200 (Fri, 13 Aug 2010) | 2 lines
Changed paths:
M /trunk/utils/fpdoc/dw_html.pp

* make interfaces clickable.

------------------------------------------------------------------------
------------------------------------------------------------------------
r15797 | marco | 2010-08-13 14:39:10 +0200 (Fri, 13 Aug 2010) | 2 lines
Changed paths:
M /trunk/utils/fpdoc/dglobals.pp
M /trunk/utils/fpdoc/fpdoc.pp

* --parse-impl option for testing.

------------------------------------------------------------------------
------------------------------------------------------------------------
r15803 | marco | 2010-08-14 00:34:42 +0200 (Sat, 14 Aug 2010) | 3 lines
Changed paths:
M /trunk/utils/fpdoc/dw_html.pp

* while searching for ancestor classes/interfaces after all USES unit
also search unit system.

------------------------------------------------------------------------
------------------------------------------------------------------------
r15809 | marco | 2010-08-14 16:18:43 +0200 (Sat, 14 Aug 2010) | 2 lines
Changed paths:
M /trunk/packages/fcl-passrc/src/pastree.pp
M /trunk/packages/fcl-passrc/src/pparser.pp

* unit implicit first in uses clause

------------------------------------------------------------------------
------------------------------------------------------------------------
r15825 | marco | 2010-08-16 05:22:39 +0200 (Mon, 16 Aug 2010) | 3 lines
Changed paths:
M /trunk/utils/fpdoc/dglobals.pp

* stuff interface implementation data into contentfile.
Inheritance data is ignored but not processed while reading atm.

------------------------------------------------------------------------
------------------------------------------------------------------------
r15849 | marco | 2010-08-19 06:26:26 +0200 (Thu, 19 Aug 2010) | 25 lines
Changed paths:
M /trunk/utils/fpdoc/dglobals.pp
D /trunk/utils/fpdoc/dw_ipf.pp
A /trunk/utils/fpdoc/dw_ipflin.pas
M /trunk/utils/fpdoc/dw_latex.pp
M /trunk/utils/fpdoc/dw_linrtf.pp
M /trunk/utils/fpdoc/dw_txt.pp
M /trunk/utils/fpdoc/dwlinear.pp
M /trunk/utils/fpdoc/fpdoc.pp

o commit patch from Mantis 17191:
* Patch with new linear based IPF writer
* patch for Interfaces Overview in all Linear writers
* patch with new Linear Writer specific parameter to control
if linked documentation should be duplicated or not.
new parameter is: --duplinkeddoc
Default is that linked docs are not duplicated.
* patch for fixing minor spelling mistakes in fpdoc
* patch to not create a section Errors if there isn't actually
any specific documentation for errors. makeskel generates error
nodes but most don't have any items. This caused an Errors title
in the docs, but with no content.
* patch to fix SeeAlso section in Linear writer. It never output
the custom text, but always the node link as text.
* new features for linear writer that could be overridden in
descendants.
- marked some protected methods as virtual so it can be overridden
in descendants for customization.
- new section for listing Types found in a unit. Default does nothing,
except in IPF writer.
- new section for listing Variables found in a unit. Default does
nothing, except in IPF writer.
- new section for listing Constants found in a unit. Default does
nothing, except in IPF writer.

------------------------------------------------------------------------
------------------------------------------------------------------------
r15866 | marco | 2010-08-21 18:25:57 +0200 (Sat, 21 Aug 2010) | 2 lines
Changed paths:
M /trunk/utils/fpdoc/dglobals.pp

* Fix implicit inheritance in writing of content file.

------------------------------------------------------------------------
------------------------------------------------------------------------
r15867 | marco | 2010-08-21 22:47:31 +0200 (Sat, 21 Aug 2010) | 3 lines
Changed paths:
M /trunk/utils/fpdoc/dglobals.pp

* Load inheritance info from content file. Inheritance diagrams now work
reasonably well over package bounderies.

------------------------------------------------------------------------
------------------------------------------------------------------------
r15868 | marco | 2010-08-21 23:12:27 +0200 (Sat, 21 Aug 2010) | 2 lines
Changed paths:
M /trunk/packages/fcl-passrc/src/pparser.pp
M /trunk/utils/fpdoc/dglobals.pp

* minor hint and warning improvements

------------------------------------------------------------------------
------------------------------------------------------------------------
r15875 | marco | 2010-08-22 16:46:03 +0200 (Sun, 22 Aug 2010) | 2 lines
Changed paths:
M /trunk/utils/fpdoc/dw_html.pp

* print also interfaces in inheritance section, fixes 15774

------------------------------------------------------------------------
------------------------------------------------------------------------
r15877 | michael | 2010-08-23 09:42:42 +0200 (Mon, 23 Aug 2010) | 1 line
Changed paths:
M /trunk/packages/fcl-passrc/src/pparser.pp
M /trunk/packages/fcl-passrc/src/pscanner.pp

* Patch from Graeme Geldenhuys (bug 17237) extending scanner to report EOL and TAB
------------------------------------------------------------------------
------------------------------------------------------------------------
r15897 | marco | 2010-08-24 22:27:30 +0200 (Tue, 24 Aug 2010) | 2 lines
Changed paths:
M /trunk/packages/chm/src/chmls.lpr
M /trunk/packages/chm/src/chmsitemap.pas

* extracttoc/extractbinary

------------------------------------------------------------------------
------------------------------------------------------------------------
r15902 | dmitry | 2010-08-25 15:22:38 +0200 (Wed, 25 Aug 2010) | 1 line
Changed paths:
M /trunk/packages/fcl-passrc/src/pastree.pp
M /trunk/packages/fcl-passrc/src/pparser.pp

passrc: initial program parsing. Fixed PasExpr constructor warnings. Added initial labels parsing
------------------------------------------------------------------------
------------------------------------------------------------------------
r15903 | dmitry | 2010-08-25 15:55:24 +0200 (Wed, 25 Aug 2010) | 1 line
Changed paths:
M /trunk/packages/fcl-passrc/src/pastree.pp
M /trunk/packages/fcl-passrc/src/pparser.pp

passrc: added parsing label marks in the code blocks
------------------------------------------------------------------------
------------------------------------------------------------------------
r15909 | dmitry | 2010-08-26 10:10:54 +0200 (Thu, 26 Aug 2010) | 1 line
Changed paths:
M /trunk/packages/fcl-passrc/src/pastree.pp
M /trunk/packages/fcl-passrc/src/pparser.pp

passrc: improve parsing code statements. TPasImplCommand replaced by actual simple or assignment. Small fix for the expression parser to handle dot separated identifier
------------------------------------------------------------------------
------------------------------------------------------------------------
r15910 | michael | 2010-08-26 16:40:20 +0200 (Thu, 26 Aug 2010) | 1 line
Changed paths:
M /trunk/utils/fpdoc/dglobals.pp
M /trunk/utils/fpdoc/fpdoc.lpi

* Applied patch from Graeme to fix link resolving (17276)
------------------------------------------------------------------------
------------------------------------------------------------------------
r15981 | michael | 2010-09-14 13:15:21 +0200 (Tue, 14 Sep 2010) | 1 line
Changed paths:
M /trunk/packages/fcl-passrc/src/pastree.pp
M /trunk/packages/fcl-passrc/src/pparser.pp

* Procedure body is now reachable (and assigned). (patch from [email protected])
------------------------------------------------------------------------

git-svn-id: branches/fixes_2_4@16369 -

marco 14 years ago
parent
commit
27680ec448

+ 1 - 1
.gitattributes

@@ -10509,7 +10509,7 @@ utils/fpdoc/dglobals.pp svneol=native#text/plain
 utils/fpdoc/dw_dxml.pp svneol=native#text/plain
 utils/fpdoc/dw_dxml.pp svneol=native#text/plain
 utils/fpdoc/dw_html.pp svneol=native#text/plain
 utils/fpdoc/dw_html.pp svneol=native#text/plain
 utils/fpdoc/dw_htmlchm.inc svneol=native#text/plain
 utils/fpdoc/dw_htmlchm.inc svneol=native#text/plain
-utils/fpdoc/dw_ipf.pp svneol=native#text/plain
+utils/fpdoc/dw_ipflin.pas svneol=native#text/plain
 utils/fpdoc/dw_latex.pp svneol=native#text/plain
 utils/fpdoc/dw_latex.pp svneol=native#text/plain
 utils/fpdoc/dw_linrtf.pp svneol=native#text/plain
 utils/fpdoc/dw_linrtf.pp svneol=native#text/plain
 utils/fpdoc/dw_lintmpl.pp svneol=native#text/plain
 utils/fpdoc/dw_lintmpl.pp svneol=native#text/plain

+ 57 - 5
packages/chm/src/chmls.lpr

@@ -28,7 +28,7 @@ program chmls;
 
 
 uses
 uses
   Classes, GetOpts, SysUtils, Types,
   Classes, GetOpts, SysUtils, Types,
-  chmreader, chmbase;
+  chmreader, chmbase, chmsitemap;
 
 
 type
 type
 
 
@@ -50,10 +50,10 @@ type
   end;
   end;
 
 
 
 
-  TCmdEnum = (cmdList,cmdExtract,cmdExtractall,cmdUnblock,cmdextractalias,cmdNone);        // One dummy element at the end avoids rangecheck errors.
+  TCmdEnum = (cmdList,cmdExtract,cmdExtractall,cmdUnblock,cmdextractalias,cmdextracttoc,cmdextractindex,cmdNone);        // One dummy element at the end avoids rangecheck errors.
 
 
 Const
 Const
-  CmdNames : array [TCmdEnum] of String = ('LIST','EXTRACT','EXTRACTALL','UNBLOCK','EXTRACTALIAS','');
+  CmdNames : array [TCmdEnum] of String = ('LIST','EXTRACT','EXTRACTALL','UNBLOCK','EXTRACTALIAS','EXTRACTTOC','EXTRACTINDEX','');
 
 
 var
 var
   theopts : array[1..4] of TOption;
   theopts : array[1..4] of TOption;
@@ -85,7 +85,10 @@ begin
   writeln(stderr,'            Extracts context info from file "chmfilename" ');
   writeln(stderr,'            Extracts context info from file "chmfilename" ');
   writeln(stderr,'            to a "basefilename".h and "basefilename".ali,');
   writeln(stderr,'            to a "basefilename".h and "basefilename".ali,');
   writeln(stderr,'            using symbols "symbolprefix"contextnr');
   writeln(stderr,'            using symbols "symbolprefix"contextnr');
-
+  writeln(stderr,' extracttoc <chmfilename> [filename]');
+  writeln(stderr,'            Extracts the toc (mainly to check binary TOC)');
+  writeln(stderr,' extractindex <chmfilename> [filename]');
+  writeln(stderr,'            Extracts the index (mainly to check binary index)');
   Halt(1);
   Halt(1);
 end;
 end;
 
 
@@ -450,11 +453,48 @@ begin
  Files.Free;
  Files.Free;
 end;
 end;
 
 
+const 
+   siteext : array[TSiteMapType] of string = ('.hhc','.hhk');
+
+procedure extracttocindex(filespec:TStringDynArray;sttype:TSiteMapType);
+var s,
+    chm,
+    extractfn     : string;
+    i,cnt: integer;
+    cl : TList;
+    f : textfile;
+    fs: TFileStream;
+    r : TChmReader;
+    x : TCHMSitemap;
+begin
+  chm:=filespec[0];
+  extractfn:=changefileext(chm,siteext[sttype]);
+  if length(filespec)>1 then
+    extractfn:=filespec[1];
+
+  if not Fileexists(chm) then
+    begin
+      writeln(stderr,' Can''t find file ',chm);
+      halt(1);
+    end;
+  fs:=TFileStream.create(chm,fmOpenRead);
+  r:=TCHMReader.create(fs,true);
+  case sttype of
+   stindex: x:=r.GetIndexSitemap(false);
+   sttoc : x:=r.gettocsitemap(false);
+  end;
+  if assigned(x) then
+   begin
+     x.savetofile( extractfn);
+     x.free;
+   end;
+  r.free;
+end;
+
 procedure buildarglist(var params: TStringDynArray;var cmd :TCmdEnum);
 procedure buildarglist(var params: TStringDynArray;var cmd :TCmdEnum);
 
 
 var s           : ansistring;
 var s           : ansistring;
     j,k         : Integer;
     j,k         : Integer;
-
 begin
 begin
   s:=uppercase(paramstr(optind));
   s:=uppercase(paramstr(optind));
   cmd:=Low(TCMDEnum);
   cmd:=Low(TCMDEnum);
@@ -564,6 +604,18 @@ begin
                         else
                         else
                           WrongNrParam(cmdnames[cmd],length(localparams));
                           WrongNrParam(cmdnames[cmd],length(localparams));
                        end;
                        end;
+       cmdextracttoc : begin
+                        if length(localparams)>0 then
+                          extracttocindex(localparams,sttoc)
+                        else
+                          WrongNrParam(cmdnames[cmd],length(localparams));
+                       end;
+       cmdextractindex: begin
+                        if length(localparams)>0 then
+                          extracttocindex(localparams,stindex)
+	                        else
+                          WrongNrParam(cmdnames[cmd],length(localparams));
+                       end;
       end; {case cmd of}
       end; {case cmd of}
   end
   end
  else
  else

+ 13 - 0
packages/chm/src/chmsitemap.pas

@@ -135,6 +135,7 @@ type
     destructor Destroy; override;
     destructor Destroy; override;
     procedure LoadFromFile(AFileName: String);
     procedure LoadFromFile(AFileName: String);
     procedure LoadFromStream(AStream: TStream);
     procedure LoadFromStream(AStream: TStream);
+    procedure SaveToFile(AFileName:String);
     procedure SaveToStream(AStream: TStream);
     procedure SaveToStream(AStream: TStream);
     property Items: TChmSiteMapItems read FItems write SetItems;
     property Items: TChmSiteMapItems read FItems write SetItems;
     property SiteMapType: TSiteMapType read FSiteMapType;
     property SiteMapType: TSiteMapType read FSiteMapType;
@@ -334,6 +335,18 @@ begin
   end;
   end;
 end;
 end;
 
 
+procedure TChmSiteMap.SaveToFile(AFileName:String);
+var
+  fs : TFileStream;
+begin
+  fs:=TFileStream.Create(AFileName,fmcreate);
+  try
+    SaveToStream(fs);
+  finally
+    fs.free;
+    end;
+end;
+                    
 procedure TChmSiteMap.SaveToStream(AStream: TStream);
 procedure TChmSiteMap.SaveToStream(AStream: TStream);
 var
 var
   Indent: Integer;
   Indent: Integer;

+ 95 - 10
packages/fcl-passrc/src/pastree.pp

@@ -138,12 +138,12 @@ type
   TPasExpr = class(TPasElement)
   TPasExpr = class(TPasElement)
     Kind      : TPasExprKind;
     Kind      : TPasExprKind;
     OpCode    : TexprOpcode;
     OpCode    : TexprOpcode;
-    constructor Create(AParent : TPasElement; AKind: TPasExprKind; AOpCode: TexprOpcode);
+    constructor Create(AParent : TPasElement; AKind: TPasExprKind; AOpCode: TexprOpcode); virtual; overload;
   end;
   end;
 
 
   TUnaryExpr = class(TPasExpr)
   TUnaryExpr = class(TPasExpr)
     Operand   : TPasExpr;
     Operand   : TPasExpr;
-    constructor Create(AParent : TPasElement; AOperand: TPasExpr; AOpCode: TExprOpCode);
+    constructor Create(AParent : TPasElement; AOperand: TPasExpr; AOpCode: TExprOpCode); overload;
     function GetDeclaration(full : Boolean) : string; override;
     function GetDeclaration(full : Boolean) : string; override;
     destructor Destroy; override;
     destructor Destroy; override;
   end;
   end;
@@ -153,28 +153,28 @@ type
   TBinaryExpr = class(TPasExpr)
   TBinaryExpr = class(TPasExpr)
     left      : TPasExpr;
     left      : TPasExpr;
     right     : TPasExpr;
     right     : TPasExpr;
-    constructor Create(AParent : TPasElement; xleft, xright: TPasExpr; AOpCode: TExprOpCode);
-    constructor CreateRange(AParent : TPasElement; xleft, xright: TPasExpr);
+    constructor Create(AParent : TPasElement; xleft, xright: TPasExpr; AOpCode: TExprOpCode); overload;
+    constructor CreateRange(AParent : TPasElement; xleft, xright: TPasExpr); overload;
     function GetDeclaration(full : Boolean) : string; override;
     function GetDeclaration(full : Boolean) : string; override;
     destructor Destroy; override;
     destructor Destroy; override;
   end;
   end;
 
 
   TPrimitiveExpr = class(TPasExpr)
   TPrimitiveExpr = class(TPasExpr)
     Value     : AnsiString;
     Value     : AnsiString;
-    constructor Create(AParent : TPasElement; AKind: TPasExprKind; const AValue : Ansistring);
+    constructor Create(AParent : TPasElement; AKind: TPasExprKind; const AValue : Ansistring); overload;
     function GetDeclaration(full : Boolean) : string; override;
     function GetDeclaration(full : Boolean) : string; override;
   end;
   end;
   
   
   TBoolConstExpr = class(TPasExpr)
   TBoolConstExpr = class(TPasExpr)
     Value     : Boolean;
     Value     : Boolean;
-    constructor Create(AParent : TPasElement; AKind: TPasExprKind; const ABoolValue : Boolean);
+    constructor Create(AParent : TPasElement; AKind: TPasExprKind; const ABoolValue : Boolean); overload;
     function GetDeclaration(full : Boolean) : string; override;
     function GetDeclaration(full : Boolean) : string; override;
   end;
   end;
 
 
   { TNilExpr }
   { TNilExpr }
 
 
   TNilExpr = class(TPasExpr)
   TNilExpr = class(TPasExpr)
-    constructor Create(AParent : TPasElement);
+    constructor Create(AParent : TPasElement); overload;
     function GetDeclaration(full : Boolean) : string; override;
     function GetDeclaration(full : Boolean) : string; override;
   end;
   end;
 
 
@@ -184,7 +184,7 @@ type
     Value     : TPasExpr;
     Value     : TPasExpr;
     Params    : array of TPasExpr;
     Params    : array of TPasExpr;
     {pekArray, pekFuncCall, pekSet}
     {pekArray, pekFuncCall, pekSet}
-    constructor Create(AParent : TPasElement; AKind: TPasExprKind);
+    constructor Create(AParent : TPasElement; AKind: TPasExprKind); overload;
     function GetDeclaration(full : Boolean) : string; override;
     function GetDeclaration(full : Boolean) : string; override;
     destructor Destroy; override;
     destructor Destroy; override;
     procedure AddParam(xp: TPasExpr);
     procedure AddParam(xp: TPasExpr);
@@ -199,7 +199,7 @@ type
 
 
   TRecordValues = class(TPasExpr)
   TRecordValues = class(TPasExpr)
     Fields    : array of TRecordValuesItem;
     Fields    : array of TRecordValuesItem;
-    constructor Create(AParent : TPasElement);
+    constructor Create(AParent : TPasElement); overload;
     destructor Destroy; override;
     destructor Destroy; override;
     procedure AddField(const AName: AnsiString; Value: TPasExpr);
     procedure AddField(const AName: AnsiString; Value: TPasExpr);
     function GetDeclaration(full : Boolean) : string; override;
     function GetDeclaration(full : Boolean) : string; override;
@@ -209,7 +209,7 @@ type
 
 
   TArrayValues = class(TPasExpr)
   TArrayValues = class(TPasExpr)
     Values    : array of TPasExpr;
     Values    : array of TPasExpr;
-    constructor Create(AParent : TPasElement);
+    constructor Create(AParent : TPasElement); overload;
     destructor Destroy; override;
     destructor Destroy; override;
     procedure AddValues(AValue: TPasExpr);
     procedure AddValues(AValue: TPasExpr);
     function GetDeclaration(full : Boolean) : string; override;
     function GetDeclaration(full : Boolean) : string; override;
@@ -248,6 +248,9 @@ type
   TImplementationSection = class(TPasSection)
   TImplementationSection = class(TPasSection)
   end;
   end;
 
 
+  TProgramSection = class(TPasSection)
+  end;
+
   TInitializationSection = class;
   TInitializationSection = class;
   TFinalizationSection = class;
   TFinalizationSection = class;
 
 
@@ -267,6 +270,10 @@ type
     Filename   : String;  // the IN filename, only written when not empty.
     Filename   : String;  // the IN filename, only written when not empty.
   end;
   end;
 
 
+  { TPasProgram }
+
+  TPasProgram = class(TPasModule);
+
   { TPasPackage }
   { TPasPackage }
 
 
   TPasPackage = class(TPasElement)
   TPasPackage = class(TPasElement)
@@ -452,6 +459,7 @@ type
 
 
     ClassVars: TList;   // class vars
     ClassVars: TList;   // class vars
     Modifiers: TStringList;
     Modifiers: TStringList;
+    Interfaces : TList;
   end;
   end;
 
 
   TArgumentAccess = (argDefault, argConst, argVar, argOut);
   TArgumentAccess = (argDefault, argConst, argVar, argOut);
@@ -587,6 +595,8 @@ type
   TProcedureModifiers = Set of TProcedureModifier;
   TProcedureModifiers = Set of TProcedureModifier;
   TProcedureMessageType = (pmtInteger,pmtString);
   TProcedureMessageType = (pmtInteger,pmtString);
                         
                         
+  TProcedureBody = class;
+
   TPasProcedure = class(TPasProcedureBase)
   TPasProcedure = class(TPasProcedureBase)
   Private
   Private
     FCallingConvention : TCallingConvention;
     FCallingConvention : TCallingConvention;
@@ -601,6 +611,7 @@ type
     procedure GetModifiers(List: TStrings);
     procedure GetModifiers(List: TStrings);
   public
   public
     ProcType : TPasProcedureType;
     ProcType : TPasProcedureType;
+    Body : TProcedureBody;
     Procedure AddModifier(AModifier : TProcedureModifier);
     Procedure AddModifier(AModifier : TProcedureModifier);
     Function IsVirtual : Boolean;
     Function IsVirtual : Boolean;
     Function IsDynamic : Boolean;
     Function IsDynamic : Boolean;
@@ -732,6 +743,15 @@ type
     Commands: TStrings;
     Commands: TStrings;
   end;
   end;
 
 
+  { TPasLabels }
+
+  TPasLabels = class(TPasImplElement)
+  public
+    Labels  : TStrings;
+    constructor Create(const AName: string; AParent: TPasElement); override;
+    destructor Destroy; override;
+  end;
+
   TPasImplBeginBlock = class;
   TPasImplBeginBlock = class;
   TPasImplRepeatUntil = class;
   TPasImplRepeatUntil = class;
   TPasImplIfElse = class;
   TPasImplIfElse = class;
@@ -742,6 +762,9 @@ type
   TPasImplTry = class;
   TPasImplTry = class;
   TPasImplExceptOn = class;
   TPasImplExceptOn = class;
   TPasImplRaise = class;
   TPasImplRaise = class;
+  TPasImplAssign = class;
+  TPasImplSimple = class;
+  TPasImplLabelMark = class;
 
 
   { TPasImplBlock }
   { TPasImplBlock }
 
 
@@ -765,6 +788,9 @@ type
     function AddTry: TPasImplTry;
     function AddTry: TPasImplTry;
     function AddExceptOn(const VarName, TypeName: string): TPasImplExceptOn;
     function AddExceptOn(const VarName, TypeName: string): TPasImplExceptOn;
     function AddRaise: TPasImplRaise;
     function AddRaise: TPasImplRaise;
+    function AddLabelMark(const Id: string): TPasImplLabelMark;
+    function AddAssign(left, right: TPasExpr): TPasImplAssign;
+    function AddSimple(exp: TPasExpr): TPasImplSimple;
     function CloseOnSemicolon: boolean; virtual;
     function CloseOnSemicolon: boolean; virtual;
   public
   public
     Elements: TList;    // TPasImplElement objects
     Elements: TList;    // TPasImplElement objects
@@ -883,6 +909,21 @@ type
     Body: TPasImplElement;
     Body: TPasImplElement;
   end;
   end;
 
 
+  { TPasImplAssign }
+
+  TPasImplAssign = class (TPasImplStatement)
+  public
+    left  : TPasExpr;
+    right : TPasExpr;
+  end;
+
+  { TPasImplSimple }
+
+  TPasImplSimple = class (TPasImplStatement)
+  public
+    expr  : TPasExpr;
+  end;
+
   TPasImplTryHandler = class;
   TPasImplTryHandler = class;
   TPasImplTryFinally = class;
   TPasImplTryFinally = class;
   TPasImplTryExcept = class;
   TPasImplTryExcept = class;
@@ -941,6 +982,11 @@ type
     procedure Visit(obj: TPasElement); virtual;
     procedure Visit(obj: TPasElement); virtual;
   end;
   end;
 
 
+  TPasImplLabelMark = class(TPasImplElement)
+  public
+    LabelId:  AnsiString;
+  end;
+
 const
 const
   AccessNames: array[TArgumentAccess] of string[6] = ('', 'const ', 'var ', 'out ');
   AccessNames: array[TArgumentAccess] of string[6] = ('', 'const ', 'var ', 'out ');
   AllVisibilities: TPasMemberVisibilities =
   AllVisibilities: TPasMemberVisibilities =
@@ -1303,6 +1349,7 @@ begin
   Members := TList.Create;
   Members := TList.Create;
   Modifiers := TStringList.Create;
   Modifiers := TStringList.Create;
   ClassVars := TList.Create;
   ClassVars := TList.Create;
+  Interfaces:= TList.Create;
 end;
 end;
 
 
 destructor TPasClassType.Destroy;
 destructor TPasClassType.Destroy;
@@ -1316,6 +1363,7 @@ begin
     AncestorType.Release;
     AncestorType.Release;
   Modifiers.Free;
   Modifiers.Free;
   ClassVars.Free;
   ClassVars.Free;
+  Interfaces.Free;
   inherited Destroy;
   inherited Destroy;
 end;
 end;
 
 
@@ -1442,6 +1490,8 @@ destructor TPasProcedure.Destroy;
 begin
 begin
   if Assigned(ProcType) then
   if Assigned(ProcType) then
     ProcType.Release;
     ProcType.Release;
+  if Assigned(Body) then
+    Body.Release;
   inherited Destroy;
   inherited Destroy;
 end;
 end;
 
 
@@ -1662,6 +1712,26 @@ begin
   AddElement(Result);
   AddElement(Result);
 end;
 end;
 
 
+function TPasImplBlock.AddLabelMark(const Id: string): TPasImplLabelMark;
+begin
+  Result:=TPasImplLabelMark.Create('', Self);
+  Result.LabelId:=Id;
+  AddElement(Result);
+end;
+
+function TPasImplBlock.AddAssign(left,right:TPasExpr):TPasImplAssign;
+begin
+  Result:=TPasImplAssign.Create('', Self);
+  Result.left:=left;
+  Result.right:=right;
+end;
+
+function TPasImplBlock.AddSimple(exp:TPasExpr):TPasImplSimple;
+begin
+  Result:=TPasImplSimple.Create('', Self);
+  Result.expr:=exp;
+end;
+
 function TPasImplBlock.CloseOnSemicolon: boolean;
 function TPasImplBlock.CloseOnSemicolon: boolean;
 begin
 begin
   Result:=false;
   Result:=false;
@@ -2416,6 +2486,7 @@ end;
 
 
 constructor TPasExpr.Create(AParent : TPasElement; AKind: TPasExprKind; AOpCode: TexprOpcode);
 constructor TPasExpr.Create(AParent : TPasElement; AKind: TPasExprKind; AOpCode: TexprOpcode);
 begin
 begin
+  Create(ClassName, AParent);
   Kind:=AKind;
   Kind:=AKind;
   OpCode:=AOpCode;
   OpCode:=AOpCode;
 end;
 end;
@@ -2639,4 +2710,18 @@ begin
   inherited Create(AParent,pekNil, eopNone);
   inherited Create(AParent,pekNil, eopNone);
 end;
 end;
 
 
+{ TPasLabels }
+
+constructor TPasLabels.Create(const AName:string;AParent:TPasElement);
+begin
+  inherited Create(AName,AParent);
+  Labels := TStringList.Create;
+end;
+
+destructor TPasLabels.Destroy;
+begin
+  Labels.Free;
+  inherited Destroy;
+end;
+
 end.
 end.

+ 111 - 25
packages/fcl-passrc/src/pparser.pp

@@ -92,16 +92,18 @@ uses Classes;
 var
 var
   IsIdentStart: array[char] of boolean;
   IsIdentStart: array[char] of boolean;
 
 
-type
+const
+  WhitespaceTokensToIgnore = [tkWhitespace, tkComment, tkLineEnding, tkTab];
 
 
+type
   TDeclType = (declNone, declConst, declResourcestring, declType, declVar, declThreadvar, declProperty);
   TDeclType = (declNone, declConst, declResourcestring, declType, declVar, declThreadvar, declProperty);
 
 
   TProcType = (ptProcedure, ptFunction, ptOperator, ptConstructor, ptDestructor,
   TProcType = (ptProcedure, ptFunction, ptOperator, ptConstructor, ptDestructor,
                ptClassProcedure, ptClassFunction);
                ptClassProcedure, ptClassFunction);
 
 
                
                
-  TExprKind = (ek_Normal, ek_PropertyIndex);               
-               
+  TExprKind = (ek_Normal, ek_PropertyIndex);
+
   { TPasParser }
   { TPasParser }
 
 
   TPasParser = class
   TPasParser = class
@@ -158,6 +160,7 @@ type
 
 
     procedure ParseMain(var Module: TPasModule);
     procedure ParseMain(var Module: TPasModule);
     procedure ParseUnit(var Module: TPasModule);
     procedure ParseUnit(var Module: TPasModule);
+    procedure ParseProgram(var Module: TPasModule);
     procedure ParseInterface;
     procedure ParseInterface;
     procedure ParseImplementation;
     procedure ParseImplementation;
     procedure ParseInitialization;
     procedure ParseInitialization;
@@ -184,6 +187,7 @@ type
     procedure ParseProcBeginBlock(Parent: TProcedureBody);
     procedure ParseProcBeginBlock(Parent: TProcedureBody);
     procedure ParseStatement(Parent: TPasImplBlock;
     procedure ParseStatement(Parent: TPasImplBlock;
                              out NewImplElement: TPasImplElement);
                              out NewImplElement: TPasImplElement);
+    procedure ParseLabels(AParent: TPasElement);
 
 
     property FileResolver: TFileResolver read FFileResolver;
     property FileResolver: TFileResolver read FFileResolver;
     property Scanner: TPascalScanner read FScanner;
     property Scanner: TPascalScanner read FScanner;
@@ -291,7 +295,7 @@ begin
     try
     try
       repeat
       repeat
         FCurToken := Scanner.FetchToken;
         FCurToken := Scanner.FetchToken;
-      until not (FCurToken in [tkWhitespace, tkComment]);
+      until not (FCurToken in WhitespaceTokensToIgnore);
     except
     except
       on e: EScannerError do
       on e: EScannerError do
         raise EParserError.Create(e.Message,
         raise EParserError.Create(e.Message,
@@ -929,6 +933,13 @@ begin
           x:=DoParseExpression(AParent);
           x:=DoParseExpression(AParent);
           if CurToken<>tkBraceClose then Exit;
           if CurToken<>tkBraceClose then Exit;
           NextToken;
           NextToken;
+
+          // for the expression like  (TObject(m)).Free;
+          if CurToken = tkDot then begin
+            NextToken;
+            x:=TBinaryExpr.Create(AParent,x, ParseExpIdent(AParent), TokenToExprOp(tkDot));
+          end;
+
         end else begin
         end else begin
           x:=ParseExpIdent(AParent);
           x:=ParseExpIdent(AParent);
         end;
         end;
@@ -1224,6 +1235,7 @@ begin
   NextToken;
   NextToken;
   case CurToken of
   case CurToken of
     tkUnit: ParseUnit(Module);
     tkUnit: ParseUnit(Module);
+    tkProgram: ParseProgram(Module);
     else
     else
       ParseExc(Format(SParserExpectTokenError, ['unit']));
       ParseExc(Format(SParserExpectTokenError, ['unit']));
   end;
   end;
@@ -1251,6 +1263,26 @@ begin
   end;
   end;
 end;
 end;
 
 
+// Starts after the "program" token
+procedure TPasParser.ParseProgram(var Module: TPasModule);
+begin
+  Module := nil;
+  Module := TPasModule(CreateElement(TPasProgram, ExpectIdentifier,
+    Engine.Package));
+  CurModule:=Module;
+  try
+    if Assigned(Engine.Package) then
+    begin
+      Module.PackageName := Engine.Package.Name;
+      Engine.Package.Modules.Add(Module);
+    end;
+    NextToken;
+    ParseImplementation;
+  finally
+    CurModule:=nil;
+  end;
+end;
+
 // Starts after the "interface" token
 // Starts after the "interface" token
 procedure TPasParser.ParseInterface;
 procedure TPasParser.ParseInterface;
 var
 var
@@ -1535,7 +1567,12 @@ begin
           end
           end
         else
         else
           ParseExc(SParserSyntaxError);
           ParseExc(SParserSyntaxError);
-        end
+        end;
+      tklabel:
+        begin
+          if not (Declarations is TInterfaceSection) then
+            ParseLabels(Declarations);
+        end;
     else
     else
       ParseExc(SParserSyntaxError);
       ParseExc(SParserSyntaxError);
     end;
     end;
@@ -1544,21 +1581,28 @@ end;
 
 
 // Starts after the "uses" token
 // Starts after the "uses" token
 procedure TPasParser.ParseUsesList(ASection: TPasSection);
 procedure TPasParser.ParseUsesList(ASection: TPasSection);
+
+function CheckUnit(AUnitName : string):TPasElement;
+begin
+    result := Engine.FindModule(AUnitName);  // should we resolve module here when "IN" filename is not known yet?
+    if Assigned(result) then
+      result.AddRef
+    else
+      Result := TPasType(CreateElement(TPasUnresolvedTypeRef, AUnitName,
+        ASection));
+    ASection.UsesList.Add(Result);
+end;
+
 var
 var
   AUnitName: String;
   AUnitName: String;
   Element: TPasElement;
   Element: TPasElement;
 begin
 begin
+  If not (Asection is TImplementationSection) Then // interface,program,library,package
+    Element:=CheckUnit('System'); // system always implicitely first.    
   while True do
   while True do
   begin
   begin
-    AUnitName := ExpectIdentifier;
-
-    Element := Engine.FindModule(AUnitName); // should we resolve module here when "IN" filename is not known yet?
-    if Assigned(Element) then
-      Element.AddRef
-    else
-      Element := TPasType(CreateElement(TPasUnresolvedTypeRef, AUnitName,
-        ASection));
-    ASection.UsesList.Add(Element);
+    AUnitName := ExpectIdentifier; 
+    Element :=CheckUnit(AUnitName);
 
 
     NextToken;
     NextToken;
 
 
@@ -2390,6 +2434,7 @@ var
   Body: TProcedureBody;
   Body: TProcedureBody;
 begin
 begin
   Body := TProcedureBody(CreateElement(TProcedureBody, '', Parent));
   Body := TProcedureBody(CreateElement(TProcedureBody, '', Parent));
+  TPasProcedure(Parent).Body:=Body;
   ParseDeclarations(Body);
   ParseDeclarations(Body);
 end;
 end;
 
 
@@ -2632,15 +2677,16 @@ var
 
 
 var
 var
   Condition: String;
   Condition: String;
-  Command: String;
   StartValue: String;
   StartValue: String;
   VarName: String;
   VarName: String;
   EndValue: String;
   EndValue: String;
   Expr: String;
   Expr: String;
   SubBlock: TPasImplElement;
   SubBlock: TPasImplElement;
-  CmdElem: TPasImplCommand;
+  CmdElem: TPasImplElement;
   TypeName: String;
   TypeName: String;
   ForDownTo: Boolean;
   ForDownTo: Boolean;
+  left: TPasExpr;
+  right: TPasExpr;
 begin
 begin
   NewImplElement:=nil;
   NewImplElement:=nil;
   CurBlock := Parent;
   CurBlock := Parent;
@@ -2874,18 +2920,48 @@ begin
           ParseExc(SParserSyntaxError);
           ParseExc(SParserSyntaxError);
       end;
       end;
     else
     else
-      UngetToken;
-      Command:=ParseCommand;
-      //WriteLn(i,'COMMAND="',Command,'" Token=',CurTokenString);
-      if Command='' then
-        ParseExc(SParserSyntaxError);
-      CmdElem:=CurBlock.AddCommand(Command);
-      if NewImplElement=nil then NewImplElement:=CmdElem;
-      if CloseStatement(false) then break;
+      left:=DoParseExpression(nil);
+      case CurToken of
+        tkAssign:
+        begin
+          // assign statement
+          NextToken;
+          right:=ParseExpIdent(Parent);
+          CmdElem:=CurBlock.AddAssign(left, right);
+          UngetToken;
+        end;
+        tkColon:
+        begin
+          if not (left is TPrimitiveExpr) then
+            ParseExc(Format(SParserExpectTokenError, [TokenInfos[tkSemicolon]]));
+          // label mark. todo: check mark identifier in the list of labels
+          CmdElem:=CurBlock.AddLabelMark(TPrimitiveExpr(left).Value);
+          left.Free;
+        end
+      else
+        // simple statement (function call)
+        CmdElem:=CurBlock.AddSimple(left);
+        UngetToken;
+      end;
+
+      if not (CmdElem is TPasImplLabelMark) then
+        if NewImplElement=nil then NewImplElement:=CmdElem;
     end;
     end;
   end;
   end;
 end;
 end;
 
 
+procedure TPasParser.ParseLabels(AParent: TPasElement);
+var
+  Labels: TPasLabels;
+begin
+  Labels:=TPasLabels(CreateElement(TPasLabels, '', AParent));
+  repeat
+    Labels.Labels.Add(ExpectIdentifier);
+    NextToken;
+    if not (CurToken in [tkSemicolon, tkComma]) then
+      ParseExc(Format(SParserExpectTokenError, [TokenInfos[tkSemicolon]]));
+  until CurToken=tkSemicolon;
+end;
 
 
 // Starts after the "procedure" or "function" token
 // Starts after the "procedure" or "function" token
 function TPasParser.ParseProcedureOrFunctionDecl(Parent: TPasElement;
 function TPasParser.ParseProcedureOrFunctionDecl(Parent: TPasElement;
@@ -3197,6 +3273,13 @@ begin
     if CurToken = tkBraceOpen then
     if CurToken = tkBraceOpen then
     begin
     begin
       TPasClassType(Result).AncestorType := ParseType(nil);
       TPasClassType(Result).AncestorType := ParseType(nil);
+      {$ifdef Inheritancewarnings}
+        s:=TPasClassType(Result).AncestorType.pathname;
+        if pos('#',s)=0 then
+          begin
+            writeln('Note: ', TPasClassType(Result).pathname,'''s ancestor ',s, ' at ',sourcefilename,':',sourcelinenumber,' cannot be resolved fully');
+          end;
+      {$endif}
       while True do
       while True do
       begin
       begin
         NextToken;
         NextToken;
@@ -3204,7 +3287,10 @@ begin
           break;
           break;
         UngetToken;
         UngetToken;
         ExpectToken(tkComma);
         ExpectToken(tkComma);
-        ExpectIdentifier;
+        //ExpectIdentifier;
+        Element:=ParseType(Nil); // search interface.
+        if assigned(element) then
+          TPasClassType(Result).Interfaces.add(element);
         // !!!: Store interface name
         // !!!: Store interface name
       end;
       end;
       NextToken;
       NextToken;

+ 23 - 5
packages/fcl-passrc/src/pscanner.pp

@@ -138,7 +138,10 @@ type
     tkvar,
     tkvar,
     tkwhile,
     tkwhile,
     tkwith,
     tkwith,
-    tkxor);
+    tkxor,
+    tkLineEnding,
+    tkTab
+    );
 
 
   TLineReader = class
   TLineReader = class
   public
   public
@@ -339,7 +342,9 @@ const
     'var',
     'var',
     'while',
     'while',
     'with',
     'with',
-    'xor'
+    'xor',
+    'LineEnding',
+    'Tab'
   );
   );
 
 
 function FilenameIsAbsolute(const TheFilename: string):boolean;
 function FilenameIsAbsolute(const TheFilename: string):boolean;
@@ -675,9 +680,9 @@ begin
     #0:         // Empty line
     #0:         // Empty line
       begin
       begin
         FetchLine;
         FetchLine;
-        Result := tkWhitespace;
+        Result := tkLineEnding;
       end;
       end;
-    #9, ' ':
+    ' ':
       begin
       begin
         Result := tkWhitespace;
         Result := tkWhitespace;
         repeat
         repeat
@@ -688,7 +693,20 @@ begin
               FCurToken := Result;
               FCurToken := Result;
               exit;
               exit;
             end;
             end;
-        until not (TokenStr[0] in [#9, ' ']);
+        until not (TokenStr[0] in [' ']);
+      end;
+    #9:
+      begin
+        Result := tkTab;
+        repeat
+          Inc(TokenStr);
+          if TokenStr[0] = #0 then
+            if not FetchLine then
+            begin
+              FCurToken := Result;
+              exit;
+            end;
+        until not (TokenStr[0] in [#9]);
       end;
       end;
     '#', '''':
     '#', '''':
       Result:=DoFetchTextToken;
       Result:=DoFetchTextToken;

+ 183 - 70
utils/fpdoc/dglobals.pp

@@ -23,12 +23,12 @@ unit dGlobals;
 
 
 interface
 interface
 
 
-uses Classes, DOM, PasTree, PParser;
+uses Classes, DOM, PasTree, PParser, StrUtils;
 
 
 Var
 Var
   LEOL : Integer;
   LEOL : Integer;
   modir : string;
   modir : string;
-  
+
 resourcestring
 resourcestring
   // Output strings
   // Output strings
   SDocPackageTitle           = 'Reference for package ''%s''';
   SDocPackageTitle           = 'Reference for package ''%s''';
@@ -63,6 +63,7 @@ resourcestring
   SDocRemark                 = 'Remark:   ';
   SDocRemark                 = 'Remark:   ';
   SDocMethodOverview         = 'Method overview';
   SDocMethodOverview         = 'Method overview';
   SDocPropertyOverview       = 'Property overview';
   SDocPropertyOverview       = 'Property overview';
+  SDocInterfacesOverview     = 'Interfaces overview';
   SDocPage                   = 'Page';
   SDocPage                   = 'Page';
   SDocMethod                 = 'Method';
   SDocMethod                 = 'Method';
   SDocProperty               = 'Property';
   SDocProperty               = 'Property';
@@ -119,6 +120,10 @@ resourcestring
   SCHMUsageAutoIDX = 'Automatically generate an Index. Ignores --index-file';
   SCHMUsageAutoIDX = 'Automatically generate an Index. Ignores --index-file';
   SCHMUsageMakeSearch = 'Automatically generate a Search Index from filenames that match *.htm*';
   SCHMUsageMakeSearch = 'Automatically generate a Search Index from filenames that match *.htm*';
 
 
+  // Linear usage
+  SLinearUsageDupLinkedDocsP1 = 'Duplicate linked element documentation in';
+  SLinearUsageDupLinkedDocsP2 = 'descendant classes.';
+
   STitle           = 'FPDoc - Free Pascal Documentation Tool';
   STitle           = 'FPDoc - Free Pascal Documentation Tool';
   SVersion         = 'Version %s [%s]';
   SVersion         = 'Version %s [%s]';
   SCopyright       = '(c) 2000 - 2003 Areca Systems GmbH / Sebastian Guenther, [email protected]';
   SCopyright       = '(c) 2000 - 2003 Areca Systems GmbH / Sebastian Guenther, [email protected]';
@@ -142,7 +147,7 @@ resourcestring
   SUsageOption160  = '--show-private    Show private methods.';
   SUsageOption160  = '--show-private    Show private methods.';
   SUsageOption170  = '--warn-no-node    Warn if no documentation node was found.';
   SUsageOption170  = '--warn-no-node    Warn if no documentation node was found.';
   SUsageOption180  = '--mo-dir=dir      Set directory where language files reside to dir';
   SUsageOption180  = '--mo-dir=dir      Set directory where language files reside to dir';
-  
+  SUsageOption190  = '--parse-impl      (Experimental) try to parse implementation too';
   SUsageFormats        = 'The following output formats are supported by this fpdoc:';
   SUsageFormats        = 'The following output formats are supported by this fpdoc:';
   SUsageBackendHelp    = 'Specify an output format, combined with --help to get more help for this backend.';
   SUsageBackendHelp    = 'Specify an output format, combined with --help to get more help for this backend.';
   SUsageFormatSpecific = 'Output format "%s" supports the following options:';
   SUsageFormatSpecific = 'Output format "%s" supports the following options:';
@@ -155,7 +160,7 @@ resourcestring
   SDone                       = 'Done.';
   SDone                       = 'Done.';
   SErrCouldNotCreateOutputDir = 'Could not create output directory "%s"';
   SErrCouldNotCreateOutputDir = 'Could not create output directory "%s"';
   SErrCouldNotCreateFile      = 'Could not create file "%s": %s';
   SErrCouldNotCreateFile      = 'Could not create file "%s": %s';
-  SSeeURL                     = '(See %s)';      // For lineair text writers.
+  SSeeURL                     = '(See %s)';      // For linear text writers.
 
 
 Const
 Const
   SVisibility: array[TPasMemberVisibility] of string =
   SVisibility: array[TPasMemberVisibility] of string =
@@ -578,6 +583,7 @@ end;
 procedure TFPDocEngine.ReadContentFile(const AFilename, ALinkPrefix: String);
 procedure TFPDocEngine.ReadContentFile(const AFilename, ALinkPrefix: String);
 var
 var
   f: Text;
   f: Text;
+  inheritanceinfo : TStringlist;
 
 
   procedure ReadLinkTree;
   procedure ReadLinkTree;
   var
   var
@@ -635,15 +641,15 @@ var
     end;
     end;
   end;
   end;
 
 
-  procedure ReadClasses;
-
-    function CreateClass(const AName: String): TPasClassType;
+  function ResolvePackageModule(AName:String;var pkg:TPasPackage;var module:TPasModule;createnew:boolean):String;
     var
     var
-      DotPos, DotPos2, i: Integer;
+      DotPos, DotPos2, i,j: Integer;
       s: String;
       s: String;
       HPackage: TPasPackage;
       HPackage: TPasPackage;
-      Module: TPasModule;
+
     begin
     begin
+      pkg:=nil; module:=nil; result:='';
+
       // Find or create package
       // Find or create package
       DotPos := Pos('.', AName);
       DotPos := Pos('.', AName);
       s := Copy(AName, 1, DotPos - 1);
       s := Copy(AName, 1, DotPos - 1);
@@ -656,6 +662,8 @@ var
         end;
         end;
       if not Assigned(HPackage) then
       if not Assigned(HPackage) then
       begin
       begin
+        if not CreateNew then
+          exit;
         HPackage := TPasPackage(inherited CreateElement(TPasPackage, s, nil,
         HPackage := TPasPackage(inherited CreateElement(TPasPackage, s, nil,
           '', 0));
           '', 0));
         FPackages.Add(HPackage);
         FPackages.Add(HPackage);
@@ -676,72 +684,157 @@ var
         end;
         end;
       if not Assigned(Module) then
       if not Assigned(Module) then
       begin
       begin
+        if not CreateNew then
+          exit;
         Module := TPasModule.Create(s, HPackage);
         Module := TPasModule.Create(s, HPackage);
         Module.InterfaceSection := TInterfaceSection.Create('', Module);
         Module.InterfaceSection := TInterfaceSection.Create('', Module);
         HPackage.Modules.Add(Module);
         HPackage.Modules.Add(Module);
       end;
       end;
+     pkg:=hpackage;
+     result:=Copy(AName, DotPos2 + 1, length(AName)-dotpos2);
+  end;
+
+  function ResolveClassType(AName:String):TPasClassType;
+  var 
+     pkg     : TPasPackage;
+     module  : TPasModule;
+     s       : string; 
+     clslist : TList;  
+     ClassEl : TPasClassType;
+     i       : Integer;
+  begin
+    Result:=nil;
+    s:=ResolvePackageModule(AName,pkg,module,False);
+    if not assigned(module) then
+      exit;
+    clslist:=module.InterfaceSection.Classes;
+    for i:=0 to clslist.count-1 do
+      begin
+        ClassEl := TPasClassType(clslist[i]);
+        if CompareText(ClassEl.Name,s) =0 then
+          exit(Classel); 
+      end;
+  end;
 
 
+  procedure ReadClasses;
+
+    function CreateClass(const AName: String;InheritanceStr:String): TPasClassType;
+    var
+      DotPos, DotPos2, i,j: Integer;
+      s: String;
+      HPackage: TPasPackage;
+      Module: TPasModule;
+
+    begin
+      s:= ResolvePackageModule(AName,HPackage,Module,True);
       // Create node for class
       // Create node for class
-      Result := TPasClassType.Create(Copy(AName, DotPos2 + 1, Length(AName)),
-        Module.InterfaceSection);
+      Result := TPasClassType.Create(s, Module.InterfaceSection);
       Result.ObjKind := okClass;
       Result.ObjKind := okClass;
       Module.InterfaceSection.Declarations.Add(Result);
       Module.InterfaceSection.Declarations.Add(Result);
       Module.InterfaceSection.Classes.Add(Result);
       Module.InterfaceSection.Classes.Add(Result);
+      // defer processing inheritancestr till all classes are loaded.
+      if inheritancestr<>'' then
+        InheritanceInfo.AddObject(Inheritancestr,result);
     end;
     end;
 
 
+   procedure ProcessInheritanceStrings(inhInfo:TStringList);
+   var i,j : integer;
+       cls : TPasClassType;  
+       cls2: TPasClassType;
+       inhclass   : TStringList;
+   begin
+     inhclass:=TStringList.Create;
+     inhclass.delimiter:=',';
+     if InhInfo.Count>0 then
+       for i:=0 to InhInfo.Count-1 do
+         begin
+           cls:=TPasClassType(InhInfo.Objects[i]);
+           inhclass.clear; 
+           inhclass.delimitedtext:=InhInfo[i];
+
+           for j:= 0 to inhclass.count-1 do
+             begin
+               // writeln('processing',inhclass[j]);
+               cls2:=TPasClassType(ResolveClassType(inhclass[j])); 
+               if assigned(cls2) and not (cls=cls2) then  // save from tobject=implicit tobject
+                 begin
+                   cls2.addref;
+                   if j=0 then
+                     cls.ancestortype:=cls2
+                   else
+                     cls.interfaces.add(cls2);
+{                   if j=0 then
+                     writeln(cls.name, ' has as ancestor ',cls2.pathname)
+                   else
+                     writeln(cls.name, ' implements ',cls2.pathname)
+}
+                 end
+               else
+                if cls<>cls2 then
+                  writeln(cls.name,'''s dependancy '  ,inhclass[j],' ',j,' could not be resolved');
+             end;
+         end;
+end;
+
   var
   var
     s, Name: String;
     s, Name: String;
     CurClass: TPasClassType;
     CurClass: TPasClassType;
     i: Integer;
     i: Integer;
     Member: TPasElement;
     Member: TPasElement;
   begin
   begin
-    CurClass := nil;
-    while True do
-    begin
-      ReadLn(f, s);
-      if Length(s) = 0 then
-        break;
-      if s[1] = '#' then
+    inheritanceinfo :=TStringlist.Create;
+    Try
+      CurClass := nil;
+      while True do
       begin
       begin
-        // New class
-        i := Pos(' ', s);
-        CurClass := CreateClass(Copy(s, 1, i - 1));
-      end else
-      begin
-        i := Pos(' ', s);
-        if i = 0 then
-          Name := Copy(s, 3, Length(s))
-        else
-          Name := Copy(s, 3, i - 3);
+        ReadLn(f, s);
+        if Length(s) = 0 then
+          break;
+        if s[1] = '#' then
+        begin
+          // New class
+          i := Pos(' ', s);
+          CurClass := CreateClass(Copy(s, 1, i - 1), copy(s,i+1,length(s)));
+        end else
+        begin
+          i := Pos(' ', s);
+          if i = 0 then
+            Name := Copy(s, 3, Length(s))
+          else
+            Name := Copy(s, 3, i - 3);
 
 
-        case s[2] of
-          'M':
-            Member := TPasProcedure.Create(Name, CurClass);
-          'P':
-            begin
-              Member := TPasProperty.Create(Name, CurClass);
-              if i > 0 then
-                while i <= Length(s) do
-                begin
-                  case s[i] of
-                    'r':
-                      TPasProperty(Member).ReadAccessorName := '<dummy>';
-                    'w':
-                      TPasProperty(Member).WriteAccessorName := '<dummy>';
-                    's':
-                      TPasProperty(Member).StoredAccessorName := '<dummy>';
+          case s[2] of
+            'M':
+              Member := TPasProcedure.Create(Name, CurClass);
+            'P':
+              begin
+                Member := TPasProperty.Create(Name, CurClass);
+                if i > 0 then
+                  while i <= Length(s) do
+                  begin
+                    case s[i] of
+                      'r':
+                        TPasProperty(Member).ReadAccessorName := '<dummy>';
+                      'w':
+                        TPasProperty(Member).WriteAccessorName := '<dummy>';
+                      's':
+                        TPasProperty(Member).StoredAccessorName := '<dummy>';
+                    end;
+                    Inc(i);
                   end;
                   end;
-                  Inc(i);
-                end;
-            end;
-          'V':
-            Member := TPasVariable.Create(Name, CurClass);
-          else
-            raise Exception.Create('Invalid member type: ' + s[2]);
+              end;
+            'V':
+              Member := TPasVariable.Create(Name, CurClass);
+            else
+              raise Exception.Create('Invalid member type: ' + s[2]);
+          end;
+          CurClass.Members.Add(Member);
         end;
         end;
-        CurClass.Members.Add(Member);
       end;
       end;
-    end;
+     ProcessInheritanceStrings(Inheritanceinfo);
+    finally
+     inheritanceinfo.Free;
+     end;
   end;
   end;
 
 
 var
 var
@@ -820,9 +913,17 @@ begin
         ClassDecl := TPasClassType(Module.InterfaceSection.Classes[j]);
         ClassDecl := TPasClassType(Module.InterfaceSection.Classes[j]);
         Write(ContentFile, ClassDecl.PathName, ' ');
         Write(ContentFile, ClassDecl.PathName, ' ');
         if Assigned(ClassDecl.AncestorType) then
         if Assigned(ClassDecl.AncestorType) then
-          WriteLn(ContentFile, ClassDecl.AncestorType.PathName)
+          Write(ContentFile, ClassDecl.AncestorType.PathName)
         else if ClassDecl.ObjKind = okClass then
         else if ClassDecl.ObjKind = okClass then
-          WriteLn(ContentFile, '.TObject');
+          Write(ContentFile, '#rtl.System.TObject')
+        else if ClassDecl.ObjKind = okInterface then
+          Write(ContentFile, '#rtl.System.IUnknown');
+        if ClassDecl.Interfaces.Count>0 then
+          begin
+            for k:=0 to ClassDecl.Interfaces.count-1 do
+              write(contentfile,',',TPasClassType(ClassDecl.Interfaces[k]).PathName);
+          end;
+        writeln(contentfile);
         for k := 0 to ClassDecl.Members.Count - 1 do
         for k := 0 to ClassDecl.Members.Count - 1 do
         begin
         begin
           Member := TPasElement(ClassDecl.Members[k]);
           Member := TPasElement(ClassDecl.Members[k]);
@@ -850,8 +951,6 @@ begin
       end;
       end;
     end;
     end;
   end;
   end;
-
-
   finally
   finally
     Close(ContentFile);
     Close(ContentFile);
   end;
   end;
@@ -972,8 +1071,17 @@ var
   i: Integer;
   i: Integer;
   ThisPackage: TLinkNode;
   ThisPackage: TLinkNode;
   UnitList: TList;
   UnitList: TList;
+
+  function CanWeExit(AResult: string): boolean;
+  var
+    s: string;
+  begin
+    s := StringReplace(Lowercase(ALinkDest), '.', '_', [rfReplaceAll]);
+    Result := pos(s, AResult) > 0;
+  end;
+
 begin
 begin
-//WriteLn('ResolveLink(', ALinkDest, ')... ');
+//system.WriteLn('ResolveLink(', AModule.Name, ' - ', ALinkDest, ')... ');
   if Length(ALinkDest) = 0 then
   if Length(ALinkDest) = 0 then
   begin
   begin
     SetLength(Result, 0);
     SetLength(Result, 0);
@@ -984,13 +1092,18 @@ begin
     Result := FindAbsoluteLink(ALinkDest)
     Result := FindAbsoluteLink(ALinkDest)
   else
   else
   begin
   begin
-    Result := ResolveLink(AModule, amodule.packagename + '.' + ALinkDest);
-    if Length(Result) > 0 then
-      exit;
-
-    Result := ResolveLink(AModule, AModule.PathName + '.' + ALinkDest);
-    if Length(Result) > 0 then
-      exit;
+    if Pos(AModule.Name, ALinkDest) = 1 then
+    begin
+      Result := ResolveLink(AModule, amodule.packagename + '.' + ALinkDest);
+      if CanWeExit(Result) then
+        Exit;
+    end
+    else
+    begin
+      Result := ResolveLink(AModule, AModule.PathName + '.' + ALinkDest);
+      if CanWeExit(Result) then
+        Exit;
+    end;
 
 
     { Try all packages }
     { Try all packages }
     SetLength(Result, 0);
     SetLength(Result, 0);
@@ -998,12 +1111,12 @@ begin
     while Assigned(ThisPackage) do
     while Assigned(ThisPackage) do
     begin
     begin
       Result := ResolveLink(AModule, ThisPackage.Name + '.' + ALinkDest);
       Result := ResolveLink(AModule, ThisPackage.Name + '.' + ALinkDest);
-      if Length(Result) > 0 then
-        exit;
+      if CanWeExit(Result) then
+        Exit;
       ThisPackage := ThisPackage.NextSibling;
       ThisPackage := ThisPackage.NextSibling;
     end;
     end;
 
 
-    if Length(Result) = 0 then
+    if not CanWeExit(Result) then
     begin
     begin
       { Okay, then we have to try all imported units of the current module }
       { Okay, then we have to try all imported units of the current module }
       UnitList := AModule.InterfaceSection.UsesList;
       UnitList := AModule.InterfaceSection.UsesList;
@@ -1015,8 +1128,8 @@ begin
         begin
         begin
           Result := ResolveLink(AModule, ThisPackage.Name + '.' +
           Result := ResolveLink(AModule, ThisPackage.Name + '.' +
             TPasType(UnitList[i]).Name + '.' + ALinkDest);
             TPasType(UnitList[i]).Name + '.' + ALinkDest);
-          if Length(Result) > 0 then
-            exit;
+            if CanWeExit(Result) then
+              Exit;
           ThisPackage := ThisPackage.NextSibling;
           ThisPackage := ThisPackage.NextSibling;
         end;
         end;
       end;
       end;

+ 23 - 2
utils/fpdoc/dw_html.pp

@@ -659,7 +659,8 @@ begin
   Doc := THTMLDocument.Create;
   Doc := THTMLDocument.Create;
   Result := Doc;
   Result := Doc;
   Doc.AppendChild(Doc.Impl.CreateDocumentType(
   Doc.AppendChild(Doc.Impl.CreateDocumentType(
-    'HTML', '-//W3C//DTD HTML 4.0 Transitional//EN', ''));
+    'HTML', '-//W3C//DTD HTML 4.01 Transitional//EN',
+    'http://www.w3.org/TR/html4/loose.dtd'));
 
 
   HTMLEl := Doc.CreateHtmlElement;
   HTMLEl := Doc.CreateHtmlElement;
   Doc.AppendChild(HTMLEl);
   Doc.AppendChild(HTMLEl);
@@ -1525,6 +1526,8 @@ begin
                 break;
                 break;
               ThisPackage := ThisPackage.NextSibling;
               ThisPackage := ThisPackage.NextSibling;
             end;
             end;
+            if length(s)=0 then
+              s := ResolveLinkID('#rtl.System.' + Element.Name);
             if Length(s) > 0 then
             if Length(s) > 0 then
               break;
               break;
           end;
           end;
@@ -2230,7 +2233,7 @@ begin
   end;
   end;
 end;
 end;
 
 
-procedure THTMLWriter.CreateIndexPage(L : TStringList);
+	procedure THTMLWriter.CreateIndexPage(L : TStringList);
 
 
 Var
 Var
   Lists  : Array['A'..'Z'] of TStringList;
   Lists  : Array['A'..'Z'] of TStringList;
@@ -2816,6 +2819,7 @@ var
     CurVisibility: TPasMemberVisibility;
     CurVisibility: TPasMemberVisibility;
     i: Integer;
     i: Integer;
     s: String;
     s: String;
+    ThisInterface,
     ThisClass: TPasClassType;
     ThisClass: TPasClassType;
     HaveSeenTObject: Boolean;
     HaveSeenTObject: Boolean;
   begin
   begin
@@ -2846,6 +2850,14 @@ var
     begin
     begin
       AppendSym(CodeEl, '(');
       AppendSym(CodeEl, '(');
       AppendHyperlink(CodeEl, AClass.AncestorType);
       AppendHyperlink(CodeEl, AClass.AncestorType);
+      if AClass.Interfaces.count>0 Then
+        begin
+          for i:=0 to AClass.interfaces.count-1 do
+           begin
+             AppendSym(CodeEl, ', ');
+             AppendHyperlink(CodeEl,TPasClassType(AClass.Interfaces[i]));
+           end; 
+        end;
       AppendSym(CodeEl, ')');
       AppendSym(CodeEl, ')');
     end;
     end;
 
 
@@ -2951,6 +2963,15 @@ var
       TDEl['align'] := 'center';
       TDEl['align'] := 'center';
       CodeEl := CreateCode(CreatePara(TDEl));
       CodeEl := CreateCode(CreatePara(TDEl));
       AppendHyperlink(CodeEl, ThisClass);
       AppendHyperlink(CodeEl, ThisClass);
+      if ThisClass.Interfaces.count>0 then
+        begin
+          for i:=0 to ThisClass.interfaces.count-1 do
+            begin
+              ThisInterface:=TPasClassType(ThisClass.Interfaces[i]);
+              AppendText(CodeEl,',');
+              AppendHyperlink(CodeEl, ThisInterface);
+            end;
+        end;
       AppendShortDescrCell(TREl, ThisClass);
       AppendShortDescrCell(TREl, ThisClass);
       if HaveSeenTObject or (CompareText(ThisClass.Name, 'TObject') = 0) then
       if HaveSeenTObject or (CompareText(ThisClass.Name, 'TObject') = 0) then
         HaveSeenTObject := True
         HaveSeenTObject := True

+ 0 - 1341
utils/fpdoc/dw_ipf.pp

@@ -1,1341 +0,0 @@
-{
-
-    FPDoc  -  Free Pascal Documentation Tool
-    Copyright (C) 2000 - 2003 by
-      Areca Systems GmbH / Sebastian Guenther, [email protected]
-
-    * IPF 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.
-}
-
-unit dw_IPF;
-
-{$MODE objfpc}
-{$H+}
-
-interface
-
-uses SysUtils, Classes, dWriter, DOM, dGlobals, PasTree;
-
-const
-  IPFHighLight : Boolean = False;
-  IPFExtension   : String = '.ipf';
-
-type
-  TLabelType = (ltConst,ltVar,ltType,ltFunction,ltProcedure,ltClass,
-                ltChapter,ltSection,ltSubsection,
-                ltTable,ltFigure);
-
-  { TIPFWriter }
-
-  TIPFWriter = class(TFPDocWriter)
-  protected
-    f: Text;
-    FLink: String;
-    PackageName: String;
-    Module: TPasModule;
-    ModuleName: String;
-    FTableCount : Integer;
-    TableRowStartFlag, TableCaptionWritten: Boolean;
-
-    function GetLabel(AElement: TPasElement): String;
-
-    procedure Write(const s: String);
-    procedure WriteF(const s: String; const Args: array of const);
-    procedure WriteLn(const s: String);
-    procedure WriteLnF(const s: String; const Args: array of const);
-    // Tex functions
-    procedure WriteLabel(El: TPasElement);
-    procedure WriteLabel(const s: String);
-    procedure WriteIndex(El: TPasElement);
-    procedure WriteIndex(const s: String);
-    procedure StartListing(Frames: Boolean; const name: String);
-    procedure StartListing(Frames: Boolean);
-    procedure EndListing;
-    Function  EscapeTex(S : String) : String;
-    Function  StripTex(S : String) : String;
-
-    procedure WriteCommentLine;
-    procedure WriteComment(Comment : String);
-    procedure StartSection(SectionName : String; SectionLabel : String);
-//    procedure StartSection(SectionName : String);
-    procedure StartSubSection(SubSectionName : String; SubSectionLabel : String);
-//    procedure StartSubSection(SubSectionName : String);
-    procedure StartChapter(ChapterName : String; ChapterLabel : String);
-    procedure StartChapter(ChapterName : String);
-    // Description node conversion
-    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 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 DescrWriteLinebreak; override;
-    procedure DescrBeginParagraph; override;
-    procedure DescrBeginCode(HasBorder: Boolean; const AHighlighterName: String); override;
-    procedure DescrWriteCodeLine(const ALine: String); override;
-    procedure DescrEndCode; override;
-    procedure DescrEndParagraph; 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;
-    function ConstValue(ConstDecl: TPasConst): String;
-    procedure ProcessSection(ASection: TPasSection);
-    // Documentation writing methods.
-    procedure WriteResourceStrings(ASection: TPasSection);
-    procedure WriteUnitOverview(ASection: TPasSection);
-    procedure WriteVarsConstsTypes(ASection: TPasSection);
-    procedure WriteConsts(ASection: TPasSection);
-    procedure WriteTypes(ASection: TPasSection);
-    procedure WriteEnumElements(TypeDecl : TPasEnumType);
-    procedure WriteVars(ASection: TPasSection);
-    procedure WriteFunctionsAndProcedures(ASection: TPasSection);
-    procedure WriteProcedure(ProcDecl: TPasProcedureBase);
-    procedure WriteClasses(ASection: TPasSection);
-    procedure WriteClassDecl(ClassDecl: TPasClassType);
-    procedure WriteClassMethodOverview(ClassDecl: TPasClassType);
-    procedure WriteClassPropertyOverview(ClassDecl: TPasClassType);
-    procedure WriteProperty(PropDecl: TPasProperty);
-    procedure WriteExample(ADocNode: TDocNode);
-    procedure WriteSeeAlso(ADocNode: TDocNode);
-    procedure SortElementList(List : TList);
-    Function  ShowMember(M : TPasElement) : boolean;
-  public
-    constructor Create(APackage: TPasPackage; AEngine: TFPDocEngine); override;
-    procedure WriteDoc; override;
-  end;
-
-
-implementation
-
-
-
-
-
-constructor TIPFWriter.Create(APackage: TPasPackage; AEngine: TFPDocEngine);
-
-  procedure AddLabel(AElement: TPasElement);
-  begin
-    Engine.AddLink(AElement.PathName, GetLabel(AElement));
-  end;
-
-  procedure AddList(AElement: TPasElement; AList: TList);
-  var
-    i: Integer;
-  begin
-    for i := 0 to AList.Count - 1 do
-      AddLabel(TPasElement(AList[i]));
-  end;
-
-  procedure ScanModule(AModule: TPasModule);
-  var
-    i, j, k: Integer;
-    s: String;
-    ClassEl: TPasClassType;
-    FPEl, AncestorMemberEl: TPasElement;
-    DocNode: TDocNode;
-    DidAutolink: Boolean;
-  begin
-    AddLabel(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 ((FPEl.Visibility = visPrivate) and Engine.HidePrivate) or
-              ((FPEl.Visibility = visProtected) and Engine.HideProtected) 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 ;
-
-  { 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
-    AddLabel(Package);
-
-  for i := 0 to Package.Modules.Count - 1 do
-    ScanModule(TPasModule(Package.Modules[i]));
-end;
-
-procedure TIPFWriter.WriteDoc;
-var
-  i : Integer;
-
-begin
-  PackageName := LowerCase(Copy(Package.Name, 2, 255));
-  If (Engine.OutPut='') then
-    Engine.Output:=PackageName+IPFExtension;
-  Assign(f, Engine.Output);
-  Rewrite(f);
-  try
-    WriteLn('.* This file has been created automatically by FPDoc,');
-    WriteLn('.* (c) 2000-2003 by Areca Systems GmbH / Sebastian Guenther ([email protected])');
-    for i := 0 to Package.Modules.Count - 1 do
-    begin
-      Module := TPasModule(Package.Modules[i]);
-      ModuleName := LowerCase(Module.Name);
-      WriteLn('');
-      Write(':h1 name=');
-      WriteLabel(Module);
-      WriteLnF('.%s', [EscapeTex(Format(SDocUnitTitle, [Module.Name]))]);
-      ProcessSection(Module.InterfaceSection);
-    end;
-  finally
-    Close(f);
-  end;
-end;
-
-function TIPFWriter.GetLabel(AElement: TPasElement): String;
-var
-  i: Integer;
-begin
-  if AElement.ClassType = TPasUnresolvedTypeRef then
-    Result := Engine.ResolveLink(Module, AElement.Name)
-  else
-  begin
-    Result := AElement.PathName;
-    Result := LowerCase(Copy(Result, 2, Length(Result) - 1));
-  end;
-  for i := 1 to Length(Result) do
-    if Result[i] = '.' then
-      Result[i] := '_';
-end;
-
-procedure TIPFWriter.Write(const s: String);
-begin
-  System.Write(f, s);
-end;
-
-procedure TIPFWriter.WriteF(const s: String; const Args: array of const);
-begin
-  System.Write(f, Format(s, Args));
-end;
-
-procedure TIPFWriter.WriteLn(const s: String);
-begin
-  System.WriteLn(f, s);
-end;
-
-procedure TIPFWriter.WriteLnF(const s: String; const Args: array of const);
-begin
-  System.WriteLn(f, Format(s, Args));
-end;
-
-Function TIPFWriter.EscapeTex(S : String) : String;
-
-var
-  i: Integer;
-
-begin
-  SetLength(Result, 0);
-  for i := 1 to Length(S) do
-    case S[i] of
-      '.':              // Escape these characters
-        Result := Result + '&per.';
-      ':':
-        Result := Result + '&colon.';
-      ',':
-        Result := Result + '&comma.';
-      '&':
-        Result := Result + '&amp.';
-(*
-³&amp.               ³ampersand           ³&                   ³
-³&and.               ³and                 ³^                   ³
-³&apos.              ³apostrophe          ³'                   ³
-³&asterisk.          ³asterisk            ³*                   ³
-³&atsign.            ³at sign             ³@                   ³
-³&bslash., &bsl.     ³back slash          ³\                   ³
-³&caret.             ³caret symbol        ³^                   ³
-³&cdq.               ³close double quote  ³"                   ³
-³&csq.               ³close single quote  ³'                   ³
-³&comma.             ³comma               ³,                   ³
-³&colon.             ³colon               ³:                   ³
-³&dash.              ³dash                ³-                   ³
-³&degree., &deg.     ³degree              ³ø                   ³
-³&dollar.            ³dollar sign         ³$                   ³
-³&dot.               ³dot                 ³ú                   ³
-³&darrow.            ³down arrow          ³                   ³
-³&emdash.            ³em dash             ³-                   ³
-³&endash.            ³en dash             ³-                   ³
-³&eq., &equals.,     ³equal sign          ³=                   ³
-³&eqsym.             ³                    ³                    ³
-³&xclm., &xclam.     ³exclamation point   ³!                   ³
-³&gtsym., &gt.       ³greater than        ³>                   ³
-³&house.             ³house               ³                   ³
-³&hyphen.            ³hyphen              ³-                   ³
-³&larrow.            ³left arrow          ³                   ³
-³&lahead.            ³left arrowhead      ³                   ³
-³&lbrace., &lbrc.    ³left brace          ³{                   ³
-³&lbracket. &lbrk.   ³left bracket        ³[                   ³
-³&lpar. , &lparen.   ³left parenthesis    ³(                   ³
-³&mdash.             ³em dash             ³-                   ³
-³&minus.             ³minus sign          ³-                   ³
-³&ndash.             ³en dash             ³-                   ³
-³&numsign.           ³number sign         ³#                   ³
-³&odq.               ³open double quote   ³"                   ³
-³&osq.               ³open single quote   ³`                   ³
-³&percent.           ³percent             ³%                   ³
-³&per.               ³period              ³.                   ³
-³&plus.              ³plus sign           ³+                   ³
-³&rbrace., &rbrc.    ³right brace         ³}                   ³
-³&rbracket., &rbrk.  ³right bracket       ³]                   ³
-³&rpar., &rparen.    ³right parenthesis   ³)                   ³
-³&slash., &slr.      ³slash               ³/                   ³
-³&splitvbar.         ³split vertical bar  ³|                   ³
-³                    ³(piping symbol)     ³                    ³
-³&sqbul.             ³square bullet       ³þ                   ³
-³&tilde.             ³tilde               ³~                   ³
-³&us.                ³underscore          ³_                   ³
-*)
-      else
-        Result := Result + S[i];
-    end;
-end;
-
-Function TIPFWriter.StripTex(S : String) : String;
-
-var
-  I,L: Integer;
-
-begin
-  Result:=S;
-//  SetLength(Result, 0);
-//  for i := 1 to Length(S) do
-//    If not (S[i] in ['&','{','}','#','_','$','%','''','~','^', '\']) then
-//      Result := Result + S[i];
-end;
-
-procedure TIPFWriter.DescrWriteText(const AText: DOMString);
-
-begin
-  Write(EscapeTex(AText));
-end;
-
-procedure TIPFWriter.DescrBeginBold;
-begin
-  Write(':hp2.');
-end;
-
-procedure TIPFWriter.DescrEndBold;
-begin
-  WriteLn(':ehp2.');
-end;
-
-procedure TIPFWriter.DescrBeginItalic;
-begin
-  Write(':hp1.');
-end;
-
-procedure TIPFWriter.DescrEndItalic;
-begin
-  WriteLn(':ehp1.');
-end;
-
-procedure TIPFWriter.DescrBeginEmph;
-begin
-  Write(':hp2.');
-end;
-
-procedure TIPFWriter.DescrEndEmph;
-begin
-  Write(':ehp2.');
-end;
-
-procedure TIPFWriter.DescrWriteFileEl(const AText: DOMString);
-begin
-  Write(':hp2.');
-  DescrWriteText(AText);
-  Write(':ehp2.');
-end;
-
-procedure TIPFWriter.DescrWriteKeywordEl(const AText: DOMString);
-begin
-  Write(':hp2.');
-  DescrWriteText(AText);
-  Write(':ehp2.');
-end;
-
-procedure TIPFWriter.DescrWriteVarEl(const AText: DOMString);
-begin
-  Write(':hp2.');
-  DescrWriteText(AText);
-  Write(':ehp2.');
-end;
-
-procedure TIPFWriter.DescrBeginLink(const AId: DOMString);
-var
-  i: Integer;
-begin
-  FLink := Engine.ResolveLink(Module, AId);
-  While pos(':',flink)>0 do flink[pos(':',flink)]:='_';
-//  System.WriteLn('Link "', AId, '" => ', FLink);
-  WriteF(':link reftype=hd refid=%s.', [flink]);
-end;
-
-procedure TIPFWriter.DescrEndLink;
-begin
-  Write(':elink.');
-end;
-
-procedure TIPFWriter.DescrWriteLinebreak;
-begin
-  WriteLn('.br');
-end;
-
-procedure TIPFWriter.DescrBeginParagraph;
-begin
-  WriteLn(':p.');
-  // Do nothing
-end;
-
-procedure TIPFWriter.DescrEndParagraph;
-begin
-  WriteLn('');
-  WriteLn('');
-end;
-
-procedure TIPFWriter.DescrBeginCode(HasBorder: Boolean;
-  const AHighlighterName: String);
-begin
-  StartListing(HasBorder);
-end;
-
-procedure TIPFWriter.DescrWriteCodeLine(const ALine: String);
-begin
-  WriteLn(EscapeTex(ALine));
-end;
-
-procedure TIPFWriter.DescrEndCode;
-begin
-  EndListing
-end;
-
-procedure TIPFWriter.DescrBeginOrderedList;
-begin
-  WriteLn(':ol.');
-end;
-
-procedure TIPFWriter.DescrEndOrderedList;
-begin
-  WriteLn(':eol.');
-end;
-
-procedure TIPFWriter.DescrBeginUnorderedList;
-begin
-  WriteLn(':ul.');
-end;
-
-procedure TIPFWriter.DescrEndUnorderedList;
-begin
-  WriteLn(':eul.');
-end;
-
-procedure TIPFWriter.DescrBeginDefinitionList;
-begin
-  WriteLn(':dl.');
-end;
-
-procedure TIPFWriter.DescrEndDefinitionList;
-begin
-  WriteLn(':edl.');
-end;
-
-procedure TIPFWriter.DescrBeginListItem;
-begin
-  Write(':li.');
-end;
-
-procedure TIPFWriter.DescrEndListItem;
-begin
-  WriteLn('');
-end;
-
-procedure TIPFWriter.DescrBeginDefinitionTerm;
-begin
-  Write(':li.');
-end;
-
-procedure TIPFWriter.DescrEndDefinitionTerm;
-begin
-  WriteLn('');
-end;
-
-procedure TIPFWriter.DescrBeginDefinitionEntry;
-begin
-  WriteLn('');
-  // Do nothing
-end;
-
-procedure TIPFWriter.DescrEndDefinitionEntry;
-begin
-  WriteLn('');
-end;
-
-procedure TIPFWriter.DescrBeginSectionTitle;
-begin
-  Write(':h3.');
-end;
-
-procedure TIPFWriter.DescrBeginSectionBody;
-begin
-  WriteLn('');
-end;
-
-procedure TIPFWriter.DescrEndSection;
-begin
-  WriteLn('');
-  // Do noting
-end;
-
-procedure TIPFWriter.DescrBeginRemark;
-begin
-  WriteLn(':note.');
-end;
-
-procedure TIPFWriter.DescrEndRemark;
-begin
-  WriteLn('');
-end;
-
-procedure TIPFWriter.DescrBeginTable(ColCount: Integer; HasBorder: Boolean);
-begin
-  // !!!: How do we set the border?
-//  for i := 1 to ColCount do
-//    Write('l');
-//  write('}{');
-  TableCaptionWritten:=False;
-end;
-
-procedure TIPFWriter.DescrEndTable;
-begin
-  WriteLn(':etable.');
-end;
-
-procedure TIPFWriter.DescrBeginTableCaption;
-begin
-  // Do nothing.
-end;
-
-procedure TIPFWriter.DescrEndTableCaption;
-begin
-  Write('');
-//  Inc(FTableCount);
-//  Write(IntToStr(FTableCount));
-//  Writeln('}');
-  TableCaptionWritten := True;
-  Write(':table cols=''30 50''.');
-end;
-
-procedure TIPFWriter.DescrBeginTableHeadRow;
-begin
-  if not TableCaptionWritten then
-    DescrEndTableCaption;
-  TableRowStartFlag := True;
-  WriteLn(':row.:c.');
-end;
-
-procedure TIPFWriter.DescrEndTableHeadRow;
-begin
-  WriteLn('');
-end;
-
-procedure TIPFWriter.DescrBeginTableRow;
-begin
-  if not TableCaptionWritten then
-    DescrEndTableCaption;
-  TableRowStartFlag := True;
-  WriteLn(':row.:c.');
-end;
-
-procedure TIPFWriter.DescrEndTableRow;
-begin
-end;
-
-procedure TIPFWriter.DescrBeginTableCell;
-begin
-  if TableRowStartFlag then
-    TableRowStartFlag := False
-  else
-    WriteLn(':c.');
-end;
-
-procedure TIPFWriter.DescrEndTableCell;
-begin
-  WriteLn('');
-  // Do nothing
-end;
-
-
-function TIPFWriter.ConstValue(ConstDecl: TPasConst): String;
-begin
-  if Assigned(ConstDecl) then
-    Result := ConstDecl.ClassName
-  else
-    Result := '<nil>';
-end;
-
-procedure TIPFWriter.WriteUnitOverview(ASection: TPasSection);
-var
-  i: Integer;
-  UnitRef: TPasType;
-  DocNode: TDocNode;
-begin
-  if ASection.UsesList.Count > 0 then
-  begin
-    WriteLnF(':h2.%s', [SDocUsedUnits]);
-    WriteLn(':ol.');
-    for i := 0 to ASection.UsesList.Count - 1 do
-    begin
-      UnitRef := TPasType(ASection.UsesList[i]);
-      WriteLnF(':li.%s', [UnitRef.Name]);
-    end;
-    WriteLn(':eol.');
-  end;
-  DocNode := Engine.FindDocNode(ASection.Parent);
-  if Assigned(DocNode) and not IsDescrNodeEmpty(DocNode.Descr) then
-  begin
-    WriteLnF(':h2.%s', [EscapeTex(SDocOverview)]);
-    WriteDescr(ASection.Parent, DocNode.Descr);
-    Writeln('');
-  end;
-end;
-
-procedure TIPFWriter.WriteResourceStrings(ASection: TPasSection);
-var
-  ResStrDecl: TPasResString;
-  i: Integer;
-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, '');
-      Writeln(ResStrDecl.GetDeclaration(True));
-      EndListing;
-      WriteLabel(ResStrDecl);
-      WriteIndex(ResStrDecl);
-      WriteDescr(ResStrDecl);
-      Writeln('');
-    end;
-  end;
-end;
-
-procedure TIPFWriter.WriteConsts(ASection: TPasSection);
-var
-  i: Integer;
-  ConstDecl: TPasConst;
-begin
-  if ASection.Consts.Count > 0 then
-  begin
-    WriteLnF(':h3 name=suse_%sconstants.%s', [EscapeTex(ModuleName), EscapeTex(SDocConstants)]);
-    for i := 0 to ASection.Consts.Count - 1 do
-    begin
-      ConstDecl := TPasConst(ASection.Consts[i]);
-      StartListing(False);
-      WriteLn(EscapeTex(ConstDecl.GetDeclaration(True)));
-      EndListing;
-//      WriteLabel(ConstDecl);
-//      WriteIndex(ConstDecl);
-      WriteDescr(ConstDecl);
-    end;
-  end;
-end;
-
-procedure TIPFWriter.WriteEnumElements(TypeDecl : TPasEnumType);
-
-Var
-  EV : TPasEnumValue;
-  I : Integer;
-  DocNode : TDocNode;
-
-begin
-  With TypeDecl do
-    begin
-    SortElementList(Values);
-    DescrBeginTable(2,True);
-    DescrBeginTableCaption;
-      Writeln(EscapeTex(Format(SDocValuesForEnum,[TypeDecl.Name])));
-    DescrEndTableCaption;
-    DescrBeginTableHeadRow;
-      DescrBeginTableCell;
-        Writeln(EscapeTex(SDocValue));
-      DescrEndTableCell;
-      DescrBeginTableCell;
-        Writeln(EscapeTex(SDocExplanation));
-      DescrEndTableCell;
-    DescrEndTableHeadRow;
-    For I:=0 to Values.Count-1 do
-      begin
-      EV:=TPasEnumValue(Values[i]);
-      DescrBeginTableRow;
-        DescrBeginTableCell;
-          Writeln(EscapeTex(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 TIPFWriter.WriteTypes(ASection: TPasSection);
-var
-  i: Integer;
-  TypeDecl: TPasType;
-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]);
-      WriteLn(':h4 name='+GetLabel(TypeDecl)+'.');
-//      WriteLn(':hdref refid='+GetLabel(TypeDecl)+'.');
-//      WriteLabel(TypeDecl);
-//      WriteIndex(TypeDecl);
-      StartListing(False);
-      Writeln(EscapeTex(TypeDecl.GetDeclaration(True)));
-      EndListing;
-      If TypeDecl is TPasEnumType then
-        begin
-        WriteENumElements(TypeDecl as TPasEnumType);
-        end;
-      WriteDescr(TypeDecl);
-    end;
-  end;
-end;
-
-procedure TIPFWriter.WriteVars(ASection: TPasSection);
-var
-  VarDecl: TPasVariable;
-  i: Integer;
-begin
-  if ASection.Variables.Count > 0 then
-  begin
-    StartSubsection(SDocVariables,ModuleName+'Variables');
-    for i := 0 to ASection.Variables.Count - 1 do
-    begin
-//      WriteIndex(VarDecl);
-      VarDecl := TPasVariable(ASection.Variables[i]);
-      WriteLn(':h4 name='+GetLabel(VarDecl)+'.');
-      StartListing(False);
-      WriteLn(EscapeTex(VarDecl.GetDeclaration(True)));
-      EndListing;
-      WriteDescr(VarDecl);
-    end;
-  end;
-end;
-
-procedure TIPFWriter.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 TIPFWriter.WriteProcedure(ProcDecl : TPasProcedureBase);
-var
-  DocNode: TDocNode;
-  OP : TPasOverloadedProc;
-  i : integer;
-begin
-  With ProcDecl do
-    begin
-    if Not (Assigned(Parent) and Parent.InheritsFrom(TPasClassType)) then
-      begin
-      StartSubSection(Name, GetLabel(ProcDecl));
-//      WriteLabel(ProcDecl);
-//      WriteIndex(ProcDecl);
-      end
-    else
-      begin // Parent assigned and hence method.
-      StartSubSection(Parent.Name+'&per.'+Name, GetLabel(ProcDecl));
-//      WriteLabel(ProcDecl);
-//      WriteIndex(Parent.Name+'.'+Name);
-      end;
-//    Writeln('\begin{FPCList}');
-    DocNode := Engine.FindDocNode(ProcDecl);
-    if Assigned(DocNode) and Assigned(DocNode.ShortDescr) then
-      begin
-      Writeln(':hp2.Synopsis:ehp2.&colon. ');
-      WriteDescr(ProcDecl, DocNode.ShortDescr);
-      WriteLn('');
-      WriteLn('.br');
-      end;
-    Writeln(':hp2.Declaration:ehp2.&colon. ');
-    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;
-    WriteLn('');
-    WriteLn('.br');
-    If Assigned(Parent) then
-      begin
-      Writeln(':hp2.Visibility:ehp2.&colon. ');
-      Writeln(VisibilityNames[Visibility]);
-      WriteLn('');
-      WriteLn('.br');
-      end;
-    if Assigned(DocNode) and Assigned(DocNode.Descr) then
-      begin
-      Writeln(':hp2.Description:ehp2.&colon. ');
-      WriteDescr(ProcDecl);
-      WriteLn('');
-      WriteLn('.br');
-      end;
-    if Assigned(DocNode) and Assigned(DocNode.ErrorsDoc) then
-      begin
-      Writeln(':hp2.Errors:ehp2.&colon.');
-      WriteDescr(ProcDecl, DocNode.ErrorsDoc);
-      WriteLn('');
-      WriteLn('.br');
-      end;
-    WriteSeeAlso(DocNode);
-    WriteLn('');
-    WriteLn('.br');
-//    Writeln('\end{FPCList}');
-    WriteExample(DocNode);
-    end;
-end;
-
-procedure TIPFWriter.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 TIPFWriter.WriteExample(ADocNode: TDocNode);
-var
-  Example: TDOMElement;
-begin
-  if Assigned(ADocNode) then
-  begin
-    Example := ADocNode.FirstExample;
-    while Assigned(Example) do
-    begin
-      WritelnF(':xmp.%s:exmp.', [EscapeTex(Engine.GetExampleFileName(Example))]);
-      if Assigned(Example.NextSibling) then
-        WriteLn('');
-      Example := TDomElement(Example.NextSibling);
-    end;
-  end;
-end;
-
-procedure TIPFWriter.WriteSeeAlso(ADocNode: TDocNode);
-var
-  Node: TDOMNode;
-  s: String;
-begin
-  if Assigned(ADocNode) and Assigned(ADocNode.SeeAlso) and
-    Assigned(ADocNode.SeeAlso.FirstChild) then
-  begin
-    Writeln(':hp2.SeeAlso:ehp2.');
-    Node := ADocNode.SeeAlso.FirstChild;
-    while Assigned(Node) do
-    begin
-      if (Node.NodeType = ELEMENT_NODE) and
-        (Node.NodeName = 'link') then
-      begin
-        S:=TDomElement(Node)['id'];
-        DescrBeginLink(S);
-        Writeln(S);
-        DescrEndLink();
-        if Assigned(Node.NextSibling) Then
-          Writeln(',');
-      end;
-      Node:=Node.NextSibling;
-    end;
-  end;
-end;
-
-procedure TIPFWriter.WriteClasses(ASection: TPasSection);
-var
-  i: Integer;
-begin
-  if (ASection.Classes.Count > 0) then
-  begin
-    for i := 0 to ASection.Classes.Count - 1 do
-      WriteClassDecl(TPasClassType(ASection.Classes[i]));
-  end;
-
-end;
-
-procedure TIPFWriter.ProcessSection(ASection: TPasSection);
-begin
-  With ASection do
-    begin
-    SortElementList(UsesList);
-    SortElementList(Declarations);
-    SortElementList(ResStrings);
-    SortElementList(Types);
-    SortElementList(Consts);
-    SortElementList(Classes);
-    SortElementList(Functions);
-    SortElementList(Variables);
-    end;
-  WriteUnitOverView(ASection);
-  WriteVarsConstsTypes(ASection);
-  WriteFunctionsAndProcedures(ASection);
-  WriteClasses(ASection);
-end;
-
-Function TIPFWriter.ShowMember(M : TPasElement) : boolean;
-
-begin
-  Result:=not ((M.Visibility=visPrivate) and Engine.HidePrivate);
-  If Result then
-    Result:=Not ((M.Visibility=visProtected) and Engine.HideProtected)
-end;
-
-procedure TIPFWriter.WriteClassMethodOverview(ClassDecl : TPasClassType);
-var
-  Member: TPasElement;
-  i: Integer;
-  DocNode: TDocNode;
-  List : TStringList;
-
-begin
-  List:=TStringList.Create;
-  Try
-    List.Sorted:=True;
-    for i := 0 to ClassDecl.Members.Count - 1 do
-      begin
-      Member := TPasElement(ClassDecl.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, GetLabel(ClassDecl) + ':Methods');
-//      WriteLabel();
-      WriteLn(':parml.');
-//      WriteLnF('%s & %s & %s \\ \hline',  [EscapeTex(SDocPage), EscapeTex(SDocMethod), EscapeTex(SDocDescription)]);
-      For I:=0 to List.Count-1 do
-        begin
-        Member:=TPasElement(List.Objects[i]);
-        DocNode := Engine.FindDocNode(Member);
-        WriteF(':pt.:link reftype=hd refid=%s.%s:elink.:pd.',[StripTex(GetLabel(Member)), EscapeTex(Member.Name)]);
-        if Assigned(DocNode) and Assigned(DocNode.ShortDescr) then
-          WriteDescr(Member, DocNode.ShortDescr);
-        WriteLn('');
-        WriteLn('.br');
-        end;
-      WriteLn(':eparml.');
-//      WriteLn('\end{tabularx}');
-      end;
-  Finally
-    List.Free;
-  end;
-end;
-
-procedure TIPFWriter.WriteClassPropertyOverview(ClassDecl : TPasClassType);
-var
-  Member: TPasElement;
-  i: Integer;
-  s: String;
-  DocNode: TDocNode;
-  List : TStringList;
-
-begin
-  // Write property overview
-  List:=TStringList.Create;
-  Try
-    List.Sorted:=True;
-    for i := 0 to ClassDecl.Members.Count - 1 do
-      begin
-      Member := TPasElement(ClassDecl.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, GetLabel(ClassDecl) + ':Properties');
-//      WriteLabel(GetLabel(ClassDecl) + ':Properties');
-      WriteLn(':parml.');
-//      WriteLn('\begin{tabularx}{\textwidth}{lllX}');
-//      WriteLnF('%s & %s & %s & %s \\ \hline',
-//        [EscapeTex(SDocPage), EscapeTex(SDocProperty), EscapeTex(SDocAccess), EscapeTex(SDocDescription)]);
-      For I:=0 to List.Count-1 do
-        begin
-        Member:=TPasElement(List.objects[i]);
-        WriteF(':pt.:link reftype=hd refid=%s.%s:elink.:pd.',[StripTex(GetLabel(Member)), EscapeTex(Member.Name)]);
-        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';
-//        Write(s + ' & ');
-        DocNode := Engine.FindDocNode(Member);
-        if Assigned(DocNode) and Assigned(DocNode.ShortDescr) then
-          WriteDescr(Member, DocNode.ShortDescr);
-        WriteLn('');
-        WriteLn('.br');
-        end;
-      WriteLn(':eparml.');
-      end;
-  Finally
-    List.Free;
-  end;
-end;
-
-
-procedure TIPFWriter.WriteClassDecl(ClassDecl: TPasClassType);
-var
-  DocNode: TDocNode;
-  Vis: TPasMemberVisibilities;
-  Member: TPasElement;
-  i: Integer;
-begin
-  StartSection(ClassDecl.Name, GetLabel(ClassDecl));
-//  WriteLabel(ClassDecl);
-//  WriteIndex(ClassDecl);
-  DocNode := Engine.FindDocNode(ClassDecl);
-  if Assigned(DocNode) and ((not IsDescrNodeEmpty(DocNode.Descr)) or
-    (not IsDescrNodeEmpty(DocNode.ShortDescr))) then
-  begin
-//    StartSubSection(SDocDescription, GetLabel(ClassDecl) + ':Description');
-    WriteDescr(ClassDecl);
-  end;
-
-  // Write method overview
-  WriteClassMethodOverView(ClassDecl);
-  // Write Property Overview;
-  WriteClassPropertyOverView(ClassDecl);
-
-  // Write method & property descriptions
-
-  // Determine visibilities
-
-  Vis := AllVisibilities;
-  if Engine.HidePrivate then
-    Exclude(Vis,visPrivate);
-  if Engine.HideProtected then
-    Exclude(Vis,visProtected);
-
-  for i := 0 to ClassDecl.Members.Count - 1 do
-    begin
-    Member := TPasElement(ClassDecl.Members[i]);
-    if ((Member.InheritsFrom(TPasProcedureBase)) and
-        (Member.Visibility in Vis)) 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
-        (Member.Visibility in Vis)) then
-      WriteProperty(TPasProperty(Member));
-    end;
-
-end;
-
-procedure TIPFWriter.WriteProperty(PropDecl : TPasProperty);
-var
-  DocNode: TDocNode;
-  S: String;
-begin
-  With PropDecl do
-    begin
-    StartSubSection(Parent.Name+'&per.'+Name, GetLabel(PropDecl));
-//    WriteLabel(PropDecl);
-//    WriteIndex(Parent.Name+'.'+Name);
-//    Writeln('\begin{FPCList}');
-    DocNode := Engine.FindDocNode(PropDecl);
-    if Assigned(DocNode) and Assigned(DocNode.ShortDescr) then
-      begin
-      Writeln(':hp2.Synopsis:ehp2.&colon. ');
-      WriteDescr(PropDecl, DocNode.ShortDescr);
-      WriteLn('');
-      WriteLn('.br');
-      end;
-    Writeln(':hp2.Declaration:ehp2.&colon. ');
-    StartListing(False);
-    WriteLn('Property '+GetDeclaration(True));
-    EndListing;
-    WriteLn('');
-    WriteLn('.br');
-    If Assigned(Parent) then
-      begin
-      Writeln(':hp2.Visibility:ehp2.&colon. ');
-      Writeln(VisibilityNames[Visibility]);
-      WriteLn('');
-      WriteLn('.br');
-      end;
-    Writeln(':hp2.Access:ehp2.&colon.');
-    Setlength(S,0);
-    If Length(ReadAccessorName) > 0 then
-      S:='Read';
-    if Length(WriteAccessorName) > 0 then
-      begin
-      If S<>'' then
-        S:=S+',';
-      S:=S+'Write';
-      end;
-    Writeln(S);
-    WriteLn('');
-    WriteLn('.br');
-    if Assigned(DocNode) and Assigned(DocNode.Descr) then
-      begin
-      Writeln(':hp2.Description:ehp2.&colon.');
-      WriteDescr(PropDecl);
-      WriteLn('');
-      WriteLn('.br');
-      end;
-    if Assigned(DocNode) and Assigned(DocNode.ErrorsDoc) then
-      begin
-      Writeln(':hp2.Errors:ehp2.&colon. ');
-      WriteDescr(PropDecl, DocNode.ErrorsDoc);
-      WriteLn('');
-      WriteLn('.br');
-      end;
-    WriteSeeAlso(DocNode);
-    WriteLn('');
-      WriteLn('.br');
-//    Writeln('\end{FPCList}');
-    WriteExample(DocNode);
-    end;
-end;
-
-Function CompareElements(P1,P2 : Pointer) : Integer;
-
-begin
-  Result:=CompareText(TPasElement(P1).Name,TPasElement(P2).Name);
-end;
-
-procedure TIPFWriter.SortElementList(List : TList);
-
-begin
-  List.Sort(@CompareElements)
-end;
-
-
-procedure TIPFWriter.WriteLabel(El: TPasElement);
-begin
-  WriteLabel(GetLabel(El));
-end;
-
-procedure TIPFWriter.WriteLabel(const s: String);
-var
-  x: String;
-begin
-  X:=s;
-  While pos(':',x)>0 do x[pos(':',x)]:='_';
-  WriteF('%s', [LowerCase(StripTex(x))]);
-end;
-
-procedure TIPFWriter.WriteIndex(El : TPasElement);
-begin
-  WriteIndex(El.Name);
-end;
-
-procedure TIPFWriter.WriteIndex(const s : String);
-begin
-//  Write('\index{');
-//  Write(EscapeTex(s));
-//  Writeln('}');
-end;
-
-procedure TIPFWriter.StartListing(Frames: Boolean; const name: String);
-begin
-  Writeln(':xmp.')
-end;
-
-procedure TIPFWriter.StartListing(Frames : Boolean);
-begin
-  StartListing(Frames,'');
-end;
-
-procedure TIPFWriter.EndListing;
-begin
-  Writeln(':exmp.')
-end;
-
-procedure TIPFWriter.WriteCommentLine;
-const
-  CommentLine =
-    '.* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%';
-begin
-  WriteLn('');
-  Writeln(CommentLine);
-end;
-
-procedure TIPFWriter.WriteComment(Comment : String);
-begin
-//  Write('.* ');
-//  Writeln(Comment);
-end;
-
-
-procedure TIPFWriter.StartSection(SectionName : String; SectionLabel : String);
-begin
-//  StartSection(SectionName);
-  WriteCommentLine;
-  WriteComment(SectionName);
-  Write(':h2 name=');
-  WriteLabel(SectionLabel);
-  WriteLn('.'+EscapeTex(SectionName));
-end;
-
-//procedure TIPFWriter.StartSection(SectionName : String);
-//begin
-//end;
-
-procedure TIPFWriter.StartSubSection(SubSectionName : String; SubSectionLabel : String);
-begin
-  Writeln('');
-  WriteComment(SubsectionName);
-  Write(':h3 name=');
-  WriteLabel(SubsectionLabel);
-  WriteLn('.'+{EscapeTex(}SubSectionName{)});
-end;
-
-//procedure TIPFWriter.StartSubSection(SubSectionName : String);
-//begin
-//end;
-
-procedure TIPFWriter.StartChapter(ChapterName : String; ChapterLabel : String);
-begin
-  StartChapter(ChapterName);
-  WriteLabel(ChapterLabel);
-end;
-
-procedure TIPFWriter.StartChapter(ChapterName : String);
-begin
-  Writeln('');
-  WriteCommentLine;
-  WriteComment(ChapterName);
-  WriteCommentLine;
-  Writeln(':h1.'+{EscapeTex(}ChapterName{)});
-end;
-
-
-
-initialization
-  // Do not localize.
-  RegisterWriter(TIPFWriter,'ipf','IPF output.');
-finalization
-  UnRegisterWriter('ipf');
-end.

+ 1010 - 0
utils/fpdoc/dw_ipflin.pas

@@ -0,0 +1,1010 @@
+{
+    FPDoc IPF Writer
+    Copyright (c) 2010 by Graeme Geldenhuys ([email protected])
+
+    * Linear IPF output for use with fpGUI or OS/2's help systems.
+
+    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.
+}
+unit dw_ipflin;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, DOM, dGlobals, PasTree, dwLinear;
+
+const
+  { Change this into the name of your writer}
+  IPFWriterName = 'ipf';
+  { Comprehensible description goes here:}
+  SIPFUsageWriterDescr = 'Writes output in fpGUI and OS/2''s IPF help format';
+  { Extension for the template }
+  TIPFExtension = '.ipf';
+
+type
+  TIPFNewWriter = class(TLinearWriter)
+  private
+    InPackageOverview: Boolean;
+    InHeading: Boolean;
+    FInHeadingText: string;
+    OrderedList: boolean;
+    TableRowStartFlag: Boolean;
+    TableCaptionWritten: Boolean;
+    InTableCell: Boolean;
+    InTypesDeclaration: Boolean;
+    SuspendWriting: Boolean;
+    LastSubSection: String;
+  protected
+    FLink: String;
+    FTableCount : Integer;
+    FInVerbatim : Boolean;
+    Inlist,
+    fColCount: integer;
+    // extras
+    procedure Write(const s: String); override;
+    procedure WriteBeginDocument; override;
+    procedure WriteEndDocument; override;
+    // Linear documentation methods overrides;
+    procedure WriteLabel(Const S : String); override;
+    procedure WriteIndex(Const S : String); override;
+    procedure WriteType(const s: string); override;
+    procedure WriteVariable(const s: string); override;
+    procedure WriteConstant(const s: string); override;
+    Procedure WriteExampleFile(FN : String); override;
+    Procedure StartProcedure; override;
+    Procedure EndProcedure; override;
+    Procedure StartProperty; override;
+    Procedure EndProperty; override;
+    Procedure StartSynopsis; override;
+    Procedure StartDeclaration; override;
+    Procedure StartVisibility; override;
+    Procedure StartDescription; override;
+    Procedure StartAccess; override;
+    Procedure StartErrors; override;
+    Procedure StartVersion; override;
+    Procedure StartSeealso; override;
+    Procedure EndSeealso; override;
+    procedure StartUnitOverview(AModuleName,AModuleLabel : String);override;
+    procedure WriteUnitEntry(UnitRef : TPasType); override;
+    Procedure EndUnitOverview; override;
+    function  GetLabel(AElement: TPasElement): String; override;
+    procedure StartListing(Frames: Boolean; const name: String); override;
+    procedure EndListing; override;
+    Function  EscapeText(S : String) : String; override;
+    Function  StripText(S : String) : String; override;
+    procedure WriteCommentLine; override;
+    procedure WriteComment(Comment : String);override;
+    procedure StartSection(SectionName : String);override;
+    procedure StartSubSection(SubSectionName : String);override;
+    procedure StartSubSubSection(SubSubSectionName : String);override;
+    procedure StartChapter(ChapterName : String); override;
+    procedure StartOverview(WithAccess : Boolean); override;
+    procedure EndOverview; override;
+    procedure WriteOverviewMember(const ALabel,AName,Access,ADescr : String); override;
+    procedure WriteOverviewMember(const ALabel,AName,ADescr : String); override;
+    class function FileNameExtension: string; override;
+    procedure DescrBeginURL(const AURL: DOMString); override;
+    procedure DescrEndURL; override;
+    // Description node conversion. Overrides for TFPDocWriter.
+    procedure DescrBeginBold; override;
+    procedure DescrEndBold; override;
+    procedure DescrBeginItalic; override;
+    procedure DescrEndItalic; override;
+    procedure DescrBeginEmph; override;
+    procedure DescrEndEmph; override;
+    procedure DescrWriteText(const AText: 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 DescrWriteLinebreak; override;
+    procedure DescrBeginParagraph; override;
+    procedure DescrBeginCode(HasBorder: Boolean; const AHighlighterName: String); override;
+    procedure DescrWriteCodeLine(const ALine: String); override;
+    procedure DescrEndCode; override;
+    procedure DescrEndParagraph; 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;
+    // TFPDocWriter class methods
+  public
+    constructor Create(APackage: TPasPackage; AEngine: TFPDocEngine); override;
+  end;
+
+
+
+implementation
+
+uses
+  SysUtils, dwriter;
+
+
+{ TFPDocWriter overrides }
+
+
+procedure TIPFNewWriter.DescrBeginBold;
+begin
+  { Start bold output }
+  WriteLn(':hp2.');
+end;
+
+procedure TIPFNewWriter.DescrEndBold;
+begin
+  { End bold output }
+  WriteLn(':ehp2.');
+end;
+
+procedure TIPFNewWriter.DescrBeginItalic;
+begin
+  { Start italic output }
+  WriteLn(':hp1.');
+end;
+
+procedure TIPFNewWriter.DescrEndItalic;
+begin
+  { End italic output }
+  WriteLn(':ehp1.');
+end;
+
+procedure TIPFNewWriter.DescrBeginEmph;
+begin
+  { Start emphasized output }
+  Write(':hp1.');
+end;
+
+procedure TIPFNewWriter.DescrEndEmph;
+begin
+  { End emphasized output }
+  Write(':ehp1.');
+end;
+
+procedure TIPFNewWriter.DescrWriteText(const AText: DOMString);
+const
+  cMax = 100;
+var
+  sl: TStringlist;
+  ns: string;
+  i: integer;
+  lText: string;
+begin
+  // IPF has an imposed line length limit.
+  if (Length(AText) > cMax) then // then we need to wrap the text.
+  begin
+    lText := WrapText(AText, LineEnding, [' ', '-', #9], cMax);
+    sl := TStringlist.Create;
+    try
+      sl.Text := lText;
+      for i := 0 to sl.Count-1 do
+        inherited DescrWriteText(sl.Strings[i] + LineEnding);
+    finally
+      sl.Free;
+    end;
+  end
+  else
+    inherited DescrWriteText(AText);
+end;
+
+procedure TIPFNewWriter.DescrWriteFileEl(const AText: DOMString);
+begin
+  { format as file name }
+  Write(':hp3.');
+  DescrWriteText(AText);
+  Write(':ehp3.');
+end;
+
+procedure TIPFNewWriter.DescrWriteKeywordEl(const AText: DOMString);
+begin
+  { Format as keyword }
+  Write(':hp1.');
+  DescrWriteText(AText);
+  Write(':ehp1.');
+end;
+
+procedure TIPFNewWriter.DescrWriteVarEl(const AText: DOMString);
+begin
+  { Format as variable }
+  Write(':hp1.');
+  DescrWriteText(AText);
+  Write(':ehp1.');
+end;
+
+procedure TIPFNewWriter.DescrBeginLink(const AId: DOMString);
+begin
+  { Start link to label ID - links are never nested.}
+  FLink := Engine.ResolveLink(Module, AId);
+  FLink := StringReplace(FLink, ':', '_', [rfReplaceAll]);
+  FLink := StringReplace(FLink, '.', '_', [rfReplaceAll]);
+  WriteF(':link reftype=hd refid=%s.', [flink]);
+end;
+
+procedure TIPFNewWriter.DescrEndLink;
+begin
+  { End link to label ID}
+  Write(':elink.');
+end;
+
+procedure TIPFNewWriter.DescrWriteLinebreak;
+begin
+  { Start a new line. }
+  WriteLn('');
+  WriteLn('.br'); // must be at the beginning of a line, hence the previous writeln call
+end;
+
+procedure TIPFNewWriter.DescrBeginParagraph;
+begin
+  { Start a new paragraph }
+  Writeln(':p.');
+end;
+
+procedure TIPFNewWriter.DescrEndParagraph;
+begin
+  { End current paragraph }
+  writeln('');
+end;
+
+procedure TIPFNewWriter.DescrBeginCode(HasBorder: Boolean;
+  const AHighlighterName: String);
+begin
+  { Start block of code }
+  StartListing(HasBorder,'');
+end;
+
+procedure TIPFNewWriter.DescrWriteCodeLine(const ALine: String);
+begin
+  { Write line of code }
+  DescrWriteText(ALine + LineEnding);
+//  writeln(EscapeText(ALine));
+end;
+
+procedure TIPFNewWriter.DescrEndCode;
+begin
+  { End block of code }
+  EndListing;
+end;
+
+procedure TIPFNewWriter.DescrBeginOrderedList;
+begin
+  {  Start numbered list }
+  OrderedList := True;
+  writeln('');
+  writeln(':ol.');
+end;
+
+procedure TIPFNewWriter.DescrEndOrderedList;
+begin
+  {  End numbered list }
+  writeln('');
+  writeln(':eol.');
+//  writeln(':p.');
+end;
+
+procedure TIPFNewWriter.DescrBeginUnorderedList;
+begin
+  {  Start bulleted list }
+  OrderedList := False;
+  writeln('');
+  if not InTableCell then
+    writeln(':ul.')
+  else
+    writeln(':lines.');
+end;
+
+procedure TIPFNewWriter.DescrEndUnorderedList;
+begin
+  {  End bulleted list }
+  writeln('');
+  if not InTableCell then
+    writeln(':eul.')
+  else
+    writeln(':elines.');
+end;
+
+procedure TIPFNewWriter.DescrBeginDefinitionList;
+begin
+  {  Start definition list }
+  writeln('');
+  writeln(':dl tsize=25 compact.');
+end;
+
+procedure TIPFNewWriter.DescrEndDefinitionList;
+begin
+  {  End definition list }
+  writeln('');
+  writeln(':edl.');
+//  writeln(':p.');
+end;
+
+procedure TIPFNewWriter.DescrBeginListItem;
+begin
+  {  Start list item (both bulleted/numbered) }
+  if not InTableCell then
+    write(':li.');
+end;
+
+procedure TIPFNewWriter.DescrEndListItem;
+begin
+  {  End list item (both bulleted/numbered) }
+  writeln('');
+end;
+
+procedure TIPFNewWriter.DescrBeginDefinitionTerm;
+begin
+  {  Start definition term }
+  writeln(':dt.');
+end;
+
+procedure TIPFNewWriter.DescrEndDefinitionTerm;
+begin
+  {  End definition term }
+  writeln('');
+end;
+
+procedure TIPFNewWriter.DescrBeginDefinitionEntry;
+begin
+  {  start definition explanation }
+  writeln(':dd.');
+end;
+
+procedure TIPFNewWriter.DescrEndDefinitionEntry;
+begin
+  {  End definition explanation }
+  writeln('');
+end;
+
+procedure TIPFNewWriter.DescrBeginSectionTitle;
+begin
+  {  Start section title }
+end;
+
+procedure TIPFNewWriter.DescrBeginSectionBody;
+begin
+  {  Start section body }
+end;
+
+procedure TIPFNewWriter.DescrEndSection;
+begin
+  {  End section body }
+end;
+
+procedure TIPFNewWriter.DescrBeginRemark;
+begin
+  {  Start remark paragraph }
+  writeln('');
+  writeln(':nt text=''Remark: ''.');
+end;
+
+procedure TIPFNewWriter.DescrEndRemark;
+begin
+  {  End remark paragraph }
+  writeln('');
+  writeln(':ent.');
+end;
+
+procedure TIPFNewWriter.DescrBeginTable(ColCount: Integer; HasBorder: Boolean);
+var
+  i: integer;
+  cols: string;
+  f: string;
+begin
+  {  Start table with ColCount columns, and with border }
+  cols := '';
+  for i := 0 to ColCount-1 do
+  begin
+    if i = 0 then
+      cols := cols + '35 '  // first colum is 30 characters
+    else
+      cols := cols + '50 '; // every other colum is 50 characters each
+  end;
+  if HasBorder then
+    f := ' frame=box.'
+  else
+    f := ' frame=none.';
+  writeln(':table cols=''' + Trim(cols) + ''' rules=both' + f);
+end;
+
+procedure TIPFNewWriter.DescrEndTable;
+begin
+  writeln(':etable.');
+end;
+
+procedure TIPFNewWriter.DescrBeginTableCaption;
+begin
+  //writeln('.* GG');
+  SuspendWriting := True;
+  // do nothing
+//  TableCaptionWritten := False;
+end;
+
+procedure TIPFNewWriter.DescrEndTableCaption;
+begin
+  // do nothing
+  SuspendWriting := False;
+  writeln('');
+end;
+
+procedure TIPFNewWriter.DescrBeginTableHeadRow;
+begin
+//  TableCaptionWritten := True;
+  SuspendWriting := False;
+  writeln(':row.');
+end;
+
+procedure TIPFNewWriter.DescrEndTableHeadRow;
+begin
+  // do nothing
+end;
+
+procedure TIPFNewWriter.DescrBeginTableRow;
+begin
+//  TableCaptionWritten := True;
+  SuspendWriting := False;
+  writeln(':row.');
+end;
+
+procedure TIPFNewWriter.DescrEndTableRow;
+begin
+  writeln('');
+end;
+
+procedure TIPFNewWriter.DescrBeginTableCell;
+begin
+  write(':c.');
+  InTableCell := True;
+end;
+
+procedure TIPFNewWriter.DescrEndTableCell;
+begin
+  // do nothing
+  writeln('');
+  InTableCell := False;
+end;
+
+constructor TIPFNewWriter.Create(APackage: TPasPackage; AEngine: TFPDocEngine);
+begin
+  inherited Create(APackage, AEngine);
+  TableCaptionWritten := True;
+  SuspendWriting := False;
+  InTableCell := False;
+  InTypesDeclaration := False;
+end;
+
+{ TLinearWriter overrides}
+
+class function TIPFNewWriter.FileNameExtension: String;
+begin
+  Result := TIPFExtension;
+end;
+
+procedure TIPFNewWriter.DescrBeginURL(const AURL: DOMString);
+begin
+  //Write(EscapeText(AURL));
+end;
+
+procedure TIPFNewWriter.DescrEndURL;
+begin
+  // do nothing
+end;
+
+function TIPFNewWriter.GetLabel(AElement: TPasElement): String;
+var
+  i: Integer;
+begin
+  if AElement.ClassType = TPasUnresolvedTypeRef then
+    Result := Engine.ResolveLink(Module, AElement.Name)
+  else
+  begin
+    Result := AElement.PathName;
+    Result := LowerCase(Copy(Result, 2, Length(Result) - 1));   // Remove # infront of eg: '#Corelib' string
+  end;
+  Result := StringReplace(Result, '.', '_', [rfReplaceAll]);
+  Result := StringReplace(Result, ' ', '_', [rfReplaceAll]);
+end;
+
+Function TIPFNewWriter.EscapeText(S : String) : String;
+var
+  i: Integer;
+begin
+  SetLength(Result, 0);
+  for i := 1 to Length(S) do
+    case S[i] of
+      '.':              // Escape these characters
+        Result := Result + '&per.';
+      ':':
+        Result := Result + '&colon.';
+      ',':
+        Result := Result + '&comma.';
+      '&':
+        Result := Result + '&amp.';
+//      '_':
+//        Result := Result + '&us.';
+      '^':
+        Result := Result + '&caret.';
+      '''':
+        Result := Result + '&apos.';
+      '*':
+        Result := Result + '&asterisk.';
+      '@':
+        Result := Result + '&atsign.';
+      '\':
+        Result := Result + '&bslash.';
+      '"':
+        Result := Result + '&cdq.';
+      '-':
+        Result := Result + '&hyphen.';
+      //'°':
+      //  Result := Result + '&degree.';
+      '$':
+        Result := Result + '&dollar.';
+      '=':
+        Result := Result + '&eq.';
+      '!':
+        Result := Result + '&xclam.';
+      '>':
+        Result := Result + '&gt.';
+      '(':
+        Result := Result + '&lpar.';
+      ')':
+        Result := Result + '&rpar.';
+      '+':
+        Result := Result + '&plus.';
+      '[':
+        Result := Result + '&lbracket.';
+      ']':
+        Result := Result + '&rbracket.';
+      else
+        Result := Result + S[i];
+    end;
+end;
+
+Function TIPFNewWriter.StripText(S : String) : String;
+var
+  I,L: Integer;
+begin
+  //Result := S;
+  SetLength(Result, 0);
+  for i := 1 to Length(S) do
+    if not (S[i] in ['&','{','}','#'{,'_'},'$','%','''','~','^', '\', ' ', '<', '>']) then
+      Result := Result + S[i];
+end;
+
+procedure TIPFNewWriter.Write(const s: String);
+begin
+  if SuspendWriting then
+    Exit;
+  inherited Write(s);
+end;
+
+procedure TIPFNewWriter.WriteBeginDocument;
+begin
+  fColCount := 0;
+  Writeln(':userdoc.');
+  WriteComment('This file has been created automatically by FPDoc');
+  WriteComment('IPF output (c) 2010 by Graeme Geldenhuys ([email protected])');
+  writeln('');
+  Writeln(':docprof toc=12345.');
+  WriteLn(':title.' + PackageName);
+  writeln('');
+  writeln('');
+  writeln(':h1.' + PackageName);
+  InPackageOverview := True;
+//  inherited WriteBeginDocument;
+end;
+
+procedure TIPFNewWriter.WriteEndDocument;
+begin
+  inherited WriteEndDocument;
+  writeln('');
+  writeln('');
+  writeln(':euserdoc.');
+  writeln('');
+end;
+
+procedure TIPFNewWriter.WriteLabel(const s: String);
+var
+  x: String;
+begin
+  x := StringReplace(s, ':', '_', [rfReplaceAll]);
+
+  if InHeading and (x <> '') then
+  begin
+    WriteLnF(FInHeadingText, [ ' name=' + LowerCase(x)]); // LowerCase(StripTexT(x))]);
+    Writeln('');
+    FInHeadingText := '';
+    InHeading := False;
+  end
+  else
+  begin
+    WriteLnF(FInHeadingText, [ '' ]);
+    Writeln('');
+    FInHeadingText := '';
+    InHeading := False;
+  end;
+end;
+
+procedure TIPFNewWriter.WriteIndex(const s : String);
+begin
+//  writeln(':i1 id=' + s + '.');
+end;
+
+procedure TIPFNewWriter.WriteType(const s: string);
+begin
+  writeln('');
+  Writeln('.* -------------------------------------------------');
+  WriteLnF(':h5 name=%s.%s', [lowercase(PackageName+'_'+ModuleName+'_'+s), s]);
+//  inherited WriteType(s);
+end;
+
+procedure TIPFNewWriter.WriteVariable(const s: string);
+begin
+  writeln('');
+  Writeln('.* -------------------------------------------------');
+  WriteLnF(':h5 name=%s.%s', [lowercase(PackageName+'_'+ModuleName+'_'+s), s]);
+end;
+
+procedure TIPFNewWriter.WriteConstant(const s: string);
+begin
+  writeln('');
+  Writeln('.* -------------------------------------------------');
+  WriteLnF(':h5 name=%s.%s', [lowercase(PackageName+'_'+ModuleName+'_'+s), s]);
+end;
+
+procedure TIPFNewWriter.StartListing(Frames: Boolean; const name: String);
+begin
+//  writeln('');
+  writeln(':xmp.');
+end;
+
+procedure TIPFNewWriter.EndListing;
+begin
+  writeln(':exmp.');
+end;
+
+procedure TIPFNewWriter.WriteCommentLine;
+begin
+  Writeln('');
+  Writeln('.* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%');
+end;
+
+procedure TIPFNewWriter.WriteComment(Comment : String);
+begin
+  Writeln('.* ' + Comment);
+end;
+
+procedure TIPFNewWriter.StartChapter(ChapterName : String);
+begin
+  InHeading := True;
+  Writeln('');
+  Writeln('');
+  WriteCommentLine;
+  WriteComment('Chapter: ' + ChapterName);
+  WriteCommentLine;
+  FInHeadingText := ':h2%s. ' + ChapterName;
+  //Writeln(':h2.' + ChapterName);
+  //Writeln('');
+end;
+
+procedure TIPFNewWriter.StartSection(SectionName : String);
+begin
+  InHeading := True;
+  Writeln('');
+  Writeln('');
+  WriteCommentLine;
+  WriteComment('Section: ' + SectionName);
+  WriteCommentLine;
+  writeln('');
+
+  if SameText(SectionName, SDocOverview) then
+  begin
+    writeln(':p.');
+    writeln(':p.');
+    writeln(':lm margin=1.');
+    DescrBeginBold;
+    WriteLn(SDocOverview);
+    DescrEndBold;
+//    writeln(':lm margin=3.');
+    writeln('.br');
+  end;
+
+  if InPackageOverview then
+  begin
+    FInHeadingText := ':h2%s. ' + SectionName;
+//    Writeln(':h2.' + SectionName);
+    InPackageOverview := False;
+  end
+  else
+  begin
+    FInHeadingText := ':h3%s. ' + SectionName;
+//    Writeln(':h3.' + SectionName);
+  end;
+//  Writeln('');
+end;
+
+procedure TIPFNewWriter.StartSubSection(SubSectionName : String);
+begin
+  LastSubSection := Lowercase(SubSectionName);
+  InHeading := True;
+  Writeln('');
+  WriteCommentLine;
+  FInHeadingText := ':h4%s. ' + SubSectionName;
+  //Writeln(':h4.' + SubSectionName);
+end;
+
+procedure TIPFNewWriter.StartSubSubSection(SubSubSectionName : String);
+begin
+  InHeading := True;
+  FInHeadingText := ':h5%s. ' + SubSubSectionName;
+  //Writeln(':h5.' + SubSubSectionName);
+end;
+
+Procedure TIPFNewWriter.StartProcedure;
+begin
+  //writeln('');
+  //writeln(':ul.');
+end;
+
+Procedure TIPFNewWriter.EndProcedure;
+begin
+  //writeln('');
+  //writeln(':eul.');
+end;
+
+Procedure TIPFNewWriter.StartSynopsis;
+begin
+  writeln('');
+  writeln(':p.');
+  writeln(':lm margin=1.');
+  writeln(':hp2.' + SDocSynopsis + ':ehp2.');
+  writeln('.br');
+  writeln(':lm margin=3.');
+end;
+
+Procedure TIPFNewWriter.StartDeclaration;
+begin
+  writeln('');
+  writeln(':p.');
+  writeln(':lm margin=1.');
+  writeln(':hp2.' + SDocDeclaration + ':ehp2.');
+  writeln(':lm margin=3.');
+end;
+
+Procedure TIPFNewWriter.StartVisibility;
+begin
+  writeln('');
+  writeln(':p.');
+  writeln(':lm margin=1.');
+  writeln(':hp2.' + SDocVisibility + ':ehp2.');
+  writeln(':lm margin=3.');
+  writeln('.br');
+end;
+
+Procedure TIPFNewWriter.StartDescription;
+begin
+  writeln('');
+  writeln(':p.');
+  writeln(':lm margin=1.');
+  writeln(':hp2.' + SDocDescription + ':ehp2.');
+  writeln(':lm margin=3.');
+  writeln('.br');
+end;
+
+Procedure TIPFNewWriter.StartErrors;
+begin
+  writeln('');
+  writeln(':p.');
+  writeln(':lm margin=1.');
+  writeln(':hp2.' + SDocErrors + ':ehp2.');
+  writeln(':lm margin=3.');
+  writeln('.br');
+end;
+
+procedure TIPFNewWriter.StartVersion;
+begin
+  writeln('');
+  writeln(':p.');
+  writeln(':lm margin=1.');
+  writeln(':hp2.' + SDocVersion +':ehp2.');
+  writeln(':lm margin=3.');
+  writeln('.br');
+end;
+
+Procedure TIPFNewWriter.StartAccess;
+begin
+  writeln('');
+  writeln(':p.');
+  writeln(':lm margin=1.');
+  writeln(':hp2.' + SDocAccess + ':ehp2.');
+  writeln(':lm margin=3.');
+  writeln('.br');
+end;
+
+Procedure TIPFNewWriter.StartProperty;
+begin
+  //writeln('');
+  //Writeln('.* here I am');
+  //writeln(':ul.');
+end;
+
+Procedure TIPFNewWriter.EndProperty;
+begin
+  //writeln('');
+  //writeln(':eul.');
+end;
+
+procedure TIPFNewWriter.WriteExampleFile(FN : String);
+var
+  sl: TStringList;
+  i: integer;
+begin
+  if (FN<>'') then
+  begin
+    writeln('');
+    writeln('');
+    Writeln(':p.');
+    writeln(':lm margin=1.');
+    Writeln(':hp2.Example:ehp2.');
+    writeln(':lm margin=3.');
+    writeln('.br');
+    writeln('Filename&colon. :hp1.' + EscapeText(FN) + ':ehp1.');
+    writeln(':p.');
+
+    writeln(':xmp.');
+    //writeln(':im ' + FN);
+    sl := TStringList.Create;
+    try
+      sl.LoadFromFile(FN);
+      for i := 0 to sl.Count-1 do
+        Writeln(EscapeText(sl[i]));
+    finally
+      sl.Free;
+    end;
+    writeln(':exmp.');
+  end;
+end;
+
+procedure TIPFNewWriter.StartOverview(WithAccess : Boolean);
+begin
+{
+  If With access then it is a property overview.
+  Otherwise it is a method/function overview.
+  If tabular output is generated, the preferred output order is:
+  With access:
+  Col 1 : Page reference
+  Col 2 : Property Name
+  Col 3 : Accessibility (r/w)
+  Col 4 : Description
+  Without access:
+  Col 1 : Page reference
+  Col 2 : Method name
+  Col 3 : Description
+  (See the two WriteOverviewMember functions)
+}
+  writeln('');
+  writeln(':parml tsize=30 break=none compact.');
+//  FlushBuffer;
+end;
+
+procedure TIPFNewWriter.EndOverview;
+begin
+  { End of overview }
+  writeln('');
+  writeln(':eparml.');
+  writeln(':p.');
+//  FlushBuffer;
+end;
+
+procedure TIPFNewWriter.WriteOverviewMember(const ALabel,AName,Access,ADescr : String);
+var
+  s1, s2: string;
+begin
+  { Write one entry in property overview:
+  ALabel : Label, as returned by GetLabel
+  AName  : Property name
+  Access : Property acces (r/w/a)
+  Descr  : Description
+  }
+  s1 := StringReplace(ALabel, ':', '_', [rfReplaceAll]);
+  s2 := StringReplace(AName, ':', '_', [rfReplaceAll]);
+  WriteLn(Format(':pt. :link reftype=hd refid=%s.%s:elink. [%s]',[s1, s2, Access]));
+  WriteLn(Format(':pd. %s', [ADescr]));
+end;
+
+procedure TIPFNewWriter.WriteOverviewMember(const ALabel,AName,ADescr : String);
+var
+  s1, s2: string;
+begin
+  { Write one entry in method overview:
+  ALabel : Label, as returned by GetLabel
+  AName  : Method name
+  Descr  : Description
+  }
+  s1 := StringReplace(ALabel, ':', '_', [rfReplaceAll]);
+  s2 := StringReplace(AName, ':', '_', [rfReplaceAll]);
+  WriteLn(Format(':pt. :link reftype=hd refid=%s.%s :elink.',[s1, s2]));
+  WriteLn(Format(':pd. %s', [ADescr]));
+end;
+
+Procedure TIPFNewWriter.StartSeeAlso;
+begin
+  writeln('');
+  writeln(':p.');
+  writeln(':lm margin=1.');
+  writeln(':hp2.See Also:ehp2.');
+  writeln(':lm margin=3.');
+  writeln('.br');
+end;
+
+procedure TIPFNewWriter.EndSeealso;
+begin
+  writeln('');
+end;
+
+procedure TIPFNewWriter.StartUnitOverview(AModuleName,AModuleLabel : String);
+begin
+  { Start of unit overview.
+    AModuleName : Name of current unit.
+    AModuleLabel : Label name of current unit.
+  }
+  writeln('');
+  writeln(':p.');
+  writeln(':lm margin=1.');
+  DescrBeginBold;
+  writeln(EscapeText(Format(SDocUsedUnitsByUnitXY, [AModuleName])));
+  DescrEndBold;
+  writeln(':lm margin=3.');
+  writeln('.br');
+
+  writeln(':p.');
+  writeln(':ol.');
+end;
+
+procedure TIPFNewWriter.WriteUnitEntry(UnitRef : TPasType);
+begin
+  { Write one unit entry }
+  writeln(':li.' + EscapeText(UnitRef.Name));
+end;
+
+procedure TIPFNewWriter.EndUnitOverview;
+begin
+  { end of unit overview }
+  writeln(':eol.');
+end;
+
+
+initialization
+  // Do not localize IPFWriterName
+  RegisterWriter(TIPFNewWriter, IPFWriterName, SIPFUsageWriterDescr);
+finalization
+  UnRegisterWriter(IPFWriterName);
+end.

+ 4 - 4
utils/fpdoc/dw_latex.pp

@@ -77,8 +77,8 @@ Type
     procedure StartChapter(ChapterName : String); override;
     procedure StartChapter(ChapterName : String); override;
     procedure StartOverview(WithAccess : Boolean); override;
     procedure StartOverview(WithAccess : Boolean); override;
     procedure EndOverview; override;
     procedure EndOverview; override;
-    procedure WriteOverviewMember(ALabel,AName,Access,ADescr : String); override;
-    procedure WriteOverviewMember(ALabel,AName,ADescr : String); override;
+    procedure WriteOverviewMember(const ALabel,AName,Access,ADescr : String); override;
+    procedure WriteOverviewMember(const ALabel,AName,ADescr : String); override;
     Class Function FileNameExtension : String; override;
     Class Function FileNameExtension : String; override;
     // Description node conversion
     // Description node conversion
     procedure DescrBeginBold; override;
     procedure DescrBeginBold; override;
@@ -658,13 +658,13 @@ begin
   WriteLn('\end{tabularx}');
   WriteLn('\end{tabularx}');
 end;
 end;
 
 
-procedure TLatexWriter.WriteOverviewMember(ALabel,AName,Access,ADescr : String);
+procedure TLatexWriter.WriteOverviewMember(const ALabel,AName,Access,ADescr : String);
 
 
 begin
 begin
   WriteLnF('\pageref{%s} & %s & %s & %s \\',[ALabel,EscapeText(AName),Access,ADescr]);
   WriteLnF('\pageref{%s} & %s & %s & %s \\',[ALabel,EscapeText(AName),Access,ADescr]);
 end;
 end;
 
 
-procedure TLatexWriter.WriteOverviewMember(ALabel,AName,ADescr : String);
+procedure TLatexWriter.WriteOverviewMember(const ALabel,AName,ADescr : String);
 
 
 begin
 begin
   WriteLnF('\pageref{%s} & %s  & %s \\',[ALabel,EscapeText(AName),ADescr]);
   WriteLnF('\pageref{%s} & %s  & %s \\',[ALabel,EscapeText(AName),ADescr]);

+ 4 - 4
utils/fpdoc/dw_linrtf.pp

@@ -111,8 +111,8 @@ type
     procedure StartSubSubSection(SubSubSectionName : String);override;
     procedure StartSubSubSection(SubSubSectionName : String);override;
     procedure StartChapter(ChapterName : String); override;
     procedure StartChapter(ChapterName : String); override;
     procedure StartOverview(WithAccess : Boolean); override;
     procedure StartOverview(WithAccess : Boolean); override;
-    procedure WriteOverviewMember(ALabel,AName,Access,ADescr : String); override;
-    procedure WriteOverviewMember(ALabel,AName,ADescr : String); override;
+    procedure WriteOverviewMember(const ALabel,AName,Access,ADescr : String); override;
+    procedure WriteOverviewMember(const ALabel,AName,ADescr : String); override;
     procedure EndOverview; override;
     procedure EndOverview; override;
     Class Function FileNameExtension : String; override;
     Class Function FileNameExtension : String; override;
     // Description node conversion
     // Description node conversion
@@ -714,7 +714,7 @@ begin
         [EscapeText(SDocPage), EscapeText(SDocProperty), EscapeText(SDocDescription)]);
         [EscapeText(SDocPage), EscapeText(SDocProperty), EscapeText(SDocDescription)]);
 end;
 end;
 
 
-procedure TRTFWriter.WriteOverviewMember(ALabel,AName,Access,ADescr : String);
+procedure TRTFWriter.WriteOverviewMember(const ALabel,AName,Access,ADescr : String);
 begin
 begin
   //TODO: Translate Latex \pageref to RTF
   //TODO: Translate Latex \pageref to RTF
   //WriteLnF('\pageref{%s} & %s  & %s & %s \\',[ALabel,AName,Access,ADescr]);
   //WriteLnF('\pageref{%s} & %s  & %s & %s \\',[ALabel,AName,Access,ADescr]);
@@ -722,7 +722,7 @@ begin
       [ALabel,AName,Access,ADescr]);
       [ALabel,AName,Access,ADescr]);
 end;
 end;
 
 
-procedure TRTFWriter.WriteOverviewMember(ALabel,AName,ADescr : String);
+procedure TRTFWriter.WriteOverviewMember(const ALabel,AName,ADescr : String);
 begin
 begin
   //TODO: Translate Latex \pageref to RTF
   //TODO: Translate Latex \pageref to RTF
   //WriteLnF('\pageref{%s} & %s  & %s \\',[ALabel,AName,ADescr]);
   //WriteLnF('\pageref{%s} & %s  & %s \\',[ALabel,AName,ADescr]);

+ 4 - 4
utils/fpdoc/dw_txt.pp

@@ -80,8 +80,8 @@ Type
     procedure StartChapter(ChapterName : String); override;
     procedure StartChapter(ChapterName : String); override;
     procedure StartOverview(WithAccess : Boolean); override;
     procedure StartOverview(WithAccess : Boolean); override;
     procedure EndOverview; override;
     procedure EndOverview; override;
-    procedure WriteOverviewMember(ALabel,AName,Access,ADescr : String); override;
-    procedure WriteOverviewMember(ALabel,AName,ADescr : String); override;
+    procedure WriteOverviewMember(const ALabel,AName,Access,ADescr : String); override;
+    procedure WriteOverviewMember(const ALabel,AName,ADescr : String); override;
     Class Function FileNameExtension : String; override;
     Class Function FileNameExtension : String; override;
     // Description node conversion
     // Description node conversion
     procedure DescrBeginBold; override;
     procedure DescrBeginBold; override;
@@ -637,13 +637,13 @@ begin
   WriteLine(False);
   WriteLine(False);
 end;
 end;
 
 
-procedure TTxtWriter.WriteOverviewMember(ALabel,AName,Access,ADescr : String);
+procedure TTxtWriter.WriteOverviewMember(const ALabel,AName,Access,ADescr : String);
 
 
 begin
 begin
   WriteLnF('%.30s %.10s  %s',[AName,Access,ADescr]);
   WriteLnF('%.30s %.10s  %s',[AName,Access,ADescr]);
 end;
 end;
 
 
-procedure TTxtWriter.WriteOverviewMember(ALabel,AName,ADescr : String);
+procedure TTxtWriter.WriteOverviewMember(const ALabel,AName,ADescr : String);
 
 
 begin
 begin
   WriteLnF('%.30s %s ',[AName,ADescr]);
   WriteLnF('%.30s %s ',[AName,ADescr]);

+ 187 - 31
utils/fpdoc/dwlinear.pp

@@ -14,19 +14,23 @@ Type
     FStream : TStream;
     FStream : TStream;
     PackageName: String;
     PackageName: String;
     Module: TPasModule;
     Module: TPasModule;
-    ModuleName: String;
     FLastURL : DomString;
     FLastURL : DomString;
   private
   private
+    FDupLinkedDoc: Boolean;
   Protected
   Protected
+    ModuleName: String;
     // Writing support.
     // Writing support.
     procedure Write(const s: String); virtual;
     procedure Write(const s: String); virtual;
     procedure WriteLn(const s: String); virtual;
     procedure WriteLn(const s: String); virtual;
-    procedure WriteF(const s: String; const Args: array of const);
-    procedure WriteLnF(const s: String; const Args: array of const);
+    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;
     Function  PushWriteContext(S : TStream) : TStream;
     Procedure PopWriteContext(S : TSTream);
     Procedure PopWriteContext(S : TSTream);
     procedure WriteLabel(El: TPasElement);
     procedure WriteLabel(El: TPasElement);
     procedure WriteIndex(El: TPasElement);
     procedure WriteIndex(El: TPasElement);
+    procedure WriteTypeDecl(El: TPasElement); virtual;
+    procedure WriteVariableDecl(El: TPasElement); virtual;
+    procedure WriteConstDecl(El: TPasElement); virtual;
     // Auxiliary routines
     // Auxiliary routines
     procedure DescrBeginURL(const AURL: DOMString); override; // Provides a default implementation
     procedure DescrBeginURL(const AURL: DOMString); override; // Provides a default implementation
     procedure DescrEndURL; override;
     procedure DescrEndURL; override;
@@ -64,6 +68,9 @@ Type
     function  GetLabel(AElement: TPasElement): String; virtual; abstract;
     function  GetLabel(AElement: TPasElement): String; virtual; abstract;
     procedure WriteLabel(Const S : String); virtual; abstract;
     procedure WriteLabel(Const S : String); virtual; abstract;
     procedure WriteIndex(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 StartChapter(ChapterName : String); virtual; abstract;
     procedure StartSection(SectionName : String); virtual; abstract;
     procedure StartSection(SectionName : String); virtual; abstract;
     procedure StartSubSection(SubSectionName : String); virtual; abstract;
     procedure StartSubSection(SubSectionName : String); virtual; abstract;
@@ -73,8 +80,8 @@ Type
     Procedure WriteExampleFile(FN : String); virtual; abstract;
     Procedure WriteExampleFile(FN : String); virtual; abstract;
     procedure StartOverview(WithAccess : Boolean); virtual; Abstract;
     procedure StartOverview(WithAccess : Boolean); virtual; Abstract;
     procedure EndOverview; virtual; Abstract;
     procedure EndOverview; virtual; Abstract;
-    procedure WriteOverviewMember(ALabel,AName,Access,ADescr : String); virtual; Abstract;
-    procedure WriteOverviewMember(ALabel,AName,ADescr : String); 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 StartUnitOverview(AModuleName,AModuleLabel : String);virtual; Abstract;
     procedure WriteUnitEntry(UnitRef : TPasType);virtual; Abstract;
     procedure WriteUnitEntry(UnitRef : TPasType);virtual; Abstract;
     procedure EndUnitOverview; virtual; Abstract;
     procedure EndUnitOverview; virtual; Abstract;
@@ -82,6 +89,8 @@ Type
     Property LastURL : DomString Read FLastURL Write FLastURL;
     Property LastURL : DomString Read FLastURL Write FLastURL;
   Public
   Public
     Constructor Create(APackage: TPasPackage; AEngine: TFPDocEngine); override;
     Constructor Create(APackage: TPasPackage; AEngine: TFPDocEngine); override;
+    function InterpretOption(const Cmd, Arg: String): Boolean; override;
+    class procedure Usage(List: TStrings); override;
     procedure WriteDoc; override;
     procedure WriteDoc; override;
     // Linear Documentation writing methods.
     // Linear Documentation writing methods.
     Procedure ProcessPackage;
     Procedure ProcessPackage;
@@ -90,7 +99,7 @@ Type
     procedure WriteUnitOverview(ASection: TPasSection);
     procedure WriteUnitOverview(ASection: TPasSection);
     procedure WriteVarsConstsTypes(ASection: TPasSection);
     procedure WriteVarsConstsTypes(ASection: TPasSection);
     procedure WriteConsts(ASection: TPasSection);
     procedure WriteConsts(ASection: TPasSection);
-    procedure WriteTypes(ASection: TPasSection);
+    procedure WriteTypes(ASection: TPasSection); virtual;
     procedure WriteEnumElements(TypeDecl : TPasEnumType);
     procedure WriteEnumElements(TypeDecl : TPasEnumType);
     procedure WriteVars(ASection: TPasSection);
     procedure WriteVars(ASection: TPasSection);
     procedure WriteFunctionsAndProcedures(ASection: TPasSection);
     procedure WriteFunctionsAndProcedures(ASection: TPasSection);
@@ -99,6 +108,7 @@ Type
     procedure WriteClassDecl(ClassDecl: TPasClassType);
     procedure WriteClassDecl(ClassDecl: TPasClassType);
     procedure WriteClassMethodOverview(ClassDecl: TPasClassType);
     procedure WriteClassMethodOverview(ClassDecl: TPasClassType);
     procedure WriteClassPropertyOverview(ClassDecl: TPasClassType);
     procedure WriteClassPropertyOverview(ClassDecl: TPasClassType);
+    procedure WriteClassInterfacesOverView(ClassDecl: TPasClassType);
     procedure WriteProperty(PropDecl: TPasProperty);
     procedure WriteProperty(PropDecl: TPasProperty);
     procedure WriteExample(ADocNode: TDocNode);
     procedure WriteExample(ADocNode: TDocNode);
     procedure WriteSeeAlso(ADocNode: TDocNode);
     procedure WriteSeeAlso(ADocNode: TDocNode);
@@ -109,6 +119,9 @@ Type
 
 
 implementation
 implementation
 
 
+const
+  cDupLinkedDocParam = '--duplinkeddoc';
+
 { TLinearWriter }
 { TLinearWriter }
 
 
 { ---------------------------------------------------------------------
 { ---------------------------------------------------------------------
@@ -157,9 +170,8 @@ begin
 end;
 end;
 
 
 procedure TLinearWriter.DescrWriteText(const AText: DOMString);
 procedure TLinearWriter.DescrWriteText(const AText: DOMString);
-
 begin
 begin
-  self.Write(EscapeText(AText));
+  Write(EscapeText(AText));
 end;
 end;
 
 
 Function TLinearWriter.GetDescrString(AContext: TPasElement; DescrNode: TDOMElement) : String;
 Function TLinearWriter.GetDescrString(AContext: TPasElement; DescrNode: TDOMElement) : String;
@@ -201,6 +213,21 @@ begin
   WriteIndex(EL.Name);
   WriteIndex(EL.Name);
 end;
 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);
 procedure TLinearWriter.DescrBeginURL(const AURL: DOMString);
 begin
 begin
   FLastURL:=AURL;
   FLastURL:=AURL;
@@ -346,6 +373,20 @@ begin
   Writeln('');
   Writeln('');
 end;
 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);
 procedure TLinearWriter.WriteClassDecl(ClassDecl: TPasClassType);
 var
 var
@@ -368,8 +409,14 @@ begin
       StartSubSection(SDocVersion);
       StartSubSection(SDocVersion);
       WriteDescr(ClassDecl,DocNode.Version);
       WriteDescr(ClassDecl,DocNode.Version);
       end;
       end;
+    if Assigned(DocNode.SeeAlso) then
+    begin
+      WriteSeeAlso(DocNode);
+    end;
   end;
   end;
 
 
+  // Write Interfaces Overview;
+  WriteClassInterfacesOverView(ClassDecl);
   // Write method overview
   // Write method overview
   WriteClassMethodOverView(ClassDecl);
   WriteClassMethodOverView(ClassDecl);
   // Write Property Overview;
   // Write Property Overview;
@@ -413,7 +460,7 @@ var
   L,N,S,A: String;
   L,N,S,A: String;
   DocNode: TDocNode;
   DocNode: TDocNode;
   List : TStringList;
   List : TStringList;
-
+  lNode: TDocNode;
 begin
 begin
   // Write property overview
   // Write property overview
   List:=TStringList.Create;
   List:=TStringList.Create;
@@ -437,10 +484,20 @@ begin
         L:=StripText(GetLabel(Member));
         L:=StripText(GetLabel(Member));
         N:=EscapeText(Member.Name);
         N:=EscapeText(Member.Name);
         DocNode := Engine.FindDocNode(Member);
         DocNode := Engine.FindDocNode(Member);
-        If Assigned(DocNode) then
-          S:=GetDescrString(Member, DocNode.ShortDescr)
+        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
         else
-          S:='';
+          S := '';
 
 
         A:='';
         A:='';
         if Length(TPasProperty(Member).ReadAccessorName) > 0 then
         if Length(TPasProperty(Member).ReadAccessorName) > 0 then
@@ -450,6 +507,7 @@ begin
         if Length(TPasProperty(Member).StoredAccessorName) > 0 then
         if Length(TPasProperty(Member).StoredAccessorName) > 0 then
           a := a + 's';
           a := a + 's';
         WriteOverviewMember(L,N,A,S);
         WriteOverviewMember(L,N,A,S);
+        S := '';
         end;
         end;
       EndOverview;
       EndOverview;
       end;
       end;
@@ -459,6 +517,61 @@ begin
 end;
 end;
 
 
 
 
+procedure TLinearWriter.WriteClassInterfacesOverView(ClassDecl: TPasClassType);
+var
+  lInterface: TPasElement;
+  i: Integer;
+  L,N,S,A: 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(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) 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;
+
+
 function TLinearWriter.ConstValue(ConstDecl: TPasConst): String;
 function TLinearWriter.ConstValue(ConstDecl: TPasConst): String;
 begin
 begin
   if Assigned(ConstDecl) then
   if Assigned(ConstDecl) then
@@ -562,7 +675,7 @@ begin
     begin
     begin
       ResStrDecl := TPasResString(ASection.ResStrings[i]);
       ResStrDecl := TPasResString(ASection.ResStrings[i]);
       StartListing(false, '');
       StartListing(false, '');
-      Writeln(ResStrDecl.GetDeclaration(True));
+      DescrWriteText(ResStrDecl.GetDeclaration(True)); // instead of WriteLn() so we can do further processing like manual line wrapping in descendants
       EndListing;
       EndListing;
       WriteLabel(ResStrDecl);
       WriteLabel(ResStrDecl);
       WriteIndex(ResStrDecl);
       WriteIndex(ResStrDecl);
@@ -683,6 +796,7 @@ begin
       begin
       begin
       DescrBeginParaGraph;
       DescrBeginParaGraph;
       ConstDecl := TPasConst(ASection.Consts[i]);
       ConstDecl := TPasConst(ASection.Consts[i]);
+      WriteConstDecl(ConstDecl);
       StartListing(False,'');
       StartListing(False,'');
       WriteLn(EscapeText(ConstDecl.GetDeclaration(True)));
       WriteLn(EscapeText(ConstDecl.GetDeclaration(True)));
       EndListing;
       EndListing;
@@ -746,16 +860,19 @@ begin
     StartSubSection(SDocTypes,ModuleName+'Types');
     StartSubSection(SDocTypes,ModuleName+'Types');
     for i := 0 to ASection.Types.Count - 1 do
     for i := 0 to ASection.Types.Count - 1 do
     begin
     begin
-      DescrBeginParaGraph;
+      DescrBeginParagraph;
       TypeDecl := TPasType(ASection.Types[i]);
       TypeDecl := TPasType(ASection.Types[i]);
+      WriteTypeDecl(TypeDecl);
       StartListing(False,'');
       StartListing(False,'');
       DocNode := Engine.FindDocNode(TypeDecl);
       DocNode := Engine.FindDocNode(TypeDecl);
       If Assigned(DocNode) and 
       If Assigned(DocNode) and 
          Assigned(DocNode.Node) and 
          Assigned(DocNode.Node) and 
          (Docnode.Node['opaque']='1') then
          (Docnode.Node['opaque']='1') then
           Writeln(TypeDecl.Name+' = '+SDocOpaque)
           Writeln(TypeDecl.Name+' = '+SDocOpaque)
-      else    
-         Writeln(EscapeText(TypeDecl.GetDeclaration(True)));
+      else
+      begin
+        Writeln(EscapeText(TypeDecl.GetDeclaration(True)));
+      end;
       EndListing;
       EndListing;
       WriteLabel(TypeDecl);
       WriteLabel(TypeDecl);
       WriteIndex(TypeDecl);
       WriteIndex(TypeDecl);
@@ -769,7 +886,7 @@ begin
         Writeln(Format('%s : ',[SDocVersion]));
         Writeln(Format('%s : ',[SDocVersion]));
         WriteDescr(TypeDecl, DocNode.Version);
         WriteDescr(TypeDecl, DocNode.Version);
         end;
         end;
-      DescrEndParaGraph;
+      DescrEndParagraph;
       end;
       end;
   end;
   end;
 end;
 end;
@@ -788,6 +905,7 @@ begin
     begin
     begin
       DescrBeginParaGraph;
       DescrBeginParaGraph;
       VarDecl := TPasVariable(ASection.Variables[i]);
       VarDecl := TPasVariable(ASection.Variables[i]);
+      WriteVariableDecl(VarDecl);
       StartListing(False,'');
       StartListing(False,'');
       WriteLn(EscapeText(VarDecl.GetDeclaration(True)));
       WriteLn(EscapeText(VarDecl.GetDeclaration(True)));
       EndListing;
       EndListing;
@@ -857,7 +975,7 @@ begin
         StartDescription;
         StartDescription;
         WriteDescr(ProcDecl);
         WriteDescr(ProcDecl);
         end;
         end;
-      if Assigned(DocNode.ErrorsDoc) then
+      if Assigned(DocNode.ErrorsDoc) and (DocNode.ErrorsDoc.HasChildNodes) then
         begin
         begin
         StartErrors;
         StartErrors;
         WriteDescr(ProcDecl, DocNode.ErrorsDoc);
         WriteDescr(ProcDecl, DocNode.ErrorsDoc);
@@ -920,6 +1038,7 @@ procedure TLinearWriter.WriteProperty(PropDecl : TPasProperty);
 var
 var
   DocNode: TDocNode;
   DocNode: TDocNode;
   S: String;
   S: String;
+  lNode: TDocNode;
 begin
 begin
   With PropDecl do
   With PropDecl do
     begin
     begin
@@ -928,11 +1047,23 @@ begin
     WriteIndex(Parent.Name+'.'+Name);
     WriteIndex(Parent.Name+'.'+Name);
     StartProperty;
     StartProperty;
     DocNode := Engine.FindDocNode(PropDecl);
     DocNode := Engine.FindDocNode(PropDecl);
-    if Assigned(DocNode) and Assigned(DocNode.ShortDescr) then
+    if Assigned(DocNode) then
+    begin
+      if FDupLinkedDoc and (DocNode.Link <> '') then
       begin
       begin
-      StartSynopsis;
-      WriteDescr(PropDecl, DocNode.ShortDescr);
+        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;
+    end;
     StartDeclaration;
     StartDeclaration;
     StartListing(False);
     StartListing(False);
     WriteLn('Property '+GetDeclaration(True));
     WriteLn('Property '+GetDeclaration(True));
@@ -954,27 +1085,27 @@ begin
       end;
       end;
     Writeln(S);
     Writeln(S);
     if Assigned(DocNode) then
     if Assigned(DocNode) then
-      begin
-      if Assigned(DocNode.Descr) then
+    begin
+      if Assigned(lNode.Descr) then     // lNode will be assigned if DocNode exists
         begin
         begin
         StartDescription;
         StartDescription;
-        WriteDescr(PropDecl);
+        WriteDescr(PropDecl, lNode);
         end;
         end;
-      if Assigned(DocNode.ErrorsDoc) then
+      if Assigned(lNode.ErrorsDoc) and (lNode.ErrorsDoc.HasChildNodes) then
         begin
         begin
         StartErrors;
         StartErrors;
         WriteDescr(PropDecl, DocNode.ErrorsDoc);
         WriteDescr(PropDecl, DocNode.ErrorsDoc);
         end;
         end;
-      if Assigned(DocNode.Version) then
+      if Assigned(lNode.Version) then
         begin
         begin
         StartVersion;
         StartVersion;
-        WriteDescr(PropDecl, DocNode.Version);
+        WriteDescr(PropDecl, lNode.Version);
         end;
         end;
-      WriteSeeAlso(DocNode);
+      WriteSeeAlso(lNode);
       EndProperty;
       EndProperty;
-      WriteExample(DocNode);
-      end
-     else
+      WriteExample(lNode);
+    end
+    else
       EndProperty;
       EndProperty;
     end;
     end;
 end;
 end;
@@ -1004,6 +1135,8 @@ begin
         Writeln(',');
         Writeln(',');
       S:=TDomElement(Node)['id'];
       S:=TDomElement(Node)['id'];
       DescrBeginLink(S);
       DescrBeginLink(S);
+      if Node.FirstChild <> nil then
+        s := Node.FirstChild.NodeValue;
       Write(EscapeText(S));
       Write(EscapeText(S));
       DescrEndLink();
       DescrEndLink();
       end;
       end;
@@ -1208,6 +1341,7 @@ var
   i: Integer;
   i: Integer;
 begin
 begin
   inherited ;
   inherited ;
+  FDupLinkedDoc := False; // by default we don't duplicate linked element documentation
 
 
   { Allocate labels for all elements for which we are going to create
   { Allocate labels for all elements for which we are going to create
     documentation. This is needed for links to work correctly. }
     documentation. This is needed for links to work correctly. }
@@ -1231,6 +1365,28 @@ end;
 
 
 procedure TLinearWriter.WriteEndDocument;
 procedure TLinearWriter.WriteEndDocument;
 begin
 begin
+  // do nothing
+end;
+
+function TLinearWriter.InterpretOption(const Cmd: String; const Arg: String): Boolean;
+begin
+  Result := True;
+  if Cmd = cDupLinkedDocParam then
+  begin
+    FDupLinkedDoc := True;
+  end
+  else
+    Result := False;
 end;
 end;
 
 
+class procedure TLinearWriter.Usage(List: TStrings);
+begin
+  List.Add(cDupLinkedDocParam);
+  List.Add(SLinearUsageDupLinkedDocsP1);
+  List.Add('');
+  List.Add(SLinearUsageDupLinkedDocsP2);
+end;
+
+
 end.
 end.
+

+ 5 - 0
utils/fpdoc/fpdoc.css

@@ -159,3 +159,8 @@ dd {
  margin: 0 0 0 110px;
  margin: 0 0 0 110px;
  padding: 0 0 0.5em 0;
  padding: 0 0 0.5em 0;
 }
 }
+
+/* for browsers in standards compliance mode */
+td p {
+  margin: 0;
+}

+ 14 - 14
utils/fpdoc/fpdoc.lpi

@@ -1,7 +1,7 @@
 <?xml version="1.0"?>
 <?xml version="1.0"?>
 <CONFIG>
 <CONFIG>
   <ProjectOptions>
   <ProjectOptions>
-    <Version Value="7"/>
+    <Version Value="9"/>
     <General>
     <General>
       <Flags>
       <Flags>
         <SaveClosedFiles Value="False"/>
         <SaveClosedFiles Value="False"/>
@@ -13,10 +13,9 @@
       </Flags>
       </Flags>
       <SessionStorage Value="InProjectDir"/>
       <SessionStorage Value="InProjectDir"/>
       <MainUnit Value="0"/>
       <MainUnit Value="0"/>
-      <TargetFileExt Value=""/>
     </General>
     </General>
     <VersionInfo>
     <VersionInfo>
-      <ProjectVersion Value=""/>
+      <StringTable ProductVersion=""/>
     </VersionInfo>
     </VersionInfo>
     <PublishOptions>
     <PublishOptions>
       <Version Value="2"/>
       <Version Value="2"/>
@@ -62,34 +61,35 @@
         <UnitName Value="dw_HTML"/>
         <UnitName Value="dw_HTML"/>
       </Unit5>
       </Unit5>
       <Unit6>
       <Unit6>
-        <Filename Value="dw_ipf.pp"/>
+        <Filename Value="dw_man.pp"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
-        <UnitName Value="dw_IPF"/>
+        <UnitName Value="dw_man"/>
       </Unit6>
       </Unit6>
       <Unit7>
       <Unit7>
-        <Filename Value="dw_man.pp"/>
+        <Filename Value="dw_linrtf.pp"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
-        <UnitName Value="dw_man"/>
+        <UnitName Value="dw_LinRTF"/>
       </Unit7>
       </Unit7>
       <Unit8>
       <Unit8>
-        <Filename Value="dw_linrtf.pp"/>
+        <Filename Value="dw_txt.pp"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
-        <UnitName Value="dw_LinRTF"/>
+        <UnitName Value="dw_txt"/>
       </Unit8>
       </Unit8>
       <Unit9>
       <Unit9>
-        <Filename Value="dw_txt.pp"/>
+        <Filename Value="dglobals.pp"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
-        <UnitName Value="dw_txt"/>
+        <UnitName Value="dGlobals"/>
       </Unit9>
       </Unit9>
       <Unit10>
       <Unit10>
-        <Filename Value="dglobals.pp"/>
+        <Filename Value="dw_ipflin.pas"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
-        <UnitName Value="dGlobals"/>
+        <UnitName Value="dw_ipflin"/>
       </Unit10>
       </Unit10>
     </Units>
     </Units>
   </ProjectOptions>
   </ProjectOptions>
   <CompilerOptions>
   <CompilerOptions>
-    <Version Value="8"/>
+    <Version Value="9"/>
+    </Parsing>
     <Other>
     <Other>
       <CompilerPath Value="$(CompPath)"/>
       <CompilerPath Value="$(CompPath)"/>
     </Other>
     </Other>

+ 5 - 2
utils/fpdoc/fpdoc.pp

@@ -24,9 +24,9 @@ uses
   dw_XML,    // XML writer
   dw_XML,    // XML writer
   dw_dxml,   // Delphi XML doc.
   dw_dxml,   // Delphi XML doc.
   dw_HTML,   // HTML writer
   dw_HTML,   // HTML writer
-  dw_ipf,    // IPF writer
+  dw_ipflin, // IPF writer (new linear output)
   dw_man,    // Man page writer
   dw_man,    // Man page writer
-  dw_linrtf, // lineair RTF writer
+  dw_linrtf, // linear RTF writer
   dw_txt;    // TXT writer
   dw_txt;    // TXT writer
 
 
 const
 const
@@ -71,6 +71,7 @@ begin
   Writeln(SUsageOption160);
   Writeln(SUsageOption160);
   Writeln(SUsageOption170);
   Writeln(SUsageOption170);
   Writeln(SUsageOption180);
   Writeln(SUsageOption180);
+  Writeln(SUsageOption190);
   L:=TStringList.Create;
   L:=TStringList.Create;
   Try
   Try
     If (Backend='') then
     If (Backend='') then
@@ -208,6 +209,8 @@ begin
       CPUTarget := Arg
       CPUTarget := Arg
     else if Cmd = '--mo-dir' then
     else if Cmd = '--mo-dir' then
       modir := Arg
       modir := Arg
+    else if Cmd = '--parse-impl' then
+      Engine.InterfaceOnly:=false
     else
     else
       begin
       begin
       BackendOptions.Add(Cmd);
       BackendOptions.Add(Cmd);