ejs.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581
  1. ejs = (function(){
  2. // CommonJS require()
  3. function require(p){
  4. if ('fs' == p) return {};
  5. var path = require.resolve(p)
  6. , mod = require.modules[path];
  7. if (!mod) throw new Error('failed to require "' + p + '"');
  8. if (!mod.exports) {
  9. mod.exports = {};
  10. mod.call(mod.exports, mod, mod.exports, require.relative(path));
  11. }
  12. return mod.exports;
  13. }
  14. require.modules = {};
  15. require.resolve = function (path){
  16. var orig = path
  17. , reg = path + '.js'
  18. , index = path + '/index.js';
  19. return require.modules[reg] && reg
  20. || require.modules[index] && index
  21. || orig;
  22. };
  23. require.register = function (path, fn){
  24. require.modules[path] = fn;
  25. };
  26. require.relative = function (parent) {
  27. return function(p){
  28. if ('.' != p.substr(0, 1)) return require(p);
  29. var path = parent.split('/')
  30. , segs = p.split('/');
  31. path.pop();
  32. for (var i = 0; i < segs.length; i++) {
  33. var seg = segs[i];
  34. if ('..' == seg) path.pop();
  35. else if ('.' != seg) path.push(seg);
  36. }
  37. return require(path.join('/'));
  38. };
  39. };
  40. require.register("ejs.js", function(module, exports, require){
  41. /*!
  42. * EJS
  43. * Copyright(c) 2012 TJ Holowaychuk <tj@vision-media.ca>
  44. * MIT Licensed
  45. */
  46. /**
  47. * Module dependencies.
  48. */
  49. var utils = require('./utils')
  50. , fs = require('fs');
  51. /**
  52. * Library version.
  53. */
  54. exports.version = '0.7.2';
  55. /**
  56. * Filters.
  57. *
  58. * @type Object
  59. */
  60. var filters = exports.filters = require('./filters');
  61. /**
  62. * Intermediate js cache.
  63. *
  64. * @type Object
  65. */
  66. var cache = {};
  67. /**
  68. * Clear intermediate js cache.
  69. *
  70. * @api public
  71. */
  72. exports.clearCache = function(){
  73. cache = {};
  74. };
  75. /**
  76. * Translate filtered code into function calls.
  77. *
  78. * @param {String} js
  79. * @return {String}
  80. * @api private
  81. */
  82. function filtered(js) {
  83. return js.substr(1).split('|').reduce(function(js, filter){
  84. var parts = filter.split(':')
  85. , name = parts.shift()
  86. , args = parts.shift() || '';
  87. if (args) args = ', ' + args;
  88. return 'filters.' + name + '(' + js + args + ')';
  89. });
  90. };
  91. /**
  92. * Re-throw the given `err` in context to the
  93. * `str` of ejs, `filename`, and `lineno`.
  94. *
  95. * @param {Error} err
  96. * @param {String} str
  97. * @param {String} filename
  98. * @param {String} lineno
  99. * @api private
  100. */
  101. function rethrow(err, str, filename, lineno){
  102. var lines = str.split('\n')
  103. , start = Math.max(lineno - 3, 0)
  104. , end = Math.min(lines.length, lineno + 3);
  105. // Error context
  106. var context = lines.slice(start, end).map(function(line, i){
  107. var curr = i + start + 1;
  108. return (curr == lineno ? ' >> ' : ' ')
  109. + curr
  110. + '| '
  111. + line;
  112. }).join('\n');
  113. // Alter exception message
  114. err.path = filename;
  115. err.message = (filename || 'ejs') + ':'
  116. + lineno + '\n'
  117. + context + '\n\n'
  118. + err.message;
  119. throw err;
  120. }
  121. /**
  122. * Parse the given `str` of ejs, returning the function body.
  123. *
  124. * @param {String} str
  125. * @return {String}
  126. * @api public
  127. */
  128. var parse = exports.parse = function(str, options){
  129. var options = options || {}
  130. , open = options.open || exports.open || '<%'
  131. , close = options.close || exports.close || '%>';
  132. var buf = [
  133. "var buf = [];"
  134. , "\nwith (locals) {"
  135. , "\n buf.push('"
  136. ];
  137. var lineno = 1;
  138. var consumeEOL = false;
  139. for (var i = 0, len = str.length; i < len; ++i) {
  140. if (str.slice(i, open.length + i) == open) {
  141. i += open.length
  142. var prefix, postfix, line = '__stack.lineno=' + lineno;
  143. switch (str.substr(i, 1)) {
  144. case '=':
  145. prefix = "', escape((" + line + ', ';
  146. postfix = ")), '";
  147. ++i;
  148. break;
  149. case '-':
  150. prefix = "', (" + line + ', ';
  151. postfix = "), '";
  152. ++i;
  153. break;
  154. default:
  155. prefix = "');" + line + ';';
  156. postfix = "; buf.push('";
  157. }
  158. var end = str.indexOf(close, i)
  159. , js = str.substring(i, end)
  160. , start = i
  161. , n = 0;
  162. if ('-' == js[js.length-1]){
  163. js = js.substring(0, js.length - 2);
  164. consumeEOL = true;
  165. }
  166. while (~(n = js.indexOf("\n", n))) n++, lineno++;
  167. if (js.substr(0, 1) == ':') js = filtered(js);
  168. buf.push(prefix, js, postfix);
  169. i += end - start + close.length - 1;
  170. } else if (str.substr(i, 1) == "\\") {
  171. buf.push("\\\\");
  172. } else if (str.substr(i, 1) == "'") {
  173. buf.push("\\'");
  174. } else if (str.substr(i, 1) == "\r") {
  175. buf.push(" ");
  176. } else if (str.substr(i, 1) == "\n") {
  177. if (consumeEOL) {
  178. consumeEOL = false;
  179. } else {
  180. buf.push("\\n");
  181. lineno++;
  182. }
  183. } else {
  184. buf.push(str.substr(i, 1));
  185. }
  186. }
  187. buf.push("');\n}\nreturn buf.join('');");
  188. return buf.join('');
  189. };
  190. /**
  191. * Compile the given `str` of ejs into a `Function`.
  192. *
  193. * @param {String} str
  194. * @param {Object} options
  195. * @return {Function}
  196. * @api public
  197. */
  198. var compile = exports.compile = function(str, options){
  199. options = options || {};
  200. var input = JSON.stringify(str)
  201. , filename = options.filename
  202. ? JSON.stringify(options.filename)
  203. : 'undefined';
  204. // Adds the fancy stack trace meta info
  205. str = [
  206. 'var __stack = { lineno: 1, input: ' + input + ', filename: ' + filename + ' };',
  207. rethrow.toString(),
  208. 'try {',
  209. exports.parse(str, options),
  210. '} catch (err) {',
  211. ' rethrow(err, __stack.input, __stack.filename, __stack.lineno);',
  212. '}'
  213. ].join("\n");
  214. if (options.debug) console.log(str);
  215. var fn = new Function('locals, filters, escape', str);
  216. return function(locals){
  217. return fn.call(this, locals, filters, utils.escape);
  218. }
  219. };
  220. /**
  221. * Render the given `str` of ejs.
  222. *
  223. * Options:
  224. *
  225. * - `locals` Local variables object
  226. * - `cache` Compiled functions are cached, requires `filename`
  227. * - `filename` Used by `cache` to key caches
  228. * - `scope` Function execution context
  229. * - `debug` Output generated function body
  230. * - `open` Open tag, defaulting to "<%"
  231. * - `close` Closing tag, defaulting to "%>"
  232. *
  233. * @param {String} str
  234. * @param {Object} options
  235. * @return {String}
  236. * @api public
  237. */
  238. exports.render = function(str, options){
  239. var fn
  240. , options = options || {};
  241. if (options.cache) {
  242. if (options.filename) {
  243. fn = cache[options.filename] || (cache[options.filename] = compile(str, options));
  244. } else {
  245. throw new Error('"cache" option requires "filename".');
  246. }
  247. } else {
  248. fn = compile(str, options);
  249. }
  250. options.__proto__ = options.locals;
  251. return fn.call(options.scope, options);
  252. };
  253. /**
  254. * Render an EJS file at the given `path` and callback `fn(err, str)`.
  255. *
  256. * @param {String} path
  257. * @param {Object|Function} options or callback
  258. * @param {Function} fn
  259. * @api public
  260. */
  261. exports.renderFile = function(path, options, fn){
  262. var key = path + ':string';
  263. if ('function' == typeof options) {
  264. fn = options, options = {};
  265. }
  266. options.filename = path;
  267. try {
  268. var str = options.cache
  269. ? cache[key] || (cache[key] = fs.readFileSync(path, 'utf8'))
  270. : fs.readFileSync(path, 'utf8');
  271. fn(null, exports.render(str, options));
  272. } catch (err) {
  273. fn(err);
  274. }
  275. };
  276. // express support
  277. exports.__express = exports.renderFile;
  278. /**
  279. * Expose to require().
  280. */
  281. if (require.extensions) {
  282. require.extensions['.ejs'] = function(module, filename) {
  283. source = require('fs').readFileSync(filename, 'utf-8');
  284. module._compile(compile(source, {}), filename);
  285. };
  286. } else if (require.registerExtension) {
  287. require.registerExtension('.ejs', function(src) {
  288. return compile(src, {});
  289. });
  290. }
  291. }); // module: ejs.js
  292. require.register("filters.js", function(module, exports, require){
  293. /*!
  294. * EJS - Filters
  295. * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
  296. * MIT Licensed
  297. */
  298. /**
  299. * First element of the target `obj`.
  300. */
  301. exports.first = function(obj) {
  302. return obj[0];
  303. };
  304. /**
  305. * Last element of the target `obj`.
  306. */
  307. exports.last = function(obj) {
  308. return obj[obj.length - 1];
  309. };
  310. /**
  311. * Capitalize the first letter of the target `str`.
  312. */
  313. exports.capitalize = function(str){
  314. str = String(str);
  315. return str[0].toUpperCase() + str.substr(1, str.length);
  316. };
  317. /**
  318. * Downcase the target `str`.
  319. */
  320. exports.downcase = function(str){
  321. return String(str).toLowerCase();
  322. };
  323. /**
  324. * Uppercase the target `str`.
  325. */
  326. exports.upcase = function(str){
  327. return String(str).toUpperCase();
  328. };
  329. /**
  330. * Sort the target `obj`.
  331. */
  332. exports.sort = function(obj){
  333. return Object.create(obj).sort();
  334. };
  335. /**
  336. * Sort the target `obj` by the given `prop` ascending.
  337. */
  338. exports.sort_by = function(obj, prop){
  339. return Object.create(obj).sort(function(a, b){
  340. a = a[prop], b = b[prop];
  341. if (a > b) return 1;
  342. if (a < b) return -1;
  343. return 0;
  344. });
  345. };
  346. /**
  347. * Size or length of the target `obj`.
  348. */
  349. exports.size = exports.length = function(obj) {
  350. return obj.length;
  351. };
  352. /**
  353. * Add `a` and `b`.
  354. */
  355. exports.plus = function(a, b){
  356. return Number(a) + Number(b);
  357. };
  358. /**
  359. * Subtract `b` from `a`.
  360. */
  361. exports.minus = function(a, b){
  362. return Number(a) - Number(b);
  363. };
  364. /**
  365. * Multiply `a` by `b`.
  366. */
  367. exports.times = function(a, b){
  368. return Number(a) * Number(b);
  369. };
  370. /**
  371. * Divide `a` by `b`.
  372. */
  373. exports.divided_by = function(a, b){
  374. return Number(a) / Number(b);
  375. };
  376. /**
  377. * Join `obj` with the given `str`.
  378. */
  379. exports.join = function(obj, str){
  380. return obj.join(str || ', ');
  381. };
  382. /**
  383. * Truncate `str` to `len`.
  384. */
  385. exports.truncate = function(str, len){
  386. str = String(str);
  387. return str.substr(0, len);
  388. };
  389. /**
  390. * Truncate `str` to `n` words.
  391. */
  392. exports.truncate_words = function(str, n){
  393. var str = String(str)
  394. , words = str.split(/ +/);
  395. return words.slice(0, n).join(' ');
  396. };
  397. /**
  398. * Replace `pattern` with `substitution` in `str`.
  399. */
  400. exports.replace = function(str, pattern, substitution){
  401. return String(str).replace(pattern, substitution || '');
  402. };
  403. /**
  404. * Prepend `val` to `obj`.
  405. */
  406. exports.prepend = function(obj, val){
  407. return Array.isArray(obj)
  408. ? [val].concat(obj)
  409. : val + obj;
  410. };
  411. /**
  412. * Append `val` to `obj`.
  413. */
  414. exports.append = function(obj, val){
  415. return Array.isArray(obj)
  416. ? obj.concat(val)
  417. : obj + val;
  418. };
  419. /**
  420. * Map the given `prop`.
  421. */
  422. exports.map = function(arr, prop){
  423. return arr.map(function(obj){
  424. return obj[prop];
  425. });
  426. };
  427. /**
  428. * Reverse the given `obj`.
  429. */
  430. exports.reverse = function(obj){
  431. return Array.isArray(obj)
  432. ? obj.reverse()
  433. : String(obj).split('').reverse().join('');
  434. };
  435. /**
  436. * Get `prop` of the given `obj`.
  437. */
  438. exports.get = function(obj, prop){
  439. return obj[prop];
  440. };
  441. /**
  442. * Packs the given `obj` into json string
  443. */
  444. exports.json = function(obj){
  445. return JSON.stringify(obj);
  446. };
  447. }); // module: filters.js
  448. require.register("utils.js", function(module, exports, require){
  449. /*!
  450. * EJS
  451. * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
  452. * MIT Licensed
  453. */
  454. /**
  455. * Escape the given string of `html`.
  456. *
  457. * @param {String} html
  458. * @return {String}
  459. * @api private
  460. */
  461. exports.escape = function(html){
  462. return String(html)
  463. .replace(/&(?!\w+;)/g, '&amp;')
  464. .replace(/</g, '&lt;')
  465. .replace(/>/g, '&gt;')
  466. .replace(/"/g, '&quot;');
  467. };
  468. }); // module: utils.js
  469. return require("ejs");
  470. })();