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