Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

jade

Package Overview
Dependencies
Maintainers
1
Versions
131
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

jade - npm Package Compare versions

Comparing version 0.28.2 to 0.29.0

170

lib/compiler.js

@@ -17,3 +17,4 @@

, runtime = require('./runtime')
, utils = require('./utils');
, utils = require('./utils')
, parseJSExpression = require('character-parser').parseMax

@@ -76,4 +77,4 @@ // if browser

compile: function(){
this.buf = ['var interp;'];
if (this.pp) this.buf.push("var __indent = [];");
this.buf = [];
if (this.pp) this.buf.push("jade.indent = [];");
this.lastBufferedIdx = -1;

@@ -101,17 +102,50 @@ this.visit(this.node);

/**
* Buffer the given `str` optionally escaped.
* Buffer the given `str` exactly as is or with interpolation
*
* @param {String} str
* @param {Boolean} esc
* @param {Boolean} interpolate
* @api public
*/
buffer: function(str, esc){
if (esc) str = utils.escape(str);
buffer: function (str, interpolate) {
var self = this;
if (interpolate) {
var match = /(\\)?([#!]){((?:.|\n)*)$/.exec(str);
if (match) {
this.buffer(str.substr(0, match.index), false);
if (match[1]) { // escape
this.buffer(match[2] + '{', false);
this.buffer(match[3], true);
return;
} else {
try {
var rest = match[3];
var range = parseJSExpression(rest);
var code = ('!' == match[2] ? '' : 'jade.escape') + "((jade.interp = " + range.src + ") == null ? '' : jade.interp)";
} catch (ex) {
throw ex;
//didn't match, just as if escaped
this.buffer(match[2] + '{', false);
this.buffer(match[3], true);
return;
}
this.bufferExpression(code);
this.buffer(rest.substr(range.end + 1), true);
return;
}
}
}
str = JSON.stringify(str);
str = str.substr(1, str.length - 2);
if (this.lastBufferedIdx == this.buf.length) {
if (this.lastBufferedType === 'code') this.lastBuffered += ' + "';
this.lastBufferedType = 'text';
this.lastBuffered += str;
this.buf[this.lastBufferedIdx - 1] = "buf.push('" + this.lastBuffered + "');"
this.buf[this.lastBufferedIdx - 1] = 'buf.push(' + this.bufferStartChar + this.lastBuffered + '");'
} else {
this.buf.push("buf.push('" + str + "');");
this.buf.push('buf.push("' + str + '");');
this.lastBufferedType = 'text';
this.bufferStartChar = '"';
this.lastBuffered = str;

@@ -123,2 +157,24 @@ this.lastBufferedIdx = this.buf.length;

/**
* Buffer the given `src` so it is evaluated at run time
*
* @param {String} src
* @api public
*/
bufferExpression: function (src) {
if (this.lastBufferedIdx == this.buf.length) {
if (this.lastBufferedType === 'text') this.lastBuffered += '"';
this.lastBufferedType = 'code';
this.lastBuffered += ' + (' + src + ')';
this.buf[this.lastBufferedIdx - 1] = 'buf.push(' + this.bufferStartChar + this.lastBuffered + ');'
} else {
this.buf.push('buf.push(' + src + ');');
this.lastBufferedType = 'code';
this.bufferStartChar = '';
this.lastBuffered = '(' + src + ')';
this.lastBufferedIdx = this.buf.length;
}
},
/**
* Buffer an indent based on the current `indent`

@@ -134,6 +190,6 @@ * property and an additional `offset`.

offset = offset || 0;
newline = newline ? '\\n' : '';
newline = newline ? '\n' : '';
this.buffer(newline + Array(this.indents + offset).join(' '));
if (this.parentIndents)
this.buf.push("buf.push.apply(buf, __indent);");
this.buf.push("buf.push.apply(buf, jade.indent);");
},

@@ -152,6 +208,6 @@

if (debug) {
this.buf.push('__jade.unshift({ lineno: ' + node.line
this.buf.push('jade.debug.unshift({ lineno: ' + node.line
+ ', filename: ' + (node.filename
? JSON.stringify(node.filename)
: '__jade[0].filename')
: 'jade.debug[0].filename')
+ ' });');

@@ -169,3 +225,3 @@ }

if (debug) this.buf.push('__jade.shift();');
if (debug) this.buf.push('jade.debug.shift();');
},

@@ -227,4 +283,3 @@

visitLiteral: function(node){
var str = node.str.replace(/\n/g, '\\\\n');
this.buffer(str);
this.buffer(node.str);
},

@@ -246,5 +301,5 @@

if (this.parentIndents && block.mode) {
if (pp) this.buf.push("__indent.push('" + Array(this.indents + 1).join(' ') + "');")
if (pp) this.buf.push("jade.indent.push('" + Array(this.indents + 1).join(' ') + "');")
this.buf.push('block && block();');
if (pp) this.buf.push("__indent.pop();")
if (pp) this.buf.push("jade.indent.pop();")
return;

@@ -265,3 +320,3 @@ }

if (block.nodes[i+1] && block.nodes[i].isText && block.nodes[i+1].isText)
this.buffer('\\n');
this.buffer('\n');
}

@@ -304,3 +359,3 @@ },

if (mixin.call) {
if (pp) this.buf.push("__indent.push('" + Array(this.indents + 1).join(' ') + "');")
if (pp) this.buf.push("jade.indent.push('" + Array(this.indents + 1).join(' ') + "');")
if (block || attrs.length) {

@@ -331,4 +386,4 @@

if (val.inherits) {
this.buf.push('attributes: merge({' + val.buf
+ '}, attributes), escaped: merge(' + val.escaped + ', escaped, true)');
this.buf.push('attributes: jade.merge({' + val.buf
+ '}, attributes), escaped: jade.merge(' + val.escaped + ', escaped, true)');
} else {

@@ -348,3 +403,3 @@ this.buf.push('attributes: {' + val.buf + '}, escaped: ' + val.escaped);

}
if (pp) this.buf.push("__indent.pop();")
if (pp) this.buf.push("jade.indent.pop();")
} else {

@@ -371,5 +426,9 @@ this.buf.push('var ' + name + ' = function(' + args + '){');

var name = tag.name
, pp = this.pp;
, pp = this.pp
, self = this;
if (tag.buffer) name = "' + (" + name + ") + '";
function bufferName() {
if (tag.buffer) self.bufferExpression(name);
else self.buffer(name);
}

@@ -388,3 +447,4 @@ if (!this.hasCompiledTag) {

if ((~selfClosing.indexOf(name) || tag.selfClosing) && !this.xml) {
this.buffer('<' + name);
this.buffer('<');
bufferName();
this.visitAttributes(tag.attrs);

@@ -397,7 +457,10 @@ this.terse

if (tag.attrs.length) {
this.buffer('<' + name);
this.buffer('<');
bufferName();
if (tag.attrs.length) this.visitAttributes(tag.attrs);
this.buffer('>');
} else {
this.buffer('<' + name + '>');
this.buffer('<');
bufferName();
this.buffer('>');
}

@@ -412,3 +475,5 @@ if (tag.code) this.visitCode(tag.code);

this.buffer('</' + name + '>');
this.buffer('</');
bufferName();
this.buffer('>');
}

@@ -426,7 +491,2 @@ this.indents--;

visitFilter: function(filter){
var fn = filters[filter.name];
// unknown filter
if (!fn) throw new Error('unknown filter ":' + filter.name + '"');
var text = filter.block.nodes.map(

@@ -437,3 +497,3 @@ function(node){ return node.val; }

filter.attrs.filename = this.options.filename;
this.buffer(utils.text(fn(text, filter.attrs)));
this.buffer(filters(filter.name, text, filter.attrs), true);
},

@@ -449,6 +509,3 @@

visitText: function(text){
text = utils.text(text.val.replace(/\\/g, '_SLASH_'));
if (this.escape) text = escape(text);
text = text.replace(/_SLASH_/g, '\\\\');
this.buffer(text);
this.buffer(text.val, true);
},

@@ -466,3 +523,3 @@

if (this.pp) this.prettyIndent(1, true);
this.buffer('<!--' + utils.escape(comment.val) + '-->');
this.buffer('<!--' + comment.val + '-->');
},

@@ -507,6 +564,5 @@

var val = code.val.trimLeft();
this.buf.push('var __val__ = ' + val);
val = 'null == __val__ ? "" : __val__';
if (code.escape) val = 'escape(' + val + ')';
this.buf.push("buf.push(" + val + ");");
val = 'null == (jade.interp = '+val+') ? "" : jade.interp';
if (code.escape) val = 'jade.escape(' + val + ')';
this.bufferExpression(val);
} else {

@@ -590,9 +646,9 @@ this.buf.push(code.val);

if (val.inherits) {
this.buf.push("buf.push(attrs(merge({ " + val.buf +
" }, attributes), merge(" + val.escaped + ", escaped, true)));");
this.bufferExpression("jade.attrs(jade.merge({ " + val.buf +
" }, attributes), jade.merge(" + val.escaped + ", escaped, true))");
} else if (val.constant) {
eval('var buf={' + val.buf + '};');
this.buffer(runtime.attrs(buf, JSON.parse(val.escaped)), true);
this.buffer(runtime.attrs(buf, JSON.parse(val.escaped)));
} else {
this.buf.push("buf.push(attrs({ " + val.buf + " }, " + val.escaped + "));");
this.bufferExpression("jade.attrs({ " + val.buf + " }, " + val.escaped + ")");
}

@@ -662,18 +718,2 @@ },

return false;
}
/**
* Escape the given string of `html`.
*
* @param {String} html
* @return {String}
* @api private
*/
function escape(html){
return String(html)
.replace(/&(?!\w+;)/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;');
}
}

@@ -1,2 +0,1 @@

/*!

@@ -8,99 +7,24 @@ * Jade - filters

/**
* Wrap text with CDATA block.
*/
var transformers = require('transformers');
exports.cdata = function(str){
return '<![CDATA[\\n' + str + '\\n]]>';
};
/**
* Wrap text in script tags.
*/
exports.js = function(str){
return '<script>' + str + '</script>';
};
/**
* Wrap text in style tags.
*/
exports.css = function(str){
return '<style>' + str + '</style>';
};
/**
* Transform stylus to css, wrapped in style tags.
*/
exports.stylus = function(str, options){
var ret;
str = str.replace(/\\n/g, '\n');
var stylus = require('stylus');
stylus(str, options).render(function(err, css){
if (err) throw err;
ret = css.replace(/\n/g, '\\n');
});
return '<style type="text/css">' + ret + '</style>';
};
/**
* Transform less to css, wrapped in style tags.
*/
exports.less = function(str){
var ret;
str = str.replace(/\\n/g, '\n');
require('less').render(str, function(err, css){
if (err) throw err;
ret = '<style type="text/css">' + css.replace(/\n/g, '\\n') + '</style>';
});
return ret;
};
/**
* Transform markdown to html.
*/
exports.markdown = function(str){
var md;
// support markdown / discount
try {
md = require('markdown');
} catch (err){
try {
md = require('discount');
} catch (err) {
try {
md = require('markdown-js');
} catch (err) {
try {
md = require('marked');
} catch (err) {
throw new
Error('Cannot find markdown library, install markdown, discount, or marked.');
}
}
module.exports = filter;
function filter(name, str, options) {
if (typeof filter[name] === 'function') {
var res = filter[name](str, options);
} else if (transformers[name]) {
var res = transformers[name].renderSync(str, options);
if (transformers[name].outputFormat === 'js') {
res = '<script type="text/javascript">\n' + res + '</script>';
} else if (transformers[name].outputFormat === 'css') {
res = '<style type="text/css">' + res + '</style>';
} else if (transformers[name].outputFormat === 'xml') {
res = res.replace(/'/g, '&#39;');
}
} else {
throw new Error('unknown filter ":' + name + '"');
}
str = str.replace(/\\n/g, '\n');
return md.parse(str).replace(/\n/g, '\\n').replace(/'/g,'&#39;');
return res;
}
filter.exists = function (name, str, options) {
return typeof filter[name] === 'function' || transformers[name];
};
/**
* Transform coffeescript to javascript.
*/
exports.coffeescript = function(str){
var js = require('coffee-script').compile(str).replace(/\\/g, '\\\\').replace(/\n/g, '\\n');
return '<script type="text/javascript">\\n' + js + '</script>';
};
// aliases
exports.md = exports.markdown;
exports.styl = exports.stylus;
exports.coffee = exports.coffeescript;

@@ -23,3 +23,3 @@ /*!

exports.version = '0.28.2';
exports.version = '0.29.0';

@@ -141,4 +141,3 @@ /**

* - `compileDebug` when `false` debugging code is stripped from the compiled template
* - `client` when `true` the helper functions `escape()` etc will reference `jade.escape()`
* for use with the Jade client-side runtime.js
* - `filename` used to improve errors when `compileDebug` is not `false`
*

@@ -153,3 +152,2 @@ * @param {String} str

var options = options || {}
, client = options.client
, filename = options.filename

@@ -164,7 +162,7 @@ ? JSON.stringify(options.filename)

fn = [
'var __jade = [{ lineno: 1, filename: ' + filename + ' }];'
'jade.debug = [{ lineno: 1, filename: ' + filename + ' }];'
, 'try {'
, parse(str, options)
, '} catch (err) {'
, ' rethrow(err, __jade[0].filename, __jade[0].lineno);'
, ' jade.rethrow(err, jade.debug[0].filename, jade.debug[0].lineno);'
, '}'

@@ -176,13 +174,5 @@ ].join('\n');

if (client) {
fn = 'attrs = attrs || jade.attrs; escape = escape || jade.escape; rethrow = rethrow || jade.rethrow; merge = merge || jade.merge;\n' + fn;
}
fn = new Function('locals, attrs, escape, rethrow, merge', fn);
if (client) return fn;
return function(locals){
return fn(locals, runtime.attrs, runtime.escape, runtime.rethrow, runtime.merge);
};
if (options.client) return new Function('locals', fn)
fn = new Function('locals, jade', fn)
return function(locals){ return fn(locals, runtime) }
};

@@ -189,0 +179,0 @@

@@ -8,2 +8,3 @@ /*!

var utils = require('./utils');
var parseJSExpression = require('character-parser').parseMax;

@@ -112,6 +113,4 @@ /**

/**
* Return the indexOf `start` / `end` delimiters.
* Return the indexOf `(` or `{` or `[` / `)` or `}` or `]` delimiters.
*
* @param {String} start
* @param {String} end
* @return {Number}

@@ -121,18 +120,10 @@ * @api private

indexOfDelimiters: function(start, end){
var str = this.input
, nstart = 0
, nend = 0
, pos = 0;
for (var i = 0, len = str.length; i < len; ++i) {
if (start == str.charAt(i)) {
++nstart;
} else if (end == str.charAt(i)) {
if (++nend == nstart) {
pos = i;
break;
}
}
}
return pos;
bracketExpression: function(skip){
skip = skip || 0;
var start = this.input[skip];
if (start != '(' && start != '{' && start != '[') throw new Error('unrecognized start character');
var end = ({'(': ')', '{': '}', '[': ']'})[start];
var range = parseJSExpression(this.input, {start: skip + 1});
if (this.input[range.end] !== end) throw new Error('start character ' + start + ' does not match end character ' + this.input[range.end]);
return range;
},

@@ -205,6 +196,12 @@

interpolation: function() {
var captures;
if (captures = /^#\{(.*?)\}/.exec(this.input)) {
this.consume(captures[0].length);
return this.tok('interpolation', captures[1]);
if (/^#\{/.test(this.input)) {
var match;
try {
match = this.bracketExpression(1);
} catch (ex) {
return;//not an interpolation expression, just an unmatched open interpolation
}
this.consume(match.end + 1);
return this.tok('interpolation', match.src);
}

@@ -395,8 +392,13 @@ },

var tok = this.tok('call', captures[1]);
// Check for args (not attributes)
if (captures = /^ *\((.*?)\)/.exec(this.input)) {
if (!/^ *[-\w]+ *=/.test(captures[1])) {
this.consume(captures[0].length);
tok.args = captures[1];
if (captures = /^ *\(/.exec(this.input)) {
try {
var range = this.bracketExpression(captures[0].length - 1);
if (!/^ *[-\w]+ *=/.test(range.src)) { // not attributes
this.consume(range.end + 1);
tok.args = range.src;
}
} catch (ex) {
//not a bracket expcetion, just unmatched open parens
}

@@ -495,3 +497,3 @@ }

if ('(' == this.input.charAt(0)) {
var index = this.indexOfDelimiters('(', ')')
var index = this.bracketExpression().end
, str = this.input.substr(1, index-1)

@@ -514,6 +516,11 @@ , tok = this.tok('attrs')

function interpolate(attr) {
return attr.replace(/(\\)?#\{([^}]+)\}/g, function(_, escape, expr){
return escape
? _
: quote + " + (" + expr + ") + " + quote;
return attr.replace(/(\\)?#\{(.+)/g, function(_, escape, expr){
if (escape) return _;
try {
var range = parseJSExpression(expr);
if (expr[range.end] !== '}') return _.substr(0, 2) + interpolate(_.substr(2));
return quote + " + (" + range.src + ") + " + quote + interpolate(expr.substr(range.end + 1));
} catch (ex) {
return _.substr(0, 2) + interpolate(_.substr(2));
}
});

@@ -520,0 +527,0 @@ }

@@ -22,6 +22,3 @@

var Literal = module.exports = function Literal(str) {
this.str = str
.replace(/\\/g, "\\\\")
.replace(/\n|\r\n/g, "\\n")
.replace(/'/g, "\\'");
this.str = str;
};

@@ -28,0 +25,0 @@

@@ -395,6 +395,6 @@ /*!

path = this.expect('extends').val.trim();
var path = this.expect('extends').val.trim();
var dir = dirname(this.filename);
path = join(dir, path + '.jade');
var path = join(dir, path + '.jade');
var str = fs.readFileSync(path, 'utf8');

@@ -453,5 +453,4 @@ var parser = new Parser(str, path, this.options);

var join = path.join;
var str;
path = this.expect('include').val.trim();
var path = this.expect('include').val.trim();
var dir = dirname(this.filename);

@@ -469,12 +468,11 @@

if ('.jade' != path.substr(-5)) {
path = join(dir, path);
str = fs.readFileSync(path, 'utf8').replace(/\r/g, '');
var path = join(dir, path);
var str = fs.readFileSync(path, 'utf8').replace(/\r/g, '');
var ext = extname(path).slice(1);
var filter = filters[ext];
if (filter) str = filter(str, { filename: path }).replace(/\\n/g, '\n');
if (filters.exists(ext)) str = filters(ext, str, { filename: path });
return new nodes.Literal(str);
}
path = join(dir, path);
str = fs.readFileSync(path, 'utf8');
var path = join(dir, path);
var str = fs.readFileSync(path, 'utf8');
var parser = new Parser(str, path, this.options);

@@ -481,0 +479,0 @@ parser.blocks = utils.merge({}, this.blocks);

@@ -135,3 +135,3 @@

return String(html)
.replace(/&(?!(\w+|\#\d+);)/g, '&amp;')
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')

@@ -138,0 +138,0 @@ .replace(/>/g, '&gt;')

@@ -9,49 +9,2 @@

/**
* Convert interpolation in the given string to JavaScript.
*
* @param {String} str
* @return {String}
* @api private
*/
var interpolate = exports.interpolate = function(str){
return str.replace(/(_SLASH_)?([#!]){(.*?)}/g, function(str, escape, flag, code){
code = code
.replace(/\\'/g, "'")
.replace(/_SLASH_/g, '\\');
return escape
? str.slice(7)
: "' + "
+ ('!' == flag ? '' : 'escape')
+ "((interp = " + code
+ ") == null ? '' : interp) + '";
});
};
/**
* Escape single quotes in `str`.
*
* @param {String} str
* @return {String}
* @api private
*/
var escape = exports.escape = function(str) {
return str.replace(/'/g, "\\'");
};
/**
* Interpolate, and escape the given `str`.
*
* @param {String} str
* @return {String}
* @api private
*/
exports.text = function(str){
return interpolate(escape(str));
};
/**
* Merge `b` into `a`.

@@ -58,0 +11,0 @@ *

{
"name": "jade",
"description": "Jade template engine",
"version": "0.28.2",
"version": "0.29.0",
"author": "TJ Holowaychuk <tj@vision-media.ca>",

@@ -14,6 +14,9 @@ "repository": "git://github.com/visionmedia/jade",

"commander": "0.6.1",
"mkdirp": "0.3.x"
"mkdirp": "0.3.x",
"transformers": "~1.8.0",
"character-parser": "~1.0.0",
"monocle": "~0.1.43"
},
"devDependencies": {
"coffee-script": "~1.4.0",
"coffee-script": "*",
"mocha": "*",

@@ -20,0 +23,0 @@ "markdown": "*",

@@ -86,3 +86,3 @@ # Jade - template engine

- [scala](http://scalate.fusesource.org/versions/snapshot/documentation/scaml-reference.html)
- [ruby](http://github.com/stonean/slim)
- [ruby](https://github.com/slim-template/slim)
- [python](https://github.com/SyrusAkbary/pyjade)

@@ -938,4 +938,4 @@ - [java](https://github.com/neuland/jade4j)

script(src='/vendor/caustic.js')
body
block content
body
block content
```

@@ -987,3 +987,5 @@

read relative to the `filename` option given to _layout.jade_,
which should be an absolute path to this file, however Express does this for you. Include then parses these files, and injects the AST produced to render what you would expect:
which should be an absolute path to this file, however Express
does this for you. Include then parses these files, and injects
the AST produced to render what you would expect:

@@ -1007,10 +1009,19 @@ ```html

As mentioned `include` can be used to include other content
such as html or css. By providing an extension Jade will not
assume that the file is Jade source and will include it as
a literal:
As mentioned `include` can be used to include other content
such as html or css. By providing an extension, Jade will
read that file in, apply any [filter](#a7) matching the file's
extension, and insert that content into the output.
```jade
html
head
//- css and js have simple filters that wrap them in
<style> and <script> tags, respectively
include stylesheet.css
include script.js
body
//- "markdown" files will use the "markdown" filter
to convert Markdown to HTML
include introduction.markdown
//- html files have no filter and are included verbatim
include content.html

@@ -1236,2 +1247,4 @@ ```

or you use the watch option below:
<a name="a17"/>

@@ -1252,4 +1265,5 @@ ## jade(1)

-P, --pretty compile pretty html output
-c, --client compile for client-side runtime.js
-c, --client compile function for client-side runtime.js
-D, --no-debug compile without debugging (smaller functions)
-w, --watch watch files for changes and automatically re-render

@@ -1271,3 +1285,3 @@ Examples:

# foo, bar dirs rendering to /tmp
$ jade foo bar --out /tmp
$ jade foo bar --out /tmp

@@ -1274,0 +1288,0 @@ ```

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc