package es.xperiments.utils { import r1.deval.D; /** * @author xperiments */ public class PureASTemplate { private static var tplMap : Array = new Array(); private static var left : String = "<#"; private static var right : String = "#>"; //Delimiters can have regex special characters in them; the following two variables will hold escaped versions of them private static var escapedLeft : String = "<#"; private static var escapedRight : String = "#>"; private static var escapeRegex : RegExp = new RegExp( '(\\' + [ '$', '^', '?', '/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\' ].join( '|\\' ) + ')', 'g' ); private static var replaceLeft : RegExp = new RegExp( "<#", "g" ); private static var regexLeftRight : RegExp = new RegExp( "<#" + "|" + "#>", "g" ); private static var replaceSingleQuote : RegExp = new RegExp( "'", "g" ); private static var replaceLineBreak : RegExp = new RegExp( "\\r|\\n", "g" ); public static function parseTemplate( id : String, tpl : String, data : Object ):String { var unreplaceLineBreak : RegExp = new RegExp( "{lineBreak}", "g" ); var tplID : String = id; var tplObj : Object = tplMap[tplID]; if (!tplObj) { var leftjs : String = String.fromCharCode( 21 ); var leftjsout : String = leftjs + "="; tpl = tpl.replace( replaceLeft, left + leftjs ); var tplSplit : Array = tpl.split( regexLeftRight ); var js:String = "function "+id+"( data ) { "; js += "var output=''; var ld='" + left + "'; var rd='" + right + "'; "; for (var i : uint = 0; i < tplSplit.length ; i++) { var line : String = tplSplit[i]; if (PureASTemplate.stringStartsWith( line, leftjsout )) { js += " output+=" + line.substring( leftjsout.length ) + "; "; } else if (PureASTemplate.stringStartsWith( line, leftjs )) { js += " " + line.substring( leftjs.length ) + " "; } else { js += " output+='" + line.replace( replaceSingleQuote, "\\'" ).replace( replaceLineBreak, '{lineBreak}' ) + "'; "; } } js += " return output; }"; tplObj = D.parseFunctions( js ); tplMap[tplID] = tplObj; } return D.evalToString( id+'( data )', { data:data }, tplObj ).replace( unreplaceLineBreak, '\n' ); } public static function setDelimiters(l : String, r : String) : void { if (l != r) { left = l; escapedLeft = left.replace( escapeRegex, '\\$1' ); replaceLeft = new RegExp( escapedLeft, "g" ); right = r; escapedRight = right.replace( escapeRegex, '\\$1' ); regexLeftRight = new RegExp( escapedLeft + "|" + escapedRight, "g" ); } } private static function stringStartsWith(str : String, startsWith : String):Boolean { return str.substring( 0, startsWith.length ) == startsWith; } } }