Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Add marked and props

  • Loading branch information...
commit 588e36f88a690889ba7bc9762dc576ce4ca02b08 1 parent 9ed9bf9
@pvorb authored
View
2  node_modules/marked/.npmignore
@@ -0,0 +1,2 @@
+.git
+test
View
19 node_modules/marked/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2011, Christopher Jeffrey (https://github.com/chjj/)
+
+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.
View
10 node_modules/marked/Makefile
@@ -0,0 +1,10 @@
+all:
+ @cp lib/marked.js marked.js
+ @uglifyjs -mt --unsafe -o marked.min.js marked.js
+
+clean:
+ @rm marked.js
+ @rm marked.min.js
+
+.PHONY: clean all
+
View
69 node_modules/marked/README.md
@@ -0,0 +1,69 @@
+# marked
+
+A full-featured markdown parser and compiler implemented in ~430 lines of JS.
+Built for speed.
+
+## Benchmarks
+
+``` bash
+$ node test --bench
+marked completed in 12071ms.
+showdown (reuse converter) completed in 27387ms.
+showdown (new converter) completed in 75617ms.
+markdown-js completed in 70069ms.
+```
+
+## Install
+
+``` bash
+$ npm install marked
+```
+
+# Another javascript markdown parser
+
+The point of marked was to create a markdown compiler where it was possible to
+frequently parse huge chunks of markdown without having to worry about
+caching the compiled output somehow...or blocking for an unnecesarily long time.
+
+marked lingers around 430 (may vary) lines long and still implements all
+markdown features. It is also now fully compatible with the client-side.
+
+marked more or less passes the official markdown test suite in its
+entirety. This is important because a surprising number of markdown compilers
+cannot pass more than a few tests. It was very difficult to get marked as
+compliant as it is. It could have cut corners in several areas for the sake
+of performance, but did not in order to be exactly what you expect in terms
+of a markdown rendering. In fact, this is why marked could be considered at a
+disadvantage in the benchmarks above.
+
+## Usage
+
+``` js
+var marked = require('marked');
+console.log(marked('i am using __markdown__.'));
+```
+
+You also have direct access to the lexer and parser if you so desire.
+
+``` js
+var tokens = marked.lexer(str);
+console.log(marked.parser(tokens));
+```
+
+``` bash
+$ node
+> require('marked').lexer('> i am using marked.')
+[ { type: 'blockquote_start' },
+ { type: 'text', text: ' i am using marked.' },
+ { type: 'blockquote_end' },
+ links: {} ]
+```
+
+## Todo (& notes to self)
+
+- Implement GFM features.
+- Possibly add some
+ [ReMarkable](http://camendesign.com/code/remarkable/documentation.html)
+ features while remaining backwardly compatible with all markdown syntax.
+- Optimize the lexer to return an iterator instead of a collection of tokens.
+- Add an explicit pretty printing and minification feature.
View
126 node_modules/marked/bin/marked
@@ -0,0 +1,126 @@
+#!/usr/bin/env node
+
+/**
+ * Marked CLI
+ * Copyright (c) 2011, Christopher Jeffrey (MIT License)
+ */
+
+var fs = require('fs')
+ , util = require('util')
+ , marked = require('../');
+
+var usage = function() {
+ console.log('marked - a markdown parser');
+ console.log('');
+ console.log('Usage:');
+ console.log(' marked [-oih] [input]');
+ console.log('');
+ console.log('Options:');
+ console.log(' -o, --output: Specify output file. If none is');
+ console.log(' specified, write to stdout.');
+ console.log(' -i, --input: Specify input file, otherwise use last');
+ console.log(' argument as input file. If no input');
+ console.log(' file is specified, read from stdin.');
+ console.log(' -t, --tokens: Output a token stream instead of html.');
+ console.log(' -h, --help: Display this message.');
+ console.log('');
+ console.log('Examples:');
+ console.log(' cat in.md | marked > out.html');
+ console.log(' echo "hello *world*" | marked');
+ console.log(' marked -o out.html in.md');
+ console.log(' marked --output="hello world.html" -i in.md');
+ console.log('');
+ console.log(' $ marked');
+ console.log(' > hello __world__\\n^D');
+ console.log(' <p>hello <strong>world</strong></p>');
+ console.log('');
+ process.exit(0);
+};
+
+var main = function(argv) {
+ var files = []
+ , input
+ , output
+ , arg
+ , data
+ , tokens;
+
+ var getarg = function() {
+ var arg = argv.shift();
+ arg = arg.split('=');
+ if (arg.length > 1) {
+ argv.unshift(arg.sice(1).join('='));
+ }
+ return arg[0];
+ };
+
+ while (argv.length) {
+ arg = getarg();
+ switch (arg) {
+ case '-o':
+ case '--output':
+ output = argv.shift();
+ break;
+ case '-i':
+ case '--input':
+ input = argv.shift();
+ break;
+ case '-t':
+ case '--tokens':
+ tokens = true;
+ break;
+ case '--gfm':
+ console.log('Implement me!');
+ process.exit(0);
+ break;
+ case '-h':
+ case '--help':
+ usage();
+ break;
+ default:
+ files.push(arg);
+ break;
+ }
+ }
+
+ if (!input && files.length !== 2) {
+ input = files.pop();
+ }
+
+ if (!input && files.length === 2) {
+ var stdin = process.openStdin()
+ , buff = [];
+
+ stdin.setEncoding('utf8');
+ stdin.on('data', function(data) {
+ buff.push(data);
+ });
+
+ stdin.on('end', function() {
+ data = buff.join('');
+ write();
+ });
+ } else {
+ data = fs.readFileSync(input, 'utf8');
+ write();
+ }
+
+ function write() {
+ data = tokens
+ ? util.inspect(marked.lexer(data))
+ : marked(data);
+
+ if (!output) {
+ process.stdout.write(data + '\n');
+ } else {
+ fs.writeFileSync(output, data);
+ }
+ }
+};
+
+if (!module.parent) {
+ process.title = 'marked';
+ main(process.argv.slice());
+} else {
+ module.exports = main;
+}
View
1  node_modules/marked/index.js
@@ -0,0 +1 @@
+module.exports = require('./lib/marked');
View
561 node_modules/marked/lib/marked.js
@@ -0,0 +1,561 @@
+/**
+ * marked - A markdown parser
+ * Copyright (c) 2011, Christopher Jeffrey. (MIT Licensed)
+ */
+
+;(function() {
+
+/**
+ * Block-Level Grammar
+ */
+
+var block = {
+ newline: /^\n+/,
+ code: /^ {4,}[^\n]*(?:\n {4,}[^\n]*|\n)*(?=\n| *$)/,
+ hr: /^( *[\-*_]){3,} *\n/,
+ heading: /^ *(#{1,6}) *([^\0]+?) *#* *\n+/,
+ lheading: /^([^\n]+)\n *(=|-){3,}/,
+ blockquote: /^ *>[^\n]*(?:\n *>[^\n]*)*/,
+ list: /^( *)([*+-]|\d+\.) [^\0]+?(?:\n{2,}(?! )|\s*$)(?!\1\2|\1\d+\.)/,
+ html: /^ *(?:<!--[^\0]*?-->|<(\w+)[^\0]+?<\/\1>|<\w+[^>]*>) *(?:\n{2,}|\s*$)/,
+ text: /^[^\n]+/
+};
+
+/**
+ * Block Lexer
+ */
+
+block.lexer = function(str) {
+ var tokens = []
+ , links = {};
+
+ str = str.replace(/\r\n|\r/g, '\n')
+ .replace(/\t/g, ' ');
+
+ str = str.replace(
+ /^ {0,3}\[([^\]]+)\]: *([^ ]+)(?: +"([^\n]+)")? *$/gm,
+ function(__, id, href, title) {
+ links[id] = {
+ href: href,
+ title: title
+ };
+ return '';
+ }
+ );
+
+ tokens.links = links;
+
+ return block.token(str, tokens);
+};
+
+block.token = function(str, tokens) {
+ var str = str.replace(/^ +$/gm, '')
+ , loose
+ , cap
+ , item
+ , space
+ , i
+ , l;
+
+ while (str) {
+ // newline
+ if (cap = block.newline.exec(str)) {
+ str = str.substring(cap[0].length);
+ if (cap[0].length > 1) {
+ tokens.push({
+ type: 'space'
+ });
+ }
+ continue;
+ }
+
+ // code
+ if (cap = block.code.exec(str)) {
+ str = str.substring(cap[0].length);
+ cap = cap[0].replace(/^ {4}/gm, '');
+ tokens.push({
+ type: 'code',
+ text: cap
+ });
+ continue;
+ }
+
+ // heading
+ if (cap = block.heading.exec(str)) {
+ str = str.substring(cap[0].length);
+ tokens.push({
+ type: 'heading',
+ depth: cap[1].length,
+ text: cap[2]
+ });
+ continue;
+ }
+
+ // lheading
+ if (cap = block.lheading.exec(str)) {
+ str = str.substring(cap[0].length);
+ tokens.push({
+ type: 'heading',
+ depth: cap[2] === '=' ? 1 : 2,
+ text: cap[1]
+ });
+ continue;
+ }
+
+ // hr
+ if (cap = block.hr.exec(str)) {
+ str = str.substring(cap[0].length);
+ tokens.push({
+ type: 'hr'
+ });
+ continue;
+ }
+
+ // blockquote
+ if (cap = block.blockquote.exec(str)) {
+ str = str.substring(cap[0].length);
+ tokens.push({
+ type: 'blockquote_start'
+ });
+ cap = cap[0].replace(/^ *>/gm, '');
+ block.token(cap, tokens);
+ tokens.push({
+ type: 'blockquote_end'
+ });
+ continue;
+ }
+
+ // list
+ if (cap = block.list.exec(str)) {
+ str = str.substring(cap[0].length);
+
+ tokens.push({
+ type: 'list_start',
+ ordered: isFinite(cap[2])
+ });
+
+ loose = /\n *\n *(?:[*+-]|\d+\.)/.test(cap[0]);
+
+ // get each top-level item
+ cap = cap[0].match(
+ /^( *)([*+-]|\d+\.)[^\n]*(?:\n(?!\1(?:\2|\d+\.))[^\n]*)*/gm
+ );
+
+ i = 0;
+ l = cap.length;
+
+ for (; i < l; i++) {
+ // remove the list items sigil
+ // so its seen as the next token
+ item = cap[i].replace(/^ *([*+-]|\d+\.) */, '');
+ // outdent whatever the
+ // list item contains, hacky
+ space = /\n( +)/.exec(item);
+ if (space) {
+ space = new RegExp('^' + space[1], 'gm');
+ item = item.replace(space, '');
+ }
+ tokens.push({
+ type: loose
+ ? 'loose_item_start'
+ : 'list_item_start'
+ });
+ block.token(item, tokens);
+ tokens.push({
+ type: 'list_item_end'
+ });
+ }
+
+ tokens.push({
+ type: 'list_end'
+ });
+
+ continue;
+ }
+
+ // html
+ if (cap = block.html.exec(str)) {
+ str = str.substring(cap[0].length);
+ tokens.push({
+ type: 'html',
+ text: cap[0]
+ });
+ continue;
+ }
+
+ // text
+ if (cap = block.text.exec(str)) {
+ str = str.substring(cap[0].length);
+ tokens.push({
+ type: 'text',
+ text: cap[0]
+ });
+ continue;
+ }
+ }
+
+ return tokens;
+};
+
+/**
+ * Inline Processing
+ */
+
+var inline = {
+ escape: /^\\([\\`*{}\[\]()#+\-.!_])/,
+ autolink: /^<([^ >]+(@|:\/)[^ >]+)>/,
+ tag: /^<!--[^\0]*?-->|^<\/?\w+[^>]*>/,
+ link: /^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]\(([^\)]*)\)/,
+ reflink: /^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]\s*\[([^\]]*)\]/,
+ nolink: /^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,
+ strong: /^__([^\0]+?)__(?!_)|^\*\*([^\0]+?)\*\*(?!\*)/,
+ em: /^_([^_]+)_|^\*([^*]+)\*/,
+ code: /^`([^`]+)`|^``([^\0]+?)``/,
+ br: /^ {2,}\n(?!\s*$)/,
+ text: /^/
+};
+
+// hacky, but performant
+inline.text = (function() {
+ var body = [];
+
+ (function push(rule) {
+ rule = inline[rule].source;
+ body.push(rule.replace(/(^|[^\[])\^/g, '$1'));
+ return push;
+ })
+ ('escape')
+ ('tag')
+ ('nolink')
+ ('strong')
+ ('em')
+ ('code')
+ ('br');
+
+ return new
+ RegExp('^[^\\0]+?(?=' + body.join('|') + '|$)');
+})();
+
+/**
+ * Inline Lexer
+ */
+
+inline.lexer = function(str) {
+ var out = ''
+ , links = tokens.links
+ , link
+ , text
+ , href
+ , cap;
+
+ while (str) {
+ // escape
+ if (cap = inline.escape.exec(str)) {
+ str = str.substring(cap[0].length);
+ out += cap[1];
+ continue;
+ }
+
+ // autolink
+ if (cap = inline.autolink.exec(str)) {
+ str = str.substring(cap[0].length);
+ if (cap[2] === '@') {
+ text = cap[1][6] === ':'
+ ? mangle(cap[1].substring(7))
+ : mangle(cap[1]);
+ href = mangle('mailto:') + text;
+ } else {
+ text = escape(cap[1]);
+ href = text;
+ }
+ out += '<a href="'
+ + href
+ + '">'
+ + text
+ + '</a>';
+ continue;
+ }
+
+ // tag
+ if (cap = inline.tag.exec(str)) {
+ str = str.substring(cap[0].length);
+ out += cap[0];
+ continue;
+ }
+
+ // link
+ if (cap = inline.link.exec(str)) {
+ str = str.substring(cap[0].length);
+ text = /^\s*<?([^\s]*?)>?(?:\s+"([^\n]+)")?\s*$/.exec(cap[2]);
+ link = {
+ href: text[1],
+ title: text[2]
+ };
+ out += mlink(cap, link);
+ continue;
+ }
+
+ // reflink, nolink
+ if ((cap = inline.reflink.exec(str))
+ || (cap = inline.nolink.exec(str))) {
+ str = str.substring(cap[0].length);
+ link = (cap[2] || cap[1]).replace(/\s+/g, ' ');
+ link = links[link];
+ if (!link) {
+ out += cap[0][0];
+ str = cap[0].substring(1) + str;
+ continue;
+ }
+ out += mlink(cap, link);
+ continue;
+ }
+
+ // strong
+ if (cap = inline.strong.exec(str)) {
+ str = str.substring(cap[0].length);
+ out += '<strong>'
+ + inline.lexer(cap[2] || cap[1])
+ + '</strong>';
+ continue;
+ }
+
+ // em
+ if (cap = inline.em.exec(str)) {
+ str = str.substring(cap[0].length);
+ out += '<em>'
+ + inline.lexer(cap[2] || cap[1])
+ + '</em>';
+ continue;
+ }
+
+ // code
+ if (cap = inline.code.exec(str)) {
+ str = str.substring(cap[0].length);
+ out += '<code>'
+ + escape(cap[2] || cap[1], true)
+ + '</code>';
+ continue;
+ }
+
+ // br
+ if (cap = inline.br.exec(str)) {
+ str = str.substring(cap[0].length);
+ out += '<br>';
+ continue;
+ }
+
+ // text
+ if (cap = inline.text.exec(str)) {
+ str = str.substring(cap[0].length);
+ out += escape(cap[0]);
+ continue;
+ }
+ }
+
+ return out;
+};
+
+var mlink = function(cap, link) {
+ if (cap[0][0] !== '!') {
+ return '<a href="'
+ + escape(link.href)
+ + '"'
+ + (link.title
+ ? ' title="'
+ + escape(link.title)
+ + '"'
+ : '')
+ + '>'
+ + inline.lexer(cap[1])
+ + '</a>';
+ } else {
+ return '<img src="'
+ + escape(link.href)
+ + '" alt="'
+ + escape(cap[1])
+ + '"'
+ + (link.title
+ ? ' title="'
+ + escape(link.title)
+ + '"'
+ : '')
+ + '>';
+ }
+};
+
+/**
+ * Parsing
+ */
+
+var tokens
+ , token;
+
+var next = function() {
+ return token = tokens.pop();
+};
+
+var tok = function() {
+ switch (token.type) {
+ case 'space': {
+ return '';
+ }
+ case 'hr': {
+ return '<hr>';
+ }
+ case 'heading': {
+ return '<h'
+ + token.depth
+ + '>'
+ + inline.lexer(token.text)
+ + '</h'
+ + token.depth
+ + '>';
+ }
+ case 'code': {
+ if (token.text[token.text.length-1] === '\n') {
+ token.text = token.text.slice(0, -1);
+ }
+ return '<pre><code>'
+ + escape(token.text, true)
+ + '</code></pre>';
+ }
+ case 'blockquote_start': {
+ var body = [];
+
+ while (next().type !== 'blockquote_end') {
+ body.push(tok());
+ }
+
+ return '<blockquote>'
+ + body.join('')
+ + '</blockquote>';
+ }
+ case 'list_start': {
+ var type = token.ordered ? 'ol' : 'ul'
+ , body = [];
+
+ while (next().type !== 'list_end') {
+ body.push(tok());
+ }
+
+ return '<'
+ + type
+ + '>'
+ + body.join('')
+ + '</'
+ + type
+ + '>';
+ }
+ case 'list_item_start': {
+ var body = [];
+
+ while (next().type !== 'list_item_end') {
+ body.push(token.type === 'text'
+ ? text()
+ : tok());
+ }
+
+ return '<li>'
+ + body.join(' ')
+ + '</li>';
+ }
+ case 'loose_item_start': {
+ var body = [];
+
+ while (next().type !== 'list_item_end') {
+ body.push(tok());
+ }
+
+ return '<li>'
+ + body.join(' ')
+ + '</li>';
+ }
+ case 'html': {
+ return inline.lexer(token.text);
+ }
+ case 'text': {
+ return '<p>'
+ + text()
+ + '</p>';
+ }
+ }
+};
+
+var text = function() {
+ var body = [ token.text ]
+ , top;
+
+ while ((top = tokens[tokens.length-1])
+ && top.type === 'text') {
+ body.push(next().text);
+ }
+
+ return inline.lexer(body.join('\n'));
+};
+
+var parse = function(src) {
+ tokens = src.reverse();
+
+ var out = [];
+ while (next()) {
+ out.push(tok());
+ }
+
+ tokens = null;
+ token = null;
+
+ return out.join(' ');
+};
+
+/**
+ * Helpers
+ */
+
+var escape = function(html, dbl) {
+ return html
+ .replace(!dbl
+ ? /&(?!#?\w+;)/g
+ : /&/g, '&amp;')
+ .replace(/</g, '&lt;')
+ .replace(/>/g, '&gt;')
+ .replace(/"/g, '&quot;')
+ .replace(/'/g, '&apos;');
+};
+
+var mangle = function(str) {
+ var out = ''
+ , ch
+ , i = 0
+ , l = str.length;
+
+ for (; i < l; i++) {
+ ch = str.charCodeAt(i);
+ if (Math.random() > 0.5) {
+ ch = 'x' + ch.toString(16);
+ }
+ out += '&#' + ch + ';';
+ }
+
+ return out;
+};
+
+/**
+ * Expose
+ */
+
+var marked = function(str) {
+ return parse(block.lexer(str));
+};
+
+marked.parser = parse;
+marked.lexer = block.lexer;
+
+marked.parse = marked;
+
+if (typeof module !== 'undefined') {
+ module.exports = marked;
+} else {
+ this.marked = marked;
+}
+
+}).call(this);
View
10 node_modules/marked/package.json
@@ -0,0 +1,10 @@
+{
+ "name": "marked",
+ "description": "A markdown parser built for speed",
+ "author": "Christopher Jeffrey",
+ "version": "0.1.4",
+ "main": "./lib/marked.js",
+ "bin": { "marked": "./bin/marked" },
+ "repository": "git://github.com/chjj/marked.git",
+ "keywords": [ "markdown", "markup" ]
+}
View
1  node_modules/props/.npmignore
@@ -0,0 +1 @@
+test/
View
18 node_modules/props/LICENSE.mkd
@@ -0,0 +1,18 @@
+Copyright © 2011 Paul Vorbach <paul@vorb.de>
+
+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, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
View
71 node_modules/props/README.mkd
@@ -0,0 +1,71 @@
+**props** is a module for node that is able to extract either JSON or YAML from
+the beginning of a string.
+
+Usage
+=====
+
+```javascript
+var props = require("props");
+
+// Use JSON
+
+var json =
+'{\n\
+ "title": "How to use node.js",\n\
+ "date": "2011-08-09T17:56:00",\n\
+ "tags": [ "example", "node.js" ]\n\
+}\n\
+\n\
+\n\
+Node.js is a new technology...';
+
+console.log(props(json));
+
+// or YAML
+
+var yaml =
+'title: How to use node.js\n\
+date: 2011-08-09T17:56:00\n\
+tags:\n\
+ - example\n\
+ - node.js\
+\n\
+\n\
+Node.js is a new technology...';
+
+console.log(props(yaml));
+```
+
+This will print nearly the same object twice, since `json` and `yaml` define the
+same object:
+
+_JSON_:
+
+```javascript
+{ title: 'How to use node.js',
+ date: '2011-08-09T17:56:00',
+ tags: [ 'example', 'node.js' ],
+ __content: 'Node.js is a new technology...' }
+
+```
+
+_YAML_:
+
+```javascript
+{ title: 'How to use node.js',
+ date: Tue, 09 Aug 2011 15:56:00 GMT,
+ tags: [ 'example', 'node.js' ],
+ __content: 'Node.js is a new technology...' }
+```
+
+The difference is that, due to it's JS implementation, the Date is parsed in the
+YAML version.
+
+The JSON/YAML part has to be **always** seperated from the content by three
+newline characters (`\n\n\n` or `\r\n\r\n\r\n`).
+
+
+License
+=======
+
+The [MIT license](http://vorb.de/license/mit.html).
View
28 node_modules/props/lib/props.js
@@ -0,0 +1,28 @@
+var yaml = require("yamlparser");
+
+module.exports = function(str) {
+ // `str` must be a string
+ if (typeof str !== 'string')
+ str = str.toString();
+
+ var split, result = {}, content;
+
+ // If the string starts with "{", look for JSON
+ if (str.match(/^{/)
+ && (split = str.split(/\r?\n\r?\n\r?\n/, 2)).length > 0) {
+ result = JSON.parse(split[0]);
+ }
+ // If not, look for YAML
+ else if ((split = str.split(/\n\n\n|\r\n\r\n\r\n/, 2)).length > 0) {
+ result = yaml.eval(split[0]);
+ }
+ // If no match was found, the whole string is the content
+ else {
+ return { __content: str };
+ }
+
+ // The second part of the array is the content string
+ result["__content"] = split[1];
+
+ return result;
+};
View
21 node_modules/props/node_modules/yamlparser/LICENSE
@@ -0,0 +1,21 @@
+This program is released under the MIT License as follows:
+
+Copyright (c) 2011 Diogo Costa (costa.h4evr@gmail.com)
+
+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.
View
48 node_modules/props/node_modules/yamlparser/README.markdown
@@ -0,0 +1,48 @@
+YAML Parser for Javascript
+==========================
+
+Author: Diogo Costa (<costa.h4evr@gmail.com>)
+
+Date: 8th August 2011
+
+Description
+-----------
+
+This is CommonJS port of my Javascript YAML Parser, available at:
+http://code.google.com/p/javascript-yaml-parser/
+
+The same as the original project, this project intends to implement a simple YAML
+parser. It does not intend to implement all the aspects formalized in the YAML
+specs, but rather to implement a robust parser in Javascript, enough to load
+simply structured YAML files.
+
+Installation
+------------
+
+The parser is available as a NPM module, this is the recommended way of installation.
+
+Run the following command and you should be ready to go:
+
+ npm install yamlparser
+
+Documentation
+-------------
+
+ToDo
+
+Disclaimer
+----------
+
+I try to deliver high quality products, but I do not guarantee that the product
+is free from defects. My software is provided "as is", and you use the software
+at your own risk.
+
+I make no warranties as to performance, merchantability, fitness for a
+particular purpose, or any other warranties whether expressed or implied.
+
+Under no circumstances shall I be liable for direct, indirect, special,
+incidental, or consequential damages resulting from the use, misuse, or
+inability to use this software, even if I have been advised of the possibility
+of such damages.
+
+Please consult the license file for more information.
View
11 node_modules/props/node_modules/yamlparser/package.json
@@ -0,0 +1,11 @@
+{
+ "author": "Diogo Costa <costa.h4evr@gmail.com> (http://diogocosta.pt.tl/)",
+ "name": "yamlparser",
+ "description": "A YAML parser written in javascript. This is the port to CommonJS. Client-side script is available at http://code.google.com/p/javascript-yaml-parser/",
+ "version": "0.0.2",
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/h4evr/commonjs-javascript-yaml-parser.git"
+ },
+ "main": "yamlparser"
+}
View
62 node_modules/props/node_modules/yamlparser/tests/example.yml
@@ -0,0 +1,62 @@
+---
+# Hello World!
+
+chart:
+ - {x: 1993, y: 5}
+
+ - {x: 1994, y: 5}
+
+ - {x: 1995, y: 5}
+
+ - {x: 1996, y: 5}
+
+multi-level:
+ - array1:
+ - 1
+ - 2
+ - 3
+ - 4
+ - 5
+ - array2: { teste: ah, bah: 123 }
+ - array3:
+ - array31:
+ - array311: [0, 1, 2, 3]
+
+receipt: Oz-Ware Purchase Invoice # isto é um comentário
+date: 2007-08-06
+customer:
+ given: Dorothy
+ family: Gale
+ pessoa:
+ married: false
+ money: .NaN
+ name: {first: "Diogo", last: "Costa"}
+ surname: Costa
+
+items:
+ - part_no: A4786
+ descrip: Water Bucket (Filled)
+ price: 1.47
+ quantity: 4
+
+ - part_no: E1628
+ descrip: High Heeled "Ruby" Slippers
+ size: 8
+ price: 100.27
+ quantity: 1
+
+bill-to: &id001
+ street: |
+ 123 Tornado Alley
+ Suite 16
+ city: East Centerville
+ state: KS
+
+ship-to: *id001
+
+specialDelivery: >
+ Follow the Yellow Brick
+ Road to the Emerald City.
+ Pay no attention to the man
+ behind the curtain.
+...
View
26 node_modules/props/node_modules/yamlparser/tests/index.html
@@ -0,0 +1,26 @@
+<!DOCTYPE HTML>
+<html lang="en-US">
+<head>
+ <meta charset="UTF-8">
+ <title>YAML Parser</title>
+ <script type="text/javascript" src="../src/yaml.js"></script>
+ <script type="text/javascript">
+ window.onload = function() {
+ var test1 = YAML.eval("---\n- one\n- two");
+ var test2 = YAML.eval("---\none: two");
+
+ YAML.fromURL("example.yml", function(data) {
+ var errors = YAML.getErrors();
+ if(errors.length == 0)
+ document.getElementById("out").innerHTML = "Done! Took " + YAML.getProcessingTime() + " miliseconds.";
+ else {
+ document.getElementById("out").innerHTML = errors.join("<br>");
+ }
+ });
+ };
+ </script>
+</head>
+<body>
+ <pre id="out"></pre>
+</body>
+</html>
View
13 node_modules/props/node_modules/yamlparser/tests/server.js
@@ -0,0 +1,13 @@
+var http = require('http');
+var yaml = require('yamlparser');
+
+http.createServer(function(req, res) {
+ res.writeHead(200, {'Content-Type' : 'text/plain' });
+
+ var fs = require('fs');
+ var fileContents = fs.readFileSync('example.yml', 'utf8');
+ var data = yaml.eval(fileContents);
+ res.end(JSON.stringify(data));
+}).listen(8080, "127.0.0.1");
+
+console.log('Server running at http://127.0.0.1:8080');
View
466 node_modules/props/node_modules/yamlparser/yamlparser.js
@@ -0,0 +1,466 @@
+/*
+YAML parser for Javascript
+Author: Diogo Costa
+
+This program is released under the MIT License as follows:
+
+Copyright (c) 2011 Diogo Costa (costa.h4evr@gmail.com)
+
+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.
+*/
+
+/**
+ * @name YAML
+ * @namespace
+*/
+
+var YAML =
+(function() {
+ var errors = [],
+ reference_blocks = [],
+ processing_time = 0,
+ regex =
+ {
+ "regLevel" : new RegExp("^([\\s\\-]+)"),
+ "invalidLine" : new RegExp("^\\-\\-\\-|^\\.\\.\\.|^\\s*#.*|^\\s*$"),
+ "dashesString" : new RegExp("^\\s*\\\"([^\\\"]*)\\\"\\s*$"),
+ "quotesString" : new RegExp("^\\s*\\\'([^\\\']*)\\\'\\s*$"),
+ "float" : new RegExp("^[+-]?[0-9]+\\.[0-9]+(e[+-]?[0-9]+(\\.[0-9]+)?)?$"),
+ "integer" : new RegExp("^[+-]?[0-9]+$"),
+ "array" : new RegExp("\\[\\s*(.*)\\s*\\]"),
+ "map" : new RegExp("\\{\\s*(.*)\\s*\\}"),
+ "key_value" : new RegExp("([a-z0-9_-][ a-z0-9_-]*):( .+)", "i"),
+ "single_key_value" : new RegExp("^([a-z0-9_-][ a-z0-9_-]*):( .+?)$", "i"),
+ "key" : new RegExp("([a-z0-9_-][ a-z0-9_-]+):( .+)?", "i"),
+ "item" : new RegExp("^-\\s+"),
+ "trim" : new RegExp("^\\s+|\\s+$"),
+ "comment" : new RegExp("([^\\\'\\\"#]+([\\\'\\\"][^\\\'\\\"]*[\\\'\\\"])*)*(#.*)?")
+ };
+
+ /**
+ * @class A block of lines of a given level.
+ * @param {int} lvl The block's level.
+ * @private
+ */
+ function Block(lvl) {
+ return {
+ /* The block's parent */
+ parent: null,
+ /* Number of children */
+ length: 0,
+ /* Block's level */
+ level: lvl,
+ /* Lines of code to process */
+ lines: [],
+ /* Blocks with greater level */
+ children : [],
+ /* Add a block to the children collection */
+ addChild : function(obj) {
+ this.children.push(obj);
+ obj.parent = this;
+ ++this.length;
+ }
+ };
+ }
+
+ function parser(str) {
+ var regLevel = regex["regLevel"];
+ var invalidLine = regex["invalidLine"];
+ var lines = str.split("\n");
+ var m;
+ var level = 0, curLevel = 0;
+
+ var blocks = [];
+
+ var result = new Block(-1);
+ var currentBlock = new Block(0);
+ result.addChild(currentBlock);
+ var levels = [];
+ var line = "";
+
+ blocks.push(currentBlock);
+ levels.push(level);
+
+ for(var i = 0, len = lines.length; i < len; ++i) {
+ line = lines[i];
+
+ if(line.match(invalidLine)) {
+ continue;
+ }
+
+ if(m = regLevel.exec(line)) {
+ level = m[1].length;
+ } else
+ level = 0;
+
+ if(level > curLevel) {
+ var oldBlock = currentBlock;
+ currentBlock = new Block(level);
+ oldBlock.addChild(currentBlock);
+ blocks.push(currentBlock);
+ levels.push(level);
+ } else if(level < curLevel) {
+ var added = false;
+
+ var k = levels.length - 1;
+ for(; k >= 0; --k) {
+ if(levels[k] == level) {
+ currentBlock = new Block(level);
+ blocks.push(currentBlock);
+ levels.push(level);
+ if(blocks[k].parent!= null)
+ blocks[k].parent.addChild(currentBlock);
+ added = true;
+ break;
+ }
+ }
+
+ if(!added) {
+ errors.push("Error: Invalid indentation at line " + i + ": " + line);
+ return;
+ }
+ }
+
+ currentBlock.lines.push(line.replace(regex["trim"], ""));
+ curLevel = level;
+ }
+
+ return result;
+ }
+
+ function processValue(val) {
+ val = val.replace(regex["trim"], "");
+ var m = null;
+
+ if(val == 'true') {
+ return true;
+ } else if(val == 'false') {
+ return false;
+ } else if(val == '.NaN') {
+ return Number.NaN;
+ } else if(val == 'null') {
+ return null;
+ } else if(val == '.inf') {
+ return Number.POSITIVE_INFINITY;
+ } else if(val == '-.inf') {
+ return Number.NEGATIVE_INFINITY;
+ } else if(m = val.match(regex["dashesString"])) {
+ return m[1];
+ } else if(m = val.match(regex["quotesString"])) {
+ return m[1];
+ } else if(m = val.match(regex["float"])) {
+ return parseFloat(m[0]);
+ } else if(m = val.match(regex["integer"])) {
+ return parseInt(m[0]);
+ } else if( !isNaN(m = Date.parse(val))) {
+ return new Date(m);
+ } else if(m = val.match(regex["single_key_value"])) {
+ var res = {};
+ res[m[1]] = processValue(m[2]);
+ return res;
+ } else if(m = val.match(regex["array"])){
+ var count = 0, c = ' ';
+ var res = [];
+ var content = "";
+ var str = false;
+ for(var j = 0, lenJ = m[1].length; j < lenJ; ++j) {
+ c = m[1][j];
+ if(c == '\'' || c == '"') {
+ if(str === false) {
+ str = c;
+ content += c;
+ continue;
+ } else if((c == '\'' && str == '\'') || (c == '"' && str == '"')) {
+ str = false;
+ content += c;
+ continue;
+ }
+ } else if(str === false && (c == '[' || c == '{')) {
+ ++count;
+ } else if(str === false && (c == ']' || c == '}')) {
+ --count;
+ } else if(str === false && count == 0 && c == ',') {
+ res.push(processValue(content));
+ content = "";
+ continue;
+ }
+
+ content += c;
+ }
+
+ if(content.length > 0)
+ res.push(processValue(content));
+ return res;
+ } else if(m = val.match(regex["map"])){
+ var count = 0, c = ' ';
+ var res = [];
+ var content = "";
+ var str = false;
+ for(var j = 0, lenJ = m[1].length; j < lenJ; ++j) {
+ c = m[1][j];
+ if(c == '\'' || c == '"') {
+ if(str === false) {
+ str = c;
+ content += c;
+ continue;
+ } else if((c == '\'' && str == '\'') || (c == '"' && str == '"')) {
+ str = false;
+ content += c;
+ continue;
+ }
+ } else if(str === false && (c == '[' || c == '{')) {
+ ++count;
+ } else if(str === false && (c == ']' || c == '}')) {
+ --count;
+ } else if(str === false && count == 0 && c == ',') {
+ res.push(content);
+ content = "";
+ continue;
+ }
+
+ content += c;
+ }
+
+ if(content.length > 0)
+ res.push(content);
+
+ var newRes = {};
+ for(var j = 0, lenJ = res.length; j < lenJ; ++j) {
+ if(m = res[j].match(regex["key_value"])) {
+ newRes[m[1]] = processValue(m[2]);
+ }
+ }
+
+ return newRes;
+ } else
+ return val;
+ }
+
+ function processFoldedBlock(block) {
+ var lines = block.lines;
+ var children = block.children;
+ var str = lines.join(" ");
+ var chunks = [str];
+ for(var i = 0, len = children.length; i < len; ++i) {
+ chunks.push(processFoldedBlock(children[i]));
+ }
+ return chunks.join("\n");
+ }
+
+ function processLiteralBlock(block) {
+ var lines = block.lines;
+ var children = block.children;
+ var str = lines.join("\n");
+ for(var i = 0, len = children.length; i < len; ++i) {
+ str += processLiteralBlock(children[i]);
+ }
+ return str;
+ }
+
+ function processBlock(blocks) {
+ var m = null;
+ var res = {};
+ var lines = null;
+ var children = null;
+ var currentObj = null;
+
+ var level = -1;
+
+ var processedBlocks = [];
+
+ var isMap = true;
+
+ for(var j = 0, lenJ = blocks.length; j < lenJ; ++j) {
+
+ if(level != -1 && level != blocks[j].level)
+ continue;
+
+ processedBlocks.push(j);
+
+ level = blocks[j].level;
+ lines = blocks[j].lines;
+ children = blocks[j].children;
+ currentObj = null;
+
+ for(var i = 0, len = lines.length; i < len; ++i) {
+ var line = lines[i];
+
+ if(m = line.match(regex["key"])) {
+ var key = m[1];
+
+ if(key[0] == '-') {
+ key = key.replace(regex["item"], "");
+ if (isMap) {
+ isMap = false;
+ if (typeof(res.length) === "undefined") {
+ res = [];
+ }
+ }
+ if(currentObj != null) res.push(currentObj);
+ currentObj = {};
+ isMap = true;
+ }
+
+ if(typeof m[2] != "undefined") {
+ var value = m[2].replace(regex["trim"], "");
+ if(value[0] == '&') {
+ var nb = processBlock(children);
+ if(currentObj != null) currentObj[key] = nb;
+ else res[key] = nb;
+ reference_blocks[value.substr(1)] = nb;
+ } else if(value[0] == '|') {
+ if(currentObj != null) currentObj[key] = processLiteralBlock(children.shift());
+ else res[key] = processLiteralBlock(children.shift());
+ } else if(value[0] == '*') {
+ var v = value.substr(1);
+ var no = {};
+
+ if(typeof reference_blocks[v] == "undefined") {
+ errors.push("Reference '" + v + "' not found!");
+ } else {
+ for(var k in reference_blocks[v]) {
+ no[k] = reference_blocks[v][k];
+ }
+
+ if(currentObj != null) currentObj[key] = no;
+ else res[key] = no;
+ }
+ } else if(value[0] == '>') {
+ if(currentObj != null) currentObj[key] = processFoldedBlock(children.shift());
+ else res[key] = processFoldedBlock(children.shift());
+ } else {
+ if(currentObj != null) currentObj[key] = processValue(value);
+ else res[key] = processValue(value);
+ }
+ } else {
+ if(currentObj != null) currentObj[key] = processBlock(children);
+ else res[key] = processBlock(children);
+ }
+ } else if(line.match(/^-\s*$/)) {
+ if (isMap) {
+ isMap = false;
+ if (typeof(res.length) === "undefined") {
+ res = [];
+ }
+ }
+ if(currentObj != null) res.push(currentObj);
+ currentObj = {};
+ isMap = true;
+ continue;
+ } else if(m = line.match(/^-\s*(.*)/)) {
+ if(currentObj != null)
+ currentObj.push(processValue(m[1]));
+ else {
+ if (isMap) {
+ isMap = false;
+ if (typeof(res.length) === "undefined") {
+ res = [];
+ }
+ }
+ res.push(processValue(m[1]));
+ }
+ continue;
+ }
+ }
+
+ if(currentObj != null) {
+ if (isMap) {
+ isMap = false;
+ if (typeof(res.length) === "undefined") {
+ res = [];
+ }
+ }
+ res.push(currentObj);
+ }
+ }
+
+ for(var j = processedBlocks.length - 1; j >= 0; --j) {
+ blocks.splice.call(blocks, processedBlocks[j], 1);
+ }
+
+ return res;
+ }
+
+ function semanticAnalysis(blocks) {
+ var res = processBlock(blocks.children);
+ return res;
+ }
+
+ function preProcess(src) {
+ var m;
+ var lines = src.split("\n");
+
+ var r = regex["comment"];
+
+ for(var i in lines) {
+ if(m = lines[i].match(r)) {
+/* var cmt = "";
+ if(typeof m[3] != "undefined")
+ lines[i] = m[1];
+ else if(typeof m[3] != "undefined")
+ lines[i] = m[3];
+ else
+ lines[i] = "";
+ */
+ if(typeof m[3] !== "undefined") {
+ lines[i] = m[0].substr(0, m[0].length - m[3].length);
+ }
+ }
+ }
+
+ return lines.join("\n");
+ }
+
+ function eval(str) {
+ errors = [];
+ reference_blocks = [];
+ processing_time = (new Date()).getTime();
+ var pre = preProcess(str)
+ var doc = parser(pre);
+ var res = semanticAnalysis(doc);
+ processing_time = (new Date()).getTime() - processing_time;
+
+ return res;
+ }
+
+ return {
+ /**
+ * Parse a YAML file from a string.
+ * @param {String} str String with the YAML file contents.
+ * @function
+ */
+ eval : eval,
+
+ /**
+ * Get errors found when parsing the last file.
+ * @function
+ * @returns Errors found when parsing the last file.
+ */
+ getErrors : function() { return errors; },
+
+ /**
+ * Get the time it took to parse the last file.
+ * @function
+ * @returns Time in milliseconds.
+ */
+ getProcessingTime : function() { return processing_time; }
+ }
+})();
+
+module.exports = YAML;
View
27 node_modules/props/package.json
@@ -0,0 +1,27 @@
+{
+ "name": "props",
+ "description": "extract json/yaml from the beginning of text files",
+ "author": "Paul Vorbach <paul@vorb.de> (http://vorb.de)",
+ "version": "0.1.1",
+ "main": "lib/props.js",
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/pvorb/node-props.git"
+ },
+ "tags": [
+ "parser",
+ "properties",
+ "json",
+ "yaml"
+ ],
+ "bugs": {
+ "url": "http://github.com/pvorb/node-props/issues"
+ },
+ "dependencies": {
+ "yamlparser": ">= 0.0.2"
+ },
+ "devDependencies": {},
+ "engines": {
+ "node": "*"
+ }
+}
Please sign in to comment.
Something went wrong with that request. Please try again.