JSDOC/BuildDocs.js
[gnome.introspection-doc-generator] / JSDOC / BuildDocs.js
1 //<script type="text/javascript">
2 /**
3         This is the main container for the JSDOC application.
4         @namespace
5 */
6
7
8 XObject = imports.XObject.XObject;
9 File = imports.File.File;
10
11 Template = imports.JsTemplate.Template.Template;
12
13 Options = imports.Options.Options;
14 Parser   = imports.Parser.Parser;
15
16 TokenReader = imports.TokenReader.TokenReader;
17 TokenStream = imports.TokenStream.TokenStream;
18 Symbol = imports.Symbol.Symbol;
19 /******************    INCLUDES ARE ALL AT THE BOTTOM OF THIS FILE!!!!! *******************/
20
21 // should not realy be here -- or anywhere...??
22
23
24
25
26
27 BuildDocs = {
28     
29     VERSION : "2.0.0",
30     
31     
32     srcFiles : [],
33     
34     build : function ()
35     {
36          
37         Options.init();
38         
39         Options.LOG.inform("JsDoc Toolkit main() running at "+new Date()+".");
40         //Options.LOG.inform("With options: ");
41         
42         if (!File.isDirectory(Options.cacheDirectory)) {   
43             File.mkdir(Options.cacheDirectory)
44         }
45         
46         Options.srcFiles = this._getSrcFiles();
47         this._parseSrcFiles();
48         this.symbolSet = Parser.symbols;
49         
50         // this currently uses the concept of publish.js...
51              
52         this.publish();
53          
54         
55         
56     },
57     
58     
59     _getSrcFiles : function() 
60     {
61         this.srcFiles = [];
62         
63         var ext = ["js"];
64         if (Options.ext) {
65             ext = Options.ext.split(",").map(function($) {return $.toLowerCase()});
66         }
67         
68         for (var i = 0; i < Options.src.length; i++) {
69             this.srcFiles = this.srcFiles.concat(
70             
71                 File.list(Options.src[i] ).filter(
72                     function($) {
73                         var thisExt = $.split(".").pop().toLowerCase();
74                         return (ext.indexOf(thisExt) > -1); // || thisExt in JSDOC.handlers);
75                             // we're only interested in files with certain extensions
76                     }
77                 )
78             );
79         }
80         
81         return this.srcFiles;
82     },
83
84     _parseSrcFiles : function() 
85     {
86         Parser.init();
87         
88         for (var i = 0, l = this.srcFiles.length; i < l; i++) {
89             
90             var srcFile = this.srcFiles[i];
91             
92             
93             var cacheFile = Options.cacheDirectory + srcFile.replace(/\//g, '_') + ".cache";
94             
95             //println(cacheFile);
96             // disabled at present!@!!
97             
98             if (false && !Options.disablecache  && File.exists(cacheFile)) {
99                 // check filetime?
100                 
101                 var c_mt = File.getTimes(cacheFile);
102                 var o_mt = File.getTimes(srcFile);
103                 //println(c_mt.toSource());
104                // println(o_mt.toSource());
105                
106                 // this check does not appear to work according to the doc's - need to check it out.
107                
108                 if (c_mt[0] > o_mt[0]) { // cached time  > original time!
109                     // use the cached mtimes..
110                     var syms =  JSON.parse(File.read(cacheFile));
111                     
112                     throw "Conversion of cache not done yet!";
113                     
114                     for (var sy in syms) {
115                         //println("ADD:" + sy );
116                        Parser.symbols.addSymbol(syms[sy]);
117                     }
118                     continue;
119                 }
120             }
121             
122             var src = ''
123             try {
124                 src = File.read(srcFile);
125             }
126             catch(e) {
127                 LOG.warn("Can't read source file '"+srcFile+"': "+e.message);
128                 continue;
129             }
130
131              
132             var tr = new TokenReader();
133             var ts = new TokenStream(tr.tokenize(src));
134         
135             Parser.parse(ts, srcFile);
136               
137             //var outstr = JSON.stringify(
138             //    Parser.filesSymbols[srcFile]._index
139             //);
140             //File.write(cacheFile, outstr);
141              
142                 
143     //          }
144         }
145         
146         
147         
148         Parser.finish();
149     },
150     
151      
152         
153     publish  : function() {
154         
155          
156         // link!!!
157         
158         
159         
160         if (!File.exists(Options.target))
161             File.mkdir(Options.target);
162         if (!File.exists(Options.target+"/symbols"))
163             File.mkdir(Options.target+"/symbols");
164         if (!File.exists(Options.target+"/symbols/src"))
165             File.mkdir(Options.target+"/symbols/src");
166         
167         // copy everything in 'static' into 
168         File.list(Options.templatesDir + '/static').forEach(function (f) {
169             File.copy(Options.templatesDir + '/static/' + f, Options.target + '/' + f);
170         });
171         if (!File.isDirectory(Options.target +"/json")) {
172             File.makeDir(Options.target +"/json");
173         }
174         
175         // used to check the details of things being linked to
176         Link.symbolSet = symbolSet;
177         Link.base = "../";
178         
179         var classTemplate = new Template({
180              templateFile : Options.templatesDir  + "/class.tmpl",
181              Link : Link
182         });
183         var classesTemplate = new Template({
184             templateFile : Options.templatesDir +"/allclasses.tmpl",
185             Link : Link
186         });
187         var classesindexTemplate = new Template({
188             templateFile : Options.templatesDir +"/index.tmpl",
189             Link : Link
190         });
191         var fileindexTemplate = new Template({   
192             templateFile : Options.templatesDir +"/allfiles.tmpl",
193             Link: Link
194         });
195
196         
197         classTemplate.symbolSet = symbolSet;
198         
199         
200         function hasNoParent($) {
201             return ($.memberOf == "")
202         }
203         function isaFile($) {
204             return ($.is("FILE"))
205         }
206         function isaClass($) { 
207             return ($.is("CONSTRUCTOR") || $.isNamespace); 
208         }
209         
210         var symbols = symbolSet.toArray();
211         
212         var files = Options.srcFiles;
213         
214         for (var i = 0, l = files.length; i < l; i++) {
215             var file = files[i];
216             var targetDir = Options.target + "/symbols/src/";
217             this.makeSrcFile(file, targetDir);
218         }
219         
220         var classes = symbols.filter(isaClass).sort(makeSortby("alias"));
221          
222        var classesIndex = classesTemplate.process(classes); // kept in memory
223         
224         
225         
226         for (var i = 0, l = classes.length; i < l; i++) {
227             var symbol = classes[i];
228             var output = "";
229             
230             File.write(Options.target+"/symbols/" +symbol.alias+'.' + Options.publishExt ,
231                     classTemplate.process(symbol));
232             
233             print("write " + Options.target+"/symbols/" +symbol.alias+'.' + Options.publishExt);
234             
235             // dump out a 
236             
237             this.publishJSON(Options.target+"/json/",  symbol.alias+'.json', symbol)
238             
239             
240             
241         }
242         
243         // regenrate the index with different relative links
244         Link.base = "";
245         var classesIndex = classesTemplate.process(classes);
246         
247           
248         
249         File.write(Options.target +  "/index."+ Options.publishExt, 
250             classesindexTemplate.process(classes)
251         );
252         
253         // blank everything???? classesindexTemplate = classesIndex = classes = null;
254         
255  
256         
257         var documentedFiles = symbols.filter(function ($) {
258             return ($.is("FILE"))
259         });
260         
261         var allFiles = [];
262         
263         for (var i = 0; i < files.length; i++) {
264             allFiles.push(new  Symbol(files[i], [], "FILE", new JSDOC.DocComment("/** */")));
265         }
266         
267         for (var i = 0; i < documentedFiles.length; i++) {
268             var offset = files.indexOf(documentedFiles[i].alias);
269             allFiles[offset] = documentedFiles[i];
270         }
271             
272         allFiles = allFiles.sort(makeSortby("name"));
273         File.write(Options.target , "/files."+Options.publishExt, 
274             fileindexTemplate.process(allFiles)
275         );
276         
277     },
278
279     publishJSON : function(file, data)
280     {
281         // what we need to output to be usefull...
282         // a) props..
283         var cfgProperties = [];
284         if (!data.comment.getTag('singleton').length) {
285             cfgProperties = data.configToArray();
286             cfgProperties = cfgProperties.sort(makeSortby("name"));
287             
288         }
289         var props = []; 
290         //println(cfgProperties.toSource());
291         var p ='';
292         for(var i =0; i < cfgProperties.length;i++) {
293             p = cfgProperties[i];
294             props.push( {
295                 name : p.name,
296                 type : p.type,
297                 desc : p.desc,
298                 memberOf : p.memberOf == data.alias ? '' : p.memberOf
299             });
300         }
301         
302          
303         var ownEvents = data.methods.filter( function(e){
304                 return e.isEvent && !e.comment.getTag('hide').length;
305             }).sort(makeSortby("name"));
306              
307         
308         var events = [];
309         var m;
310         for(var i =0; i < ownEvents.length;i++) {
311             m = ownEvents[i];
312             events.push( {
313                 name : m.name.substring(1),
314                 sig : makeFuncSkel(m.params),
315                 type : 'function',
316                 desc : m.desc
317             });
318         }
319         //println(props.toSource());
320         // we need to output:
321         //classname => {
322         //    propname => 
323         //        type=>
324         //        desc=>
325         //    }
326
327         var ret = {
328             props : props,
329             events: events
330         };
331         File.write(file, JSON.stringify(ret, null, 2 ));
332         
333         
334         // b) methods
335         // c) events
336         
337         
338     },
339     makeSrcFile: function(sourceFile) 
340     {
341         
342         
343         name = sourceFile.substring(Options.baseDir.length);
344         name = name.replace(/\.\.?[\\\/]/g, "").replace(/[\\\/]/g, "_");
345         name = name.replace(/\:/g, "_"); //??
346         
347         
348         var pretty = imports.PrettyPrint.toPretty(File.read(sourceFile));
349         File.write(Options.target+"/symbols/src/" + name, 
350             '<html><head>' +
351             '<title>' + sourceFile + '</title>' +
352             '<link rel="stylesheet" type="text/css" href="../../../highlight-js.css"/>' + 
353             '</head><body class="highlightpage">' +
354             pretty +
355             '</body></html>');
356     }
357      
358     
359 };
360   
361
362
363
364
365
366  
367
368
369
370