Added game info bar

This commit is contained in:
clerie
2018-04-04 12:31:55 +02:00
parent 811ecfddfb
commit 95741499fd
271 changed files with 46086 additions and 2 deletions

15
node_modules/jade/.npmignore generated vendored Normal file
View File

@@ -0,0 +1,15 @@
test
support
benchmarks
examples
lib-cov
coverage.html
.gitmodules
.travis.yml
History.md
Readme.md
Makefile
test/
support/
benchmarks/
examples/

22
node_modules/jade/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,22 @@
(The MIT License)
Copyright (c) 2009-2010 TJ Holowaychuk <tj@vision-media.ca>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

147
node_modules/jade/bin/jade generated vendored Executable file
View File

@@ -0,0 +1,147 @@
#!/usr/bin/env node
/**
* Module dependencies.
*/
var fs = require('fs')
, program = require('commander')
, path = require('path')
, basename = path.basename
, dirname = path.dirname
, resolve = path.resolve
, join = path.join
, mkdirp = require('mkdirp')
, jade = require('../');
// jade options
var options = {};
// options
program
.version(jade.version)
.usage('[options] [dir|file ...]')
.option('-o, --obj <str>', 'javascript options object')
.option('-O, --out <dir>', 'output the compiled html to <dir>')
.option('-p, --path <path>', 'filename used to resolve includes')
.option('-P, --pretty', 'compile pretty html output')
.option('-c, --client', 'compile for client-side runtime.js')
.option('-D, --no-debug', 'compile without debugging (smaller functions)')
program.on('--help', function(){
console.log(' Examples:');
console.log('');
console.log(' # translate jade the templates dir');
console.log(' $ jade templates');
console.log('');
console.log(' # create {foo,bar}.html');
console.log(' $ jade {foo,bar}.jade');
console.log('');
console.log(' # jade over stdio');
console.log(' $ jade < my.jade > my.html');
console.log('');
console.log(' # jade over stdio');
console.log(' $ echo "h1 Jade!" | jade');
console.log('');
console.log(' # foo, bar dirs rendering to /tmp');
console.log(' $ jade foo bar --out /tmp ');
console.log('');
});
program.parse(process.argv);
// options given, parse them
if (program.obj) options = eval('(' + program.obj + ')');
// --filename
if (program.path) options.filename = program.path;
// --no-debug
options.compileDebug = program.debug;
// --client
options.client = program.client;
// --pretty
options.pretty = program.pretty;
// left-over args are file paths
var files = program.args;
// compile files
if (files.length) {
console.log();
files.forEach(renderFile);
process.on('exit', console.log);
// stdio
} else {
stdin();
}
/**
* Compile from stdin.
*/
function stdin() {
var buf = '';
process.stdin.setEncoding('utf8');
process.stdin.on('data', function(chunk){ buf += chunk; });
process.stdin.on('end', function(){
var fn = jade.compile(buf, options);
var output = options.client
? fn.toString()
: fn(options);
process.stdout.write(output);
}).resume();
}
/**
* Process the given path, compiling the jade files found.
* Always walk the subdirectories.
*/
function renderFile(path) {
var re = /\.jade$/;
fs.lstat(path, function(err, stat) {
if (err) throw err;
// Found jade file
if (stat.isFile() && re.test(path)) {
fs.readFile(path, 'utf8', function(err, str){
if (err) throw err;
options.filename = path;
var fn = jade.compile(str, options);
var extname = options.client ? '.js' : '.html';
path = path.replace(re, extname);
if (program.out) path = join(program.out, basename(path));
var dir = resolve(dirname(path));
mkdirp(dir, 0755, function(err){
if (err) throw err;
var output = options.client
? fn.toString()
: fn(options);
fs.writeFile(path, output, function(err){
if (err) throw err;
console.log(' \033[90mrendered \033[36m%s\033[0m', path);
});
});
});
// Found directory
} else if (stat.isDirectory()) {
fs.readdir(path, function(err, files) {
if (err) throw err;
files.map(function(filename) {
return path + '/' + filename;
}).forEach(renderFile);
});
}
});
}

4
node_modules/jade/index.js generated vendored Normal file
View File

@@ -0,0 +1,4 @@
module.exports = process.env.JADE_COV
? require('./lib-cov/jade')
: require('./lib/jade');

3586
node_modules/jade/jade.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

510
node_modules/jade/jade.md generated vendored Normal file
View File

@@ -0,0 +1,510 @@
# Jade
The jade template engine for node.js
## Synopsis
jade [-h|--help] [-v|--version] [-o|--obj STR]
[-O|--out DIR] [-p|--path PATH] [-P|--pretty]
[-c|--client] [-D|--no-debug]
## Examples
translate jade the templates dir
$ jade templates
create {foo,bar}.html
$ jade {foo,bar}.jade
jade over stdio
$ jade < my.jade > my.html
jade over s
$ echo "h1 Jade!" | jade
foo, bar dirs rendering to /tmp
$ jade foo bar --out /tmp
compile client-side templates without debugging
instrumentation, making the output javascript
very light-weight. This requires runtime.js
in your projects.
$ jade --client --no-debug < my.jade
## Tags
Tags are simply nested via whitespace, closing
tags defined for you. These indents are called "blocks".
ul
li
a Foo
li
a Bar
You may have several tags in one "block":
ul
li
a Foo
a Bar
a Baz
## Self-closing Tags
Some tags are flagged as self-closing by default, such
as `meta`, `link`, and so on. To explicitly self-close
a tag simply append the `/` character:
foo/
foo(bar='baz')/
Would yield:
<foo/>
<foo bar="baz"/>
## Attributes
Tag attributes look similar to HTML, however
the values are regular JavaScript, here are
some examples:
a(href='google.com') Google
a(class='button', href='google.com') Google
As mentioned the attribute values are just JavaScript,
this means ternary operations and other JavaScript expressions
work just fine:
body(class=user.authenticated ? 'authenticated' : 'anonymous')
a(href=user.website || 'http://google.com')
Multiple lines work too:
input(type='checkbox',
name='agreement',
checked)
Multiple lines without the comma work fine:
input(type='checkbox'
name='agreement'
checked)
Funky whitespace? fine:
input(
type='checkbox'
name='agreement'
checked)
## Boolean attributes
Boolean attributes are mirrored by Jade, and accept
bools, aka _true_ or _false_. When no value is specified
_true_ is assumed. For example:
input(type="checkbox", checked)
// => "<input type="checkbox" checked="checked" />"
For example if the checkbox was for an agreement, perhaps `user.agreed`
was _true_ the following would also output 'checked="checked"':
input(type="checkbox", checked=user.agreed)
## Class attributes
The _class_ attribute accepts an array of classes,
this can be handy when generated from a javascript
function etc:
classes = ['foo', 'bar', 'baz']
a(class=classes)
// => "<a class="foo bar baz"></a>"
## Class literal
Classes may be defined using a ".CLASSNAME" syntax:
.button
// => "<div class="button"></div>"
Or chained:
.large.button
// => "<div class="large button"></div>"
The previous defaulted to divs, however you
may also specify the tag type:
h1.title My Title
// => "<h1 class="title">My Title</h1>"
## Id literal
Much like the class literal there's an id literal:
#user-1
// => "<div id="user-1"></div>"
Again we may specify the tag as well:
ul#menu
li: a(href='/home') Home
li: a(href='/store') Store
li: a(href='/contact') Contact
Finally all of these may be used in any combination,
the following are all valid tags:
a.button#contact(style: 'color: red') Contact
a.button(style: 'color: red')#contact Contact
a(style: 'color: red').button#contact Contact
## Block expansion
Jade supports the concept of "block expansion", in which
using a trailing ":" after a tag will inject a block:
ul
li: a Foo
li: a Bar
li: a Baz
## Text
Arbitrary text may follow tags:
p Welcome to my site
yields:
<p>Welcome to my site</p>
## Pipe text
Another form of text is "pipe" text. Pipes act
as the text margin for large bodies of text.
p
| This is a large
| body of text for
| this tag.
|
| Nothing too
| exciting.
yields:
<p>This is a large
body of text for
this tag.
Nothing too
exciting.
</p>
Using pipes we can also specify regular Jade tags
within the text:
p
| Click to visit
a(href='http://google.com') Google
| if you want.
## Text only tags
As an alternative to pipe text you may add
a trailing "." to indicate that the block
contains nothing but plain-text, no tags:
p.
This is a large
body of text for
this tag.
Nothing too
exciting.
Some tags are text-only by default, for example
_script_, _textarea_, and _style_ tags do not
contain nested HTML so Jade implies the trailing ".":
script
if (foo) {
bar();
}
style
body {
padding: 50px;
font: 14px Helvetica;
}
## Template script tags
Sometimes it's useful to define HTML in script
tags using Jade, typically for client-side templates.
To do this simply give the _script_ tag an arbitrary
_type_ attribute such as _text/x-template_:
script(type='text/template')
h1 Look!
p Jade still works in here!
## Interpolation
Both plain-text and piped-text support interpolation,
which comes in two forms, escapes and non-escaped. The
following will output the _user.name_ in the paragraph
but HTML within it will be escaped to prevent XSS attacks:
p Welcome #{user.name}
The following syntax is identical however it will _not_ escape
HTML, and should only be used with strings that you trust:
p Welcome !{user.name}
## Inline HTML
Sometimes constructing small inline snippets of HTML
in Jade can be annoying, luckily we can add plain
HTML as well:
p Welcome <em>#{user.name}</em>
## Code
To buffer output with Jade simply use _=_ at the beginning
of a line or after a tag. This method escapes any HTML
present in the string.
p= user.description
To buffer output unescaped use the _!=_ variant, but again
be careful of XSS.
p!= user.description
The final way to mess with JavaScript code in Jade is the unbuffered
_-_, which can be used for conditionals, defining variables etc:
- var user = { description: 'foo bar baz' }
#user
- if (user.description) {
h2 Description
p.description= user.description
- }
When compiled blocks are wrapped in anonymous functions, so the
following is also valid, without braces:
- var user = { description: 'foo bar baz' }
#user
- if (user.description)
h2 Description
p.description= user.description
If you really want you could even use `.forEach()` and others:
- users.forEach(function(user){
.user
h2= user.name
p User #{user.name} is #{user.age} years old
- })
Taking this further Jade provides some syntax for conditionals,
iteration, switch statements etc. Let's look at those next!
## Assignment
Jade's first-class assignment is simple, simply use the _=_
operator and Jade will _var_ it for you. The following are equivalent:
- var user = { name: 'tobi' }
user = { name: 'tobi' }
## Conditionals
Jade's first-class conditional syntax allows for optional
parenthesis, and you may now omit the leading _-_ otherwise
it's identical, still just regular javascript:
user = { description: 'foo bar baz' }
#user
if user.description
h2 Description
p.description= user.description
Jade provides the negated version, _unless_ as well, the following
are equivalent:
- if (!(user.isAnonymous))
p You're logged in as #{user.name}
unless user.isAnonymous
p You're logged in as #{user.name}
## Iteration
JavaScript's _for_ loops don't look very declarative, so Jade
also provides its own _for_ loop construct, aliased as _each_:
for user in users
.user
h2= user.name
p user #{user.name} is #{user.age} year old
As mentioned _each_ is identical:
each user in users
.user
h2= user.name
If necessary the index is available as well:
for user, i in users
.user(class='user-#{i}')
h2= user.name
Remember, it's just JavaScript:
ul#letters
for letter in ['a', 'b', 'c']
li= letter
## Mixins
Mixins provide a way to define jade "functions" which "mix in"
their contents when called. This is useful for abstracting
out large fragments of Jade.
The simplest possible mixin which accepts no arguments might
look like this:
mixin hello
p Hello
You use a mixin by placing `+` before the name:
+hello
For something a little more dynamic, mixins can take
arguments, the mixin itself is converted to a javascript
function internally:
mixin hello(user)
p Hello #{user}
+hello('Tobi')
Yields:
<p>Hello Tobi</p>
Mixins may optionally take blocks, when a block is passed
its contents becomes the implicit `block` argument. For
example here is a mixin passed a block, and also invoked
without passing a block:
mixin article(title)
.article
.article-wrapper
h1= title
if block
block
else
p No content provided
+article('Hello world')
+article('Hello world')
p This is my
p Amazing article
yields:
<div class="article">
<div class="article-wrapper">
<h1>Hello world</h1>
<p>No content provided</p>
</div>
</div>
<div class="article">
<div class="article-wrapper">
<h1>Hello world</h1>
<p>This is my</p>
<p>Amazing article</p>
</div>
</div>
Mixins can even take attributes, just like a tag. When
attributes are passed they become the implicit `attributes`
argument. Individual attributes can be accessed just like
normal object properties:
mixin centered
.centered(class=attributes.class)
block
+centered.bold Hello world
+centered.red
p This is my
p Amazing article
yields:
<div class="centered bold">Hello world</div>
<div class="centered red">
<p>This is my</p>
<p>Amazing article</p>
</div>
If you use `attributes` directly, *all* passed attributes
get used:
mixin link
a.menu(attributes)
block
+link.highlight(href='#top') Top
+link#sec1.plain(href='#section1') Section 1
+link#sec2.plain(href='#section2') Section 2
yields:
<a href="#top" class="highlight menu">Top</a>
<a id="sec1" href="#section1" class="plain menu">Section 1</a>
<a id="sec2" href="#section2" class="plain menu">Section 2</a>
If you pass arguments, they must directly follow the mixin:
mixin list(arr)
if block
.title
block
ul(attributes)
each item in arr
li= item
+list(['foo', 'bar', 'baz'])(id='myList', class='bold')
yields:
<ul id="myList" class="bold">
<li>foo</li>
<li>bar</li>
<li>baz</li>
</ul>

2
node_modules/jade/jade.min.js generated vendored Normal file

File diff suppressed because one or more lines are too long

642
node_modules/jade/lib/compiler.js generated vendored Normal file
View File

@@ -0,0 +1,642 @@
/*!
* Jade - Compiler
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
* MIT Licensed
*/
/**
* Module dependencies.
*/
var nodes = require('./nodes')
, filters = require('./filters')
, doctypes = require('./doctypes')
, selfClosing = require('./self-closing')
, runtime = require('./runtime')
, utils = require('./utils');
// if browser
//
// if (!Object.keys) {
// Object.keys = function(obj){
// var arr = [];
// for (var key in obj) {
// if (obj.hasOwnProperty(key)) {
// arr.push(key);
// }
// }
// return arr;
// }
// }
//
// if (!String.prototype.trimLeft) {
// String.prototype.trimLeft = function(){
// return this.replace(/^\s+/, '');
// }
// }
//
// end
/**
* Initialize `Compiler` with the given `node`.
*
* @param {Node} node
* @param {Object} options
* @api public
*/
var Compiler = module.exports = function Compiler(node, options) {
this.options = options = options || {};
this.node = node;
this.hasCompiledDoctype = false;
this.hasCompiledTag = false;
this.pp = options.pretty || false;
this.debug = false !== options.compileDebug;
this.indents = 0;
this.parentIndents = 0;
if (options.doctype) this.setDoctype(options.doctype);
};
/**
* Compiler prototype.
*/
Compiler.prototype = {
/**
* Compile parse tree to JavaScript.
*
* @api public
*/
compile: function(){
this.buf = ['var interp;'];
if (this.pp) this.buf.push("var __indent = [];");
this.lastBufferedIdx = -1;
this.visit(this.node);
return this.buf.join('\n');
},
/**
* Sets the default doctype `name`. Sets terse mode to `true` when
* html 5 is used, causing self-closing tags to end with ">" vs "/>",
* and boolean attributes are not mirrored.
*
* @param {string} name
* @api public
*/
setDoctype: function(name){
var doctype = doctypes[(name || 'default').toLowerCase()];
doctype = doctype || '<!DOCTYPE ' + name + '>';
this.doctype = doctype;
this.terse = '5' == name || 'html' == name;
this.xml = 0 == this.doctype.indexOf('<?xml');
},
/**
* Buffer the given `str` optionally escaped.
*
* @param {String} str
* @param {Boolean} esc
* @api public
*/
buffer: function(str, esc){
if (esc) str = utils.escape(str);
if (this.lastBufferedIdx == this.buf.length) {
this.lastBuffered += str;
this.buf[this.lastBufferedIdx - 1] = "buf.push('" + this.lastBuffered + "');"
} else {
this.buf.push("buf.push('" + str + "');");
this.lastBuffered = str;
this.lastBufferedIdx = this.buf.length;
}
},
/**
* Buffer an indent based on the current `indent`
* property and an additional `offset`.
*
* @param {Number} offset
* @param {Boolean} newline
* @api public
*/
prettyIndent: function(offset, newline){
offset = offset || 0;
newline = newline ? '\\n' : '';
this.buffer(newline + Array(this.indents + offset).join(' '));
if (this.parentIndents)
this.buf.push("buf.push.apply(buf, __indent);");
},
/**
* Visit `node`.
*
* @param {Node} node
* @api public
*/
visit: function(node){
var debug = this.debug;
if (debug) {
this.buf.push('__jade.unshift({ lineno: ' + node.line
+ ', filename: ' + (node.filename
? JSON.stringify(node.filename)
: '__jade[0].filename')
+ ' });');
}
// Massive hack to fix our context
// stack for - else[ if] etc
if (false === node.debug && this.debug) {
this.buf.pop();
this.buf.pop();
}
this.visitNode(node);
if (debug) this.buf.push('__jade.shift();');
},
/**
* Visit `node`.
*
* @param {Node} node
* @api public
*/
visitNode: function(node){
var name = node.constructor.name
|| node.constructor.toString().match(/function ([^(\s]+)()/)[1];
return this['visit' + name](node);
},
/**
* Visit case `node`.
*
* @param {Literal} node
* @api public
*/
visitCase: function(node){
var _ = this.withinCase;
this.withinCase = true;
this.buf.push('switch (' + node.expr + '){');
this.visit(node.block);
this.buf.push('}');
this.withinCase = _;
},
/**
* Visit when `node`.
*
* @param {Literal} node
* @api public
*/
visitWhen: function(node){
if ('default' == node.expr) {
this.buf.push('default:');
} else {
this.buf.push('case ' + node.expr + ':');
}
this.visit(node.block);
this.buf.push(' break;');
},
/**
* Visit literal `node`.
*
* @param {Literal} node
* @api public
*/
visitLiteral: function(node){
var str = node.str.replace(/\n/g, '\\\\n');
this.buffer(str);
},
/**
* Visit all nodes in `block`.
*
* @param {Block} block
* @api public
*/
visitBlock: function(block){
var len = block.nodes.length
, escape = this.escape
, pp = this.pp
// Block keyword has a special meaning in mixins
if (this.parentIndents && block.mode) {
if (pp) this.buf.push("__indent.push('" + Array(this.indents + 1).join(' ') + "');")
this.buf.push('block && block();');
if (pp) this.buf.push("__indent.pop();")
return;
}
// Pretty print multi-line text
if (pp && len > 1 && !escape && block.nodes[0].isText && block.nodes[1].isText)
this.prettyIndent(1, true);
for (var i = 0; i < len; ++i) {
// Pretty print text
if (pp && i > 0 && !escape && block.nodes[i].isText && block.nodes[i-1].isText)
this.prettyIndent(1, false);
this.visit(block.nodes[i]);
// Multiple text nodes are separated by newlines
if (block.nodes[i+1] && block.nodes[i].isText && block.nodes[i+1].isText)
this.buffer('\\n');
}
},
/**
* Visit `doctype`. Sets terse mode to `true` when html 5
* is used, causing self-closing tags to end with ">" vs "/>",
* and boolean attributes are not mirrored.
*
* @param {Doctype} doctype
* @api public
*/
visitDoctype: function(doctype){
if (doctype && (doctype.val || !this.doctype)) {
this.setDoctype(doctype.val || 'default');
}
if (this.doctype) this.buffer(this.doctype);
this.hasCompiledDoctype = true;
},
/**
* Visit `mixin`, generating a function that
* may be called within the template.
*
* @param {Mixin} mixin
* @api public
*/
visitMixin: function(mixin){
var name = mixin.name.replace(/-/g, '_') + '_mixin'
, args = mixin.args || ''
, block = mixin.block
, attrs = mixin.attrs
, pp = this.pp;
if (mixin.call) {
if (pp) this.buf.push("__indent.push('" + Array(this.indents + 1).join(' ') + "');")
if (block || attrs.length) {
this.buf.push(name + '.call({');
if (block) {
this.buf.push('block: function(){');
// Render block with no indents, dynamically added when rendered
this.parentIndents++;
var _indents = this.indents;
this.indents = 0;
this.visit(mixin.block);
this.indents = _indents;
this.parentIndents--;
if (attrs.length) {
this.buf.push('},');
} else {
this.buf.push('}');
}
}
if (attrs.length) {
var val = this.attrs(attrs);
if (val.inherits) {
this.buf.push('attributes: merge({' + val.buf
+ '}, attributes), escaped: merge(' + val.escaped + ', escaped, true)');
} else {
this.buf.push('attributes: {' + val.buf + '}, escaped: ' + val.escaped);
}
}
if (args) {
this.buf.push('}, ' + args + ');');
} else {
this.buf.push('});');
}
} else {
this.buf.push(name + '(' + args + ');');
}
if (pp) this.buf.push("__indent.pop();")
} else {
this.buf.push('var ' + name + ' = function(' + args + '){');
this.buf.push('var block = this.block, attributes = this.attributes || {}, escaped = this.escaped || {};');
this.parentIndents++;
this.visit(block);
this.parentIndents--;
this.buf.push('};');
}
},
/**
* Visit `tag` buffering tag markup, generating
* attributes, visiting the `tag`'s code and block.
*
* @param {Tag} tag
* @api public
*/
visitTag: function(tag){
this.indents++;
var name = tag.name
, pp = this.pp;
if (tag.buffer) name = "' + (" + name + ") + '";
if (!this.hasCompiledTag) {
if (!this.hasCompiledDoctype && 'html' == name) {
this.visitDoctype();
}
this.hasCompiledTag = true;
}
// pretty print
if (pp && !tag.isInline())
this.prettyIndent(0, true);
if ((~selfClosing.indexOf(name) || tag.selfClosing) && !this.xml) {
this.buffer('<' + name);
this.visitAttributes(tag.attrs);
this.terse
? this.buffer('>')
: this.buffer('/>');
} else {
// Optimize attributes buffering
if (tag.attrs.length) {
this.buffer('<' + name);
if (tag.attrs.length) this.visitAttributes(tag.attrs);
this.buffer('>');
} else {
this.buffer('<' + name + '>');
}
if (tag.code) this.visitCode(tag.code);
this.escape = 'pre' == tag.name;
this.visit(tag.block);
// pretty print
if (pp && !tag.isInline() && 'pre' != tag.name && !tag.canInline())
this.prettyIndent(0, true);
this.buffer('</' + name + '>');
}
this.indents--;
},
/**
* Visit `filter`, throwing when the filter does not exist.
*
* @param {Filter} filter
* @api public
*/
visitFilter: function(filter){
var fn = filters[filter.name];
// unknown filter
if (!fn) {
if (filter.isASTFilter) {
throw new Error('unknown ast filter "' + filter.name + ':"');
} else {
throw new Error('unknown filter ":' + filter.name + '"');
}
}
if (filter.isASTFilter) {
this.buf.push(fn(filter.block, this, filter.attrs));
} else {
var text = filter.block.nodes.map(function(node){ return node.val }).join('\n');
filter.attrs = filter.attrs || {};
filter.attrs.filename = this.options.filename;
this.buffer(utils.text(fn(text, filter.attrs)));
}
},
/**
* Visit `text` node.
*
* @param {Text} text
* @api public
*/
visitText: function(text){
text = utils.text(text.val.replace(/\\/g, '\\\\'));
if (this.escape) text = escape(text);
this.buffer(text);
},
/**
* Visit a `comment`, only buffering when the buffer flag is set.
*
* @param {Comment} comment
* @api public
*/
visitComment: function(comment){
if (!comment.buffer) return;
if (this.pp) this.prettyIndent(1, true);
this.buffer('<!--' + utils.escape(comment.val) + '-->');
},
/**
* Visit a `BlockComment`.
*
* @param {Comment} comment
* @api public
*/
visitBlockComment: function(comment){
if (!comment.buffer) return;
if (0 == comment.val.trim().indexOf('if')) {
this.buffer('<!--[' + comment.val.trim() + ']>');
this.visit(comment.block);
this.buffer('<![endif]-->');
} else {
this.buffer('<!--' + comment.val);
this.visit(comment.block);
this.buffer('-->');
}
},
/**
* Visit `code`, respecting buffer / escape flags.
* If the code is followed by a block, wrap it in
* a self-calling function.
*
* @param {Code} code
* @api public
*/
visitCode: function(code){
// Wrap code blocks with {}.
// we only wrap unbuffered code blocks ATM
// since they are usually flow control
// Buffer code
if (code.buffer) {
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 + ");");
} else {
this.buf.push(code.val);
}
// Block support
if (code.block) {
if (!code.buffer) this.buf.push('{');
this.visit(code.block);
if (!code.buffer) this.buf.push('}');
}
},
/**
* Visit `each` block.
*
* @param {Each} each
* @api public
*/
visitEach: function(each){
this.buf.push(''
+ '// iterate ' + each.obj + '\n'
+ ';(function(){\n'
+ ' if (\'number\' == typeof ' + each.obj + '.length) {\n'
+ ' for (var ' + each.key + ' = 0, $$l = ' + each.obj + '.length; ' + each.key + ' < $$l; ' + each.key + '++) {\n'
+ ' var ' + each.val + ' = ' + each.obj + '[' + each.key + '];\n');
this.visit(each.block);
this.buf.push(''
+ ' }\n'
+ ' } else {\n'
+ ' for (var ' + each.key + ' in ' + each.obj + ') {\n'
// if browser
// + ' if (' + each.obj + '.hasOwnProperty(' + each.key + ')){'
// end
+ ' var ' + each.val + ' = ' + each.obj + '[' + each.key + '];\n');
this.visit(each.block);
// if browser
// this.buf.push(' }\n');
// end
this.buf.push(' }\n }\n}).call(this);\n');
},
/**
* Visit `attrs`.
*
* @param {Array} attrs
* @api public
*/
visitAttributes: function(attrs){
var val = this.attrs(attrs);
if (val.inherits) {
this.buf.push("buf.push(attrs(merge({ " + val.buf +
" }, attributes), merge(" + val.escaped + ", escaped, true)));");
} else if (val.constant) {
eval('var buf={' + val.buf + '};');
this.buffer(runtime.attrs(buf, JSON.parse(val.escaped)), true);
} else {
this.buf.push("buf.push(attrs({ " + val.buf + " }, " + val.escaped + "));");
}
},
/**
* Compile attributes.
*/
attrs: function(attrs){
var buf = []
, classes = []
, escaped = {}
, constant = attrs.every(function(attr){ return isConstant(attr.val) })
, inherits = false;
if (this.terse) buf.push('terse: true');
attrs.forEach(function(attr){
if (attr.name == 'attributes') return inherits = true;
escaped[attr.name] = attr.escaped;
if (attr.name == 'class') {
classes.push('(' + attr.val + ')');
} else {
var pair = "'" + attr.name + "':(" + attr.val + ')';
buf.push(pair);
}
});
if (classes.length) {
classes = classes.join(" + ' ' + ");
buf.push("class: " + classes);
}
return {
buf: buf.join(', ').replace('class:', '"class":'),
escaped: JSON.stringify(escaped),
inherits: inherits,
constant: constant
};
}
};
/**
* Check if expression can be evaluated to a constant
*
* @param {String} expression
* @return {Boolean}
* @api private
*/
function isConstant(val){
// Check strings/literals
if (/^ *("([^"\\]*(\\.[^"\\]*)*)"|'([^'\\]*(\\.[^'\\]*)*)'|true|false|null|undefined) *$/i.test(val))
return true;
// Check numbers
if (!isNaN(Number(val)))
return true;
// Check arrays
var matches;
if (matches = /^ *\[(.*)\] *$/.exec(val))
return matches[1].split(',').every(isConstant);
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;');
}

18
node_modules/jade/lib/doctypes.js generated vendored Normal file
View File

@@ -0,0 +1,18 @@
/*!
* Jade - doctypes
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
* MIT Licensed
*/
module.exports = {
'5': '<!DOCTYPE html>'
, 'default': '<!DOCTYPE html>'
, 'xml': '<?xml version="1.0" encoding="utf-8" ?>'
, 'transitional': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'
, 'strict': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'
, 'frameset': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">'
, '1.1': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">'
, 'basic': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">'
, 'mobile': '<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd">'
};

97
node_modules/jade/lib/filters.js generated vendored Normal file
View File

@@ -0,0 +1,97 @@
/*!
* Jade - filters
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
* MIT Licensed
*/
module.exports = {
/**
* Wrap text with CDATA block.
*/
cdata: function(str){
return '<![CDATA[\\n' + str + '\\n]]>';
},
/**
* Transform sass to css, wrapped in style tags.
*/
sass: function(str){
str = str.replace(/\\n/g, '\n');
var sass = require('sass').render(str).replace(/\n/g, '\\n');
return '<style type="text/css">' + sass + '</style>';
},
/**
* Transform stylus to css, wrapped in style tags.
*/
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.
*/
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.
*/
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.');
}
}
}
}
str = str.replace(/\\n/g, '\n');
return md.parse(str).replace(/\n/g, '\\n').replace(/'/g,'&#39;');
},
/**
* Transform coffeescript to javascript.
*/
coffeescript: function(str){
str = str.replace(/\\n/g, '\n');
var js = require('coffee-script').compile(str).replace(/\\/g, '\\\\').replace(/\n/g, '\\n');
return '<script type="text/javascript">\\n' + js + '</script>';
}
};

28
node_modules/jade/lib/inline-tags.js generated vendored Normal file
View File

@@ -0,0 +1,28 @@
/*!
* Jade - inline tags
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
* MIT Licensed
*/
module.exports = [
'a'
, 'abbr'
, 'acronym'
, 'b'
, 'br'
, 'code'
, 'em'
, 'font'
, 'i'
, 'img'
, 'ins'
, 'kbd'
, 'map'
, 'samp'
, 'small'
, 'span'
, 'strong'
, 'sub'
, 'sup'
];

237
node_modules/jade/lib/jade.js generated vendored Normal file
View File

@@ -0,0 +1,237 @@
/*!
* Jade
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
* MIT Licensed
*/
/**
* Module dependencies.
*/
var Parser = require('./parser')
, Lexer = require('./lexer')
, Compiler = require('./compiler')
, runtime = require('./runtime')
// if node
, fs = require('fs');
// end
/**
* Library version.
*/
exports.version = '0.26.3';
/**
* Expose self closing tags.
*/
exports.selfClosing = require('./self-closing');
/**
* Default supported doctypes.
*/
exports.doctypes = require('./doctypes');
/**
* Text filters.
*/
exports.filters = require('./filters');
/**
* Utilities.
*/
exports.utils = require('./utils');
/**
* Expose `Compiler`.
*/
exports.Compiler = Compiler;
/**
* Expose `Parser`.
*/
exports.Parser = Parser;
/**
* Expose `Lexer`.
*/
exports.Lexer = Lexer;
/**
* Nodes.
*/
exports.nodes = require('./nodes');
/**
* Jade runtime helpers.
*/
exports.runtime = runtime;
/**
* Template function cache.
*/
exports.cache = {};
/**
* Parse the given `str` of jade and return a function body.
*
* @param {String} str
* @param {Object} options
* @return {String}
* @api private
*/
function parse(str, options){
try {
// Parse
var parser = new Parser(str, options.filename, options);
// Compile
var compiler = new (options.compiler || Compiler)(parser.parse(), options)
, js = compiler.compile();
// Debug compiler
if (options.debug) {
console.error('\nCompiled Function:\n\n\033[90m%s\033[0m', js.replace(/^/gm, ' '));
}
return ''
+ 'var buf = [];\n'
+ (options.self
? 'var self = locals || {};\n' + js
: 'with (locals || {}) {\n' + js + '\n}\n')
+ 'return buf.join("");';
} catch (err) {
parser = parser.context();
runtime.rethrow(err, parser.filename, parser.lexer.lineno);
}
}
/**
* Compile a `Function` representation of the given jade `str`.
*
* Options:
*
* - `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
*
* @param {String} str
* @param {Options} options
* @return {Function}
* @api public
*/
exports.compile = function(str, options){
var options = options || {}
, client = options.client
, filename = options.filename
? JSON.stringify(options.filename)
: 'undefined'
, fn;
if (options.compileDebug !== false) {
fn = [
'var __jade = [{ lineno: 1, filename: ' + filename + ' }];'
, 'try {'
, parse(String(str), options)
, '} catch (err) {'
, ' rethrow(err, __jade[0].filename, __jade[0].lineno);'
, '}'
].join('\n');
} else {
fn = parse(String(str), options);
}
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);
};
};
/**
* Render the given `str` of jade and invoke
* the callback `fn(err, str)`.
*
* Options:
*
* - `cache` enable template caching
* - `filename` filename required for `include` / `extends` and caching
*
* @param {String} str
* @param {Object|Function} options or fn
* @param {Function} fn
* @api public
*/
exports.render = function(str, options, fn){
// swap args
if ('function' == typeof options) {
fn = options, options = {};
}
// cache requires .filename
if (options.cache && !options.filename) {
return fn(new Error('the "filename" option is required for caching'));
}
try {
var path = options.filename;
var tmpl = options.cache
? exports.cache[path] || (exports.cache[path] = exports.compile(str, options))
: exports.compile(str, options);
fn(null, tmpl(options));
} catch (err) {
fn(err);
}
};
/**
* Render a Jade file at the given `path` and callback `fn(err, str)`.
*
* @param {String} path
* @param {Object|Function} options or callback
* @param {Function} fn
* @api public
*/
exports.renderFile = function(path, options, fn){
var key = path + ':string';
if ('function' == typeof options) {
fn = options, options = {};
}
try {
options.filename = path;
var str = options.cache
? exports.cache[key] || (exports.cache[key] = fs.readFileSync(path, 'utf8'))
: fs.readFileSync(path, 'utf8');
exports.render(str, options, fn);
} catch (err) {
fn(err);
}
};
/**
* Express support.
*/
exports.__express = exports.renderFile;

771
node_modules/jade/lib/lexer.js generated vendored Normal file
View File

@@ -0,0 +1,771 @@
/*!
* Jade - Lexer
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
* MIT Licensed
*/
/**
* Initialize `Lexer` with the given `str`.
*
* Options:
*
* - `colons` allow colons for attr delimiters
*
* @param {String} str
* @param {Object} options
* @api private
*/
var Lexer = module.exports = function Lexer(str, options) {
options = options || {};
this.input = str.replace(/\r\n|\r/g, '\n');
this.colons = options.colons;
this.deferredTokens = [];
this.lastIndents = 0;
this.lineno = 1;
this.stash = [];
this.indentStack = [];
this.indentRe = null;
this.pipeless = false;
};
/**
* Lexer prototype.
*/
Lexer.prototype = {
/**
* Construct a token with the given `type` and `val`.
*
* @param {String} type
* @param {String} val
* @return {Object}
* @api private
*/
tok: function(type, val){
return {
type: type
, line: this.lineno
, val: val
}
},
/**
* Consume the given `len` of input.
*
* @param {Number} len
* @api private
*/
consume: function(len){
this.input = this.input.substr(len);
},
/**
* Scan for `type` with the given `regexp`.
*
* @param {String} type
* @param {RegExp} regexp
* @return {Object}
* @api private
*/
scan: function(regexp, type){
var captures;
if (captures = regexp.exec(this.input)) {
this.consume(captures[0].length);
return this.tok(type, captures[1]);
}
},
/**
* Defer the given `tok`.
*
* @param {Object} tok
* @api private
*/
defer: function(tok){
this.deferredTokens.push(tok);
},
/**
* Lookahead `n` tokens.
*
* @param {Number} n
* @return {Object}
* @api private
*/
lookahead: function(n){
var fetch = n - this.stash.length;
while (fetch-- > 0) this.stash.push(this.next());
return this.stash[--n];
},
/**
* Return the indexOf `start` / `end` delimiters.
*
* @param {String} start
* @param {String} end
* @return {Number}
* @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;
},
/**
* Stashed token.
*/
stashed: function() {
return this.stash.length
&& this.stash.shift();
},
/**
* Deferred token.
*/
deferred: function() {
return this.deferredTokens.length
&& this.deferredTokens.shift();
},
/**
* end-of-source.
*/
eos: function() {
if (this.input.length) return;
if (this.indentStack.length) {
this.indentStack.shift();
return this.tok('outdent');
} else {
return this.tok('eos');
}
},
/**
* Blank line.
*/
blank: function() {
var captures;
if (captures = /^\n *\n/.exec(this.input)) {
this.consume(captures[0].length - 1);
if (this.pipeless) return this.tok('text', '');
return this.next();
}
},
/**
* Comment.
*/
comment: function() {
var captures;
if (captures = /^ *\/\/(-)?([^\n]*)/.exec(this.input)) {
this.consume(captures[0].length);
var tok = this.tok('comment', captures[2]);
tok.buffer = '-' != captures[1];
return tok;
}
},
/**
* Interpolated tag.
*/
interpolation: function() {
var captures;
if (captures = /^#\{(.*?)\}/.exec(this.input)) {
this.consume(captures[0].length);
return this.tok('interpolation', captures[1]);
}
},
/**
* Tag.
*/
tag: function() {
var captures;
if (captures = /^(\w[-:\w]*)(\/?)/.exec(this.input)) {
this.consume(captures[0].length);
var tok, name = captures[1];
if (':' == name[name.length - 1]) {
name = name.slice(0, -1);
tok = this.tok('tag', name);
this.defer(this.tok(':'));
while (' ' == this.input[0]) this.input = this.input.substr(1);
} else {
tok = this.tok('tag', name);
}
tok.selfClosing = !! captures[2];
return tok;
}
},
/**
* Filter.
*/
filter: function() {
return this.scan(/^:(\w+)/, 'filter');
},
/**
* Doctype.
*/
doctype: function() {
return this.scan(/^(?:!!!|doctype) *([^\n]+)?/, 'doctype');
},
/**
* Id.
*/
id: function() {
return this.scan(/^#([\w-]+)/, 'id');
},
/**
* Class.
*/
className: function() {
return this.scan(/^\.([\w-]+)/, 'class');
},
/**
* Text.
*/
text: function() {
return this.scan(/^(?:\| ?| ?)?([^\n]+)/, 'text');
},
/**
* Extends.
*/
"extends": function() {
return this.scan(/^extends? +([^\n]+)/, 'extends');
},
/**
* Block prepend.
*/
prepend: function() {
var captures;
if (captures = /^prepend +([^\n]+)/.exec(this.input)) {
this.consume(captures[0].length);
var mode = 'prepend'
, name = captures[1]
, tok = this.tok('block', name);
tok.mode = mode;
return tok;
}
},
/**
* Block append.
*/
append: function() {
var captures;
if (captures = /^append +([^\n]+)/.exec(this.input)) {
this.consume(captures[0].length);
var mode = 'append'
, name = captures[1]
, tok = this.tok('block', name);
tok.mode = mode;
return tok;
}
},
/**
* Block.
*/
block: function() {
var captures;
if (captures = /^block\b *(?:(prepend|append) +)?([^\n]*)/.exec(this.input)) {
this.consume(captures[0].length);
var mode = captures[1] || 'replace'
, name = captures[2]
, tok = this.tok('block', name);
tok.mode = mode;
return tok;
}
},
/**
* Yield.
*/
yield: function() {
return this.scan(/^yield */, 'yield');
},
/**
* Include.
*/
include: function() {
return this.scan(/^include +([^\n]+)/, 'include');
},
/**
* Case.
*/
"case": function() {
return this.scan(/^case +([^\n]+)/, 'case');
},
/**
* When.
*/
when: function() {
return this.scan(/^when +([^:\n]+)/, 'when');
},
/**
* Default.
*/
"default": function() {
return this.scan(/^default */, 'default');
},
/**
* Assignment.
*/
assignment: function() {
var captures;
if (captures = /^(\w+) += *([^;\n]+)( *;? *)/.exec(this.input)) {
this.consume(captures[0].length);
var name = captures[1]
, val = captures[2];
return this.tok('code', 'var ' + name + ' = (' + val + ');');
}
},
/**
* Call mixin.
*/
call: function(){
var captures;
if (captures = /^\+([-\w]+)/.exec(this.input)) {
this.consume(captures[0].length);
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];
}
}
return tok;
}
},
/**
* Mixin.
*/
mixin: function(){
var captures;
if (captures = /^mixin +([-\w]+)(?: *\((.*)\))?/.exec(this.input)) {
this.consume(captures[0].length);
var tok = this.tok('mixin', captures[1]);
tok.args = captures[2];
return tok;
}
},
/**
* Conditional.
*/
conditional: function() {
var captures;
if (captures = /^(if|unless|else if|else)\b([^\n]*)/.exec(this.input)) {
this.consume(captures[0].length);
var type = captures[1]
, js = captures[2];
switch (type) {
case 'if': js = 'if (' + js + ')'; break;
case 'unless': js = 'if (!(' + js + '))'; break;
case 'else if': js = 'else if (' + js + ')'; break;
case 'else': js = 'else'; break;
}
return this.tok('code', js);
}
},
/**
* While.
*/
"while": function() {
var captures;
if (captures = /^while +([^\n]+)/.exec(this.input)) {
this.consume(captures[0].length);
return this.tok('code', 'while (' + captures[1] + ')');
}
},
/**
* Each.
*/
each: function() {
var captures;
if (captures = /^(?:- *)?(?:each|for) +(\w+)(?: *, *(\w+))? * in *([^\n]+)/.exec(this.input)) {
this.consume(captures[0].length);
var tok = this.tok('each', captures[1]);
tok.key = captures[2] || '$index';
tok.code = captures[3];
return tok;
}
},
/**
* Code.
*/
code: function() {
var captures;
if (captures = /^(!?=|-)([^\n]+)/.exec(this.input)) {
this.consume(captures[0].length);
var flags = captures[1];
captures[1] = captures[2];
var tok = this.tok('code', captures[1]);
tok.escape = flags[0] === '=';
tok.buffer = flags[0] === '=' || flags[1] === '=';
return tok;
}
},
/**
* Attributes.
*/
attrs: function() {
if ('(' == this.input.charAt(0)) {
var index = this.indexOfDelimiters('(', ')')
, str = this.input.substr(1, index-1)
, tok = this.tok('attrs')
, len = str.length
, colons = this.colons
, states = ['key']
, escapedAttr
, key = ''
, val = ''
, quote
, c
, p;
function state(){
return states[states.length - 1];
}
function interpolate(attr) {
return attr.replace(/#\{([^}]+)\}/g, function(_, expr){
return quote + " + (" + expr + ") + " + quote;
});
}
this.consume(index + 1);
tok.attrs = {};
tok.escaped = {};
function parse(c) {
var real = c;
// TODO: remove when people fix ":"
if (colons && ':' == c) c = '=';
switch (c) {
case ',':
case '\n':
switch (state()) {
case 'expr':
case 'array':
case 'string':
case 'object':
val += c;
break;
default:
states.push('key');
val = val.trim();
key = key.trim();
if ('' == key) return;
key = key.replace(/^['"]|['"]$/g, '').replace('!', '');
tok.escaped[key] = escapedAttr;
tok.attrs[key] = '' == val
? true
: interpolate(val);
key = val = '';
}
break;
case '=':
switch (state()) {
case 'key char':
key += real;
break;
case 'val':
case 'expr':
case 'array':
case 'string':
case 'object':
val += real;
break;
default:
escapedAttr = '!' != p;
states.push('val');
}
break;
case '(':
if ('val' == state()
|| 'expr' == state()) states.push('expr');
val += c;
break;
case ')':
if ('expr' == state()
|| 'val' == state()) states.pop();
val += c;
break;
case '{':
if ('val' == state()) states.push('object');
val += c;
break;
case '}':
if ('object' == state()) states.pop();
val += c;
break;
case '[':
if ('val' == state()) states.push('array');
val += c;
break;
case ']':
if ('array' == state()) states.pop();
val += c;
break;
case '"':
case "'":
switch (state()) {
case 'key':
states.push('key char');
break;
case 'key char':
states.pop();
break;
case 'string':
if (c == quote) states.pop();
val += c;
break;
default:
states.push('string');
val += c;
quote = c;
}
break;
case '':
break;
default:
switch (state()) {
case 'key':
case 'key char':
key += c;
break;
default:
val += c;
}
}
p = c;
}
for (var i = 0; i < len; ++i) {
parse(str.charAt(i));
}
parse(',');
if ('/' == this.input.charAt(0)) {
this.consume(1);
tok.selfClosing = true;
}
return tok;
}
},
/**
* Indent | Outdent | Newline.
*/
indent: function() {
var captures, re;
// established regexp
if (this.indentRe) {
captures = this.indentRe.exec(this.input);
// determine regexp
} else {
// tabs
re = /^\n(\t*) */;
captures = re.exec(this.input);
// spaces
if (captures && !captures[1].length) {
re = /^\n( *)/;
captures = re.exec(this.input);
}
// established
if (captures && captures[1].length) this.indentRe = re;
}
if (captures) {
var tok
, indents = captures[1].length;
++this.lineno;
this.consume(indents + 1);
if (' ' == this.input[0] || '\t' == this.input[0]) {
throw new Error('Invalid indentation, you can use tabs or spaces but not both');
}
// blank line
if ('\n' == this.input[0]) return this.tok('newline');
// outdent
if (this.indentStack.length && indents < this.indentStack[0]) {
while (this.indentStack.length && this.indentStack[0] > indents) {
this.stash.push(this.tok('outdent'));
this.indentStack.shift();
}
tok = this.stash.pop();
// indent
} else if (indents && indents != this.indentStack[0]) {
this.indentStack.unshift(indents);
tok = this.tok('indent', indents);
// newline
} else {
tok = this.tok('newline');
}
return tok;
}
},
/**
* Pipe-less text consumed only when
* pipeless is true;
*/
pipelessText: function() {
if (this.pipeless) {
if ('\n' == this.input[0]) return;
var i = this.input.indexOf('\n');
if (-1 == i) i = this.input.length;
var str = this.input.substr(0, i);
this.consume(str.length);
return this.tok('text', str);
}
},
/**
* ':'
*/
colon: function() {
return this.scan(/^: */, ':');
},
/**
* Return the next token object, or those
* previously stashed by lookahead.
*
* @return {Object}
* @api private
*/
advance: function(){
return this.stashed()
|| this.next();
},
/**
* Return the next token object.
*
* @return {Object}
* @api private
*/
next: function() {
return this.deferred()
|| this.blank()
|| this.eos()
|| this.pipelessText()
|| this.yield()
|| this.doctype()
|| this.interpolation()
|| this["case"]()
|| this.when()
|| this["default"]()
|| this["extends"]()
|| this.append()
|| this.prepend()
|| this.block()
|| this.include()
|| this.mixin()
|| this.call()
|| this.conditional()
|| this.each()
|| this["while"]()
|| this.assignment()
|| this.tag()
|| this.filter()
|| this.code()
|| this.id()
|| this.className()
|| this.attrs()
|| this.indent()
|| this.comment()
|| this.colon()
|| this.text();
}
};

77
node_modules/jade/lib/nodes/attrs.js generated vendored Normal file
View File

@@ -0,0 +1,77 @@
/*!
* Jade - nodes - Attrs
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
* MIT Licensed
*/
/**
* Module dependencies.
*/
var Node = require('./node'),
Block = require('./block');
/**
* Initialize a `Attrs` node.
*
* @api public
*/
var Attrs = module.exports = function Attrs() {
this.attrs = [];
};
/**
* Inherit from `Node`.
*/
Attrs.prototype.__proto__ = Node.prototype;
/**
* Set attribute `name` to `val`, keep in mind these become
* part of a raw js object literal, so to quote a value you must
* '"quote me"', otherwise or example 'user.name' is literal JavaScript.
*
* @param {String} name
* @param {String} val
* @param {Boolean} escaped
* @return {Tag} for chaining
* @api public
*/
Attrs.prototype.setAttribute = function(name, val, escaped){
this.attrs.push({ name: name, val: val, escaped: escaped });
return this;
};
/**
* Remove attribute `name` when present.
*
* @param {String} name
* @api public
*/
Attrs.prototype.removeAttribute = function(name){
for (var i = 0, len = this.attrs.length; i < len; ++i) {
if (this.attrs[i] && this.attrs[i].name == name) {
delete this.attrs[i];
}
}
};
/**
* Get attribute value by `name`.
*
* @param {String} name
* @return {String}
* @api public
*/
Attrs.prototype.getAttribute = function(name){
for (var i = 0, len = this.attrs.length; i < len; ++i) {
if (this.attrs[i] && this.attrs[i].name == name) {
return this.attrs[i].val;
}
}
};

33
node_modules/jade/lib/nodes/block-comment.js generated vendored Normal file
View File

@@ -0,0 +1,33 @@
/*!
* Jade - nodes - BlockComment
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
* MIT Licensed
*/
/**
* Module dependencies.
*/
var Node = require('./node');
/**
* Initialize a `BlockComment` with the given `block`.
*
* @param {String} val
* @param {Block} block
* @param {Boolean} buffer
* @api public
*/
var BlockComment = module.exports = function BlockComment(val, block, buffer) {
this.block = block;
this.val = val;
this.buffer = buffer;
};
/**
* Inherit from `Node`.
*/
BlockComment.prototype.__proto__ = Node.prototype;

121
node_modules/jade/lib/nodes/block.js generated vendored Normal file
View File

@@ -0,0 +1,121 @@
/*!
* Jade - nodes - Block
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
* MIT Licensed
*/
/**
* Module dependencies.
*/
var Node = require('./node');
/**
* Initialize a new `Block` with an optional `node`.
*
* @param {Node} node
* @api public
*/
var Block = module.exports = function Block(node){
this.nodes = [];
if (node) this.push(node);
};
/**
* Inherit from `Node`.
*/
Block.prototype.__proto__ = Node.prototype;
/**
* Block flag.
*/
Block.prototype.isBlock = true;
/**
* Replace the nodes in `other` with the nodes
* in `this` block.
*
* @param {Block} other
* @api private
*/
Block.prototype.replace = function(other){
other.nodes = this.nodes;
};
/**
* Pust the given `node`.
*
* @param {Node} node
* @return {Number}
* @api public
*/
Block.prototype.push = function(node){
return this.nodes.push(node);
};
/**
* Check if this block is empty.
*
* @return {Boolean}
* @api public
*/
Block.prototype.isEmpty = function(){
return 0 == this.nodes.length;
};
/**
* Unshift the given `node`.
*
* @param {Node} node
* @return {Number}
* @api public
*/
Block.prototype.unshift = function(node){
return this.nodes.unshift(node);
};
/**
* Return the "last" block, or the first `yield` node.
*
* @return {Block}
* @api private
*/
Block.prototype.includeBlock = function(){
var ret = this
, node;
for (var i = 0, len = this.nodes.length; i < len; ++i) {
node = this.nodes[i];
if (node.yield) return node;
else if (node.textOnly) continue;
else if (node.includeBlock) ret = node.includeBlock();
else if (node.block && !node.block.isEmpty()) ret = node.block.includeBlock();
}
return ret;
};
/**
* Return a clone of this block.
*
* @return {Block}
* @api private
*/
Block.prototype.clone = function(){
var clone = new Block;
for (var i = 0, len = this.nodes.length; i < len; ++i) {
clone.push(this.nodes[i].clone());
}
return clone;
};

43
node_modules/jade/lib/nodes/case.js generated vendored Normal file
View File

@@ -0,0 +1,43 @@
/*!
* Jade - nodes - Case
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
* MIT Licensed
*/
/**
* Module dependencies.
*/
var Node = require('./node');
/**
* Initialize a new `Case` with `expr`.
*
* @param {String} expr
* @api public
*/
var Case = exports = module.exports = function Case(expr, block){
this.expr = expr;
this.block = block;
};
/**
* Inherit from `Node`.
*/
Case.prototype.__proto__ = Node.prototype;
var When = exports.When = function When(expr, block){
this.expr = expr;
this.block = block;
this.debug = false;
};
/**
* Inherit from `Node`.
*/
When.prototype.__proto__ = Node.prototype;

35
node_modules/jade/lib/nodes/code.js generated vendored Normal file
View File

@@ -0,0 +1,35 @@
/*!
* Jade - nodes - Code
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
* MIT Licensed
*/
/**
* Module dependencies.
*/
var Node = require('./node');
/**
* Initialize a `Code` node with the given code `val`.
* Code may also be optionally buffered and escaped.
*
* @param {String} val
* @param {Boolean} buffer
* @param {Boolean} escape
* @api public
*/
var Code = module.exports = function Code(val, buffer, escape) {
this.val = val;
this.buffer = buffer;
this.escape = escape;
if (val.match(/^ *else/)) this.debug = false;
};
/**
* Inherit from `Node`.
*/
Code.prototype.__proto__ = Node.prototype;

32
node_modules/jade/lib/nodes/comment.js generated vendored Normal file
View File

@@ -0,0 +1,32 @@
/*!
* Jade - nodes - Comment
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
* MIT Licensed
*/
/**
* Module dependencies.
*/
var Node = require('./node');
/**
* Initialize a `Comment` with the given `val`, optionally `buffer`,
* otherwise the comment may render in the output.
*
* @param {String} val
* @param {Boolean} buffer
* @api public
*/
var Comment = module.exports = function Comment(val, buffer) {
this.val = val;
this.buffer = buffer;
};
/**
* Inherit from `Node`.
*/
Comment.prototype.__proto__ = Node.prototype;

29
node_modules/jade/lib/nodes/doctype.js generated vendored Normal file
View File

@@ -0,0 +1,29 @@
/*!
* Jade - nodes - Doctype
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
* MIT Licensed
*/
/**
* Module dependencies.
*/
var Node = require('./node');
/**
* Initialize a `Doctype` with the given `val`.
*
* @param {String} val
* @api public
*/
var Doctype = module.exports = function Doctype(val) {
this.val = val;
};
/**
* Inherit from `Node`.
*/
Doctype.prototype.__proto__ = Node.prototype;

35
node_modules/jade/lib/nodes/each.js generated vendored Normal file
View File

@@ -0,0 +1,35 @@
/*!
* Jade - nodes - Each
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
* MIT Licensed
*/
/**
* Module dependencies.
*/
var Node = require('./node');
/**
* Initialize an `Each` node, representing iteration
*
* @param {String} obj
* @param {String} val
* @param {String} key
* @param {Block} block
* @api public
*/
var Each = module.exports = function Each(obj, val, key, block) {
this.obj = obj;
this.val = val;
this.key = key;
this.block = block;
};
/**
* Inherit from `Node`.
*/
Each.prototype.__proto__ = Node.prototype;

35
node_modules/jade/lib/nodes/filter.js generated vendored Normal file
View File

@@ -0,0 +1,35 @@
/*!
* Jade - nodes - Filter
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
* MIT Licensed
*/
/**
* Module dependencies.
*/
var Node = require('./node')
, Block = require('./block');
/**
* Initialize a `Filter` node with the given
* filter `name` and `block`.
*
* @param {String} name
* @param {Block|Node} block
* @api public
*/
var Filter = module.exports = function Filter(name, block, attrs) {
this.name = name;
this.block = block;
this.attrs = attrs;
this.isASTFilter = !block.nodes.every(function(node){ return node.isText });
};
/**
* Inherit from `Node`.
*/
Filter.prototype.__proto__ = Node.prototype;

20
node_modules/jade/lib/nodes/index.js generated vendored Normal file
View File

@@ -0,0 +1,20 @@
/*!
* Jade - nodes
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
* MIT Licensed
*/
exports.Node = require('./node');
exports.Tag = require('./tag');
exports.Code = require('./code');
exports.Each = require('./each');
exports.Case = require('./case');
exports.Text = require('./text');
exports.Block = require('./block');
exports.Mixin = require('./mixin');
exports.Filter = require('./filter');
exports.Comment = require('./comment');
exports.Literal = require('./literal');
exports.BlockComment = require('./block-comment');
exports.Doctype = require('./doctype');

32
node_modules/jade/lib/nodes/literal.js generated vendored Normal file
View File

@@ -0,0 +1,32 @@
/*!
* Jade - nodes - Literal
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
* MIT Licensed
*/
/**
* Module dependencies.
*/
var Node = require('./node');
/**
* Initialize a `Literal` node with the given `str.
*
* @param {String} str
* @api public
*/
var Literal = module.exports = function Literal(str) {
this.str = str
.replace(/\\/g, "\\\\")
.replace(/\n|\r\n/g, "\\n")
.replace(/'/g, "\\'");
};
/**
* Inherit from `Node`.
*/
Literal.prototype.__proto__ = Node.prototype;

36
node_modules/jade/lib/nodes/mixin.js generated vendored Normal file
View File

@@ -0,0 +1,36 @@
/*!
* Jade - nodes - Mixin
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
* MIT Licensed
*/
/**
* Module dependencies.
*/
var Attrs = require('./attrs');
/**
* Initialize a new `Mixin` with `name` and `block`.
*
* @param {String} name
* @param {String} args
* @param {Block} block
* @api public
*/
var Mixin = module.exports = function Mixin(name, args, block, call){
this.name = name;
this.args = args;
this.block = block;
this.attrs = [];
this.call = call;
};
/**
* Inherit from `Attrs`.
*/
Mixin.prototype.__proto__ = Attrs.prototype;

25
node_modules/jade/lib/nodes/node.js generated vendored Normal file
View File

@@ -0,0 +1,25 @@
/*!
* Jade - nodes - Node
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
* MIT Licensed
*/
/**
* Initialize a `Node`.
*
* @api public
*/
var Node = module.exports = function Node(){};
/**
* Clone this node (return itself)
*
* @return {Node}
* @api private
*/
Node.prototype.clone = function(){
return this;
};

95
node_modules/jade/lib/nodes/tag.js generated vendored Normal file
View File

@@ -0,0 +1,95 @@
/*!
* Jade - nodes - Tag
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
* MIT Licensed
*/
/**
* Module dependencies.
*/
var Attrs = require('./attrs'),
Block = require('./block'),
inlineTags = require('../inline-tags');
/**
* Initialize a `Tag` node with the given tag `name` and optional `block`.
*
* @param {String} name
* @param {Block} block
* @api public
*/
var Tag = module.exports = function Tag(name, block) {
this.name = name;
this.attrs = [];
this.block = block || new Block;
};
/**
* Inherit from `Attrs`.
*/
Tag.prototype.__proto__ = Attrs.prototype;
/**
* Clone this tag.
*
* @return {Tag}
* @api private
*/
Tag.prototype.clone = function(){
var clone = new Tag(this.name, this.block.clone());
clone.line = this.line;
clone.attrs = this.attrs;
clone.textOnly = this.textOnly;
return clone;
};
/**
* Check if this tag is an inline tag.
*
* @return {Boolean}
* @api private
*/
Tag.prototype.isInline = function(){
return ~inlineTags.indexOf(this.name);
};
/**
* Check if this tag's contents can be inlined. Used for pretty printing.
*
* @return {Boolean}
* @api private
*/
Tag.prototype.canInline = function(){
var nodes = this.block.nodes;
function isInline(node){
// Recurse if the node is a block
if (node.isBlock) return node.nodes.every(isInline);
return node.isText || (node.isInline && node.isInline());
}
// Empty tag
if (!nodes.length) return true;
// Text-only or inline-only tag
if (1 == nodes.length) return isInline(nodes[0]);
// Multi-line inline-only tag
if (this.block.nodes.every(isInline)) {
for (var i = 1, len = nodes.length; i < len; ++i) {
if (nodes[i-1].isText && nodes[i].isText)
return false;
}
return true;
}
// Mixed tag
return false;
};

36
node_modules/jade/lib/nodes/text.js generated vendored Normal file
View File

@@ -0,0 +1,36 @@
/*!
* Jade - nodes - Text
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
* MIT Licensed
*/
/**
* Module dependencies.
*/
var Node = require('./node');
/**
* Initialize a `Text` node with optional `line`.
*
* @param {String} line
* @api public
*/
var Text = module.exports = function Text(line) {
this.val = '';
if ('string' == typeof line) this.val = line;
};
/**
* Inherit from `Node`.
*/
Text.prototype.__proto__ = Node.prototype;
/**
* Flag as text.
*/
Text.prototype.isText = true;

710
node_modules/jade/lib/parser.js generated vendored Normal file
View File

@@ -0,0 +1,710 @@
/*!
* Jade - Parser
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
* MIT Licensed
*/
/**
* Module dependencies.
*/
var Lexer = require('./lexer')
, nodes = require('./nodes');
/**
* Initialize `Parser` with the given input `str` and `filename`.
*
* @param {String} str
* @param {String} filename
* @param {Object} options
* @api public
*/
var Parser = exports = module.exports = function Parser(str, filename, options){
this.input = str;
this.lexer = new Lexer(str, options);
this.filename = filename;
this.blocks = {};
this.mixins = {};
this.options = options;
this.contexts = [this];
};
/**
* Tags that may not contain tags.
*/
var textOnly = exports.textOnly = ['script', 'style'];
/**
* Parser prototype.
*/
Parser.prototype = {
/**
* Push `parser` onto the context stack,
* or pop and return a `Parser`.
*/
context: function(parser){
if (parser) {
this.contexts.push(parser);
} else {
return this.contexts.pop();
}
},
/**
* Return the next token object.
*
* @return {Object}
* @api private
*/
advance: function(){
return this.lexer.advance();
},
/**
* Skip `n` tokens.
*
* @param {Number} n
* @api private
*/
skip: function(n){
while (n--) this.advance();
},
/**
* Single token lookahead.
*
* @return {Object}
* @api private
*/
peek: function() {
return this.lookahead(1);
},
/**
* Return lexer lineno.
*
* @return {Number}
* @api private
*/
line: function() {
return this.lexer.lineno;
},
/**
* `n` token lookahead.
*
* @param {Number} n
* @return {Object}
* @api private
*/
lookahead: function(n){
return this.lexer.lookahead(n);
},
/**
* Parse input returning a string of js for evaluation.
*
* @return {String}
* @api public
*/
parse: function(){
var block = new nodes.Block, parser;
block.line = this.line();
while ('eos' != this.peek().type) {
if ('newline' == this.peek().type) {
this.advance();
} else {
block.push(this.parseExpr());
}
}
if (parser = this.extending) {
this.context(parser);
var ast = parser.parse();
this.context();
// hoist mixins
for (var name in this.mixins)
ast.unshift(this.mixins[name]);
return ast;
}
return block;
},
/**
* Expect the given type, or throw an exception.
*
* @param {String} type
* @api private
*/
expect: function(type){
if (this.peek().type === type) {
return this.advance();
} else {
throw new Error('expected "' + type + '", but got "' + this.peek().type + '"');
}
},
/**
* Accept the given `type`.
*
* @param {String} type
* @api private
*/
accept: function(type){
if (this.peek().type === type) {
return this.advance();
}
},
/**
* tag
* | doctype
* | mixin
* | include
* | filter
* | comment
* | text
* | each
* | code
* | yield
* | id
* | class
* | interpolation
*/
parseExpr: function(){
switch (this.peek().type) {
case 'tag':
return this.parseTag();
case 'mixin':
return this.parseMixin();
case 'block':
return this.parseBlock();
case 'case':
return this.parseCase();
case 'when':
return this.parseWhen();
case 'default':
return this.parseDefault();
case 'extends':
return this.parseExtends();
case 'include':
return this.parseInclude();
case 'doctype':
return this.parseDoctype();
case 'filter':
return this.parseFilter();
case 'comment':
return this.parseComment();
case 'text':
return this.parseText();
case 'each':
return this.parseEach();
case 'code':
return this.parseCode();
case 'call':
return this.parseCall();
case 'interpolation':
return this.parseInterpolation();
case 'yield':
this.advance();
var block = new nodes.Block;
block.yield = true;
return block;
case 'id':
case 'class':
var tok = this.advance();
this.lexer.defer(this.lexer.tok('tag', 'div'));
this.lexer.defer(tok);
return this.parseExpr();
default:
throw new Error('unexpected token "' + this.peek().type + '"');
}
},
/**
* Text
*/
parseText: function(){
var tok = this.expect('text')
, node = new nodes.Text(tok.val);
node.line = this.line();
return node;
},
/**
* ':' expr
* | block
*/
parseBlockExpansion: function(){
if (':' == this.peek().type) {
this.advance();
return new nodes.Block(this.parseExpr());
} else {
return this.block();
}
},
/**
* case
*/
parseCase: function(){
var val = this.expect('case').val
, node = new nodes.Case(val);
node.line = this.line();
node.block = this.block();
return node;
},
/**
* when
*/
parseWhen: function(){
var val = this.expect('when').val
return new nodes.Case.When(val, this.parseBlockExpansion());
},
/**
* default
*/
parseDefault: function(){
this.expect('default');
return new nodes.Case.When('default', this.parseBlockExpansion());
},
/**
* code
*/
parseCode: function(){
var tok = this.expect('code')
, node = new nodes.Code(tok.val, tok.buffer, tok.escape)
, block
, i = 1;
node.line = this.line();
while (this.lookahead(i) && 'newline' == this.lookahead(i).type) ++i;
block = 'indent' == this.lookahead(i).type;
if (block) {
this.skip(i-1);
node.block = this.block();
}
return node;
},
/**
* comment
*/
parseComment: function(){
var tok = this.expect('comment')
, node;
if ('indent' == this.peek().type) {
node = new nodes.BlockComment(tok.val, this.block(), tok.buffer);
} else {
node = new nodes.Comment(tok.val, tok.buffer);
}
node.line = this.line();
return node;
},
/**
* doctype
*/
parseDoctype: function(){
var tok = this.expect('doctype')
, node = new nodes.Doctype(tok.val);
node.line = this.line();
return node;
},
/**
* filter attrs? text-block
*/
parseFilter: function(){
var block
, tok = this.expect('filter')
, attrs = this.accept('attrs');
this.lexer.pipeless = true;
block = this.parseTextBlock();
this.lexer.pipeless = false;
var node = new nodes.Filter(tok.val, block, attrs && attrs.attrs);
node.line = this.line();
return node;
},
/**
* tag ':' attrs? block
*/
parseASTFilter: function(){
var block
, tok = this.expect('tag')
, attrs = this.accept('attrs');
this.expect(':');
block = this.block();
var node = new nodes.Filter(tok.val, block, attrs && attrs.attrs);
node.line = this.line();
return node;
},
/**
* each block
*/
parseEach: function(){
var tok = this.expect('each')
, node = new nodes.Each(tok.code, tok.val, tok.key);
node.line = this.line();
node.block = this.block();
return node;
},
/**
* 'extends' name
*/
parseExtends: function(){
var path = require('path')
, fs = require('fs')
, dirname = path.dirname
, basename = path.basename
, join = path.join;
if (!this.filename)
throw new Error('the "filename" option is required to extend templates');
var path = this.expect('extends').val.trim()
, dir = dirname(this.filename);
var path = join(dir, path + '.jade')
, str = fs.readFileSync(path, 'utf8')
, parser = new Parser(str, path, this.options);
parser.blocks = this.blocks;
parser.contexts = this.contexts;
this.extending = parser;
// TODO: null node
return new nodes.Literal('');
},
/**
* 'block' name block
*/
parseBlock: function(){
var block = this.expect('block')
, mode = block.mode
, name = block.val.trim();
block = 'indent' == this.peek().type
? this.block()
: new nodes.Block(new nodes.Literal(''));
var prev = this.blocks[name];
if (prev) {
switch (prev.mode) {
case 'append':
block.nodes = block.nodes.concat(prev.nodes);
prev = block;
break;
case 'prepend':
block.nodes = prev.nodes.concat(block.nodes);
prev = block;
break;
}
}
block.mode = mode;
return this.blocks[name] = prev || block;
},
/**
* include block?
*/
parseInclude: function(){
var path = require('path')
, fs = require('fs')
, dirname = path.dirname
, basename = path.basename
, join = path.join;
var path = this.expect('include').val.trim()
, dir = dirname(this.filename);
if (!this.filename)
throw new Error('the "filename" option is required to use includes');
// no extension
if (!~basename(path).indexOf('.')) {
path += '.jade';
}
// non-jade
if ('.jade' != path.substr(-5)) {
var path = join(dir, path)
, str = fs.readFileSync(path, 'utf8');
return new nodes.Literal(str);
}
var path = join(dir, path)
, str = fs.readFileSync(path, 'utf8')
, parser = new Parser(str, path, this.options);
parser.blocks = this.blocks;
parser.mixins = this.mixins;
this.context(parser);
var ast = parser.parse();
this.context();
ast.filename = path;
if ('indent' == this.peek().type) {
ast.includeBlock().push(this.block());
}
return ast;
},
/**
* call ident block
*/
parseCall: function(){
var tok = this.expect('call')
, name = tok.val
, args = tok.args
, mixin = new nodes.Mixin(name, args, new nodes.Block, true);
this.tag(mixin);
if (mixin.block.isEmpty()) mixin.block = null;
return mixin;
},
/**
* mixin block
*/
parseMixin: function(){
var tok = this.expect('mixin')
, name = tok.val
, args = tok.args
, mixin;
// definition
if ('indent' == this.peek().type) {
mixin = new nodes.Mixin(name, args, this.block(), false);
this.mixins[name] = mixin;
return mixin;
// call
} else {
return new nodes.Mixin(name, args, null, true);
}
},
/**
* indent (text | newline)* outdent
*/
parseTextBlock: function(){
var block = new nodes.Block;
block.line = this.line();
var spaces = this.expect('indent').val;
if (null == this._spaces) this._spaces = spaces;
var indent = Array(spaces - this._spaces + 1).join(' ');
while ('outdent' != this.peek().type) {
switch (this.peek().type) {
case 'newline':
this.advance();
break;
case 'indent':
this.parseTextBlock().nodes.forEach(function(node){
block.push(node);
});
break;
default:
var text = new nodes.Text(indent + this.advance().val);
text.line = this.line();
block.push(text);
}
}
if (spaces == this._spaces) this._spaces = null;
this.expect('outdent');
return block;
},
/**
* indent expr* outdent
*/
block: function(){
var block = new nodes.Block;
block.line = this.line();
this.expect('indent');
while ('outdent' != this.peek().type) {
if ('newline' == this.peek().type) {
this.advance();
} else {
block.push(this.parseExpr());
}
}
this.expect('outdent');
return block;
},
/**
* interpolation (attrs | class | id)* (text | code | ':')? newline* block?
*/
parseInterpolation: function(){
var tok = this.advance();
var tag = new nodes.Tag(tok.val);
tag.buffer = true;
return this.tag(tag);
},
/**
* tag (attrs | class | id)* (text | code | ':')? newline* block?
*/
parseTag: function(){
// ast-filter look-ahead
var i = 2;
if ('attrs' == this.lookahead(i).type) ++i;
if (':' == this.lookahead(i).type) {
if ('indent' == this.lookahead(++i).type) {
return this.parseASTFilter();
}
}
var tok = this.advance()
, tag = new nodes.Tag(tok.val);
tag.selfClosing = tok.selfClosing;
return this.tag(tag);
},
/**
* Parse tag.
*/
tag: function(tag){
var dot;
tag.line = this.line();
// (attrs | class | id)*
out:
while (true) {
switch (this.peek().type) {
case 'id':
case 'class':
var tok = this.advance();
tag.setAttribute(tok.type, "'" + tok.val + "'");
continue;
case 'attrs':
var tok = this.advance()
, obj = tok.attrs
, escaped = tok.escaped
, names = Object.keys(obj);
if (tok.selfClosing) tag.selfClosing = true;
for (var i = 0, len = names.length; i < len; ++i) {
var name = names[i]
, val = obj[name];
tag.setAttribute(name, val, escaped[name]);
}
continue;
default:
break out;
}
}
// check immediate '.'
if ('.' == this.peek().val) {
dot = tag.textOnly = true;
this.advance();
}
// (text | code | ':')?
switch (this.peek().type) {
case 'text':
tag.block.push(this.parseText());
break;
case 'code':
tag.code = this.parseCode();
break;
case ':':
this.advance();
tag.block = new nodes.Block;
tag.block.push(this.parseExpr());
break;
}
// newline*
while ('newline' == this.peek().type) this.advance();
tag.textOnly = tag.textOnly || ~textOnly.indexOf(tag.name);
// script special-case
if ('script' == tag.name) {
var type = tag.getAttribute('type');
if (!dot && type && 'text/javascript' != type.replace(/^['"]|['"]$/g, '')) {
tag.textOnly = false;
}
}
// block?
if ('indent' == this.peek().type) {
if (tag.textOnly) {
this.lexer.pipeless = true;
tag.block = this.parseTextBlock();
this.lexer.pipeless = false;
} else {
var block = this.block();
if (tag.block) {
for (var i = 0, len = block.nodes.length; i < len; ++i) {
tag.block.push(block.nodes[i]);
}
} else {
tag.block = block;
}
}
}
return tag;
}
};

174
node_modules/jade/lib/runtime.js generated vendored Normal file
View File

@@ -0,0 +1,174 @@
/*!
* Jade - runtime
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
* MIT Licensed
*/
/**
* Lame Array.isArray() polyfill for now.
*/
if (!Array.isArray) {
Array.isArray = function(arr){
return '[object Array]' == Object.prototype.toString.call(arr);
};
}
/**
* Lame Object.keys() polyfill for now.
*/
if (!Object.keys) {
Object.keys = function(obj){
var arr = [];
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
arr.push(key);
}
}
return arr;
}
}
/**
* Merge two attribute objects giving precedence
* to values in object `b`. Classes are special-cased
* allowing for arrays and merging/joining appropriately
* resulting in a string.
*
* @param {Object} a
* @param {Object} b
* @return {Object} a
* @api private
*/
exports.merge = function merge(a, b) {
var ac = a['class'];
var bc = b['class'];
if (ac || bc) {
ac = ac || [];
bc = bc || [];
if (!Array.isArray(ac)) ac = [ac];
if (!Array.isArray(bc)) bc = [bc];
ac = ac.filter(nulls);
bc = bc.filter(nulls);
a['class'] = ac.concat(bc).join(' ');
}
for (var key in b) {
if (key != 'class') {
a[key] = b[key];
}
}
return a;
};
/**
* Filter null `val`s.
*
* @param {Mixed} val
* @return {Mixed}
* @api private
*/
function nulls(val) {
return val != null;
}
/**
* Render the given attributes object.
*
* @param {Object} obj
* @param {Object} escaped
* @return {String}
* @api private
*/
exports.attrs = function attrs(obj, escaped){
var buf = []
, terse = obj.terse;
delete obj.terse;
var keys = Object.keys(obj)
, len = keys.length;
if (len) {
buf.push('');
for (var i = 0; i < len; ++i) {
var key = keys[i]
, val = obj[key];
if ('boolean' == typeof val || null == val) {
if (val) {
terse
? buf.push(key)
: buf.push(key + '="' + key + '"');
}
} else if (0 == key.indexOf('data') && 'string' != typeof val) {
buf.push(key + "='" + JSON.stringify(val) + "'");
} else if ('class' == key && Array.isArray(val)) {
buf.push(key + '="' + exports.escape(val.join(' ')) + '"');
} else if (escaped && escaped[key]) {
buf.push(key + '="' + exports.escape(val) + '"');
} else {
buf.push(key + '="' + val + '"');
}
}
}
return buf.join(' ');
};
/**
* Escape the given string of `html`.
*
* @param {String} html
* @return {String}
* @api private
*/
exports.escape = function escape(html){
return String(html)
.replace(/&(?!(\w+|\#\d+);)/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;');
};
/**
* Re-throw the given `err` in context to the
* the jade in `filename` at the given `lineno`.
*
* @param {Error} err
* @param {String} filename
* @param {String} lineno
* @api private
*/
exports.rethrow = function rethrow(err, filename, lineno){
if (!filename) throw err;
var context = 3
, str = require('fs').readFileSync(filename, 'utf8')
, lines = str.split('\n')
, start = Math.max(lineno - context, 0)
, end = Math.min(lines.length, lineno + context);
// Error context
var context = lines.slice(start, end).map(function(line, i){
var curr = i + start + 1;
return (curr == lineno ? ' > ' : ' ')
+ curr
+ '| '
+ line;
}).join('\n');
// Alter exception message
err.path = filename;
err.message = (filename || 'Jade') + ':' + lineno
+ '\n' + context + '\n\n' + err.message;
throw err;
};

19
node_modules/jade/lib/self-closing.js generated vendored Normal file
View File

@@ -0,0 +1,19 @@
/*!
* Jade - self closing tags
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
* MIT Licensed
*/
module.exports = [
'meta'
, 'img'
, 'link'
, 'input'
, 'source'
, 'area'
, 'base'
, 'col'
, 'br'
, 'hr'
];

49
node_modules/jade/lib/utils.js generated vendored Normal file
View File

@@ -0,0 +1,49 @@
/*!
* Jade - utils
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
* MIT Licensed
*/
/**
* Convert interpolation in the given string to JavaScript.
*
* @param {String} str
* @return {String}
* @api private
*/
var interpolate = exports.interpolate = function(str){
return str.replace(/(\\)?([#!]){(.*?)}/g, function(str, escape, flag, code){
return escape
? str
: "' + "
+ ('!' == flag ? '' : 'escape')
+ "((interp = " + code.replace(/\\'/g, "'")
+ ") == 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));
};

4
node_modules/jade/node_modules/commander/.npmignore generated vendored Normal file
View File

@@ -0,0 +1,4 @@
support
test
examples
*.sock

4
node_modules/jade/node_modules/commander/.travis.yml generated vendored Normal file
View File

@@ -0,0 +1,4 @@
language: node_js
node_js:
- 0.4
- 0.6

107
node_modules/jade/node_modules/commander/History.md generated vendored Normal file
View File

@@ -0,0 +1,107 @@
0.6.1 / 2012-06-01
==================
* Added: append (yes or no) on confirmation
* Added: allow node.js v0.7.x
0.6.0 / 2012-04-10
==================
* Added `.prompt(obj, callback)` support. Closes #49
* Added default support to .choose(). Closes #41
* Fixed the choice example
0.5.1 / 2011-12-20
==================
* Fixed `password()` for recent nodes. Closes #36
0.5.0 / 2011-12-04
==================
* Added sub-command option support [itay]
0.4.3 / 2011-12-04
==================
* Fixed custom help ordering. Closes #32
0.4.2 / 2011-11-24
==================
* Added travis support
* Fixed: line-buffered input automatically trimmed. Closes #31
0.4.1 / 2011-11-18
==================
* Removed listening for "close" on --help
0.4.0 / 2011-11-15
==================
* Added support for `--`. Closes #24
0.3.3 / 2011-11-14
==================
* Fixed: wait for close event when writing help info [Jerry Hamlet]
0.3.2 / 2011-11-01
==================
* Fixed long flag definitions with values [felixge]
0.3.1 / 2011-10-31
==================
* Changed `--version` short flag to `-V` from `-v`
* Changed `.version()` so it's configurable [felixge]
0.3.0 / 2011-10-31
==================
* Added support for long flags only. Closes #18
0.2.1 / 2011-10-24
==================
* "node": ">= 0.4.x < 0.7.0". Closes #20
0.2.0 / 2011-09-26
==================
* Allow for defaults that are not just boolean. Default peassignment only occurs for --no-*, optional, and required arguments. [Jim Isaacs]
0.1.0 / 2011-08-24
==================
* Added support for custom `--help` output
0.0.5 / 2011-08-18
==================
* Changed: when the user enters nothing prompt for password again
* Fixed issue with passwords beginning with numbers [NuckChorris]
0.0.4 / 2011-08-15
==================
* Fixed `Commander#args`
0.0.3 / 2011-08-15
==================
* Added default option value support
0.0.2 / 2011-08-15
==================
* Added mask support to `Command#password(str[, mask], fn)`
* Added `Command#password(str, fn)`
0.0.1 / 2010-01-03
==================
* Initial release

7
node_modules/jade/node_modules/commander/Makefile generated vendored Normal file
View File

@@ -0,0 +1,7 @@
TESTS = $(shell find test/test.*.js)
test:
@./test/run $(TESTS)
.PHONY: test

262
node_modules/jade/node_modules/commander/Readme.md generated vendored Normal file
View File

@@ -0,0 +1,262 @@
# Commander.js
The complete solution for [node.js](http://nodejs.org) command-line interfaces, inspired by Ruby's [commander](https://github.com/visionmedia/commander).
[![Build Status](https://secure.travis-ci.org/visionmedia/commander.js.png)](http://travis-ci.org/visionmedia/commander.js)
## Installation
$ npm install commander
## Option parsing
Options with commander are defined with the `.option()` method, also serving as documentation for the options. The example below parses args and options from `process.argv`, leaving remaining args as the `program.args` array which were not consumed by options.
```js
#!/usr/bin/env node
/**
* Module dependencies.
*/
var program = require('commander');
program
.version('0.0.1')
.option('-p, --peppers', 'Add peppers')
.option('-P, --pineapple', 'Add pineapple')
.option('-b, --bbq', 'Add bbq sauce')
.option('-c, --cheese [type]', 'Add the specified type of cheese [marble]', 'marble')
.parse(process.argv);
console.log('you ordered a pizza with:');
if (program.peppers) console.log(' - peppers');
if (program.pineapple) console.log(' - pineappe');
if (program.bbq) console.log(' - bbq');
console.log(' - %s cheese', program.cheese);
```
Short flags may be passed as a single arg, for example `-abc` is equivalent to `-a -b -c`. Multi-word options such as "--template-engine" are camel-cased, becoming `program.templateEngine` etc.
## Automated --help
The help information is auto-generated based on the information commander already knows about your program, so the following `--help` info is for free:
```
$ ./examples/pizza --help
Usage: pizza [options]
Options:
-V, --version output the version number
-p, --peppers Add peppers
-P, --pineapple Add pineappe
-b, --bbq Add bbq sauce
-c, --cheese <type> Add the specified type of cheese [marble]
-h, --help output usage information
```
## Coercion
```js
function range(val) {
return val.split('..').map(Number);
}
function list(val) {
return val.split(',');
}
program
.version('0.0.1')
.usage('[options] <file ...>')
.option('-i, --integer <n>', 'An integer argument', parseInt)
.option('-f, --float <n>', 'A float argument', parseFloat)
.option('-r, --range <a>..<b>', 'A range', range)
.option('-l, --list <items>', 'A list', list)
.option('-o, --optional [value]', 'An optional value')
.parse(process.argv);
console.log(' int: %j', program.integer);
console.log(' float: %j', program.float);
console.log(' optional: %j', program.optional);
program.range = program.range || [];
console.log(' range: %j..%j', program.range[0], program.range[1]);
console.log(' list: %j', program.list);
console.log(' args: %j', program.args);
```
## Custom help
You can display arbitrary `-h, --help` information
by listening for "--help". Commander will automatically
exit once you are done so that the remainder of your program
does not execute causing undesired behaviours, for example
in the following executable "stuff" will not output when
`--help` is used.
```js
#!/usr/bin/env node
/**
* Module dependencies.
*/
var program = require('../');
function list(val) {
return val.split(',').map(Number);
}
program
.version('0.0.1')
.option('-f, --foo', 'enable some foo')
.option('-b, --bar', 'enable some bar')
.option('-B, --baz', 'enable some baz');
// must be before .parse() since
// node's emit() is immediate
program.on('--help', function(){
console.log(' Examples:');
console.log('');
console.log(' $ custom-help --help');
console.log(' $ custom-help -h');
console.log('');
});
program.parse(process.argv);
console.log('stuff');
```
yielding the following help output:
```
Usage: custom-help [options]
Options:
-h, --help output usage information
-V, --version output the version number
-f, --foo enable some foo
-b, --bar enable some bar
-B, --baz enable some baz
Examples:
$ custom-help --help
$ custom-help -h
```
## .prompt(msg, fn)
Single-line prompt:
```js
program.prompt('name: ', function(name){
console.log('hi %s', name);
});
```
Multi-line prompt:
```js
program.prompt('description:', function(name){
console.log('hi %s', name);
});
```
Coercion:
```js
program.prompt('Age: ', Number, function(age){
console.log('age: %j', age);
});
```
```js
program.prompt('Birthdate: ', Date, function(date){
console.log('date: %s', date);
});
```
## .password(msg[, mask], fn)
Prompt for password without echoing:
```js
program.password('Password: ', function(pass){
console.log('got "%s"', pass);
process.stdin.destroy();
});
```
Prompt for password with mask char "*":
```js
program.password('Password: ', '*', function(pass){
console.log('got "%s"', pass);
process.stdin.destroy();
});
```
## .confirm(msg, fn)
Confirm with the given `msg`:
```js
program.confirm('continue? ', function(ok){
console.log(' got %j', ok);
});
```
## .choose(list, fn)
Let the user choose from a `list`:
```js
var list = ['tobi', 'loki', 'jane', 'manny', 'luna'];
console.log('Choose the coolest pet:');
program.choose(list, function(i){
console.log('you chose %d "%s"', i, list[i]);
});
```
## Links
- [API documentation](http://visionmedia.github.com/commander.js/)
- [ascii tables](https://github.com/LearnBoost/cli-table)
- [progress bars](https://github.com/visionmedia/node-progress)
- [more progress bars](https://github.com/substack/node-multimeter)
- [examples](https://github.com/visionmedia/commander.js/tree/master/examples)
## License
(The MIT License)
Copyright (c) 2011 TJ Holowaychuk &lt;tj@vision-media.ca&gt;
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

2
node_modules/jade/node_modules/commander/index.js generated vendored Normal file
View File

@@ -0,0 +1,2 @@
module.exports = require('./lib/commander');

1026
node_modules/jade/node_modules/commander/lib/commander.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

60
node_modules/jade/node_modules/commander/package.json generated vendored Normal file
View File

@@ -0,0 +1,60 @@
{
"_from": "commander@0.6.1",
"_id": "commander@0.6.1",
"_inBundle": false,
"_integrity": "sha1-+mihT2qUXVTbvlDYzbMyDp47GgY=",
"_location": "/jade/commander",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "commander@0.6.1",
"name": "commander",
"escapedName": "commander",
"rawSpec": "0.6.1",
"saveSpec": null,
"fetchSpec": "0.6.1"
},
"_requiredBy": [
"/jade"
],
"_resolved": "https://registry.npmjs.org/commander/-/commander-0.6.1.tgz",
"_shasum": "fa68a14f6a945d54dbbe50d8cdb3320e9e3b1a06",
"_spec": "commander@0.6.1",
"_where": "/home/clemens/Dokumente/git/pixelnode/node_modules/jade",
"author": {
"name": "TJ Holowaychuk",
"email": "tj@vision-media.ca"
},
"bugs": {
"url": "https://github.com/visionmedia/commander.js/issues"
},
"bundleDependencies": false,
"dependencies": {},
"deprecated": false,
"description": "the complete solution for node.js command-line programs",
"devDependencies": {
"should": ">= 0.0.1"
},
"engines": {
"node": ">= 0.4.x"
},
"homepage": "https://github.com/visionmedia/commander.js#readme",
"keywords": [
"command",
"option",
"parser",
"prompt",
"stdin"
],
"main": "index",
"name": "commander",
"repository": {
"type": "git",
"url": "git+https://github.com/visionmedia/commander.js.git"
},
"scripts": {
"test": "make test"
},
"version": "0.6.1"
}

View File

@@ -0,0 +1,2 @@
node_modules/
npm-debug.log

5
node_modules/jade/node_modules/mkdirp/.gitignore.rej generated vendored Normal file
View File

@@ -0,0 +1,5 @@
--- /dev/null
+++ .gitignore
@@ -0,0 +1,2 @@
+node_modules/
+npm-debug.log

2
node_modules/jade/node_modules/mkdirp/.npmignore generated vendored Normal file
View File

@@ -0,0 +1,2 @@
node_modules/
npm-debug.log

21
node_modules/jade/node_modules/mkdirp/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
Copyright 2010 James Halliday (mail@substack.net)
This project is free software released under the MIT/X11 license:
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

54
node_modules/jade/node_modules/mkdirp/README.markdown generated vendored Normal file
View File

@@ -0,0 +1,54 @@
mkdirp
======
Like `mkdir -p`, but in node.js!
example
=======
pow.js
------
var mkdirp = require('mkdirp');
mkdirp('/tmp/foo/bar/baz', function (err) {
if (err) console.error(err)
else console.log('pow!')
});
Output
pow!
And now /tmp/foo/bar/baz exists, huzzah!
methods
=======
var mkdirp = require('mkdirp');
mkdirp(dir, mode, cb)
---------------------
Create a new directory and any necessary subdirectories at `dir` with octal
permission string `mode`.
If `mode` isn't specified, it defaults to `0777 & (~process.umask())`.
mkdirp.sync(dir, mode)
----------------------
Synchronously create a new directory and any necessary subdirectories at `dir`
with octal permission string `mode`.
If `mode` isn't specified, it defaults to `0777 & (~process.umask())`.
install
=======
With [npm](http://npmjs.org) do:
npm install mkdirp
license
=======
MIT/X11

View File

@@ -0,0 +1,6 @@
var mkdirp = require('mkdirp');
mkdirp('/tmp/foo/bar/baz', function (err) {
if (err) console.error(err)
else console.log('pow!')
});

View File

@@ -0,0 +1,6 @@
var mkdirp = require('mkdirp');
mkdirp('/tmp/foo/bar/baz', 0755, function (err) {
if (err) console.error(err)
else console.log('pow!')
});

View File

@@ -0,0 +1,19 @@
--- examples/pow.js
+++ examples/pow.js
@@ -1,6 +1,15 @@
-var mkdirp = require('mkdirp').mkdirp;
+var mkdirp = require('../').mkdirp,
+ mkdirpSync = require('../').mkdirpSync;
mkdirp('/tmp/foo/bar/baz', 0755, function (err) {
if (err) console.error(err)
else console.log('pow!')
});
+
+try {
+ mkdirpSync('/tmp/bar/foo/baz', 0755);
+ console.log('double pow!');
+}
+catch (ex) {
+ console.log(ex);
+}

79
node_modules/jade/node_modules/mkdirp/index.js generated vendored Normal file
View File

@@ -0,0 +1,79 @@
var path = require('path');
var fs = require('fs');
module.exports = mkdirP.mkdirp = mkdirP.mkdirP = mkdirP;
function mkdirP (p, mode, f) {
if (typeof mode === 'function' || mode === undefined) {
f = mode;
mode = 0777 & (~process.umask());
}
var cb = f || function () {};
if (typeof mode === 'string') mode = parseInt(mode, 8);
p = path.resolve(p);
fs.mkdir(p, mode, function (er) {
if (!er) return cb();
switch (er.code) {
case 'ENOENT':
mkdirP(path.dirname(p), mode, function (er) {
if (er) cb(er);
else mkdirP(p, mode, cb);
});
break;
case 'EEXIST':
fs.stat(p, function (er2, stat) {
// if the stat fails, then that's super weird.
// let the original EEXIST be the failure reason.
if (er2 || !stat.isDirectory()) cb(er)
else cb();
});
break;
default:
cb(er);
break;
}
});
}
mkdirP.sync = function sync (p, mode) {
if (mode === undefined) {
mode = 0777 & (~process.umask());
}
if (typeof mode === 'string') mode = parseInt(mode, 8);
p = path.resolve(p);
try {
fs.mkdirSync(p, mode)
}
catch (err0) {
switch (err0.code) {
case 'ENOENT' :
var err1 = sync(path.dirname(p), mode)
if (err1) throw err1;
else return sync(p, mode);
break;
case 'EEXIST' :
var stat;
try {
stat = fs.statSync(p);
}
catch (err1) {
throw err0
}
if (!stat.isDirectory()) throw err0;
else return null;
break;
default :
throw err0
break;
}
}
return null;
};

58
node_modules/jade/node_modules/mkdirp/package.json generated vendored Normal file
View File

@@ -0,0 +1,58 @@
{
"_from": "mkdirp@0.3.0",
"_id": "mkdirp@0.3.0",
"_inBundle": false,
"_integrity": "sha1-G79asbqCevI1dRQ0kEJkVfSB/h4=",
"_location": "/jade/mkdirp",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "mkdirp@0.3.0",
"name": "mkdirp",
"escapedName": "mkdirp",
"rawSpec": "0.3.0",
"saveSpec": null,
"fetchSpec": "0.3.0"
},
"_requiredBy": [
"/jade"
],
"_resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz",
"_shasum": "1bbf5ab1ba827af23575143490426455f481fe1e",
"_spec": "mkdirp@0.3.0",
"_where": "/home/clemens/Dokumente/git/pixelnode/node_modules/jade",
"author": {
"name": "James Halliday",
"email": "mail@substack.net",
"url": "http://substack.net"
},
"bugs": {
"url": "https://github.com/substack/node-mkdirp/issues"
},
"bundleDependencies": false,
"deprecated": false,
"description": "Recursively mkdir, like `mkdir -p`",
"devDependencies": {
"tap": "0.0.x"
},
"engines": {
"node": "*"
},
"homepage": "https://github.com/substack/node-mkdirp#readme",
"keywords": [
"mkdir",
"directory"
],
"license": "MIT/X11",
"main": "./index",
"name": "mkdirp",
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/substack/node-mkdirp.git"
},
"scripts": {
"test": "tap test/*.js"
},
"version": "0.3.0"
}

38
node_modules/jade/node_modules/mkdirp/test/chmod.js generated vendored Normal file
View File

@@ -0,0 +1,38 @@
var mkdirp = require('../').mkdirp;
var path = require('path');
var fs = require('fs');
var test = require('tap').test;
var ps = [ '', 'tmp' ];
for (var i = 0; i < 25; i++) {
var dir = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
ps.push(dir);
}
var file = ps.join('/');
test('chmod-pre', function (t) {
var mode = 0744
mkdirp(file, mode, function (er) {
t.ifError(er, 'should not error');
fs.stat(file, function (er, stat) {
t.ifError(er, 'should exist');
t.ok(stat && stat.isDirectory(), 'should be directory');
t.equal(stat && stat.mode & 0777, mode, 'should be 0744');
t.end();
});
});
});
test('chmod', function (t) {
var mode = 0755
mkdirp(file, mode, function (er) {
t.ifError(er, 'should not error');
fs.stat(file, function (er, stat) {
t.ifError(er, 'should exist');
t.ok(stat && stat.isDirectory(), 'should be directory');
t.end();
});
});
});

37
node_modules/jade/node_modules/mkdirp/test/clobber.js generated vendored Normal file
View File

@@ -0,0 +1,37 @@
var mkdirp = require('../').mkdirp;
var path = require('path');
var fs = require('fs');
var test = require('tap').test;
var ps = [ '', 'tmp' ];
for (var i = 0; i < 25; i++) {
var dir = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
ps.push(dir);
}
var file = ps.join('/');
// a file in the way
var itw = ps.slice(0, 3).join('/');
test('clobber-pre', function (t) {
console.error("about to write to "+itw)
fs.writeFileSync(itw, 'I AM IN THE WAY, THE TRUTH, AND THE LIGHT.');
fs.stat(itw, function (er, stat) {
t.ifError(er)
t.ok(stat && stat.isFile(), 'should be file')
t.end()
})
})
test('clobber', function (t) {
t.plan(2);
mkdirp(file, 0755, function (err) {
t.ok(err);
t.equal(err.code, 'ENOTDIR');
t.end();
});
});

28
node_modules/jade/node_modules/mkdirp/test/mkdirp.js generated vendored Normal file
View File

@@ -0,0 +1,28 @@
var mkdirp = require('../');
var path = require('path');
var fs = require('fs');
var test = require('tap').test;
test('woo', function (t) {
t.plan(2);
var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
var file = '/tmp/' + [x,y,z].join('/');
mkdirp(file, 0755, function (err) {
if (err) t.fail(err);
else path.exists(file, function (ex) {
if (!ex) t.fail('file not created')
else fs.stat(file, function (err, stat) {
if (err) t.fail(err)
else {
t.equal(stat.mode & 0777, 0755);
t.ok(stat.isDirectory(), 'target not a directory');
t.end();
}
})
})
});
});

32
node_modules/jade/node_modules/mkdirp/test/perm.js generated vendored Normal file
View File

@@ -0,0 +1,32 @@
var mkdirp = require('../');
var path = require('path');
var fs = require('fs');
var test = require('tap').test;
test('async perm', function (t) {
t.plan(2);
var file = '/tmp/' + (Math.random() * (1<<30)).toString(16);
mkdirp(file, 0755, function (err) {
if (err) t.fail(err);
else path.exists(file, function (ex) {
if (!ex) t.fail('file not created')
else fs.stat(file, function (err, stat) {
if (err) t.fail(err)
else {
t.equal(stat.mode & 0777, 0755);
t.ok(stat.isDirectory(), 'target not a directory');
t.end();
}
})
})
});
});
test('async root perm', function (t) {
mkdirp('/tmp', 0755, function (err) {
if (err) t.fail(err);
t.end();
});
t.end();
});

View File

@@ -0,0 +1,39 @@
var mkdirp = require('../');
var path = require('path');
var fs = require('fs');
var test = require('tap').test;
test('sync perm', function (t) {
t.plan(2);
var file = '/tmp/' + (Math.random() * (1<<30)).toString(16) + '.json';
mkdirp.sync(file, 0755);
path.exists(file, function (ex) {
if (!ex) t.fail('file not created')
else fs.stat(file, function (err, stat) {
if (err) t.fail(err)
else {
t.equal(stat.mode & 0777, 0755);
t.ok(stat.isDirectory(), 'target not a directory');
t.end();
}
})
});
});
test('sync root perm', function (t) {
t.plan(1);
var file = '/tmp';
mkdirp.sync(file, 0755);
path.exists(file, function (ex) {
if (!ex) t.fail('file not created')
else fs.stat(file, function (err, stat) {
if (err) t.fail(err)
else {
t.ok(stat.isDirectory(), 'target not a directory');
t.end();
}
})
});
});

41
node_modules/jade/node_modules/mkdirp/test/race.js generated vendored Normal file
View File

@@ -0,0 +1,41 @@
var mkdirp = require('../').mkdirp;
var path = require('path');
var fs = require('fs');
var test = require('tap').test;
test('race', function (t) {
t.plan(4);
var ps = [ '', 'tmp' ];
for (var i = 0; i < 25; i++) {
var dir = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
ps.push(dir);
}
var file = ps.join('/');
var res = 2;
mk(file, function () {
if (--res === 0) t.end();
});
mk(file, function () {
if (--res === 0) t.end();
});
function mk (file, cb) {
mkdirp(file, 0755, function (err) {
if (err) t.fail(err);
else path.exists(file, function (ex) {
if (!ex) t.fail('file not created')
else fs.stat(file, function (err, stat) {
if (err) t.fail(err)
else {
t.equal(stat.mode & 0777, 0755);
t.ok(stat.isDirectory(), 'target not a directory');
if (cb) cb();
}
})
})
});
}
});

32
node_modules/jade/node_modules/mkdirp/test/rel.js generated vendored Normal file
View File

@@ -0,0 +1,32 @@
var mkdirp = require('../');
var path = require('path');
var fs = require('fs');
var test = require('tap').test;
test('rel', function (t) {
t.plan(2);
var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
var cwd = process.cwd();
process.chdir('/tmp');
var file = [x,y,z].join('/');
mkdirp(file, 0755, function (err) {
if (err) t.fail(err);
else path.exists(file, function (ex) {
if (!ex) t.fail('file not created')
else fs.stat(file, function (err, stat) {
if (err) t.fail(err)
else {
process.chdir(cwd);
t.equal(stat.mode & 0777, 0755);
t.ok(stat.isDirectory(), 'target not a directory');
t.end();
}
})
})
});
});

27
node_modules/jade/node_modules/mkdirp/test/sync.js generated vendored Normal file
View File

@@ -0,0 +1,27 @@
var mkdirp = require('../');
var path = require('path');
var fs = require('fs');
var test = require('tap').test;
test('sync', function (t) {
t.plan(2);
var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
var file = '/tmp/' + [x,y,z].join('/');
var err = mkdirp.sync(file, 0755);
if (err) t.fail(err);
else path.exists(file, function (ex) {
if (!ex) t.fail('file not created')
else fs.stat(file, function (err, stat) {
if (err) t.fail(err)
else {
t.equal(stat.mode & 0777, 0755);
t.ok(stat.isDirectory(), 'target not a directory');
t.end();
}
})
})
});

28
node_modules/jade/node_modules/mkdirp/test/umask.js generated vendored Normal file
View File

@@ -0,0 +1,28 @@
var mkdirp = require('../');
var path = require('path');
var fs = require('fs');
var test = require('tap').test;
test('implicit mode from umask', function (t) {
t.plan(2);
var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
var file = '/tmp/' + [x,y,z].join('/');
mkdirp(file, function (err) {
if (err) t.fail(err);
else path.exists(file, function (ex) {
if (!ex) t.fail('file not created')
else fs.stat(file, function (err, stat) {
if (err) t.fail(err)
else {
t.equal(stat.mode & 0777, 0777 & (~process.umask()));
t.ok(stat.isDirectory(), 'target not a directory');
t.end();
}
})
})
});
});

View File

@@ -0,0 +1,27 @@
var mkdirp = require('../');
var path = require('path');
var fs = require('fs');
var test = require('tap').test;
test('umask sync modes', function (t) {
t.plan(2);
var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
var file = '/tmp/' + [x,y,z].join('/');
var err = mkdirp.sync(file);
if (err) t.fail(err);
else path.exists(file, function (ex) {
if (!ex) t.fail('file not created')
else fs.stat(file, function (err, stat) {
if (err) t.fail(err)
else {
t.equal(stat.mode & 0777, (0777 & (~process.umask())));
t.ok(stat.isDirectory(), 'target not a directory');
t.end();
}
})
})
});

70
node_modules/jade/package.json generated vendored Normal file
View File

@@ -0,0 +1,70 @@
{
"_from": "jade@0.26.3",
"_id": "jade@0.26.3",
"_inBundle": false,
"_integrity": "sha1-jxDXl32NefL2/4YqgbBRPMslaGw=",
"_location": "/jade",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "jade@0.26.3",
"name": "jade",
"escapedName": "jade",
"rawSpec": "0.26.3",
"saveSpec": null,
"fetchSpec": "0.26.3"
},
"_requiredBy": [
"/mocha"
],
"_resolved": "https://registry.npmjs.org/jade/-/jade-0.26.3.tgz",
"_shasum": "8f10d7977d8d79f2f6ff862a81b0513ccb25686c",
"_spec": "jade@0.26.3",
"_where": "/home/clemens/Dokumente/git/pixelnode/node_modules/mocha",
"author": {
"name": "TJ Holowaychuk",
"email": "tj@vision-media.ca"
},
"bin": {
"jade": "./bin/jade"
},
"bugs": {
"url": "https://github.com/visionmedia/jade/issues"
},
"bundleDependencies": false,
"component": {
"scripts": {
"jade": "runtime.js"
}
},
"dependencies": {
"commander": "0.6.1",
"mkdirp": "0.3.0"
},
"deprecated": "Jade has been renamed to pug, please install the latest version of pug instead of jade",
"description": "Jade template engine",
"devDependencies": {
"less": "*",
"markdown": "*",
"mocha": "*",
"should": "*",
"stylus": "*",
"uglify-js": "*",
"uubench": "*"
},
"homepage": "https://github.com/visionmedia/jade#readme",
"main": "./index.js",
"man": [
"./jade.1"
],
"name": "jade",
"repository": {
"type": "git",
"url": "git://github.com/visionmedia/jade.git"
},
"scripts": {
"prepublish": "npm prune"
},
"version": "0.26.3"
}

179
node_modules/jade/runtime.js generated vendored Normal file
View File

@@ -0,0 +1,179 @@
jade = (function(exports){
/*!
* Jade - runtime
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
* MIT Licensed
*/
/**
* Lame Array.isArray() polyfill for now.
*/
if (!Array.isArray) {
Array.isArray = function(arr){
return '[object Array]' == Object.prototype.toString.call(arr);
};
}
/**
* Lame Object.keys() polyfill for now.
*/
if (!Object.keys) {
Object.keys = function(obj){
var arr = [];
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
arr.push(key);
}
}
return arr;
}
}
/**
* Merge two attribute objects giving precedence
* to values in object `b`. Classes are special-cased
* allowing for arrays and merging/joining appropriately
* resulting in a string.
*
* @param {Object} a
* @param {Object} b
* @return {Object} a
* @api private
*/
exports.merge = function merge(a, b) {
var ac = a['class'];
var bc = b['class'];
if (ac || bc) {
ac = ac || [];
bc = bc || [];
if (!Array.isArray(ac)) ac = [ac];
if (!Array.isArray(bc)) bc = [bc];
ac = ac.filter(nulls);
bc = bc.filter(nulls);
a['class'] = ac.concat(bc).join(' ');
}
for (var key in b) {
if (key != 'class') {
a[key] = b[key];
}
}
return a;
};
/**
* Filter null `val`s.
*
* @param {Mixed} val
* @return {Mixed}
* @api private
*/
function nulls(val) {
return val != null;
}
/**
* Render the given attributes object.
*
* @param {Object} obj
* @param {Object} escaped
* @return {String}
* @api private
*/
exports.attrs = function attrs(obj, escaped){
var buf = []
, terse = obj.terse;
delete obj.terse;
var keys = Object.keys(obj)
, len = keys.length;
if (len) {
buf.push('');
for (var i = 0; i < len; ++i) {
var key = keys[i]
, val = obj[key];
if ('boolean' == typeof val || null == val) {
if (val) {
terse
? buf.push(key)
: buf.push(key + '="' + key + '"');
}
} else if (0 == key.indexOf('data') && 'string' != typeof val) {
buf.push(key + "='" + JSON.stringify(val) + "'");
} else if ('class' == key && Array.isArray(val)) {
buf.push(key + '="' + exports.escape(val.join(' ')) + '"');
} else if (escaped && escaped[key]) {
buf.push(key + '="' + exports.escape(val) + '"');
} else {
buf.push(key + '="' + val + '"');
}
}
}
return buf.join(' ');
};
/**
* Escape the given string of `html`.
*
* @param {String} html
* @return {String}
* @api private
*/
exports.escape = function escape(html){
return String(html)
.replace(/&(?!(\w+|\#\d+);)/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;');
};
/**
* Re-throw the given `err` in context to the
* the jade in `filename` at the given `lineno`.
*
* @param {Error} err
* @param {String} filename
* @param {String} lineno
* @api private
*/
exports.rethrow = function rethrow(err, filename, lineno){
if (!filename) throw err;
var context = 3
, str = require('fs').readFileSync(filename, 'utf8')
, lines = str.split('\n')
, start = Math.max(lineno - context, 0)
, end = Math.min(lines.length, lineno + context);
// Error context
var context = lines.slice(start, end).map(function(line, i){
var curr = i + start + 1;
return (curr == lineno ? ' > ' : ' ')
+ curr
+ '| '
+ line;
}).join('\n');
// Alter exception message
err.path = filename;
err.message = (filename || 'Jade') + ':' + lineno
+ '\n' + context + '\n\n' + err.message;
throw err;
};
return exports;
})({});

1
node_modules/jade/runtime.min.js generated vendored Normal file
View File

@@ -0,0 +1 @@
jade=function(exports){Array.isArray||(Array.isArray=function(arr){return"[object Array]"==Object.prototype.toString.call(arr)}),Object.keys||(Object.keys=function(obj){var arr=[];for(var key in obj)obj.hasOwnProperty(key)&&arr.push(key);return arr}),exports.merge=function merge(a,b){var ac=a["class"],bc=b["class"];if(ac||bc)ac=ac||[],bc=bc||[],Array.isArray(ac)||(ac=[ac]),Array.isArray(bc)||(bc=[bc]),ac=ac.filter(nulls),bc=bc.filter(nulls),a["class"]=ac.concat(bc).join(" ");for(var key in b)key!="class"&&(a[key]=b[key]);return a};function nulls(val){return val!=null}return exports.attrs=function attrs(obj,escaped){var buf=[],terse=obj.terse;delete obj.terse;var keys=Object.keys(obj),len=keys.length;if(len){buf.push("");for(var i=0;i<len;++i){var key=keys[i],val=obj[key];"boolean"==typeof val||null==val?val&&(terse?buf.push(key):buf.push(key+'="'+key+'"')):0==key.indexOf("data")&&"string"!=typeof val?buf.push(key+"='"+JSON.stringify(val)+"'"):"class"==key&&Array.isArray(val)?buf.push(key+'="'+exports.escape(val.join(" "))+'"'):escaped&&escaped[key]?buf.push(key+'="'+exports.escape(val)+'"'):buf.push(key+'="'+val+'"')}}return buf.join(" ")},exports.escape=function escape(html){return String(html).replace(/&(?!(\w+|\#\d+);)/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")},exports.rethrow=function rethrow(err,filename,lineno){if(!filename)throw err;var context=3,str=require("fs").readFileSync(filename,"utf8"),lines=str.split("\n"),start=Math.max(lineno-context,0),end=Math.min(lines.length,lineno+context),context=lines.slice(start,end).map(function(line,i){var curr=i+start+1;return(curr==lineno?" > ":" ")+curr+"| "+line}).join("\n");throw err.path=filename,err.message=(filename||"Jade")+":"+lineno+"\n"+context+"\n\n"+err.message,err},exports}({});

7
node_modules/jade/test.jade generated vendored Normal file
View File

@@ -0,0 +1,7 @@
p.
This is a large
body of text for
this tag.
Nothing too
exciting.

5
node_modules/jade/testing/head.jade generated vendored Normal file
View File

@@ -0,0 +1,5 @@
head
script(src='/jquery.js')
yield
if false
script(src='/jquery.ui.js')

22
node_modules/jade/testing/index.jade generated vendored Normal file
View File

@@ -0,0 +1,22 @@
tag = 'p'
foo = 'bar'
#{tag} value
#{tag}(foo='bar') value
#{foo ? 'a' : 'li'}(something) here
mixin item(icon)
li
if attributes.href
a(attributes)
img.icon(src=icon)
block
else
span(attributes)
img.icon(src=icon)
block
ul
+item('contact') Contact
+item(href='/contact') Contact

11
node_modules/jade/testing/index.js generated vendored Normal file
View File

@@ -0,0 +1,11 @@
/**
* Module dependencies.
*/
var jade = require('../');
jade.renderFile('testing/index.jade', { pretty: true, debug: true, compileDebug: false }, function(err, str){
if (err) throw err;
console.log(str);
});

6
node_modules/jade/testing/layout.jade generated vendored Normal file
View File

@@ -0,0 +1,6 @@
html
include head
script(src='/caustic.js')
script(src='/app.js')
body
block content

7
node_modules/jade/testing/user.jade generated vendored Normal file
View File

@@ -0,0 +1,7 @@
h1 Tobi
p Is a ferret
ul
li: a foo
li: a bar
li: a baz

27
node_modules/jade/testing/user.js generated vendored Normal file
View File

@@ -0,0 +1,27 @@
function anonymous(locals, attrs, escape, rethrow) {
var attrs = jade.attrs, escape = jade.escape, rethrow = jade.rethrow;
var __jade = [{ lineno: 1, filename: "testing/user.jade" }];
try {
var buf = [];
with (locals || {}) {
var interp;
__jade.unshift({ lineno: 1, filename: __jade[0].filename });
__jade.unshift({ lineno: 1, filename: __jade[0].filename });
buf.push('<h1>Tobi');
__jade.unshift({ lineno: undefined, filename: __jade[0].filename });
__jade.shift();
buf.push('</h1>');
__jade.shift();
__jade.unshift({ lineno: 2, filename: __jade[0].filename });
buf.push('<p>Is a ferret');
__jade.unshift({ lineno: undefined, filename: __jade[0].filename });
__jade.shift();
buf.push('</p>');
__jade.shift();
__jade.shift();
}
return buf.join("");
} catch (err) {
rethrow(err, __jade[0].filename, __jade[0].lineno);
}
}