3
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
11
var Parser = require('./parser')
12
, Lexer = require('./lexer')
13
, Compiler = require('./compiler')
14
, runtime = require('./runtime')
23
exports.version = '0.26.3';
26
* Expose self closing tags.
29
exports.selfClosing = require('./self-closing');
32
* Default supported doctypes.
35
exports.doctypes = require('./doctypes');
41
exports.filters = require('./filters');
47
exports.utils = require('./utils');
53
exports.Compiler = Compiler;
59
exports.Parser = Parser;
65
exports.Lexer = Lexer;
71
exports.nodes = require('./nodes');
74
* Jade runtime helpers.
77
exports.runtime = runtime;
80
* Template function cache.
86
* Parse the given `str` of jade and return a function body.
89
* @param {Object} options
94
function parse(str, options){
97
var parser = new Parser(str, options.filename, options);
100
var compiler = new (options.compiler || Compiler)(parser.parse(), options)
101
, js = compiler.compile();
105
console.error('\nCompiled Function:\n\n\033[90m%s\033[0m', js.replace(/^/gm, ' '));
111
? 'var self = locals || {};\n' + js
112
: 'with (locals || {}) {\n' + js + '\n}\n')
113
+ 'return buf.join("");';
115
parser = parser.context();
116
runtime.rethrow(err, parser.filename, parser.lexer.lineno);
121
* Compile a `Function` representation of the given jade `str`.
125
* - `compileDebug` when `false` debugging code is stripped from the compiled template
126
* - `client` when `true` the helper functions `escape()` etc will reference `jade.escape()`
127
* for use with the Jade client-side runtime.js
129
* @param {String} str
130
* @param {Options} options
135
exports.compile = function(str, options){
136
var options = options || {}
137
, client = options.client
138
, filename = options.filename
139
? JSON.stringify(options.filename)
143
if (options.compileDebug !== false) {
145
'var __jade = [{ lineno: 1, filename: ' + filename + ' }];'
147
, parse(String(str), options)
149
, ' rethrow(err, __jade[0].filename, __jade[0].lineno);'
153
fn = parse(String(str), options);
157
fn = 'attrs = attrs || jade.attrs; escape = escape || jade.escape; rethrow = rethrow || jade.rethrow; merge = merge || jade.merge;\n' + fn;
160
fn = new Function('locals, attrs, escape, rethrow, merge', fn);
162
if (client) return fn;
164
return function(locals){
165
return fn(locals, runtime.attrs, runtime.escape, runtime.rethrow, runtime.merge);
170
* Render the given `str` of jade and invoke
171
* the callback `fn(err, str)`.
175
* - `cache` enable template caching
176
* - `filename` filename required for `include` / `extends` and caching
178
* @param {String} str
179
* @param {Object|Function} options or fn
180
* @param {Function} fn
184
exports.render = function(str, options, fn){
186
if ('function' == typeof options) {
187
fn = options, options = {};
190
// cache requires .filename
191
if (options.cache && !options.filename) {
192
return fn(new Error('the "filename" option is required for caching'));
196
var path = options.filename;
197
var tmpl = options.cache
198
? exports.cache[path] || (exports.cache[path] = exports.compile(str, options))
199
: exports.compile(str, options);
200
fn(null, tmpl(options));
207
* Render a Jade file at the given `path` and callback `fn(err, str)`.
209
* @param {String} path
210
* @param {Object|Function} options or callback
211
* @param {Function} fn
215
exports.renderFile = function(path, options, fn){
216
var key = path + ':string';
218
if ('function' == typeof options) {
219
fn = options, options = {};
223
options.filename = path;
224
var str = options.cache
225
? exports.cache[key] || (exports.cache[key] = fs.readFileSync(path, 'utf8'))
226
: fs.readFileSync(path, 'utf8');
227
exports.render(str, options, fn);
237
exports.__express = exports.renderFile;