generate gjs documentation, run under gjs
[gnome.introspection-doc-generator] / JsTemplate / Template.js
1 //<script type="text/javscript">
2
3 const Gio     = imports.gi.Gio;
4 const GLib    = imports.gi.GLib;
5
6 const XObject = imports.XObject.XObject;
7 const console = imports.console.console;
8
9 const File    = imports.File.File;
10
11 /**
12  * Template 
13  * 
14  * 
15  */
16
17 var Template = XObject.define(
18
19     function(cfg) {
20         XObject.extend(this, cfg);
21
22         //this.templateFile = templateFile;
23
24         if (!this.templateFile || !this.Link) {
25             throw  "No templateFile or Link sent to Template Constructor..";
26         }
27         //console.log("this.templateFile: " + this.templateFile);
28
29         //this.template     = Gio.simple_read(this.templateFile);
30         this.template     = File.read(this.templateFile);
31         //console.log("this.template: " + this.template);
32
33         this.templateName = GLib.path_get_basename(this.templateFile);
34         this.code = "";
35         this.parse();
36     },
37
38     Object,
39
40     {
41         parse : function() {
42
43             console.log("Parsing template: " + this.templateName);
44             this.template = this.template.replace(/\{#[\s\S]+?#\}/gi, "");
45             this.code     = "var output=``" + this.template;
46
47             this.code = this.code.replace(
48                 /<for +each="(.+?)" +in="(.+?)" *>/gi, 
49                 function (match, eachName, inName) {
50                     return "``;\rvar $"+eachName+"_keys = keys("+inName+");\rfor(var $"+eachName+"_i = 0; $"+eachName+"_i < $"+eachName+"_keys.length; $"+eachName+"_i++) {\rvar $"+eachName+"_last = ($"+eachName+"_i == $"+eachName+"_keys.length-1);\rvar $"+eachName+"_key = $"+eachName+"_keys[$"+eachName+"_i];\rvar "+eachName+" = "+inName+"[$"+eachName+"_key];\routput+=``";
51                 }
52             );
53
54             this.code = this.code.replace(/<if test="(.+?)">/g, "``;\rif ($1) { \routput+=``");
55             this.code = this.code.replace(/<else\s*\/>/g, "``;} \relse\r{ \routput+=``");
56
57             this.code = this.code.replace(/<\/(if|for)>/g, "``;\r};\routput+=``");
58
59             //File.write("/tmp/jstookit_eval_"+this.templateName+".4.js", this.code);
60
61             this.code = this.code.replace(
62                 /\{\+\s*([\s\S]+?)\s*\+\}/gi,
63                 function (match, code) {
64                     code = code.replace(/"/g, "``"); // prevent qoute-escaping of inline code
65                     code = code.replace(/(\r?\n)/g, " ");
66                     return "``+ \r("+code+") +\r``";
67                 }
68             );
69             //File.write("/tmp/jstookit_eval_"+this.templateName+".6.js", this.code);
70
71             this.code = this.code.replace(
72                 /\{!\s*([\s\S]+?)\s*!\}/gi,
73                 function (match, code) {
74                     code = code.replace(/"/g, "``"); // prevent qoute-escaping of inline code
75                     code = code.replace(/(\n)/g, " "); // remove quotes..
76                     return "``; "+code+";\routput+=``";
77                 }
78             );
79            //File.write("/tmp/jstookit_eval_"+this.templateName+".7.js", this.code);
80             this.code = this.code+"``;";
81
82             this.code = this.code.replace(/(\r?\n)/g, "\\n");
83             this.code = this.code.replace(/"/g, "\\\"");
84
85             this.code = this.code.replace(/``/g, "\"");
86             this.code = this.code.replace(/\\r/g, "\n");
87             //File.write("/tmp/jstookit_eval_"+this.templateName+".9.js", this.code);
88             this.code = this.code.replace(/\r/g, "\n\n");
89         },
90
91         toCode : function() {
92             return this.code;
93         },
94
95         keys : function(obj) {
96             var keys = [];
97             if (obj && obj.constructor.toString().indexOf("Array") > -1) {
98                 for (var i = 0; i < obj.length; i++) {
99                     keys.push(i);
100                 }
101             }
102             else {
103                 for (var i in obj) {
104                     keys.push(i);
105                 }
106             }
107             return keys;
108         },
109
110         values : function(obj) {
111             var values = [];
112             if (obj.constructor.toString().indexOf("Array") > -1) {
113                 for (var i = 0; i < obj.length; i++) {
114                     values.push(obj[i]);
115                 }
116             }
117             else {
118                 for (var i in obj) {
119                     values.push(obj[i]);
120                 }
121             }
122             
123             
124             return values;
125         },
126
127         process : function(data) {
128             
129             //console.log("processing template");
130             var keys          = this.keys;
131             var values        = this.values;
132             
133             var makeSortby    = this.makeSortby;
134             var makeSignature = XObject.createDelegate(this.makeSignature, this);
135             var summarize     = this.summarize ;
136             var makeFuncSkel  = this.makeFuncSkel;
137             var resolveLinks  = this.resolveLinks;
138             var makeImage     = this.makeImage;
139
140             // usefull for cross refing..
141             Template.data = data;
142
143             var Link = this.Link;
144             //var Options = imports.Options ? imports.Options.Options : false;
145
146             try {
147                 eval(this.code);
148             } catch (e) {
149                  //Gio.simple_write('/tmp/template.js', this.code);
150                  File.write('/tmp/template.js', this.code);
151                  //Seed.print('in /tmp/template.js');
152                  console.log('in /tmp/template.js');
153                  //throw e;
154                  //Seed.quit();
155             }
156
157             //File.write("/tmp/jstookit_eval.js", this.code);
158             //try {
159             //eval('include     "/tmp/jstookit_eval.js";');
160             //includeJs("/tmp/jstookit_eval.js");
161                 //eval(this.code);
162             // console.log("done eval of template");
163
164             return output;
165         },
166
167         isdefined : function (typ) {
168             return typ != 'undefined';
169         },
170
171         summarize : function(desc) {
172             if (typeof desc != "undefined")
173                 return desc.match(/([\w\W]+?\.)[^a-z0-9]/i)? RegExp.$1 : desc;
174             else
175                 return '';
176         },
177
178         /** make a symbol sorter by some attribute */
179         makeSortby : function(attribute) {
180             return function(a, b) {
181                 if (a[attribute] != undefined && b[attribute] != undefined) {
182                     a = a[attribute]; //.toLowerCase();
183                     b = b[attribute];//.toLowerCase();
184                     if (a < b) return -1;
185                     if (a > b) return  1;
186                     //return 0;
187                 }
188                 return 0;
189             }
190         },
191
192         makeImage : function(alias) {
193             ///  http://library.gnome.org/devel/gtk/stable/notebook.png
194             var ns  = alias.split('.').shift();
195             var cls = alias.split('.').pop().toLowerCase();
196             if (ns != 'Gtk' ) {
197                 return '';//ns;
198             }
199             return '<img class="class-picture" src="http://library.gnome.org/devel/gtk/stable/' + cls + '.png">';
200         },
201
202         makeSignature : function(params) {
203             if (!params) return "()";
204             var Link = this.Link;
205             var signature = "(" +
206                 params.filter(
207                     function($) {
208                         return $.name.indexOf(".") == -1; // don't show config params in signature
209                     }
210                 ).map(
211                     function($) {
212                         $.defaultValue = typeof($.defaultValue) == 'undefined' ? false : $.defaultValue;
213                         
214                         return "" +
215                             ($.isOptional ? "[" : "") +
216                             (($.type) ? 
217                                 (new Link().toSymbol(
218                                     (typeof($.type) == 'object' ) ? 'Function' : $.type
219                                 )) + " " :  ""
220                             )   + 
221                             "<B><i>" +$.name + "</i></B>" +
222                             ($.defaultValue ? "=" +item.defaultValue : "") +
223                             ($.isOptional ? "]" : "");
224                         
225                          
226                     }
227                 ).join(", ")
228             +
229             ")";
230             return signature;
231         },
232
233         makeFuncSkel :  function(params) {
234             if (!params) return "function ()\n{\n\n}";
235             return "function (" +
236                 params.filter(
237                     function($) {
238                         return $.name.indexOf(".") == -1; // don't show config params in signature
239                     }
240                 ).map( function($) { return $.name == 'this' ? '_self' : $.name; } ).join(", ")
241             +
242             ")\n{\n\n}";
243
244         },
245
246         /** Find symbol {@link ...} strings in text and turn into html links */
247         resolveLinks : function (str, from) {
248
249             if (!str || typeof(str) == 'undefined') {
250                 return '';
251             }
252
253             // gtk specific. now..
254             // @ -> bold.. - they are arguments..
255
256             str = str.replace(/@([a-z_]+)/gi,
257                 function(match, symbolName) {
258                     return '<b>' + symbolName + '</b>';
259                 }
260             );
261
262             // constants.
263             str = str.replace(/%([a-z_]+)/gi,
264                 function(match, symbolName) {
265                     return '<b>' + symbolName + '</b>';
266                 }
267             );
268
269             str = str.replace(/#([a-z_]+)/gi,
270                 function(match, symbolName) {
271                     return '<b>' + symbolName + '</b>';
272                     // this should do a lookup!!!!
273                     /// it could use data in the signature to find out..
274                     //return new Link().toSymbol(Template.data.ns + '.' + symbolName);
275                 }
276             );
277
278             str = str.replace(/\n/gi, '<br/>');
279
280             /*
281             str = str.replace(/\{@link ([^} ]+) ?\}/gi,
282                 function(match, symbolName) {
283                     return new Link().toSymbol(symbolName);
284                 }
285             );
286             */
287             /*
288             str = str.replace(/\{([a-z\.\/]+)\}/gi,
289                 function(match, symbolName) {
290                     //println("got match " + symbolName);
291                     bits = symbolName.split('/');
292                     var mret = '';
293                     for(var i = 0; i < bits.length; i++) {
294                         
295                         mret += (mret.length ? '&nbsp;|&nbsp;' : '') + new Link().toSymbol(bits[i]);
296                     }
297                     
298                     return mret; //new Link().toSymbol(symbolName);
299                 }
300             );
301             */
302             // look for aaaa.\S+  ??? this might work???
303             /*
304             str = str.replace(/\([a-z]+\.\S+)/gi,
305                 function(match, symbolName) {
306                     return new Link().toSymbol(symbolName);
307                 }
308             );
309             */
310
311             return str;
312         }
313 });