doT.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. // doT.js
  2. // 2011, Laura Doktorova
  3. // https://github.com/olado/doT
  4. //
  5. // doT.js is an open source component of http://bebedo.com
  6. //
  7. // doT is a custom blend of templating functions from jQote2.js
  8. // (jQuery plugin) by aefxx (http://aefxx.com/jquery-plugins/jqote2/)
  9. // and underscore.js (http://documentcloud.github.com/underscore/)
  10. // plus extensions.
  11. //
  12. // Licensed under the MIT license.
  13. //
  14. (function() {
  15. var doT = { version : '0.1.7' };
  16. if (typeof module !== 'undefined' && module.exports) {
  17. module.exports = doT;
  18. } else {
  19. this.doT = doT;
  20. }
  21. doT.templateSettings = {
  22. evaluate: /\{\{([\s\S]+?)\}\}/g,
  23. interpolate: /\{\{=([\s\S]+?)\}\}/g,
  24. encode: /\{\{!([\s\S]+?)\}\}/g,
  25. use: /\{\{#([\s\S]+?)\}\}/g, //compile time evaluation
  26. define: /\{\{##\s*([\w\.$]+)\s*(\:|=)([\s\S]+?)#\}\}/g, //compile time defs
  27. conditionalStart: /\{\{\?([\s\S]+?)\}\}/g,
  28. conditionalEnd: /\{\{\?\}\}/g,
  29. varname: 'it',
  30. strip : true,
  31. append: true
  32. };
  33. function resolveDefs(c, block, def) {
  34. return ((typeof block === 'string') ? block : block.toString())
  35. .replace(c.define, function (match, code, assign, value) {
  36. if (code.indexOf('def.') === 0) {
  37. code = code.substring(4);
  38. }
  39. if (!(code in def)) {
  40. if (assign === ':') {
  41. def[code]= value;
  42. } else {
  43. eval("def[code]=" + value);
  44. }
  45. }
  46. return '';
  47. })
  48. .replace(c.use, function(match, code) {
  49. var v = eval(code);
  50. return v ? resolveDefs(c, v, def) : v;
  51. });
  52. }
  53. doT.template = function(tmpl, c, def) {
  54. c = c || doT.templateSettings;
  55. var cstart = c.append ? "'+(" : "';out+=(", // optimal choice depends on platform/size of templates
  56. cend = c.append ? ")+'" : ");out+='";
  57. var str = (c.use || c.define) ? resolveDefs(c, tmpl, def || {}) : tmpl;
  58. str = ("var out='" +
  59. ((c.strip) ? str.replace(/\s*<!\[CDATA\[\s*|\s*\]\]>\s*|[\r\n\t]|(\/\*[\s\S]*?\*\/)/g, ''): str)
  60. .replace(/\\/g, '\\\\')
  61. .replace(/'/g, "\\'")
  62. .replace(c.interpolate, function(match, code) {
  63. return cstart + code.replace(/\\'/g, "'").replace(/\\\\/g,"\\").replace(/[\r\t\n]/g, ' ') + cend;
  64. })
  65. .replace(c.encode, function(match, code) {
  66. return cstart + code.replace(/\\'/g, "'").replace(/\\\\/g, "\\").replace(/[\r\t\n]/g, ' ') + ").toString().replace(/&(?!\\w+;)/g, '&#38;').split('<').join('&#60;').split('>').join('&#62;').split('" + '"' + "').join('&#34;').split(" + '"' + "'" + '"' + ").join('&#39;').split('/').join('&#47;'" + cend;
  67. })
  68. .replace(c.conditionalEnd, function(match, expression) {
  69. return "';}out+='";
  70. })
  71. .replace(c.conditionalStart, function(match, expression) {
  72. var code = "if(" + expression + "){";
  73. return "';" + code.replace(/\\'/g, "'").replace(/\\\\/g,"\\").replace(/[\r\t\n]/g, ' ') + "out+='";
  74. })
  75. .replace(c.evaluate, function(match, code) {
  76. return "';" + code.replace(/\\'/g, "'").replace(/\\\\/g,"\\").replace(/[\r\t\n]/g, ' ') + "out+='";
  77. })
  78. + "';return out;")
  79. .replace(/\n/g, '\\n')
  80. .replace(/\t/g, '\\t')
  81. .replace(/\r/g, '\\r')
  82. .split("out+='';").join('')
  83. .split("var out='';out+=").join('var out=');
  84. try {
  85. return new Function(c.varname, str);
  86. } catch (e) {
  87. if (typeof console !== 'undefined') console.log("Could not create a template function: " + str);
  88. throw e;
  89. }
  90. };
  91. doT.compile = function(tmpl, def) {
  92. return doT.template(tmpl, null, def);
  93. };
  94. }());