PageRenderTime 28ms CodeModel.GetById 14ms app.highlight 11ms RepoModel.GetById 1ms app.codeStats 0ms

/branches/version1.x/app/JsPlate.js

http://jsdoc-toolkit.googlecode.com/
JavaScript | 135 lines | 111 code | 7 blank | 17 comment | 1 complexity | 760d780bf5924543a1b5a637c1baa834 MD5 | raw file
  1/**
  2 * @fileOverview
  3 * @name JsPlate
  4 * @author Michael Mathews micmath@gmail.com
  5 * @url $HeadURL: http://jsdoc-toolkit.googlecode.com/svn/branches/version1.x/app/JsPlate.js $
  6 * @revision $Id: JsPlate.js 389 2007-12-26 17:26:27Z micmath $
  7 * @license <a href="http://en.wikipedia.org/wiki/MIT_License">X11/MIT License</a>
  8 *          (See the accompanying README file for full details.)
  9
 10 */
 11
 12 /**
 13  * @class A lightweight template engine for JavaScript.
 14  * @constructor
 15  * @author Michael Mathews <a href="mailto:micmath@gmail.com">micmath@gmail.com</a>
 16  * @param {string} template
 17  */
 18JsPlate = function(templateFile) {
 19	if (templateFile) this.template = IO.readFile(templateFile);
 20	
 21	this.templateFile = templateFile;
 22	this.code = "";
 23	this.parse();
 24}
 25
 26
 27
 28/** Converts a template into evalable code. */
 29JsPlate.prototype.parse = function() {
 30	this.template = this.template.replace(/\{#[\s\S]+?#\}/gi, "");
 31	this.code = "var output=``"+this.template;
 32
 33	this.code = this.code.replace(
 34		/<for +each="(.+?)" +in="(.+?)" *>/gi, 
 35		function (match, eachName, inName) {
 36			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+=``";
 37		}
 38	);	
 39	this.code = this.code.replace(/<if test="(.+?)">/g, "``;\rif ($1) { output+=``");
 40	this.code = this.code.replace(/<\/(if|for)>/g, "``;\r};\routput+=``");
 41	this.code = this.code.replace(
 42		/\{\+\s*([\s\S]+?)\s*\+\}/gi,
 43		function (match, code) {
 44			code = code.replace(/"/g, "``"); // prevent qoute-escaping of inline code
 45			code = code.replace(/(\r?\n)/g, " ");
 46			return "``+"+code+"+``";
 47		}
 48	);
 49	this.code = this.code.replace(
 50		/\{!\s*([\s\S]+?)\s*!\}/gi,
 51		function (match, code) {
 52			code = code.replace(/"/g, "``"); // prevent qoute-escaping of inline code
 53			code = code.replace(/(\n)/g, " ");
 54			return "``; "+code+";\routput+=``";
 55		}
 56	);
 57	this.code = this.code+"``;";
 58
 59	this.code = this.code.replace(/(\r?\n)/g, "\\n");
 60	this.code = this.code.replace(/"/g, "\\\"");
 61	this.code = this.code.replace(/``/g, "\"");
 62}
 63
 64/**
 65 * @private
 66 */
 67JsPlate.prototype.toCode = function() {
 68	return this.code;
 69}
 70
 71/**
 72 * @private
 73 * @static
 74 * @memberOf JsPlate
 75 */
 76JsPlate.keys = function(obj) {
 77	var keys = [];
 78	// TODO: Confirm that arrays are not treated as objects
 79	if (obj.constructor.toString().indexOf("Array") > -1) {
 80		for (var i = 0; i < obj.length; i++) {
 81			keys.push(i);
 82		}
 83	}
 84	else {
 85		for (var i in obj) {
 86			keys.push(i);
 87		}
 88	}
 89	return keys;
 90};
 91
 92/**
 93 * @private
 94 * @static
 95 * @memberOf JsPlate
 96 */
 97JsPlate.values = function(obj) {
 98	var values = [];
 99	// TODO: Confirm that arrays are not treated as objects
100	if (obj.constructor.toString().indexOf("Array") > -1) {
101		for (var i = 0; i < obj.length; i++) {
102			values.push(obj[i]);
103		}
104	}
105	else {
106		for (var i in obj) {
107			values.push(obj[i]);
108		}
109	}
110	return values;
111};
112
113/**
114 * Return the output. This must be called after parse()
115 * @param {object} data What shall represent the "data" in your template.
116 * @return {string}
117 */
118JsPlate.prototype.process = function(data) {
119	var keys = JsPlate.keys;
120	var values = JsPlate.values;
121	
122	try {
123		eval(this.code);
124	}
125	catch (e) {
126		print(">> There was an error evaluating the compiled code from template: "+this.templateFile);
127		print("   The error was on line "+e.lineNumber+" "+e.name+": "+e.message);
128		var lines = this.code.split("\r");
129		if (e.lineNumber-2 >= 0) print("line "+(e.lineNumber-1)+": "+lines[e.lineNumber-2]);
130		print("line "+e.lineNumber+": "+lines[e.lineNumber-1]);
131		print("");
132	}
133	return output;
134	//print(this.code);
135}