7 class DocBuilder : Object
10 // extractable via JSON?
11 public string VERSION = "1.0.0" { get set };
14 private Packer packer;
16 public DocBuilder (Packer p)
20 GLib.debug("Roo JsDoc Toolkit started at %s ", (new GLib.DateTime()).format("Y/m/d H:i:s"));
24 if (PackerRun.opt_tmp_dir != null && !FileUtils.test(PackerRun.opt_tmp_dir, GLib.FileTest.IS_DIR)) {
25 Posix.mkdir(PackerRun.opt_tmp_dir, 0700);
31 this.symbolSet = DocParser.symbols;
33 // this currently uses the concept of publish.js...
41 * Parse the source files.
45 private void parseSrcFiles()
50 var useCache = PackerRun.opt_cache_dir == null ;
53 for (var i = 0, l = this.packer.files.size; i < l; i++) {
55 var srcFile = this.packer.files.get(i);
59 cacheFile = PackerRun.opt_cache_dir + srcFile.replace(/\//g, '_') + ".cache";
62 // disabled at present!@!!
64 if (GLib.FileUtils.test(cacheFile, GLib.FileTest.EXISTS)) {
66 var cache_mt = File.new_for_path (cacheFile).queryInfo(FileAttribute.TIME_MODIFIED,
67 GLib.FileQueryInfoFlags.NONE, null).
68 get_modification_time();
69 var original_mt = File.new_for_path (sourceInfo).queryInfo(FileAttribute.TIME_MODIFIED,
70 GLib.FileQueryInfoFlags.NONE, null).
71 get_modification_time();
72 // this check does not appear to work according to the doc's - need to check it out.
74 if (cache_mt > original_mt) { // cached time > original time!
75 // use the cached mtimes..
76 GLib.debug("Read %s" , cacheFile);
77 var parser = new Json.Parser();
78 parser.load_from_file(cacheFile);
79 var ar = parser.get_root ().get_array();
81 for(var i = 0;i < ar.get_length();i++) {
82 var o = ar.get_object_element(i);
83 var sym = Json.gobject_from_data(typeof(Symbol), o) as Symbol;
84 DocParser.symbols.add(sym);
93 GLib.debug("reading : %s" , srcFile);
94 src = GLib.FileUtils.get_contents(srcFile);
96 catch(GLib.FileError e) {
97 GLib.debug("Can't read source file '%s': %s", srcFile, e.to_string());
103 var tr = new TokenReader(this.packer);
106 tr.keepComments = true;
107 tr.sepIdents = false;
108 tr.collapseWhite = false;
112 var toks = tr.tokenize( new TextStream(src);
113 if (PackerRun.opt_dump_tokens) {
116 //GLib.Process.exit(0);
120 var ts = new TokenStream(toks);
125 DocParser.parse(ts, srcFile);
129 var ar = DocParser.symbolsToObject(srcFile);
131 var builder = new Json.Builder ();
132 builder.begin_array ();
133 for (var i=0;i<ar.size;i++) {
135 builder.add_object_value (ar.get(i));
137 builder.end_array ();
138 Json.Generator generator = new Json.Generator ();
139 Json.Node root = builder.get_root ();
140 generator.set_root (root);
141 generator.pretty= true;
143 generator.to_file(cacheFile);
157 publish : function() {
158 GLib.debug("Publishing");
163 GLib.debug("Making directories");
164 if (!File.isDirectory(PackerRun.opt_doc_target)) {
165 Posix.mkdir(PackerRun.opt_doc_target,0755);
167 if (!File.isDirectory(PackerRun.opt_doc_target+"/symbols")) {
168 Posix.mkdir(PackerRun.opt_doc_target+"/symbols",0755);
170 if (!File.isDirectory(PackerRun.opt_doc_target+"/symbols/src")) {
171 Posix.mkdir(PackerRun.opt_doc_target+"/symbols/src",075);
173 if (!File.isDirectory(PackerRun.opt_doc_target +"/json")) {
174 File.mkdir(PackerRun.opt_doc_target +"/json",0755);
177 GLib.debug("Copying files from static: %s " , PackerRun.opt_doc_template_dir);
178 // copy everything in 'static' into
180 var iter = GLib.File.new_from_path(PackerRun.opt_doc_template_dir + "/static")..enumerate_children (
182 FileQueryInfoFlags.NOFOLLOW_SYMLINKS,
186 while ( (info = enumerator.next_file (null)) != null)) {
187 if (info.get_file_type () == FileType.DIRECTORY) {
190 var src = .File.new_from_path(info.get_name());
191 GLib.debug("Copy %s to %s/%s" , info.get_name() , f, PackerRun.opt_doc_target , src.get_basename());
194 GLib.File.new_from_path(PackerRun.opt_doc_target + '/' + src.get_basename()),
195 GLib.FileCopyFlags.OVERWRITE,
200 GLib.debug("Setting up templates");
201 // used to check the details of things being linked to
202 Link.symbolSet = this.symbolSet;// need to work out where 'symbolset will be stored/set!
205 Link.srcFileFlatName = this.srcFileFlatName; // where set?
206 Link.srcFileRelName = this.srcFileRelName; // where set?
208 var classTemplate = new Template( PackerRun.opt_doc_template_dir + "/class." + PackerRun.opt_doc_ext );
209 var classesTemplate = new Template( PackerRun.opt_doc_template_dir+"/allclasses." + PackerRun.opt_doc_ext );
210 var classesindexTemplate = new Template( PackerRun.opt_doc_template_dir +"/index." + PackerRun.opt_doc_ext );
211 var fileindexTemplate = new Template( PackerRun.opt_doc_template_dir +"/allfiles."+ PackerRun.opt_doc_ext );
214 classTemplate.symbolSet = this.symbolSet; // where?
217 function hasNoParent($) {
218 return ($.memberOf == "")
220 function isaFile($) {
221 return ($.is("FILE"))
223 function isaClass($) {
224 return ($.is("CONSTRUCTOR") || $.isNamespace || $.isClass);
236 var symbols = this.symbolSet.toArray();
238 var files = this.packer.files;
240 for (var i = 0, l = files.size; i < l; i++) {
241 var file = files.get(i);
242 var targetDir = PackerRun.opt_doc_target + "/symbols/src/";
243 this.makeSrcFile(file, targetDir);
245 //print(JSON.stringify(symbols,null,4));
246 var classes = new Gee.ArrayList<Symbol>();
248 for(var symbol in symbol) {
249 if (symbol.isaClass()) {
250 classes.add(symbol).;
253 classes.sort( (a,b) => {
254 return a.alias.collate(b.alias);
257 //GLib.debug("classTemplate Process : all classes");
259 // var classesIndex = classesTemplate.process(classes); // kept in memory
261 GLib.debug("iterate classes");
263 var jsonAll = new JSON.Object();
265 for (var i = 0, l = classes.size; i < l; i++) {
266 var symbol = classes.get(i);
269 GLib.debug("classTemplate Process : %s" , symbol.alias);
274 FileUtils.set_contents(
275 PackerRun.opt_doc_target+"/symbols/" +symbol.alias+'.' + PackerRun.opt_doc_ext ,
276 classTemplate.process(symbol)
279 jsonAll.set_object_member(symbol.alias, this.publishJSON(symbol));
282 Json.Generator generator = new Json.Generator ();
283 generator.set_root (jsonAll.get_node());
284 generator.pretty= true;
286 generator.to_file(PackerRun.opt_doc_target+"/json/roodata.json",);
290 // regenrate the index with different relative links
292 //var classesIndex = classesTemplate.process(classes);
294 GLib.debug("build index");
296 FileUtils.set_contents(
297 PackerRun.opt_doc_target + "/index." _ PackerRun.opt_doc_ext
298 classesindexTemplate.process(classes)
301 // blank everything???? classesindexTemplate = classesIndex = classes = null;
305 var documentedFiles = symbols.filter(function ($) {
306 return ($.is("FILE"))
311 for (var i = 0; i < files.length; i++) {
312 allFiles.push(new Symbol(files[i], [], "FILE", new DocComment("/** *" + "/")));
315 for (var i = 0; i < documentedFiles.length; i++) {
316 var offset = files.indexOf(documentedFiles[i].alias);
317 allFiles[offset] = documentedFiles[i];
320 allFiles = allFiles.sort(makeSortby("name"));
321 GLib.debug("write files index");
323 FileUtils.set_contents(
324 PackerRun.opt_doc_target + "/files." + PackerRun.opt_doc_ext ,
325 fileindexTemplate.process(allFiles)
333 * JSON files are lookup files for the documentation
334 * - can be used by IDE's or AJAX based doc tools
338 JSON.Object publishJSON (Symbol data)
340 // what we need to output to be usefull...
342 var cfgProperties = new GLib.ArrayList<Symbol>();
343 if (!data.comment.getTag(DocTagTitle.SINGLETON).length) {
344 cfgProperties = data.configToArray();
345 cfgProperties = cfgProperties.sort((a,b) =>{
346 return a.alias.collate(b.alias);
352 //println(cfgProperties.toSource());
354 for(var i =0; i < cfgProperties.length;i++) {
355 p = cfgProperties[i];
361 memberOf : p.memberOf == data.alias ? '' : p.memberOf
364 add.optvals = p.optvalues;
370 var ownEvents = data.methods.filter( function(e){
371 return e.isEvent && !e.comment.getTag('hide').length;
372 }).sort(makeSortby("name"));
377 for(var i =0; i < ownEvents.length;i++) {
380 name : m.name.substring(1),
381 sig : this.makeFuncSkel(m.params),
387 var ownMethods = data.methods.filter( function(e){
388 return !e.isEvent && !e.comment.getTag('hide').length;
389 }).sort(makeSortby("name"));
394 for(var i =0; i < ownMethods.length;i++) {
398 sig : this.makeMethodSkel(m.params),
404 //println(props.toSource());
405 // we need to output:
426 srcFileRelName : function(sourceFile)
428 return sourceFile.substring(PackerRun.opt_real_basedir.length+1);
430 srcFileFlatName: function(sourceFile)
432 var name = this.srcFileRelName(sourceFile);
433 name = name.replace(/\.\.?[\\\/]/g, "").replace(/[\\\/]/g, "_");
434 return name.replace(/\:/g, "_") + '.html'; //??;
438 makeSrcFile: function(sourceFile)
440 // this stuff works...
443 var name = this.srcFileFlatName(sourceFile);
445 GLib.debug("Write Source file : " + PackerRun.opt_doc_target+"/symbols/src/" + name);
446 var pretty = imports.PrettyPrint.toPretty(File.read( sourceFile));
447 File.write(PackerRun.opt_doc_target+"/symbols/src/" + name,
449 '<title>' + sourceFile + '</title>' +
450 '<link rel="stylesheet" type="text/css" href="../../../css/highlight-js.css"/>' +
451 '</head><body class="highlightpage">' +
456 * used by JSON output to generate a function skeleton
458 makeFuncSkel :function(params) {
459 if (!params) return "function ()\n{\n\n}";
460 return "function (" +
463 return $.name.indexOf(".") == -1; // don't show config params in signature
465 ).map( function($) { return $.name == 'this' ? '_self' : $.name; } ).join(", ") +
468 makeMethodSkel :function(params) {
469 if (!params) return "()";
473 return $.name.indexOf(".") == -1; // don't show config params in signature
475 ).map( function($) { return $.type + " " +( $.name == 'this' ? '_self' : $.name ); } ).join(", ") +