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  "No templateFile or Link sent to Template Contructor..";
26             
27         }
28         
29         
30         this.template = Gio.simple_read(this.templateFile);
31         this.templateName = GLib.path_get_basename(this.templateFile);
32         this.code = "";
33         this.parse();
34     }, 
35     Object,  {
36     
37
38         parse : function() {
39             
40             console.log("Parsing template? " + this.templateName);
41             
42             this.template = this.template.replace(/\{#[\s\S]+?#\}/gi, "");
43             this.code = "var output=``"+this.template;
44
45             this.code = this.code.replace(
46                 /<for +each="(.+?)" +in="(.+?)" *>/gi, 
47                 function (match, eachName, inName) {
48                     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+=``";
49                 }
50             );  
51             this.code = this.code.replace(/<if test="(.+?)">/g, "``;\rif ($1) { \routput+=``");
52             this.code = this.code.replace(/<else\s*\/>/g, "``;} \relse\r{ \routput+=``");
53             
54             this.code = this.code.replace(/<\/(if|for)>/g, "``;\r};\routput+=``");
55             
56             //File.write("/tmp/jstookit_eval_"+this.templateName+".4.js", this.code);
57             
58             this.code = this.code.replace(
59                 /\{\+\s*([\s\S]+?)\s*\+\}/gi,
60                 function (match, code) {
61                     code = code.replace(/"/g, "``"); // prevent qoute-escaping of inline code
62                     code = code.replace(/(\r?\n)/g, " ");
63                     return "``+ \r("+code+") +\r``";
64                 }
65             );
66             //File.write("/tmp/jstookit_eval_"+this.templateName+".6.js", this.code);
67             
68             this.code = this.code.replace(
69                 /\{!\s*([\s\S]+?)\s*!\}/gi,
70                 function (match, code) {
71                     code = code.replace(/"/g, "``"); // prevent qoute-escaping of inline code
72                     code = code.replace(/(\n)/g, " "); // remove quotes..
73                     return "``; "+code+";\routput+=``";
74                 }
75             );
76            //File.write("/tmp/jstookit_eval_"+this.templateName+".7.js", this.code);
77             this.code = this.code+"``;";
78
79             
80             
81             this.code = this.code.replace(/(\r?\n)/g, "\\n");
82             this.code = this.code.replace(/"/g, "\\\"");
83             
84             this.code = this.code.replace(/``/g, "\"");
85             this.code = this.code.replace(/\\r/g, "\n");
86             //File.write("/tmp/jstookit_eval_"+this.templateName+".9.js", this.code);
87             this.code = this.code.replace(/\r/g, "\n\n");
88             
89
90         },
91
92         toCode : function() {
93             return this.code;
94         },
95
96         keys : function(obj) {
97             var keys = [];
98             if (obj && obj.constructor.toString().indexOf("Array") > -1) {
99                 for (var i = 0; i < obj.length; i++) {
100                     keys.push(i);
101                 }
102             }
103             else {
104                 for (var i in obj) {
105                     keys.push(i);
106                 }
107             }
108             return keys;
109         },
110
111         values : function(obj) {
112             var values = [];
113             if (obj.constructor.toString().indexOf("Array") > -1) {
114                 for (var i = 0; i < obj.length; i++) {
115                     values.push(obj[i]);
116                 }
117             }
118             else {
119                 for (var i in obj) {
120                     values.push(obj[i]);
121                 }
122             }
123             
124             
125             return values;
126         },
127
128         process : function(data) {
129             
130             //console.log("processing template");
131             var keys = this.keys;
132             var values = this.values;
133             
134             var makeSortby = this.makeSortby;
135             var makeSignature =   XObject.createDelegate(this.makeSignature, this);
136             var summarize = this.summarize ;
137             var makeFuncSkel = this.makeFuncSkel;
138             var resolveLinks = this.resolveLinks;
139             var makeImage = this.makeImage;
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             try {
146                 eval(this.code);
147             } catch (e) {
148                  Gio.simple_write('/tmp/template.js', this.code);
149                  Seed.print('in /tmp/template.js');
150                 throw e;
151                 Seed.quit();
152             }
153             
154             
155             //File.write("/tmp/jstookit_eval.js", this.code);
156             //try {
157             //eval('include     "/tmp/jstookit_eval.js";');
158             //includeJs("/tmp/jstookit_eval.js");
159                 //eval(this.code);
160            // console.log("done eval of template");   
161             
162             return output;
163         },
164
165      
166         isdefined : function (typ) {
167             return typ != 'undefined';
168         },
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         },
175
176         /** make a symbol sorter by some attribute */
177         makeSortby : function(attribute) {
178             return function(a, b) {
179                 if (a[attribute] != undefined && b[attribute] != undefined) {
180                     a = a[attribute]; //.toLowerCase();
181                     b = b[attribute];//.toLowerCase();
182                     if (a < b) return -1;
183                     if (a > b) return 1;
184                     return 0;
185                 }
186             }
187         },
188         makeImage : function(alias) {
189             ///  http://library.gnome.org/devel/gtk/stable/notebook.png
190             var ns = alias.split('.').shift();
191             var cls = alias.split('.').pop().toLowerCase();
192             if (ns != 'Gtk' ) {
193                 return '';//ns;
194             }
195             return '<img class="class-picture" src="http://library.gnome.org/devel/gtk/stable/' + cls + '.png">';
196             
197             
198         },
199         
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             if (!str || typeof(str) == 'undefined') {
249                 return '';
250             }
251             
252             // gtk specific. now..
253             // @ -> bold.. - they are arguments..
254             
255             str = str.replace(/@([a-z_]+)/gi,
256                 function(match, symbolName) {
257                     return '<b>' + symbolName + '</b>';
258                 }
259             );
260             // constants.
261             str = str.replace(/%([a-z_]+)/gi,
262                 function(match, symbolName) {
263                     return '<b>' + symbolName + '</b>';
264                 }
265             );
266             
267             str = str.replace(/#([a-z_]+)/gi,
268                 function(match, symbolName) {
269                     return '<b>' + symbolName + '</b>';
270                     // this should do a lookup!!!!
271                     /// it could use data in the signature to find out..
272                     //return new Link().toSymbol(Template.data.ns + '.' + symbolName);
273                 }
274             );
275             
276             str = str.replace(/\n/gi, '<br/>');
277             
278             /*
279             str = str.replace(/\{@link ([^} ]+) ?\}/gi,
280                 function(match, symbolName) {
281                     return new Link().toSymbol(symbolName);
282                 }
283             );
284             */
285             /*
286             str = str.replace(/\{([a-z\.\/]+)\}/gi,
287                 function(match, symbolName) {
288                     //println("got match " + symbolName);
289                     bits = symbolName.split('/');
290                     var mret = '';
291                     for(var i = 0; i < bits.length; i++) {
292                         
293                         mret += (mret.length ? '&nbsp;|&nbsp;' : '') + new Link().toSymbol(bits[i]);
294                     }
295                     
296                     return mret; //new Link().toSymbol(symbolName);
297                 }
298             );
299             */
300             // look for aaaa.\S+  ??? this might work???
301             /*
302             str = str.replace(/\([a-z]+\.\S+)/gi,
303                 function(match, symbolName) {
304                     return new Link().toSymbol(symbolName);
305                 }
306             );
307             */
308             
309             return str;
310         }
311         
312         
313 });