6
static function loadTemplate() {
8
// load in current local/web directory
9
neko.io.File.getContent(neko.Web.getCwd()+"template.xml")
10
catch( e : Dynamic ) try {
11
// load in haxe subdirectory (TODO : make it work on linux/osx)
12
var p = ~/[\/\\]/g.split(neko.Sys.executablePath());
14
neko.io.File.getContent(p.join("/")+"/std/tools/template.xml");
15
} catch( e : Dynamic )
17
return Xml.parse(hdata);
20
static var default_template = "<html><body><data/></body></html>";
21
static var template = loadTemplate();
23
public var baseUrl : String;
24
var indexUrl : String;
25
var fileExtension : String;
26
var curpackage : String;
27
var filters : List<String>;
28
var typeParams : TypeParams;
30
public function new( baseUrl, fileExtension, indexUrl ) {
31
this.baseUrl = baseUrl;
32
this.fileExtension = fileExtension;
33
this.indexUrl = indexUrl;
35
typeParams = new Array();
38
public function output(str) {
42
public function addFilter(f) {
46
public function print(str, ?params : Dynamic ) {
48
for( f in Reflect.fields(params) )
49
str = StringTools.replace(str, "$"+f, Std.string(Reflect.field(params, f)));
53
public function process(t) {
54
processHtml(t,template);
57
public function filtered( path : Path, isPackage : Bool ) {
58
if( isPackage && path == "Remoting" )
60
if( StringTools.endsWith(path,"__") )
62
if( filters.isEmpty() )
65
if( StringTools.startsWith(path,x) )
70
function makeUrl( url, text, css ) {
71
return "<a href=\"" + baseUrl + url + fileExtension + "\" class=\""+css+"\">"+text+"</a>";
74
function prefix( arr : Array<String>, path : String ) {
76
for( i in 0...arr.length )
77
arr[i] = path + "." + arr[i];
81
function makePathUrl( path : Path, css ) {
82
var p = path.split(".");
84
var local = (p.join(".") == curpackage);
85
for( x in typeParams )
90
return makeUrl(p.join("/"),name,css);
91
return makeUrl(p.join("/"),fmtpath(path),css);
94
function fmtpath(path : String) {
95
if( path.substr(0,7) == "flash9." )
96
return "flash."+path.substr(7);
97
var pack = path.split(".");
98
if( pack.length > 1 && pack[pack.length-2].charAt(0) == "_" ) {
100
path = pack.join(".");
105
public function processHtml(t,html : Xml) {
106
var ht = html.nodeType;
107
if( ht == Xml.Element ) {
108
if( html.nodeName == "data" ) {
112
if( !html.iterator().hasNext() ) {
113
print(html.toString());
117
print(html.nodeName);
118
for( k in html.attributes() )
119
print(" "+k+"=\""+html.get(k)+"\"");
123
print("</"+html.nodeName+">");
124
} else if( ht == Xml.Document )
128
print(html.toString());
131
public function processPage(t) {
133
case TPackage(p,full,list):
134
processPackage(p,list);
136
var head = '<a href="#" onclick="javascript:history.back(-1); return false" class="index">Back</a> | '+makeUrl(indexUrl,"Index","index");
138
var inf = TypeApi.typeInfos(t);
139
typeParams = prefix(inf.params,inf.path);
140
var p = inf.path.split(".");
142
curpackage = p.join(".");
144
case TClassdecl(c): processClass(c);
145
case TEnumdecl(e): processEnum(e);
146
case TTypedecl(t): processTypedef(t);
147
case TPackage(_,_,_): throw "ASSERT";
153
function processPackage(name,list : Array<TypeTree> ) {
154
print('<ul class="entry">');
157
case TPackage(name,full,list):
158
if( filtered(full,true) )
160
var isPrivate = name.charAt(0) == "_";
162
print('<li><a href="#" class="package" onclick="return toggle(\'$id\')">$name</a><div id="$id" class="package_content">', { id : full.split(".").join("_"), name : name });
163
var old = curpackage;
165
processPackage(name,list);
168
print("</div></li>");
170
var i = TypeApi.typeInfos(e);
171
if( i.isPrivate || i.path == "@Main" || filtered(i.path,false) )
173
print("<li>"+makePathUrl(i.path,"entry")+"</li>");
179
function processInfos(t : TypeInfos) {
180
if( t.module != null )
181
print('<div class="importmod">import $module</div>',{ module : t.module });
182
if( !t.platforms.isEmpty() ) {
183
print('<div class="platforms">Available in ');
184
display(t.platforms,output,", ");
187
if( t.doc != null ) {
188
print('<div class="classdoc">');
194
function processClass(c : Classdef) {
195
print('<div class="classname">');
201
keyword("interface");
204
print(fmtpath(c.path));
205
if( c.params.length != 0 ) {
207
print(c.params.join(", "));
211
if( c.superClass != null ) {
212
print('<div class="extends">extends ');
213
processPath(c.superClass.path,c.superClass.params);
216
for( i in c.interfaces ) {
217
print('<div class="implements">implements ');
218
processPath(i.path,i.params);
221
if( c.dynamic != null ) {
224
print('<div class="implements">implements ');
225
processPath("Dynamic",d);
231
processClassField(c.platforms,f,false);
232
for( f in c.statics )
233
processClassField(c.platforms,f,true);
237
function processClassField(platforms : Platforms,f : ClassField,stat) {
240
var oldParams = typeParams;
241
if( f.params != null )
242
typeParams = typeParams.concat(prefix(f.params,f.name));
244
if( stat ) keyword("static");
245
var isMethod = false;
247
case TFunction(args,ret):
248
if( f.get == RNormal && (f.set == RNormal || f.set == RF9Dynamic) ) {
250
if( f.set == RF9Dynamic )
251
keyword("f9dynamic");
254
if( f.params != null )
255
print("<"+f.params.join(", ")+">");
258
display(args,function(a) {
261
if( a.name != null && a.name != "" ) {
275
if( f.get != RNormal || f.set != RNormal )
276
print("("+rightsStr(f.get)+","+rightsStr(f.set)+")");
280
if( f.platforms.length != platforms.length ) {
281
print('<div class="platforms">Available in ');
282
display(f.platforms,output,", ");
289
if( f.params != null )
290
typeParams = oldParams;
293
function processEnum(e : Enumdef) {
294
print('<div class="classname">');
300
print(fmtpath(e.path));
301
if( e.params.length != 0 ) {
303
print(e.params.join(", "));
309
for( c in e.constructors ) {
312
if( c.args != null ) {
315
display(c.args,function(a) {
332
function processTypedef(t : Typedef) {
333
print('<div class="classname">');
337
print(fmtpath(t.path));
338
if( t.params.length != 0 ) {
340
print(t.params.join(", "));
345
if( t.platforms.length == 0 ) {
346
processTypedefType(t.type,t.platforms,t.platforms);
349
var platforms = new List();
350
for( p in t.platforms )
352
for( p in t.types.keys() ) {
353
var td = t.types.get(p);
354
var support = new List();
355
for( p2 in platforms )
356
if( TypeApi.typeEq(td,t.types.get(p2)) ) {
357
platforms.remove(p2);
360
if( support.length == 0 )
362
processTypedefType(td,t.platforms,support);
366
function processTypedefType(t,all,platforms) {
368
case TAnonymous(fields):
371
processClassField(all,{
379
platforms : platforms,
384
if( all.length != platforms.length ) {
385
print('<div class="platforms">Defined in ');
386
display(platforms,output,", ");
389
print('<div class="typedef">= ');
395
function processPath( path : Path, ?params : List<Type> ) {
396
print(makePathUrl(path,"type"));
397
if( params != null && !params.isEmpty() ) {
405
function processType( t : Type ) {
409
case TEnum(path,params):
410
processPath(path,params);
411
case TClass(path,params):
412
processPath(path,params);
413
case TTypedef(path,params):
414
processPath(path,params);
415
case TFunction(args,ret):
416
if( args.isEmpty() ) {
423
if( a.name != null && a.name != "" )
425
processTypeFun(a.t,true);
428
processTypeFun(ret,false);
429
case TAnonymous(fields):
432
display(fields,function(f) {
433
me.print(f.name+" : ");
439
processPath("Dynamic");
443
processPath("Dynamic",l);
448
function processTypeFun( t : Type, isArg ) {
449
var parent = switch( t ) { case TFunction(_,_): true; case TEnum(n,_): isArg && n == "Void"; default : false; };
457
function rightsStr(r) {
459
case RNormal: "default";
462
case RDynamic: "dynamic";
463
case RF9Dynamic: "f9dynamic";
467
function keyword(w) {
468
print('<span class="kwd">'+w+' </span>');
471
function processDoc(doc : String) {
475
// unixify line endings
476
doc = doc.split("\r\n").join("\n").split("\r").join("\n");
479
doc = ~/^([ \t]*)\*+/gm.replace(doc, "$1");
480
doc = ~/\**[ \t]*$/gm.replace(doc, "");
484
var tmp = new StringBuf();
485
var codes = new List();
486
while (rx.match(doc)) {
487
tmp.add( rx.matchedLeft() );
489
var code = rx.matchedRight();
492
while( i < code.length && brackets > 0 ) {
493
switch( code.charCodeAt(i++) ) {
498
doc = code.substr(i);
499
code = code.substr(0, i-1);
500
code = ~/&/g.replace(code, "&");
501
code = ~/</g.replace(code, "<");
502
code = ~/>/g.replace(code, ">");
503
var tag = "##__code__"+codes.length+"##";
504
if( code.indexOf('\n') != -1 ) {
508
codes.add(code.split("\t").join(" "));
518
// separate into paragraphs
519
var parts = ~/\n[ \t]*\n/g.split(tmp.toString());
520
if( parts.length == 1 )
523
doc = Lambda.map(parts,function(x) { return "<p>"+StringTools.trim(x)+"</p>"; }).join("\n");
525
// put back code parts
528
doc = doc.split("##__code__"+(i++)+"##").join(c);
532
function display<T>( l : List<T>, f : T -> Void, sep : String ) {