7 class DocBuilder : Object
10 // extractable via JSON?
11 string VERSION = "1.0.0" { get set };
14 public DocBuilder (Packer p)
16 GLib.debug("Roo JsDoc Toolkit started at %s ", (new GLib.DateTime()).format("Y/m/d H:i:s"));
20 if (Options.cacheDirectory.length && !File.isDirectory(Options.cacheDirectory)) {
21 File.mkdir(Options.cacheDirectory)
24 Options.srcFiles = this._getSrcFiles();
25 this._parseSrcFiles();
26 this.symbolSet = Parser.symbols;
28 // this currently uses the concept of publish.js...
36 * create a list of files in this.srcFiles using list of directories / files in Options.src
40 _getSrcFiles : function()
46 ext = Options.ext.split(",").map(function($) {return $.toLowerCase()});
49 for (var i = 0; i < Options.src.length; i++) {
50 // add to sourcefiles..
51 if (!File.isDirectory(Options.src[i])) {
52 _this.srcFiles.push(Options.src[i]);
55 File.list(Options.src[i] ).forEach(function($) {
56 if (Options['exclude-src'].indexOf($) > -1) {
59 var thisExt = $.split(".").pop().toLowerCase();
60 if (ext.indexOf(thisExt) < 0) {
63 _this.srcFiles.push(Options.src[i] + '/' + $);
67 //Seed.print(JSON.stringify(this.srcFiles, null,4));Seed.quit();
71 * Parse the source files.
75 _parseSrcFiles : function()
79 for (var i = 0, l = this.srcFiles.length; i < l; i++) {
81 var srcFile = this.srcFiles[i];
84 var cacheFile = !Options.cacheDirectory.length ? false :
85 Options.cacheDirectory + srcFile.replace(/\//g, '_') + ".cache";
88 // disabled at present!@!!
90 if (cacheFile && File.exists(cacheFile)) {
93 var c_mt = File.mtime(cacheFile);
94 var o_mt = File.mtime(srcFile);
95 //println(c_mt.toSource());
96 // println(o_mt.toSource());
98 // this check does not appear to work according to the doc's - need to check it out.
100 if (c_mt > o_mt) { // cached time > original time!
101 // use the cached mtimes..
102 print("Read " + cacheFile);
103 var syms = JSON.parse(File.read(cacheFile), function(k, v) {
105 if (typeof(v) != 'object') {
108 if (typeof(v['*object']) == 'undefined') {
111 var cls = imports[v['*object']][v['*object']];
112 //print(v['*object']);
115 XObject.extend(ret, v);
120 //print("Add sybmols " + cacheFile);
121 for (var sy in syms._index) {
122 // print("ADD:" + sy );
123 Parser.symbols.addSymbol(syms._index[sy]);
131 Options.LOG.inform("reading : " + srcFile);
132 src = File.read(srcFile);
135 Options.LOG.warn("Can't read source file '"+srcFile+"': "+e.message);
139 var txs = new TextStream(src);
141 var tr = new TokenReader({ keepComments : true, keepWhite : true , sepIdents: false });
143 var ts = new TokenStream(tr.tokenize(txs));
145 Parser.parse(ts, srcFile);
148 File.write(cacheFile,
150 Parser.symbolsToObject(srcFile),
156 //var outstr = JSON.stringify(
157 // Parser.filesSymbols[srcFile]._index
159 //File.write(cacheFile, outstr);
172 publish : function() {
173 Options.LOG.inform("Publishing");
178 Options.LOG.inform("Making directories");
179 if (!File.isDirectory(Options.target))
180 File.mkdir(Options.target);
181 if (!File.isDirectory(Options.target+"/symbols"))
182 File.mkdir(Options.target+"/symbols");
183 if (!File.isDirectory(Options.target+"/symbols/src"))
184 File.mkdir(Options.target+"/symbols/src");
186 if (!File.isDirectory(Options.target +"/json")) {
187 File.mkdir(Options.target +"/json");
190 Options.LOG.inform("Copying files from static: " +Options.templateDir);
191 // copy everything in 'static' into
192 File.list(Options.templateDir + '/static').forEach(function (f) {
193 Options.LOG.inform("Copy " + Options.templateDir + '/static/' + f + ' to ' + Options.target + '/' + f);
194 File.copyFile(Options.templateDir + '/static/' + f, Options.target + '/' + f, Gio.FileCopyFlags.OVERWRITE);
198 Options.LOG.inform("Setting up templates");
199 // used to check the details of things being linked to
200 Link.symbolSet = this.symbolSet;
203 Link.srcFileFlatName = this.srcFileFlatName;
204 Link.srcFileRelName = this.srcFileRelName;
206 var classTemplate = new Template({
207 templateFile : Options.templateDir + "/class.html",
210 var classesTemplate = new Template({
211 templateFile : Options.templateDir +"/allclasses.html",
214 var classesindexTemplate = new Template({
215 templateFile : Options.templateDir +"/index.html",
218 var fileindexTemplate = new Template({
219 templateFile : Options.templateDir +"/allfiles.html",
224 classTemplate.symbolSet = this.symbolSet;
227 function hasNoParent($) {
228 return ($.memberOf == "")
230 function isaFile($) {
231 return ($.is("FILE"))
233 function isaClass($) {
234 return ($.is("CONSTRUCTOR") || $.isNamespace || $.isClass);
246 var symbols = this.symbolSet.toArray();
248 var files = Options.srcFiles;
250 for (var i = 0, l = files.length; i < l; i++) {
252 var targetDir = Options.target + "/symbols/src/";
253 this.makeSrcFile(file, targetDir);
255 //print(JSON.stringify(symbols,null,4));
257 var classes = symbols.filter(isaClass).sort(makeSortby("alias"));
259 //Options.LOG.inform("classTemplate Process : all classes");
261 // var classesIndex = classesTemplate.process(classes); // kept in memory
263 Options.LOG.inform("iterate classes");
267 for (var i = 0, l = classes.length; i < l; i++) {
268 var symbol = classes[i];
271 Options.LOG.inform("classTemplate Process : " + symbol.alias);
276 File.write(Options.target+"/symbols/" +symbol.alias+'.' + Options.publishExt ,
277 classTemplate.process(symbol));
279 jsonAll[symbol.alias] = this.publishJSON(symbol);
285 File.write(Options.target+"/json/roodata.json",
293 // regenrate the index with different relative links
295 //var classesIndex = classesTemplate.process(classes);
297 Options.LOG.inform("build index");
299 File.write(Options.target + "/index."+ Options.publishExt,
300 classesindexTemplate.process(classes)
303 // blank everything???? classesindexTemplate = classesIndex = classes = null;
307 var documentedFiles = symbols.filter(function ($) {
308 return ($.is("FILE"))
313 for (var i = 0; i < files.length; i++) {
314 allFiles.push(new Symbol(files[i], [], "FILE", new DocComment("/** */")));
317 for (var i = 0; i < documentedFiles.length; i++) {
318 var offset = files.indexOf(documentedFiles[i].alias);
319 allFiles[offset] = documentedFiles[i];
322 allFiles = allFiles.sort(makeSortby("name"));
323 Options.LOG.inform("write files index");
325 File.write(Options.target + "/files."+Options.publishExt,
326 fileindexTemplate.process(allFiles)
334 * JSON files are lookup files for the documentation
335 * - can be used by IDE's or AJAX based doc tools
339 publishJSON : function(data)
341 // what we need to output to be usefull...
343 var cfgProperties = [];
344 if (!data.comment.getTag('singleton').length) {
345 cfgProperties = data.configToArray();
346 cfgProperties = cfgProperties.sort(makeSortby("alias"));
350 //println(cfgProperties.toSource());
352 for(var i =0; i < cfgProperties.length;i++) {
353 p = cfgProperties[i];
359 memberOf : p.memberOf == data.alias ? '' : p.memberOf
362 add.optvals = p.optvalues;
368 var ownEvents = data.methods.filter( function(e){
369 return e.isEvent && !e.comment.getTag('hide').length;
370 }).sort(makeSortby("name"));
375 for(var i =0; i < ownEvents.length;i++) {
378 name : m.name.substring(1),
379 sig : this.makeFuncSkel(m.params),
385 var ownMethods = data.methods.filter( function(e){
386 return !e.isEvent && !e.comment.getTag('hide').length;
387 }).sort(makeSortby("name"));
392 for(var i =0; i < ownMethods.length;i++) {
396 sig : this.makeMethodSkel(m.params),
402 //println(props.toSource());
403 // we need to output:
424 srcFileRelName : function(sourceFile)
426 return sourceFile.substring(Options.baseDir.length+1);
428 srcFileFlatName: function(sourceFile)
430 var name = this.srcFileRelName(sourceFile);
431 name = name.replace(/\.\.?[\\\/]/g, "").replace(/[\\\/]/g, "_");
432 return name.replace(/\:/g, "_") + '.html'; //??;
436 makeSrcFile: function(sourceFile)
438 // this stuff works...
441 var name = this.srcFileFlatName(sourceFile);
443 Options.LOG.inform("Write Source file : " + Options.target+"/symbols/src/" + name);
444 var pretty = imports.PrettyPrint.toPretty(File.read( sourceFile));
445 File.write(Options.target+"/symbols/src/" + name,
447 '<title>' + sourceFile + '</title>' +
448 '<link rel="stylesheet" type="text/css" href="../../../css/highlight-js.css"/>' +
449 '</head><body class="highlightpage">' +
454 * used by JSON output to generate a function skeleton
456 makeFuncSkel :function(params) {
457 if (!params) return "function ()\n{\n\n}";
458 return "function (" +
461 return $.name.indexOf(".") == -1; // don't show config params in signature
463 ).map( function($) { return $.name == 'this' ? '_self' : $.name; } ).join(", ") +
466 makeMethodSkel :function(params) {
467 if (!params) return "()";
471 return $.name.indexOf(".") == -1; // don't show config params in signature
473 ).map( function($) { return $.type + " " +( $.name == 'this' ? '_self' : $.name ); } ).join(", ") +