JsTemplate/Template.js
[app.jsdoc] / 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  * @class Template 
12  * @scope JsTemplate
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, "\\r");
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, "\\r"); // 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         
178         makeSortby : function (attributeA, attributeB) {
179             return function(aa, bb) {
180                 var a,b;
181                 
182                 if (aa[attributeA] != undefined && bb[attributeA] != undefined) {
183                     a = aa[attributeA]; //.toLowerCase();
184                     b = bb[attributeA];//.toLowerCase();
185                     if (a < b) return -1;
186                     if (a > b) return 1;
187                     // same.. try attribute b..
188                 }
189                 if (attributeB && (aa[attributeB] != undefined && bb[attributeB] != undefined)) {
190                     a = aa[attributeB]; //.toLowerCase();
191                     b = bb[attributeB];//.toLowerCase();
192                     if (a < b) return -1;
193                     if (a > b) return 1;
194                     // same.. try attribute b..
195                 }
196                 
197                 return 0;
198             };
199         },
200         
201         
202         
203         makeImage : function(alias) {
204             ///  http://library.gnome.org/devel/gtk/stable/notebook.png
205             var ns = alias.split('.').shift();
206             var cls = alias.split('.').pop().toLowerCase();
207             if (ns != 'Gtk' ) {
208                 return '';//ns;
209             }
210             return '<img class="class-picture" src="http://library.gnome.org/devel/gtk/stable/' + cls + '.png">';
211             
212             
213         },
214         
215         
216
217         makeSignature : function(params) {
218             if (!params) return "()";
219             var Link = this.Link;
220             var signature = "(" +
221                 params.filter(
222                     function($) {
223                         return $.name.indexOf(".") == -1; // don't show config params in signature
224                     }
225                 ).map(
226                     function($) {
227                         $.defaultValue = typeof($.defaultValue) == 'undefined' ? false : $.defaultValue;
228                         
229                         return "" +
230                             ($.isOptional ? "[" : "") +
231                             (($.type) ? 
232                                 (new Link().toSymbol(
233                                     (typeof($.type) == 'object' ) ? 'Function' : $.type
234                                 )) + " " :  ""
235                             )   + 
236                             "<B><i>" +$.name + "</i></B>" +
237                             ($.defaultValue ? "=" +item.defaultValue : "") +
238                             ($.isOptional ? "]" : "");
239                         
240                          
241                     }
242                 ).join(", ")
243             +
244             ")";
245             return signature;
246         },
247
248         makeFuncSkel :  function(params) {
249             if (!params) return "function ()\n{\n\n}";
250             return "function (" +
251                 params.filter(
252                     function($) {
253                         return $.name.indexOf(".") == -1; // don't show config params in signature
254                     }
255                 ).map( function($) { return $.name == 'this' ? '_self' : $.name; } ).join(", ")
256             +
257             ")\n{\n\n}";
258             
259         },
260
261         /** Find symbol {@link ...} strings in text and turn into html links */
262         resolveLinks : function (str, from) {
263             if (!str || typeof(str) == 'undefined') {
264                 return '';
265             }
266             
267             // gtk specific. now..
268             // @ -> bold.. - they are arguments..
269             
270             str = str.replace(/@([a-z_]+)/gi,
271                 function(match, symbolName) {
272                     return '<b>' + symbolName + '</b>';
273                 }
274             );
275             // constants.
276             str = str.replace(/%([a-z_]+)/gi,
277                 function(match, symbolName) {
278                     return '<b>' + symbolName + '</b>';
279                 }
280             );
281             
282             str = str.replace(/#([a-z_]+)/gi,
283                 function(match, symbolName) {
284                     return '<b>' + symbolName + '</b>';
285                     // this should do a lookup!!!!
286                     /// it could use data in the signature to find out..
287                     //return new Link().toSymbol(Template.data.ns + '.' + symbolName);
288                 }
289             );
290             
291             str = str.replace(/\n/gi, '<br/>');
292             
293             /*
294             str = str.replace(/\{@link ([^} ]+) ?\}/gi,
295                 function(match, symbolName) {
296                     return new Link().toSymbol(symbolName);
297                 }
298             );
299             */
300             /*
301             str = str.replace(/\{([a-z\.\/]+)\}/gi,
302                 function(match, symbolName) {
303                     //println("got match " + symbolName);
304                     bits = symbolName.split('/');
305                     var mret = '';
306                     for(var i = 0; i < bits.length; i++) {
307                         
308                         mret += (mret.length ? '&nbsp;|&nbsp;' : '') + new Link().toSymbol(bits[i]);
309                     }
310                     
311                     return mret; //new Link().toSymbol(symbolName);
312                 }
313             );
314             */
315             // look for aaaa.\S+  ??? this might work???
316             /*
317             str = str.replace(/\([a-z]+\.\S+)/gi,
318                 function(match, symbolName) {
319                     return new Link().toSymbol(symbolName);
320                 }
321             );
322             */
323             
324             return str;
325         }
326         
327         
328 });