summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornickysn <nickysn@3ad0048d-3df7-0310-abae-a5850022a9f2>2021-01-04 02:57:44 +0000
committernickysn <nickysn@3ad0048d-3df7-0310-abae-a5850022a9f2>2021-01-04 02:57:44 +0000
commit638c27429e2a49f89a0bbf5f4d1dd76d316c127e (patch)
tree39100e6a62e6e1ccebef9db0162a648a5984b16e
parent3c2de493eb97524fd25695ffdad6c500a5fa50f9 (diff)
parentabfb61ea77f5db2a4da1c97eab88ac4978af8c83 (diff)
downloadfpc-638c27429e2a49f89a0bbf5f4d1dd76d316c127e.tar.gz
* synchronized with trunk
git-svn-id: https://svn.freepascal.org/svn/fpc/branches/wasm@48022 3ad0048d-3df7-0310-abae-a5850022a9f2
-rw-r--r--compiler/dbgstabs.pas3
-rw-r--r--compiler/nadd.pas81
-rw-r--r--compiler/pdecsub.pas20
-rw-r--r--compiler/pexports.pas4
-rw-r--r--compiler/pexpr.pas60
-rw-r--r--compiler/pgenutil.pas31
-rw-r--r--compiler/symtable.pas10
-rw-r--r--compiler/x86/nx86inl.pas4
-rw-r--r--packages/fcl-passrc/src/pasresolveeval.pas2
-rw-r--r--packages/fcl-passrc/src/pasresolver.pp66
-rw-r--r--packages/fcl-passrc/src/pastree.pp3
-rw-r--r--packages/fcl-passrc/src/pparser.pp56
-rw-r--r--packages/fcl-passrc/tests/tcresolver.pas20
-rw-r--r--packages/pastojs/src/pas2jsfiler.pp2
-rw-r--r--packages/pastojs/tests/tcfiler.pas1
-rw-r--r--packages/rtl-objpas/src/inc/nullable.pp14
-rw-r--r--rtl/aarch64/mathu.inc2
-rw-r--r--rtl/arm/mathu.inc3
-rw-r--r--rtl/i386/mathu.inc1
-rw-r--r--rtl/i8086/mathu.inc1
-rw-r--r--rtl/m68k/mathu.inc2
-rw-r--r--rtl/mips/mathu.inc1
-rw-r--r--rtl/powerpc/mathu.inc2
-rw-r--r--rtl/powerpc64/mathu.inc2
-rw-r--r--rtl/riscv64/mathu.inc2
-rw-r--r--rtl/sparc/mathu.inc1
-rw-r--r--rtl/sparc64/mathu.inc1
-rw-r--r--rtl/win/syswin.inc8
-rw-r--r--rtl/x86_64/mathu.inc1
-rw-r--r--rtl/xtensa/mathu.inc1
-rw-r--r--tests/test/tgenfunc24.pp25
-rw-r--r--tests/test/tgenfunc25.pp24
-rw-r--r--tests/test/tgenfunc26.pp24
-rw-r--r--tests/test/tgenfunc27.pp24
-rw-r--r--tests/test/units/math/trndcurr.pp156
-rw-r--r--tests/webtbf/tw38289a.pp8
-rw-r--r--tests/webtbf/tw38289b.pp8
-rw-r--r--tests/webtbs/tw38267b.pp31
-rw-r--r--tests/webtbs/tw38295.pp19
-rw-r--r--tests/webtbs/tw38299.pp15
-rw-r--r--utils/fpdoc/dglobals.pp14
-rw-r--r--utils/fpdoc/dw_basehtml.pp1060
-rw-r--r--utils/fpdoc/dw_basemd.pp27
-rw-r--r--utils/fpdoc/dw_chm.pp23
-rw-r--r--utils/fpdoc/dw_html.pp2032
-rw-r--r--utils/fpdoc/dw_markdown.pp19
-rw-r--r--utils/fpdoc/dwriter.pp19
-rw-r--r--utils/fpdoc/fpdoc.lpi6
-rw-r--r--utils/fpdoc/fpdoc.pp2
-rw-r--r--utils/fpdoc/fpdocclasstree.pp2
50 files changed, 2283 insertions, 1660 deletions
diff --git a/compiler/dbgstabs.pas b/compiler/dbgstabs.pas
index 2d8b986e8c..ef8a575475 100644
--- a/compiler/dbgstabs.pas
+++ b/compiler/dbgstabs.pas
@@ -480,6 +480,9 @@ implementation
begin
if tsym(p).typ = procsym then
begin
+ if (sp_generic_dummy in tsym(p).symoptions) and
+ (tprocsym(p).procdeflist.count=0) then
+ exit;
pd :=tprocdef(tprocsym(p).ProcdefList[0]);
if (po_virtualmethod in pd.procoptions) and
not is_objectpascal_helper(pd.struct) then
diff --git a/compiler/nadd.pas b/compiler/nadd.pas
index 62689f4fe4..b7ba6594fc 100644
--- a/compiler/nadd.pas
+++ b/compiler/nadd.pas
@@ -536,12 +536,28 @@ implementation
function SwapLeftWithRightRight : tnode;
var
- hp: tnode;
+ hp,hp2 : tnode;
begin
- hp:=left;
- left:=taddnode(right).right;
- taddnode(right).right:=hp;
- right:=right.simplify(false);
+ { keep the order of val+const else string operations might cause an error }
+ hp:=taddnode(right).right;
+
+ taddnode(right).right:=taddnode(right).left;
+ taddnode(right).left:=left;
+
+ right.resultdef:=nil;
+ do_typecheckpass(right);
+ hp2:=right.simplify(forinline);
+ if assigned(hp2) then
+ right:=hp2;
+ if resultdef.typ<>pointerdef then
+ begin
+ { ensure that the constant is not expanded to a larger type due to overflow,
+ but this is only useful if no pointer operation is done }
+ right:=ctypeconvnode.create_internal(right,resultdef);
+ do_typecheckpass(right);
+ end;
+ left:=right;
+ right:=hp;
result:=GetCopyAndTypeCheck;
end;
@@ -1207,23 +1223,7 @@ implementation
exit;
end;
- { try to fold
- op
- / \
- op const1
- / \
- val const2
-
- while operating on strings
- }
- if (cs_opt_level2 in current_settings.optimizerswitches) and (nodetype=addn) and ((rt=stringconstn) or is_constcharnode(right)) and (left.nodetype=nodetype) and
- (compare_defs(resultdef,left.resultdef,nothingn)=te_exact) and ((taddnode(left).right.nodetype=stringconstn) or is_constcharnode(taddnode(left).right)) then
- begin
- Result:=SwapRightWithLeftLeft;
- exit;
- end;
-
- { set constant evaluation }
+ { set constant evaluation }
if (right.nodetype=setconstn) and
not assigned(tsetconstnode(right).left) and
(left.nodetype=setconstn) and
@@ -1381,9 +1381,44 @@ implementation
exit;
end;
- { slow simplifications }
+ { slow simplifications and/or more sophisticated transformations which might make debugging harder }
if cs_opt_level2 in current_settings.optimizerswitches then
begin
+ if nodetype=addn then
+ begin
+ { try to fold
+ op
+ / \
+ op const1
+ / \
+ val const2
+
+ while operating on strings
+ }
+ if ((rt=stringconstn) or is_constcharnode(right)) and (left.nodetype=nodetype) and
+ (compare_defs(resultdef,left.resultdef,nothingn)=te_exact) and ((taddnode(left).right.nodetype=stringconstn) or is_constcharnode(taddnode(left).right)) then
+ begin
+ Result:=SwapRightWithLeftLeft;
+ exit;
+ end;
+
+ { try to fold
+ op
+ / \
+ const1 op
+ / \
+ const2 val
+
+ while operating on strings
+ }
+ if ((lt=stringconstn) or is_constcharnode(left)) and (right.nodetype=nodetype) and
+ (compare_defs(resultdef,right.resultdef,nothingn)=te_exact) and ((taddnode(right).left.nodetype=stringconstn) or is_constcharnode(taddnode(right).left)) then
+ begin
+ Result:=SwapLeftWithRightRight;
+ exit;
+ end;
+ end;
+
{ the comparison is might be expensive and the nodes are usually only
equal if some previous optimizations were done so don't check
this simplification always
diff --git a/compiler/pdecsub.pas b/compiler/pdecsub.pas
index c2ebfb2bc2..baf558743b 100644
--- a/compiler/pdecsub.pas
+++ b/compiler/pdecsub.pas
@@ -1066,7 +1066,8 @@ implementation
end
else if (srsym.typ=typesym) and
(sp_generic_dummy in srsym.symoptions) and
- (ttypesym(srsym).typedef.typ=undefineddef) then
+ (ttypesym(srsym).typedef.typ=undefineddef) and
+ not assigned(genericparams) then
begin
{ this is a generic dummy symbol that has not yet
been used; so we rename the dummy symbol and continue
@@ -1162,13 +1163,26 @@ implementation
end;
if not assigned(dummysym) then
begin
- dummysym:=ctypesym.create(orgspnongen,cundefineddef.create(true));
+ { overloading generic routines with non-generic types is not
+ allowed, so we create a procsym as dummy }
+ dummysym:=cprocsym.create(orgspnongen);
if assigned(astruct) then
astruct.symtable.insert(dummysym)
else
symtablestack.top.insert(dummysym);
+ end
+ else if (dummysym.typ<>procsym) and
+ (
+ { show error only for the declaration, not also the implementation }
+ not assigned(astruct) or
+ (symtablestack.top.symtablelevel<>main_program_level)
+ ) then
+ Message1(sym_e_duplicate_id,dummysym.realname);
+ if not (sp_generic_dummy in dummysym.symoptions) then
+ begin
+ include(dummysym.symoptions,sp_generic_dummy);
+ add_generic_dummysym(dummysym);
end;
- include(dummysym.symoptions,sp_generic_dummy);
{ start token recorder for the declaration }
pd.init_genericdecl;
current_scanner.startrecordtokens(pd.genericdecltokenbuf);
diff --git a/compiler/pexports.pas b/compiler/pexports.pas
index dfd37bbf3b..8770410872 100644
--- a/compiler/pexports.pas
+++ b/compiler/pexports.pas
@@ -149,7 +149,7 @@ implementation
else
begin
index:=0;
- consume(_INTCONST);
+ message(type_e_ordinal_expr_expected);
end;
include(options,eo_index);
pt.free;
@@ -166,7 +166,7 @@ implementation
else if is_constcharnode(pt) then
hpname:=chr(tordconstnode(pt).value.svalue and $ff)
else
- consume(_CSTRING);
+ message(type_e_string_expr_expected);
include(options,eo_name);
pt.free;
DefString:=hpname+'='+InternalProcName;
diff --git a/compiler/pexpr.pas b/compiler/pexpr.pas
index 1558e38263..a36bef1900 100644
--- a/compiler/pexpr.pas
+++ b/compiler/pexpr.pas
@@ -1514,13 +1514,15 @@ implementation
begin
if srsym.typ=typesym then
spezdef:=ttypesym(srsym).typedef
+ else if tprocsym(srsym).procdeflist.count>0 then
+ spezdef:=tdef(tprocsym(srsym).procdeflist[0])
else
- spezdef:=tdef(tprocsym(srsym).procdeflist[0]);
- if (spezdef.typ=errordef) and (sp_generic_dummy in srsym.symoptions) then
+ spezdef:=nil;
+ if (not assigned(spezdef) or (spezdef.typ=errordef)) and (sp_generic_dummy in srsym.symoptions) then
symname:=srsym.RealName
else
symname:='';
- spezdef:=generate_specialization_phase1(spezcontext,spezdef,symname);
+ spezdef:=generate_specialization_phase1(spezcontext,spezdef,symname,srsym.owner);
case spezdef.typ of
errordef:
begin
@@ -2994,7 +2996,7 @@ implementation
begin
{$push}
{$warn 5036 off}
- hdef:=generate_specialization_phase1(spezcontext,nil,nil,orgstoredpattern,dummypos);
+ hdef:=generate_specialization_phase1(spezcontext,nil,nil,orgstoredpattern,nil,dummypos);
{$pop}
if hdef=generrordef then
begin
@@ -3048,12 +3050,20 @@ implementation
wasgenericdummy:=false;
if assigned(srsym) and
(sp_generic_dummy in srsym.symoptions) and
- (srsym.typ=typesym) and
+ (srsym.typ in [procsym,typesym]) and
(
(
(m_delphi in current_settings.modeswitches) and
not (token in [_LT, _LSHARPBRACKET]) and
- (ttypesym(srsym).typedef.typ=undefineddef)
+ (
+ (
+ (srsym.typ=typesym) and
+ (ttypesym(srsym).typedef.typ=undefineddef)
+ ) or (
+ (srsym.typ=procsym) and
+ (tprocsym(srsym).procdeflist.count=0)
+ )
+ )
)
or
(
@@ -3306,8 +3316,14 @@ implementation
procsym :
begin
p1:=nil;
+ if (m_delphi in current_settings.modeswitches) and
+ (sp_generic_dummy in srsym.symoptions) and
+ (token in [_LT,_LSHARPBRACKET]) then
+ begin
+ p1:=cspecializenode.create(nil,getaddr,srsym)
+ end
{ check if it's a method/class method }
- if is_member_read(srsym,srsymtable,p1,hdef) then
+ else if is_member_read(srsym,srsymtable,p1,hdef) then
begin
{ if we are accessing a owner procsym from the nested }
{ class we need to call it as a class member }
@@ -3558,17 +3574,20 @@ implementation
(block_type=bt_body) and
(token in [_LT,_LSHARPBRACKET]) then
begin
- if p1.nodetype=typen then
- idstr:=ttypenode(p1).typesym.name
- else
- if (p1.nodetype=loadvmtaddrn) and
- (tloadvmtaddrnode(p1).left.nodetype=typen) then
- idstr:=ttypenode(tloadvmtaddrnode(p1).left).typesym.name
+ idstr:='';
+ case p1.nodetype of
+ typen:
+ idstr:=ttypenode(p1).typesym.name;
+ loadvmtaddrn:
+ if tloadvmtaddrnode(p1).left.nodetype=typen then
+ idstr:=ttypenode(tloadvmtaddrnode(p1).left).typesym.name;
+ loadn:
+ idstr:=tloadnode(p1).symtableentry.name;
+ calln:
+ idstr:=tcallnode(p1).symtableprocentry.name;
else
- if (p1.nodetype=loadn) then
- idstr:=tloadnode(p1).symtableentry.name
- else
- idstr:='';
+ ;
+ end;
{ if this is the case then the postfix handling is done in
sub_expr if necessary }
dopostfix:=not could_be_generic(idstr);
@@ -4211,7 +4230,8 @@ implementation
typesym:
result:=ttypesym(sym).typedef;
procsym:
- result:=tdef(tprocsym(sym).procdeflist[0]);
+ if not (sp_generic_dummy in sym.symoptions) or (tprocsym(sym).procdeflist.count>0) then
+ result:=tdef(tprocsym(sym).procdeflist[0]);
else
internalerror(2015092701);
end;
@@ -4230,6 +4250,8 @@ implementation
loadn:
if not searchsym_with_symoption(tloadnode(n).symtableentry.Name,srsym,srsymtable,sp_generic_dummy) then
srsym:=nil;
+ calln:
+ srsym:=tcallnode(n).symtableprocentry;
specializen:
srsym:=tspecializenode(n).sym;
{ TODO : handle const nodes }
@@ -4264,7 +4286,7 @@ implementation
end;
if assigned(parseddef) and assigned(gensym) and assigned(p2) then
- gendef:=generate_specialization_phase1(spezcontext,gendef,parseddef,gensym.realname,p2.fileinfo)
+ gendef:=generate_specialization_phase1(spezcontext,gendef,parseddef,gensym.realname,gensym.owner,p2.fileinfo)
else
gendef:=generate_specialization_phase1(spezcontext,gendef);
case gendef.typ of
diff --git a/compiler/pgenutil.pas b/compiler/pgenutil.pas
index 56567d6cff..a4de4abf13 100644
--- a/compiler/pgenutil.pas
+++ b/compiler/pgenutil.pas
@@ -39,8 +39,8 @@ uses
procedure generate_specialization(var tt:tdef;parse_class_parent:boolean;_prettyname:string;parsedtype:tdef;symname:string;parsedpos:tfileposinfo);inline;
procedure generate_specialization(var tt:tdef;parse_class_parent:boolean;_prettyname:string);inline;
function generate_specialization_phase1(out context:tspecializationcontext;genericdef:tdef):tdef;inline;
- function generate_specialization_phase1(out context:tspecializationcontext;genericdef:tdef;symname:string):tdef;inline;
- function generate_specialization_phase1(out context:tspecializationcontext;genericdef:tdef;parsedtype:tdef;symname:string;parsedpos:tfileposinfo):tdef;
+ function generate_specialization_phase1(out context:tspecializationcontext;genericdef:tdef;symname:string;symtable:tsymtable):tdef;inline;
+ function generate_specialization_phase1(out context:tspecializationcontext;genericdef:tdef;parsedtype:tdef;symname:string;symtable:tsymtable;parsedpos:tfileposinfo):tdef;
function generate_specialization_phase2(context:tspecializationcontext;genericdef:tstoreddef;parse_class_parent:boolean;_prettyname:ansistring):tdef;
function check_generic_constraints(genericdef:tstoreddef;paramlist:tfpobjectlist;poslist:tfplist):boolean;
function parse_generic_parameters(allowconstraints:boolean):tfphashobjectlist;
@@ -613,23 +613,23 @@ uses
{$push}
{$warn 5036 off}
begin
- result:=generate_specialization_phase1(context,genericdef,nil,'',dummypos);
+ result:=generate_specialization_phase1(context,genericdef,nil,'',nil,dummypos);
end;
{$pop}
- function generate_specialization_phase1(out context:tspecializationcontext;genericdef:tdef;symname:string):tdef;
+ function generate_specialization_phase1(out context:tspecializationcontext;genericdef:tdef;symname:string;symtable:tsymtable):tdef;
var
dummypos : tfileposinfo;
{$push}
{$warn 5036 off}
begin
- result:=generate_specialization_phase1(context,genericdef,nil,symname,dummypos);
+ result:=generate_specialization_phase1(context,genericdef,nil,symname,symtable,dummypos);
end;
{$pop}
- function generate_specialization_phase1(out context:tspecializationcontext;genericdef:tdef;parsedtype:tdef;symname:string;parsedpos:tfileposinfo):tdef;
+ function generate_specialization_phase1(out context:tspecializationcontext;genericdef:tdef;parsedtype:tdef;symname:string;symtable:tsymtable;parsedpos:tfileposinfo):tdef;
var
found,
err : boolean;
@@ -637,6 +637,7 @@ uses
gencount : longint;
countstr,genname,ugenname : string;
tmpstack : tfpobjectlist;
+ symowner : tsymtable;
begin
context:=nil;
result:=nil;
@@ -741,12 +742,17 @@ uses
context.genname:=genname;
- if assigned(genericdef) and (genericdef.owner.symtabletype in [objectsymtable,recordsymtable]) then
+ if assigned(genericdef) then
+ symowner:=genericdef.owner
+ else
+ symowner:=symtable;
+
+ if assigned(symowner) and (symowner.symtabletype in [objectsymtable,recordsymtable]) then
begin
- if genericdef.owner.symtabletype = objectsymtable then
- found:=searchsym_in_class(tobjectdef(genericdef.owner.defowner),tobjectdef(genericdef.owner.defowner),ugenname,context.sym,context.symtable,[])
+ if symowner.symtabletype = objectsymtable then
+ found:=searchsym_in_class(tobjectdef(symowner.defowner),tobjectdef(symowner.defowner),ugenname,context.sym,context.symtable,[])
else
- found:=searchsym_in_record(tabstractrecorddef(genericdef.owner.defowner),ugenname,context.sym,context.symtable);
+ found:=searchsym_in_record(tabstractrecorddef(symowner.defowner),ugenname,context.sym,context.symtable);
if not found then
found:=searchsym(ugenname,context.sym,context.symtable);
end
@@ -1350,7 +1356,7 @@ uses
context : tspecializationcontext;
genericdef : tstoreddef;
begin
- genericdef:=tstoreddef(generate_specialization_phase1(context,tt,parsedtype,symname,parsedpos));
+ genericdef:=tstoreddef(generate_specialization_phase1(context,tt,parsedtype,symname,nil,parsedpos));
if genericdef<>generrordef then
genericdef:=tstoreddef(generate_specialization_phase2(context,genericdef,parse_class_parent,_prettyname));
tt:=genericdef;
@@ -1790,8 +1796,7 @@ uses
if not searchsym_with_flags(sym.name,srsym,srsymtable,[ssf_no_addsymref]) then
srsym:=nil;
end
- else if (sym.typ=procsym) and
- (tprocsym(sym).procdeflist.count>0) then
+ else if sym.typ=procsym then
srsym:=sym
else
{ dummy symbol is already not so dummy anymore }
diff --git a/compiler/symtable.pas b/compiler/symtable.pas
index 731b5028e5..8117af72f7 100644
--- a/compiler/symtable.pas
+++ b/compiler/symtable.pas
@@ -3374,6 +3374,8 @@ implementation
exit;
end;
end;
+ if (tprocsym(sym).procdeflist.count=0) and (sp_generic_dummy in tprocsym(sym).symoptions) then
+ result:=is_visible_for_object(sym.owner,sym.visibility,contextobjdef);
end
else
result:=is_visible_for_object(sym.owner,sym.visibility,contextobjdef);
@@ -4254,6 +4256,14 @@ implementation
result:=true;
exit;
end;
+ if (sp_generic_dummy in tprocsym(srsym).symoptions) and
+ (tprocsym(srsym).procdeflist.count=0) and
+ is_visible_for_object(srsym.owner,srsym.visibility,contextclassh) then
+ begin
+ srsymtable:=srsym.owner;
+ result:=true;
+ exit;
+ end;
end;
typesym,
fieldvarsym,
diff --git a/compiler/x86/nx86inl.pas b/compiler/x86/nx86inl.pas
index 2f40bfba22..1b9c174d44 100644
--- a/compiler/x86/nx86inl.pas
+++ b/compiler/x86/nx86inl.pas
@@ -1223,7 +1223,9 @@ implementation
{ only one memory operand is allowed }
gotmem:=false;
memop:=0;
- for i:=1 to 3 do
+ { in case parameters come on the FPU stack, we have to pop them in reverse order as we
+ called secondpass }
+ for i:=3 downto 1 do
begin
if not(paraarray[i].location.loc in [LOC_MMREGISTER,LOC_CMMREGISTER]) then
begin
diff --git a/packages/fcl-passrc/src/pasresolveeval.pas b/packages/fcl-passrc/src/pasresolveeval.pas
index a2d654cb21..c570595277 100644
--- a/packages/fcl-passrc/src/pasresolveeval.pas
+++ b/packages/fcl-passrc/src/pasresolveeval.pas
@@ -208,6 +208,7 @@ const
nClassTypesAreNotRelatedXY = 3142;
nDirectiveXNotAllowedHere = 3143;
nAwaitWithoutPromise = 3144;
+ nSymbolCannotExportedFromALibrary = 3145;
// using same IDs as FPC
nVirtualMethodXHasLowerVisibility = 3250; // was 3050
@@ -363,6 +364,7 @@ resourcestring
sClassTypesAreNotRelatedXY = 'Class types "%s" and "%s" are not related';
sDirectiveXNotAllowedHere = 'Directive "%s" not allowed here';
sAwaitWithoutPromise = 'Await without promise';
+ sSymbolCannotExportedFromALibrary = 'The symbol cannot be exported from a library';
type
{ TResolveData - base class for data stored in TPasElement.CustomData }
diff --git a/packages/fcl-passrc/src/pasresolver.pp b/packages/fcl-passrc/src/pasresolver.pp
index 77630339f3..9fe78b10ff 100644
--- a/packages/fcl-passrc/src/pasresolver.pp
+++ b/packages/fcl-passrc/src/pasresolver.pp
@@ -1612,6 +1612,7 @@ type
procedure AddClassType(El: TPasClassType; TypeParams: TFPList); virtual;
procedure AddVariable(El: TPasVariable); virtual;
procedure AddResourceString(El: TPasResString); virtual;
+ procedure AddExportSymbol(El: TPasExportSymbol); virtual;
procedure AddEnumType(El: TPasEnumType); virtual;
procedure AddEnumValue(El: TPasEnumValue); virtual;
procedure AddProperty(El: TPasProperty); virtual;
@@ -9139,7 +9140,7 @@ end;
procedure TPasResolver.FinishExportSymbol(El: TPasExportSymbol);
- procedure CheckExpExpr(Expr: TPasExpr; Kinds: TREVKinds; const Expected: string);
+ procedure CheckConstExpr(Expr: TPasExpr; Kinds: TREVKinds; const Expected: string);
var
Value: TResEvalValue;
ResolvedEl: TPasResolverResult;
@@ -9157,9 +9158,40 @@ procedure TPasResolver.FinishExportSymbol(El: TPasExportSymbol);
RaiseXExpectedButYFound(20210101194628,Expected,GetTypeDescription(ResolvedEl),Expr);
end;
+var
+ Expr: TPasExpr;
+ DeclEl: TPasElement;
+ FindData: TPRFindData;
+ Ref: TResolvedReference;
+ ResolvedEl: TPasResolverResult;
begin
- CheckExpExpr(El.ExportIndex,[revkInt,revkUInt],'integer');
- CheckExpExpr(El.ExportName,[revkString,revkUnicodeString],'string');
+ Expr:=El.NameExpr;
+ if Expr<>nil then
+ begin
+ ResolveExpr(Expr,rraRead);
+ //ResolveGlobalSymbol(Expr);
+ ComputeElement(Expr,ResolvedEl,[rcConstant]);
+ DeclEl:=ResolvedEl.IdentEl;
+ if DeclEl=nil then
+ RaiseMsg(20210103012907,nXExpectedButYFound,sXExpectedButYFound,['symbol',GetTypeDescription(ResolvedEl)],Expr);
+ if not (DeclEl.Parent is TPasSection) then
+ RaiseMsg(20210103012908,nXExpectedButYFound,sXExpectedButYFound,['global symbol',GetElementTypeName(DeclEl)],Expr);
+ end
+ else
+ begin
+ FindFirstEl(El.Name,FindData,El);
+ DeclEl:=FindData.Found;
+ if DeclEl=nil then
+ RaiseMsg(20210103002747,nIdentifierNotFound,sIdentifierNotFound,[El.Name],El);
+ if not (DeclEl.Parent is TPasSection) then
+ RaiseMsg(20210103003244,nXExpectedButYFound,sXExpectedButYFound,['global symbol',GetObjPath(DeclEl)],El);
+ Ref:=CreateReference(DeclEl,El,rraRead,@FindData);
+ CheckFoundElement(FindData,Ref);
+ end;
+
+ // check index and name
+ CheckConstExpr(El.ExportIndex,[revkInt,revkUInt],'integer');
+ CheckConstExpr(El.ExportName,[revkString,revkUnicodeString],'string');
end;
procedure TPasResolver.FinishProcParamAccess(ProcType: TPasProcedureType;
@@ -10276,7 +10308,7 @@ begin
if ProcNeedsParams(Proc.ProcType) and not ExprIsAddrTarget(El) then
begin
{$IFDEF VerbosePasResolver}
- writeln('TPasResolver.ResolveNameExpr ',GetObjName(El));
+ writeln('TPasResolver.ResolveNameExpr ',GetObjPath(El));
{$ENDIF}
RaiseMsg(20170216152138,nWrongNumberOfParametersForCallTo,
sWrongNumberOfParametersForCallTo,[Proc.Name],El);
@@ -12205,6 +12237,14 @@ begin
AddIdentifier(TPasIdentifierScope(TopScope),El.Name,El,pikSimple);
end;
+procedure TPasResolver.AddExportSymbol(El: TPasExportSymbol);
+begin
+ {$IFDEF VerbosePasResolver}
+ writeln('TPasResolver.AddExportSymbol ',GetObjName(El));
+ {$ENDIF}
+ // Note: export symbol is not added to scope
+end;
+
procedure TPasResolver.AddEnumType(El: TPasEnumType);
var
CanonicalSet: TPasSetType;
@@ -17452,6 +17492,8 @@ begin
AddProcedureType(TPasProcedureType(SpecEl),nil);
SpecializeProcedureType(TPasProcedureType(GenEl),TPasProcedureType(SpecEl),nil);
end
+ else if C=TPasExportSymbol then
+ RaiseMsg(20210101234958,nSymbolCannotExportedFromALibrary,sSymbolCannotExportedFromALibrary,[],GenEl)
else
RaiseNotYetImplemented(20190728151215,GenEl);
end;
@@ -20866,6 +20908,7 @@ begin
// resolved when finished
else if AClass=TPasAttributes then
else if AClass=TPasExportSymbol then
+ AddExportSymbol(TPasExportSymbol(El))
else if AClass=TPasUnresolvedUnitRef then
RaiseMsg(20171018121900,nCantFindUnitX,sCantFindUnitX,[AName],El)
else
@@ -28209,10 +28252,12 @@ function TPasResolver.ExprIsAddrTarget(El: TPasExpr): boolean;
e.g. '@p().o[].El' or '@El[]'
b) mode delphi: the last element of a right side of an assignment
c) an accessor function, e.g. property P read El;
+ d) an export
}
var
Parent: TPasElement;
Prop: TPasProperty;
+ C: TClass;
begin
Result:=false;
if El=nil then exit;
@@ -28221,31 +28266,34 @@ begin
repeat
Parent:=El.Parent;
//writeln('TPasResolver.ExprIsAddrTarget El=',GetObjName(El),' Parent=',GetObjName(Parent));
- if Parent.ClassType=TUnaryExpr then
+ C:=Parent.ClassType;
+ if C=TUnaryExpr then
begin
if TUnaryExpr(Parent).OpCode=eopAddress then exit(true);
end
- else if Parent.ClassType=TBinaryExpr then
+ else if C=TBinaryExpr then
begin
if TBinaryExpr(Parent).right<>El then exit;
if TBinaryExpr(Parent).OpCode<>eopSubIdent then exit;
end
- else if Parent.ClassType=TParamsExpr then
+ else if C=TParamsExpr then
begin
if TParamsExpr(Parent).Value<>El then exit;
end
- else if Parent.ClassType=TPasProperty then
+ else if C=TPasProperty then
begin
Prop:=TPasProperty(Parent);
Result:=(Prop.ReadAccessor=El) or (Prop.WriteAccessor=El) or (Prop.StoredAccessor=El);
exit;
end
- else if Parent.ClassType=TPasImplAssign then
+ else if C=TPasImplAssign then
begin
if TPasImplAssign(Parent).right<>El then exit;
if (msDelphi in CurrentParser.CurrentModeswitches) then exit(true);
exit;
end
+ else if C=TPasExportSymbol then
+ exit(true)
else
exit;
El:=TPasExpr(Parent);
diff --git a/packages/fcl-passrc/src/pastree.pp b/packages/fcl-passrc/src/pastree.pp
index 819fe25907..709090d435 100644
--- a/packages/fcl-passrc/src/pastree.pp
+++ b/packages/fcl-passrc/src/pastree.pp
@@ -975,6 +975,7 @@ type
TPasExportSymbol = class(TPasElement)
public
+ NameExpr: TPasExpr; // only if name is not a simple identifier
ExportName : TPasExpr;
ExportIndex : TPasExpr;
Destructor Destroy; override;
@@ -2601,6 +2602,7 @@ end;
destructor TPasExportSymbol.Destroy;
begin
+ ReleaseAndNil(TPasElement(NameExpr){$IFDEF CheckPasTreeRefCount},'TPasExportSymbol.NameExpr'{$ENDIF});
ReleaseAndNil(TPasElement(ExportName){$IFDEF CheckPasTreeRefCount},'TPasExportSymbol.ExportName'{$ENDIF});
ReleaseAndNil(TPasElement(ExportIndex){$IFDEF CheckPasTreeRefCount},'TPasExportSymbol.ExportIndex'{$ENDIF});
inherited Destroy;
@@ -2624,6 +2626,7 @@ procedure TPasExportSymbol.ForEachCall(const aMethodCall: TOnForEachPasElement;
const Arg: Pointer);
begin
inherited ForEachCall(aMethodCall, Arg);
+ ForEachChildCall(aMethodCall,Arg,NameExpr,false);
ForEachChildCall(aMethodCall,Arg,ExportName,false);
ForEachChildCall(aMethodCall,Arg,ExportIndex,false);
end;
diff --git a/packages/fcl-passrc/src/pparser.pp b/packages/fcl-passrc/src/pparser.pp
index 467a7fa721..1e8a23c240 100644
--- a/packages/fcl-passrc/src/pparser.pp
+++ b/packages/fcl-passrc/src/pparser.pp
@@ -4341,27 +4341,43 @@ end;
procedure TPasParser.ParseExportDecl(Parent: TPasElement; List: TFPList);
Var
E : TPasExportSymbol;
+ aName: String;
+ NameExpr: TPasExpr;
begin
- Repeat
- if List.Count<>0 then
- ExpectIdentifier;
- E:=TPasExportSymbol(CreateElement(TPasExportSymbol,CurtokenString,Parent));
- List.Add(E);
- NextToken;
- if CurTokenIsIdentifier('INDEX') then
- begin
- NextToken;
- E.Exportindex:=DoParseExpression(E,Nil)
- end
- else if CurTokenIsIdentifier('NAME') then
- begin
- NextToken;
- E.ExportName:=DoParseExpression(E,Nil)
- end;
- if not (CurToken in [tkComma,tkSemicolon]) then
- ParseExc(nParserExpectedCommaSemicolon,SParserExpectedCommaSemicolon);
- Engine.FinishScope(stDeclaration,E);
- until (CurToken=tkSemicolon);
+ try
+ Repeat
+ if List.Count>0 then
+ ExpectIdentifier;
+ aName:=ReadDottedIdentifier(Parent,NameExpr,true);
+ E:=TPasExportSymbol(CreateElement(TPasExportSymbol,aName,Parent));
+ if NameExpr.Kind=pekIdent then
+ // simple identifier -> no need to store NameExpr
+ NameExpr.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF}
+ else
+ begin
+ E.NameExpr:=NameExpr;
+ NameExpr.Parent:=E;
+ end;
+ NameExpr:=nil;
+ List.Add(E);
+ if CurTokenIsIdentifier('INDEX') then
+ begin
+ NextToken;
+ E.Exportindex:=DoParseExpression(E,Nil)
+ end
+ else if CurTokenIsIdentifier('NAME') then
+ begin
+ NextToken;
+ E.ExportName:=DoParseExpression(E,Nil)
+ end;
+ if not (CurToken in [tkComma,tkSemicolon]) then
+ ParseExc(nParserExpectedCommaSemicolon,SParserExpectedCommaSemicolon);
+ Engine.FinishScope(stDeclaration,E);
+ until (CurToken=tkSemicolon);
+ finally
+ if NameExpr<>nil then
+ NameExpr.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF}
+ end;
end;
function TPasParser.ParseProcedureType(Parent: TPasElement;
diff --git a/packages/fcl-passrc/tests/tcresolver.pas b/packages/fcl-passrc/tests/tcresolver.pas
index c1000b6150..587d86c3bf 100644
--- a/packages/fcl-passrc/tests/tcresolver.pas
+++ b/packages/fcl-passrc/tests/tcresolver.pas
@@ -986,6 +986,7 @@ type
Procedure TestLibrary_ExportFunc_IndexStringFail;
Procedure TestLibrary_ExportVar; // ToDo
Procedure TestLibrary_Initialization_Finalization;
+ Procedure TestLibrary_ExportFuncOverloadFail; // ToDo
// ToDo Procedure TestLibrary_UnitExports;
end;
@@ -18833,6 +18834,25 @@ begin
ParseLibrary;
end;
+procedure TTestResolver.TestLibrary_ExportFuncOverloadFail;
+begin
+ exit;
+
+ StartLibrary(false);
+ Add([
+ 'procedure Run(w: word); overload;',
+ 'begin',
+ 'end;',
+ 'procedure Run(d: double); overload;',
+ 'begin',
+ 'end;',
+ 'exports',
+ ' Run,',
+ ' afile.run;',
+ 'begin']);
+ CheckResolverException('The symbol cannot be exported from a library',123);
+end;
+
initialization
RegisterTests([TTestResolver]);
diff --git a/packages/pastojs/src/pas2jsfiler.pp b/packages/pastojs/src/pas2jsfiler.pp
index 362cfb987e..3767d01d2c 100644
--- a/packages/pastojs/src/pas2jsfiler.pp
+++ b/packages/pastojs/src/pas2jsfiler.pp
@@ -4430,6 +4430,7 @@ procedure TPCUWriter.WriteExportSymbol(Obj: TJSONObject; El: TPasExportSymbol;
aContext: TPCUWriterContext);
begin
WritePasElement(Obj,El,aContext);
+ WriteExpr(Obj,El,'NameExpr',El.NameExpr,aContext);
WriteExpr(Obj,El,'ExportName',El.ExportName,aContext);
WriteExpr(Obj,El,'ExportIndex',El.ExportIndex,aContext);
end;
@@ -9256,6 +9257,7 @@ procedure TPCUReader.ReadExportSymbol(Obj: TJSONObject; El: TPasExportSymbol;
aContext: TPCUReaderContext);
begin
ReadPasElement(Obj,El,aContext);
+ El.NameExpr:=ReadExpr(Obj,El,'NameExpr',aContext);
El.ExportName:=ReadExpr(Obj,El,'ExportName',aContext);
El.ExportIndex:=ReadExpr(Obj,El,'ExportIndex',aContext);
end;
diff --git a/packages/pastojs/tests/tcfiler.pas b/packages/pastojs/tests/tcfiler.pas
index d66ca39bbc..e08cbfc904 100644
--- a/packages/pastojs/tests/tcfiler.pas
+++ b/packages/pastojs/tests/tcfiler.pas
@@ -1935,6 +1935,7 @@ end;
procedure TCustomTestPrecompile.CheckRestoredExportSymbol(const Path: string;
Orig, Rest: TPasExportSymbol; Flags: TPCCheckFlags);
begin
+ CheckRestoredElement(Path+'.NameExpr',Orig.NameExpr,Rest.NameExpr,Flags);
CheckRestoredElement(Path+'.ExportName',Orig.ExportName,Rest.ExportName,Flags);
CheckRestoredElement(Path+'.ExportIndex',Orig.ExportIndex,Rest.ExportIndex,Flags);
end;
diff --git a/packages/rtl-objpas/src/inc/nullable.pp b/packages/rtl-objpas/src/inc/nullable.pp
index c66e7d914c..1968ab04ce 100644
--- a/packages/rtl-objpas/src/inc/nullable.pp
+++ b/packages/rtl-objpas/src/inc/nullable.pp
@@ -1,3 +1,17 @@
+{
+ This file is part of the Free Pascal run time library.
+ Copyright (C) 2020 Michael Van Canneyt
+ member of the Free Pascal development team.
+
+ Nullable generic type.
+
+ See the file COPYING.FPC, included in this distribution,
+ for details about the copyright.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+}
unit nullable;
{$mode objfpc}
diff --git a/rtl/aarch64/mathu.inc b/rtl/aarch64/mathu.inc
index 469bb49eca..f55471e963 100644
--- a/rtl/aarch64/mathu.inc
+++ b/rtl/aarch64/mathu.inc
@@ -51,7 +51,7 @@ function SetRoundMode(const RoundMode: TFPURoundingMode): TFPURoundingMode;
rm2bits: array[TFPURoundingMode] of byte = (0,2,1,3);
begin
softfloat_rounding_mode:=RoundMode;
- SetRoundMode:=RoundMode;
+ SetRoundMode:=GetRoundMode;
setfpcr((getfpcr and $ff3fffff) or (rm2bits[RoundMode] shl 22));
end;
diff --git a/rtl/arm/mathu.inc b/rtl/arm/mathu.inc
index 038ec6f220..c7fa2a1c60 100644
--- a/rtl/arm/mathu.inc
+++ b/rtl/arm/mathu.inc
@@ -62,9 +62,10 @@ function SetRoundMode(const RoundMode: TFPURoundingMode): TFPURoundingMode;
var
c: dword;
begin
+ softfloat_rounding_mode:=RoundMode;
+ Reslut:=GetRoundMode;
c:=Ord(RoundMode) shl 16;
c:=_controlfp(c, _MCW_RC);
- Result:=TFPURoundingMode((c shr 16) and 3);
end;
function GetPrecisionMode: TFPUPrecisionMode;
diff --git a/rtl/i386/mathu.inc b/rtl/i386/mathu.inc
index a1ba0970d1..ab0361cc34 100644
--- a/rtl/i386/mathu.inc
+++ b/rtl/i386/mathu.inc
@@ -147,6 +147,7 @@ function SetRoundMode(const RoundMode: TFPURoundingMode): TFPURoundingMode;
var
CtlWord: Word;
begin
+ softfloat_rounding_mode:=RoundMode;
CtlWord := Get8087CW;
Set8087CW((CtlWord and $F3FF) or (Ord(RoundMode) shl 10));
if has_sse_support then
diff --git a/rtl/i8086/mathu.inc b/rtl/i8086/mathu.inc
index 237ecf0300..4229183064 100644
--- a/rtl/i8086/mathu.inc
+++ b/rtl/i8086/mathu.inc
@@ -155,6 +155,7 @@ function SetRoundMode(const RoundMode: TFPURoundingMode): TFPURoundingMode;
var
CtlWord: Word;
begin
+ softfloat_rounding_mode:=RoundMode;
CtlWord := Get8087CW;
Set8087CW((CtlWord and $F3FF) or (Ord(RoundMode) shl 10));
{ if has_sse_support then
diff --git a/rtl/m68k/mathu.inc b/rtl/m68k/mathu.inc
index a3c656b4bc..1dd65451df 100644
--- a/rtl/m68k/mathu.inc
+++ b/rtl/m68k/mathu.inc
@@ -137,10 +137,10 @@ const
var
FPCR: DWord;
begin
+ Result:=GetRoundMode;
FPCR:=GetFPCR and not FPU68K_ROUND_MASK;
SetFPCR(FPCR or FPCToFPURoundingMode[RoundMode]);
softfloat_rounding_mode:=RoundMode;
- Result:=RoundMode;
end;
function GetPrecisionMode: TFPUPrecisionMode;
diff --git a/rtl/mips/mathu.inc b/rtl/mips/mathu.inc
index 8a4be08746..9f8e9aa616 100644
--- a/rtl/mips/mathu.inc
+++ b/rtl/mips/mathu.inc
@@ -62,6 +62,7 @@ function SetRoundMode(const RoundMode: TFPURoundingMode): TFPURoundingMode;
begin
fsr:=get_fsr;
result:=fsr2roundmode[fsr and fpu_rounding_mask];
+ softfloat_rounding_mode:=RoundMode;
set_fsr((fsr and not fpu_rounding_mask) or roundmode2fsr[RoundMode]);
end;
diff --git a/rtl/powerpc/mathu.inc b/rtl/powerpc/mathu.inc
index 7d204f341b..372ec4c2e4 100644
--- a/rtl/powerpc/mathu.inc
+++ b/rtl/powerpc/mathu.inc
@@ -101,12 +101,12 @@ begin
mode := FP_RND_RM;
end;
end;
+ result := GetRoundMode;
{$ifndef aix}
setFPSCR((getFPSCR and (not RoundModeMask)) or mode);
{$else not aix}
fp_swap_rnd(mode);
{$endif not aix}
- result := RoundMode;
end;
diff --git a/rtl/powerpc64/mathu.inc b/rtl/powerpc64/mathu.inc
index 4e3a62b8b9..12247e0b68 100644
--- a/rtl/powerpc64/mathu.inc
+++ b/rtl/powerpc64/mathu.inc
@@ -109,12 +109,12 @@ begin
mode := FP_RND_RM;
end;
end;
+ result := GetRoundMode;
{$ifndef aix}
setFPSCR((getFPSCR and (not RoundModeMask)) or mode);
{$else not aix}
fp_swap_rnd(mode);
{$endif not aix}
- result := RoundMode;
end;
diff --git a/rtl/riscv64/mathu.inc b/rtl/riscv64/mathu.inc
index 1c0f48bfeb..8dfb273a0a 100644
--- a/rtl/riscv64/mathu.inc
+++ b/rtl/riscv64/mathu.inc
@@ -50,7 +50,7 @@ function SetRoundMode(const RoundMode: TFPURoundingMode): TFPURoundingMode;
rm2bits : array[TFPURoundingMode] of byte = (0,2,3,1);
begin
softfloat_rounding_mode:=RoundMode;
- SetRoundMode:=RoundMode;
+ SetRoundMode:=GetRoundMode;
setrm(rm2bits[RoundMode]);
end;
diff --git a/rtl/sparc/mathu.inc b/rtl/sparc/mathu.inc
index 9749147f82..50d00a1abb 100644
--- a/rtl/sparc/mathu.inc
+++ b/rtl/sparc/mathu.inc
@@ -32,6 +32,7 @@ function SetRoundMode(const RoundMode: TFPURoundingMode): TFPURoundingMode;
cw: dword;
begin
cw:=get_fsr;
+ softfloat_rounding_mode:=RoundMode;
result:=TFPURoundingMode(cw shr 30);
set_fsr((cw and $3fffffff) or (rm2bits[RoundMode] shl 30));
end;
diff --git a/rtl/sparc64/mathu.inc b/rtl/sparc64/mathu.inc
index 43f2010a41..b8d4d70870 100644
--- a/rtl/sparc64/mathu.inc
+++ b/rtl/sparc64/mathu.inc
@@ -31,6 +31,7 @@ function SetRoundMode(const RoundMode: TFPURoundingMode): TFPURoundingMode;
cw: dword;
begin
cw:=get_fsr;
+ softfloat_rounding_mode:=RoundMode;
result:=TFPURoundingMode(cw shr 30);
set_fsr((cw and $3fffffff) or (rm2bits[RoundMode] shl 30));
end;
diff --git a/rtl/win/syswin.inc b/rtl/win/syswin.inc
index 63ee752569..f79b9849cd 100644
--- a/rtl/win/syswin.inc
+++ b/rtl/win/syswin.inc
@@ -609,6 +609,14 @@ procedure Win32Ansi2UnicodeMove(source:pchar;cp : TSystemCodePage;var dest:Unico
dwFlags:=MB_PRECOMPOSED;
end;
destlen:=MultiByteToWideChar(cp, dwFlags, source, len, nil, 0);
+ { destlen=0 means that Windows cannot convert, so call the default
+ handler. This is similiar to what unix does and is a good fallback
+ if rawbyte strings are passed }
+ if destlen=0 then
+ begin
+ DefaultAnsi2UnicodeMove(source,DefaultSystemCodePage,dest,len);
+ exit;
+ end;
// this will null-terminate
setlength(dest, destlen);
if destlen>0 then
diff --git a/rtl/x86_64/mathu.inc b/rtl/x86_64/mathu.inc
index 1271828161..955a01de5c 100644
--- a/rtl/x86_64/mathu.inc
+++ b/rtl/x86_64/mathu.inc
@@ -201,6 +201,7 @@ var
begin
CtlWord:=Get8087CW;
SSECSR:=GetMXCSR;
+ softfloat_rounding_mode:=RoundMode;
Set8087CW((CtlWord and $F3FF) or (Ord(RoundMode) shl 10));
SetMXCSR((SSECSR and $ffff9fff) or (dword(RoundMode) shl 13));
{$ifdef FPC_HAS_TYPE_EXTENDED}
diff --git a/rtl/xtensa/mathu.inc b/rtl/xtensa/mathu.inc
index 06b7338fa7..381a7d00df 100644
--- a/rtl/xtensa/mathu.inc
+++ b/rtl/xtensa/mathu.inc
@@ -20,6 +20,7 @@ function GetRoundMode: TFPURoundingMode;
function SetRoundMode(const RoundMode: TFPURoundingMode): TFPURoundingMode;
begin
+ SetRoundMode:=softfloat_rounding_mode;
softfloat_rounding_mode:=RoundMode;
end;
diff --git a/tests/test/tgenfunc24.pp b/tests/test/tgenfunc24.pp
new file mode 100644
index 0000000000..ca592be8d5
--- /dev/null
+++ b/tests/test/tgenfunc24.pp
@@ -0,0 +1,25 @@
+{ %FAIL }
+
+program tgenfunc24;
+
+{$mode delphi}
+
+type
+ TTest = class
+ public type
+ Test = class
+ end;
+
+ public
+ procedure Test<T>;
+ end;
+
+procedure TTest.Test<T>;
+begin
+
+end;
+
+begin
+
+end.
+
diff --git a/tests/test/tgenfunc25.pp b/tests/test/tgenfunc25.pp
new file mode 100644
index 0000000000..3728c37807
--- /dev/null
+++ b/tests/test/tgenfunc25.pp
@@ -0,0 +1,24 @@
+{ %FAIL }
+
+program tgenfunc25;
+
+{$mode delphi}
+
+type
+ TTest = class
+ public
+ procedure Test<T>;
+ public type
+ Test = class
+ end;
+ end;
+
+procedure TTest.Test<T>;
+begin
+
+end;
+
+begin
+
+end.
+
diff --git a/tests/test/tgenfunc26.pp b/tests/test/tgenfunc26.pp
new file mode 100644
index 0000000000..f0f34b9b13
--- /dev/null
+++ b/tests/test/tgenfunc26.pp
@@ -0,0 +1,24 @@
+{ %FAIL }
+
+unit tgenfunc26;
+
+{$mode objfpc}{$H+}
+
+interface
+
+generic procedure Test<T>;
+
+type
+ Test = record
+
+ end;
+
+implementation
+
+generic procedure Test<T>;
+begin
+
+end;
+
+end.
+
diff --git a/tests/test/tgenfunc27.pp b/tests/test/tgenfunc27.pp
new file mode 100644
index 0000000000..ea18a34fea
--- /dev/null
+++ b/tests/test/tgenfunc27.pp
@@ -0,0 +1,24 @@
+{ %FAIL }
+
+unit tgenfunc27;
+
+{$mode objfpc}{$H+}
+
+interface
+
+type
+ Test = record
+
+ end;
+
+generic procedure Test<T>;
+
+implementation
+
+generic procedure Test<T>;
+begin
+
+end;
+
+end.
+
diff --git a/tests/test/units/math/trndcurr.pp b/tests/test/units/math/trndcurr.pp
index 1c198789eb..a98728160c 100644
--- a/tests/test/units/math/trndcurr.pp
+++ b/tests/test/units/math/trndcurr.pp
@@ -1,13 +1,34 @@
uses
Math;
+
+const
+ failure_count : longint = 0;
+ first_error : longint = 0;
+
{$ifndef SKIP_CURRENCY_TEST}
procedure testround(const c, expected: currency; error: longint);
begin
if round(c)<>expected then
begin
writeln('round(',c,') = ',round(c),' instead of ', expected);
- halt(error);
+ inc(failure_count);
+ if first_error=0 then
+ first_error:=error;
+ end;
+end;
+{$endif}
+
+
+{$ifndef SKIP_SINGLE_TEST}
+procedure testroundsingle(const c, expected: single; error: longint);
+begin
+ if round(c)<>expected then
+ begin
+ writeln('round(',c,') = ',round(c),' instead of ', expected);
+ inc(failure_count);
+ if first_error=0 then
+ first_error:=error;
end;
end;
@@ -16,6 +37,13 @@ end;
begin
{$ifndef SKIP_CURRENCY_TEST}
+ if GetRoundMode <> rmNearest then
+ begin
+ writeln('Starting rounding mode is not rmNearest');
+ inc(failure_count);
+ if first_error=0 then
+ first_error:=200;
+ end;
writeln('Rounding mode: rmNearest (even)');
testround(0.5,0.0,1);
testround(1.5,2.0,2);
@@ -31,7 +59,15 @@ begin
testround(-1.4,-1.0,154);
writeln('Rounding mode: rmUp');
- SetRoundMode(rmUp);
+ if SetRoundMode(rmUp)<>rmNearest then
+ writeln('Warning: previous mode was not rmNearest');
+ if GetRoundMode <> rmUp then
+ begin
+ writeln('Failed to set rounding mode to rmUp');
+ inc(failure_count);
+ if first_error=0 then
+ first_error:=201;
+ end;
testround(0.5,1.0,5);
testround(1.5,2.0,6);
testround(-0.5,0.0,7);
@@ -46,7 +82,15 @@ begin
testround(-1.4,-1.0,158);
writeln('Rounding mode: rmDown');
- SetRoundMode(rmDown);
+ if SetRoundMode(rmDown)<>rmUp then
+ writeln('Warning: previous mode was not rmUp');
+ if GetRoundMode <> rmDown then
+ begin
+ writeln('Failed to set rounding mode to rmDown');
+ inc(failure_count);
+ if first_error=0 then
+ first_error:=202;
+ end;
testround(0.5,0.0,9);
testround(1.5,1.0,10);
testround(-0.5,-1.0,11);
@@ -61,7 +105,15 @@ begin
testround(-1.4,-2.0,162);
writeln('Rounding mode: rmTruncate');
- SetRoundMode(rmTruncate);
+ if SetRoundMode(rmTruncate)<>rmDown then
+ writeln('Warning: previous mode was not rmDown');
+ if GetRoundMode <> rmTruncate then
+ begin
+ writeln('Failed to set rounding mode to rmTruncate');
+ inc(failure_count);
+ if first_error=0 then
+ first_error:=203;
+ end;
testround(0.5,0.0,13);
testround(1.5,1.0,14);
testround(-0.5,0.0,15);
@@ -75,4 +127,100 @@ begin
testround(-0.4,0.0,165);
testround(-1.4,-1.0,166);
{$endif}
+{$ifndef SKIP_SINGLE_TEST}
+ SetRoundMode(rmNearest);
+ if GetRoundMode <> rmNearest then
+ begin
+ writeln('Starting rounding mode is not rmNearest');
+ inc(failure_count);
+ if first_error=0 then
+ first_error:=200;
+ end;
+ writeln('Rounding mode: rmNearest (even)');
+ testroundsingle(0.5,0.0,1);
+ testroundsingle(1.5,2.0,2);
+ testroundsingle(-0.5,0.0,3);
+ testroundsingle(-1.5,-2.0,4);
+ testroundsingle(0.6,1.0,101);
+ testroundsingle(1.6,2.0,102);
+ testroundsingle(-0.6,-1.0,103);
+ testroundsingle(-1.6,-2.0,104);
+ testroundsingle(0.4,0.0,151);
+ testroundsingle(1.4,1.0,152);
+ testroundsingle(-0.4,-0.0,153);
+ testroundsingle(-1.4,-1.0,154);
+
+ writeln('Rounding mode: rmUp');
+ if SetRoundMode(rmUp)<>rmNearest then
+ writeln('Warning: previous mode was not rmNearest');
+ if GetRoundMode <> rmUp then
+ begin
+ writeln('Failed to set rounding mode to rmUp');
+ inc(failure_count);
+ if first_error=0 then
+ first_error:=201;
+ end;
+ testroundsingle(0.5,1.0,5);
+ testroundsingle(1.5,2.0,6);
+ testroundsingle(-0.5,0.0,7);
+ testroundsingle(-1.5,-1.0,8);
+ testroundsingle(0.6,1.0,105);
+ testroundsingle(1.6,2.0,106);
+ testroundsingle(-0.6,0.0,107);
+ testroundsingle(-1.6,-1.0,108);
+ testroundsingle(0.4,1.0,155);
+ testroundsingle(1.4,2.0,156);
+ testroundsingle(-0.4,0.0,157);
+ testroundsingle(-1.4,-1.0,158);
+
+ writeln('Rounding mode: rmDown');
+ if SetRoundMode(rmDown)<>rmUp then
+ writeln('Warning: previous mode was not rmUp');
+ if GetRoundMode <> rmDown then
+ begin
+ writeln('Failed to set rounding mode to rmDown');
+ inc(failure_count);
+ if first_error=0 then
+ first_error:=202;
+ end;
+ testroundsingle(0.5,0.0,9);
+ testroundsingle(1.5,1.0,10);
+ testroundsingle(-0.5,-1.0,11);
+ testroundsingle(-1.5,-2.0,12);
+ testroundsingle(0.6,0.0,109);
+ testroundsingle(1.6,1.0,110);
+ testroundsingle(-0.6,-1.0,111);
+ testroundsingle(-1.6,-2.0,112);
+ testroundsingle(0.4,0.0,159);
+ testroundsingle(1.4,1.0,160);
+ testroundsingle(-0.4,-1.0,161);
+ testroundsingle(-1.4,-2.0,162);
+
+ writeln('Rounding mode: rmTruncate');
+ if SetRoundMode(rmTruncate)<>rmDown then
+ writeln('Warning: previous mode was not rmDown');
+ if GetRoundMode <> rmTruncate then
+ begin
+ writeln('Failed to set rounding mode to rmTruncate');
+ inc(failure_count);
+ if first_error=0 then
+ first_error:=203;
+ end;
+ testroundsingle(0.5,0.0,13);
+ testroundsingle(1.5,1.0,14);
+ testroundsingle(-0.5,0.0,15);
+ testroundsingle(-1.5,-1.0,16);
+ testroundsingle(0.6,0.0,113);
+ testroundsingle(1.6,1.0,114);
+ testroundsingle(-0.6,0.0,115);
+ testroundsingle(-1.6,-1.0,116);
+ testroundsingle(0.4,0.0,163);
+ testroundsingle(1.4,1.0,164);
+ testroundsingle(-0.4,0.0,165);
+ testroundsingle(-1.4,-1.0,166);
+{$endif}
+ if failure_count=0 then
+ writeln('SetRoundMode test finished OK')
+ else
+ halt(first_error);
end.
diff --git a/tests/webtbf/tw38289a.pp b/tests/webtbf/tw38289a.pp
new file mode 100644
index 0000000000..9e89a8a9df
--- /dev/null
+++ b/tests/webtbf/tw38289a.pp
@@ -0,0 +1,8 @@
+{ %FAIL }
+
+library tw38289a;
+procedure Test; begin end;
+exports
+ Test index 3 'abc';
+ //------------^^^
+end.
diff --git a/tests/webtbf/tw38289b.pp b/tests/webtbf/tw38289b.pp
new file mode 100644
index 0000000000..5229c86a3a
--- /dev/null
+++ b/tests/webtbf/tw38289b.pp
@@ -0,0 +1,8 @@
+{ %FAIL }
+
+library tw38289b;
+procedure Test; begin end;
+exports
+ Test index 'abc' 3;
+ //------------^^^
+end.
diff --git a/tests/webtbs/tw38267b.pp b/tests/webtbs/tw38267b.pp
index 4dd0449d81..df7ee09010 100644
--- a/tests/webtbs/tw38267b.pp
+++ b/tests/webtbs/tw38267b.pp
@@ -1,6 +1,6 @@
{ %opt=-O3 -Sg }
{$mode objfpc} {$longstrings+}
-label start1, end1, start2, end2, start3, end3;
+label start1, end1, start2, end2, start3, end3, start4, end4;
var
s: string;
@@ -88,5 +88,34 @@ end3:
if PtrUint(CodePointer(@end3) - CodePointer(@start3))>300 then
halt(3);
writeln;
+
+ writeln('31 literals concatenated with 1 dynamic string, they could fold but didn''t at all:');
+start4:
+ s := 'Once like a Great House' + (LineEnding +
+ ('founded on sand,' + (LineEnding +
+ ('Stood our Temple' + (LineEnding +
+ ('whose pillars on troubles were based.' + (LineEnding +
+ ('Now mischievous spirits, bound,' + (LineEnding +
+ ('in dim corners stand,' + (LineEnding +
+ ('Rotted columns, but' + (LineEnding +
+ ('with iron-bound bands embraced' + (LineEnding +
+ ('Cracked, crumbling marble,' + (LineEnding +
+ ('tempered on every hand,' + (LineEnding +
+ ('By strong steel' + (LineEnding +
+ ('forged in fire and faith.' + (LineEnding +
+ ('Shackled, these wayward servants' + (LineEnding +
+ ('serve the land,' + (LineEnding +
+ ('The Temple secured' + (LineEnding +
+ ('by the Builder’s grace.' +
+ Copy('', 1, 0)))))))))))))))))))))))))))))));
+end4:
+ writeln(Copy(s, 1, 0), PtrUint(CodePointer(@end4) - CodePointer(@start4)), ' b of code');
+ { more than 100 bytes of code might point out that the constants are not folded,
+ example x86_64-linux: not folded: 1384 bytes; folded: 108 bytes
+ }
+ if PtrUint(CodePointer(@end4) - CodePointer(@start4))>300 then
+ halt(4);
+
+
writeln('ok');
end.
diff --git a/tests/webtbs/tw38295.pp b/tests/webtbs/tw38295.pp
new file mode 100644
index 0000000000..eb3eab25ba
--- /dev/null
+++ b/tests/webtbs/tw38295.pp
@@ -0,0 +1,19 @@
+{ %cpu=i386 }
+{ %opt=-CfAVX -CpCOREAVX2 -OoFASTMATH }
+uses
+ cpu;
+var
+ a, b: uint32; // or (u)int64; int32 works
+ r: single; // or double, or even extended
+begin
+ if FMASupport then
+ begin
+ a := 1;
+ b := 3;
+ r := a + b / 10;
+ writeln(r:0:3);
+ if r>2.0 then
+ halt(1);
+ writeln('ok');
+ end;
+end.
diff --git a/tests/webtbs/tw38299.pp b/tests/webtbs/tw38299.pp
new file mode 100644
index 0000000000..8c52902b48
--- /dev/null
+++ b/tests/webtbs/tw38299.pp
@@ -0,0 +1,15 @@
+{ %opt=-O2 -Fcutf8 }
+program bug;
+const
+ cAnsiLineFeed = AnsiChar(#10);
+ cAnsiCarriageReturn = AnsiChar(#13);
+var
+ test: RawByteString;
+begin
+ test := '123';
+ test := test + UTF8Encode('456') + '789' + cAnsiCarriageReturn + cAnsiLineFeed;
+ writeln(test);
+ if test<>'123456789'#13#10 then
+ halt(1);
+ writeln('ok');
+end.
diff --git a/utils/fpdoc/dglobals.pp b/utils/fpdoc/dglobals.pp
index f44619eed2..a1ce8bb899 100644
--- a/utils/fpdoc/dglobals.pp
+++ b/utils/fpdoc/dglobals.pp
@@ -139,7 +139,7 @@ resourcestring
SHTMLIndexColcount = 'Use N columns in the identifier index pages';
SHTMLImageUrl = 'Prefix image URLs with url';
SHTMLDisableMenuBrackets = 'Disable ''['' and '']'' characters around menu items at the top of the page. Useful for custom css';
-
+
// CHM usage
SCHMUsageTOC = 'Use [File] as the table of contents. Usually a .hhc file.';
SCHMUsageIndex = 'Use [File] as the index. Usually a .hhk file.';
@@ -151,6 +151,18 @@ resourcestring
SCHMUsageMakeSearch = 'Automatically generate a Search Index from filenames that match *.htm*';
SCHMUsageChmTitle= 'Title of the chm. Defaults to the value from --package';
+ // MarkDown usage
+ SMDUsageFooter = 'Append markdown (@filename reads from file) as footer to every markdown page';
+ SMDUsageHeader = 'Prepend markdown (@filename reads from file) as header to every markdown page';
+ SMDIndexColcount = 'Use N columns in the identifier index pages';
+ SMDImageUrl = 'Prefix image URLs with url';
+ SMDTheme = 'Use name as theme name';
+ SMDNavigation = 'Use scheme for navigation tree, here scheme is one of:';
+ SMDNavSubtree = ' UnitSubTree : put all units in a sub tree of a Units node';
+ SMDNavTree = ' UnitTree : put every units as a node on the same level as packages node';
+
+
+
SXMLUsageSource = 'Include source file and line info in generated XML';
// Linear usage
diff --git a/utils/fpdoc/dw_basehtml.pp b/utils/fpdoc/dw_basehtml.pp
new file mode 100644
index 0000000000..c0a82aae25
--- /dev/null
+++ b/utils/fpdoc/dw_basehtml.pp
@@ -0,0 +1,1060 @@
+{
+ FPDoc - Free Pascal Documentation Tool
+ Copyright (C) 2021 by Michael Van Canneyt
+
+ * Basic HTML output generator. No assumptions about document/documentation structure
+
+ 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_basehtml;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses Classes, DOM, DOM_HTML, dGlobals, PasTree, dWriter;
+
+
+type
+
+ { THTMLWriter }
+
+ { TBaseHTMLWriter }
+
+ TBaseHTMLWriter = class(TMultiFileDocWriter)
+ Private
+ FImageFileList: TStrings;
+ FContentElement : THTMLELement;
+ FInsideHeadRow: Boolean;
+ FOutputNodeStack: TFPList;
+ FBaseImageURL : String;
+ FDoc: THTMLDocument;
+ FCurOutputNode: TDOMNode;
+ FDoPasHighlighting : Boolean;
+ FHighlighterFlags: Byte;
+ Protected
+
+ Procedure SetContentElement(aElement : THTMLELement); virtual;
+ // Description node conversion
+ Procedure DescrEmitNotesHeader(AContext : TPasElement); override;
+ Procedure DescrEmitNotesFooter(AContext : TPasElement); override;
+ 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 DescrBeginUnderline; override;
+ procedure DescrEndUnderline; override;
+ procedure DescrWriteImageEl(const AFileName, ACaption, ALinkName : DOMString); override;
+ procedure DescrWriteFileEl(const AText: DOMString); override;
+ procedure DescrWriteKeywordEl(const AText: DOMString); override;
+ procedure DescrWriteVarEl(const AText: DOMString); override;
+ procedure DescrBeginLink(const AId: DOMString); override;
+ procedure DescrEndLink; override;
+ procedure DescrBeginURL(const AURL: DOMString); override;
+ procedure DescrEndURL; override;
+ procedure DescrWriteLinebreak; override;
+ procedure DescrBeginParagraph; override;
+ procedure DescrEndParagraph; override;
+ procedure DescrBeginCode(HasBorder: Boolean; const AHighlighterName: String); override;
+ procedure DescrWriteCodeLine(const ALine: String); override;
+ procedure DescrEndCode; override;
+ procedure DescrBeginOrderedList; override;
+ procedure DescrEndOrderedList; override;
+ procedure DescrBeginUnorderedList; override;
+ procedure DescrEndUnorderedList; override;
+ procedure DescrBeginDefinitionList; override;
+ procedure DescrEndDefinitionList; override;
+ procedure DescrBeginListItem; override;
+ procedure DescrEndListItem; override;
+ procedure DescrBeginDefinitionTerm; override;
+ procedure DescrEndDefinitionTerm; override;
+ procedure DescrBeginDefinitionEntry; override;
+ procedure DescrEndDefinitionEntry; override;
+ procedure DescrBeginSectionTitle; override;
+ procedure DescrBeginSectionBody; override;
+ procedure DescrEndSection; override;
+ procedure DescrBeginRemark; override;
+ procedure DescrEndRemark; override;
+ procedure DescrBeginTable(ColCount: Integer; HasBorder: Boolean); override;
+ procedure DescrEndTable; override;
+ procedure DescrBeginTableCaption; override;
+ procedure DescrEndTableCaption; override;
+ procedure DescrBeginTableHeadRow; override;
+ procedure DescrEndTableHeadRow; override;
+ procedure DescrBeginTableRow; override;
+ procedure DescrEndTableRow; override;
+ procedure DescrBeginTableCell; override;
+ procedure DescrEndTableCell; override;
+
+ // Basic HTML handling
+ Procedure SetHTMLDocument(aDoc : THTMLDocument);
+ procedure PushOutputNode(ANode: TDOMNode);
+ procedure PopOutputNode;
+ procedure AppendText(Parent: TDOMNode; const AText: String);
+ procedure AppendText(Parent: TDOMNode; const AText: DOMString);
+ procedure AppendNbSp(Parent: TDOMNode; ACount: Integer);
+ procedure AppendSym(Parent: TDOMNode; const AText: DOMString);
+ procedure AppendKw(Parent: TDOMNode; const AText: String);
+ procedure AppendKw(Parent: TDOMNode; const AText: DOMString);
+ function AppendPasSHFragment(Parent: TDOMNode; const AText: String; AShFlags: Byte): Byte;
+ procedure AppendFragment(aParentNode: TDOMElement; aStream: TStream);
+ // FPDoc specifics
+ procedure AppendSourceRef(aParent: TDOMElement; AElement: TPasElement);
+ Procedure AppendSeeAlsoSection(AElement: TPasElement; DocNode: TDocNode); virtual;
+ Procedure AppendExampleSection(AElement : TPasElement;DocNode : TDocNode); virtual;
+ Procedure AppendShortDescr(Parent: TDOMNode; Element: TPasElement);
+ procedure AppendShortDescr(AContext: TPasElement; Parent: TDOMNode; DocNode: TDocNode);
+ procedure AppendShortDescrCell(Parent: TDOMNode; Element: TPasElement);
+ procedure AppendDescr(AContext: TPasElement; Parent: TDOMNode; DescrNode: TDOMElement; AutoInsertBlock: Boolean);
+ procedure AppendDescrSection(AContext: TPasElement; Parent: TDOMNode; DescrNode: TDOMElement; const ATitle: DOMString);
+ procedure AppendDescrSection(AContext: TPasElement; Parent: TDOMNode; DescrNode: TDOMElement; const ATitle: String);
+ function AppendHyperlink(Parent: TDOMNode; Element: TPasElement): TDOMElement;
+
+ // Helper functions for creating DOM elements
+
+ function CreateEl(Parent: TDOMNode; const AName: DOMString): THTMLElement;
+ function CreatePara(Parent: TDOMNode): THTMLElement;
+ function CreateH1(Parent: TDOMNode): THTMLElement;
+ function CreateH2(Parent: TDOMNode): THTMLElement;
+ function CreateH3(Parent: TDOMNode): THTMLElement;
+ function CreateTable(Parent: TDOMNode; const AClass: DOMString = ''): THTMLElement;
+ function CreateContentTable(Parent: TDOMNode): THTMLElement;
+ function CreateTR(Parent: TDOMNode): THTMLElement;
+ function CreateTD(Parent: TDOMNode): THTMLElement;
+ function CreateTD_vtop(Parent: TDOMNode): THTMLElement;
+ function CreateLink(Parent: TDOMNode; const AHRef: String): THTMLElement;
+ function CreateLink(Parent: TDOMNode; const AHRef: DOMString): THTMLElement;
+ function CreateAnchor(Parent: TDOMNode; const AName: DOMString): THTMLElement;
+ function CreateCode(Parent: TDOMNode): THTMLElement;
+ function CreateWarning(Parent: TDOMNode): THTMLElement;
+
+
+ // Some info
+ Property ContentElement : THTMLELement Read FContentElement Write SetContentElement;
+ Property OutputNodeStack: TFPList Read FOutputNodeStack;
+ Property CurOutputNode : TDomNode Read FCurOutputNode;
+ Property ImageFileList : TStrings Read FImageFileList;
+ Property Doc: THTMLDocument Read FDoc;
+ Property InsideHeadRow: Boolean Read FInsideHeadRow;
+ Property DoPasHighlighting : Boolean Read FDoPasHighlighting;
+ Property HighlighterFlags : Byte read FHighlighterFlags;
+
+ Public
+ constructor Create(APackage: TPasPackage; AEngine: TFPDocEngine); override;
+ Destructor Destroy; override;
+ Property BaseImageURL : String Read FBaseImageURL Write FBaseImageURL;
+ end;
+
+Function FixHTMLpath(S : String) : STring;
+
+implementation
+
+uses xmlread, sysutils, sh_pas;
+
+Function FixHTMLpath(S : String) : STring;
+
+begin
+ Result:=StringReplace(S,'\','/',[rfReplaceAll]);
+end;
+
+constructor TBaseHTMLWriter.Create(APackage: TPasPackage; AEngine: TFPDocEngine);
+
+begin
+ Inherited;
+ FOutputNodeStack := TFPList.Create;
+ FImageFileList:=TStringList.Create;
+end;
+
+destructor TBaseHTMLWriter.Destroy;
+begin
+ FreeAndNil(FOutputNodeStack);
+ FreeAndNil(FImageFileList);
+ inherited Destroy;
+end;
+
+Procedure TBaseHTMLWriter.SetContentElement(aElement : THTMLELement);
+
+begin
+ FContentElement:=aElement;
+end;
+
+function TBaseHTMLWriter.CreateEl(Parent: TDOMNode;
+ const AName: DOMString): THTMLElement;
+begin
+ Result := Doc.CreateElement(AName);
+ Parent.AppendChild(Result);
+end;
+
+function TBaseHTMLWriter.CreatePara(Parent: TDOMNode): THTMLElement;
+begin
+ Result := CreateEl(Parent, 'p');
+end;
+
+function TBaseHTMLWriter.CreateH1(Parent: TDOMNode): THTMLElement;
+begin
+ Result := CreateEl(Parent, 'h1');
+end;
+
+function TBaseHTMLWriter.CreateH2(Parent: TDOMNode): THTMLElement;
+begin
+ Result := CreateEl(Parent, 'h2');
+end;
+
+function TBaseHTMLWriter.CreateH3(Parent: TDOMNode): THTMLElement;
+begin
+ Result := CreateEl(Parent, 'h3');
+end;
+
+function TBaseHTMLWriter.CreateTable(Parent: TDOMNode; const AClass: DOMString = ''): THTMLElement;
+begin
+ Result := CreateEl(Parent, 'table');
+ Result['cellspacing'] := '0';
+ Result['cellpadding'] := '0';
+ if AClass <> '' then
+ Result['class'] := AClass;
+end;
+
+function TBaseHTMLWriter.CreateContentTable(Parent: TDOMNode): THTMLElement;
+begin
+ Result := CreateEl(Parent, 'table');
+end;
+
+function TBaseHTMLWriter.CreateTR(Parent: TDOMNode): THTMLElement;
+begin
+ Result := CreateEl(Parent, 'tr');
+end;
+
+function TBaseHTMLWriter.CreateTD(Parent: TDOMNode): THTMLElement;
+begin
+ Result := CreateEl(Parent, 'td');
+end;
+
+function TBaseHTMLWriter.CreateTD_vtop(Parent: TDOMNode): THTMLElement;
+begin
+ Result := CreateEl(Parent, 'td');
+ Result['valign'] := 'top';
+end;
+
+function TBaseHTMLWriter.CreateLink(Parent: TDOMNode; const AHRef: String): THTMLElement;
+begin
+ Result := CreateEl(Parent, 'a');
+ Result['href'] := UTF8Decode(FixHtmlPath(AHRef));
+end;
+
+function TBaseHTMLWriter.CreateLink(Parent: TDOMNode;
+ const AHRef: DOMString): THTMLElement;
+begin
+ Result:=CreateLink(Parent,UTF8Encode(aHREf));
+end;
+
+function TBaseHTMLWriter.CreateAnchor(Parent: TDOMNode;
+ const AName: DOMString): THTMLElement;
+begin
+ Result := CreateEl(Parent, 'a');
+ Result['name'] := AName;
+end;
+
+function TBaseHTMLWriter.CreateCode(Parent: TDOMNode): THTMLElement;
+begin
+ Result := CreateEl(CreateEl(Parent, 'tt'), 'span');
+ Result['class'] := 'code';
+end;
+
+function TBaseHTMLWriter.CreateWarning(Parent: TDOMNode): THTMLElement;
+begin
+ Result := CreateEl(Parent, 'span');
+ Result['class'] := 'warning';
+end;
+
+procedure TBaseHTMLWriter.DescrEmitNotesHeader(AContext: TPasElement);
+begin
+ AppendText(CreateH2(ContentElement), SDocNotes);
+ PushOutputNode(ContentElement);
+end;
+
+procedure TBaseHTMLWriter.DescrEmitNotesFooter(AContext: TPasElement);
+begin
+ PopOutPutNode;
+end;
+
+procedure TBaseHTMLWriter.PushOutputNode(ANode: TDOMNode);
+begin
+ OutputNodeStack.Add(CurOutputNode);
+ FCurOutputNode := ANode;
+end;
+
+procedure TBaseHTMLWriter.PopOutputNode;
+begin
+ FCurOutputNode := TDOMNode(OutputNodeStack[OutputNodeStack.Count - 1]);
+ OutputNodeStack.Delete(OutputNodeStack.Count - 1);
+end;
+
+procedure TBaseHTMLWriter.DescrWriteText(const AText: DOMString);
+begin
+ AppendText(CurOutputNode, AText);
+end;
+
+procedure TBaseHTMLWriter.DescrBeginBold;
+begin
+ PushOutputNode(CreateEl(CurOutputNode, 'b'));
+end;
+
+procedure TBaseHTMLWriter.DescrEndBold;
+begin
+ PopOutputNode;
+end;
+
+procedure TBaseHTMLWriter.DescrBeginItalic;
+begin
+ PushOutputNode(CreateEl(CurOutputNode, 'i'));
+end;
+
+procedure TBaseHTMLWriter.DescrEndItalic;
+begin
+ PopOutputNode;
+end;
+
+procedure TBaseHTMLWriter.DescrBeginEmph;
+begin
+ PushOutputNode(CreateEl(CurOutputNode, 'em'));
+end;
+
+procedure TBaseHTMLWriter.DescrEndEmph;
+begin
+ PopOutputNode;
+end;
+
+procedure TBaseHTMLWriter.DescrBeginUnderline;
+begin
+ PushOutputNode(CreateEl(CurOutputNode, 'u'));
+end;
+
+procedure TBaseHTMLWriter.DescrEndUnderline;
+begin
+ PopOutputNode;
+end;
+
+procedure TBaseHTMLWriter.DescrWriteImageEl(const AFileName, ACaption, ALinkName : DOMString);
+
+Var
+ Pel,Cel: TDOMNode;
+ El :TDomElement;
+ D : String;
+ L : Integer;
+
+begin
+ // Determine parent node.
+ If (ACaption='') then
+ Pel:=CurOutputNode
+ else
+ begin
+ Cel:=CreateTable(CurOutputNode, 'imagetable');
+ Pel:=CreateTD(CreateTR(Cel));
+ Cel:=CreateTD(CreateTR(Cel));
+ El := CreateEl(Cel, 'span');
+ El['class'] := 'imagecaption';
+ Cel := El;
+ If (ALinkName<>'') then
+ Cel:=CreateAnchor(Cel,ALinkName);
+ AppendText(Cel,ACaption);
+ end;
+
+ // Determine URL for image.
+ If (Module=Nil) then
+ D:=Allocator.GetRelativePathToTop(Package)
+ else
+ D:=Allocator.GetRelativePathToTop(Module);
+ L:=Length(D);
+ If (L>0) and (D[L]<>'/') then
+ D:=D+'/';
+
+ // Create image node.
+ El:=CreateEl(Pel,'img');
+ EL['src']:=UTF8Decode(D + BaseImageURL) + AFileName;
+ El['alt']:=ACaption;
+
+ //cache image filename, so it can be used later (CHM)
+ ImageFileList.Add(UTF8Encode(UTF8Decode(BaseImageURL) + AFileName));
+end;
+
+procedure TBaseHTMLWriter.DescrWriteFileEl(const AText: DOMString);
+var
+ NewEl: TDOMElement;
+begin
+ NewEl := CreateEl(CurOutputNode, 'span');
+ NewEl['class'] := 'file';
+ AppendText(NewEl, AText);
+end;
+
+procedure TBaseHTMLWriter.DescrWriteKeywordEl(const AText: DOMString);
+var
+ NewEl: TDOMElement;
+begin
+ NewEl := CreateEl(CurOutputNode, 'span');
+ NewEl['class'] := 'kw';
+ AppendText(NewEl, AText);
+end;
+
+procedure TBaseHTMLWriter.DescrWriteVarEl(const AText: DOMString);
+begin
+ AppendText(CreateEl(CurOutputNode, 'var'), AText);
+end;
+
+procedure TBaseHTMLWriter.DescrBeginLink(const AId: DOMString);
+var
+ a,s,n : String;
+
+begin
+ a:=UTF8Encode(AId);
+ s := UTF8Encode(ResolveLinkID(a));
+ if Length(s) = 0 then
+ begin
+ if assigned(module) then
+ s:=module.name
+ else
+ s:='?';
+ if a='' then a:='<empty>';
+ if Assigned(CurrentContext) then
+ N:=CurrentContext.Name
+ else
+ N:='?';
+ DoLog(SErrUnknownLinkID, [s,n,a]);
+ PushOutputNode(CreateEl(CurOutputNode, 'b'));
+ end else
+ PushOutputNode(CreateLink(CurOutputNode, s));
+end;
+
+procedure TBaseHTMLWriter.DescrEndLink;
+begin
+ PopOutputNode;
+end;
+
+procedure TBaseHTMLWriter.DescrBeginURL(const AURL: DOMString);
+begin
+ PushOutputNode(CreateLink(CurOutputNode, AURL));
+end;
+
+procedure TBaseHTMLWriter.DescrEndURL;
+begin
+ PopOutputNode;
+end;
+
+procedure TBaseHTMLWriter.DescrWriteLinebreak;
+begin
+ CreateEl(CurOutputNode, 'br');
+end;
+
+procedure TBaseHTMLWriter.DescrBeginParagraph;
+begin
+ PushOutputNode(CreatePara(CurOutputNode));
+end;
+
+procedure TBaseHTMLWriter.DescrEndParagraph;
+begin
+ PopOutputNode;
+end;
+
+procedure TBaseHTMLWriter.DescrBeginCode(HasBorder: Boolean; const AHighlighterName: String);
+begin
+ FDoPasHighlighting := (AHighlighterName = '') or (AHighlighterName = 'Pascal');
+ FHighlighterFlags := 0;
+ PushOutputNode(CreateEl(CurOutputNode, 'pre'));
+end;
+
+procedure TBaseHTMLWriter.DescrWriteCodeLine(const ALine: String);
+begin
+ if DoPasHighlighting then
+ begin
+ FHighlighterFlags := AppendPasSHFragment(CurOutputNode, ALine,FHighlighterFlags);
+ AppendText(CurOutputNode, #10);
+ end else
+ AppendText(CurOutputNode, ALine + #10);
+end;
+
+procedure TBaseHTMLWriter.DescrEndCode;
+begin
+ PopOutputNode;
+end;
+
+procedure TBaseHTMLWriter.DescrBeginOrderedList;
+begin
+ PushOutputNode(CreateEl(CurOutputNode, 'ol'));
+end;
+
+procedure TBaseHTMLWriter.DescrEndOrderedList;
+begin
+ PopOutputNode;
+end;
+
+procedure TBaseHTMLWriter.DescrBeginUnorderedList;
+begin
+ PushOutputNode(CreateEl(CurOutputNode, 'ul'));
+end;
+
+procedure TBaseHTMLWriter.DescrEndUnorderedList;
+begin
+ PopOutputNode;
+end;
+
+procedure TBaseHTMLWriter.DescrBeginDefinitionList;
+begin
+ PushOutputNode(CreateEl(CurOutputNode, 'dl'));
+end;
+
+procedure TBaseHTMLWriter.DescrEndDefinitionList;
+begin
+ PopOutputNode;
+end;
+
+procedure TBaseHTMLWriter.DescrBeginListItem;
+begin
+ PushOutputNode(CreateEl(CurOutputNode, 'li'));
+end;
+
+procedure TBaseHTMLWriter.DescrEndListItem;
+begin
+ PopOutputNode;
+end;
+
+procedure TBaseHTMLWriter.DescrBeginDefinitionTerm;
+begin
+ PushOutputNode(CreateEl(CurOutputNode, 'dt'));
+end;
+
+procedure TBaseHTMLWriter.DescrEndDefinitionTerm;
+begin
+ PopOutputNode;
+end;
+
+procedure TBaseHTMLWriter.DescrBeginDefinitionEntry;
+begin
+ PushOutputNode(CreateEl(CurOutputNode, 'dd'));
+end;
+
+procedure TBaseHTMLWriter.DescrEndDefinitionEntry;
+begin
+ PopOutputNode;
+end;
+
+procedure TBaseHTMLWriter.DescrBeginSectionTitle;
+begin
+ PushOutputNode(CreateEl(CurOutputNode, 'h3'));
+end;
+
+procedure TBaseHTMLWriter.DescrBeginSectionBody;
+begin
+ PopOutputNode;
+end;
+
+procedure TBaseHTMLWriter.DescrEndSection;
+begin
+end;
+
+procedure TBaseHTMLWriter.DescrBeginRemark;
+var
+ NewEl, TDEl: TDOMElement;
+begin
+ NewEl := CreateEl(CurOutputNode, 'table');
+ NewEl['width'] := '100%';
+ NewEl['border'] := '0';
+ NewEl['CellSpacing'] := '0';
+ NewEl['class'] := 'remark';
+ NewEl := CreateTR(NewEl);
+ TDEl := CreateTD(NewEl);
+ TDEl['valign'] := 'top';
+ TDEl['class'] := 'pre';
+ AppendText(CreateEl(TDEl, 'b'), SDocRemark);
+ PushOutputNode(CreateTD(NewEl));
+end;
+
+procedure TBaseHTMLWriter.DescrEndRemark;
+begin
+ PopOutputNode;
+end;
+
+procedure TBaseHTMLWriter.DescrBeginTable(ColCount: Integer; HasBorder: Boolean);
+var
+ Table: TDOMElement;
+begin
+ Table := CreateEl(CurOutputNode, 'table');
+ Table['border'] := UTF8Decode(IntToStr(Ord(HasBorder)));
+ PushOutputNode(Table);
+end;
+
+procedure TBaseHTMLWriter.DescrEndTable;
+begin
+ PopOutputNode;
+end;
+
+procedure TBaseHTMLWriter.DescrBeginTableCaption;
+begin
+ PushOutputNode(CreateEl(CurOutputNode, 'caption'));
+end;
+
+procedure TBaseHTMLWriter.DescrEndTableCaption;
+begin
+ PopOutputNode;
+end;
+
+procedure TBaseHTMLWriter.DescrBeginTableHeadRow;
+begin
+ PushOutputNode(CreateTr(CurOutputNode));
+ FInsideHeadRow := True;
+end;
+
+procedure TBaseHTMLWriter.DescrEndTableHeadRow;
+begin
+ FInsideHeadRow := False;
+ PopOutputNode;
+end;
+
+procedure TBaseHTMLWriter.DescrBeginTableRow;
+begin
+ PushOutputNode(CreateTR(CurOutputNode));
+end;
+
+procedure TBaseHTMLWriter.DescrEndTableRow;
+begin
+ PopOutputNode;
+end;
+
+procedure TBaseHTMLWriter.DescrBeginTableCell;
+begin
+ if InsideHeadRow then
+ PushOutputNode(CreateEl(CurOutputNode, 'th'))
+ else
+ PushOutputNode(CreateTD(CurOutputNode));
+end;
+
+procedure TBaseHTMLWriter.DescrEndTableCell;
+begin
+ PopOutputNode;
+end;
+
+procedure TBaseHTMLWriter.SetHTMLDocument(aDoc: THTMLDocument);
+begin
+ FDoc:=aDoc;
+ FOutputNodeStack.Clear;
+ FCurOutputNode:=Nil;
+end;
+
+procedure TBaseHTMLWriter.AppendText(Parent: TDOMNode; const AText: String);
+begin
+ AppendText(Parent,UTF8Decode(aText));
+end;
+
+
+procedure TBaseHTMLWriter.AppendText(Parent: TDOMNode; const AText: DOMString);
+begin
+ Parent.AppendChild(Doc.CreateTextNode(AText));
+end;
+
+procedure TBaseHTMLWriter.AppendNbSp(Parent: TDOMNode; ACount: Integer);
+begin
+ while ACount > 0 do
+ begin
+ Parent.AppendChild(Doc.CreateEntityReference('nbsp'));
+ Dec(ACount);
+ end;
+end;
+
+procedure TBaseHTMLWriter.AppendSym(Parent: TDOMNode; const AText: DOMString);
+var
+ El: TDOMElement;
+begin
+ El := CreateEl(Parent, 'span');
+ El['class'] := 'sym';
+ AppendText(El, AText);
+end;
+
+procedure TBaseHTMLWriter.AppendKw(Parent: TDOMNode; const AText: String);
+begin
+ AppendKW(Parent,UTF8Decode(aText));
+end;
+
+procedure TBaseHTMLWriter.AppendKw(Parent: TDOMNode; const AText: DOMString);
+var
+ El: TDOMElement;
+begin
+ El := CreateEl(Parent, 'span');
+ El['class'] := 'kw';
+ AppendText(El, AText);
+end;
+
+function TBaseHTMLWriter.AppendPasSHFragment(Parent: TDOMNode;
+ const AText: String; AShFlags: Byte): Byte;
+
+
+var
+ Line, Last, p: PChar;
+ El: TDOMElement;
+
+ Procedure MaybeOutput;
+
+ Var
+ CurParent: TDomNode;
+
+ begin
+ If (Last<>Nil) then
+ begin
+ If (el<>Nil) then
+ CurParent:=El
+ else
+ CurParent:=Parent;
+ AppendText(CurParent,Last);
+ El:=Nil;
+ Last:=Nil;
+ end;
+ end;
+
+ Function NewEl(Const ElType,Attr,AttrVal : DOMString) : TDomElement;
+
+ begin
+ Result:=CreateEl(Parent,ElType);
+ Result[Attr]:=AttrVal;
+ end;
+
+ Function NewSpan(Const AttrVal : DOMString) : TDomElement;
+
+ begin
+ Result:=CreateEl(Parent,'span');
+ Result['class']:=AttrVal;
+ end;
+
+begin
+ GetMem(Line, Length(AText) * 3 + 4);
+ Try
+ DoPascalHighlighting(AShFlags, PChar(AText), Line);
+ Result := AShFlags;
+ Last := Nil;
+ p := Line;
+ el:=nil;
+ while p[0] <> #0 do
+ begin
+ if p[0] = LF_ESCAPE then
+ begin
+ p[0] := #0;
+ MaybeOutput;
+ case Ord(p[1]) of
+ shDefault: El:=Nil;
+ shInvalid: El:=newel('font','color','red');
+ shSymbol : El:=newspan('sym');
+ shKeyword: El:=newspan('kw');
+ shComment: El:=newspan('cmt');
+ shDirective: El:=newspan('dir');
+ shNumbers: El:=newspan('num');
+ shCharacters: El:=newspan('chr');
+ shStrings: El:=newspan('str');
+ shAssembler: El:=newspan('asm');
+ end;
+ Inc(P);
+ end
+ else If (Last=Nil) then
+ Last:=P;
+ Inc(p);
+ end;
+ MaybeOutput;
+ Finally
+ FreeMem(Line);
+ end;
+end;
+
+
+procedure TBaseHTMLWriter.AppendSeeAlsoSection ( AElement: TPasElement;
+ DocNode: TDocNode ) ;
+
+var
+ Node: TDOMNode;
+ TableEl, El, TREl, ParaEl, NewEl, DescrEl: TDOMElement;
+ l,s,n: DOMString;
+ IsFirstSeeAlso : Boolean;
+
+begin
+ if Not (Assigned(DocNode) and Assigned(DocNode.SeeAlso)) then
+ Exit;
+ IsFirstSeeAlso := True;
+ Node:=DocNode.SeeAlso.FirstChild;
+ While Assigned(Node) do
+ begin
+ if (Node.NodeType=ELEMENT_NODE) and (Node.NodeName='link') then
+ begin
+ if IsFirstSeeAlso then
+ begin
+ IsFirstSeeAlso := False;
+ AppendText(CreateH2(ContentElement), SDocSeeAlso);
+ TableEl := CreateTable(ContentElement);
+ end;
+ El:=TDOMElement(Node);
+ TREl:=CreateTR(TableEl);
+ ParaEl:=CreatePara(CreateTD_vtop(TREl));
+ l:=El['id'];
+ s:= ResolveLinkID(UTF8ENcode(l));
+ if Length(s)=0 then
+ begin
+ if assigned(module) then
+ s:=UTF8Decode(module.name)
+ else
+ s:='?';
+ if l='' then l:='<empty>';
+ if Assigned(AElement) then
+ N:=UTF8Decode(AElement.Name)
+ else
+ N:='?';
+ DoLog(SErrUnknownLinkID, [s,N,l]);
+ NewEl := CreateEl(ParaEl,'b')
+ end
+ else
+ NewEl := CreateLink(ParaEl,s);
+ if Not IsDescrNodeEmpty(El) then
+ begin
+ PushOutputNode(NewEl);
+ Try
+ ConvertBaseShortList(AElement, El, True)
+ Finally
+ PopOutputNode;
+ end;
+ end
+ else
+ AppendText(NewEl,El['id']);
+ l:=El['id'];
+ DescrEl := Engine.FindShortDescr(AElement.GetModule,UTF8Encode(L));
+ if Assigned(DescrEl) then
+ begin
+ AppendNbSp(CreatePara(CreateTD(TREl)), 2);
+ ParaEl := CreatePara(CreateTD(TREl));
+ ParaEl['class'] := 'cmt';
+ PushOutputNode(ParaEl);
+ try
+ ConvertShort(AElement, DescrEl);
+ finally
+ PopOutputNode;
+ end;
+ end;
+ end; // Link node
+ Node := Node.NextSibling;
+ end; // While
+end;
+
+procedure TBaseHTMLWriter.AppendExampleSection ( AElement: TPasElement; DocNode: TDocNode ) ;
+
+var
+ Node: TDOMNode;
+ fn,s: String;
+ f: Text;
+
+begin
+ if not (Assigned(DocNode) and Assigned(DocNode.FirstExample)) then
+ Exit;
+ Node := DocNode.FirstExample;
+ while Assigned(Node) do
+ begin
+ if (Node.NodeType = ELEMENT_NODE) and (Node.NodeName = 'example') then
+ begin
+ fn:=Engine.GetExampleFilename(TDOMElement(Node));
+ If (fn<>'') then
+ begin
+ AppendText(CreateH2(ContentElement), SDocExample);
+ try
+ Assign(f, FN);
+ Reset(f);
+ try
+ PushOutputNode(ContentElement);
+ DescrBeginCode(False, UTF8Encode(TDOMElement(Node)['highlighter']));
+ while not EOF(f) do
+ begin
+ ReadLn(f, s);
+ DescrWriteCodeLine(s);
+ end;
+ DescrEndCode;
+ PopOutputNode;
+ finally
+ Close(f);
+ end;
+ except
+ on e: Exception do
+ begin
+ e.Message := '[example] ' + e.Message;
+ raise;
+ end;
+ end;
+ end;
+ end;
+ Node := Node.NextSibling;
+ end;
+end;
+
+procedure TBaseHTMLWriter.AppendFragment(aParentNode : TDOMElement; aStream : TStream);
+
+begin
+ if (aStream<>Nil) then
+ begin
+ aStream.Position:=0;
+ ReadXMLFragment(aParentNode,aStream);
+ end;
+end;
+
+procedure TBaseHTMLWriter.AppendShortDescr ( AContext: TPasElement;
+ Parent: TDOMNode; DocNode: TDocNode ) ;
+
+Var
+ N : TDocNode;
+
+begin
+ if Assigned(DocNode) then
+ begin
+ If (DocNode.Link<>'') then
+ begin
+ N:=Engine.FindLinkedNode(DocNode);
+ If (N<>Nil) then
+ DocNode:=N;
+ end;
+ If Assigned(DocNode.ShortDescr) then
+ begin
+ PushOutputNode(Parent);
+ try
+ if not ConvertShort(AContext,TDomElement(DocNode.ShortDescr)) then
+ Warning(AContext, SErrInvalidShortDescr)
+ finally
+ PopOutputNode;
+ end;
+ end;
+ end;
+end;
+
+procedure TBaseHTMLWriter.AppendShortDescr(Parent: TDOMNode; Element: TPasElement);
+
+begin
+ AppendShortDescr(Element,Parent,Engine.FindDocNode(Element));
+end;
+
+procedure TBaseHTMLWriter.AppendShortDescrCell(Parent: TDOMNode; Element: TPasElement);
+
+var
+ ParaEl: TDOMElement;
+
+begin
+ if Assigned(Engine.FindShortDescr(Element)) then
+ begin
+ AppendNbSp(CreatePara(CreateTD(Parent)), 2);
+ ParaEl := CreatePara(CreateTD(Parent));
+ ParaEl['class'] := 'cmt';
+ AppendShortDescr(ParaEl, Element);
+ end;
+end;
+
+procedure TBaseHTMLWriter.AppendDescr(AContext: TPasElement; Parent: TDOMNode;
+ DescrNode: TDOMElement; AutoInsertBlock: Boolean);
+begin
+ if Assigned(DescrNode) then
+ begin
+ PushOutputNode(Parent);
+ try
+ ConvertDescr(AContext, DescrNode, AutoInsertBlock);
+ finally
+ PopOutputNode;
+ end;
+ end;
+end;
+
+procedure TBaseHTMLWriter.AppendDescrSection(AContext: TPasElement; Parent: TDOMNode; DescrNode: TDOMElement; const ATitle: String);
+begin
+ AppendDescrSection(aContext,Parent,DescrNode,UTF8Decode(aTitle));
+end;
+
+procedure TBaseHTMLWriter.AppendDescrSection(AContext: TPasElement;
+ Parent: TDOMNode; DescrNode: TDOMElement; const ATitle: DOMString);
+begin
+ if not IsDescrNodeEmpty(DescrNode) then
+ begin
+ If (ATitle<>'') then // Can be empty for topic.
+ AppendText(CreateH2(Parent), ATitle);
+ AppendDescr(AContext, Parent, DescrNode, True);
+ end;
+end;
+
+function TBaseHTMLWriter.AppendHyperlink(Parent: TDOMNode; Element: TPasElement): TDOMElement;
+var
+ s: DOMString;
+ UnitList: TFPList;
+ i: Integer;
+ ThisPackage: TLinkNode;
+begin
+ if Not Assigned(Element) then
+ begin
+ Result := nil;
+ AppendText(CreateWarning(Parent), '<NIL>');
+ end;
+ if Element.InheritsFrom(TPasUnresolvedTypeRef) then
+ begin
+ s := ResolveLinkID(Element.Name);
+ if Length(s) = 0 then
+ begin
+ { Try all packages }
+ ThisPackage := Engine.RootLinkNode.FirstChild;
+ while Assigned(ThisPackage) do
+ begin
+ s := ResolveLinkID(ThisPackage.Name + '.' + Element.Name);
+ if Length(s) > 0 then
+ break;
+ ThisPackage := ThisPackage.NextSibling;
+ end;
+ if Length(s) = 0 then
+ begin
+ { Okay, then we have to try all imported units of the current module }
+ UnitList := Module.InterfaceSection.UsesList;
+ for i := UnitList.Count - 1 downto 0 do
+ begin
+ { Try all packages }
+ ThisPackage := Engine.RootLinkNode.FirstChild;
+ while Assigned(ThisPackage) do
+ begin
+ s := ResolveLinkID(ThisPackage.Name + '.' +
+ TPasType(UnitList[i]).Name + '.' + Element.Name);
+ if Length(s) > 0 then
+ break;
+ ThisPackage := ThisPackage.NextSibling;
+ end;
+ if length(s)=0 then
+ s := ResolveLinkID('#rtl.System.' + Element.Name);
+ if Length(s) > 0 then
+ break;
+ end;
+ end;
+ end;
+ end
+ else if Element is TPasEnumValue then
+ s := ResolveLinkID(Element.Parent.PathName)
+ else
+ s := ResolveLinkID(Element.PathName);
+
+ if Length(s) > 0 then
+ begin
+ Result := CreateLink(Parent, s);
+ AppendText(Result, Element.Name);
+ end
+ else
+ begin
+ Result := nil;
+ AppendText(Parent, Element.Name); // unresolved items
+ end;
+end;
+
+procedure TBaseHTMLWriter.AppendSourceRef(aParent : TDOMElement; AElement: TPasElement);
+
+begin
+ AppendText(CreatePara(aParent), Format(SDocSourcePosition,
+ [ExtractFileName(AElement.SourceFilename), AElement.SourceLinenumber]));
+end;
+
+
+end.
+
diff --git a/utils/fpdoc/dw_basemd.pp b/utils/fpdoc/dw_basemd.pp
index 0b365a9e56..46de0ee314 100644
--- a/utils/fpdoc/dw_basemd.pp
+++ b/utils/fpdoc/dw_basemd.pp
@@ -1,3 +1,16 @@
+{
+ FPDoc - Free Pascal Documentation Tool
+ Copyright (C) 2021 by Michael Van Canneyt
+
+ * Basic Markdown output generator. No assumptions about document/documentation structure
+
+ 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_basemd;
{$mode objfpc}{$H+}
@@ -32,7 +45,6 @@ Type
FFileRendering: TRender;
FIndentSize: Byte;
FKeywordRendering: TRender;
- FModule: TPasModule;
FPrefix : string;
FMetadata,
FMarkDown: TStrings;
@@ -486,7 +498,7 @@ end;
procedure TBaseMarkdownWriter.DescrWriteImageEl(const AFileName, ACaption, ALinkName : DOMString);
Var
- D,FN : String;
+ aLink,D,FN : String;
L : integer;
begin
// Determine URL for image.
@@ -498,15 +510,16 @@ begin
If (L>0) and (D[L]<>'/') then
D:=D+'/';
- FN:=UTF8Decode(D + BaseImageURL) + AFileName;
+ FN:=D + BaseImageURL+ Utf8Encode(AFileName);
EnsureEmptyLine;
- AppendToLine('!['+aCaption+']('+FN+')',False);
+ aLink:='!['+UTF8Encode(aCaption)+']('+FN+')';
+ AppendToLine(aLink,False);
end;
procedure TBaseMarkdownWriter.DescrWriteFileEl(const AText: DOMString);
begin
- AppendRendered(aText,FileRendering);
+ AppendRendered(UTF8Encode(aText),FileRendering);
end;
procedure TBaseMarkdownWriter.DescrWriteKeywordEl(const AText: DOMString);
@@ -516,7 +529,7 @@ end;
procedure TBaseMarkdownWriter.DescrWriteVarEl(const AText: DOMString);
begin
- AppendRendered(aText,VarRendering);
+ AppendRendered(UTF8Encode(aText),VarRendering);
end;
procedure TBaseMarkdownWriter.DescrBeginLink(const AId: DOMString);
@@ -556,7 +569,7 @@ end;
procedure TBaseMarkdownWriter.DescrBeginURL(const AURL: DOMString);
begin
- FLink:=aURL;
+ FLink:=UTF8Encode(aURL);
AppendToLine('[');
end;
diff --git a/utils/fpdoc/dw_chm.pp b/utils/fpdoc/dw_chm.pp
index 632665f1ac..e37076e24b 100644
--- a/utils/fpdoc/dw_chm.pp
+++ b/utils/fpdoc/dw_chm.pp
@@ -2,7 +2,7 @@ unit dw_chm;
interface
-uses Classes, DOM, DOM_HTML,
+uses Classes, DOM,
dGlobals, PasTree, dwriter, dw_html, chmwriter, chmtypes, chmsitemap;
type
@@ -63,7 +63,7 @@ type
implementation
-uses SysUtils, HTMWrite;
+uses SysUtils, HTMWrite, dw_basehtml;
{ TCHmFileNameAllocator }
@@ -152,11 +152,18 @@ end;
procedure TFpDocChmWriter.FileAdded ( AStream: TStream;
const AEntry: TFileEntryRec ) ;
+var FTsave : boolean;
begin
// Exclude Full text index for files starting from the dot
if Pos('.', AEntry.Name) <> 1 then
- inherited FileAdded(AStream, AEntry);
-
+ inherited FileAdded(AStream, AEntry)
+ else
+ begin
+ FTsave:=FullTextSearch;
+ FullTextSearch:=False;
+ inherited FileAdded(AStream, AEntry);
+ FullTextSearch:=FTsave;
+ end;
end;
{ TCHMHTMLWriter }
@@ -179,12 +186,12 @@ begin
DoLog('Note: --index-page not assigned. Using default "index.html"');
end;
- if FCSSFile <> '' then
+ if CSSFile <> '' then
begin
- if not FileExists(FCSSFile) Then
- Raise Exception.CreateFmt('Can''t find CSS file "%S"',[FCSSFILE]);
+ if not FileExists(CSSFile) Then
+ Raise Exception.CreateFmt('Can''t find CSS file "%S"',[CSSFILE]);
TempStream := TMemoryStream.Create;
- TempStream.LoadFromFile(FCSSFile);
+ TempStream.LoadFromFile(CSSFile);
TempStream.Position := 0;
FChm.AddStreamToArchive('fpdoc.css', '/', TempStream, True);
TempStream.Free;
diff --git a/utils/fpdoc/dw_html.pp b/utils/fpdoc/dw_html.pp
index 5d28ffd354..5b43b06c1f 100644
--- a/utils/fpdoc/dw_html.pp
+++ b/utils/fpdoc/dw_html.pp
@@ -19,168 +19,76 @@ unit dw_html;
{$WARN 5024 off : Parameter "$1" not used}
interface
-uses Classes, DOM, DOM_HTML, dGlobals, PasTree, dWriter;
+uses Classes, DOM, DOM_HTML, dGlobals, PasTree, dWriter, dw_basehtml;
type
{ THTMLWriter }
- THTMLWriter = class(TMultiFileDocWriter)
+ THTMLWriter = class(TBaseHTMLWriter)
private
- FImageFileList: TStrings;
+ FHeadElement: TDomElement;
FOnTest: TNotifyEvent;
+ FCSSFile: String;
FCharSet : String;
+ FHeaderHTML,
+ FNavigatorHTML,
+ FFooterHTML: TStringStream;
+ FTitleElement: TDOMElement;
+ FIncludeDateInFooter : Boolean;
+ FUseMenuBrackets: Boolean;
+ FDateFormat: String;
+ FIndexColCount : Integer;
+ FSearchPage : String;
procedure CreateMinusImage;
procedure CreatePlusImage;
procedure SetOnTest(const AValue: TNotifyEvent);
protected
- FCSSFile: String;
-
- Doc: THTMLDocument;
- HeadElement,
- BodyElement, TitleElement: TDOMElement;
-
-
- OutputNodeStack: TList;
- CurOutputNode: TDOMNode;
- InsideHeadRow, DoPasHighlighting: Boolean;
- HighlighterFlags: Byte;
- HeaderHTML,
- NavigatorHTML,
- FooterHTML: TStringStream;
- FIDF : Boolean;
- FDateFormat: String;
- FIndexColCount : Integer;
- FSearchPage : String;
- FBaseImageURL : String;
- FUseMenuBrackets: Boolean;
-
- procedure AppendFragment(aParentNode: TDOMElement; aStream: TStream);
function CreateAllocator : TFileAllocator; override;
procedure WriteDocPage(const aFileName: String; aElement: TPasElement; aSubPageIndex: Integer); override;
procedure CreateCSSFile; virtual;
- // Helper functions for creating DOM elements
- function CreateEl(Parent: TDOMNode; const AName: DOMString): THTMLElement;
- function CreatePara(Parent: TDOMNode): THTMLElement;
- function CreateH1(Parent: TDOMNode): THTMLElement;
- function CreateH2(Parent: TDOMNode): THTMLElement;
- function CreateH3(Parent: TDOMNode): THTMLElement;
- function CreateTable(Parent: TDOMNode; const AClass: DOMString = ''): THTMLElement;
- function CreateContentTable(Parent: TDOMNode): THTMLElement;
- function CreateTR(Parent: TDOMNode): THTMLElement;
- function CreateTD(Parent: TDOMNode): THTMLElement;
- function CreateTD_vtop(Parent: TDOMNode): THTMLElement;
- function CreateLink(Parent: TDOMNode; const AHRef: String): THTMLElement;
- function CreateLink(Parent: TDOMNode; const AHRef: DOMString): THTMLElement;
- function CreateAnchor(Parent: TDOMNode; const AName: DOMString): THTMLElement;
- function CreateCode(Parent: TDOMNode): THTMLElement;
- function CreateWarning(Parent: TDOMNode): THTMLElement;
-
- // Description node conversion
- Procedure DescrEmitNotesHeader(AContext : TPasElement); override;
- Procedure DescrEmitNotesFooter(AContext : TPasElement); override;
- procedure PushOutputNode(ANode: TDOMNode);
- procedure PopOutputNode;
- procedure DescrWriteText(const AText: DOMString); override;
- procedure DescrBeginBold; override;
- procedure DescrEndBold; override;
- procedure DescrBeginItalic; override;
- procedure DescrEndItalic; override;
- procedure DescrBeginEmph; override;
- procedure DescrEndEmph; override;
- procedure DescrBeginUnderline; override;
- procedure DescrEndUnderline; override;
- procedure DescrWriteImageEl(const AFileName, ACaption, ALinkName : DOMString); override;
- procedure DescrWriteFileEl(const AText: DOMString); override;
- procedure DescrWriteKeywordEl(const AText: DOMString); override;
- procedure DescrWriteVarEl(const AText: DOMString); override;
- procedure DescrBeginLink(const AId: DOMString); override;
- procedure DescrEndLink; override;
- procedure DescrBeginURL(const AURL: DOMString); override;
- procedure DescrEndURL; override;
- procedure DescrWriteLinebreak; override;
- procedure DescrBeginParagraph; override;
- procedure DescrEndParagraph; override;
- procedure DescrBeginCode(HasBorder: Boolean; const AHighlighterName: String); override;
- procedure DescrWriteCodeLine(const ALine: String); override;
- procedure DescrEndCode; override;
- procedure DescrBeginOrderedList; override;
- procedure DescrEndOrderedList; override;
- procedure DescrBeginUnorderedList; override;
- procedure DescrEndUnorderedList; override;
- procedure DescrBeginDefinitionList; override;
- procedure DescrEndDefinitionList; override;
- procedure DescrBeginListItem; override;
- procedure DescrEndListItem; override;
- procedure DescrBeginDefinitionTerm; override;
- procedure DescrEndDefinitionTerm; override;
- procedure DescrBeginDefinitionEntry; override;
- procedure DescrEndDefinitionEntry; override;
- procedure DescrBeginSectionTitle; override;
- procedure DescrBeginSectionBody; override;
- procedure DescrEndSection; override;
- procedure DescrBeginRemark; override;
- procedure DescrEndRemark; override;
- procedure DescrBeginTable(ColCount: Integer; HasBorder: Boolean); override;
- procedure DescrEndTable; override;
- procedure DescrBeginTableCaption; override;
- procedure DescrEndTableCaption; override;
- procedure DescrBeginTableHeadRow; override;
- procedure DescrEndTableHeadRow; override;
- procedure DescrBeginTableRow; override;
- procedure DescrEndTableRow; override;
- procedure DescrBeginTableCell; override;
- procedure DescrEndTableCell; override;
-
- procedure AppendText(Parent: TDOMNode; const AText: String);
- procedure AppendText(Parent: TDOMNode; const AText: DOMString);
- procedure AppendNbSp(Parent: TDOMNode; ACount: Integer);
- procedure AppendSym(Parent: TDOMNode; const AText: DOMString);
- procedure AppendKw(Parent: TDOMNode; const AText: String);
- procedure AppendKw(Parent: TDOMNode; const AText: DOMString);
- function AppendPasSHFragment(Parent: TDOMNode; const AText: String;
- AShFlags: Byte): Byte;
- Procedure AppendShortDescr(AContext : TPasElement;Parent: TDOMNode; DocNode : TDocNode);
- procedure AppendShortDescr(Parent: TDOMNode; Element: TPasElement);
- procedure AppendShortDescrCell(Parent: TDOMNode; Element: TPasElement);
- procedure AppendDescr(AContext: TPasElement; Parent: TDOMNode;
- DescrNode: TDOMElement; AutoInsertBlock: Boolean);
- procedure AppendDescrSection(AContext: TPasElement; Parent: TDOMNode; DescrNode: TDOMElement; const ATitle: String);
- procedure AppendDescrSection(AContext: TPasElement; Parent: TDOMNode; DescrNode: TDOMElement; const ATitle: DOMString);
- function AppendHyperlink(Parent: TDOMNode; Element: TPasElement): TDOMElement;
+ procedure AppendTitle(const AText: String; Hints : TPasMemberHints = []); virtual;
+ procedure AppendTitle(const AText: DOMString; Hints : TPasMemberHints = []); virtual;
function AppendType(CodeEl, TableEl: TDOMElement;
Element: TPasType; Expanded: Boolean;
- NestingLevel: Integer = 0): TDOMElement;
- function AppendProcType(CodeEl, TableEl: TDOMElement;
- Element: TPasProcedureType; Indent: Integer): TDOMElement;
- procedure AppendProcExt(CodeEl: TDOMElement; Element: TPasProcedure);
- procedure AppendProcDecl(CodeEl, TableEl: TDOMElement; Element: TPasProcedureBase);
- procedure AppendProcArgsSection(Parent: TDOMNode; Element: TPasProcedureType; SkipResult : Boolean = False);
- function AppendRecordType(CodeEl, TableEl: TDOMElement; Element: TPasRecordType; NestingLevel: Integer): TDOMElement;
- procedure CreateMemberDeclarations(AParent: TPasElement; Members: TFPList; TableEl: TDOmelement; AddEnd: Boolean);
-
- procedure AppendTitle(const AText: String; Hints : TPasMemberHints = []);
- procedure AppendTitle(const AText: DOMString; Hints : TPasMemberHints = []);
- procedure AppendMenuBar(ASubpageIndex: Integer);
- procedure AppendTopicMenuBar(Topic : TTopicElement);
- procedure AppendSourceRef(AElement: TPasElement);
- procedure FinishElementPage(AElement: TPasElement);
- Procedure AppendSeeAlsoSection(AElement : TPasElement;DocNode : TDocNode);
- Procedure AppendExampleSection(AElement : TPasElement;DocNode : TDocNode);
- procedure AppendFooter;
- procedure CreateIndexPage(L : TStringList);
- procedure CreateModuleIndexPage(AModule: TPasModule);
+ NestingLevel: Integer = 0): TDOMElement; virtual;
+ function AppendProcType(CodeEl, TableEl: TDOMElement; Element: TPasProcedureType; Indent: Integer): TDOMElement; virtual;
+ procedure AppendProcExt(CodeEl: TDOMElement; Element: TPasProcedure); virtual;
+ procedure AppendProcDecl(CodeEl, TableEl: TDOMElement; Element: TPasProcedureBase); virtual;
+ procedure AppendProcArgsSection(Parent: TDOMNode; Element: TPasProcedureType; SkipResult : Boolean = False); virtual;
+ function AppendRecordType(CodeEl, TableEl: TDOMElement; Element: TPasRecordType; NestingLevel: Integer): TDOMElement; virtual;
+ procedure CreateMemberDeclarations(AParent: TPasElement; Members: TFPList; TableEl: TDOmelement; AddEnd: Boolean); virtual;
+
+ procedure AppendMenuBar(ASubpageIndex: Integer);virtual;
+ procedure AppendTopicMenuBar(Topic : TTopicElement);virtual;
+ procedure FinishElementPage(AElement: TPasElement);virtual;
+ procedure AppendFooter;virtual;
+
+
+ procedure AppendClassMemberListLink(aClass: TPasClassType; ParaEl: TDomElement; AListSubpageIndex: Integer; const AText: DOMString);virtual;
+ procedure CreateClassMainPage(aClass: TPasClassType);virtual;
+ procedure CreateClassInheritanceSubpage(aClass: TPasClassType; AFilter: TMemberFilter);virtual;
+ procedure CreateClassSortedSubpage(AClass: TPasClassType; AFilter: TMemberFilter);virtual;
+
+ procedure CreateIndexPage(L : TStringList); virtual;
+ procedure CreateModuleIndexPage(AModule: TPasModule); virtual;
+ // Package
procedure CreatePageBody(AElement: TPasElement; ASubpageIndex: Integer); virtual;
- procedure CreatePackagePageBody;
+ procedure CreatePackagePageBody;virtual;
procedure CreatePackageIndex;
procedure CreatePackageClassHierarchy;
procedure CreateClassHierarchyPage(AddUnit : Boolean);
- procedure AddModuleIdentifiers(AModule : TPasModule; L : TStrings);
+ // Topic
Procedure CreateTopicPageBody(AElement : TTopicElement);
+ // Module
+ procedure CreateModuleMainPage(aModule: TPasModule);virtual;
+ procedure CreateModuleSimpleSubpage(aModule: TPasModule; ASubpageIndex: Integer; const ATitle: DOMString; AList: TFPList);virtual;
+ procedure CreateModuleResStringsPage(aModule: TPasModule);virtual;
procedure CreateModulePageBody(AModule: TPasModule; ASubpageIndex: Integer);
+ // Identifiers
procedure CreateConstPageBody(AConst: TPasConst);
procedure CreateTypePageBody(AType: TPasType);
procedure CreateClassPageBody(AClass: TPasClassType; ASubpageIndex: Integer);
@@ -189,36 +97,35 @@ type
procedure CreateProcPageBody(AProc: TPasProcedureBase);
Procedure CreateTopicLinks(Node : TDocNode; PasElement : TPasElement);
procedure AppendTypeDecl(AType: TPasType; TableEl, CodeEl: TDomElement);
+ Property HeaderHTML : TStringStream Read FHeaderHTML;
+ Property NavigatorHTML : TStringStream read FNavigatorHTML;
+ Property FooterHTML : TStringStream read FFooterHTML;
+ Property CSSFile : String Read FCSSFile;
+ Property HeadElement : TDomElement Read FHeadElement;
+ Property TitleElement: TDOMElement Read FTitleElement;
public
// Creating all module hierarchy classes is here !!!!
constructor Create(APackage: TPasPackage; AEngine: TFPDocEngine); override;
- destructor Destroy; override;
-
- // Single-page generation
- function CreateHTMLPage(AElement: TPasElement; ASubpageIndex: Integer): TXMLDocument;
- function CreateXHTMLPage(AElement: TPasElement; ASubpageIndex: Integer): TXMLDocument;
-
- // Start producing html complete package documentation
- procedure WriteXHTMLPages;
-
- Function InterPretOption(Const Cmd,Arg : String) : boolean; override;
- Procedure WriteDoc; override;
+ // Overrides
Class Function FileNameExtension : String; override;
class procedure Usage(List: TStrings); override;
Class procedure SplitImport(var AFilename, ALinkPrefix: String); override;
- Property SearchPage: String Read FSearchPage Write FSearchPage;
- Property IncludeDateInFooter : Boolean Read FIDF Write FIDF;
+ Function InterPretOption(Const Cmd,Arg : String) : boolean; override;
+ Procedure WriteDoc; override;
+
+ // Single-page generation
+ function CreateHTMLPage(AElement: TPasElement; ASubpageIndex: Integer): TXMLDocument; virtual;
+
+ Property SearchPage: String Read FSearchPage Write FSearchPage;
+ Property IncludeDateInFooter : Boolean Read FIncludeDateInFooter Write FIncludeDateInFooter;
Property DateFormat : String Read FDateFormat Write FDateFormat;
property OnTest: TNotifyEvent read FOnTest write SetOnTest;
Property CharSet : String Read FCharSet Write FCharSet;
Property IndexColCount : Integer Read FIndexColCount write FIndexColCount;
- Property BaseImageURL : String Read FBaseImageURL Write FBaseImageURL;
Property UseMenuBrackets : Boolean Read FUseMenuBrackets write FUseMenuBrackets;
- Property ImageFileList : TStrings Read FImageFileList;
end;
-Function FixHTMLpath(S : String) : STring;
implementation
@@ -228,47 +135,27 @@ uses SysUtils, XMLRead, HTMWrite, sh_pas, fpdocclasstree;
{$i plusimage.inc}
{$i minusimage.inc}
-Function FixHTMLpath(S : String) : STring;
-
-begin
- Result:=StringReplace(S,'\','/',[rfReplaceAll]);
-end;
-
constructor THTMLWriter.Create(APackage: TPasPackage; AEngine: TFPDocEngine);
-
-var
- i: Integer;
- L : TObjectList;
- H : Boolean;
-
begin
inherited Create(APackage, AEngine);
// should default to true since this is the old behavior
UseMenuBrackets:=True;
IndexColCount:=3;
Charset:='iso-8859-1';
- OutputNodeStack := TList.Create;
- FImageFileList := TStringList.Create;
AllocatePages;
end;
-destructor THTMLWriter.Destroy;
-begin
- OutputNodeStack.Free;
- FImageFileList.Free;
- inherited Destroy;
-end;
-
function THTMLWriter.CreateHTMLPage(AElement: TPasElement;
ASubpageIndex: Integer): TXMLDocument;
var
HTMLEl: THTMLHtmlElement;
HeadEl: THTMLHeadElement;
+ BodyElement : THTMLElement;
El: TDOMElement;
begin
- Doc := THTMLDocument.Create;
- Result := Doc;
+ Result := THTMLDocument.Create;
+ SetHTMLDocument(THTMLDocument(Result));
Doc.AppendChild(Doc.Impl.CreateDocumentType(
'HTML', '-//W3C//DTD HTML 4.01 Transitional//EN',
'http://www.w3.org/TR/html4/loose.dtd'));
@@ -277,18 +164,19 @@ begin
Doc.AppendChild(HTMLEl);
HeadEl := Doc.CreateHeadElement;
- HeadElement:=HeadEl;
+ FHeadElement:=HeadEl;
HTMLEl.AppendChild(HeadEl);
El := Doc.CreateElement('meta');
HeadEl.AppendChild(El);
El['http-equiv'] := 'Content-Type';
El['content'] := 'text/html; charset=utf-8';
- TitleElement := Doc.CreateElement('title');
+ FTitleElement := Doc.CreateElement('title');
HeadEl.AppendChild(TitleElement);
El := Doc.CreateElement('link');
BodyElement := Doc.CreateElement('body');
+ ContentElement:=BodyElement;
HTMLEl.AppendChild(BodyElement);
CreatePageBody(AElement, ASubpageIndex);
@@ -301,23 +189,18 @@ begin
El['href'] := UTF8Decode(FixHtmlPath(UTF8Encode(Allocator.GetCSSFilename(AElement))));
end;
-function THTMLWriter.CreateXHTMLPage(AElement: TPasElement;
- ASubpageIndex: Integer): TXMLDocument;
-begin
- Result := nil;
-end;
-
procedure THTMLWriter.WriteDocPage(const aFileName: String; aElement: TPasElement; aSubPageIndex: Integer);
Var
PageDoc: TXMLDocument;
-
+ FN : String;
begin
PageDoc := CreateHTMLPage(aElement, aSubpageIndex);
try
- //writeln('Element: ',Element.PathName, ' FileName: ', Filename);
- WriteHTMLFile(PageDoc, aFilename);
+ FN:=GetFileBaseDir(Engine.Output)+aFilename;
+ //writeln('Element: ',Element.PathName, ' FileName: ', FN);
+ WriteHTMLFile(PageDoc, FN);
except
on E: Exception do
DoLog(SErrCouldNotCreateFile, [aFileName, e.Message]);
@@ -367,7 +250,6 @@ begin
end;
end;
-
procedure THTMLWriter.CreateCSSFile;
Var
@@ -397,783 +279,9 @@ begin
end;
end;
-procedure THTMLWriter.WriteXHTMLPages;
-begin
-end;
-
-{procedure THTMLWriter.CreateDoc(const ATitle: DOMString;
- AElement: TPasElement; const AFilename: String);
-var
- El: TDOMElement;
- DocInfo: TDocInfo;
- CSSName: String;
-
-begin
- Doc := TXHTMLDocument.Create;
- with TXHTMLDocument(Doc) do
- begin
- Encoding := 'ISO8859-1';
- CSSName := 'fpdoc.css';
- if Assigned(Module) then
- CSSName := '../' + CSSName;
-$IFNDEF ver1_0
- StylesheetType := 'text/css';
- StylesheetHRef := CSSName;
-$ENDIF
- CreateRoot(xhtmlStrict);
- with RequestHeadElement do
- begin
- AppendText(RequestTitleElement, ATitle);
- El := CreateElement('link');
- AppendChild(El);
- El['rel'] := 'stylesheet';
- El['type'] := 'text/css';
- El['href'] := FixHtmlPath(CSSName);
- end;
- Self.BodyElement := RequestBodyElement('en');
- end;
-
- if Length(AFilename) > 0 then
- begin
- DocInfo := TDocInfo.Create;
- DocInfos.Add(DocInfo);
- DocInfo.Element := AElement;
- DocInfo.Filename := AFilename;
- end;
-end;
-}
-
-
-
-function THTMLWriter.CreateEl(Parent: TDOMNode;
- const AName: DOMString): THTMLElement;
-begin
- Result := Doc.CreateElement(AName);
- Parent.AppendChild(Result);
-end;
-
-function THTMLWriter.CreatePara(Parent: TDOMNode): THTMLElement;
-begin
- Result := CreateEl(Parent, 'p');
-end;
-
-function THTMLWriter.CreateH1(Parent: TDOMNode): THTMLElement;
-begin
- Result := CreateEl(Parent, 'h1');
-end;
-
-function THTMLWriter.CreateH2(Parent: TDOMNode): THTMLElement;
-begin
- Result := CreateEl(Parent, 'h2');
-end;
-
-function THTMLWriter.CreateH3(Parent: TDOMNode): THTMLElement;
-begin
- Result := CreateEl(Parent, 'h3');
-end;
-
-function THTMLWriter.CreateTable(Parent: TDOMNode; const AClass: DOMString = ''): THTMLElement;
-begin
- Result := CreateEl(Parent, 'table');
- Result['cellspacing'] := '0';
- Result['cellpadding'] := '0';
- if AClass <> '' then
- Result['class'] := AClass;
-end;
-
-function THTMLWriter.CreateContentTable(Parent: TDOMNode): THTMLElement;
-begin
- Result := CreateEl(Parent, 'table');
-end;
-
-function THTMLWriter.CreateTR(Parent: TDOMNode): THTMLElement;
-begin
- Result := CreateEl(Parent, 'tr');
-end;
-
-function THTMLWriter.CreateTD(Parent: TDOMNode): THTMLElement;
-begin
- Result := CreateEl(Parent, 'td');
-end;
-
-function THTMLWriter.CreateTD_vtop(Parent: TDOMNode): THTMLElement;
-begin
- Result := CreateEl(Parent, 'td');
- Result['valign'] := 'top';
-end;
-
-function THTMLWriter.CreateLink(Parent: TDOMNode; const AHRef: String): THTMLElement;
-begin
- Result := CreateEl(Parent, 'a');
- Result['href'] := UTF8Decode(FixHtmlPath(AHRef));
-end;
-
-function THTMLWriter.CreateLink(Parent: TDOMNode;
- const AHRef: DOMString): THTMLElement;
-begin
- Result:=CreateLink(Parent,UTF8Encode(aHREf));
-end;
-
-function THTMLWriter.CreateAnchor(Parent: TDOMNode;
- const AName: DOMString): THTMLElement;
-begin
- Result := CreateEl(Parent, 'a');
- Result['name'] := AName;
-end;
-
-function THTMLWriter.CreateCode(Parent: TDOMNode): THTMLElement;
-begin
- Result := CreateEl(CreateEl(Parent, 'tt'), 'span');
- Result['class'] := 'code';
-end;
-
-function THTMLWriter.CreateWarning(Parent: TDOMNode): THTMLElement;
-begin
- Result := CreateEl(Parent, 'span');
- Result['class'] := 'warning';
-end;
-
-procedure THTMLWriter.DescrEmitNotesHeader(AContext: TPasElement);
-begin
- AppendText(CreateH2(BodyElement), SDocNotes);
- PushOutputNode(BodyElement);
-end;
-
-procedure THTMLWriter.DescrEmitNotesFooter(AContext: TPasElement);
-begin
- PopOutPutNode;
-end;
-
-procedure THTMLWriter.PushOutputNode(ANode: TDOMNode);
-begin
- OutputNodeStack.Add(CurOutputNode);
- CurOutputNode := ANode;
-end;
-
-procedure THTMLWriter.PopOutputNode;
-begin
- CurOutputNode := TDOMNode(OutputNodeStack[OutputNodeStack.Count - 1]);
- OutputNodeStack.Delete(OutputNodeStack.Count - 1);
-end;
-
-procedure THTMLWriter.DescrWriteText(const AText: DOMString);
-begin
- AppendText(CurOutputNode, AText);
-end;
-
-procedure THTMLWriter.DescrBeginBold;
-begin
- PushOutputNode(CreateEl(CurOutputNode, 'b'));
-end;
-
-procedure THTMLWriter.DescrEndBold;
-begin
- PopOutputNode;
-end;
-
-procedure THTMLWriter.DescrBeginItalic;
-begin
- PushOutputNode(CreateEl(CurOutputNode, 'i'));
-end;
-
-procedure THTMLWriter.DescrEndItalic;
-begin
- PopOutputNode;
-end;
-
-procedure THTMLWriter.DescrBeginEmph;
-begin
- PushOutputNode(CreateEl(CurOutputNode, 'em'));
-end;
-
-procedure THTMLWriter.DescrEndEmph;
-begin
- PopOutputNode;
-end;
-
-procedure THTMLWriter.DescrBeginUnderline;
-begin
- PushOutputNode(CreateEl(CurOutputNode, 'u'));
-end;
-
-procedure THTMLWriter.DescrEndUnderline;
-begin
- PopOutputNode;
-end;
-
-procedure THTMLWriter.DescrWriteImageEl(const AFileName, ACaption, ALinkName : DOMString);
-
-Var
- Pel,Cel: TDOMNode;
- El :TDomElement;
- D : String;
- L : Integer;
-
-begin
- // Determine parent node.
- If (ACaption='') then
- Pel:=CurOutputNode
- else
- begin
- Cel:=CreateTable(CurOutputNode, 'imagetable');
- Pel:=CreateTD(CreateTR(Cel));
- Cel:=CreateTD(CreateTR(Cel));
- El := CreateEl(Cel, 'span');
- El['class'] := 'imagecaption';
- Cel := El;
- If (ALinkName<>'') then
- Cel:=CreateAnchor(Cel,ALinkName);
- AppendText(Cel,ACaption);
- end;
-
- // Determine URL for image.
- If (Module=Nil) then
- D:=Allocator.GetRelativePathToTop(Package)
- else
- D:=Allocator.GetRelativePathToTop(Module);
- L:=Length(D);
- If (L>0) and (D[L]<>'/') then
- D:=D+'/';
-
- // Create image node.
- El:=CreateEl(Pel,'img');
- EL['src']:=UTF8Decode(D + BaseImageURL) + AFileName;
- El['alt']:=ACaption;
-
- //cache image filename, so it can be used later (CHM)
- FImageFileList.Add(UTF8Encode(UTF8Decode(BaseImageURL) + AFileName));
-end;
-
-procedure THTMLWriter.DescrWriteFileEl(const AText: DOMString);
-var
- NewEl: TDOMElement;
-begin
- NewEl := CreateEl(CurOutputNode, 'span');
- NewEl['class'] := 'file';
- AppendText(NewEl, AText);
-end;
-
-procedure THTMLWriter.DescrWriteKeywordEl(const AText: DOMString);
-var
- NewEl: TDOMElement;
-begin
- NewEl := CreateEl(CurOutputNode, 'span');
- NewEl['class'] := 'kw';
- AppendText(NewEl, AText);
-end;
-
-procedure THTMLWriter.DescrWriteVarEl(const AText: DOMString);
-begin
- AppendText(CreateEl(CurOutputNode, 'var'), AText);
-end;
-
-procedure THTMLWriter.DescrBeginLink(const AId: DOMString);
-var
- a,s,n : String;
-
-begin
- a:=UTF8Encode(AId);
- s := UTF8Encode(ResolveLinkID(a));
- if Length(s) = 0 then
- begin
- if assigned(module) then
- s:=module.name
- else
- s:='?';
- if a='' then a:='<empty>';
- if Assigned(CurrentContext) then
- N:=CurrentContext.Name
- else
- N:='?';
- DoLog(SErrUnknownLinkID, [s,n,a]);
- PushOutputNode(CreateEl(CurOutputNode, 'b'));
- end else
- PushOutputNode(CreateLink(CurOutputNode, s));
-end;
-
-procedure THTMLWriter.DescrEndLink;
-begin
- PopOutputNode;
-end;
-
-procedure THTMLWriter.DescrBeginURL(const AURL: DOMString);
-begin
- PushOutputNode(CreateLink(CurOutputNode, AURL));
-end;
-
-procedure THTMLWriter.DescrEndURL;
-begin
- PopOutputNode;
-end;
-
-procedure THTMLWriter.DescrWriteLinebreak;
-begin
- CreateEl(CurOutputNode, 'br');
-end;
-
-procedure THTMLWriter.DescrBeginParagraph;
-begin
- PushOutputNode(CreatePara(CurOutputNode));
-end;
-
-procedure THTMLWriter.DescrEndParagraph;
-begin
- PopOutputNode;
-end;
-
-procedure THTMLWriter.DescrBeginCode(HasBorder: Boolean; const AHighlighterName: String);
-begin
- DoPasHighlighting := (AHighlighterName = '') or (AHighlighterName = 'Pascal');
- HighlighterFlags := 0;
- PushOutputNode(CreateEl(CurOutputNode, 'pre'));
-end;
-
-procedure THTMLWriter.DescrWriteCodeLine(const ALine: String);
-begin
- if DoPasHighlighting then
- begin
- HighlighterFlags := AppendPasSHFragment(CurOutputNode, ALine,
- HighlighterFlags);
- AppendText(CurOutputNode, #10);
- end else
- AppendText(CurOutputNode, ALine + #10);
-end;
-
-procedure THTMLWriter.DescrEndCode;
-begin
- PopOutputNode;
-end;
-
-procedure THTMLWriter.DescrBeginOrderedList;
-begin
- PushOutputNode(CreateEl(CurOutputNode, 'ol'));
-end;
-
-procedure THTMLWriter.DescrEndOrderedList;
-begin
- PopOutputNode;
-end;
-
-procedure THTMLWriter.DescrBeginUnorderedList;
-begin
- PushOutputNode(CreateEl(CurOutputNode, 'ul'));
-end;
-
-procedure THTMLWriter.DescrEndUnorderedList;
-begin
- PopOutputNode;
-end;
-
-procedure THTMLWriter.DescrBeginDefinitionList;
-begin
- PushOutputNode(CreateEl(CurOutputNode, 'dl'));
-end;
-
-procedure THTMLWriter.DescrEndDefinitionList;
-begin
- PopOutputNode;
-end;
-
-procedure THTMLWriter.DescrBeginListItem;
-begin
- PushOutputNode(CreateEl(CurOutputNode, 'li'));
-end;
-
-procedure THTMLWriter.DescrEndListItem;
-begin
- PopOutputNode;
-end;
-
-procedure THTMLWriter.DescrBeginDefinitionTerm;
-begin
- PushOutputNode(CreateEl(CurOutputNode, 'dt'));
-end;
-
-procedure THTMLWriter.DescrEndDefinitionTerm;
-begin
- PopOutputNode;
-end;
-
-procedure THTMLWriter.DescrBeginDefinitionEntry;
-begin
- PushOutputNode(CreateEl(CurOutputNode, 'dd'));
-end;
-
-procedure THTMLWriter.DescrEndDefinitionEntry;
-begin
- PopOutputNode;
-end;
-
-procedure THTMLWriter.DescrBeginSectionTitle;
-begin
- PushOutputNode(CreateEl(CurOutputNode, 'h3'));
-end;
-
-procedure THTMLWriter.DescrBeginSectionBody;
-begin
- PopOutputNode;
-end;
-
-procedure THTMLWriter.DescrEndSection;
-begin
-end;
-
-procedure THTMLWriter.DescrBeginRemark;
-var
- NewEl, TDEl: TDOMElement;
-begin
- NewEl := CreateEl(CurOutputNode, 'table');
- NewEl['width'] := '100%';
- NewEl['border'] := '0';
- NewEl['CellSpacing'] := '0';
- NewEl['class'] := 'remark';
- NewEl := CreateTR(NewEl);
- TDEl := CreateTD(NewEl);
- TDEl['valign'] := 'top';
- TDEl['class'] := 'pre';
- AppendText(CreateEl(TDEl, 'b'), SDocRemark);
- PushOutputNode(CreateTD(NewEl));
-end;
-
-procedure THTMLWriter.DescrEndRemark;
-begin
- PopOutputNode;
-end;
-
-procedure THTMLWriter.DescrBeginTable(ColCount: Integer; HasBorder: Boolean);
-var
- Table: TDOMElement;
-begin
- Table := CreateEl(CurOutputNode, 'table');
- Table['border'] := UTF8Decode(IntToStr(Ord(HasBorder)));
- PushOutputNode(Table);
-end;
-
-procedure THTMLWriter.DescrEndTable;
-begin
- PopOutputNode;
-end;
-
-procedure THTMLWriter.DescrBeginTableCaption;
-begin
- PushOutputNode(CreateEl(CurOutputNode, 'caption'));
-end;
-
-procedure THTMLWriter.DescrEndTableCaption;
-begin
- PopOutputNode;
-end;
-
-procedure THTMLWriter.DescrBeginTableHeadRow;
-begin
- PushOutputNode(CreateTr(CurOutputNode));
- InsideHeadRow := True;
-end;
-
-procedure THTMLWriter.DescrEndTableHeadRow;
-begin
- InsideHeadRow := False;
- PopOutputNode;
-end;
-
-procedure THTMLWriter.DescrBeginTableRow;
-begin
- PushOutputNode(CreateTR(CurOutputNode));
-end;
-
-procedure THTMLWriter.DescrEndTableRow;
-begin
- PopOutputNode;
-end;
-
-procedure THTMLWriter.DescrBeginTableCell;
-begin
- if InsideHeadRow then
- PushOutputNode(CreateEl(CurOutputNode, 'th'))
- else
- PushOutputNode(CreateTD(CurOutputNode));
-end;
-
-procedure THTMLWriter.DescrEndTableCell;
-begin
- PopOutputNode;
-end;
-
-procedure THTMLWriter.AppendText(Parent: TDOMNode; const AText: String);
-begin
- AppendText(Parent,UTF8Decode(aText));
-end;
-
-
-procedure THTMLWriter.AppendText(Parent: TDOMNode; const AText: DOMString);
-begin
- Parent.AppendChild(Doc.CreateTextNode(AText));
-end;
-
-procedure THTMLWriter.AppendNbSp(Parent: TDOMNode; ACount: Integer);
-begin
- while ACount > 0 do
- begin
- Parent.AppendChild(Doc.CreateEntityReference('nbsp'));
- Dec(ACount);
- end;
-end;
-
-procedure THTMLWriter.AppendSym(Parent: TDOMNode; const AText: DOMString);
-var
- El: TDOMElement;
-begin
- El := CreateEl(Parent, 'span');
- El['class'] := 'sym';
- AppendText(El, AText);
-end;
-
-procedure THTMLWriter.AppendKw(Parent: TDOMNode; const AText: String);
-begin
- AppendKW(Parent,UTF8Decode(aText));
-end;
-
-procedure THTMLWriter.AppendKw(Parent: TDOMNode; const AText: DOMString);
-var
- El: TDOMElement;
-begin
- El := CreateEl(Parent, 'span');
- El['class'] := 'kw';
- AppendText(El, AText);
-end;
-
-function THTMLWriter.AppendPasSHFragment(Parent: TDOMNode;
- const AText: String; AShFlags: Byte): Byte;
-
-
-var
- Line, Last, p: PChar;
- El: TDOMElement;
-
- Procedure MaybeOutput;
-
- Var
- CurParent: TDomNode;
-
- begin
- If (Last<>Nil) then
- begin
- If (el<>Nil) then
- CurParent:=El
- else
- CurParent:=Parent;
- AppendText(CurParent,Last);
- El:=Nil;
- Last:=Nil;
- end;
- end;
-
- Function NewEl(Const ElType,Attr,AttrVal : DOMString) : TDomElement;
-
- begin
- Result:=CreateEl(Parent,ElType);
- Result[Attr]:=AttrVal;
- end;
-
- Function NewSpan(Const AttrVal : DOMString) : TDomElement;
-
- begin
- Result:=CreateEl(Parent,'span');
- Result['class']:=AttrVal;
- end;
-
-begin
- GetMem(Line, Length(AText) * 3 + 4);
- Try
- DoPascalHighlighting(AShFlags, PChar(AText), Line);
- Result := AShFlags;
- Last := Nil;
- p := Line;
- el:=nil;
- while p[0] <> #0 do
- begin
- if p[0] = LF_ESCAPE then
- begin
- p[0] := #0;
- MaybeOutput;
- case Ord(p[1]) of
- shDefault: El:=Nil;
- shInvalid: El:=newel('font','color','red');
- shSymbol : El:=newspan('sym');
- shKeyword: El:=newspan('kw');
- shComment: El:=newspan('cmt');
- shDirective: El:=newspan('dir');
- shNumbers: El:=newspan('num');
- shCharacters: El:=newspan('chr');
- shStrings: El:=newspan('str');
- shAssembler: El:=newspan('asm');
- end;
- Inc(P);
- end
- else If (Last=Nil) then
- Last:=P;
- Inc(p);
- end;
- MaybeOutput;
- Finally
- FreeMem(Line);
- end;
-end;
-
-procedure THTMLWriter.AppendShortDescr ( AContext: TPasElement;
- Parent: TDOMNode; DocNode: TDocNode ) ;
-
-Var
- N : TDocNode;
-
-begin
- if Assigned(DocNode) then
- begin
- If (DocNode.Link<>'') then
- begin
- N:=Engine.FindLinkedNode(DocNode);
- If (N<>Nil) then
- DocNode:=N;
- end;
- If Assigned(DocNode.ShortDescr) then
- begin
- PushOutputNode(Parent);
- try
- if not ConvertShort(AContext,TDomElement(DocNode.ShortDescr)) then
- Warning(AContext, SErrInvalidShortDescr)
- finally
- PopOutputNode;
- end;
- end;
- end;
-end;
-
-procedure THTMLWriter.AppendShortDescr(Parent: TDOMNode; Element: TPasElement);
-
-begin
- AppendShortDescr(Element,Parent,Engine.FindDocNode(Element));
-end;
-
-procedure THTMLWriter.AppendShortDescrCell(Parent: TDOMNode;
- Element: TPasElement);
-
-var
- ParaEl: TDOMElement;
-
-begin
- if Assigned(Engine.FindShortDescr(Element)) then
- begin
- AppendNbSp(CreatePara(CreateTD(Parent)), 2);
- ParaEl := CreatePara(CreateTD(Parent));
- ParaEl['class'] := 'cmt';
- AppendShortDescr(ParaEl, Element);
- end;
-end;
-
-procedure THTMLWriter.AppendDescr(AContext: TPasElement; Parent: TDOMNode;
- DescrNode: TDOMElement; AutoInsertBlock: Boolean);
-begin
- if Assigned(DescrNode) then
- begin
- PushOutputNode(Parent);
- try
- ConvertDescr(AContext, DescrNode, AutoInsertBlock);
- finally
- PopOutputNode;
- end;
- end;
-end;
-
-procedure THTMLWriter.AppendDescrSection(AContext: TPasElement; Parent: TDOMNode; DescrNode: TDOMElement; const ATitle: String);
-begin
- AppendDescrSection(aContext,Parent,DescrNode,UTF8Decode(aTitle));
-end;
-
-procedure THTMLWriter.AppendDescrSection(AContext: TPasElement;
- Parent: TDOMNode; DescrNode: TDOMElement; const ATitle: DOMString);
-begin
- if not IsDescrNodeEmpty(DescrNode) then
- begin
- If (ATitle<>'') then // Can be empty for topic.
- AppendText(CreateH2(Parent), ATitle);
- AppendDescr(AContext, Parent, DescrNode, True);
- end;
-end;
-
-
-
-function THTMLWriter.AppendHyperlink(Parent: TDOMNode;
- Element: TPasElement): TDOMElement;
-var
- s: DOMString;
- UnitList: TFPList;
- i: Integer;
- ThisPackage: TLinkNode;
-begin
- if Assigned(Element) then
- begin
- if Element.InheritsFrom(TPasUnresolvedTypeRef) then
- begin
- s := ResolveLinkID(Element.Name);
- if Length(s) = 0 then
- begin
- { Try all packages }
- ThisPackage := Engine.RootLinkNode.FirstChild;
- while Assigned(ThisPackage) do
- begin
- s := ResolveLinkID(ThisPackage.Name + '.' + Element.Name);
- if Length(s) > 0 then
- break;
- ThisPackage := ThisPackage.NextSibling;
- end;
- if Length(s) = 0 then
- begin
- { Okay, then we have to try all imported units of the current module }
- UnitList := Module.InterfaceSection.UsesList;
- for i := UnitList.Count - 1 downto 0 do
- begin
- { Try all packages }
- ThisPackage := Engine.RootLinkNode.FirstChild;
- while Assigned(ThisPackage) do
- begin
- s := ResolveLinkID(ThisPackage.Name + '.' +
- TPasType(UnitList[i]).Name + '.' + Element.Name);
- if Length(s) > 0 then
- break;
- ThisPackage := ThisPackage.NextSibling;
- end;
- if length(s)=0 then
- s := ResolveLinkID('#rtl.System.' + Element.Name);
- if Length(s) > 0 then
- break;
- end;
- end;
- end;
- end else if Element is TPasEnumValue then
- s := ResolveLinkID(Element.Parent.PathName)
- else
- s := ResolveLinkID(Element.PathName);
-
- if Length(s) > 0 then
- begin
- Result := CreateLink(Parent, s);
- AppendText(Result, Element.Name);
- end else
- begin
- Result := nil;
- AppendText(Parent, Element.Name); // unresolved items
- end;
- end else
- begin
- Result := nil;
- AppendText(CreateWarning(Parent), '<NIL>');
- end;
-end;
-
{ Returns the new CodeEl, which will be the old CodeEl in most cases }
-function THTMLWriter.AppendType(CodeEl, TableEl: TDOMElement;
- Element: TPasType; Expanded: Boolean; NestingLevel: Integer): TDOMElement;
+function THTMLWriter.AppendType(CodeEl, TableEl: TDOMElement; Element: TPasType; Expanded: Boolean; NestingLevel: Integer): TDOMElement;
Var
S : String;
@@ -1504,17 +612,6 @@ begin
Result := CodeEl;
end;
-procedure THTMLWriter.AppendTitle(const AText: DOMString; Hints : TPasMemberHints = []);
-
-Var
- T : UnicodeString;
-begin
- T:=AText;
- if (Hints<>[]) then
- T:=T+' ('+UTF8Decode(Engine.HintsToStr(Hints))+')';
- AppendText(TitleElement, AText);
- AppendText(CreateH1(BodyElement), T);
-end;
procedure THTMLWriter.AppendTopicMenuBar(Topic : TTopicElement);
@@ -1531,7 +628,7 @@ var
end;
begin
- TableEl := CreateEl(BodyElement, 'table');
+ TableEl := CreateEl(ContentElement, 'table');
TableEl['cellpadding'] := '4';
TableEl['cellspacing'] := '0';
TableEl['border'] := '0';
@@ -1567,15 +664,6 @@ begin
end;
end;
-procedure THTMLWriter.AppendFragment(aParentNode : TDOMElement; aStream : TStream);
-
-begin
- if (aStream<>Nil) then
- begin
- aStream.Position:=0;
- ReadXMLFragment(aParentNode,aStream);
- end;
-end;
function THTMLWriter.CreateAllocator: TFileAllocator;
begin
@@ -1618,7 +706,7 @@ var
begin
- TableEl := CreateEl(BodyElement, 'table');
+ TableEl := CreateEl(ContentElement, 'table');
TableEl['cellpadding'] := '4';
TableEl['cellspacing'] := '0';
TableEl['border'] := '0';
@@ -1703,139 +791,9 @@ begin
AppendHyperlink(ParaEl, Package);
AppendText(ParaEl, ']');
end;
- AppendFragment(BodyElement,HeaderHTML);
+ AppendFragment(ContentElement,HeaderHTML);
end;
-procedure THTMLWriter.AppendSourceRef(AElement: TPasElement);
-begin
- AppendText(CreatePara(BodyElement), Format(SDocSourcePosition,
- [ExtractFileName(AElement.SourceFilename), AElement.SourceLinenumber]));
-end;
-
-procedure THTMLWriter.AppendSeeAlsoSection ( AElement: TPasElement;
- DocNode: TDocNode ) ;
-
-var
- Node: TDOMNode;
- TableEl, El, TREl, ParaEl, NewEl, DescrEl: TDOMElement;
- l,s,n: DOMString;
- IsFirstSeeAlso : Boolean;
-
-begin
- if Not (Assigned(DocNode) and Assigned(DocNode.SeeAlso)) then
- Exit;
- IsFirstSeeAlso := True;
- Node:=DocNode.SeeAlso.FirstChild;
- While Assigned(Node) do
- begin
- if (Node.NodeType=ELEMENT_NODE) and (Node.NodeName='link') then
- begin
- if IsFirstSeeAlso then
- begin
- IsFirstSeeAlso := False;
- AppendText(CreateH2(BodyElement), SDocSeeAlso);
- TableEl := CreateTable(BodyElement);
- end;
- El:=TDOMElement(Node);
- TREl:=CreateTR(TableEl);
- ParaEl:=CreatePara(CreateTD_vtop(TREl));
- l:=El['id'];
- s:= ResolveLinkID(UTF8ENcode(l));
- if Length(s)=0 then
- begin
- if assigned(module) then
- s:=UTF8Decode(module.name)
- else
- s:='?';
- if l='' then l:='<empty>';
- if Assigned(AElement) then
- N:=UTF8Decode(AElement.Name)
- else
- N:='?';
- DoLog(SErrUnknownLinkID, [s,N,l]);
- NewEl := CreateEl(ParaEl,'b')
- end
- else
- NewEl := CreateLink(ParaEl,s);
- if Not IsDescrNodeEmpty(El) then
- begin
- PushOutputNode(NewEl);
- Try
- ConvertBaseShortList(AElement, El, True)
- Finally
- PopOutputNode;
- end;
- end
- else
- AppendText(NewEl,El['id']);
- l:=El['id'];
- DescrEl := Engine.FindShortDescr(AElement.GetModule,UTF8Encode(L));
- if Assigned(DescrEl) then
- begin
- AppendNbSp(CreatePara(CreateTD(TREl)), 2);
- ParaEl := CreatePara(CreateTD(TREl));
- ParaEl['class'] := 'cmt';
- PushOutputNode(ParaEl);
- try
- ConvertShort(AElement, DescrEl);
- finally
- PopOutputNode;
- end;
- end;
- end; // Link node
- Node := Node.NextSibling;
- end; // While
-end;
-
-procedure THTMLWriter.AppendExampleSection ( AElement: TPasElement;
- DocNode: TDocNode ) ;
-
-var
- Node: TDOMNode;
-// TableEl, El, TREl, TDEl, ParaEl, NewEl, DescrEl: TDOMElement;
- fn,s: String;
- f: Text;
-
-begin
- if not (Assigned(DocNode) and Assigned(DocNode.FirstExample)) then
- Exit;
- Node := DocNode.FirstExample;
- while Assigned(Node) do
- begin
- if (Node.NodeType = ELEMENT_NODE) and (Node.NodeName = 'example') then
- begin
- fn:=Engine.GetExampleFilename(TDOMElement(Node));
- If (fn<>'') then
- begin
- AppendText(CreateH2(BodyElement), SDocExample);
- try
- Assign(f, FN);
- Reset(f);
- try
- PushOutputNode(BodyElement);
- DescrBeginCode(False, UTF8Encode(TDOMElement(Node)['highlighter']));
- while not EOF(f) do
- begin
- ReadLn(f, s);
- DescrWriteCodeLine(s);
- end;
- DescrEndCode;
- PopOutputNode;
- finally
- Close(f);
- end;
- except
- on e: Exception do
- begin
- e.Message := '[example] ' + e.Message;
- raise;
- end;
- end;
- end;
- end;
- Node := Node.NextSibling;
- end;
-end;
procedure THTMLWriter.AppendFooter;
@@ -1844,11 +802,11 @@ Var
F : TDomElement;
begin
if Assigned(FooterHTML) then
- AppendFragment(BodyElement, FooterHTML)
+ AppendFragment(ContentElement, FooterHTML)
else if IncludeDateInFooter then
begin
- CreateEl(BodyElement, 'hr');
- F:=CreateEl(BodyElement,'span');
+ CreateEl(ContentElement, 'hr');
+ F:=CreateEl(ContentElement,'span');
F['class']:='footer';
If (FDateFormat='') then
S:=DateToStr(Date)
@@ -1865,43 +823,44 @@ var
begin
DocNode := Engine.FindDocNode(AElement);
- If Assigned(DocNode) then
- begin
- // Description
- if Assigned(DocNode.Descr) then
- AppendDescrSection(AElement, BodyElement, DocNode.Descr, UTF8Encode(SDocDescription));
+ If Not Assigned(DocNode) then
+ exit;
- // Append "Errors" section
- if Assigned(DocNode.ErrorsDoc) then
- AppendDescrSection(AElement, BodyElement, DocNode.ErrorsDoc, UTF8Encode(SDocErrors));
+ // Description
+ if Assigned(DocNode.Descr) then
+ AppendDescrSection(AElement, ContentElement, DocNode.Descr, UTF8Encode(SDocDescription));
- // Append Version info
- if Assigned(DocNode.Version) then
- AppendDescrSection(AElement, BodyElement, DocNode.Version, UTF8Encode(SDocVersion));
+ // Append "Errors" section
+ if Assigned(DocNode.ErrorsDoc) then
+ AppendDescrSection(AElement, ContentElement, DocNode.ErrorsDoc, UTF8Encode(SDocErrors));
- // Append "See also" section
- AppendSeeAlsoSection(AElement,DocNode);
+ // Append Version info
+ if Assigned(DocNode.Version) then
+ AppendDescrSection(AElement, ContentElement, DocNode.Version, UTF8Encode(SDocVersion));
- // Append examples, if present
- AppendExampleSection(AElement,DocNode);
- // Append notes, if present
- ConvertNotes(AElement,DocNode.Notes);
- end;
+ // Append "See also" section
+ AppendSeeAlsoSection(AElement,DocNode);
+
+ // Append examples, if present
+ AppendExampleSection(AElement,DocNode);
+ // Append notes, if present
+ ConvertNotes(AElement,DocNode.Notes);
end;
procedure THTMLWriter.CreateTopicPageBody(AElement: TTopicElement);
var
DocNode: TDocNode;
+
begin
AppendTopicMenuBar(AElement);
DocNode:=AElement.TopicNode;
if Assigned(DocNode) then // should always be true, but we're being careful.
begin
AppendShortDescr(AElement,TitleElement, DocNode);
- AppendShortDescr(AElement,CreateH2(BodyElement), DocNode);
+ AppendShortDescr(AElement,CreateH2(ContentElement), DocNode);
if Assigned(DocNode.Descr) then
- AppendDescrSection(AElement, BodyElement, DocNode.Descr, '');
+ AppendDescrSection(AElement, ContentElement, DocNode.Descr, '');
AppendSeeAlsoSection(AElement,DocNode);
CreateTopicLinks(DocNode,AElement);
AppendExampleSection(AElement,DocNode);
@@ -1910,6 +869,7 @@ begin
end;
procedure THTMLWriter.CreateClassHierarchyPage(AddUnit : Boolean);
+
type
TypeEN = (NPackage, NModule, NName);
@@ -1995,7 +955,7 @@ type
end;
begin
- PushOutputNode(BodyElement);
+ PushOutputNode(ContentElement);
try
PushClassList;
AppendClass(TreeClass.RootNode);
@@ -2030,11 +990,12 @@ begin
CreateClassHierarchyPage(True);
end;
-procedure THTMLWriter.CreatePageBody(AElement: TPasElement;
- ASubpageIndex: Integer);
+procedure THTMLWriter.CreatePageBody(AElement: TPasElement; ASubpageIndex: Integer);
+
var
i: Integer;
Element: TPasElement;
+
begin
CurDirectory := Allocator.GetFilename(AElement, ASubpageIndex);
i := Length(CurDirectory);
@@ -2121,7 +1082,7 @@ begin
end;
Try
// Create a quick jump table to all available letters.
- TableEl := CreateTable(BodyElement);
+ TableEl := CreateTable(ContentElement);
TableEl['border']:='1';
TableEl['width']:='50%';
TREl := CreateTR(TableEl);
@@ -2140,10 +1101,10 @@ begin
CL:=Lists[C];
If CL<>Nil then
begin
- El:=CreateH2(BodyElement);
+ El:=CreateH2(ContentElement);
AppendText(El,UTF8Decode(C));
CreateAnchor(El,UTF8Decode('SECTION'+C));
- TableEl := CreateTable(BodyElement);
+ TableEl := CreateTable(ContentElement);
TableEl['Width']:='80%';
// Determine number of rows needed
Rows:=(CL.Count div IndexColCount);
@@ -2173,22 +1134,6 @@ begin
end;
end;
-
-procedure THTMLWriter.AddModuleIdentifiers(AModule : TPasModule; L : TStrings);
-
-begin
- if assigned(AModule.InterfaceSection) Then
- begin
- AddElementsFromList(L,AModule.InterfaceSection.Consts);
- AddElementsFromList(L,AModule.InterfaceSection.Types);
- AddElementsFromList(L,AModule.InterfaceSection.Functions);
- AddElementsFromList(L,AModule.InterfaceSection.Classes);
- AddElementsFromList(L,AModule.InterfaceSection.Variables);
- AddElementsFromList(L,AModule.InterfaceSection.ResStrings);
- end;
-end;
-
-
procedure THTMLWriter.CreatePackageIndex;
Var
@@ -2219,6 +1164,7 @@ begin
end;
procedure THTMLWriter.CreatePackagePageBody;
+
var
DocNode: TDocNode;
TableEl, TREl: TDOMElement;
@@ -2229,10 +1175,10 @@ var
begin
AppendMenuBar(0);
AppendTitle(UTF8Encode(Format(SDocPackageTitle, [Copy(Package.Name, 2, 256)])));
- AppendShortDescr(CreatePara(BodyElement), Package);
+ AppendShortDescr(CreatePara(ContentElement), Package);
- AppendText(CreateH2(BodyElement), UTF8Encode(SDocUnits));
- TableEl := CreateTable(BodyElement);
+ AppendText(CreateH2(ContentElement), UTF8Encode(SDocUnits));
+ TableEl := CreateTable(ContentElement);
L:=TStringList.Create;
Try
L.Sorted:=True;
@@ -2255,13 +1201,12 @@ begin
if Assigned(DocNode) then
begin
if Assigned(DocNode.Descr) then
- AppendDescrSection(nil, BodyElement, DocNode.Descr, UTF8Decode(SDocDescription));
+ AppendDescrSection(nil, ContentElement, DocNode.Descr, UTF8Decode(SDocDescription));
CreateTopicLinks(DocNode,Package);
end;
end;
-procedure THTMLWriter.CreateTopicLinks ( Node: TDocNode;
- PasElement: TPasElement ) ;
+procedure THTMLWriter.CreateTopicLinks (Node: TDocNode; PasElement: TPasElement) ;
var
DocNode: TDocNode;
@@ -2279,8 +1224,8 @@ begin
if first then
begin
First:=False;
- AppendText(CreateH2(BodyElement), UTF8Decode(SDocRelatedTopics));
- TableEl := CreateTable(BodyElement);
+ AppendText(CreateH2(ContentElement), UTF8Decode(SDocRelatedTopics));
+ TableEl := CreateTable(ContentElement);
end;
TREl := CreateTR(TableEl);
ThisTopic:=FindTopicElement(DocNode);
@@ -2309,133 +1254,137 @@ begin
end;
end;
-procedure THTMLWriter.CreateModulePageBody(AModule: TPasModule;
- ASubpageIndex: Integer);
+procedure THTMLWriter.CreateModuleMainPage(aModule : TPasModule);
- procedure CreateMainPage;
- var
- TableEl, TREl, TDEl, CodeEl: TDOMElement;
- i: Integer;
- UnitRef: TPasType;
- DocNode: TDocNode;
+var
+ TableEl, TREl, TDEl, CodeEl: TDOMElement;
+ i: Integer;
+ UnitRef: TPasType;
+ DocNode: TDocNode;
+
+begin
+ AppendMenuBar(0);
+ AppendTitle(UTF8Decode(Format(SDocUnitTitle, [AModule.Name])),AModule.Hints);
+ AppendShortDescr(CreatePara(ContentElement), AModule);
+
+ if AModule.InterfaceSection.UsesList.Count > 0 then
begin
- AppendMenuBar(0);
- AppendTitle(UTF8Decode(Format(SDocUnitTitle, [AModule.Name])),AModule.Hints);
- AppendShortDescr(CreatePara(BodyElement), AModule);
+ TableEl := CreateTable(ContentElement);
+ AppendKw(CreateCode(CreatePara(CreateTD(CreateTR(TableEl)))), 'uses');
+ for i := 0 to AModule.InterfaceSection.UsesList.Count - 1 do
+ begin
+ UnitRef := TPasType(AModule.InterfaceSection.UsesList[i]);
+ DocNode := Engine.FindDocNode(UnitRef);
+ if Assigned(DocNode) and DocNode.IsSkipped then
+ continue;
+ TREl := CreateTR(TableEl);
+ TDEl := CreateTD_vtop(TREl);
+ CodeEl := CreateCode(CreatePara(TDEl));
+ AppendNbSp(CodeEl, 2);
+ AppendHyperlink(CodeEl, UnitRef);
+ if i < AModule.InterfaceSection.UsesList.Count - 1 then
+ AppendSym(CodeEl, ',')
+ else
+ AppendSym(CodeEl, ';');
+ AppendText(CodeEl, ' '); // Space for descriptions
+ AppendShortDescrCell(TREl, UnitRef);
+ end;
+ end;
- if AModule.InterfaceSection.UsesList.Count > 0 then
+ DocNode := Engine.FindDocNode(AModule);
+ if Assigned(DocNode) then
begin
- TableEl := CreateTable(BodyElement);
- AppendKw(CreateCode(CreatePara(CreateTD(CreateTR(TableEl)))), 'uses');
- for i := 0 to AModule.InterfaceSection.UsesList.Count - 1 do
- begin
- UnitRef := TPasType(AModule.InterfaceSection.UsesList[i]);
- DocNode := Engine.FindDocNode(UnitRef);
- if Assigned(DocNode) and DocNode.IsSkipped then
- continue;
- TREl := CreateTR(TableEl);
- TDEl := CreateTD_vtop(TREl);
- CodeEl := CreateCode(CreatePara(TDEl));
- AppendNbSp(CodeEl, 2);
- AppendHyperlink(CodeEl, UnitRef);
- if i < AModule.InterfaceSection.UsesList.Count - 1 then
- AppendSym(CodeEl, ',')
- else
- AppendSym(CodeEl, ';');
- AppendText(CodeEl, ' '); // Space for descriptions
- AppendShortDescrCell(TREl, UnitRef);
- end;
+ if Assigned(DocNode.Descr) then
+ AppendDescrSection(AModule, ContentElement, DocNode.Descr, UTF8Decode(SDocOverview));
+ ConvertNotes(AModule,DocNode.Notes);
+ CreateTopicLinks(DocNode,AModule);
end;
+end;
- DocNode := Engine.FindDocNode(AModule);
- if Assigned(DocNode) then
- begin
- if Assigned(DocNode.Descr) then
- AppendDescrSection(AModule, BodyElement, DocNode.Descr, UTF8Decode(SDocOverview));
- ConvertNotes(AModule,DocNode.Notes);
- CreateTopicLinks(DocNode,AModule);
- end;
- end;
- procedure CreateSimpleSubpage(const ATitle: DOMString; AList: TFPList);
- var
- TableEl, TREl, CodeEl: TDOMElement;
- i, j: Integer;
- Decl: TPasElement;
- SortedList: TFPList;
- DocNode: TDocNode;
- S : String;
+procedure THTMLWriter.CreateModuleSimpleSubpage(aModule: TPasModule; ASubpageIndex: Integer; const ATitle: DOMString; AList: TFPList);
- begin
- AppendMenuBar(ASubpageIndex);
- S:=UTF8Encode(ATitle);
- AppendTitle(UTF8Decode(Format(SDocUnitTitle + ': %s', [AModule.Name, S])));
- SortedList := TFPList.Create;
- try
- for i := 0 to AList.Count - 1 do
- begin
- Decl := TPasElement(AList[i]);
- DocNode := Engine.FindDocNode(Decl);
- if (not Assigned(DocNode)) or (not DocNode.IsSkipped) then
- begin
- j := 0;
- while (j < SortedList.Count) and (CompareText(
- TPasElement(SortedList[j]).PathName, Decl.PathName) < 0) do
- Inc(j);
- SortedList.Insert(j, Decl);
- end;
- end;
+var
+ TableEl, TREl, CodeEl: TDOMElement;
+ i, j: Integer;
+ Decl: TPasElement;
+ SortedList: TFPList;
+ DocNode: TDocNode;
+ S : String;
- TableEl := CreateTable(BodyElement);
- for i := 0 to SortedList.Count - 1 do
+begin
+ AppendMenuBar(ASubpageIndex);
+ S:=UTF8Encode(ATitle);
+ AppendTitle(UTF8Decode(Format(SDocUnitTitle + ': %s', [AModule.Name, S])));
+ SortedList := TFPList.Create;
+ try
+ for i := 0 to AList.Count - 1 do
+ begin
+ Decl := TPasElement(AList[i]);
+ DocNode := Engine.FindDocNode(Decl);
+ if (not Assigned(DocNode)) or (not DocNode.IsSkipped) then
begin
- Decl := TPasElement(SortedList[i]);
- TREl := CreateTR(TableEl);
- CodeEl := CreateCode(CreatePara(CreateTD_vtop(TREl)));
- AppendHyperlink(CodeEl, Decl);
- AppendShortDescrCell(TREl, Decl);
+ j := 0;
+ while (j < SortedList.Count) and (CompareText(
+ TPasElement(SortedList[j]).PathName, Decl.PathName) < 0) do
+ Inc(j);
+ SortedList.Insert(j, Decl);
end;
- finally
- SortedList.Free;
end;
- end;
- procedure CreateResStringsPage;
- var
- ParaEl: TDOMElement;
- i: Integer;
- Decl: TPasResString;
- begin
- AppendMenuBar(ResstrSubindex);
- AppendTitle(UTF8Decode(Format(SDocUnitTitle + ': %s', [AModule.Name, SDocResStrings])));
- for i := 0 to AModule.InterfaceSection.ResStrings.Count - 1 do
+ TableEl := CreateTable(ContentElement);
+ for i := 0 to SortedList.Count - 1 do
begin
- Decl := TPasResString(AModule.InterfaceSection.ResStrings[i]);
- CreateEl(BodyElement, 'a')['name'] := UTF8Decode(LowerCase(Decl.Name));
- ParaEl := CreatePara(BodyElement);
- AppendText(CreateCode(ParaEl), UTF8Decode(Decl.Name));
- CreateEl(ParaEl, 'br');
- AppendText(ParaEl, UTF8Decode(Decl.Expr.getDeclaration(true)));
+ Decl := TPasElement(SortedList[i]);
+ TREl := CreateTR(TableEl);
+ CodeEl := CreateCode(CreatePara(CreateTD_vtop(TREl)));
+ AppendHyperlink(CodeEl, Decl);
+ AppendShortDescrCell(TREl, Decl);
end;
+ finally
+ SortedList.Free;
end;
-
+end;
+
+procedure THTMLWriter.CreateModuleResStringsPage(aModule : TPasModule);
+var
+ ParaEl: TDOMElement;
+ i: Integer;
+ Decl: TPasResString;
+begin
+ AppendMenuBar(ResstrSubindex);
+ AppendTitle(UTF8Decode(Format(SDocUnitTitle + ': %s', [AModule.Name, SDocResStrings])));
+ for i := 0 to AModule.InterfaceSection.ResStrings.Count - 1 do
+ begin
+ Decl := TPasResString(AModule.InterfaceSection.ResStrings[i]);
+ CreateEl(ContentElement, 'a')['name'] := UTF8Decode(LowerCase(Decl.Name));
+ ParaEl := CreatePara(ContentElement);
+ AppendText(CreateCode(ParaEl), UTF8Decode(Decl.Name));
+ CreateEl(ParaEl, 'br');
+ AppendText(ParaEl, UTF8Decode(Decl.Expr.getDeclaration(true)));
+ end;
+end;
+
+
+procedure THTMLWriter.CreateModulePageBody(AModule: TPasModule;
+ ASubpageIndex: Integer);
begin
case ASubpageIndex of
0:
- CreateMainPage;
+ CreateModuleMainPage(aModule);
ResstrSubindex:
- CreateResStringsPage;
+ CreateModuleResStringsPage(aModule);
ConstsSubindex:
- CreateSimpleSubpage(UTF8Decode(SDocConstants), AModule.InterfaceSection.Consts);
+ CreateModuleSimpleSubpage(aModule, ConstsSubindex,UTF8Decode(SDocConstants), AModule.InterfaceSection.Consts);
TypesSubindex:
- CreateSimpleSubpage(UTF8Decode(SDocTypes), AModule.InterfaceSection.Types);
+ CreateModuleSimpleSubpage(aModule, TypesSubindex,UTF8Decode(SDocTypes), AModule.InterfaceSection.Types);
ClassesSubindex:
- CreateSimpleSubpage(UTF8Decode(SDocClasses), AModule.InterfaceSection.Classes);
+ CreateModuleSimpleSubpage(aModule, ClassesSubindex,UTF8Decode(SDocClasses), AModule.InterfaceSection.Classes);
ProcsSubindex:
- CreateSimpleSubpage(UTF8Decode(SDocProceduresAndFunctions), AModule.InterfaceSection.Functions);
+ CreateModuleSimpleSubpage(aModule, ProcsSubindex, UTF8Decode(SDocProceduresAndFunctions), AModule.InterfaceSection.Functions);
VarsSubindex:
- CreateSimpleSubpage(UTF8Decode(SDocVariables), AModule.InterfaceSection.Variables);
+ CreateModuleSimpleSubpage(aModule, VarsSubindex,UTF8Decode(SDocVariables), AModule.InterfaceSection.Variables);
IndexSubIndex:
CreateModuleIndexPage(AModule);
end;
@@ -2447,11 +1396,11 @@ var
begin
AppendMenuBar(-1);
AppendTitle(UTF8Decode(AConst.Name),AConst.Hints);
- AppendShortDescr(CreatePara(BodyElement), AConst);
- AppendText(CreateH2(BodyElement), UTF8Decode(SDocDeclaration));
- AppendSourceRef(AConst);
+ AppendShortDescr(CreatePara(ContentElement), AConst);
+ AppendText(CreateH2(ContentElement), UTF8Decode(SDocDeclaration));
+ AppendSourceRef(ContentElement,AConst);
- TableEl := CreateTable(BodyElement);
+ TableEl := CreateTable(ContentElement);
CodeEl := CreateCode(CreatePara(CreateTD(CreateTR(TableEl))));
AppendKw(CodeEl, 'const');
@@ -2524,7 +1473,7 @@ begin
if AType.InheritsFrom(TPasProcedureType) then
begin
AppendSym(AppendType(CodeEl, TableEl, TPasType(AType), True), ';');
- AppendProcArgsSection(BodyElement, TPasProcedureType(AType));
+ AppendProcArgsSection(ContentElement, TPasProcedureType(AType));
end else
// Record
if AType.ClassType = TPasRecordType then
@@ -2579,11 +1528,11 @@ var
begin
AppendMenuBar(-1);
AppendTitle(UTF8Decode(AType.Name),AType.Hints);
- AppendShortDescr(CreatePara(BodyElement), AType);
- AppendText(CreateH2(BodyElement), UTF8Decode(SDocDeclaration));
- AppendSourceRef(AType);
+ AppendShortDescr(CreatePara(ContentElement), AType);
+ AppendText(CreateH2(ContentElement), UTF8Decode(SDocDeclaration));
+ AppendSourceRef(ContentElement,AType);
- TableEl := CreateTable(BodyElement);
+ TableEl := CreateTable(ContentElement);
TREl := CreateTR(TableEl);
TDEl := CreateTD(TREl);
CodeEl := CreateCode(CreatePara(TDEl));
@@ -2753,35 +1702,46 @@ begin
AppendTitle(UTF8Decode(aText),Hints);
end;
-procedure THTMLWriter.CreateClassPageBody(AClass: TPasClassType;
- ASubpageIndex: Integer);
+procedure THTMLWriter.AppendTitle(const AText: DOMString; Hints : TPasMemberHints = []);
+
+Var
+ T : UnicodeString;
+begin
+ T:=AText;
+ if (Hints<>[]) then
+ T:=T+' ('+UTF8Decode(Engine.HintsToStr(Hints))+')';
+ AppendText(TitleElement, AText);
+ AppendText(CreateH1(ContentElement), T);
+end;
+
+
+procedure THTMLWriter.AppendClassMemberListLink(aClass : TPasClassType; ParaEl : TDomElement; AListSubpageIndex: Integer; const AText: DOMString);
+
var
- ParaEl: TDOMElement;
+ LinkEl: TDOMElement;
+begin
+ if FUseMenuBrackets then
+ AppendText(ParaEl, '[');
+ LinkEl := CreateEl(ParaEl, 'a');
+ LinkEl['href'] :=UTF8Decode(FixHtmlPath(ResolveLinkWithinPackage(AClass, AListSubpageIndex)));
+ LinkEl['onClick'] := 'window.open(''' + LinkEl['href'] + ''', ''list'', ' +
+ '''dependent=yes,resizable=yes,scrollbars=yes,height=400,width=300''); return false;';
+ AppendText(LinkEl, AText);
+ AppendText(ParaEl, ' (');
+ LinkEl := CreateEl(ParaEl, 'a');
+ LinkEl['href'] :=UTF8Decode(FixHtmlPath(ResolveLinkWithinPackage(AClass, AListSubpageIndex + 1)));
+ LinkEl['onClick'] := 'window.open(''' + LinkEl['href'] + ''', ''list'', ' +
+ '''dependent=yes,resizable=yes,scrollbars=yes,height=400,width=300''); return false;';
+ AppendText(LinkEl, UTF8Decode(SDocByName));
+ AppendText(ParaEl, ')');
+ if FUseMenuBrackets then
+ AppendText(ParaEl, '] ')
+ else
+ AppendText(ParaEl, ' ');
+end;
- procedure AppendMemberListLink(AListSubpageIndex: Integer;
- const AText: DOMString);
- var
- LinkEl: TDOMElement;
- begin
- if FUseMenuBrackets then
- AppendText(ParaEl, '[');
- LinkEl := CreateEl(ParaEl, 'a');
- LinkEl['href'] :=UTF8Decode(FixHtmlPath(ResolveLinkWithinPackage(AClass, AListSubpageIndex)));
- LinkEl['onClick'] := 'window.open(''' + LinkEl['href'] + ''', ''list'', ' +
- '''dependent=yes,resizable=yes,scrollbars=yes,height=400,width=300''); return false;';
- AppendText(LinkEl, AText);
- AppendText(ParaEl, ' (');
- LinkEl := CreateEl(ParaEl, 'a');
- LinkEl['href'] :=UTF8Decode(FixHtmlPath(ResolveLinkWithinPackage(AClass, AListSubpageIndex + 1)));
- LinkEl['onClick'] := 'window.open(''' + LinkEl['href'] + ''', ''list'', ' +
- '''dependent=yes,resizable=yes,scrollbars=yes,height=400,width=300''); return false;';
- AppendText(LinkEl, UTF8Decode(SDocByName));
- AppendText(ParaEl, ')');
- if FUseMenuBrackets then
- AppendText(ParaEl, '] ')
- else
- AppendText(ParaEl, ' ');
- end;
+
+procedure THTMLWriter.CreateClassMainPage(aClass : TPasClassType);
procedure AppendGenericTypes(CodeEl : TDomElement; AList : TFPList; isSpecialize : Boolean);
@@ -2799,264 +1759,268 @@ var
AppendSym(CodeEl, '>');
end;
- procedure CreateMainPage;
- var
- TableEl, TREl, TDEl, CodeEl: TDOMElement;
- i: Integer;
- ThisInterface,
- ThisClass: TPasClassType;
- ThisTreeNode: TPasElementNode;
- begin
- //WriteLn('@ClassPageBody.CreateMainPage Class=', AClass.Name);
- AppendMenuBar(-1);
- AppendTitle(UTF8Decode(AClass.Name),AClass.Hints);
- ParaEl := CreatePara(BodyElement);
- AppendMemberListLink(PropertiesByInheritanceSubindex, UTF8Decode(SDocProperties));
- AppendMemberListLink(MethodsByInheritanceSubindex, UTF8Decode(SDocMethods));
- AppendMemberListLink(EventsByInheritanceSubindex, UTF8Decode(SDocEvents));
+var
+ ParaEl,TableEl, TREl, TDEl, CodeEl: TDOMElement;
+ i: Integer;
+ ThisInterface,
+ ThisClass: TPasClassType;
+ ThisTreeNode: TPasElementNode;
+begin
+ //WriteLn('@ClassPageBody.CreateMainPage Class=', AClass.Name);
+ AppendMenuBar(-1);
+ AppendTitle(UTF8Decode(AClass.Name),AClass.Hints);
+
+ ParaEl := CreatePara(ContentElement);
+ AppendClassMemberListLink(aClass,ParaEl,PropertiesByInheritanceSubindex, UTF8Decode(SDocProperties));
+ AppendClassMemberListLink(aClass,ParaEl,MethodsByInheritanceSubindex, UTF8Decode(SDocMethods));
+ AppendClassMemberListLink(aClass,ParaEl,EventsByInheritanceSubindex, UTF8Decode(SDocEvents));
- AppendShortDescr(CreatePara(BodyElement), AClass);
- AppendText(CreateH2(BodyElement), UTF8Decode(SDocDeclaration));
- AppendSourceRef(AClass);
+ AppendShortDescr(CreatePara(ContentElement), AClass);
+ AppendText(CreateH2(ContentElement), UTF8Decode(SDocDeclaration));
+ AppendSourceRef(ContentElement,AClass);
- TableEl := CreateTable(BodyElement);
+ TableEl := CreateTable(ContentElement);
+ TREl := CreateTR(TableEl);
+ TDEl := CreateTD(TREl);
+ CodeEl := CreateCode(CreatePara(TDEl));
+ AppendKw(CodeEl, 'type');
+ if AClass.GenericTemplateTypes.Count>0 then
+ AppendKw(CodeEl, ' generic ');
+ AppendText(CodeEl, ' ' + UTF8Decode(AClass.Name) + ' ');
+ if AClass.GenericTemplateTypes.Count>0 then
+ AppendGenericTypes(CodeEl,AClass.GenericTemplateTypes,false);
+ AppendSym(CodeEl, '=');
+ AppendText(CodeEl, ' ');
+ AppendKw(CodeEl, UTF8Decode(ObjKindNames[AClass.ObjKind]));
+
+ if Assigned(AClass.AncestorType) then
+ begin
+ AppendSym(CodeEl, '(');
+ 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, ')');
+ end;
+ CreateMemberDeclarations(AClass, AClass.Members,TableEl, not AClass.IsShortDefinition);
+
+ AppendText(CreateH2(ContentElement), UTF8Decode(SDocInheritance));
+ TableEl := CreateTable(ContentElement);
+
+ // Now we are using only TreeClass for show inheritance
+
+ ThisClass := AClass; ThisTreeNode := Nil;
+ if AClass.ObjKind = okInterface then
+ ThisTreeNode := TreeInterface.GetPasElNode(AClass)
+ else
+ ThisTreeNode := TreeClass.GetPasElNode(AClass);
+ while True do
+ begin
TREl := CreateTR(TableEl);
- TDEl := CreateTD(TREl);
+ TDEl := CreateTD_vtop(TREl);
+ TDEl['align'] := 'center';
CodeEl := CreateCode(CreatePara(TDEl));
- AppendKw(CodeEl, 'type');
- if AClass.GenericTemplateTypes.Count>0 then
- AppendKw(CodeEl, ' generic ');
- AppendText(CodeEl, ' ' + UTF8Decode(AClass.Name) + ' ');
- if AClass.GenericTemplateTypes.Count>0 then
- AppendGenericTypes(CodeEl,AClass.GenericTemplateTypes,false);
- AppendSym(CodeEl, '=');
- AppendText(CodeEl, ' ');
- AppendKw(CodeEl, UTF8Decode(ObjKindNames[AClass.ObjKind]));
-
- if Assigned(AClass.AncestorType) then
- begin
- AppendSym(CodeEl, '(');
- 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, ')');
- end;
- CreateMemberDeclarations(AClass, AClass.Members,TableEl, not AClass.IsShortDefinition);
- AppendText(CreateH2(BodyElement), UTF8Decode(SDocInheritance));
- TableEl := CreateTable(BodyElement);
-
- // Now we are using only TreeClass for show inheritance
+ // Show class item
+ if Assigned(ThisClass) Then
+ AppendHyperlink(CodeEl, ThisClass);
+ //else
+ // AppendHyperlink(CodeEl, ThisTreeNode);
+ // Show links to class interfaces
+ if Assigned(ThisClass) and (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;
+ // short class description
+ if Assigned(ThisClass) then
+ AppendShortDescrCell(TREl, ThisClass);
- ThisClass := AClass; ThisTreeNode := Nil;
- if AClass.ObjKind = okInterface then
- ThisTreeNode := TreeInterface.GetPasElNode(AClass)
+ if Assigned(ThisTreeNode) then
+ if Assigned(ThisTreeNode.ParentNode) then
+ begin
+ TDEl := CreateTD(CreateTR(TableEl));
+ TDEl['align'] := 'center';
+ AppendText(TDEl, '|');
+ ThisClass := ThisTreeNode.ParentNode.Element;
+ ThisTreeNode := ThisTreeNode.ParentNode;
+ end
+ else
+ begin
+ ThisClass := nil;
+ ThisTreeNode:= nil;
+ break;
+ end
else
- ThisTreeNode := TreeClass.GetPasElNode(AClass);
- while True do
+ break;
+ end;
+ FinishElementPage(AClass);
+end;
+
+procedure THTMLWriter.CreateClassInheritanceSubpage(aClass : TPasClassType; AFilter: TMemberFilter);
+
+var
+ ThisClass: TPasClassType;
+ i: Integer;
+ Member: TPasElement;
+ TableEl, TREl, TDEl, ParaEl, LinkEl: TDOMElement;
+begin
+ TableEl := CreateTable(ContentElement);
+ ThisClass := AClass;
+ while True do
+ begin
+ TREl := CreateTR(TableEl);
+ TDEl := CreateTD(TREl);
+ TDEl['colspan'] := '3';
+ CreateTD(TREl);
+ LinkEl := AppendHyperlink(CreateEl(CreateCode(CreatePara(TDEl)), 'b'), ThisClass);
+ if Assigned(LinkEl) then
+ LinkEl['onClick'] := 'opener.location.href = ''' + LinkEl['href'] +
+ '''; return false;';
+ for i := 0 to ThisClass.Members.Count - 1 do
begin
+ Member := TPasElement(ThisClass.Members[i]);
+ if Not (Engine.ShowElement(Member) and AFilter(Member)) then
+ continue;
TREl := CreateTR(TableEl);
- TDEl := CreateTD_vtop(TREl);
- TDEl['align'] := 'center';
- CodeEl := CreateCode(CreatePara(TDEl));
+ ParaEl := CreatePara(CreateTD(TREl));
+ case Member.Visibility of
+ visPrivate:
+ AppendText(ParaEl, 'pv');
+ visProtected:
+ AppendText(ParaEl, 'pt');
+ visPublished:
+ AppendText(ParaEl, 'pl');
+ else
+ end;
+ AppendNbSp(ParaEl, 1);
- // Show class item
- if Assigned(ThisClass) Then
- AppendHyperlink(CodeEl, ThisClass);
- //else
- // AppendHyperlink(CodeEl, ThisTreeNode);
- // Show links to class interfaces
- if Assigned(ThisClass) and (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;
- // short class description
- if Assigned(ThisClass) then
- AppendShortDescrCell(TREl, ThisClass);
+ ParaEl := CreateTD(TREl);
+ if (Member.ClassType = TPasProperty) and
+ (Length(TPasProperty(Member).WriteAccessorName) = 0) then
+ begin
+ AppendText(ParaEl, 'ro');
+ AppendNbSp(ParaEl, 1);
+ end;
- if Assigned(ThisTreeNode) then
- if Assigned(ThisTreeNode.ParentNode) then
- begin
- TDEl := CreateTD(CreateTR(TableEl));
- TDEl['align'] := 'center';
- AppendText(TDEl, '|');
- ThisClass := ThisTreeNode.ParentNode.Element;
- ThisTreeNode := ThisTreeNode.ParentNode;
- end
- else
- begin
- ThisClass := nil;
- ThisTreeNode:= nil;
- break;
- end
- else
- break;
+ LinkEl := AppendHyperlink(CreatePara(CreateTD(TREl)), Member);
+ if Assigned(LinkEl) then
+ LinkEl['onClick'] := 'opener.location.href = ''' + LinkEl['href'] +
+ '''; return false;';
end;
- FinishElementPage(AClass);
+ if (not Assigned(ThisClass.AncestorType)) or
+ (not (ThisClass.AncestorType.ClassType.inheritsfrom(TPasClassType))) then
+ break;
+ ThisClass := TPasClassType(ThisClass.AncestorType);
+ AppendNbSp(CreatePara(CreateTD(CreateTR(TableEl))), 1);
end;
+end;
- procedure CreateInheritanceSubpage(AFilter: TMemberFilter);
- var
- ThisClass: TPasClassType;
- i: Integer;
- Member: TPasElement;
- TableEl, TREl, TDEl, ParaEl, LinkEl: TDOMElement;
- begin
- TableEl := CreateTable(BodyElement);
+procedure THTMLWriter.CreateClassSortedSubpage(AClass: TPasClassType; AFilter: TMemberFilter);
+var
+ List: TFPList;
+ ThisClass: TPasClassType;
+ i, j: Integer;
+ Member: TPasElement;
+ ParaEl, TableEl, TREl, TDEl, LinkEl: TDOMElement;
+
+begin
+ List := TFPList.Create;
+ try
ThisClass := AClass;
while True do
begin
- TREl := CreateTR(TableEl);
- TDEl := CreateTD(TREl);
- TDEl['colspan'] := '3';
- CreateTD(TREl);
- LinkEl := AppendHyperlink(CreateEl(CreateCode(CreatePara(TDEl)), 'b'), ThisClass);
- if Assigned(LinkEl) then
- LinkEl['onClick'] := 'opener.location.href = ''' + LinkEl['href'] +
- '''; return false;';
for i := 0 to ThisClass.Members.Count - 1 do
begin
Member := TPasElement(ThisClass.Members[i]);
- if Not (Engine.ShowElement(Member) and AFilter(Member)) then
- continue;
- TREl := CreateTR(TableEl);
- ParaEl := CreatePara(CreateTD(TREl));
- case Member.Visibility of
- visPrivate:
- AppendText(ParaEl, 'pv');
- visProtected:
- AppendText(ParaEl, 'pt');
- visPublished:
- AppendText(ParaEl, 'pl');
- else
- end;
- AppendNbSp(ParaEl, 1);
-
- ParaEl := CreateTD(TREl);
- if (Member.ClassType = TPasProperty) and
- (Length(TPasProperty(Member).WriteAccessorName) = 0) then
+ if Engine.ShowElement(Member) and AFilter(Member) then
begin
- AppendText(ParaEl, 'ro');
- AppendNbSp(ParaEl, 1);
+ j := 0;
+ while (j < List.Count) and
+ (CompareText(TPasElement(List[j]).Name, Member.Name) < 0) do
+ Inc(j);
+ List.Insert(j, Member);
end;
-
- LinkEl := AppendHyperlink(CreatePara(CreateTD(TREl)), Member);
- if Assigned(LinkEl) then
- LinkEl['onClick'] := 'opener.location.href = ''' + LinkEl['href'] +
- '''; return false;';
end;
if (not Assigned(ThisClass.AncestorType)) or
(not (ThisClass.AncestorType.ClassType.inheritsfrom(TPasClassType))) then
break;
ThisClass := TPasClassType(ThisClass.AncestorType);
- AppendNbSp(CreatePara(CreateTD(CreateTR(TableEl))), 1);
end;
- end;
- procedure CreateSortedSubpage(AFilter: TMemberFilter);
- var
- List: TFPList;
- ThisClass: TPasClassType;
- i, j: Integer;
- Member: TPasElement;
- TableEl, TREl, TDEl, ParaEl, LinkEl: TDOMElement;
- begin
- List := TFPList.Create;
- try
- ThisClass := AClass;
- while True do
- begin
- for i := 0 to ThisClass.Members.Count - 1 do
- begin
- Member := TPasElement(ThisClass.Members[i]);
- if Engine.ShowElement(Member) and AFilter(Member) then
- begin
- j := 0;
- while (j < List.Count) and
- (CompareText(TPasElement(List[j]).Name, Member.Name) < 0) do
- Inc(j);
- List.Insert(j, Member);
- end;
- end;
- if (not Assigned(ThisClass.AncestorType)) or
- (not (ThisClass.AncestorType.ClassType.inheritsfrom(TPasClassType))) then
- break;
- ThisClass := TPasClassType(ThisClass.AncestorType);
+ TableEl := CreateTable(ContentElement);
+ for i := 0 to List.Count - 1 do
+ begin
+ Member := TPasElement(List[i]);
+ TREl := CreateTR(TableEl);
+ ParaEl := CreatePara(CreateTD(TREl));
+ case Member.Visibility of
+ visPrivate:
+ AppendText(ParaEl, 'pv');
+ visProtected:
+ AppendText(ParaEl, 'pt');
+ visPublished:
+ AppendText(ParaEl, 'pl');
+ else
end;
+ AppendNbSp(ParaEl, 1);
- TableEl := CreateTable(BodyElement);
- for i := 0 to List.Count - 1 do
+ ParaEl := CreatePara(CreateTD(TREl));
+ if (Member.ClassType = TPasProperty) and
+ (Length(TPasProperty(Member).WriteAccessorName) = 0) then
begin
- Member := TPasElement(List[i]);
- TREl := CreateTR(TableEl);
- ParaEl := CreatePara(CreateTD(TREl));
- case Member.Visibility of
- visPrivate:
- AppendText(ParaEl, 'pv');
- visProtected:
- AppendText(ParaEl, 'pt');
- visPublished:
- AppendText(ParaEl, 'pl');
- else
- end;
+ AppendText(ParaEl, 'ro');
AppendNbSp(ParaEl, 1);
-
- ParaEl := CreatePara(CreateTD(TREl));
- if (Member.ClassType = TPasProperty) and
- (Length(TPasProperty(Member).WriteAccessorName) = 0) then
- begin
- AppendText(ParaEl, 'ro');
- AppendNbSp(ParaEl, 1);
- end;
-
- TDEl := CreateTD(TREl);
- TDEl['nowrap'] := 'nowrap';
- ParaEl := CreatePara(TDEl);
- LinkEl := AppendHyperlink(ParaEl, Member);
- if Assigned(LinkEl) then
- LinkEl['onClick'] := 'opener.location.href = ''' + LinkEl['href'] +
- '''; return false;';
- AppendText(ParaEl, ' (');
- LinkEl := AppendHyperlink(ParaEl, Member.Parent);
- if Assigned(LinkEl) then
- LinkEl['onClick'] := 'opener.location.href = ''' + LinkEl['href'] +
- '''; return false;';
- AppendText(ParaEl, ')');
end;
- finally
- List.Free;
+
+ TDEl := CreateTD(TREl);
+ TDEl['nowrap'] := 'nowrap';
+ ParaEl := CreatePara(TDEl);
+ LinkEl := AppendHyperlink(ParaEl, Member);
+ if Assigned(LinkEl) then
+ LinkEl['onClick'] := 'opener.location.href = ''' + LinkEl['href'] +
+ '''; return false;';
+ AppendText(ParaEl, ' (');
+ LinkEl := AppendHyperlink(ParaEl, Member.Parent);
+ if Assigned(LinkEl) then
+ LinkEl['onClick'] := 'opener.location.href = ''' + LinkEl['href'] +
+ '''; return false;';
+ AppendText(ParaEl, ')');
end;
+ finally
+ List.Free;
end;
+end;
+
+procedure THTMLWriter.CreateClassPageBody(AClass: TPasClassType; ASubpageIndex: Integer);
begin
case ASubpageIndex of
0:
- CreateMainPage;
+ CreateClassMainPage(aClass);
PropertiesByInheritanceSubindex:
- CreateInheritanceSubpage(@PropertyFilter);
+ CreateClassInheritanceSubpage(aClass,@PropertyFilter);
PropertiesByNameSubindex:
- CreateSortedSubpage(@PropertyFilter);
+ CreateClassSortedSubpage(aClass,@PropertyFilter);
MethodsByInheritanceSubindex:
- CreateInheritanceSubpage(@MethodFilter);
+ CreateClassInheritanceSubpage(aClass,@MethodFilter);
MethodsByNameSubindex:
- CreateSortedSubpage(@MethodFilter);
+ CreateClassSortedSubpage(aClass,@MethodFilter);
EventsByInheritanceSubindex:
- CreateInheritanceSubpage(@EventFilter);
+ CreateClassInheritanceSubpage(aClass,@EventFilter);
EventsByNameSubindex:
- CreateSortedSubpage(@EventFilter);
+ CreateClassSortedSubpage(aClass,@EventFilter);
end;
end;
@@ -3200,11 +2164,11 @@ var
begin
AppendMenuBar(-1);
AppendTitle(UTF8Decode(AElement.FullName),AElement.Hints);
- AppendShortDescr(CreatePara(BodyElement), AElement);
- AppendText(CreateH2(BodyElement), SDocDeclaration);
- AppendSourceRef(AElement);
+ AppendShortDescr(CreatePara(ContentElement), AElement);
+ AppendText(CreateH2(ContentElement), SDocDeclaration);
+ AppendSourceRef(ContentElement,AElement);
- TableEl := CreateTable(BodyElement);
+ TableEl := CreateTable(ContentElement);
TREl := CreateTR(TableEl);
CodeEl := CreateCode(CreatePara(CreateTD(TREl)));
AppendText(CodeEl, ' '); // !!!: Workaround for current HTML writer
@@ -3227,7 +2191,7 @@ begin
else if AElement is TPasType then
CreateTypePage(TPasType(AElement))
else
- AppendText(CreateWarning(BodyElement), '<' + AElement.ClassName + '>');
+ AppendText(CreateWarning(ContentElement), '<' + AElement.ClassName + '>');
FinishElementPage(AElement);
end;
@@ -3238,11 +2202,11 @@ var
begin
AppendMenuBar(-1);
AppendTitle(AVar.FullName,AVar.Hints);
- AppendShortDescr(CreatePara(BodyElement), AVar);
- AppendText(CreateH2(BodyElement), SDocDeclaration);
- AppendSourceRef(AVar);
+ AppendShortDescr(CreatePara(ContentElement), AVar);
+ AppendText(CreateH2(ContentElement), SDocDeclaration);
+ AppendSourceRef(ContentElement,AVar);
- TableEl := CreateTable(BodyElement);
+ TableEl := CreateTable(ContentElement);
TREl := CreateTR(TableEl);
TDEl := CreateTD(TREl);
CodeEl := CreateCode(CreatePara(TDEl));
@@ -3264,16 +2228,18 @@ begin
end;
procedure THTMLWriter.CreateProcPageBody(AProc: TPasProcedureBase);
+
var
TableEl, TREl, TDEl, CodeEl: TDOMElement;
+
begin
AppendMenuBar(-1);
AppendTitle(UTF8Decode(AProc.Name),AProc.Hints);
- AppendShortDescr(CreatePara(BodyElement), AProc);
- AppendText(CreateH2(BodyElement), SDocDeclaration);
- AppendSourceRef(AProc);
+ AppendShortDescr(CreatePara(ContentElement), AProc);
+ AppendText(CreateH2(ContentElement), SDocDeclaration);
+ AppendSourceRef(ContentElement,AProc);
- TableEl := CreateTable(BodyElement);
+ TableEl := CreateTable(ContentElement);
TREl := CreateTR(TableEl);
TDEl := CreateTD(TREl);
CodeEl := CreateCode(CreatePara(TDEl));
@@ -3310,22 +2276,22 @@ begin
if Cmd = '--html-search' then
SearchPage := Arg
else if Cmd = '--footer' then
- FooterHTML := ReadFile(Arg)
+ FFooterHTML := ReadFile(Arg)
else if Cmd = '--header' then
- HeaderHTML := ReadFile(Arg)
+ FHeaderHTML := ReadFile(Arg)
else if Cmd = '--navigator' then
- NavigatorHTML := ReadFile(Arg)
+ FNavigatorHTML := ReadFile(Arg)
else if Cmd = '--charset' then
CharSet := Arg
else if Cmd = '--index-colcount' then
IndexColCount := StrToIntDef(Arg,IndexColCount)
else if Cmd = '--image-url' then
- FBaseImageURL := Arg
+ BaseImageURL := Arg
else if Cmd = '--css-file' then
FCSSFile := arg
else if Cmd = '--footer-date' then
begin
- FIDF:=True;
+ FIncludeDateInFooter:=True;
FDateFormat:=Arg;
end
else if Cmd = '--disable-menu-brackets' then
diff --git a/utils/fpdoc/dw_markdown.pp b/utils/fpdoc/dw_markdown.pp
index 8b82e710dd..85cc29ba17 100644
--- a/utils/fpdoc/dw_markdown.pp
+++ b/utils/fpdoc/dw_markdown.pp
@@ -1,9 +1,8 @@
{
FPDoc - Free Pascal Documentation Tool
- Copyright (C) 2000 - 2005 by
- Areca Systems GmbH / Sebastian Guenther, sg@freepascal.org
+ Copyright (C) 2021 by Michael Van Canneyt
- * HTML/XHTML output generator
+ * Markdown generator, multi-file
See the file COPYING, included in this distribution,
for details about the copyright.
@@ -1909,13 +1908,19 @@ end;
class procedure TMarkdownWriter.Usage(List: TStrings);
begin
List.add('--header=file');
- List.Add(SHTMLUsageHeader);
+ List.Add(SMDUsageHeader);
List.add('--footer=file');
- List.Add(SHTMLUsageFooter);
+ List.Add(SMDUsageFooter);
List.Add('--index-colcount=N');
- List.Add(SHTMLIndexColcount);
+ List.Add(SMDIndexColcount);
List.Add('--image-url=url');
- List.Add(SHTMLImageUrl);
+ List.Add(SMDImageUrl);
+ List.Add('--theme=name');
+ List.Add(SMDTheme);
+ List.Add('--navigation=scheme');
+ List.Add(SMDNavigation);
+ List.Add(SMDNavSubtree);
+ List.Add(SMDNavTree);
end;
class procedure TMarkdownWriter.SplitImport(var AFilename, ALinkPrefix: String);
diff --git a/utils/fpdoc/dwriter.pp b/utils/fpdoc/dwriter.pp
index ddd7d09539..3d1e2103a9 100644
--- a/utils/fpdoc/dwriter.pp
+++ b/utils/fpdoc/dwriter.pp
@@ -186,10 +186,12 @@ type
procedure DescrEndTableRow; virtual; abstract;
procedure DescrBeginTableCell; virtual; abstract;
procedure DescrEndTableCell; virtual; abstract;
+
Property CurrentContext : TPasElement Read FContext ;
public
Constructor Create(APackage: TPasPackage; AEngine: TFPDocEngine); virtual;
destructor Destroy; override;
+ procedure AddModuleIdentifiers(AModule: TPasModule; L: TStrings);
property Engine : TFPDocEngine read FEngine;
Property Package : TPasPackage read FPackage;
Property Topics : TList Read FTopics;
@@ -526,6 +528,7 @@ begin
and (AModule.InterfaceSection.Classes.Count>0);
end;
+
procedure TMultiFileDocWriter.AddPages(AElement: TPasElement; ASubpageIndex: Integer;
AList: TFPList);
var
@@ -1028,6 +1031,22 @@ begin
Inherited;
end;
+procedure TFPDocWriter.AddModuleIdentifiers(AModule : TPasModule; L : TStrings);
+
+begin
+ if assigned(AModule.InterfaceSection) Then
+ begin
+ AddElementsFromList(L,AModule.InterfaceSection.Consts);
+ AddElementsFromList(L,AModule.InterfaceSection.Types);
+ AddElementsFromList(L,AModule.InterfaceSection.Functions);
+ AddElementsFromList(L,AModule.InterfaceSection.Classes);
+ AddElementsFromList(L,AModule.InterfaceSection.Variables);
+ AddElementsFromList(L,AModule.InterfaceSection.ResStrings);
+ end;
+end;
+
+
+
function TFPDocWriter.InterpretOption(const Cmd, Arg: String): Boolean;
begin
Result:=False;
diff --git a/utils/fpdoc/fpdoc.lpi b/utils/fpdoc/fpdoc.lpi
index c0fa9a2262..b9c99b0c3f 100644
--- a/utils/fpdoc/fpdoc.lpi
+++ b/utils/fpdoc/fpdoc.lpi
@@ -46,7 +46,7 @@
<PackageName Value="FCL"/>
</Item1>
</RequiredPackages>
- <Units Count="19">
+ <Units Count="20">
<Unit0>
<Filename Value="fpdoc.pp"/>
<IsPartOfProject Value="True"/>
@@ -130,6 +130,10 @@
<Filename Value="dw_basemd.pp"/>
<IsPartOfProject Value="True"/>
</Unit18>
+ <Unit19>
+ <Filename Value="dw_basehtml.pp"/>
+ <IsPartOfProject Value="True"/>
+ </Unit19>
</Units>
</ProjectOptions>
<CompilerOptions>
diff --git a/utils/fpdoc/fpdoc.pp b/utils/fpdoc/fpdoc.pp
index 0efc47add7..5e789409e1 100644
--- a/utils/fpdoc/fpdoc.pp
+++ b/utils/fpdoc/fpdoc.pp
@@ -37,7 +37,7 @@ uses
dw_man, // Man page writer
dw_linrtf, // linear RTF writer
dw_txt, // TXT writer
- fpdocproj, mkfpdoc, dw_basemd;
+ fpdocproj, mkfpdoc, dw_basemd, dw_basehtml;
Type
diff --git a/utils/fpdoc/fpdocclasstree.pp b/utils/fpdoc/fpdocclasstree.pp
index 91084de79f..ca25b2b75e 100644
--- a/utils/fpdoc/fpdocclasstree.pp
+++ b/utils/fpdoc/fpdocclasstree.pp
@@ -5,7 +5,7 @@ unit fpdocclasstree;
interface
uses
- Classes, SysUtils, dGlobals, pastree, contnrs, DOM ,XMLWrite;
+ Classes, SysUtils, dGlobals, pastree, contnrs{$IFDEF TREE_TEST}, DOM ,XMLWrite{$ENDIF};
Type